PageRenderTime 63ms CodeModel.GetById 3ms app.highlight 47ms RepoModel.GetById 1ms app.codeStats 1ms

/SugarCRM/ModuleInstall/ModuleInstaller.php

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

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