PageRenderTime 57ms CodeModel.GetById 18ms app.highlight 25ms RepoModel.GetById 7ms app.codeStats 1ms

/modules/UpgradeWizard/upgradeMetaHelper.php

https://bitbucket.org/cviolette/sugarcrm
PHP | 393 lines | 241 code | 47 blank | 105 comment | 59 complexity | e8ec7f254fdb515c8e519d4535c3954d MD5 | raw file
  1<?php
  2/*********************************************************************************
  3 * SugarCRM Community Edition is a customer relationship management program developed by
  4 * SugarCRM, Inc. Copyright (C) 2004-2012 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
 39class 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
124function 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
151function 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 */
216function 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?>