3 /*********************************************************************************
4 * SugarCRM is a customer relationship management program developed by
5 * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
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.
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
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
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.
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.
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 ********************************************************************************/
39 //////////////////////////////////////////////////////////////////////////////////////////
40 //// This is a stand alone file that can be run from the command prompt for upgrading a
41 //// Sugar Instance. Three parameters are required to be defined in order to execute this file.
42 //// php.exe -f silentUpgrade.php [Path to Upgrade Package zip] [Path to Log file] [Path to Instance]
43 //// See below the Usage for more details.
44 /////////////////////////////////////////////////////////////////////////////////////////
45 ini_set('memory_limit',-1);
46 ///////////////////////////////////////////////////////////////////////////////
47 //// UTILITIES THAT MUST BE LOCAL :(
48 function prepSystemForUpgradeSilent() {
53 // make sure dirs exist
54 foreach($subdirs as $subdir) {
55 if(!is_dir(clean_path("{$cwd}/{$sugar_config['upload_dir']}upgrades/{$subdir}"))) {
56 mkdir_recursive(clean_path("{$cwd}/{$sugar_config['upload_dir']}upgrades/{$subdir}"));
61 //local function for clearing cache
62 function clearCacheSU($thedir, $extension) {
63 if ($current = @opendir($thedir)) {
64 while (false !== ($children = readdir($current))) {
65 if ($children != "." && $children != "..") {
66 if (is_dir($thedir . "/" . $children)) {
67 clearCacheSU($thedir . "/" . $children, $extension);
69 elseif (is_file($thedir . "/" . $children) && substr_count($children, $extension)) {
70 unlink($thedir . "/" . $children);
76 //Bug 24890, 24892. default_permissions not written to config.php. Following function checks and if
77 //no found then adds default_permissions to the config file.
78 function checkConfigForPermissions(){
79 if(file_exists(getcwd().'/config.php')){
80 require(getcwd().'/config.php');
83 if(!isset($sugar_config['default_permissions'])){
84 $sugar_config['default_permissions'] = array (
91 if(is_writable('config.php') && write_array_to_file("sugar_config", $sugar_config,'config.php')) {
96 function checkLoggerSettings(){
97 if(file_exists(getcwd().'/config.php')){
98 require(getcwd().'/config.php');
100 global $sugar_config;
101 if(!isset($sugar_config['logger'])){
102 $sugar_config['logger'] =array (
107 'name' => 'sugarcrm',
108 'dateFormat' => '%c',
114 ksort($sugar_config);
115 if(is_writable('config.php') && write_array_to_file("sugar_config", $sugar_config,'config.php')) {
116 //writing to the file
121 function checkResourceSettings(){
122 if(file_exists(getcwd().'/config.php')){
123 require(getcwd().'/config.php');
125 global $sugar_config;
126 if(!isset($sugar_config['resource_management'])){
127 $sugar_config['resource_management'] =
129 'special_query_limit' => 50000,
130 'special_query_modules' =>
135 3 => 'Administration',
138 'default_limit' => 1000,
140 ksort($sugar_config);
141 if(is_writable('config.php') && write_array_to_file("sugar_config", $sugar_config,'config.php')) {
142 //writing to the file
148 //rebuild all relationships...
149 function rebuildRelations($pre_path = ''){
150 $_REQUEST['silent'] = true;
151 include($pre_path.'modules/Administration/RebuildRelationship.php');
152 $_REQUEST['upgradeWizard'] = true;
153 include($pre_path.'modules/ACL/install_actions.php');
156 function createMissingRels(){
157 $relForObjects = array('leads'=>'Leads','campaigns'=>'Campaigns','prospects'=>'Prospects');
158 foreach($relForObjects as $relObjName=>$relModName){
160 $guid = create_guid();
161 $query = "SELECT id FROM relationships WHERE relationship_name = '{$relObjName}_assigned_user'";
162 $result= $GLOBALS['db']->query($query, true);
164 $a = $GLOBALS['db']->fetchByAssoc($result);
165 if($GLOBALS['db']->checkError()){
168 if(!isset($a['id']) && empty($a['id']) ){
169 $qRel = "INSERT INTO relationships (id,relationship_name, lhs_module, lhs_table, lhs_key, rhs_module, rhs_table, rhs_key, join_table, join_key_lhs, join_key_rhs, relationship_type, relationship_role_column, relationship_role_column_value, reverse, deleted)
170 VALUES ('{$guid}', '{$relObjName}_assigned_user','Users','users','id','{$relModName}','{$relObjName}','assigned_user_id',NULL,NULL,NULL,'one-to-many',NULL,NULL,'0','0')";
171 $GLOBALS['db']->query($qRel);
172 if($GLOBALS['db']->checkError()){
177 $guid = create_guid();
178 $query = "SELECT id FROM relationships WHERE relationship_name = '{$relObjName}_modified_user'";
179 $result= $GLOBALS['db']->query($query, true);
180 if($GLOBALS['db']->checkError()){
184 $a = $GLOBALS['db']->fetchByAssoc($result);
185 if(!isset($a['id']) && empty($a['id']) ){
186 $qRel = "INSERT INTO relationships (id,relationship_name, lhs_module, lhs_table, lhs_key, rhs_module, rhs_table, rhs_key, join_table, join_key_lhs, join_key_rhs, relationship_type, relationship_role_column, relationship_role_column_value, reverse, deleted)
187 VALUES ('{$guid}', '{$relObjName}_modified_user','Users','users','id','{$relModName}','{$relObjName}','modified_user_id',NULL,NULL,NULL,'one-to-many',NULL,NULL,'0','0')";
188 $GLOBALS['db']->query($qRel);
189 if($GLOBALS['db']->checkError()){
194 $guid = create_guid();
195 $query = "SELECT id FROM relationships WHERE relationship_name = '{$relObjName}_created_by'";
196 $result= $GLOBALS['db']->query($query, true);
198 $a = $GLOBALS['db']->fetchByAssoc($result);
199 if(!isset($a['id']) && empty($a['id']) ){
200 $qRel = "INSERT INTO relationships (id,relationship_name, lhs_module, lhs_table, lhs_key, rhs_module, rhs_table, rhs_key, join_table, join_key_lhs, join_key_rhs, relationship_type, relationship_role_column, relationship_role_column_value, reverse, deleted)
201 VALUES ('{$guid}', '{$relObjName}_created_by','Users','users','id','{$relModName}','{$relObjName}','created_by',NULL,NULL,NULL,'one-to-many',NULL,NULL,'0','0')";
202 $GLOBALS['db']->query($qRel);
203 if($GLOBALS['db']->checkError()){
207 $guid = create_guid();
208 $query = "SELECT id FROM relationships WHERE relationship_name = '{$relObjName}_team'";
209 $result= $GLOBALS['db']->query($query, true);
211 $a = $GLOBALS['db']->fetchByAssoc($result);
212 if(!isset($a['id']) && empty($a['id']) ){
213 $qRel = "INSERT INTO relationships (id,relationship_name, lhs_module, lhs_table, lhs_key, rhs_module, rhs_table, rhs_key, join_table, join_key_lhs, join_key_rhs, relationship_type, relationship_role_column, relationship_role_column_value, reverse, deleted)
214 VALUES ('{$guid}', '{$relObjName}_team','Teams','teams','id','{$relModName}','{$relObjName}','team_id',NULL,NULL,NULL,'one-to-many',NULL,NULL,'0','0')";
215 $GLOBALS['db']->query($qRel);
216 if($GLOBALS['db']->checkError()){
222 //Also add tracker perf relationship
223 $guid = create_guid();
224 $query = "SELECT id FROM relationships WHERE relationship_name = 'tracker_monitor_id'";
225 $result= $GLOBALS['db']->query($query, true);
226 if($GLOBALS['db']->checkError()){
230 $a = $GLOBALS['db']->fetchByAssoc($result);
231 if($GLOBALS['db']->checkError()){
234 if(!isset($a['id']) && empty($a['id']) ){
235 $qRel = "INSERT INTO relationships (id,relationship_name, lhs_module, lhs_table, lhs_key, rhs_module, rhs_table, rhs_key, join_table, join_key_lhs, join_key_rhs, relationship_type, relationship_role_column, relationship_role_column_value, reverse, deleted)
236 VALUES ('{$guid}', 'tracker_monitor_id','TrackerPerfs','tracker_perf','monitor_id','Trackers','tracker','monitor_id',NULL,NULL,NULL,'one-to-many',NULL,NULL,'0','0')";
237 $GLOBALS['db']->query($qRel);
238 if($GLOBALS['db']->checkError()){
246 * This function will merge password default settings into config file
247 * @param $sugar_config
248 * @param $sugar_version
249 * @return bool true if successful
251 function merge_passwordsetting($sugar_config, $sugar_version) {
253 $passwordsetting_defaults = array (
254 'passwordsetting' => array (
255 'minpwdlength' => '',
256 'maxpwdlength' => '',
261 'SystemGeneratedPasswordON' => '',
262 'generatepasswordtmpl' => '',
263 'lostpasswordtmpl' => '',
265 'regexcomment' => '',
266 'forgotpasswordON' => false,
267 'linkexpiration' => '1',
268 'linkexpirationtime' => '30',
269 'linkexpirationtype' => '1',
270 'userexpiration' => '0',
271 'userexpirationtime' => '',
272 'userexpirationtype' => '1',
273 'userexpirationlogin' => '',
274 'systexpiration' => '0',
275 'systexpirationtime' => '',
276 'systexpirationtype' => '0',
277 'systexpirationlogin' => '',
278 'lockoutexpiration' => '0',
279 'lockoutexpirationtime' => '',
280 'lockoutexpirationtype' => '1',
281 'lockoutexpirationlogin' => '',
285 $sugar_config = sugarArrayMerge($passwordsetting_defaults, $sugar_config );
287 // need to override version with default no matter what
288 $sugar_config['sugar_version'] = $sugar_version;
290 ksort( $sugar_config );
292 if( write_array_to_file( "sugar_config", $sugar_config, "config.php" ) ){
300 function addDefaultModuleRoles($defaultRoles = array()) {
301 foreach($defaultRoles as $roleName=>$role){
302 foreach($role as $category=>$actions){
303 foreach($actions as $name=>$access_override){
304 $query = "SELECT * FROM acl_actions WHERE name='$name' AND category = '$category' AND acltype='$roleName' AND deleted=0 ";
305 $result = $GLOBALS['db']->query($query);
306 //only add if an action with that name and category don't exist
307 $row=$GLOBALS['db']->fetchByAssoc($result);
309 $guid = create_guid();
310 $currdate = gmdate($GLOBALS['timedate']->get_db_date_time_format());
311 $query= "INSERT INTO acl_actions (id,date_entered,date_modified,modified_user_id,name,category,acltype,aclaccess,deleted ) VALUES ('$guid','$currdate','$currdate','1','$name','$category','$roleName','$access_override','0')";
312 $GLOBALS['db']->query($query);
313 if($GLOBALS['db']->checkError()){
322 function verifyArguments($argv,$usage_dce,$usage_regular){
324 $cwd = getcwd(); // default to current, assumed to be in a valid SugarCRM root dir.
325 if(isset($argv[3])) {
326 if(is_dir($argv[3])) {
330 echo "*******************************************************************************\n";
331 echo "*** ERROR: 3rd parameter must be a valid directory. Tried to cd to [ {$argv[3]} ].\n";
336 //check if this is an instance
337 if(is_file("{$cwd}/ini_setup.php")){
338 // this is an instance
339 $upgradeType = constant('DCE_INSTANCE');
340 //now that this is dce instance we want to make sure that there are
342 if(count($argv) < 7) {
343 echo "*******************************************************************************\n";
344 echo "*** ERROR: Missing required parameters. Received ".count($argv)." argument(s), require 7.\n";
349 // this is an instance
350 if(!is_dir($argv[1])) { // valid directory . template path?
351 echo "*******************************************************************************\n";
352 echo "*** ERROR: First argument must be a full path to the template. Got [ {$argv[1]} ].\n";
358 else if(is_file("{$cwd}/include/entryPoint.php")) {
359 //this should be a regular sugar install
360 $upgradeType = constant('SUGARCRM_INSTALL');
361 //check if this is a valid zip file
362 if(!is_file($argv[1])) { // valid zip?
363 echo "*******************************************************************************\n";
364 echo "*** ERROR: First argument must be a full path to the patch file. Got [ {$argv[1]} ].\n";
369 if(count($argv) < 5) {
370 echo "*******************************************************************************\n";
371 echo "*** ERROR: Missing required parameters. Received ".count($argv)." argument(s), require 5.\n";
378 //this should be a regular sugar install
379 echo "*******************************************************************************\n";
380 echo "*** ERROR: Tried to execute in a non-SugarCRM root directory.\n";
384 if(isset($argv[7]) && file_exists($argv[7].'SugarTemplateUtilties.php')){
385 require_once($argv[7].'SugarTemplateUtilties.php');
391 function upgradeDCEFiles($argv,$instanceUpgradePath){
392 //copy and update following files from upgrade package
393 $upgradeTheseFiles = array('cron.php','download.php','index.php','install.php','soap.php','sugar_version.php','vcal_server.php');
394 foreach($upgradeTheseFiles as $file){
395 $srcFile = clean_path("{$instanceUpgradePath}/$file");
396 $destFile = clean_path("{$argv[3]}/$file");
397 if(file_exists($srcFile)){
398 if(!is_dir(dirname($destFile))) {
399 mkdir_recursive(dirname($destFile)); // make sure the directory exists
401 copy_recursive($srcFile,$destFile);
402 $_GET['TEMPLATE_PATH'] = $destFile;
403 $_GET['CONVERT_FILE_ONLY'] = true;
404 if(!class_exists('TemplateConverter')){
405 include($argv[7].'templateConverter.php');
407 TemplateConverter::convertFile($_GET['TEMPLATE_PATH']);
417 function threeWayMerge(){
418 //using threeway merge apis
421 //// END UTILITIES THAT MUST BE LOCAL :(
422 ///////////////////////////////////////////////////////////////////////////////
425 // only run from command line
426 if(isset($_SERVER['HTTP_USER_AGENT'])) {
427 fwrite(STDERR,'This utility may only be run from the command line or command prompt.');
430 //Clean_string cleans out any file passed in as a parameter
431 $_SERVER['PHP_SELF'] = 'silentUpgrade.php';
434 ///////////////////////////////////////////////////////////////////////////////
437 Usage: php.exe -f silentUpgrade.php [upgradeZipFile] [logFile] [pathToSugarInstance]
439 On Command Prompt Change directory to where silentUpgrade.php resides. Then type path to
440 php.exe followed by -f silentUpgrade.php and the arguments.
443 [path-to-PHP/]php.exe -f silentUpgrade.php [path-to-upgrade-package/]SugarEnt-Upgrade-4.5.1-to-5.0.0b.zip [path-to-log-file/]silentupgrade.log [path-to-sugar-instance/]Sugar451e
444 [Old Template path] [skipdbupgrade] [exitOrContinue]
447 New Template Path or Upgrade Package : Upgrade package name. Template2 (upgrade to)location.
448 silentupgrade.log : Silent Upgarde log file.
449 Sugar451e/DCE : Sugar or DCE Instance instance being upgraded.
450 Old Template path : Template1 (upgrade from) Instance is being upgraded.
451 skipDBupgrade : If set to Yes then silentupgrade will only upgrade files. Default is No.
452 exitOnConflicts : If set to No and conflicts are found then Upgrade continues. Default Yes.
453 pathToDCEClient : This is path to to DCEClient directory
457 $usage_regular =<<<eoq2
458 Usage: php.exe -f silentUpgrade.php [upgradeZipFile] [logFile] [pathToSugarInstance] [admin-user]
460 On Command Prompt Change directory to where silentUpgrade.php resides. Then type path to
461 php.exe followed by -f silentUpgrade.php and the arguments.
464 [path-to-PHP/]php.exe -f silentUpgrade.php [path-to-upgrade-package/]SugarEnt-Upgrade-5.2.0-to-5.5.0.zip [path-to-log-file/]silentupgrade.log [path-to-sugar-instance/] admin
467 upgradeZipFile : Upgrade package file.
468 logFile : Silent Upgarde log file.
469 pathToSugarInstance : Sugar Instance instance being upgraded.
470 admin-user : admin user performing the upgrade
473 ///////////////////////////////////////////////////////////////////////////////
477 ///////////////////////////////////////////////////////////////////////////////
478 //// STANDARD REQUIRED SUGAR INCLUDES AND PRESETS
479 if(!defined('sugarEntry')) define('sugarEntry', true);
482 $_SESSION['schema_change'] = 'sugar'; // we force-run all SQL
483 $_SESSION['silent_upgrade'] = true;
484 $_SESSION['step'] = 'silent'; // flag to NOT try redirect to 4.5.x upgrade wizard
487 $_REQUEST['addTaskReminder'] = 'remind';
490 define('SUGARCRM_INSTALL', 'SugarCRM_Install');
491 define('DCE_INSTANCE', 'DCE_Instance');
494 $cwd = getcwd(); // default to current, assumed to be in a valid SugarCRM root dir.
496 $upgradeType = verifyArguments($argv,$usage_dce,$usage_regular);
498 ///////////////////////////////////////////////////////////////////////////////
499 ////// Verify that all the arguments are appropriately placed////////////////
501 ///////////////////////////////////////////////////////////////////////////////
502 //// PREP LOCALLY USED PASSED-IN VARS & CONSTANTS
503 //$GLOBALS['log'] = LoggerManager::getLogger('SugarCRM');
504 //require_once('/var/www/html/eddy/sugarnode/SugarTemplateUtilities.php');
506 $path = $argv[2]; // custom log file, if blank will use ./upgradeWizard.log
507 //$db = &DBManagerFactory::getInstance(); //<---------
510 //$UWstrings = return_module_language('en_us', 'UpgradeWizard');
511 //$adminStrings = return_module_language('en_us', 'Administration');
512 //$mod_strings = array_merge($adminStrings, $UWstrings);
513 $subdirs = array('full', 'langpack', 'module', 'patch', 'theme', 'temp');
515 //$_REQUEST['zip_from_dir'] = $zip_from_dir;
517 define('SUGARCRM_PRE_INSTALL_FILE', 'scripts/pre_install.php');
518 define('SUGARCRM_POST_INSTALL_FILE', 'scripts/post_install.php');
519 define('SUGARCRM_PRE_UNINSTALL_FILE', 'scripts/pre_uninstall.php');
520 define('SUGARCRM_POST_UNINSTALL_FILE', 'scripts/post_uninstall.php');
525 echo "********************************************************************\n";
526 echo "***************This Upgrade process may take sometime***************\n";
527 echo "********************************************************************\n";
530 global $sugar_config;
531 $isDCEInstance = false;
535 if($upgradeType != constant('DCE_INSTANCE')) {
537 ini_set('error_reporting',1);
538 require_once('include/entryPoint.php');
539 require_once('include/SugarLogger/SugarLogger.php');
540 require_once('include/utils/zip_utils.php');
544 require('config.php');
545 //require_once('modules/UpgradeWizard/uw_utils.php'); // must upgrade UW first
546 if(isset($argv[3])) {
547 if(is_dir($argv[3])) {
553 require_once("{$cwd}/sugar_version.php"); // provides $sugar_version & $sugar_flavor
555 $GLOBALS['log'] = LoggerManager::getLogger('SugarCRM');
556 $patchName = basename($argv[1]);
557 $zip_from_dir = substr($patchName, 0, strlen($patchName) - 4); // patch folder name (minus ".zip")
558 $path = $argv[2]; // custom log file, if blank will use ./upgradeWizard.log
560 if($sugar_version < '5.1.0'){
561 $db = &DBManager :: getInstance();
564 $db = &DBManagerFactory::getInstance();
566 $UWstrings = return_module_language('en_us', 'UpgradeWizard');
567 $adminStrings = return_module_language('en_us', 'Administration');
568 $mod_strings = array_merge($adminStrings, $UWstrings);
569 $subdirs = array('full', 'langpack', 'module', 'patch', 'theme', 'temp');
571 $license_accepted = false;
572 if(isset($argv[5]) && (strtolower($argv[5])=='yes' || strtolower($argv[5])=='y')){
573 $license_accepted = true;
575 //////////////////////////////////////////////////////////////////////////////
576 //Adding admin user to the silent upgrade
578 $current_user = new User();
579 if(isset($argv[4])) {
580 //if being used for internal upgrades avoid admin user verification
581 $user_name = $argv[4];
582 $q = "select id from users where user_name = '" . $user_name . "' and is_admin=1";
583 $result = $GLOBALS['db']->query($q, false);
584 $logged_user = $GLOBALS['db']->fetchByAssoc($result);
585 if(isset($logged_user['id']) && $logged_user['id'] != null){
587 $current_user->retrieve($logged_user['id']);
590 echo "FAILURE: Not an admin user in users table. Please provide an admin user\n";
595 echo "*******************************************************************************\n";
596 echo "*** ERROR: 4th parameter must be a valid admin user.\n";
603 /////retrieve admin user
604 global $sugar_config;
605 $configOptions = $sugar_config['dbconfig'];
608 ///////////////////////////////////////////////////////////////////////////////
610 prepSystemForUpgradeSilent();
613 $unzip_dir = clean_path("{$cwd}/{$sugar_config['upload_dir']}upgrades/temp");
614 $install_file = clean_path("{$cwd}/{$sugar_config['upload_dir']}upgrades/patch/".basename($argv[1]));
616 $_SESSION['unzip_dir'] = $unzip_dir;
617 $_SESSION['install_file'] = $install_file;
618 $_SESSION['zip_from_dir'] = $zip_from_dir;
619 if(is_dir($unzip_dir.'/scripts'))
621 rmdir_recursive($unzip_dir.'/scripts');
623 if(is_file($unzip_dir.'/manifest.php'))
625 rmdir_recursive($unzip_dir.'/manifest.php');
627 mkdir_recursive($unzip_dir);
628 if(!is_dir($unzip_dir)) {
629 fwrite(STDERR,"\n{$unzip_dir} is not an available directory\nFAILURE\n");
633 unzip($argv[1], $unzip_dir);
634 // mimic standard UW by copy patch zip to appropriate dir
635 copy($argv[1], $install_file);
636 //// END UPGRADE PREP
637 ///////////////////////////////////////////////////////////////////////////////
639 ///////////////////////////////////////////////////////////////////////////////
640 //// UPGRADE UPGRADEWIZARD
642 $zipBasePath = clean_path("{$cwd}/{$sugar_config['upload_dir']}upgrades/temp/{$zip_from_dir}");
643 $uwFiles = findAllFiles(clean_path("{$zipBasePath}/modules/UpgradeWizard"), array());
644 $destFiles = array();
646 foreach($uwFiles as $uwFile) {
647 $destFile = clean_path(str_replace($zipBasePath, $cwd, $uwFile));
648 copy($uwFile, $destFile);
650 require_once('modules/UpgradeWizard/uw_utils.php'); // must upgrade UW first
651 removeSilentUpgradeVarsCache(); // Clear the silent upgrade vars - Note: Any calls to these functions within this file are removed here
652 logThis("*** SILENT UPGRADE INITIATED.", $path);
653 logThis("*** UpgradeWizard Upgraded ", $path);
655 if(function_exists('set_upgrade_vars')){
659 if($configOptions['db_type'] == 'mysql'){
660 //Change the db wait_timeout for this session
661 $que ="select @@wait_timeout";
662 $result = $db->query($que);
663 $tb = $db->fetchByAssoc($result);
664 logThis('Wait Timeout before change ***** '.$tb['@@wait_timeout'] , $path);
665 $query ="set wait_timeout=28800";
667 $result = $db->query($que);
668 $ta = $db->fetchByAssoc($result);
669 logThis('Wait Timeout after change ***** '.$ta['@@wait_timeout'] , $path);
672 //// END UPGRADE UPGRADEWIZARD
673 ///////////////////////////////////////////////////////////////////////////////
675 ///////////////////////////////////////////////////////////////////////////////
676 //// MAKE SURE PATCH IS COMPATIBLE
677 if(is_file("{$cwd}/{$sugar_config['upload_dir']}upgrades/temp/manifest.php")) {
678 // provides $manifest array
679 include("{$cwd}/{$sugar_config['upload_dir']}upgrades/temp/manifest.php");
680 if(!isset($manifest)) {
681 fwrite(STDERR,"\nThe patch did not contain a proper manifest.php file. Cannot continue.\n\n");
684 copy("{$cwd}/{$sugar_config['upload_dir']}upgrades/temp/manifest.php", "{$cwd}/{$sugar_config['upload_dir']}upgrades/patch/{$zip_from_dir}-manifest.php");
686 $error = validate_manifest($manifest);
688 $error = strip_tags(br2nl($error));
689 fwrite(STDERR,"\n{$error}\n\nFAILURE\n");
694 fwrite(STDERR,"\nThe patch did not contain a proper manifest.php file. Cannot continue.\n\n");
698 $ce_to_pro_ent = isset($manifest['name']) && ($manifest['name'] == 'SugarCE to SugarPro' || $manifest['name'] == 'SugarCE to SugarEnt');
699 $_SESSION['upgrade_from_flavor'] = $manifest['name'];
701 global $sugar_config;
702 global $sugar_version;
703 global $sugar_flavor;
705 //// END MAKE SURE PATCH IS COMPATIBLE
706 ///////////////////////////////////////////////////////////////////////////////
708 ///////////////////////////////////////////////////////////////////////////////
709 //// RUN SILENT UPGRADE
712 if(file_exists('ModuleInstall/PackageManager/PackageManagerDisplay.php')) {
713 require_once('ModuleInstall/PackageManager/PackageManagerDisplay.php');
716 $parserFiles = array();
718 if(file_exists(clean_path("{$zipBasePath}/include/SugarFields"))) {
719 $parserFiles = findAllFiles(clean_path("{$zipBasePath}/include/SugarFields"), $parserFiles);
721 //$cwd = clean_path(getcwd());
722 foreach($parserFiles as $file) {
723 $srcFile = clean_path($file);
724 //$targetFile = clean_path(getcwd() . '/' . $srcFile);
725 if (strpos($srcFile,".svn") !== false) {
729 $targetFile = str_replace(clean_path($zipBasePath), $cwd, $srcFile);
731 if(!is_dir(dirname($targetFile))) {
732 mkdir_recursive(dirname($targetFile)); // make sure the directory exists
735 if(!file_exists($targetFile))
737 logThis('Copying file to destination: ' . $targetFile, $path);
738 if(!copy($srcFile, $targetFile)) {
739 logThis('*** ERROR: could not copy file: ' . $targetFile, $path);
741 $copiedFiles[] = $targetFile;
744 logThis('Skipping file: ' . $targetFile, $path);
745 //$skippedFiles[] = $targetFile;
749 //copy minimum required files including sugar_file_utils.php
750 if(file_exists("{$zipBasePath}/include/utils/sugar_file_utils.php")){
751 $destFile = clean_path(str_replace($zipBasePath, $cwd, "{$zipBasePath}/include/utils/sugar_file_utils.php"));
752 copy("{$zipBasePath}/include/utils/sugar_file_utils.php", $destFile);
754 if(file_exists('include/utils/sugar_file_utils.php')){
755 require_once('include/utils/sugar_file_utils.php');
759 $errors = preflightCheck();
760 if((count($errors) == 1)) { // only diffs
761 logThis('file preflight check passed successfully.', $path);
764 fwrite(STDERR,"\nThe user doesn't have sufficient permissions to write to database'.\n\n");
768 //If version less than 500 then look for modules to be upgraded
769 if(function_exists('set_upgrade_vars')){
772 //Initialize the session variables. If upgrade_progress.php is already created
773 //look for session vars there and restore them
774 if(function_exists('initialize_session_vars')){
775 initialize_session_vars();
778 if(!didThisStepRunBefore('preflight')){
779 set_upgrade_progress('preflight','in_progress');
780 //Quickcreatedefs on the basis of editviewdefs
781 if(substr($sugar_version,0,1) >= 5){
782 updateQuickCreateDefs();
784 set_upgrade_progress('preflight','done');
786 ////////////////COMMIT PROCESS BEGINS///////////////////////////////////////////////////////////////
787 //// MAKE BACKUPS OF TARGET FILES
789 if(!didThisStepRunBefore('commit')){
790 set_upgrade_progress('commit','in_progress','commit','in_progress');
791 if(!didThisStepRunBefore('commit','commitMakeBackupFiles')){
792 set_upgrade_progress('commit','in_progress','commitMakeBackupFiles','in_progress');
793 $errors = commitMakeBackupFiles($rest_dir, $install_file, $unzip_dir, $zip_from_dir, array());
794 set_upgrade_progress('commit','in_progress','commitMakeBackupFiles','done');
797 ///////////////////////////////////////////////////////////////////////////////
798 //// HANDLE PREINSTALL SCRIPTS
800 $file = "{$unzip_dir}/".constant('SUGARCRM_PRE_INSTALL_FILE');
804 if(!didThisStepRunBefore('commit','pre_install')){
805 set_upgrade_progress('commit','in_progress','pre_install','in_progress');
807 set_upgrade_progress('commit','in_progress','pre_install','done');
812 //Clean smarty from cache
813 if(is_dir($GLOBALS['sugar_config']['cache_dir'].'smarty')){
814 $allModFiles = array();
815 $allModFiles = findAllFiles($GLOBALS['sugar_config']['cache_dir'].'smarty',$allModFiles);
816 foreach($allModFiles as $file){
817 //$file_md5_ref = str_replace(clean_path(getcwd()),'',$file);
818 if(file_exists($file)){
824 //Also add the three-way merge here. The idea is after the 451 html files have
825 //been converted run the 3-way merge. If 500 then just run the 3-way merge
826 if(file_exists('modules/UpgradeWizard/SugarMerge/SugarMerge.php')){
827 set_upgrade_progress('end','in_progress','threewaymerge','in_progress');
828 require_once('modules/UpgradeWizard/SugarMerge/SugarMerge.php');
829 $merger = new SugarMerge($zipBasePath);
831 set_upgrade_progress('end','in_progress','threewaymerge','done');
833 ///////////////////////////////////////////////////////////////////////////////
834 //// COPY NEW FILES INTO TARGET INSTANCE
836 if(!didThisStepRunBefore('commit','commitCopyNewFiles')){
837 set_upgrade_progress('commit','in_progress','commitCopyNewFiles','in_progress');
838 $split = commitCopyNewFiles($unzip_dir, $zip_from_dir);
839 $copiedFiles = $split['copiedFiles'];
840 $skippedFiles = $split['skippedFiles'];
841 set_upgrade_progress('commit','in_progress','commitCopyNewFiles','done');
843 require_once(clean_path($unzip_dir.'/scripts/upgrade_utils.php'));
844 $new_sugar_version = getUpgradeVersion();
845 $origVersion = substr(preg_replace("/[^0-9]/", "", $sugar_version),0,3);
846 $destVersion = substr(preg_replace("/[^0-9]/", "", $new_sugar_version),0,3);
847 $siv_varset_1 = setSilentUpgradeVar('origVersion', $origVersion);
848 $siv_varset_2 = setSilentUpgradeVar('destVersion', $destVersion);
849 $siv_write = writeSilentUpgradeVars();
850 if(!$siv_varset_1 || !$siv_varset_2 || !$siv_write){
851 logThis("Error with silent upgrade variables: origVersion write success is ({$siv_varset_1}) ".
852 "-- destVersion write success is ({$siv_varset_2}) -- ".
853 "writeSilentUpgradeVars success is ({$siv_write}) -- ".
854 "path to cache dir is ({$GLOBALS['sugar_config']['cache_dir']})", $path);
856 require_once('modules/DynamicFields/templates/Fields/TemplateText.php');
857 ///////////////////////////////////////////////////////////////////////////////
858 /// RELOAD NEW DEFINITIONS
859 global $ACLActions, $beanList, $beanFiles;
860 include('modules/ACLActions/actiondefs.php');
861 include('include/modules.php');
862 /////////////////////////////////////////////
864 if (!function_exists("inDeveloperMode")) {
865 //this function was introduced from tokyo in the file include/utils.php, so when upgrading from 5.1x and 5.2x we should declare the this function
866 function inDeveloperMode()
868 return isset($GLOBALS['sugar_config']['developerMode']) && $GLOBALS['sugar_config']['developerMode'];
871 ///////////////////////////////////////////////////////////////////////////////
872 //// HANDLE POSTINSTALL SCRIPTS
874 logThis('Starting post_install()...', $path);
876 $trackerManager = TrackerManager::getInstance();
877 $trackerManager->pause();
878 $trackerManager->unsetMonitors();
880 if(!didThisStepRunBefore('commit','post_install')){
881 $file = "$unzip_dir/" . constant('SUGARCRM_POST_INSTALL_FILE');
883 //set_upgrade_progress('commit','in_progress','post_install','in_progress');
884 $progArray['post_install']='in_progress';
885 post_install_progress($progArray,'set');
887 if($origVersion < '551' && !in_array('Feeds', $moduleList))
889 $moduleList[] = 'Feeds';
893 // cn: only run conversion if admin selects "Sugar runs SQL"
894 if(!empty($_SESSION['allTables']) && $_SESSION['schema_change'] == 'sugar')
895 executeConvertTablesSql($db->dbType, $_SESSION['allTables']);
896 //set process to done
897 $progArray['post_install']='done';
898 //set_upgrade_progress('commit','in_progress','post_install','done');
899 post_install_progress($progArray,'set');
903 logThis('Performing UWrebuild()...', $path);
907 logThis('UWrebuild() done.', $path);
909 logThis('begin check default permissions .', $path);
910 checkConfigForPermissions();
911 logThis('end check default permissions .', $path);
913 logThis('begin check logger settings .', $path);
914 checkLoggerSettings();
915 logThis('begin check logger settings .', $path);
917 logThis('begin check resource settings .', $path);
918 checkResourceSettings();
919 logThis('begin check resource settings .', $path);
922 require("sugar_version.php");
923 require('config.php');
924 global $sugar_config;
926 if($origVersion < '550' && $sugar_config['dbconfig']['db_type'] == 'mssql' && !is_freetds()){
927 convertImageToText('import_maps', 'content');
928 convertImageToText('import_maps', 'default_values');
929 convertImageToText('saved_reports', 'content');
933 if($origVersion < '550'){
934 logThis("Upgrading multienum data", $path);
935 require_once("$unzip_dir/scripts/upgrade_multienum_data.php");
936 upgrade_multienum_data();
938 if($origVersion < '550' && $sugar_config['dbconfig']['db_type'] == 'mssql') {
939 dropColumnConstraintForMSSQL("outbound_email", "mail_smtpssl");
940 $GLOBALS['db']->query("ALTER TABLE outbound_email alter column mail_smtpssl int NULL");
944 if($ce_to_pro_ent || $origVersion < '550'){
945 if(isset($sugar_config['sugarbeet']))
947 //$sugar_config['sugarbeet'] is only set in COMM
948 unset($sugar_config['sugarbeet']);
950 if(isset($sugar_config['disable_team_access_check']))
952 //$sugar_config['disable_team_access_check'] is a runtime configration,
953 //no need to write to config.php
954 unset($sugar_config['disable_team_access_check']);
956 if(!merge_passwordsetting($sugar_config, $sugar_version)) {
957 logThis('*** ERROR: could not write config.php! - upgrade will fail!', $path);
958 $errors[] = 'Could not write config.php!';
963 logThis('Set default_theme to Sugar', $path);
964 $sugar_config['default_theme'] = 'Sugar';
966 if( !write_array_to_file( "sugar_config", $sugar_config, "config.php" ) ) {
967 logThis('*** ERROR: could not write config.php! - upgrade will fail!', $path);
968 $errors[] = 'Could not write config.php!';
971 logThis('Set default_max_tabs to 7', $path);
972 $sugar_config['default_max_tabs'] = '7';
974 if( !write_array_to_file( "sugar_config", $sugar_config, "config.php" ) ) {
975 logThis('*** ERROR: could not write config.php! - upgrade will fail!', $path);
976 $errors[] = 'Could not write config.php!';
979 logThis('Upgrade the sugar_version', $path);
980 $sugar_config['sugar_version'] = $sugar_version;
981 if($destVersion == $origVersion)
982 require('config.php');
983 if( !write_array_to_file( "sugar_config", $sugar_config, "config.php" ) ) {
984 logThis('*** ERROR: could not write config.php! - upgrade will fail!', $path);
985 $errors[] = 'Could not write config.php!';
988 logThis('post_install() done.', $path);
991 ///////////////////////////////////////////////////////////////////////////////
992 //// REGISTER UPGRADE
994 logThis('Registering upgrade with UpgradeHistory', $path);
995 if(!didThisStepRunBefore('commit','upgradeHistory')){
996 set_upgrade_progress('commit','in_progress','upgradeHistory','in_progress');
997 $file_action = "copied";
998 // if error was encountered, script should have died before now
999 $new_upgrade = new UpgradeHistory();
1000 $new_upgrade->filename = $install_file;
1001 $new_upgrade->md5sum = md5_file($install_file);
1002 $new_upgrade->name = $zip_from_dir;
1003 $new_upgrade->description = $manifest['description'];
1004 $new_upgrade->type = 'patch';
1005 $new_upgrade->version = $sugar_version;
1006 $new_upgrade->status = "installed";
1007 $new_upgrade->manifest = (!empty($_SESSION['install_manifest']) ? $_SESSION['install_manifest'] : '');
1009 if($new_upgrade->description == null){
1010 $new_upgrade->description = "Silent Upgrade was used to upgrade the instance";
1013 $new_upgrade->description = $new_upgrade->description." Silent Upgrade was used to upgrade the instance.";
1015 $new_upgrade->save();
1016 set_upgrade_progress('commit','in_progress','upgradeHistory','done');
1017 set_upgrade_progress('commit','done','commit','done');
1021 //Clean modules from cache
1022 if(is_dir($GLOBALS['sugar_config']['cache_dir'].'smarty')){
1023 $allModFiles = array();
1024 $allModFiles = findAllFiles($GLOBALS['sugar_config']['cache_dir'].'smarty',$allModFiles);
1025 foreach($allModFiles as $file){
1026 //$file_md5_ref = str_replace(clean_path(getcwd()),'',$file);
1027 if(file_exists($file)){
1032 //delete cache/modules before rebuilding the relations
1033 //Clean modules from cache
1034 if(is_dir($GLOBALS['sugar_config']['cache_dir'].'modules')){
1035 $allModFiles = array();
1036 $allModFiles = findAllFiles($GLOBALS['sugar_config']['cache_dir'].'modules',$allModFiles);
1037 foreach($allModFiles as $file){
1038 //$file_md5_ref = str_replace(clean_path(getcwd()),'',$file);
1039 if(file_exists($file)){
1045 //delete cache/themes
1046 if(is_dir($GLOBALS['sugar_config']['cache_dir'].'themes')){
1047 $allModFiles = array();
1048 $allModFiles = findAllFiles($GLOBALS['sugar_config']['cache_dir'].'themes',$allModFiles);
1049 foreach($allModFiles as $file){
1050 //$file_md5_ref = str_replace(clean_path(getcwd()),'',$file);
1051 if(file_exists($file)){
1057 if(!isset($_REQUEST['silent'])){
1058 $_REQUEST['silent'] = true;
1060 else if(isset($_REQUEST['silent']) && $_REQUEST['silent'] != true){
1061 $_REQUEST['silent'] = true;
1064 if($origVersion < '550')
1066 include("install/seed_data/Advanced_Password_SeedData.php");
1067 $GLOBALS['db']->query(" update email_templates set team_set_id=team_id where team_set_id is null and team_id is not null ");
1069 logThis('Start rebuild relationships.', $path);
1070 @rebuildRelations();
1071 logThis('End rebuild relationships.', $path);
1072 //logThis('Checking for leads_assigned_user relationship and if not found then create.', $path);
1073 @createMissingRels();
1074 //logThis('Checked for leads_assigned_user relationship.', $path);
1076 //// run fix on dropdown lists that may have been incorrectly named
1077 //fix_dropdown_list();
1080 set_upgrade_progress('end','in_progress','end','in_progress');
1081 /////////////////////////Old Logger settings///////////////////////////////////////
1082 ///////////////////////////////////////////////////////////////////////////////
1084 if(function_exists('deleteCache')){
1085 set_upgrade_progress('end','in_progress','deleteCache','in_progress');
1087 set_upgrade_progress('end','in_progress','deleteCache','done');
1090 ///////////////////////////////////////////////////////////////////////////////
1091 //// HANDLE REMINDERS
1092 if(empty($errors)) {
1093 commitHandleReminders($skippedFiles, $path);
1096 if(file_exists(clean_path(getcwd()).'/original451files')){
1097 rmdir_recursive(clean_path(getcwd()).'/original451files');
1100 require_once('modules/Administration/Administration.php');
1101 $admin = new Administration();
1102 $admin->saveSetting('system','adminwizard',1);
1104 logThis('Upgrading user preferences start .', $path);
1105 if(function_exists('upgradeUserPreferences')){
1106 upgradeUserPreferences();
1108 logThis('Upgrading user preferences finish .', $path);
1111 require_once('modules/Administration/upgrade_custom_relationships.php');
1112 upgrade_custom_relationships();
1114 if(isset($_SESSION['upgrade_from_flavor'])){
1116 //check to see if there are any new files that need to be added to systems tab
1117 //retrieve old modules list
1118 logThis('check to see if new modules exist',$path);
1119 $oldModuleList = array();
1120 $newModuleList = array();
1121 include($argv[3].'/include/modules.php');
1122 $oldModuleList = $moduleList;
1123 include('include/modules.php');
1124 $newModuleList = $moduleList;
1126 //include tab controller
1127 require_once('modules/MySettings/TabController.php');
1128 $newTB = new TabController();
1130 //make sure new modules list has a key we can reference directly
1131 $newModuleList = $newTB->get_key_array($newModuleList);
1132 $oldModuleList = $newTB->get_key_array($oldModuleList);
1134 //iterate through list and remove commonalities to get new modules
1135 foreach ($newModuleList as $remove_mod){
1136 if(in_array($remove_mod, $oldModuleList)){
1137 unset($newModuleList[$remove_mod]);
1141 $must_have_modules= array(
1142 'Activities'=>'Activities',
1143 'Calendar'=>'Calendar',
1144 'Reports' => 'Reports',
1145 'Quotes' => 'Quotes',
1146 'Products' => 'Products',
1147 'Forecasts' => 'Forecasts',
1148 'Contracts' => 'Contracts',
1149 'KBDocuments' => 'KBDocuments'
1151 $newModuleList = array_merge($newModuleList,$must_have_modules);
1153 //new modules list now has left over modules which are new to this install, so lets add them to the system tabs
1154 logThis('new modules to add are '.var_export($newModuleList,true),$path);
1156 //grab the existing system tabs
1157 $tabs = $newTB->get_system_tabs();
1159 //add the new tabs to the array
1160 foreach($newModuleList as $nm ){
1164 //Set the default order
1165 $default_order = array(
1167 'Accounts'=>'Accounts',
1168 'Contacts'=>'Contacts',
1169 'Opportunities'=>'Opportunities',
1170 'Activities'=>'Activities',
1171 'Reports'=>'Reports',
1172 'Documents'=>'Documents'
1174 $tabs = array_merge($default_order, $tabs);
1176 //now assign the modules to system tabs
1177 $newTB->set_system_tabs($tabs);
1178 logThis('module tabs updated',$path);
1183 //Also set the tracker settings if flavor conversion ce->pro or ce->ent
1184 if(isset($_SESSION['current_db_version']) && isset($_SESSION['target_db_version'])){
1185 if($_SESSION['current_db_version'] == $_SESSION['target_db_version']){
1186 $_REQUEST['upgradeWizard'] = true;
1188 include('include/Smarty/internals/core.write_file.php');
1190 $db =& DBManagerFactory::getInstance();
1192 //Also set license information
1193 $admin = new Administration();
1194 $category = 'license';
1196 $admin->saveSetting($category, 'users', $value);
1197 $key = array('num_lic_oc','key','expire_date');
1199 foreach($key as $k){
1200 $admin->saveSetting($category, $k, $value);
1206 $phpErrors = ob_get_contents();
1208 logThis("**** Potential PHP generated error messages: {$phpErrors}", $path);
1210 if(count($errors) > 0) {
1211 foreach($errors as $error) {
1212 logThis("****** SilentUpgrade ERROR: {$error}", $path);
1219 //ELSE if DCE_INSTANCE
1220 echo "RUNNING DCE UPGRADE\n";
1222 } //END of big if-else block for DCE_INSTANCE