PageRenderTime 60ms CodeModel.GetById 3ms app.highlight 43ms RepoModel.GetById 1ms app.codeStats 1ms

/ModuleInstall/ModuleInstaller.php

https://github.com/BarnetikKoop/SuiteCRM
PHP | 2546 lines | 1987 code | 225 blank | 334 comment | 458 complexity | ea9d046088e06d216acdbccf520bc2de MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1<?php
   2if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
   3/*********************************************************************************
   4 * SugarCRM Community Edition is a customer relationship management program developed by
   5 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
   6
   7 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
   8 * Copyright (C) 2011 - 2014 Salesagility Ltd.
   9 *
  10 * This program is free software; you can redistribute it and/or modify it under
  11 * the terms of the GNU Affero General Public License version 3 as published by the
  12 * Free Software Foundation with the addition of the following permission added
  13 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
  14 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
  15 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
  16 *
  17 * This program is distributed in the hope that it will be useful, but WITHOUT
  18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  19 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
  20 * details.
  21 *
  22 * You should have received a copy of the GNU Affero General Public License along with
  23 * this program; if not, see http://www.gnu.org/licenses or write to the Free
  24 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  25 * 02110-1301 USA.
  26 *
  27 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
  28 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
  29 *
  30 * The interactive user interfaces in modified source and object code versions
  31 * of this program must display Appropriate Legal Notices, as required under
  32 * Section 5 of the GNU Affero General Public License version 3.
  33 *
  34 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
  35 * these Appropriate Legal Notices must retain the display of the "Powered by
  36 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
  37 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
  38 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
  39 ********************************************************************************/
  40
  41
  42/*
  43 * ModuleInstaller - takes an installation package from files in the custom/Extension/X directories, and moves them into custom/X to install them.
  44 * If a directory has multiple files they are concatenated together.
  45 * Relevant directories (X) are Layoutdefs, Vardefs, Include (bean stuff), Language, TableDictionary (relationships)
  46 *
  47 * Installation steps that involve more than just copying files:
  48 * 1. installing custom fields - calls bean->custom_fields->addField
  49 * 2. installing relationships - calls createTableParams to build the relationship table, and createRelationshipMeta to add the relationship to the relationship table
  50 * 3. rebuilding the relationships - at almost the last step in install(), calls modules/Administration/RebuildRelationship.php
  51 * 4. repair indices - uses "modules/Administration/RepairIndex.php";
  52 */
  53
  54
  55
  56require_once('include/utils/progress_bar_utils.php');
  57
  58require_once('ModuleInstall/ModuleScanner.php');
  59define('DISABLED_PATH', 'Disabled');
  60
  61class ModuleInstaller{
  62	var $modules = array();
  63	var $silent = false;
  64	var $base_dir  = '';
  65	var $modulesInPackage = array();
  66	public $disabled_path = DISABLED_PATH;
  67    public $id_name;
  68	function ModuleInstaller(){
  69		$this->ms = new ModuleScanner();
  70		$this->modules = get_module_dir_list();
  71		$this->db = & DBManagerFactory::getInstance();
  72        include("ModuleInstall/extensions.php");
  73        $this->extensions = $extensions;
  74	}
  75
  76   /*
  77    * ModuleInstaller->install includes the manifest.php from the base directory it has been given. If it has been asked to do an upgrade it checks to see if there is
  78    * an upgrade_manifest defined in the manifest; if not it errors. It then adds the bean into the custom/Extension/application/Ext/Include/<module>.php - sets beanList, beanFiles
  79    * and moduleList - and then calls ModuleInstaller->merge_files('Ext/Include', 'modules.ext.php', '', true) to merge the individual module files into a combined file
  80    * /custom/Extension/application/Ext/Include/modules.ext.php (which now contains a list of all $beanList, $beanFiles and $moduleList for all extension modules) -
  81    * this file modules.ext.php is included at the end of modules.php.
  82    *
  83    * Finally it runs over a list of defined tasks; then install_beans, then install_custom_fields, then clear the Vardefs, run a RepairAndClear, then finally call rebuild_relationships.
  84    */
  85	function install($base_dir, $is_upgrade = false, $previous_version = ''){
  86		if(defined('TEMPLATE_URL'))SugarTemplateUtilities::disableCache();
  87        if ((defined('MODULE_INSTALLER_PACKAGE_SCAN') && MODULE_INSTALLER_PACKAGE_SCAN)
  88            || !empty($GLOBALS['sugar_config']['moduleInstaller']['packageScan'])) {
  89			$this->ms->scanPackage($base_dir);
  90			if($this->ms->hasIssues()){
  91				$this->ms->displayIssues();
  92				sugar_cleanup(true);
  93			}
  94		}
  95
  96        // workaround for bug 45812 - refresh vardefs cache before unpacking to avoid partial vardefs in cache
  97        global $beanList;
  98        foreach ($this->modules as $module_name) {
  99            if (!empty($beanList[$module_name])) {
 100                $objectName = BeanFactory::getObjectName($module_name);
 101                VardefManager::loadVardef($module_name, $objectName);
 102            }
 103        }
 104
 105		global $app_strings, $mod_strings;
 106		$this->base_dir = $base_dir;
 107		$total_steps = 5; //minimum number of steps with no tasks
 108		$current_step = 0;
 109		$tasks = array(
 110			'pre_execute',
 111			'install_copy',
 112		    'install_extensions',
 113			'install_images',
 114			'install_dcactions',
 115			'install_dashlets',
 116			'install_connectors',
 117			'install_layoutfields',
 118			'install_relationships',
 119            'enable_manifest_logichooks',
 120			'post_execute',
 121			'reset_opcodes',
 122		);
 123
 124		$total_steps += count($tasks);
 125		if(file_exists($this->base_dir . '/manifest.php')){
 126				if(!$this->silent){
 127					$current_step++;
 128					display_progress_bar('install', $current_step, $total_steps);
 129					echo '<div id ="displayLoglink" ><a href="#" onclick="document.getElementById(\'displayLog\').style.display=\'\'">'
 130						.$app_strings['LBL_DISPLAY_LOG'].'</a> </div><div id="displayLog" style="display:none">';
 131				}
 132
 133				include($this->base_dir . '/manifest.php');
 134				if($is_upgrade && !empty($previous_version)){
 135					//check if the upgrade path exists
 136					if(!empty($upgrade_manifest)){
 137						if(!empty($upgrade_manifest['upgrade_paths'])){
 138							if(!empty($upgrade_manifest['upgrade_paths'][$previous_version])){
 139								$installdefs = 	$upgrade_manifest['upgrade_paths'][$previous_version];
 140							}else{
 141								$errors[] = 'No Upgrade Path Found in manifest.';
 142								$this->abort($errors);
 143							}//fi
 144						}//fi
 145					}//fi
 146				}//fi
 147				$this->id_name = $installdefs['id'];
 148				$this->installdefs = $installdefs;
 149				if(!$this->silent){
 150					$current_step++;
 151					update_progress_bar('install', $current_step, $total_steps);
 152				}
 153
 154				foreach($tasks as $task){
 155					$this->$task();
 156					if(!$this->silent){
 157						$current_step++;
 158						update_progress_bar('install', $current_step, $total_steps);
 159					}
 160				}
 161				$this->install_beans($this->installed_modules);
 162				if(!$this->silent){
 163					$current_step++;
 164					update_progress_bar('install', $total_steps, $total_steps);
 165				}
 166				if(isset($installdefs['custom_fields'])){
 167					$this->log(translate('LBL_MI_IN_CUSTOMFIELD'));
 168					$this->install_custom_fields($installdefs['custom_fields']);
 169				}
 170				if(!$this->silent){
 171					$current_step++;
 172					update_progress_bar('install', $current_step, $total_steps);
 173					echo '</div>';
 174				}
 175				if(!$this->silent){
 176					$current_step++;
 177					update_progress_bar('install', $current_step, $total_steps);
 178					echo '</div>';
 179				}
 180				$selectedActions = array(
 181			'clearTpls',
 182			'clearJsFiles',
 183			'clearDashlets',
 184			'clearVardefs',
 185			'clearJsLangFiles',
 186			'rebuildAuditTables',
 187			'repairDatabase',
 188		);
 189				VardefManager::clearVardef();
 190				global $beanList, $beanFiles, $moduleList;
 191				if (file_exists('custom/application/Ext/Include/modules.ext.php'))
 192				{
 193				    include('custom/application/Ext/Include/modules.ext.php');
 194				}
 195				require_once("modules/Administration/upgrade_custom_relationships.php");
 196            	upgrade_custom_relationships($this->installed_modules);
 197				$this->rebuild_all(true);
 198				require_once('modules/Administration/QuickRepairAndRebuild.php');
 199				$rac = new RepairAndClear();
 200				$rac->repairAndClearAll($selectedActions, $this->installed_modules,true, false);
 201				$this->rebuild_relationships();
 202				UpdateSystemTabs('Add',$this->tab_modules);
 203                //Clear out all the langauge cache files.
 204                clearAllJsAndJsLangFilesWithoutOutput();
 205                $cache_key = 'app_list_strings.'.$GLOBALS['current_language'];
 206                sugar_cache_clear($cache_key );
 207                sugar_cache_reset();
 208
 209				//clear the unified_search_module.php file
 210	            require_once('modules/Home/UnifiedSearchAdvanced.php');
 211	            UnifiedSearchAdvanced::unlinkUnifiedSearchModulesFile();
 212
 213				$this->log('<br><b>' . translate('LBL_MI_COMPLETE') . '</b>');
 214		}else{
 215			die("No \$installdefs Defined In $this->base_dir/manifest.php");
 216		}
 217
 218	}
 219
 220	function install_user_prefs($module, $hide_from_user=false){
 221		UserPreference::updateAllUserPrefs('display_tabs', $module, '', true, !$hide_from_user);
 222		UserPreference::updateAllUserPrefs('hide_tabs', $module, '', true, $hide_from_user);
 223		UserPreference::updateAllUserPrefs('remove_tabs', $module, '', true, $hide_from_user);
 224	}
 225	function uninstall_user_prefs($module){
 226		UserPreference::updateAllUserPrefs('display_tabs', $module, '', true, true);
 227		UserPreference::updateAllUserPrefs('hide_tabs', $module, '', true, true);
 228		UserPreference::updateAllUserPrefs('remove_tabs', $module, '', true, true);
 229	}
 230
 231	function pre_execute(){
 232		require_once($this->base_dir . '/manifest.php');
 233		if(isset($this->installdefs['pre_execute']) && is_array($this->installdefs['pre_execute'])){
 234			foreach($this->installdefs['pre_execute'] as $includefile){
 235				require_once(str_replace('<basepath>', $this->base_dir, $includefile));
 236			}
 237		}
 238	}
 239
 240	function post_execute(){
 241		require_once($this->base_dir . '/manifest.php');
 242		if(isset($this->installdefs['post_execute']) && is_array($this->installdefs['post_execute'])){
 243			foreach($this->installdefs['post_execute'] as $includefile){
 244				require_once(str_replace('<basepath>', $this->base_dir, $includefile));
 245			}
 246		}
 247	}
 248
 249	function pre_uninstall(){
 250		require_once($this->base_dir . '/manifest.php');
 251		if(isset($this->installdefs['pre_uninstall']) && is_array($this->installdefs['pre_uninstall'])){
 252			foreach($this->installdefs['pre_uninstall'] as $includefile){
 253				require_once(str_replace('<basepath>', $this->base_dir, $includefile));
 254			}
 255		}
 256	}
 257
 258	function post_uninstall(){
 259		require_once($this->base_dir . '/manifest.php');
 260		if(isset($this->installdefs['post_uninstall']) && is_array($this->installdefs['post_uninstall'])){
 261			foreach($this->installdefs['post_uninstall'] as $includefile){
 262				require_once(str_replace('<basepath>', $this->base_dir, $includefile));
 263			}
 264		}
 265	}
 266
 267	/*
 268     * ModuleInstaller->install_copy gets the copy section of installdefs in the manifest and calls copy_path to copy each path (file or directory) to its final location
 269     * (specified as from and to in the manifest), replacing <basepath> by the base_dir value passed in to install.
 270     */
 271	function install_copy(){
 272		if(isset($this->installdefs['copy'])){
 273			/* BEGIN - RESTORE POINT - by MR. MILK August 31, 2005 02:22:11 PM */
 274			$backup_path = clean_path( remove_file_extension(urldecode($_REQUEST['install_file']))."-restore" );
 275			/* END - RESTORE POINT - by MR. MILK August 31, 2005 02:22:18 PM */
 276			foreach($this->installdefs['copy'] as $cp){
 277				$GLOBALS['log']->debug("Copying ..." . $cp['from'].  " to " .$cp['to'] );
 278				/* BEGIN - RESTORE POINT - by MR. MILK August 31, 2005 02:22:11 PM */
 279				//$this->copy_path($cp['from'], $cp['to']);
 280				$this->copy_path($cp['from'], $cp['to'], $backup_path);
 281				/* END - RESTORE POINT - by MR. MILK August 31, 2005 02:22:18 PM */
 282			}
 283			//here we should get the module list again as we could have copied something to the modules dir
 284			$this->modules = get_module_dir_list();
 285		}
 286	}
 287	function uninstall_copy(){
 288		if(!empty($this->installdefs['copy'])){
 289					foreach($this->installdefs['copy'] as $cp){
 290						$cp['to'] = clean_path(str_replace('<basepath>', $this->base_dir, $cp['to']));
 291						$cp['from'] = clean_path(str_replace('<basepath>', $this->base_dir, $cp['from']));
 292						$GLOBALS['log']->debug('Unlink ' . $cp['to']);
 293				/* BEGIN - RESTORE POINT - by MR. MILK August 31, 2005 02:22:11 PM */
 294						//rmdir_recursive($cp['to']);
 295
 296						$backup_path = clean_path( remove_file_extension(urldecode(hashToFile($_REQUEST['install_file'])))."-restore/".$cp['to'] );
 297						$this->uninstall_new_files($cp, $backup_path);
 298						$this->copy_path($backup_path, $cp['to'], $backup_path, true);
 299				/* END - RESTORE POINT - by MR. MILK August 31, 2005 02:22:18 PM */
 300					}
 301					$backup_path = clean_path( remove_file_extension(urldecode(hashToFile($_REQUEST['install_file'])))."-restore");
 302					if(file_exists($backup_path))
 303						rmdir_recursive($backup_path);
 304				}
 305	}
 306
 307
 308	/**
 309	 * Removes any files that were added by the loaded module. If the files already existed prior to install
 310	 * it will be handled by copy_path with the uninstall parameter.
 311	 *
 312	 */
 313	function uninstall_new_files($cp, $backup_path){
 314		$zip_files = $this->dir_get_files($cp['from'],$cp['from']);
 315		$backup_files = $this->dir_get_files($backup_path, $backup_path);
 316		foreach($zip_files as $k=>$v){
 317			//if it's not a backup then it is probably a new file but we'll check that it is not in the md5.files first
 318			if(!isset($backup_files[$k])){
 319				$to = $cp['to'] . $k;
 320				//if it's not a sugar file then we remove it otherwise we can't restor it
 321				if(!$this->ms->sugarFileExists($to)){
 322					$GLOBALS['log']->debug('ModuleInstaller[uninstall_new_file] deleting file ' . $to);
 323					if(file_exists($to)) {
 324					    unlink($to);
 325					}
 326				}else{
 327					$GLOBALS['log']->fatal('ModuleInstaller[uninstall_new_file] Could not remove file ' . $to . ' as no backup file was found to restore to');
 328				}
 329			}
 330		}
 331		//lets check if the directory is empty if it is we will delete it as well
 332		$files_remaining = $this->dir_file_count($cp['to']);
 333		if(file_exists($cp['to']) && $files_remaining == 0){
 334			$GLOBALS['log']->debug('ModuleInstaller[uninstall_new_file] deleting directory ' . $cp['to']);
 335			rmdir_recursive($cp['to']);
 336		}
 337
 338	}
 339
 340	/**
 341	 * Get directory where module's extensions go
 342	 * @param string $module Module name
 343	 */
 344    public function getExtDir($module)
 345    {
 346	    if($module == 'application') {
 347            return "custom/Extension/application/Ext";
 348        } else {
 349			return "custom/Extension/modules/$module/Ext";
 350        }
 351    }
 352
 353	/**
 354	 * Install file(s) into Ext/ part
 355	 * @param string $section Name of the install file section
 356	 * @param string $extname Name in Ext directory
 357	 * @param string $module This extension belongs to a specific module
 358	 */
 359	public function installExt($section, $extname, $module = '')
 360	{
 361        if(isset($this->installdefs[$section])){
 362			$this->log(sprintf(translate("LBL_MI_IN_EXT"), $section));
 363			foreach($this->installdefs[$section] as $item){
 364			    if(isset($item['from'])) {
 365				    $from = str_replace('<basepath>', $this->base_dir, $item['from']);
 366			    } else {
 367			        $from = '';
 368			    }
 369				if(!empty($module)) {
 370				    $item['to_module'] = $module;
 371				}
 372				$GLOBALS['log']->debug("Installing section $section from $from for " .$item['to_module'] );
 373                if($item['to_module'] == 'application') {
 374                    $path = "custom/Extension/application/Ext/$extname";
 375                } else {
 376				    $path = "custom/Extension/modules/{$item['to_module']}/Ext/$extname";
 377                }
 378				if(!file_exists($path)){
 379					mkdir_recursive($path, true);
 380				}
 381				if(isset($item["name"])) {
 382				    $target = $item["name"];
 383				} else if (!empty($from)){
 384                    $target = basename($from, ".php");
 385                } else {
 386				    $target = $this->id_name;
 387				}
 388				if(!empty($from)) {
 389				    copy_recursive($from , "$path/$target.php");
 390				}
 391			}
 392		}
 393	}
 394
 395	/**
 396	 * Uninstall file(s) into Ext/ part
 397	 * @param string $section Name of the install file section
 398	 * @param string $extname Name in Ext directory
 399	 * @param string $module This extension belongs to a specific module
 400	 */
 401	public function uninstallExt($section, $extname, $module = '')
 402	{
 403        if(isset($this->installdefs[$section])){
 404			$this->log(sprintf(translate("LBL_MI_UN_EXT"), $section));
 405			foreach($this->installdefs[$section] as $item){
 406			    if(isset($item['from'])) {
 407				    $from = str_replace('<basepath>', $this->base_dir, $item['from']);
 408			    } else {
 409			        $from = '';
 410			    }
 411			    if(!empty($module)) {
 412				    $item['to_module'] = $module;
 413				}
 414				$GLOBALS['log']->debug("Uninstalling section $section from $from for " .$item['to_module'] );
 415                if($item['to_module'] == 'application') {
 416                    $path = "custom/Extension/application/Ext/$extname";
 417                } else {
 418				    $path = "custom/Extension/modules/{$item['to_module']}/Ext/$extname";
 419                }
 420				if(isset($item["name"])) {
 421				    $target = $item["name"];
 422				} else if (!empty($from)){
 423                    $target = basename($from, ".php");
 424                } else {
 425				    $target = $this->id_name;
 426				}
 427				$disabled_path = $path.'/'.DISABLED_PATH;
 428				if (file_exists("$path/$target.php")) {
 429				    rmdir_recursive("$path/$target.php");
 430                } else if (file_exists("$disabled_path/$target.php")) {
 431                    rmdir_recursive("$disabled_path/$target.php");
 432				} else if (!empty($from) && file_exists($path . '/'. basename($from))) {
 433				    rmdir_recursive( $path . '/'. basename($from));
 434                } else if (!empty($from) && file_exists($disabled_path . '/'. basename($from))) {
 435					rmdir_recursive( $disabled_path . '/'. basename($from));
 436				}
 437		    }
 438	    }
 439	}
 440
 441	/**
 442     * Rebuild generic extension
 443     * @param string $ext Extension directory
 444     * @param string $filename Target filename
 445     */
 446	public function rebuildExt($ext, $filename)
 447	{
 448            $this->log(translate('LBL_MI_REBUILDING') . " $ext...");
 449			$this->merge_files("Ext/$ext/", $filename);
 450	}
 451
 452	/**
 453	 * Disable generic extension
 454	 * @param string $section Install file section name
 455	 * @param string $extname Extension directory
 456 	 * @param string $module This extension belongs to a specific module
 457	 */
 458	public function disableExt($section, $extname, $module = '')
 459	{
 460		if(isset($this->installdefs[$section])) {
 461			foreach($this->installdefs[$section] as $item) {
 462			    if(isset($item['from'])) {
 463				    $from = str_replace('<basepath>', $this->base_dir, $item['from']);
 464			    } else {
 465			        $from = '';
 466			    }
 467				if(!empty($module)) {
 468				    $item['to_module'] = $module;
 469				}
 470				$GLOBALS['log']->debug("Disabling $extname ... from $from for " .$item['to_module']);
 471                if($item['to_module'] == 'application') {
 472                    $path = "custom/Extension/application/Ext/$extname";
 473                } else {
 474				    $path = "custom/Extension/modules/{$item['to_module']}/Ext/$extname";
 475                }
 476				if(isset($item["name"])) {
 477				    $target = $item["name"];
 478				} else if (!empty($from)){
 479                    $target = basename($from, ".php");
 480                }else {
 481				    $target = $this->id_name;
 482				}
 483				$disabled_path = $path.'/'.DISABLED_PATH;
 484                if (file_exists("$path/$target.php")) {
 485					mkdir_recursive($disabled_path, true);
 486					rename("$path/$target.php", "$disabled_path/$target.php");
 487				} else if (!empty($from) && file_exists($path . '/'. basename($from))) {
 488					mkdir_recursive($disabled_path, true);
 489				    rename( $path . '/'. basename($from), $disabled_path.'/'. basename($from));
 490				}
 491			}
 492		}
 493	}
 494
 495	/**
 496	 * Enable generic extension
 497	 * @param string $section Install file section name
 498	 * @param string $extname Extension directory
 499 	 * @param string $module This extension belongs to a specific module
 500	 */
 501	public function enableExt($section, $extname, $module = '')
 502	{
 503		if(isset($this->installdefs[$section])) {
 504			foreach($this->installdefs[$section] as $item) {
 505			    if(isset($item['from'])) {
 506				    $from = str_replace('<basepath>', $this->base_dir, $item['from']);
 507			    } else {
 508			        $from = '';
 509			    }
 510			    if(!empty($module)) {
 511				    $item['to_module'] = $module;
 512				}
 513				$GLOBALS['log']->debug("Enabling $extname ... from $from for " .$item['to_module']);
 514
 515                if($item['to_module'] == 'application') {
 516                    $path = "custom/Extension/application/Ext/$extname";
 517                } else {
 518				    $path = "custom/Extension/modules/{$item['to_module']}/Ext/$extname";
 519                }
 520				if(isset($item["name"])) {
 521				    $target = $item["name"];
 522				} else if (!empty($from)){
 523                    $target = basename($from, ".php");
 524                } else {
 525				    $target = $this->id_name;
 526				}
 527				if(!file_exists($path)) {
 528				    mkdir_recursive($path, true);
 529				}
 530                $disabled_path = $path.'/'.DISABLED_PATH;
 531				if (file_exists("$disabled_path/$target.php")) {
 532					rename("$disabled_path/$target.php",  "$path/$target.php");
 533				}
 534				if (!empty($from) && file_exists($disabled_path . '/'. basename($from))) {
 535					rename($disabled_path.'/'. basename($from),  $path . '/'. basename($from));
 536				}
 537			}
 538		}
 539    }
 540
 541    /**
 542     * Method removes module from global search configurations
 543     *
 544     * return bool
 545     */
 546    public function uninstall_global_search()
 547    {
 548        if (empty($this->installdefs['beans']))
 549        {
 550            return true;
 551        }
 552
 553        if (is_file('custom/modules/unified_search_modules_display.php') == false)
 554        {
 555            return true;
 556        }
 557
 558        $user = new User();
 559        $users = get_user_array();
 560        $unified_search_modules_display = array();
 561        require('custom/modules/unified_search_modules_display.php');
 562
 563        foreach($this->installdefs['beans'] as $beanDefs)
 564        {
 565            if (array_key_exists($beanDefs['module'], $unified_search_modules_display) == false)
 566            {
 567                continue;
 568            }
 569            unset($unified_search_modules_display[$beanDefs['module']]);
 570            foreach($users as $userId => $userName)
 571            {
 572                if (empty($userId))
 573                {
 574                    continue;
 575                }
 576                $user->retrieve($userId);
 577                $prefs = $user->getPreference('globalSearch', 'search');
 578                if (array_key_exists($beanDefs['module'], $prefs) == false)
 579                {
 580                    continue;
 581                }
 582                unset($prefs[$beanDefs['module']]);
 583                $user->setPreference('globalSearch', $prefs, 0, 'search');
 584                $user->savePreferencesToDB();
 585            }
 586        }
 587
 588        if (write_array_to_file("unified_search_modules_display", $unified_search_modules_display, 'custom/modules/unified_search_modules_display.php') == false)
 589        {
 590            global $app_strings;
 591            $msg = string_format($app_strings['ERR_FILE_WRITE'], array('custom/modules/unified_search_modules_display.php'));
 592            $GLOBALS['log']->error($msg);
 593            throw new Exception($msg);
 594            return false;
 595        }
 596        return true;
 597    }
 598
 599    /**
 600     * Method enables module in global search configurations by disabled_module_visible key
 601     *
 602     * return bool
 603     */
 604    public function enable_global_search()
 605    {
 606        if (empty($this->installdefs['beans']))
 607        {
 608            return true;
 609        }
 610
 611        if (is_file('custom/modules/unified_search_modules_display.php') == false)
 612        {
 613            return true;
 614        }
 615
 616        $unified_search_modules_display = array();
 617        require('custom/modules/unified_search_modules_display.php');
 618
 619        foreach($this->installdefs['beans'] as $beanDefs)
 620        {
 621            if (array_key_exists($beanDefs['module'], $unified_search_modules_display) == false)
 622            {
 623                continue;
 624            }
 625            if (isset($unified_search_modules_display[$beanDefs['module']]['disabled_module_visible']) == false)
 626            {
 627                continue;
 628            }
 629            $unified_search_modules_display[$beanDefs['module']]['visible'] = $unified_search_modules_display[$beanDefs['module']]['disabled_module_visible'];
 630            unset($unified_search_modules_display[$beanDefs['module']]['disabled_module_visible']);
 631        }
 632
 633        if (write_array_to_file("unified_search_modules_display", $unified_search_modules_display, 'custom/modules/unified_search_modules_display.php') == false)
 634        {
 635            global $app_strings;
 636            $msg = string_format($app_strings['ERR_FILE_WRITE'], array('custom/modules/unified_search_modules_display.php'));
 637            $GLOBALS['log']->error($msg);
 638            throw new Exception($msg);
 639            return false;
 640        }
 641        return true;
 642    }
 643
 644    /**
 645     * Method disables module in global search configurations by disabled_module_visible key
 646     *
 647     * return bool
 648     */
 649    public function disable_global_search()
 650    {
 651        if (empty($this->installdefs['beans']))
 652        {
 653            return true;
 654        }
 655
 656        if (is_file('custom/modules/unified_search_modules_display.php') == false)
 657        {
 658            return true;
 659        }
 660
 661        $unified_search_modules_display = array();
 662        require('custom/modules/unified_search_modules_display.php');
 663
 664        foreach($this->installdefs['beans'] as $beanDefs)
 665        {
 666            if (array_key_exists($beanDefs['module'], $unified_search_modules_display) == false)
 667            {
 668                continue;
 669            }
 670            if (isset($unified_search_modules_display[$beanDefs['module']]['visible']) == false)
 671            {
 672                continue;
 673            }
 674            $unified_search_modules_display[$beanDefs['module']]['disabled_module_visible'] = $unified_search_modules_display[$beanDefs['module']]['visible'];
 675            $unified_search_modules_display[$beanDefs['module']]['visible'] = false;
 676        }
 677
 678        if (write_array_to_file("unified_search_modules_display", $unified_search_modules_display, 'custom/modules/unified_search_modules_display.php') == false)
 679        {
 680            global $app_strings;
 681            $msg = string_format($app_strings['ERR_FILE_WRITE'], array('custom/modules/unified_search_modules_display.php'));
 682            $GLOBALS['log']->error($msg);
 683            throw new Exception($msg);
 684            return false;
 685        }
 686        return true;
 687    }
 688
 689    public function install_extensions()
 690	{
 691	    foreach($this->extensions as $extname => $ext) {
 692	        $install = "install_$extname";
 693	        if(method_exists($this, $install)) {
 694	            // non-standard function
 695                $this->$install();
 696	        } else {
 697	            if(!empty($ext["section"])) {
 698	                $module = isset($ext['module'])?$ext['module']:'';
 699	                $this->installExt($ext["section"], $ext["extdir"], $module);
 700	            }
 701	        }
 702	    }
 703	    $this->rebuild_extensions();
 704	}
 705
 706	public function uninstall_extensions()
 707	{
 708	    foreach($this->extensions as $extname => $ext) {
 709	        $func = "uninstall_$extname";
 710	        if(method_exists($this, $func)) {
 711	            // non-standard function
 712                $this->$func();
 713	        } else {
 714	            if(!empty($ext["section"])) {
 715	                $module = isset($ext['module'])?$ext['module']:'';
 716	                $this->uninstallExt($ext["section"], $ext["extdir"], $module);
 717	            }
 718	        }
 719	    }
 720	    $this->rebuild_extensions();
 721	}
 722
 723	public function rebuild_extensions()
 724	{
 725	    foreach($this->extensions as $extname => $ext) {
 726	        $func = "rebuild_$extname";
 727	        if(method_exists($this, $func)) {
 728	            // non-standard function
 729                $this->$func();
 730	        } else {
 731    	        $this->rebuildExt($ext["extdir"], $ext["file"]);
 732	        }
 733	    }
 734	}
 735
 736	public function disable_extensions()
 737	{
 738	    foreach($this->extensions as $extname => $ext) {
 739	        $func = "disable_$extname";
 740	        if(method_exists($this, $func)) {
 741	            // non-standard install
 742                $this->$func();
 743	        } else {
 744	            if(!empty($ext["section"])) {
 745	                $module = isset($ext['module'])?$ext['module']:'';
 746	                $this->disableExt($ext["section"], $ext["extdir"], $module);
 747	            }
 748	        }
 749	    }
 750	    $this->rebuild_extensions();
 751	}
 752
 753	public function enable_extensions()
 754	{
 755	    foreach($this->extensions as $extname => $ext) {
 756	        $func = "enable_$extname";
 757	        if(method_exists($this, $func)) {
 758	            // non-standard install
 759                $this->$func();
 760	        } else {
 761	            if(!empty($ext["section"])) {
 762	                $module = isset($ext['module'])?$ext['module']:'';
 763	                $this->enableExt($ext["section"], $ext["extdir"], $module);
 764	            }
 765	        }
 766	    }
 767	    $this->rebuild_extensions();
 768	}
 769
 770	function install_dashlets()
 771	{
 772        if(isset($this->installdefs['dashlets'])){
 773			foreach($this->installdefs['dashlets'] as $cp){
 774				$this->log(translate('LBL_MI_IN_DASHLETS') . $cp['name']);
 775				$cp['from'] = str_replace('<basepath>', $this->base_dir, $cp['from']);
 776				$path = 'custom/modules/Home/Dashlets/' . $cp['name'] . '/';
 777				$GLOBALS['log']->debug("Installing Dashlet " . $cp['name'] . "..." . $cp['from'] );
 778				if(!file_exists($path)){
 779					mkdir_recursive($path, true);
 780				}
 781				copy_recursive($cp['from'] , $path);
 782			}
 783			include('modules/Administration/RebuildDashlets.php');
 784
 785		}
 786	}
 787
 788	function uninstall_dashlets(){
 789        if(isset($this->installdefs['dashlets'])){
 790			foreach($this->installdefs['dashlets'] as $cp){
 791				$this->log(translate('LBL_MI_UN_DASHLETS') . $cp['name']);
 792				$path = 'custom/modules/Home/Dashlets/' . $cp['name'];
 793				$GLOBALS['log']->debug('Unlink ' .$path);
 794				if (file_exists($path))
 795					rmdir_recursive($path);
 796			}
 797			include('modules/Administration/RebuildDashlets.php');
 798		}
 799	}
 800
 801
 802	function install_images(){
 803        if(isset($this->installdefs['image_dir'])){
 804			$this->log( translate('LBL_MI_IN_IMAGES') );
 805			$this->copy_path($this->installdefs['image_dir'] , 'custom/themes');
 806
 807		}
 808	}
 809
 810	function install_dcactions(){
 811		if(isset($this->installdefs['dcaction'])){
 812			$this->log(translate('LBL_MI_IN_MENUS'));
 813			foreach($this->installdefs['dcaction'] as $action){
 814				$action['from'] = str_replace('<basepath>', $this->base_dir, $action['from']);
 815				$GLOBALS['log']->debug("Installing DCActions ..." . $action['from']);
 816				$path = 'custom/Extension/application/Ext/DashletContainer/Containers';
 817				if(!file_exists($path)){
 818					mkdir_recursive($path, true);
 819				}
 820				copy_recursive($action['from'] , $path . '/'. $this->id_name . '.php');
 821			}
 822			$this->rebuild_dashletcontainers();
 823		}
 824	}
 825
 826	function uninstall_dcactions(){
 827        if(isset($this->installdefs['dcaction'])){
 828			$this->log(translate('LBL_MI_UN_MENUS'));
 829			foreach($this->installdefs['dcaction'] as $action){
 830				$action['from'] = str_replace('<basepath>', $this->base_dir, $action['from']);
 831				$GLOBALS['log']->debug("Uninstalling DCActions ..." . $action['from'] );
 832				$path = 'custom/Extension/application/Ext/DashletContainer/Containers';
 833				if (sugar_is_file($path . '/'. $this->id_name . '.php', 'w'))
 834				{
 835					rmdir_recursive( $path . '/'. $this->id_name . '.php');
 836				}
 837				else if (sugar_is_file($path . '/'. DISABLED_PATH . '/'. $this->id_name . '.php', 'w'))
 838				{
 839					rmdir_recursive( $path . '/'. DISABLED_PATH . '/'. $this->id_name . '.php');
 840				}
 841			}
 842			$this->rebuild_dashletcontainers();
 843		}
 844	}
 845
 846	function install_connectors(){
 847        if(isset($this->installdefs['connectors'])){
 848        	foreach($this->installdefs['connectors'] as $cp){
 849				$this->log(translate('LBL_MI_IN_CONNECTORS') . $cp['name']);
 850				$dir = str_replace('_','/',$cp['name']);
 851				$cp['connector'] = str_replace('<basepath>', $this->base_dir, $cp['connector']);
 852				$source_path = 'custom/modules/Connectors/connectors/sources/' . $dir. '/';
 853				$GLOBALS['log']->debug("Installing Connector " . $cp['name'] . "..." . $cp['connector'] );
 854				if(!file_exists($source_path)){
 855					mkdir_recursive($source_path, true);
 856				}
 857				copy_recursive($cp['connector'] , $source_path);
 858
 859				//Install optional formatter code if it is specified
 860				if(!empty($cp['formatter'])) {
 861					$cp['formatter'] = str_replace('<basepath>', $this->base_dir, $cp['formatter']);
 862					$formatter_path = 'custom/modules/Connectors/connectors/formatters/' . $dir. '/';
 863					if(!file_exists($formatter_path)){
 864						mkdir_recursive($formatter_path, true);
 865					}
 866					copy_recursive($cp['formatter'] , $formatter_path);
 867				}
 868			}
 869			require_once('include/connectors/utils/ConnectorUtils.php');
 870			ConnectorUtils::installSource($cp['name']);
 871		}
 872
 873	}
 874	function uninstall_connectors(){
 875    	if(isset($this->installdefs['connectors'])){
 876    		foreach($this->installdefs['connectors'] as $cp){
 877				$this->log(translate('LBL_MI_UN_CONNECTORS') . $cp['name']);
 878				$dir = str_replace('_','/',$cp['name']);
 879				$source_path = 'custom/modules/Connectors/connectors/sources/' . $dir;
 880				$formatter_path = 'custom/modules/Connectors/connectors/formatters/' . $dir;
 881				$GLOBALS['log']->debug('Unlink ' .$source_path);
 882				rmdir_recursive($source_path);
 883				rmdir_recursive($formatter_path);
 884			}
 885			require_once('include/connectors/utils/ConnectorUtils.php');
 886			//ConnectorUtils::getConnectors(true);
 887			ConnectorUtils::uninstallSource($cp['name']);
 888		}
 889	}
 890
 891	function install_vardef($from, $to_module)
 892	{
 893			$GLOBALS['log']->debug("Installing Vardefs ..." . $from .  " for " .$to_module);
 894			$path = 'custom/Extension/modules/' . $to_module. '/Ext/Vardefs';
 895			if($to_module == 'application'){
 896				$path ='custom/Extension/' . $to_module. '/Ext/Vardefs';
 897			}
 898			if(!file_exists($path)){
 899				mkdir_recursive($path, true);
 900			}
 901			copy_recursive($from , $path.'/'. basename($from));
 902	}
 903
 904	function install_layoutdef($from, $to_module){
 905			$GLOBALS['log']->debug("Installing Layout Defs ..." . $from .  " for " .$to_module);
 906			$path = 'custom/Extension/modules/' . $to_module. '/Ext/Layoutdefs';
 907			if($to_module == 'application'){
 908				$path ='custom/Extension/' . $to_module. '/Ext/Layoutdefs';
 909			}
 910			if(!file_exists($path)){
 911				mkdir_recursive($path, true);
 912			}
 913			copy_recursive($from , $path.'/'. basename($from));
 914	}
 915
 916    // Non-standard - needs special rebuild call
 917	function install_languages()
 918	{
 919        $languages = array();
 920        if(isset($this->installdefs['language']))
 921        {
 922            $this->log(translate('LBL_MI_IN_LANG') );
 923            foreach($this->installdefs['language'] as $packs)
 924            {
 925                $modules[]=$packs['to_module'];
 926                $languages[$packs['language']] = $packs['language'];
 927				$packs['from'] = str_replace('<basepath>', $this->base_dir, $packs['from']);
 928				$GLOBALS['log']->debug("Installing Language Pack ..." . $packs['from']  .  " for " .$packs['to_module']);
 929                $path = $this->getInstallLanguagesPath($packs);
 930                if (!file_exists(dirname($path))) {
 931                    mkdir_recursive(dirname($path), true);
 932                }
 933                copy_recursive($packs['from'], $path);
 934
 935			}
 936			$this->rebuild_languages($languages, $modules);
 937
 938		}
 939	}
 940
 941    /**
 942     * Function return path to file where store label
 943     * 
 944     * @param $packs
 945     * @return string
 946     */
 947    protected function getInstallLanguagesPath($packs)
 948    {
 949        $path = 'custom/Extension/modules/' . $packs['to_module']. '/Ext/Language';
 950        if($packs['to_module'] == 'application'){
 951            $path ='custom/Extension/' . $packs['to_module']. '/Ext/Language';
 952        }
 953        $path .= '/'.$packs['language'].'.'. $this->id_name . '.php';
 954        return $path;
 955    }
 956
 957    // Non-standard, needs special rebuild
 958	function uninstall_languages(){
 959        $languages = array();
 960				if(isset($this->installdefs['language'])){
 961					$this->log(translate('LBL_MI_UN_LANG') );
 962					foreach($this->installdefs['language'] as $packs){
 963						$modules[]=$packs['to_module'];
 964						$languages[$packs['language']] = $packs['language'];
 965						$packs['from'] = str_replace('<basepath>', $this->base_dir, $packs['from']);
 966						$GLOBALS['log']->debug("Uninstalling Language Pack ..." . $packs['from']  .  " for " .$packs['to_module']);
 967						$path = 'custom/Extension/modules/' . $packs['to_module']. '/Ext/Language';
 968						if($packs['to_module'] == 'application'){
 969							$path ='custom/Extension/' . $packs['to_module']. '/Ext/Language';
 970						}
 971						if (sugar_is_file($path.'/'.$packs['language'].'.'. $this->id_name . '.php', 'w')) {
 972							rmdir_recursive( $path.'/'.$packs['language'].'.'. $this->id_name . '.php');
 973						} else if (sugar_is_file($path.'/'.DISABLED_PATH.'/'.$packs['language'].'.'. $this->id_name . '.php', 'w')) {
 974							rmdir_recursive($path.'/'.DISABLED_PATH.'/'.$packs['language'].'.'. $this->id_name . '.php', 'w');
 975						}
 976					}
 977					$this->rebuild_languages($languages, $modules);
 978
 979				}
 980	}
 981
 982    // Non-standard, needs special rebuild
 983	public function disable_languages()
 984	{
 985		if(isset($this->installdefs['language'])) {
 986		    $languages = $modules = array();
 987			foreach($this->installdefs['language'] as $item) {
 988				$from = str_replace('<basepath>', $this->base_dir, $item['from']);
 989				$GLOBALS['log']->debug("Disabling Language {$item['language']}... from $from for " .$item['to_module']);
 990				$modules[]=$item['to_module'];
 991				$languages[$item['language']] = $item['language'];
 992				if($item['to_module'] == 'application') {
 993                    $path = "custom/Extension/application/Ext/Language";
 994                } else {
 995				    $path = "custom/Extension/modules/{$item['to_module']}/Ext/Language";
 996                }
 997				if(isset($item["name"])) {
 998				    $target = $item["name"];
 999				} else {
1000				    $target = $this->id_name;
1001				}
1002				$target = "{$item['language']}.$target";
1003
1004				$disabled_path = $path.'/'.DISABLED_PATH;
1005                if (file_exists("$path/$target.php")) {
1006					mkdir_recursive($disabled_path, true);
1007					rename("$path/$target.php", "$disabled_path/$target.php");
1008				} else if (file_exists($path . '/'. basename($from))) {
1009					mkdir_recursive($disabled_path, true);
1010				    rename( $path . '/'. basename($from), $disabled_path.'/'. basename($from));
1011				}
1012			}
1013			$this->rebuild_languages($languages, $modules);
1014		}
1015	}
1016
1017    // Non-standard, needs special rebuild
1018	public function enable_languages()
1019	{
1020		if(isset($this->installdefs['language'])) {
1021			foreach($this->installdefs['language'] as $item) {
1022				$from = str_replace('<basepath>', $this->base_dir, $item['from']);
1023				$GLOBALS['log']->debug("Enabling Language {$item['language']}... from $from for " .$item['to_module']);
1024				$modules[]=$item['to_module'];
1025				$languages[$item['language']] = $item['language'];
1026				if(!empty($module)) {
1027				    $item['to_module'] = $module;
1028				}
1029
1030                if($item['to_module'] == 'application') {
1031                    $path = "custom/Extension/application/Ext/Language";
1032                } else {
1033				    $path = "custom/Extension/modules/{$item['to_module']}/Ext/Language";
1034                }
1035				if(isset($item["name"])) {
1036				    $target = $item["name"];
1037				} else {
1038				    $target = $this->id_name;
1039				}
1040				$target = "{$item['language']}.$target";
1041
1042				if(!file_exists($path)) {
1043				    mkdir_recursive($path, true);
1044				}
1045                $disabled_path = $path.'/'.DISABLED_PATH;
1046				if (file_exists("$disabled_path/$target.php")) {
1047					rename("$disabled_path/$target.php",  "$path/$target.php");
1048				}
1049				if (file_exists($disabled_path . '/'. basename($from))) {
1050					rename($disabled_path.'/'. basename($from),  $path . '/'. basename($from));
1051				}
1052			}
1053			$this->rebuild_languages($languages, $modules);
1054		}
1055    }
1056
1057    // Functions for adding and removing logic hooks from uploaded files
1058    // Since one class/file can be used by multiple logic hooks, I'm not going to touch the file labeled in the logic_hook entry
1059    /* The module hook definition should look like this:
1060     $installdefs = array(
1061     ... blah blah ...
1062         'logic_hooks' => array(
1063             array('module'      => 'Accounts',
1064                   'hook'        => 'after_save',
1065                   'order'       => 99,
1066                   'description' => 'Account sample logic hook',
1067                   'file'        => 'modules/Sample/sample_account_logic_hook_file.php',
1068                   'class'       => 'SampleLogicClass',
1069                   'function'    => 'accountAfterSave',
1070             ),
1071         ),
1072     ... blah blah ...
1073     );
1074     */
1075    function enable_manifest_logichooks() {
1076        if(empty($this->installdefs['logic_hooks']) || !is_array($this->installdefs['logic_hooks'])) {
1077           return;
1078        }
1079
1080
1081
1082        foreach($this->installdefs['logic_hooks'] as $hook ) {
1083            check_logic_hook_file($hook['module'], $hook['hook'], array($hook['order'], $hook['description'],  $hook['file'], $hook['class'], $hook['function']));
1084        }
1085    }
1086
1087    function disable_manifest_logichooks() {
1088        if(empty($this->installdefs['logic_hooks']) || !is_array($this->installdefs['logic_hooks'])) {
1089            return;
1090        }
1091
1092        foreach($this->installdefs['logic_hooks'] as $hook ) {
1093            remove_logic_hook($hook['module'], $hook['hook'], array($hook['order'], $hook['description'],  $hook['file'], $hook['class'], $hook['function']));
1094        }
1095    }
1096
1097    /**
1098     * Check labels inside label files and remove them
1099     * 
1100     * @param $basePath - path to files with labels
1101     * @param array $labelDefinitions - format like output from AbstractRelationship buildLabels()
1102     */
1103    public function uninstallLabels($basePath, $labelDefinitions)
1104    {
1105
1106        foreach ($labelDefinitions as $definition) {
1107
1108            $filename = $basePath . "{$definition['module']}.php";
1109
1110            if (!file_exists($filename)) {
1111                continue;
1112            }
1113
1114            $uninstalLabes = $this->getLabelsToUninstall($labelDefinitions);
1115            $this->uninstallLabel($uninstalLabes, $definition, $filename);
1116        }
1117
1118    }
1119
1120    /**
1121     * Check labels inside label file and remove them
1122     * 
1123     * @param $uninstalLabes
1124     * @param $definition
1125     * @param $filename
1126     */
1127    protected function uninstallLabel($uninstalLabes, $definition, $filename)
1128    {
1129        $app_list_strings = array();
1130        $mod_strings = array();
1131        $stringsName = $definition['module'] == 'application' ? 'app_list_strings' : 'mod_strings';
1132
1133        include($filename);
1134        if ('app_list_strings' == $stringsName) {
1135            $strings = $app_list_strings;
1136        } else {
1137            $strings = $mod_strings;
1138        }
1139
1140        foreach ($uninstalLabes AS $label) {
1141            if (isset($strings[$label])) {
1142                unset($strings[$label]);
1143            }
1144        }
1145
1146        if (count($strings)) {
1147            $this->saveContentToFile($filename, $stringsName, $strings);
1148        } else {
1149            unlink($filename);
1150        }
1151    }
1152
1153    /**
1154     * Save labels that not need be uninstalled at this case
1155     * 
1156     * @param $filename
1157     * @param $stringsName
1158     * @param $strings
1159     */
1160    protected function saveContentToFile($filename, $stringsName, $strings)
1161    {
1162        $fileContent = "<?php\n//THIS FILE IS AUTO GENERATED, DO NOT MODIFY\n";
1163        foreach ($strings as $key => $val) {
1164            $fileContent .= override_value_to_string_recursive2($stringsName, $key, $val);
1165        }
1166        sugar_file_put_contents($filename, $fileContent);
1167    }
1168
1169    /**
1170     * Uninstall extend labels
1171     * 
1172     * @param $labelDefinitions
1173     */
1174    public function uninstallExtLabels($labelDefinitions)
1175    {
1176        foreach ($labelDefinitions as $definition) {
1177            if (!isset($GLOBALS['sugar_config']['languages']) || !is_array($GLOBALS['sugar_config']['languages'])) {
1178                continue;
1179            }
1180            
1181            foreach (array_keys($GLOBALS['sugar_config']['languages']) AS $language) {
1182                $pathDef = array(
1183                    'language' => $language,
1184                    'to_module' => $definition['module']
1185                );
1186                $path = $this->getInstallLanguagesPath($pathDef);
1187                if (file_exists($path)) {
1188                    unlink($path);
1189                }
1190            }
1191        }
1192
1193    }
1194
1195    /**
1196     * Returns the names of the label(key 'system_label') from a multi-dimensional array $labelDefinitions
1197     * 
1198     * @param $labelDefinitions
1199     * @return array of labels
1200     */
1201    protected function getLabelsToUninstall($labelDefinitions)
1202    {
1203        $labels = array();
1204        foreach($labelDefinitions AS $definition){
1205            $labels[] = $definition['system_label'];
1206        }
1207        return $labels;
1208    }
1209
1210/* BEGIN - RESTORE POINT - by MR. MILK August 31, 2005 02:22:18 PM */
1211	function copy_path($from, $to, $backup_path='', $uninstall=false){
1212	//function copy_path($from, $to){
1213/* END - RESTORE POINT - by MR. MILK August 31, 2005 02:22:18 PM */
1214		$to = str_replace('<basepath>', $this->base_dir, $to);
1215
1216		if(!$uninstall) {
1217		$from = str_replace('<basepath>', $this->base_dir, $from);
1218		$GLOBALS['log']->debug('Copy ' . $from);
1219		}
1220		else {
1221			$from = str_replace('<basepath>', $backup_path, $from);
1222			//$GLOBALS['log']->debug('Restore ' . $from);
1223		}
1224		$from = clean_path($from);
1225		$to = clean_path($to);
1226
1227		$dir = dirname($to);
1228		//there are cases where if we need to create a directory in the root directory
1229		if($dir == '.' && is_dir($from)){
1230			$dir = $to;
1231		}
1232		if(!sugar_is_dir($dir, 'instance'))
1233			mkdir_recursive($dir, true);
1234/* BEGIN - RESTORE POINT - by MR. MILK August 31, 2005 02:22:18 PM */
1235		if(empty($backup_path)) {
1236/* END - RESTORE POINT - by MR. MILK August 31, 2005 02:22:18 PM */
1237		if(!copy_recursive($from, $to)){
1238			die('Failed to copy ' . $from. ' ' . $to);
1239		}
1240/* BEGIN - RESTORE POINT - by MR. MILK August 31, 2005 02:22:18 PM */
1241		}
1242		elseif(!$this->copy_recursive_with_backup($from, $to, $backup_path, $uninstall)){
1243			die('Failed to copy ' . $from. ' to ' . $to);
1244		}
1245/* END - RESTORE POINT - by MR. MILK August 31, 2005 02:22:18 PM */
1246	}
1247
1248	function install_custom_fields($fields){
1249		global $beanList, $beanFiles;
1250		include('include/modules.php');
1251		require_once('modules/DynamicFields/FieldCases.php');
1252		foreach($fields as $field){
1253			$installed = false;
1254			if(isset($beanList[ $field['module']])){
1255				$class = $beanList[ $field['module']];
1256                if(!isset($field['ext4']))$field['ext4'] = '';
1257                if(!isset($field['mass_update']))$field['mass_update'] = 0;
1258                if(!isset($field['duplicate_merge']))$field['duplicate_merge'] = 0;
1259                if(!isset($field['help']))$field['help'] = '';
1260
1261                //Merge contents of the sugar field extension if we copied one over
1262                if (file_exists("custom/Extension/modules/{$field['module']}/Ext/Vardefs/sugarfield_{$field['name']}.php"))
1263                {
1264                    $dictionary = array();
1265                    include ("custom/Extension/modules/{$field['module']}/Ext/Vardefs/sugarfield_{$field['name']}.php");
1266                    $obj = BeanFactory::getObjectName($field['module']);
1267                    if (!empty($dictionary[$obj]['fields'][$field['name']])) {
1268                        $field = array_merge($dictionary[$obj]['fields'][$field['name']], $field);
1269                    }
1270                }
1271
1272                if(file_exists($beanFiles[$class])){
1273					require_once($beanFiles[$class]);
1274					$mod = new $class();
1275					$installed = true;
1276					$fieldObject = get_widget($field['type']);
1277					$fieldObject->populateFromRow($field);
1278					$mod->custom_fields->use_existing_labels =  true;
1279					$mod->custom_fields->addFieldObject($fieldObject);
1280				}
1281			}
1282			if(!$installed){
1283				$GLOBALS['log']->debug('Could not install custom field ' . $field['name'] . ' for module ' .  $field['module'] . ': Module does not exist');
1284			}
1285		}
1286	}
1287
1288	function uninstall_custom_fields($fields){
1289		global $beanList, $beanFiles;
1290		require_once('modules/DynamicFields/DynamicField.php');
1291		$dyField = new DynamicField();
1292
1293		foreach($fields as $field){
1294			$class = $beanList[ $field['module']];
1295			if(file_exists($beanFiles[$class])){
1296					require_once($beanFiles[$class]);
1297					$mod = new $class();
1298					$dyField->bean = $mod;
1299					$dyField->module = $field['module'];
1300					$dyField->deleteField($field['name']);
1301			}
1302		}
1303	}
1304
1305        /*
1306     * ModuleInstaller->install_relationships calls install_relationship for every file included in the module package that defines a relationship, and then
1307     * writes a custom/Extension/application/Ext/TableDictionary/$module.php file containing an include_once for every relationship metadata file passed to install_relationship.
1308     * Next it calls install_vardef and install_layoutdef. Finally, it rebuilds the vardefs and layoutdefs (by calling merge_files as usual), and then calls merge_files to merge
1309     * everything in 'Ext/TableDictionary/' into 'tabledictionary.ext.php'
1310     */
1311    function install_relationships ()
1312    {
1313        if (isset ( $this->installdefs [ 'relationships' ] ))
1314        {
1315            $this->log ( translate ( 'LBL_MI_IN_RELATIONSHIPS' ) ) ;
1316            $str = "<?php \n //WARNING: The contents of this file are auto-generated\n" ;
1317            $sav…

Large files files are truncated, but you can click here to view the full file