PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/ModuleInstall/ModuleInstaller.php

https://github.com/BarnetikKoop/SuiteCRM
PHP | 2546 lines | 1987 code | 225 blank | 334 comment | 458 complexity | ea9d046088e06d216acdbccf520bc2de MD5 | raw file
Possible License(s): AGPL-3.0, LGPL-2.1, MPL-2.0-no-copyleft-exception

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

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

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