]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/UpgradeWizard/upgradeMetaHelper.php
Release 6.4.0
[Github/sugarcrm.git] / modules / UpgradeWizard / upgradeMetaHelper.php
1 <?php
2 /*********************************************************************************
3  * SugarCRM Community Edition is a customer relationship management program developed by
4  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
5  * 
6  * This program is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  * 
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
16  * details.
17  * 
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  * 
23  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
24  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
25  * 
26  * The interactive user interfaces in modified source and object code versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  * 
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the "Powered by
32  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
33  * technical reasons, the Appropriate Legal Notices must display the words
34  * "Powered by SugarCRM".
35  ********************************************************************************/
36
37
38
39 class UpgradeMetaHelper{
40
41         var $upgrade_dir;
42         var $debug_mode;
43         var $upgrade_modules;
44         var $customized_modules;
45         var $source_dir;
46         var $dest_dir ;
47         var $evparser;
48         var $dvparser;
49         var $path_to_master_copy;
50         /**
51          * UpgradeMetaHelper
52          * This is the constructor for the UpgradeMetaHelper class
53          * @param $dir The root upgrade directory (where to copy working files)
54          * @param $masterCopyDirectory The root master directory (where SugarCRM 5.x files reside)
55          * @param $debugMode Debug mode, default is false
56          *
57          */
58         function UpgradeMetaHelper($dir='upgrade', $masterCopyDirecotry='modules_50', $debugMode = false) {
59                 $this->upgrade_dir = $dir;
60                 $this->debug_mode = $debugMode;
61                 $this->upgrade_modules = $this->getModifiedModules();
62
63                 if(count($this->upgrade_modules) > 0) {
64                         $_SESSION['Upgraded_Modules'] = $this->upgrade_modules;
65                         $this->create_upgrade_directory();
66                         $this->path_to_master_copy = $masterCopyDirecotry;
67                     $this->runParser();
68                 }
69
70                 $this->customized_modules = $this->getAllCustomizedModulesBeyondStudio();
71                 if(count($this->customized_modules) > 0) {
72                         $_SESSION['Customized_Modules'] = $this->customized_modules;
73                 }
74         }
75
76
77         /**
78          * getModifiedModules
79          * This method returns a two-dimensional Array of Studio enabled
80          * modules that have been modified.  The second Array index is an
81          * Array of files that do not match the md5 checksum for the module
82          * @return $return_array Two-dimensional Array of [module][modified file(s) Array]
83          */
84                 function getModifiedModules() {
85
86                 $md5_string = array();
87                 if(file_exists(clean_path(getcwd().'/files.md5'))){
88                         require(clean_path(getcwd().'/files.md5'));
89                 }
90
91             $return_array = array();
92             $modules = $this->loadStudioModules();
93             foreach($modules as $mod) {
94
95                    $editView = "modules/$mod/EditView.html";
96                    $detailView = "modules/$mod/DetailView.html";
97                    $searchForm = "modules/$mod/SearchForm.html";
98                if(file_exists($editView) && isset($md5_string['./' . $editView])) {
99                   $fileContents = file_get_contents($editView);
100                   if(md5($fileContents) != $md5_string['./' . $editView]) {
101                          $return_array[$mod][] = $editView;
102                   }
103                }
104
105                if(file_exists($detailView) && isset($md5_string['./' . $detailView])) {
106                   $fileContents = file_get_contents($detailView);
107                   if(md5($fileContents) != $md5_string['./' . $detailView]) {
108                          $return_array[$mod][] = $detailView;
109                   }
110                }
111
112                if(file_exists($searchForm) && isset($md5_string['./' . $searchForm])) {
113                   $fileContents = file_get_contents($searchForm);
114                   if(md5($fileContents) != $md5_string['./' . $searchForm]) {
115                          $return_array[$mod][] = $searchForm;
116                   }
117                }
118
119             } //foreach
120
121                 return $return_array;
122         }
123
124 function saveMatchingFilesQueries($currStep,$value){
125         $upgrade_progress_dir = sugar_cached('upgrades/temp');
126         if(!is_dir($upgrade_progress_dir)){
127                 mkdir($upgrade_progress_dir);
128         }
129         $file_queries_file = $upgrade_progress_dir.'/files_queries.php';
130         if(file_exists($file_queries_file)){
131                 include($file_queries_file);
132         }
133         else{
134                 if(function_exists('sugar_fopen')){
135                         sugar_fopen($file_queries_file, 'w+');
136                 }
137                 else{
138                         fopen($file_queries_file, 'w+');
139                 }
140         }
141         if(!isset($files_queries) || $files_queries == NULL){
142                 $files_queries = array();
143         }
144         $files_queries[$currStep]=$value;
145         if(is_writable($file_queries_file) && write_array_to_file( "file_queries", $file_queries,
146                 $file_queries_file)) {
147                //writing to the file
148         }
149 }
150
151 function getAllCustomizedModulesBeyondStudio() {
152
153         require_once('modules/UpgradeWizard/uw_utils.php');
154         $md5_string = array();
155         if(file_exists(clean_path(getcwd().'/files.md5'))){
156                 require(clean_path(getcwd().'/files.md5'));
157         }
158     $return_array = array();
159     $modules = $this->loadStudioModules();
160     $modulesAll = getAllModules(); //keep all modules as well
161     $allOtherModules = array_diff($modulesAll,$modules);
162     foreach($modules as $mod) {
163           if(!is_dir('modules/'.$mod)) continue;
164           $editView = "modules/$mod/EditView.html";
165           $detailView ="modules/$mod/DetailView.html";
166           $exclude_files[]=$editView;
167           $exclude_files[]=$detailView;
168           $allModFiles = array();
169           $allModFiles = findAllFiles('modules/'.$mod,$allModFiles);
170            foreach($allModFiles as $file){
171                //$file_md5_ref = str_replace(clean_path(getcwd()),'',$file);
172                   if(file_exists($file) && !in_array($file,$exclude_files)){
173                         if(isset($md5_string['./'.$file])) {
174                           $fileContents = file_get_contents($file);
175                           if(md5($fileContents) != $md5_string['./'.$file]) {
176                                 $return_array[$mod][] = $file;
177                           }
178                           else{
179                                 //keep in the array to be deleted later
180                                 $_SESSION['removeMd5MatchingFiles'][] = $file;
181                                   }
182                            }
183                       }
184                   }
185     } //foreach
186     //also check out other non-studio modules by taking the difference between
187     //allMOdules and
188   foreach($allOtherModules as $mod) {
189           if(!is_dir('modules/'.$mod)) continue;
190           $allModFiles = array();
191       $allModFiles = findAllFiles('modules/'.$mod,$allModFiles);
192       foreach($allModFiles as $file){
193                 //$file_md5_ref = str_replace(clean_path(getcwd()),'',$file);
194                 if(file_exists($file)){
195                         if(isset($md5_string['./'.$file])) {
196                           $fileContents = file_get_contents($file);
197                           if(md5($fileContents) == $md5_string['./'.$file]) {
198                                 $_SESSION['removeMd5MatchingFiles'][] = $file;
199                           }
200                }
201           }
202       }
203   }
204    //Also store in a file
205    //saveMatchingFilesQueries('removeMd5MatchingFiles',$_SESSION['removeMd5MatchingFiles']);
206         return $return_array;
207 }
208
209
210
211 /**
212  * Get all the customized modules. Compare the file md5s with the base md5s
213  * If a file has been modified then put the module in the list of customized
214  * modules. Show the list in the preflight check UI.
215  */
216 function getAllCustomizedModules() {
217
218                 require_once('files.md5');
219
220             $return_array = array();
221             $modules = getAllModules();
222             foreach($modules as $mod) {
223                    //find all files in each module if the files have been modified
224                    //as compared to the base version then add the module to the
225                    //customized modules array
226                    $modFiles = findAllFiles(clean_path(getcwd())."/modules/$mod", array());
227                foreach($modFiles as $file){
228                   $fileContents = file_get_contents($file);
229                    $file = str_replace(clean_path(getcwd()),'',$file);
230                   if($md5_string['./' . $file]){
231                           if(md5($fileContents) != $md5_string['./' . $file]) {
232                              //A file has been customized in the module. Put the module into the
233                              // customized modules array.
234                              echo 'Changed File'.$file;
235                                   $return_array[$mod];
236                                   break;
237                           }
238                   }
239                   else{
240                         // This is a new file in user's version and indicates that module has been
241                         //customized. Put the module in the customized array.
242                        echo 'New File'.$file;
243                        $return_array[$mod];
244                        break;
245                   }
246                }
247             } //foreach
248
249                 return $return_array;
250         }
251
252     /**
253      * loadStudioModules
254      * This method returns an Array of all modules where a studio.php file is
255      * present in the metadata directory of the module
256      * @return $modules Array of modules that are studio enabled
257      */
258         function loadStudioModules() {
259                 $modules = array();
260                 $d = dir('modules');
261                 while($e = $d->read()){
262                         if(substr($e, 0, 1) == '.' || !is_dir('modules/' . $e))continue;
263                         if(file_exists('modules/' . $e . '/metadata/studio.php')){
264                            $modules[] = $e;
265                         }
266                 }
267                 return $modules;
268         }
269
270
271         /**
272          * runParser
273          * This method creates the EditView and DetailView parser intances
274          * and runs the parsing for the modules to upgrade
275          *
276          */
277         function runParser() {
278                 require_once('include/SugarFields/Parsers/EditViewMetaParser.php');
279                 require_once('include/SugarFields/Parsers/DetailViewMetaParser.php');
280                 require_once('include/SugarFields/Parsers/SearchFormMetaParser.php');
281
282                 $this->evparser = new EditViewMetaParser();
283                 $this->dvparser = new DetailViewMetaParser();
284                 $this->svparser = new SearchFormMetaParser();
285
286                 foreach($this->upgrade_modules as $module_name=>$files) {
287                         $this->parseFile($module_name, $files);
288                 } //foreach
289         }
290
291
292         /**
293          * parseFile
294          * Hanldes parsing the files for given module where Studio or manual
295          * changes have been detected.
296          * @param $module_name The module to parse
297          * @param $files Array of files found to parse
298          *
299          */
300         function parseFile($module_name, $files) {
301                 global $beanList, $dictionary;
302                 foreach($files as $file) {
303                 if(preg_match('/(EditView|DetailView|SearchForm|QuickCreate)(\.html|\.tpl)$/s', $file, $matches)) {
304                     $view = $matches[1];
305
306                     switch($view) {
307                        case 'EditView' : $parser = $this->evparser; break;
308                        case 'DetailView' : $parser = $this->dvparser; break;
309                        case 'SearchForm' : $parser = $this->svparser; break;
310                     }
311
312                     $lowerCaseView = $view == 'SearchForm' ? 'search' : strtolower($view);
313
314                                         include('modules/'.$module_name.'/vardefs.php');
315                                         $bean_name = $beanList[$module_name];
316                                         $newFile = $this->upgrade_dir.'/modules/'.$module_name.'/metadata/'.$lowerCaseView.'defs.php';
317                                         $evfp = fopen($newFile,'w');
318
319                                         $bean_name = $bean_name == 'aCase' ? 'Case' : $bean_name;
320                                         fwrite($evfp, $parser->parse($file,
321                                                                                         $dictionary[$bean_name]['fields'],
322                                                                                         $module_name,
323                                                                                         true,
324                                                                                         $this->path_to_master_copy.'/modules/'.$module_name.'/metadata/'.$lowerCaseView.'defs.php'));
325                                         fclose($evfp);
326                 } //if
327                 } //foreach
328         }
329
330
331         /**
332          * create_upgrade_directory
333          * Creates a directory called upgrade to house all the modules that are studio enabled.
334          * Also creates subdirectories for all studio enabled modules.
335          *
336          */
337         function create_upgrade_directory() {
338
339                 $dir = $this->upgrade_dir.'/modules';
340                 if(!file_exists($this->upgrade_dir)) {
341                         mkdir($this->upgrade_dir, 0755);
342                 }
343                 if(!file_exists($dir)) {
344                         mkdir($dir, 0755);
345                 }
346
347                 foreach($this->upgrade_modules as $module=>$files){
348                         if(!file_exists($dir.'/'.$module)) {
349                                 mkdir($dir.'/'.$module, 0755);
350                         }
351                         if(!file_exists($dir.'/'.$module.'/metadata')) {
352                                 mkdir($dir.'/'.$module.'/metadata', 0755);
353                         }
354
355                         foreach($files as $file) {
356                                 if(file_exists($file) && is_file($file)) {
357                                    copy($file, $this->upgrade_dir.'/'.$file);
358                                 } //if
359                         } //foreach
360                 }
361         }
362
363
364         /**
365          * verifyMetaData
366          * This function does some quick checks to make sure the metadataFile at
367          * least has an Array panel
368          *
369          * @param $metadataFile The path to the metadata file to verify
370          * @param $module The module to verify
371          * @param $view The view (EditView or DetailView)
372          * @return boolean true if verification check is okay; false otherwise
373          */
374         function verifyMetaData($metadataFile, $module, $view) {
375             if(!file_exists($metadataFile) || !is_file($metadataFile)) {
376                return false;
377             }
378
379             include($metadataFile);
380
381             if(isset($viewdefs) && isset($viewdefs[$module][$view]['panels']) && is_array($viewdefs[$module][$view]['panels'])) {
382                return true;
383             }
384
385         if(isset($searchdefs) && isset($searchdefs[$module]) &&  is_array($searchdefs[$module])) {
386            return true;
387         }
388
389             return false;
390         }
391 }
392
393 ?>