]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/UpgradeWizard/uw_utils.php
Release 6.1.4
[Github/sugarcrm.git] / modules / UpgradeWizard / uw_utils.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38
39
40
41 /**
42  * Backs-up files that are targeted for patch/upgrade to a restore directory
43  * @param string rest_dir Full path to the directory containing the original, replaced files.
44  * @param string install_file Full path to the uploaded patch/upgrade zip file
45  * @param string unzip_dir Full path to the unzipped files in a temporary directory
46  * @param string zip_from_dir Name of directory that the unzipped files containing the actuall replacement files
47  * @param array errors Collection of errors to be displayed at end of process
48  * @param string path Optional full path to the log file.
49  * @return array errors
50  */
51 function commitMakeBackupFiles($rest_dir, $install_file, $unzip_dir, $zip_from_dir, $errors, $path='') {
52         global $mod_strings;
53         // create restore file directory
54         mkdir_recursive($rest_dir);
55
56     if(file_exists($rest_dir) && is_dir($rest_dir)){
57                 logThis('backing up files to be overwritten...', $path);
58                 $newFiles = findAllFiles(clean_path($unzip_dir . '/' . $zip_from_dir), array());
59
60                 // keep this around for canceling
61                 $_SESSION['uw_restore_dir'] = clean_path($rest_dir);
62
63                 foreach ($newFiles as $file) {
64                         if (strpos($file, 'md5'))
65                                 continue;
66
67                         // get name of current file to place in restore directory
68                         $cleanFile = str_replace(clean_path($unzip_dir . '/' . $zip_from_dir), '', $file);
69
70                         // make sure the directory exists
71                         $cleanDir = $rest_dir . '/' . dirname($cleanFile);
72                         if (!is_dir($cleanDir)) {
73                                 mkdir_recursive($cleanDir);
74                         }
75
76                         $oldFile = clean_path(getcwd() . '/' . $cleanFile);
77
78                         // only copy restore files for replacements - ignore new files from patch
79                         if (is_file($oldFile)) {
80                                 if (is_writable($rest_dir)) {
81                                         logThis('Backing up file: ' . $oldFile, $path);
82                                         if (!copy($oldFile, $rest_dir . '/' . $cleanFile)) {
83                                                 logThis('*** ERROR: could not backup file: ' . $oldFile, $path);
84                                                 $errors[] = "{$mod_strings['LBL_UW_BACKUP']}::{$mod_strings['ERR_UW_FILE_NOT_COPIED']}: {$oldFile}";
85                                         } else {
86                                                 $backupFilesExist = true;
87                                         }
88
89                                 } else {
90                                         logThis('*** ERROR: directory not writable: ' . $rest_dir, $path);
91                                         $errors[] = "{$mod_strings['LBL_UW_BACKUP']}::{$mod_strings['ERR_UW_DIR_NOT_WRITABLE']}: {$oldFile}";
92                                 }
93                         }
94                 }
95     }
96         logThis('file backup done.', $path);
97         return $errors;
98 }
99
100 /**
101  * Copies files from the unzipped patch to the destination.
102  * @param string unzip_dir Full path to the temporary directory created during unzip operation.
103  * @param string zip_from_dir Name of folder containing the unzipped files; usually the name of the Patch without the
104  * extension.
105  * @param string path Optional full path to alternate upgradeWizard log file.
106  * @return array Two element array containing to $copiedFiles and $skippedFiles.
107  */
108
109
110
111 function commitCopyNewFiles($unzip_dir, $zip_from_dir, $path='') {
112         logThis('Starting file copy process...', $path);
113         global $sugar_version;
114         $backwardModules='';
115     if(substr($sugar_version,0,1) >= 5){
116         $modules = getAllModules();
117                         $backwardModules = array();
118                         foreach($modules as $mod){
119                                 if(is_dir(clean_path(getcwd().'/modules/'.$mod.'/.500'))){
120                                         $files = array();
121                                 $files= findAllFiles(clean_path(getcwd().'/modules/'.$mod.'/.500'),$files);
122                                 if(sizeof($files) >0){
123                                         //backward compatibility is on
124                                                 $backwardModules[] = $mod;
125                                 }
126                            }
127                         }
128        }
129
130         $newFiles = findAllFiles(clean_path($unzip_dir . '/' . $zip_from_dir), array());
131         $zipPath = clean_path($unzip_dir . '/' . $zip_from_dir);
132
133         // handle special do-not-overwrite conditions
134         $doNotOverwrite = array();
135         $doNotOverwrite[] = '__stub';
136         if(isset($_REQUEST['overwrite_files_serial'])) {
137                 $doNotOverwrite = explode('::', $_REQUEST['overwrite_files_serial']);
138         }
139
140         $copiedFiles = array();
141         $skippedFiles = array();
142
143         foreach($newFiles as $file) {
144                 $cleanFile = str_replace($zipPath, '', $file);
145                 $srcFile = $zipPath . $cleanFile;
146                 $targetFile = clean_path(getcwd() . '/' . $cleanFile);
147                 if($backwardModules != null && sizeof($backwardModules) >0){
148                         foreach($backwardModules as $mod){
149                                 $splitPath = explode('/',trim($cleanFile));
150                                 if('modules' == trim($splitPath[1]) && $mod == trim($splitPath[2])){
151                                         $cleanFile = str_replace('/modules/'.$mod, '/modules/'.$mod.'/.500', $cleanFile);
152                                         $targetFile = clean_path(getcwd() . '/' . $cleanFile);
153                                 }
154                         }
155                 }
156                 if(!is_dir(dirname($targetFile))) {
157                         mkdir_recursive(dirname($targetFile)); // make sure the directory exists
158                 }
159
160                 if((!file_exists($targetFile)) || /* brand new file */
161                         (!in_array($targetFile, $doNotOverwrite)) /* manual diff file */
162                         ) {
163                         // handle sugar_version.php
164                         if(strpos($targetFile, 'sugar_version.php') !== false && !preg_match('/\/portal\/sugar_version\.php$/i', $targetFile)) {
165                                 logThis('Skipping "sugar_version.php" - file copy will occur at end of successful upgrade', $path);
166                                 $_SESSION['sugar_version_file'] = $srcFile;
167                                 continue;
168                         }
169
170                         logThis('Copying file to destination: ' . $targetFile, $path);
171
172                         if(!copy($srcFile, $targetFile)) {
173                                 logThis('*** ERROR: could not copy file: ' . $targetFile, $path);
174                         } else {
175                                 $copiedFiles[] = $targetFile;
176                         }
177                 } else {
178                         logThis('Skipping file: ' . $targetFile, $path);
179                         $skippedFiles[] = $targetFile;
180                 }
181         }
182         logThis('File copy done.', $path);
183
184         $ret = array();
185         $ret['copiedFiles'] = $copiedFiles;
186         $ret['skippedFiles'] = $skippedFiles;
187
188         return $ret;
189 }
190
191
192 //On cancel put back the copied files from 500 to 451 state
193 function copyFilesOnCancel($step){
194 //place hoder for cancel action
195
196 }
197
198
199 function removeFileFromPath($file,$path, $deleteNot=array()){
200                 $removed = 0;
201                 $cur = $path . '/' . $file;
202                 if(file_exists($cur)){
203                         $del = true;
204                         foreach($deleteNot as $dn){
205                                 if($cur == $dn){
206                                         $del = false;
207                                 }
208                         }
209                         if($del){
210                                 unlink($cur);
211                                 $removed++;
212                         }
213                 }
214                 if(!file_exists($path))return $removed;
215                 $d = dir($path);
216                 while($e = $d->read()){
217                         $next = $path . '/'. $e;
218                         if(substr($e, 0, 1) != '.' && is_dir($next)){
219                                 $removed += removeFileFromPath($file, $next, $deleteNot);
220                         }
221                 }
222                 return $removed;
223         }
224
225 /**
226  * This function copies/overwrites between directories
227  *
228  * @param string the directory name to remove
229  * @param boolean whether to just empty the given directory, without deleting the given directory.
230  * @return boolean True/False whether the directory was deleted.
231  */
232
233 function copyRecursiveBetweenDirectories($from,$to){
234         if(file_exists($from)){
235                 $modifiedFiles = array();
236                 $modifiedFiles = findAllFiles(clean_path($from), $modifiedFiles);
237                 $cwd = clean_path(getcwd());
238                 foreach($modifiedFiles as $file) {
239                         $srcFile = clean_path($file);
240                         //$targetFile = clean_path(getcwd() . '/' . $srcFile);
241             if (strpos($srcFile,".svn") !== false) {
242                           //do nothing
243                  }
244                 else{
245                         $targetFile = str_replace($from, $to, $srcFile);
246
247                                 if(!is_dir(dirname($targetFile))) {
248                                         mkdir_recursive(dirname($targetFile)); // make sure the directory exists
249                                 }
250
251                                         // handle sugar_version.php
252                                         if(strpos($targetFile, 'sugar_version.php') !== false && !preg_match('/\/portal\/sugar_version\.php$/i', $targetFile)) {
253                                                 logThis('Skipping "sugar_version.php" - file copy will occur at end of successful upgrade', $path);
254                                                 $_SESSION['sugar_version_file'] = $srcFile;
255                                                 continue;
256                                         }
257
258                                         logThis('Copying file to destination: ' . $targetFile);
259
260                                         if(!copy($srcFile, $targetFile)) {
261                                                 logThis('*** ERROR: could not copy file: ' . $targetFile);
262                                         } else {
263                                                 logThis('Copied file: ' . $targetFile);
264                                                 //$copiedFiles[] = $targetFile;
265                                         }
266
267                 }
268                  }
269         }
270 }
271
272 function deleteDirectory($dirname,$only_empty=false) {
273     if (!is_dir($dirname))
274         return false;
275     $dscan = array(realpath($dirname));
276     $darr = array();
277     while (!empty($dscan)) {
278         $dcur = array_pop($dscan);
279         $darr[] = $dcur;
280         if ($d=opendir($dcur)) {
281             while ($f=readdir($d)) {
282                 if ($f=='.' || $f=='..')
283                     continue;
284                 $f=$dcur.'/'.$f;
285                 if (is_dir($f))
286                     $dscan[] = $f;
287                 else
288                     unlink($f);
289             }
290             closedir($d);
291         }
292     }
293     $i_until = ($only_empty)? 1 : 0;
294     for ($i=count($darr)-1; $i>=$i_until; $i--) {
295         //echo "\nDeleting '".$darr[$i]."' ... ";
296         if (rmdir($darr[$i]))
297             logThis('Success :Copying file to destination: ' . $darr[$i]);
298         else
299             logThis('Copy problem:Copying file to destination: ' . $darr[$i]);
300     }
301     return (($only_empty)? (count(scandir)<=2) : (!is_dir($dirname)));
302 }
303 /**
304  * Get all the customized modules. Compare the file md5s with the base md5s
305  * If a file has been modified then put the module in the list of customized
306  * modules. Show the list in the preflight check UI.
307  */
308
309 function deleteAndOverWriteSelectedFiles($unzip_dir, $zip_from_dir,$delete_dirs){
310         if($delete_dirs != null){
311                 foreach($delete_dirs as $del_dir){
312                         deleteDirectory($del_dir);
313                         $newFiles = findAllFiles(clean_path($unzip_dir . '/' . $zip_from_dir.'/'.$del_dir), array());
314                         $zipPath = clean_path($unzip_dir . '/' . $zip_from_dir.'/'.$del_dir);
315                         $copiedFiles = array();
316                         $skippedFiles = array();
317
318                         foreach($newFiles as $file) {
319                                 $cleanFile = str_replace($zipPath, '', $file);
320                                 $srcFile = $zipPath . $cleanFile;
321                                 $targetFile = clean_path(getcwd() . '/' . $cleanFile);
322
323                                 if(!is_dir(dirname($targetFile))) {
324                                         mkdir_recursive(dirname($targetFile)); // make sure the directory exists
325                                 }
326
327                                 if(!file_exists($targetFile)){
328                                         // handle sugar_version.php
329                                         if(strpos($targetFile, 'sugar_version.php') !== false) {
330                                                 logThis('Skipping sugar_version.php - file copy will occur at end of successful upgrade');
331                                                 $_SESSION['sugar_version_file'] = $srcFile;
332                                                 continue;
333                                         }
334
335                                         logThis('Copying file to destination: ' . $targetFile);
336
337                                         if(!copy($srcFile, $targetFile)) {
338                                                 logThis('*** ERROR: could not copy file: ' . $targetFile);
339                                         } else {
340                                                 $copiedFiles[] = $targetFile;
341                                         }
342                                 } else {
343                                         logThis('Skipping file: ' . $targetFile);
344                                         $skippedFiles[] = $targetFile;
345                                 }
346                           }
347                 }
348         }
349         $ret = array();
350         $ret['copiedFiles'] = $copiedFiles;
351         $ret['skippedFiles'] = $skippedFiles;
352
353         return $ret;
354 }
355
356 //Default is empty the directory. For removing set it to false
357 // to use this function to totally remove a directory, write:
358 // recursive_remove_directory('path/to/directory/to/delete',FALSE);
359
360 // to use this function to empty a directory, write:
361 // recursive_remove_directory('path/to/full_directory');
362
363 function recursive_empty_or_remove_directory($directory, $exclude_dirs=null,$exclude_files=null,$empty=TRUE)
364 {
365         // if the path has a slash at the end we remove it here
366         if(substr($directory,-1) == '/')
367         {
368                 $directory = substr($directory,0,-1);
369         }
370
371         // if the path is not valid or is not a directory ...
372         if(!file_exists($directory) || !is_dir($directory))
373         {
374                 // ... we return false and exit the function
375                 return FALSE;
376
377         // ... if the path is not readable
378         }elseif(!is_readable($directory))
379         {
380                 // ... we return false and exit the function
381                 return FALSE;
382
383         // ... else if the path is readable
384         }else{
385
386                 // we open the directory
387                 $handle = opendir($directory);
388
389                 // and scan through the items inside
390                 while (FALSE !== ($item = readdir($handle)))
391                 {
392                         // if the filepointer is not the current directory
393                         // or the parent directory
394                         if($item != '.' && $item != '..')
395                         {
396                                 // we build the new path to delete
397                                 $path = $directory.'/'.$item;
398
399                                 // if the new path is a directory
400                                 //add another check if the dir is in the list to exclude delete
401                                 if(is_dir($path) && $exclude_dirs != null && in_array($path,$exclude_dirs)){
402                                     //do nothing
403                                 }
404                                 else if(is_dir($path))
405                                 {
406                                         // we call this function with the new path
407                                         recursive_empty_or_remove_directory($path);
408                                 }
409                                 // if the new path is a file
410                                 else{
411                                         // we remove the file
412                                         if($exclude_files != null && in_array($path,$exclude_files)){
413                            //do nothing
414                                         }
415                                         else{
416                                                 unlink($path);
417                                     }
418                                 }
419                         }
420                 }
421                 // close the directory
422                 closedir($handle);
423
424                 // if the option to empty is not set to true
425                 if($empty == FALSE)
426                 {
427                         // try to delete the now empty directory
428                         if(!rmdir($directory))
429                         {
430                                 // return false if not possible
431                                 return FALSE;
432                         }
433                 }
434                 // return success
435                 return TRUE;
436         }
437 }
438 // ------------------------------------------------------------
439
440
441
442
443 function getAllCustomizedModules() {
444
445                 require_once('files.md5');
446
447             $return_array = array();
448             $modules = getAllModules();
449             foreach($modules as $mod) {
450                    //find all files in each module if the files have been modified
451                    //as compared to the base version then add the module to the
452                    //customized modules array
453                    $modFiles = findAllFiles(clean_path(getcwd())."/modules/$mod", array());
454                foreach($modFiles as $file){
455                   $fileContents = file_get_contents($file);
456                    $file = str_replace(clean_path(getcwd()),'',$file);
457                   if($md5_string['./' . $file]){
458                           if(md5($fileContents) != $md5_string['./' . $file]) {
459                              //A file has been customized in the module. Put the module into the
460                              // customized modules array.
461                              echo 'Changed File'.$file;
462                                   $return_array[$mod];
463                                   break;
464                           }
465                   }
466                   else{
467                         // This is a new file in user's version and indicates that module has been
468                         //customized. Put the module in the customized array.
469                        echo 'New File'.$file;
470                        $return_array[$mod];
471                        break;
472                   }
473                }
474             } //foreach
475
476                 return $return_array;
477         }
478
479     /**
480      * Array of all Modules in the version bein upgraded
481      * This method returns an Array of all modules
482      * @return $modules Array of modules.
483      */
484         function getAllModules() {
485                 $modules = array();
486                 $d = dir('modules');
487                 while($e = $d->read()){
488                         if(substr($e, 0, 1) == '.' || !is_dir('modules/' . $e))continue;
489                         $modules[] = $e;
490                 }
491                 return $modules;
492         }
493
494 //Remove files with the smae md5
495
496 function removeMd5MatchingFiles($deleteNot=array()){
497
498         $md5_string = array();
499         if(file_exists(clean_path(getcwd().'/files.md5'))){
500                 require(clean_path(getcwd().'/files.md5'));
501         }
502     $modulesAll = getAllModules();
503      foreach($modulesAll as $mod){
504               $allModFiles = array();
505               if(is_dir('modules/'.$mod)){
506               $allModFiles = findAllFiles('modules/'.$mod,$allModFiles);
507                foreach($allModFiles as $file){
508                         if(file_exists($file) && !in_array(basename($file),$deleteNot)){
509                                  if(isset($md5_string['./'.$file])) {
510                                   $fileContents = file_get_contents($file);
511                                   if(md5($fileContents) == $md5_string['./'.$file]) {
512                                         unlink($file);
513                                   }
514                               }
515                     }
516            }
517            }
518    }
519 }
520
521 /**
522  * Handles requirements for creating reminder Tasks and Emails
523  * @param array skippedFiles Array of files that were not overwriten and must be manually mereged.
524  * @param string path Optional full path to alternate upgradeWizard log.
525  */
526 function commitHandleReminders($skippedFiles, $path='') {
527         global $mod_strings;
528         global $current_user;
529
530         if(empty($mod_strings))
531                 $mod_strings = return_module_language('en_us', 'UpgradeWizard');
532
533         if(empty($current_user->id)) {
534                 $current_user->getSystemUser();
535         }
536
537         if(count($skippedFiles) > 0) {
538                 $desc = $mod_strings['LBL_UW_COMMIT_ADD_TASK_OVERVIEW'] . "\n\n";
539                 $desc .= $mod_strings['LBL_UW_COMMIT_ADD_TASK_DESC_1'];
540                 $desc .= $_SESSION['uw_restore_dir'] . "\n\n";
541                 $desc .= $mod_strings['LBL_UW_COMMIT_ADD_TASK_DESC_2'] . "\n\n";
542
543                 foreach($skippedFiles as $file) {
544                         $desc .= $file . "\n";
545                 }
546
547                 //MFH #13468
548                 $nowDate = gmdate($timedate->dbDateFormat);
549                 $nowTime = gmdate($timedate->dbTimeFormat);
550                 $nowDateTime = $nowDate . ' ' . $nowTime;
551
552                 if($_REQUEST['addTaskReminder'] == 'remind') {
553                         logThis('Adding Task for admin for manual merge.', $path);
554
555                         $task = new Task();
556                         $task->name = $mod_strings['LBL_UW_COMMIT_ADD_TASK_NAME'];
557                         $task->description = $desc;
558                         $task->date_due = $nowDate;
559                         $task->time_due = $nowTime;
560                         $task->priority = 'High';
561                         $task->status = 'Not Started';
562                         $task->assigned_user_id = $current_user->id;
563                         $task->created_by = $current_user->id;
564                         $task->date_entered = $nowDateTime;
565                         $task->date_modified = $nowDateTime;
566                         $task->save();
567                 }
568
569                 if($_REQUEST['addEmailReminder'] == 'remind') {
570                         logThis('Sending Reminder for admin for manual merge.', $path);
571
572                         $email = new Email();
573                         $email->assigned_user_id = $current_user->id;
574                         $email->name = $mod_strings['LBL_UW_COMMIT_ADD_TASK_NAME'];
575                         $email->description = $desc;
576                         $email->description_html = nl2br($desc);
577                         $email->from_name = $current_user->full_name;
578                         $email->from_addr = $current_user->email1;
579                         $email->to_addrs_arr = $email->parse_addrs($current_user->email1, '', '', '');
580                         $email->cc_addrs_arr = array();
581                         $email->bcc_addrs_arr = array();
582                         $email->date_entered = $nowDateTime;
583                         $email->date_modified = $nowDateTime;
584                         $email->send();
585                         $email->save();
586                 }
587         }
588 }
589
590 function deleteCache(){
591         //Clean modules from cache
592         if(is_dir($GLOBALS['sugar_config']['cache_dir'].'modules')){
593                 $allModFiles = array();
594                 $allModFiles = findAllFiles($GLOBALS['sugar_config']['cache_dir'].'modules',$allModFiles);
595            foreach($allModFiles as $file){
596                 if(file_exists($file)){
597                                 unlink($file);
598                 }
599            }
600         }
601         //Clean jsLanguage from cache
602         if(is_dir($GLOBALS['sugar_config']['cache_dir'].'jsLanguage')){
603                 $allModFiles = array();
604                 $allModFiles = findAllFiles($GLOBALS['sugar_config']['cache_dir'].'jsLanguage',$allModFiles);
605            foreach($allModFiles as $file){
606                         if(file_exists($file)){
607                                 unlink($file);
608                         }
609                 }
610         }
611         //Clean smarty from cache
612         if(is_dir($GLOBALS['sugar_config']['cache_dir'].'smarty')){
613                 $allModFiles = array();
614                 $allModFiles = findAllFiles($GLOBALS['sugar_config']['cache_dir'].'smarty',$allModFiles);
615            foreach($allModFiles as $file){
616                 if(file_exists($file)){
617                                 unlink($file);
618                 }
619            }
620         }
621         //Rebuild dashlets cache
622         require_once('include/Dashlets/DashletCacheBuilder.php');
623         $dc = new DashletCacheBuilder();
624     $dc->buildCache();
625 }
626
627 function deleteChance(){
628         //Clean folder from cache
629         if(is_dir('include/SugarObjects/templates/chance')){
630                 rmdir_recursive('include/SugarObjects/templates/chance');
631          }
632         if(is_dir('include/SugarObjects/templates/chance')){
633                 if(!isset($_SESSION['chance'])){
634                         $_SESSION['chance'] = '';
635                 }
636                 $_SESSION['chance'] = 'include/SugarObjects/templates/chance';
637                 //rename('include/SugarObjects/templates/chance','include/SugarObjects/templates/chance_removeit');
638         }
639 }
640
641
642
643 /**
644  * copies upgrade wizard files from new patch if that dir exists
645  * @param       string file Path to uploaded zip file
646  */
647 function upgradeUWFiles($file) {
648         global $sugar_config;
649         // file = getcwd().'/'.$sugar_config['upload_dir'].$_FILES['upgrade_zip']['name'];
650
651         $cacheUploadUpgradesTemp = clean_path(mk_temp_dir("{$sugar_config['upload_dir']}upgrades/temp"));
652
653         unzip($file, $cacheUploadUpgradesTemp);
654
655         if(!file_exists(clean_path("{$cacheUploadUpgradesTemp}/manifest.php"))) {
656                 logThis("*** ERROR: no manifest file detected while bootstraping upgrade wizard files!");
657                 return;
658         } else {
659                 include(clean_path("{$cacheUploadUpgradesTemp}/manifest.php"));
660         }
661
662         $allFiles = array();
663         // upgradeWizard
664         if(file_exists(clean_path("{$cacheUploadUpgradesTemp}/{$manifest['copy_files']['from_dir']}/modules/UpgradeWizard"))) {
665                 $allFiles = findAllFiles(clean_path("{$cacheUploadUpgradesTemp}/{$manifest['copy_files']['from_dir']}/modules/UpgradeWizard"), $allFiles);
666         }
667         // moduleInstaller
668         if(file_exists(clean_path("{$cacheUploadUpgradesTemp}/{$manifest['copy_files']['from_dir']}/ModuleInstall"))) {
669                 $allFiles = findAllFiles(clean_path("{$cacheUploadUpgradesTemp}/{$manifest['copy_files']['from_dir']}/ModuleInstall"), $allFiles);
670         }
671         if(file_exists(clean_path("{$cacheUploadUpgradesTemp}/{$manifest['copy_files']['from_dir']}/include/javascript/yui"))) {
672                 $allFiles = findAllFiles(clean_path("{$cacheUploadUpgradesTemp}/{$manifest['copy_files']['from_dir']}/include/javascript/yui"), $allFiles);
673         }
674         if(file_exists(clean_path("{$cacheUploadUpgradesTemp}/{$manifest['copy_files']['from_dir']}/HandleAjaxCall.php"))) {
675                 $allFiles[] = clean_path("{$cacheUploadUpgradesTemp}/{$manifest['copy_files']['from_dir']}/HandleAjaxCall.php");
676         }
677         if(file_exists(clean_path("{$cacheUploadUpgradesTemp}/{$manifest['copy_files']['from_dir']}/include/SugarTheme"))) {
678                 $allFiles = findAllFiles(clean_path("{$cacheUploadUpgradesTemp}/{$manifest['copy_files']['from_dir']}/include/SugarTheme"), $allFiles);
679         }
680
681         /*
682          * /home/chris/workspace/maint450/cache/upload/upgrades/temp/DlNnqP/
683          * SugarEnt-Patch-4.5.0c/modules/Leads/ConvertLead.html
684          */
685         $cwd = clean_path(getcwd());
686
687         foreach($allFiles as $k => $file) {
688                 $file = clean_path($file);
689                 $destFile = str_replace(clean_path($cacheUploadUpgradesTemp.'/'.$manifest['copy_files']['from_dir']), $cwd, $file);
690        if(!is_dir(dirname($destFile))) {
691                         mkdir_recursive(dirname($destFile)); // make sure the directory exists
692                 }
693                 if ( stristr($file,'uw_main.tpl') )
694             logThis('Skipping "'.$file.'" - file copy will during commit step.');
695         else {
696             logThis('updating UpgradeWizard code: '.$destFile);
697             copy_recursive($file, $destFile);
698         }
699         }
700         logThis ('is sugar_file_util there '.file_exists(clean_path("{$cacheUploadUpgradesTemp}/{$manifest['copy_files']['from_dir']}/include/utils/sugar_file_utils.php")));
701         if(file_exists(clean_path("{$cacheUploadUpgradesTemp}/{$manifest['copy_files']['from_dir']}/include/utils/sugar_file_utils.php"))) {
702                 $file = clean_path("{$cacheUploadUpgradesTemp}/{$manifest['copy_files']['from_dir']}/include/utils/sugar_file_utils.php");
703                 $destFile = str_replace(clean_path($cacheUploadUpgradesTemp.'/'.$manifest['copy_files']['from_dir']), $cwd, $file);
704         copy($file,$destFile);
705         }
706 }
707
708
709
710 /**
711  * gets valid patch file names that exist in upload/upgrade/patch/
712  */
713 function getValidPatchName($returnFull = true) {
714         global $base_upgrade_dir;
715         global $mod_strings;
716         global $uh;
717         global $sugar_version;
718     global $sugar_config;
719     $uh = new UpgradeHistory();
720     $base_upgrade_dir = $sugar_config['upload_dir'] . "upgrades";
721         $return = array();
722
723         // scan for new files (that are not installed)
724         logThis('finding new files for upgrade');
725         $upgrade_content = '';
726         $upgrade_contents = findAllFiles($base_upgrade_dir, array(), false, 'zip');
727         //other variations of zip file i.e. ZIP, zIp,zIP,Zip,ZIp,ZiP
728     $extns = array('ZIP','ZIp','ZiP','Zip','zIP','zIp','ziP');
729     foreach($extns as $extn){
730         $upgrade_contents = array_merge($upgrade_contents,findAllFiles( "$base_upgrade_dir", array() , false, $extn));
731     }
732         $ready = "<ul>\n";
733         $ready .= "
734                 <table>
735                         <tr>
736                                 <td></td>
737                                 <td align=left>
738                                         <b>{$mod_strings['LBL_ML_NAME']}</b>
739                                 </td>
740                                 <td align=left>
741                                         <b>{$mod_strings['LBL_ML_TYPE']}</b>
742                                 </td>
743                                 <td align=left>
744                                         <b>{$mod_strings['LBL_ML_VERSION']}</b>
745                                 </td>
746                                 <td align=left>
747                                         <b>{$mod_strings['LBL_ML_PUBLISHED']}</b>
748                                 </td>
749                                 <td align=left>
750                                         <b>{$mod_strings['LBL_ML_UNINSTALLABLE']}</b>
751                                 </td>
752                                 <td align=left>
753                                         <b>{$mod_strings['LBL_ML_DESCRIPTION']}</b>
754                                 </td>
755                         </tr>";
756         $disabled = '';
757
758         // assume old patches are there.
759         $upgradeToVersion = array(); // fill with valid patches - we will only use the latest qualified found patch
760
761         // cn: bug 10609 - notices for uninitialized variables
762         $icon = '';
763         $name = '';
764         $type = '';
765         $version = '';
766         $published_date = '';
767         $uninstallable = '';
768         $description = '';
769         $disabled = '';
770
771         foreach($upgrade_contents as $upgrade_content) {
772                 if(!preg_match("#.*\.zip\$#i", strtolower($upgrade_content))) {
773                         continue;
774                 }
775
776                 $upgrade_content = clean_path($upgrade_content);
777                 $the_base = basename($upgrade_content);
778                 $the_md5 = md5_file($upgrade_content);
779
780                 $md5_matches = $uh->findByMd5($the_md5);
781
782                 /* If a patch is in the /patch dir AND has no record in the upgrade_history table we assume that it's the one we want.
783                  * Edge-case: manual upgrade with a FTP of a patch; UH table has no entry for it.  Assume nothing. :( */
784                 if(0 == sizeof($md5_matches)) {
785                         $target_manifest = remove_file_extension( $upgrade_content ) . '-manifest.php';
786                         require_once($target_manifest);
787
788                         if(empty($manifest['version'])) {
789                                 logThis("*** Potential error: patch found with no version [ {$upgrade_content} ]");
790                                 continue;
791                         }
792                         if(!isset($manifest['type']) || $manifest['type'] != 'patch') {
793                                 logThis("*** Potential error: patch found with either no 'type' or non-patch type [ {$upgrade_content} ]");
794                                 continue;
795                         }
796
797                         $upgradeToVersion[$manifest['version']] = urlencode($upgrade_content);
798
799                         $name = empty($manifest['name']) ? $upgrade_content : $manifest['name'];
800                         $version = empty($manifest['version']) ? '' : $manifest['version'];
801                         $published_date = empty($manifest['published_date']) ? '' : $manifest['published_date'];
802                         $icon = '';
803                         $description = empty($manifest['description']) ? 'None' : $manifest['description'];
804                         $uninstallable = empty($manifest['is_uninstallable']) ? 'No' : 'Yes';
805                         $type = getUITextForType( $manifest['type'] );
806                         $manifest_type = $manifest['type'];
807
808                         if(empty($manifest['icon'])) {
809                                 $icon = getImageForType( $manifest['type'] );
810                         } else {
811                                 $path_parts = pathinfo( $manifest['icon'] );
812                                 $icon = "<img src=\"" . remove_file_extension( $upgrade_content ) . "-icon." . $path_parts['extension'] . "\">";
813                         }
814             }
815         }
816
817         // cn: bug 10488 use the NEWEST upgrade/patch available when running upgrade wizard.
818         ksort($upgradeToVersion);
819         $upgradeToVersion = array_values($upgradeToVersion);
820         $newest = array_pop($upgradeToVersion);
821         $_SESSION['install_file'] = urldecode($newest); // in-case it was there from a prior.
822         logThis("*** UW using [ {$_SESSION['install_file']} ] as source for patch files.");
823
824         $cleanUpgradeContent = urlencode($_SESSION['install_file']);
825
826         // cn: 10606 - cannot upload a patch file since this returned always.
827         if(!empty($cleanUpgradeContent)) {
828                 $ready .= "<tr><td>$icon</td><td>$name</td><td>$type</td><td>$version</td><td>$published_date</td><td>$uninstallable</td><td>$description</td>\n";
829                 $ready .=<<<eoq
830                 <td>
831                                 <form action="index.php" method="post">
832                                         <input type="hidden" name="module" value="UpgradeWizard">
833                                         <input type="hidden" name="action" value="index">
834                                         <input type="hidden" name="step" value="{$_REQUEST['step']}">
835                                         <input type="hidden" name="run" value="delete">
836                                 <input type=hidden name="install_file" value="{$cleanUpgradeContent}" />
837                                 <input type=submit value="{$mod_strings['LBL_BUTTON_DELETE']}" />
838                                 </form>
839                         </td></table>\n
840 eoq;
841                 $disabled = "DISABLED";
842         }
843
844         
845
846         if(empty($cleanUpgradeContent)){
847             $ready .= "<tr><td colspan='7'><i>None</i></td>\n";
848                 $ready .= "</table>\n";
849         }
850         $ready .= "<br></ul>\n";
851
852         $return['ready'] = $ready;
853         $return['disabled'] = $disabled;
854
855         if($returnFull) {
856                 return $return;
857         }
858 }
859
860
861 /**
862  * finalizes upgrade by setting upgrade versions in DB (config table) and sugar_version.php
863  * @return bool true on success
864  */
865 function updateVersions($version) {
866         global $db;
867         global $sugar_config;
868         global $path;
869
870         logThis('At updateVersions()... updating config table and sugar_version.php.', $path);
871
872         // handle file copy
873         if(isset($_SESSION['sugar_version_file']) && !empty($_SESSION['sugar_version_file'])) {
874                 if(!copy($_SESSION['sugar_version_file'], clean_path(getcwd().'/sugar_version.php'))) {
875                         logThis('*** ERROR: sugar_version.php could not be copied to destination! Cannot complete upgrade', $path);
876                         return false;
877                 } else {
878                         logThis('sugar_version.php successfully updated!', $path);
879                 }
880         } else {
881                 logThis('*** ERROR: no sugar_version.php file location found! - cannot complete upgrade...', $path);
882                 return false;
883         }
884
885         // handle config table
886         if($db->dbType == 'mysql') {
887                 $q1 = "DELETE FROM `config` WHERE `category` = 'info' AND `name` = 'sugar_version'";
888                 $q2 = "INSERT INTO `config` (`category`, `name`, `value`) VALUES ('info', 'sugar_version', '{$version}')";
889         } elseif($db->dbType == 'oci8' || $db->dbType == 'oracle') {
890         } elseif($db->dbType == 'mssql') {
891                 $q1 = "DELETE FROM config WHERE category = 'info' AND name = 'sugar_version'";
892                 $q2 = "INSERT INTO config (category, name, value) VALUES ('info', 'sugar_version', '{$version}')";
893         }
894
895         logThis('Deleting old DB version info from config table.', $path);
896         $db->query($q1);
897
898         logThis('Inserting updated version info into config table.', $path);
899         $db->query($q2);
900
901         logThis('updateVersions() complete.', $path);
902         return true;
903 }
904
905
906
907 /**
908  * gets a module's lang pack - does not need to be a SugarModule
909  * @param lang string Language
910  * @param module string Path to language folder
911  * @return array mod_strings
912  */
913 function getModuleLanguagePack($lang, $module) {
914         $mod_strings = array();
915
916         if(!empty($lang) && !empty($module)) {
917                 $langPack = clean_path(getcwd().'/'.$module.'/language/'.$lang.'.lang.php');
918                 $langPackEn = clean_path(getcwd().'/'.$module.'/language/en_us.lang.php');
919
920                 if(file_exists($langPack))
921                         include_once($langPack);
922                 elseif(file_exists($langPackEn))
923                         include_once($langPackEn);
924         }
925
926         return $mod_strings;
927 }
928 /**
929  * checks system compliance for 4.5+ codebase
930  * @return array Mixed values
931  */
932 function checkSystemCompliance() {
933         global $sugar_config;
934         global $current_language;
935         global $db;
936         global $mod_strings;
937
938         if(!defined('SUGARCRM_MIN_MEM')) {
939                 define('SUGARCRM_MIN_MEM', 40);
940         }
941
942         $installer_mod_strings = getModuleLanguagePack($current_language, './install');
943         $ret = array();
944         $ret['error_found'] = false;
945
946         // PHP version
947         $php_version = constant('PHP_VERSION');
948         $check_php_version_result = check_php_version($php_version);
949
950         switch($check_php_version_result) {
951                 case -1:
952                         $ret['phpVersion'] = "<b><span class=stop>{$installer_mod_strings['ERR_CHECKSYS_PHP_INVALID_VER']} {$php_version} )</span></b>";
953                         $ret['error_found'] = true;
954                         break;
955                 case 0:
956                         $ret['phpVersion'] = "<b><span class=go>{$installer_mod_strings['ERR_CHECKSYS_PHP_UNSUPPORTED']} {$php_version} )</span></b>";
957                         break;
958                 case 1:
959                         $ret['phpVersion'] = "<b><span class=go>{$installer_mod_strings['LBL_CHECKSYS_PHP_OK']} {$php_version} )</span></b>";
960                         break;
961         }
962
963         // database and connect
964         switch($sugar_config['dbconfig']['db_type']){
965             case 'mysql':
966                 // mysql version
967                 $q = "SELECT version();";
968                 $r = $db->query($q);
969                 $a = $db->fetchByAssoc($r);
970                 if(version_compare($a['version()'], '4.1.2') < 0) {
971                         $ret['error_found'] = true;
972                         $ret['mysqlVersion'] = "<b><span class=stop>".$mod_strings['ERR_UW_MYSQL_VERSION'].$a['version()']."</span></b>";
973                 }
974
975                 break;
976                 case 'mssql':
977                 break;
978             case 'oci8':
979                 break;
980         }
981
982
983
984
985         // XML Parsing
986         if(function_exists('xml_parser_create')) {
987                 $ret['xmlStatus'] = "<b><span class=go>{$installer_mod_strings['LBL_CHECKSYS_OK']}</span></b>";
988         } else {
989                 $ret['xmlStatus'] = "<b><span class=stop>{$installer_mod_strings['LBL_CHECKSYS_NOT_AVAILABLE']}</span></b>";
990                 $ret['error_found'] = true;
991         }
992
993         // cURL
994         if(function_exists('curl_init')) {
995                 $ret['curlStatus'] = "<b><span class=go>{$installer_mod_strings['LBL_CHECKSYS_OK']}</font></b>";
996         } else {
997                 $ret['curlStatus'] = "<b><span class=go>{$installer_mod_strings['ERR_CHECKSYS_CURL']}</font></b>";
998                 $ret['error_found'] = false;
999         }
1000
1001         // mbstrings
1002         if(function_exists('mb_strlen')) {
1003                 $ret['mbstringStatus'] = "<b><span class=go>{$installer_mod_strings['LBL_CHECKSYS_OK']}</font></b>";
1004         } else {
1005                 $ret['mbstringStatus'] = "<b><span class=stop>{$installer_mod_strings['ERR_CHECKSYS_MBSTRING']}</font></b>";
1006                 $ret['error_found'] = true;
1007         }
1008
1009         // imap
1010         if(function_exists('imap_open')) {
1011                 $ret['imapStatus'] = "<b><span class=go>{$installer_mod_strings['LBL_CHECKSYS_OK']}</span></b>";
1012         } else {
1013                 $ret['imapStatus'] = "<b><span class=go>{$installer_mod_strings['ERR_CHECKSYS_IMAP']}</span></b>";
1014                 $ret['error_found'] = false;
1015         }
1016
1017
1018         // safe mode
1019         if('1' == ini_get('safe_mode')) {
1020                 $ret['safeModeStatus'] = "<b><span class=stop>{$installer_mod_strings['ERR_CHECKSYS_SAFE_MODE']}</span></b>";
1021                 $ret['error_found'] = true;
1022         } else {
1023                 $ret['safeModeStatus'] = "<b><span class=go>{$installer_mod_strings['LBL_CHECKSYS_OK']}</span></b>";
1024         }
1025
1026
1027         // call time pass by ref
1028     if('1' == ini_get('allow_call_time_pass_reference')) {
1029                 $ret['callTimeStatus'] = "<b><span class=stop>{$installer_mod_strings['ERR_CHECKSYS_CALL_TIME']}</span></b>";
1030                 //continue upgrading
1031         } else {
1032                 $ret['callTimeStatus'] = "<b><span class=go>{$installer_mod_strings['LBL_CHECKSYS_OK']}</span></b>";
1033         }
1034
1035         // memory limit
1036         $ret['memory_msg']     = "";
1037         $memory_limit   = "-1";//ini_get('memory_limit');
1038         $sugarMinMem = constant('SUGARCRM_MIN_MEM');
1039         // logic based on: http://us2.php.net/manual/en/ini.core.php#ini.memory-limit
1040         if( $memory_limit == "" ){          // memory_limit disabled at compile time, no memory limit
1041             $ret['memory_msg'] = "<b><span class=\"go\">{$installer_mod_strings['LBL_CHECKSYS_MEM_OK']}</span></b>";
1042         } elseif( $memory_limit == "-1" ){   // memory_limit enabled, but set to unlimited
1043             $ret['memory_msg'] = "<b><span class=\"go\">{$installer_mod_strings['LBL_CHECKSYS_MEM_UNLIMITED']}</span></b>";
1044         } else {
1045             rtrim($memory_limit, 'M');
1046             $memory_limit_int = (int) $memory_limit;
1047             if( $memory_limit_int < constant('SUGARCRM_MIN_MEM') ){
1048                 $ret['memory_msg'] = "<b><span class=\"stop\">{$installer_mod_strings['ERR_CHECKSYS_MEM_LIMIT_1']}" . constant('SUGARCRM_MIN_MEM') . "{$installer_mod_strings['ERR_CHECKSYS_MEM_LIMIT_2']}</span></b>";
1049                         $ret['error_found'] = true;
1050             } else {
1051                         $ret['memory_msg'] = "<b><span class=\"go\">{$installer_mod_strings['LBL_CHECKSYS_OK']} ({$memory_limit})</span></b>";
1052             }
1053         }
1054
1055         /* mbstring.func_overload
1056         $ret['mbstring.func_overload'] = '';
1057         $mb = ini_get('mbstring.func_overload');
1058
1059         if($mb > 1) {
1060                 $ret['mbstring.func_overload'] = "<b><span class=\"stop\">{$mod_strings['ERR_UW_MBSTRING_FUNC_OVERLOAD']}</b>";
1061                 $ret['error_found'] = true;
1062         }
1063         */
1064         return $ret;
1065 }
1066
1067
1068
1069 function checkMysqlConnection(){
1070         global $sugar_config;
1071         $configOptions = $sugar_config['dbconfig'];
1072         if($sugar_config['dbconfig']['db_type'] == 'mysql'){
1073         @mysql_ping($GLOBALS['db']->database);
1074     }
1075 }
1076
1077 /**
1078  * is a file that we blow away automagically
1079  */
1080 function isAutoOverwriteFile($file) {
1081         $overwriteDirs = array(
1082                 './sugar_version.php',
1083                 './modules/UpgradeWizard/uw_main.tpl',
1084         );
1085         $file = trim('.'.str_replace(clean_path(getcwd()), '', $file));
1086
1087         if(in_array($file, $overwriteDirs)) {
1088                 return true;
1089         }
1090
1091         $fileExtension = substr(strrchr($file, "."), 1);
1092         if($fileExtension == 'tpl' || $fileExtension == 'html') {
1093                 return false;
1094         }
1095
1096         return true;
1097 }
1098
1099 /**
1100  * flatfile logger
1101  */
1102 function logThis($entry, $path='') {
1103         global $mod_strings;
1104         if(file_exists('include/utils/sugar_file_utils.php')){
1105                 require_once('include/utils/sugar_file_utils.php');
1106         }
1107                 $log = empty($path) ? clean_path(getcwd().'/upgradeWizard.log') : clean_path($path);
1108
1109                 // create if not exists
1110                 if(!file_exists($log)) {
1111                         if(function_exists('sugar_fopen')){
1112                                 $fp = @sugar_fopen($log, 'w+'); // attempts to create file
1113                      }
1114                      else{
1115                                 $fp = fopen($log, 'w+'); // attempts to create file
1116                      }
1117                         if(!is_resource($fp)) {
1118                                 $GLOBALS['log']->fatal('UpgradeWizard could not create the upgradeWizard.log file');
1119                                 die($mod_strings['ERR_UW_LOG_FILE_UNWRITABLE']);
1120                         }
1121                 } else {
1122                         if(function_exists('sugar_fopen')){
1123                                 $fp = @sugar_fopen($log, 'a+'); // write pointer at end of file
1124                      }
1125                      else{
1126                                 $fp = @fopen($log, 'a+'); // write pointer at end of file
1127                      }
1128
1129                         if(!is_resource($fp)) {
1130                                 $GLOBALS['log']->fatal('UpgradeWizard could not open/lock upgradeWizard.log file');
1131                                 die($mod_strings['ERR_UW_LOG_FILE_UNWRITABLE']);
1132                         }
1133                 }
1134
1135                 $line = date('r').' [UpgradeWizard] - '.$entry."\n";
1136
1137                 if(@fwrite($fp, $line) === false) {
1138                         $GLOBALS['log']->fatal('UpgradeWizard could not write to upgradeWizard.log: '.$entry);
1139                         die($mod_strings['ERR_UW_LOG_FILE_UNWRITABLE']);
1140                 }
1141
1142                 if(is_resource($fp)) {
1143                         fclose($fp);
1144                 }
1145 }
1146
1147
1148 /**
1149  * tries to validate the query based on type
1150  * @param string query The query to verify
1151  * @param string dbType The DB type
1152  * @return string error Non-empty string on error
1153  */
1154 function verifySqlStatement($query, $dbType, &$newTables) {
1155         $error = '';
1156         logThis('verifying SQL statement');
1157
1158         $table  = getTableFromQuery($query);
1159
1160         switch(strtoupper(substr($query, 0, 10))) {
1161                 // ignore DROPs
1162                 case 'ALTER TABL':
1163                         // get ddl
1164                         $error = testQueryAlter($table, $dbType, strtoupper($query), $newTables);
1165                 break;
1166
1167                 case 'CREATE TAB':
1168                         $error = testQueryCreate($table, $dbType, $query, $newTables);
1169                 break;
1170
1171                 case 'DELETE FRO':
1172                         $error = testQueryDelete($table, $dbType, $query);
1173                 break;
1174
1175                 case 'DROP TABLE':
1176                         $error = testQueryDrop($table, $dbType, $query);
1177                 break;
1178
1179                 case 'INSERT INT':
1180                         $error = testQueryInsert($table, $dbType, $query);
1181                 break;
1182
1183                 case (strtoupper(substr($query, 0, 6)) == 'UPDATE'):
1184                         $error = testQueryUpdate($table, $dbType, $query);
1185                 break;
1186
1187         }
1188
1189         return $error;
1190 }
1191
1192
1193 /**
1194         *  @params : none
1195         *  @author: nsingh
1196         *  @desc This function is to be used in the upgrade process to preserve changes/customaizations made to pre 5.1 quickcreate layout.
1197         *  Prior to 5.1 we have been using editviewdefs as the base for quickcreatedefs. If a custom field was added to edit view layout, it
1198         *  was automatically picked up by the quick create. [Addresses Bug 21469]
1199         *  This function will check if customizations were made, and will create quickcreatedefs.php in the /cutom/working/$module_name directory.
1200         **/
1201 function updateQuickCreateDefs(){
1202         $d = dir('modules');
1203         $studio_modules = array();
1204
1205         while($e = $d->read()){ //collect all studio modules.
1206                 if(substr($e, 0, 1) == '.' || !is_dir('modules/' . $e))continue;
1207                 if(file_exists('modules/' . $e . '/metadata/studio.php'))
1208                 {
1209                         array_push($studio_modules, $e);
1210                 }
1211         }
1212
1213         foreach( $studio_modules as $modname ){ //for each studio enabled module
1214                 //Check !exists modules/$modname/metadata/quickcreatedefs.php &&
1215                 //exists custom/$modname/editviewdefs.php (module was customized) &&
1216                 //!exists custom/$modname/quickcreateviewdefs.php
1217
1218                 $editviewdefs = "custom/working/modules/".$modname."/metadata/editviewdefs.php";
1219                 $quickcreatedefs = "custom/working/modules/".$modname."/metadata/quickcreatedefs.php";
1220
1221                 if ( !file_exists("modules/".$modname."/metadata/quickcreatedefs.php") &&
1222                          file_exists($editviewdefs) &&
1223                          !file_exists($quickcreatedefs) ){
1224                                 //clone editviewdef and save it in custom/working/modules/metadata
1225                                 $GLOBALS['log']->debug("Copying editviewdefs.php as quickcreatedefs.php for the $modname module in custom/working/modules/$modname/metadata!");
1226                                 if(copy( $editviewdefs, $quickcreatedefs)){
1227                                         if(file_exists($quickcreatedefs) && is_readable($quickcreatedefs)){
1228                                                 $file = file($quickcreatedefs);
1229                                                 //replace 'EditView' with 'QuickCreate'
1230                                                 $fp = fopen($quickcreatedefs,'w');
1231                                                 foreach($file as &$line){
1232                                                         if(preg_match("/^\s*'EditView'\s*=>\s*$/", $line) > 0){
1233                                                                 $line = "'QuickCreate' =>\n";
1234                                                         }
1235                                                         fwrite($fp, $line);
1236                                                 }
1237                                                 //write back.
1238                                                 fclose($fp);
1239                                         }
1240                                         else{
1241                                                 $GLOBALS['log']->debug("Failed to replace 'EditView' with QuickCreate because $quickcreatedefs is either not readable or does not exist.");
1242                                         }
1243                                 }else{
1244                                         $GLOBALS['log']->debug("Failed to copy $editviewdefs to $quickcreatedefs!");
1245                                 }
1246                 }
1247         }
1248 }
1249
1250
1251 function cleanQuery($query, $oci8=false) {
1252         $bad = array(
1253                         "&#039;",
1254                         "&quot;",
1255                         );
1256         $good = array(
1257                         '"',
1258                         "",
1259                         );
1260
1261         $q = str_replace($bad, $good, $query);
1262
1263         return $q;
1264 }
1265
1266 /**
1267  * test perms for CREATE queries
1268  */
1269 function testPermsCreate($type, $out) {
1270         logThis('Checking CREATE TABLE permissions...');
1271         global $db;
1272         global $mod_strings;
1273
1274         switch($type) {
1275                 case 'mysql':
1276                 case 'mssql':
1277                         $db->query('CREATE TABLE temp (id varchar(36))');
1278                         if($db->checkError()) {
1279                                 logThis('cannot CREATE TABLE!');
1280                                 $out['db']['dbNoCreate'] = true;
1281                                 $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_CREATE']}</span></td></tr>";
1282                         }
1283                 break;
1284
1285                 case 'oci8':
1286                 break;
1287         }
1288
1289         return $out;
1290 }
1291
1292 /**
1293  * test perms for INSERT
1294  */
1295 function testPermsInsert($type, $out, $skip=false) {
1296         logThis('Checking INSERT INTO permissions...');
1297         global $db;
1298         global $mod_strings;
1299
1300         switch($type) {
1301                 case 'mysql':
1302                 case 'mssql':
1303                         if(!$skip) {
1304                                 $db->query("INSERT INTO temp (id) VALUES ('abcdef0123456789abcdef0123456789abcd')");
1305                                 if($db->checkError()) {
1306                                         logThis('cannot INSERT INTO!');
1307                                         $out['db']['dbNoInsert'] = true;
1308                                         $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_INSERT']}</span></td></tr>";
1309                                 }
1310                         }
1311                 break;
1312
1313                 case 'oci8':
1314                 break;
1315         }
1316
1317         return $out;
1318 }
1319
1320
1321 /**
1322  * test perms for UPDATE TABLE
1323  */
1324 function testPermsUpdate($type, $out, $skip=false) {
1325         logThis('Checking UPDATE TABLE permissions...');
1326         global $db;
1327         global $mod_strings;
1328
1329         switch($type) {
1330                 case 'mysql':
1331                 case 'mssql':
1332                         if(!$skip) {
1333                                 $db->query("UPDATE temp SET id = '000000000000000000000000000000000000' WHERE id = 'abcdef0123456789abcdef0123456789abcd'");
1334                                 if($db->checkError()) {
1335                                         logThis('cannot UPDATE TABLE!');
1336                                         $out['db']['dbNoUpdate'] = true;
1337                                         $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_UPDATE']}</span></td></tr>";
1338                                 }
1339                         }
1340                 break;
1341
1342                 case 'oci8':
1343                 break;
1344         }
1345
1346         return $out;
1347 }
1348
1349
1350 /**
1351  * test perms for SELECT
1352  */
1353 function testPermsSelect($type, $out, $skip=false) {
1354         logThis('Checking SELECT permissions...');
1355         global $db;
1356         global $mod_strings;
1357
1358         switch($type) {
1359                 case 'mysql':
1360                 case 'mssql':
1361                         $r = $db->query('SELECT id FROM temp');
1362                         if($db->checkError()) {
1363                                 logThis('cannot SELECT!');
1364                                 $out['db']['dbNoSelect'] = true;
1365                                 $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_SELECT']}</span></td></tr>";
1366                         }
1367                         logThis('Checking validity of SELECT results');
1368                         while($a = $db->fetchByAssoc($r)) {
1369                                 if($a['id'] != '000000000000000000000000000000000000') {
1370                                         logThis('results DO NOT MATCH! got: '.$a['id']);
1371                                         $out['db'][] = 'selectFailed';
1372                                         $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_INSERT_FAILED']}</span></td></tr>";
1373                                 }
1374                         }
1375                 break;
1376
1377                 case 'oci8':
1378                 break;
1379         }
1380
1381         return $out;
1382 }
1383
1384
1385
1386 /**
1387  * test perms for DELETE
1388  */
1389 function testPermsDelete($type, $out, $skip=false) {
1390         logThis('Checking DELETE FROM permissions...');
1391         global $db;
1392         global $mod_strings;
1393
1394         switch($type) {
1395                 case 'mysql':
1396                 case 'mssql':
1397                         $db->query("DELETE FROM temp WHERE id = '000000000000000000000000000000000000'");
1398                         if($db->checkError()) {
1399                                 logThis('cannot DELETE FROM!');
1400                                 $out['db']['dbNoDelete'] = true;
1401                                 $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_DELETE']}</span></td></tr>";
1402                         }
1403                 break;
1404
1405                 case 'oci8':
1406                 break;
1407         }
1408
1409         return $out;
1410 }
1411
1412
1413 /**
1414  * test perms for ALTER TABLE ADD COLUMN
1415  */
1416 function testPermsAlterTableAdd($type, $out, $skip=false) {
1417         logThis('Checking ALTER TABLE ADD COLUMN permissions...');
1418         global $db;
1419         global $mod_strings;
1420
1421         switch($type) {
1422                 case 'mysql':
1423                         $db->query('ALTER TABLE temp ADD COLUMN test varchar(100)');
1424                         if($db->checkError()) {
1425                                 logThis('cannot ADD COLUMN!');
1426                                 $out['db']['dbNoAddColumn'] = true;
1427                                 $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_ADD_COLUMN']}</span></td></tr>";
1428                         }
1429                 break;
1430
1431                 case 'mssql':
1432                         $db->query('ALTER TABLE [temp] ADD [test] [varchar] (100)');
1433                         if($db->checkError()) {
1434                                 logThis('cannot ADD COLUMN!');
1435                                 $out['db']['dbNoAddColumn'] = true;
1436                                 $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_ADD_COLUMN']}</span></td></tr>";
1437                         }
1438                 break;
1439
1440                 case 'oci8':
1441                 break;
1442         }
1443
1444         return $out;
1445 }
1446
1447
1448
1449
1450 /**
1451  * test perms for ALTER TABLE ADD COLUMN
1452  */
1453 function testPermsAlterTableChange($type, $out, $skip=false) {
1454         logThis('Checking ALTER TABLE CHANGE COLUMN permissions...');
1455         global $db;
1456         global $mod_strings;
1457
1458         switch($type) {
1459                 case 'mysql':
1460                         $db->query('ALTER TABLE temp CHANGE COLUMN test test varchar(100)');
1461                         if($db->checkError()) {
1462                                 logThis('cannot CHANGE COLUMN!');
1463                                 $out['db']['dbNoChangeColumn'] = true;
1464                                 $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_CHANGE_COLUMN']}</span></td></tr>";
1465                         }
1466                 break;
1467
1468                 case 'mssql':
1469                         $db->query('ALTER TABLE [temp] ALTER COLUMN [test] [varchar] (100)');
1470                         if($db->checkError()) {
1471                                 logThis('cannot CHANGE COLUMN!');
1472                                 $out['db']['dbNoChangeColumn'] = true;
1473                                 $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_CHANGE_COLUMN']}</span></td></tr>";
1474                         }
1475                 break;
1476
1477                 case 'oci8':
1478                 break;
1479         }
1480
1481         return $out;
1482 }
1483
1484
1485
1486 /**
1487  * test perms for ALTER TABLE DROP COLUMN
1488  */
1489 function testPermsAlterTableDrop($type, $out, $skip=false) {
1490         logThis('Checking ALTER TABLE DROP COLUMN permissions...');
1491         global $db;
1492         global $mod_strings;
1493
1494         switch($type) {
1495                 case 'mysql':
1496                 case 'mssql':
1497                         $db->query('ALTER TABLE temp DROP COLUMN test');
1498                         if($db->checkError()) {
1499                                 logThis('cannot DROP COLUMN!');
1500                                 $out['db']['dbNoDropColumn'] = true;
1501                                 $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_DROP_COLUMN']}</span></td></tr>";
1502                         }
1503                 break;
1504
1505                 case 'oci8':
1506                 break;
1507         }
1508
1509         return $out;
1510 }
1511
1512
1513 /**
1514  * test perms for DROP TABLE
1515  */
1516 function testPermsDropTable($type, $out, $skip=false) {
1517         logThis('Checking DROP TABLE permissions...');
1518         global $db;
1519         global $mod_strings;
1520
1521         switch($type) {
1522                 case 'mysql':
1523                 case 'mssql':
1524                         $db->query('DROP TABLE temp');
1525                         if($db->checkError()) {
1526                                 logThis('cannot DROP TABLE!');
1527                                 $out['db']['dbNoDropTable'] = true;
1528                                 $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_DROP_TABLE']}</span></td></tr>";
1529                         }
1530                 break;
1531
1532                 case 'oci8':
1533                 break;
1534         }
1535
1536         return $out;
1537 }
1538
1539
1540
1541 function createMSSQLTemp($table) {
1542         global $sugar_config;
1543         global $db;
1544
1545         $qtest = "SELECT TABLE_NAME tn FROM information.tables WHERE TABLE_NAME = '{$table}__UW_TEMP'";
1546         $rtest = $db->query($qtest);
1547         $atest = $db->fetchByAssoc($rtest);
1548
1549         if(empty($atest)) {
1550                 $tempTable = "CREATE TABLE {$table}__UW_TEMP AS ".$db->limitQuerySql("SELECT * FROM {$table}",0,8);
1551                 logThis("Creating temp table for {$table}: {$tempTable}");
1552                 $db->query($tempTable);
1553         }
1554         else {
1555                 logThis("Found {$table}__UW_TEMP - skipping temp table creation.");
1556         }
1557 }
1558
1559 /**
1560  * Tests an ALTER TABLE query
1561  * @param string table The table name to get DDL
1562  * @param string dbType MySQL, MSSQL, etc.
1563  * @param string query The query to test.
1564  * @return string Non-empty if error found
1565  */
1566 function testQueryAlter($table, $dbType, $query, $newTables) {
1567         logThis('verifying ALTER statement...');
1568         global $db;
1569         global $sugar_config;
1570
1571         if(empty($db)) {
1572                 $db = &DBManagerFactory::getInstance();
1573         }
1574
1575         // Skipping ALTER TABLE [table] DROP PRIMARY KEY because primary keys are not being copied
1576         // over to the temp tables
1577         if(strpos(strtoupper($query), 'DROP PRIMARY KEY') !== false) {
1578                 logThis('Skipping DROP PRIMARY KEY verification');
1579                 return '';
1580         }
1581
1582         if ($dbType == 'mysql'){
1583                 mysql_error(); // initialize errors
1584         }
1585         $error = '';
1586
1587         if(!in_array($table, $newTables)) {
1588                 switch($dbType) {
1589                         case 'mysql':
1590                                 // get DDL
1591                                 logThis('creating temp table for ['.$table.']...');
1592                                 $q = "SHOW CREATE TABLE {$table}";
1593                                 $r = $db->query($q);
1594                                 $a = $db->fetchByAssoc($r);
1595
1596                                 // rewrite DDL with _temp name
1597                                 $cleanQuery = cleanQuery($a['Create Table']);
1598                                 $tempTableQuery = str_replace("CREATE TABLE `{$table}`", "CREATE TABLE `{$table}__uw_temp`", $cleanQuery);
1599                                 $r2 = $db->query($tempTableQuery);
1600
1601                                 // get sample data into the temp table to test for data/constraint conflicts
1602                                 logThis('inserting temp dataset...');
1603                                 $q3 = "INSERT INTO `{$table}__uw_temp` SELECT * FROM `{$table}` LIMIT 10";
1604                                 $r3 = $db->query($q3, false, "Preflight Failed for: {$query}");
1605
1606                                 // test the query on the test table
1607                                 logThis('testing query: ['.$query.']');
1608                                 $tempTableTestQuery = str_replace("ALTER TABLE `{$table}`", "ALTER TABLE `{$table}__uw_temp`", $query);
1609                                 if (strpos($tempTableTestQuery, 'idx') === false) {
1610                                         if(isRunningAgainstTrueTable($tempTableTestQuery)) {
1611                                                 $error = getFormattedError('Could not use a temp table to test query!', $query);
1612                                                 return $error;
1613                                         }
1614
1615                                         logThis('testing query on temp table: ['.$tempTableTestQuery.']');
1616                                         $r4 = $db->query($tempTableTestQuery, false, "Preflight Failed for: {$query}");
1617                                 }
1618                                 else {
1619                                         // test insertion of an index on a table
1620                                         $tempTableTestQuery_idx = str_replace("ADD INDEX `idx_", "ADD INDEX `temp_idx_", $tempTableTestQuery);
1621                                         logThis('testing query on temp table: ['.$tempTableTestQuery_idx.']');
1622                                         $r4 = $db->query($tempTableTestQuery_idx, false, "Preflight Failed for: {$query}");
1623                                 }
1624                                 $mysqlError = mysql_error(); // empty on no-errors
1625                                 if(!empty($mysqlError)) {
1626                                         logThis('*** ERROR: query failed: '.$mysqlError);
1627                                         $error = getFormattedError($mysqlError, $query);
1628                                 }
1629
1630
1631                                 // clean up moved to end of preflight
1632                         break;
1633
1634                         case 'mssql':
1635                                 logThis('mssql found: skipping test query - ['.$query.']');
1636                         break;
1637
1638                         case 'oci8':
1639                                 logThis('Oracle found: skipping test query - ['.$query.']');
1640                         break;
1641                 } // end switch()
1642         } else {
1643                 logThis($table . ' is a new table');
1644         }
1645
1646         logThis('verification done.');
1647         return $error;
1648 }
1649
1650 /**
1651  * Tests an CREATE TABLE query
1652  * @param string table The table name to get DDL
1653  * @param string dbType MySQL, MSSQL, etc.
1654  * @param string query The query to test.
1655  * @return string Non-empty if error found
1656  */
1657 function testQueryCreate($table, $dbType, $query, &$newTables) {
1658         logThis('verifying CREATE statement...');
1659         global $db;
1660         if(empty($db)) {
1661                 $db = &DBManagerFactory::getInstance();
1662         }
1663
1664         $error = '';
1665         switch($dbType) {
1666                 case 'mysql':
1667                         // rewrite DDL with _temp name
1668                         logThis('testing query: ['.$query.']');
1669                         $tempTableQuery = str_replace("CREATE TABLE `{$table}`", "CREATE TABLE `{$table}__uw_temp`", $query);
1670
1671                         if(isRunningAgainstTrueTable($tempTableQuery)) {
1672                                 $error = getFormattedError('Could not use a temp table to test query!', $query);
1673                                 return $error;
1674                         }
1675
1676                         $r4 = $db->query($tempTableQuery, false, "Preflight Failed for: {$query}");
1677
1678                         $error = mysql_error(); // empty on no-errors
1679                         if(!empty($error)) {
1680                                 logThis('*** ERROR: query failed.');
1681                                 $error = getFormattedError($error, $query);
1682                         }
1683
1684                         // check if table exists
1685                         logThis('testing for table: '.$table);
1686                         $q1 = "DESC `{$table}`";
1687                         $r1 = $db->query($q1);
1688
1689                         $mysqlError = mysql_error();
1690                         if(empty($mysqlError)) {
1691                                 logThis('*** ERROR: table already exists!: '.$table);
1692                                 $error = getFormattedError('table exists', $query);
1693                         }
1694                         else {
1695                                 logThis('NEW TABLE: '.$query);
1696                                 $newTables[] = $table;
1697                         }
1698                 break;
1699
1700                 case 'mssql':
1701                         logThis('mssql found: skipping test query - ['.$query.']');
1702                 break;
1703
1704                 case 'oci8':
1705                                 logThis('Oracle found: skipping test query - ['.$query.']');
1706                         break;
1707         }
1708         return $error;
1709 }
1710
1711 /**
1712  * Tests an DELETE FROM query
1713  * @param string table The table name to get DDL
1714  * @param string dbType MySQL, MSSQL, etc.
1715  * @param string query The query to test.
1716  * @return string Non-empty if error found
1717  */
1718 function testQueryDelete($table, $dbType, $query) {
1719         logThis('verifying DELETE statements');
1720         global $db;
1721         if(empty($db)) {
1722                 $db = &DBManagerFactory::getInstance();
1723         }
1724
1725         $error = '';
1726
1727         switch($dbType) {
1728                 case 'mysql':
1729                         // get DDL
1730                         logThis('creating temp table...');
1731                         $q = "SHOW CREATE TABLE {$table}";
1732                         $r = $db->query($q);
1733                         $a = $db->fetchByAssoc($r);
1734
1735                         // rewrite DDL with _temp name
1736                         $cleanQuery = cleanQuery($a['Create Table']);
1737                         $tempTableQuery = str_replace("CREATE TABLE `{$table}`", "CREATE TABLE `{$table}__uw_temp`", $cleanQuery);
1738                         $r2 = $db->query($tempTableQuery);
1739
1740                         // get sample data into the temp table to test for data/constraint conflicts
1741                         logThis('inserting temp dataset...');
1742                         $q3 = "INSERT INTO `{$table}__uw_temp` SELECT * FROM `{$table}` LIMIT 10";
1743                         $r3 = $db->query($q3);
1744
1745                         // test the query on the test table
1746                         logThis('testing query: ['.$query.']');
1747                         $tempTableTestQuery = str_replace("DELETE FROM `{$table}`", "DELETE FROM `{$table}__uw_temp`", $query);
1748
1749                         if(isRunningAgainstTrueTable($tempTableTestQuery)) {
1750                                 $error = getFormattedError('Could not use a temp table to test query!', $tempTableTestQuery);
1751                                 return $error;
1752                         }
1753
1754                         $r4 = $db->query($tempTableTestQuery, false, "Preflight Failed for: {$query}");
1755                         $error = mysql_error(); // empty on no-errors
1756                         if(!empty($error)) {
1757                                 logThis('*** ERROR: query failed.');
1758                                 $error = getFormattedError($error, $query);
1759                         }
1760                 break;
1761
1762                 case 'mssql':
1763                         logThis('mssql found: skipping test query - ['.$query.']');
1764                 break;
1765
1766                 case 'oci8':
1767                                 logThis('Oracle found: skipping test query - ['.$query.']');
1768                         break;
1769         }
1770         logThis('verification done.');
1771         return $error;
1772 }
1773
1774 /**
1775  * Tests a DROP TABLE query
1776  *
1777  */
1778 function testQueryDrop($table, $dbType, $query) {
1779         logThis('verifying DROP TABLE statement');
1780         global $db;
1781         if(empty($db)) {
1782                 $db = &DBManagerFactory::getInstance();
1783         }
1784
1785         $error = '';
1786
1787         switch($dbType) {
1788                 case 'mysql':
1789                         // get DDL
1790                         logThis('creating temp table...');
1791                         $q = "SHOW CREATE TABLE {$table}";
1792                         $r = $db->query($q);
1793                         $a = $db->fetchByAssoc($r);
1794
1795                         // rewrite DDL with _temp name
1796                         $cleanQuery = cleanQuery($a['Create Table']);
1797                         $tempTableQuery = str_replace("CREATE TABLE `{$table}`", "CREATE TABLE `{$table}__uw_temp`", $cleanQuery);
1798                         $r2 = $db->query($tempTableQuery);
1799
1800                         // get sample data into the temp table to test for data/constraint conflicts
1801                         logThis('inserting temp dataset...');
1802                         $query = stripQuotes($query, $table);
1803                         $q3 = "INSERT INTO `{$table}__uw_temp` SELECT * FROM `{$table}` LIMIT 10";
1804                         $r3 = $db->query($q3);
1805
1806                         // test the query on the test table
1807                         logThis('testing query: ['.$query.']');
1808                         $tempTableTestQuery = str_replace("DROP TABLE `{$table}`", "DROP TABLE `{$table}__uw_temp`", $query);
1809
1810                         // make sure the test query is running against a temp table
1811                         if(isRunningAgainstTrueTable($tempTableTestQuery)) {
1812                                 $error = getFormattedError('Could not use a temp table to test query!', $tempTableTestQuery);
1813                                 return $error;
1814                         }
1815
1816                         $r4 = $db->query($tempTableTestQuery, false, "Preflight Failed for: {$query}");
1817                         $error = mysql_error(); // empty on no-errors
1818                         if(!empty($error)) {
1819                                 logThis('*** ERROR: query failed.');
1820                                 $error = getFormattedError($error, $query);
1821                         }
1822                 break;
1823
1824                 case 'mssql':
1825                         logThis('mssql found: skipping test query - ['.$query.']');
1826                 break;
1827
1828                 case 'oci8':
1829                                 logThis('Oracle found: skipping test query - ['.$query.']');
1830                         break;
1831         }
1832         logThis('verification done.');
1833         return $error;
1834 }
1835
1836 /**
1837  * Tests an INSERT INTO query
1838  * @param string table The table name to get DDL
1839  * @param string dbType MySQL, MSSQL, etc.
1840  * @param string query The query to test.
1841  * @return string Non-empty if error found
1842  */
1843 function testQueryInsert($table, $dbType, $query) {
1844         logThis('verifying INSERT statement...');
1845         global $db;
1846         if(empty($db)) {
1847                 $db = &DBManagerFactory::getInstance();
1848         }
1849
1850         $error = '';
1851
1852         switch($dbType) {
1853                 case 'mysql':
1854                         // get DDL
1855                         $q = "SHOW CREATE TABLE {$table}";
1856                         $r = $db->query($q);
1857                         $a = $db->fetchByAssoc($r);
1858
1859                         // rewrite DDL with _temp name
1860                         $cleanQuery = cleanQuery($a['Create Table']);
1861                         $tempTableQuery = str_replace("CREATE TABLE `{$table}`", "CREATE TABLE `{$table}__uw_temp`", $cleanQuery);
1862                         $r2 = $db->query($tempTableQuery);
1863
1864                         // test the query on the test table
1865                         logThis('testing query: ['.$query.']');
1866                         $tempTableTestQuery = str_replace("INSERT INTO `{$table}`", "INSERT INTO `{$table}__uw_temp`", $query);
1867
1868                         // make sure the test query is running against a temp table
1869                         if(isRunningAgainstTrueTable($tempTableTestQuery)) {
1870                                 $error = getFormattedError('Could not use a temp table to test query!', $tempTableTestQuery);
1871                                 return $error;
1872                         }
1873
1874                         $r4 = $db->query($tempTableTestQuery, false, "Preflight Failed for: {$query}");
1875                         $error = mysql_error(); // empty on no-errors
1876                         if(!empty($error)) {
1877                                 logThis('*** ERROR: query failed.');
1878                                 $error = getFormattedError($error, $query);
1879                         }
1880                 break;
1881
1882                 case 'mssql':
1883                         logThis('mssql found: skipping test query - ['.$query.']');
1884                 break;
1885
1886                 case 'oci8':
1887                                 logThis('Oracle found: skipping test query - ['.$query.']');
1888                         break;
1889         }
1890         logThis('verification done.');
1891         return $error;
1892 }
1893
1894
1895 /**
1896  * Tests an UPDATE TABLE query
1897  * @param string table The table name to get DDL
1898  * @param string dbType MySQL, MSSQL, etc.
1899  * @param string query The query to test.
1900  * @return string Non-empty if error found
1901  */
1902 function testQueryUpdate($table, $dbType, $query) {
1903         logThis('verifying UPDATE TABLE statement...');
1904         global $db;
1905         if(empty($db)) {
1906                 $db = &DBManagerFactory::getInstance();
1907         }
1908
1909         $error = '';
1910
1911         switch($dbType) {
1912                 case 'mysql':
1913                         // get DDL
1914                         $q = "SHOW CREATE TABLE {$table}";
1915                         $r = $db->query($q);
1916                         $a = $db->fetchByAssoc($r);
1917
1918                         // rewrite DDL with _temp name
1919                         $cleanQuery = cleanQuery($a['Create Table']);
1920                         $tempTableQuery = str_replace("CREATE TABLE `{$table}`", "CREATE TABLE `{$table}__uw_temp`", $cleanQuery);
1921                         $r2 = $db->query($tempTableQuery);
1922
1923                         // get sample data into the temp table to test for data/constraint conflicts
1924                         logThis('inserting temp dataset...');
1925                         $q3 = "INSERT INTO `{$table}__uw_temp` SELECT * FROM `{$table}` LIMIT 10";
1926                         $r3 = $db->query($q3, false, "Preflight Failed for: {$query}");
1927
1928                         // test the query on the test table
1929                         logThis('testing query: ['.$query.']');
1930                         $tempTableTestQuery = str_replace("UPDATE `{$table}`", "UPDATE `{$table}__uw_temp`", $query);
1931
1932                         // make sure the test query is running against a temp table
1933                         if(isRunningAgainstTrueTable($tempTableTestQuery)) {
1934                                 $error = getFormattedError('Could not use a temp table to test query!', $tempTableTestQuery);
1935                                 return $error;
1936                         }
1937
1938                         $r4 = $db->query($tempTableTestQuery, false, "Preflight Failed for: {$query}");
1939                         $error = mysql_error(); // empty on no-errors
1940                         if(!empty($error)) {
1941                                 logThis('*** ERROR: query failed.');
1942                                 $error = getFormattedError($error, $query);
1943                         }
1944                 break;
1945
1946                 case 'mssql':
1947                 break;
1948
1949                 case 'oci8':
1950                                 logThis('Oracle found: skipping test query - ['.$query.']');
1951                         break;
1952         }
1953         logThis('verification done.');
1954         return $error;
1955 }
1956
1957
1958 /**
1959  * strip queries of single and double quotes
1960  */
1961 function stripQuotes($query, $table) {
1962         $queryStrip = '';
1963
1964         $start = strpos($query, $table);
1965
1966         if(substr($query, ($start - 1), 1) != ' ') {
1967                 $queryStrip  = substr($query, 0, ($start-2));
1968                 $queryStrip .= " {$table} ";
1969                 $queryStrip .= substr($query, ($start + strlen($table) + 2), strlen($query));
1970         }
1971
1972         return (empty($queryStrip)) ? $query : $queryStrip;
1973 }
1974
1975 /**
1976  * ensures that a __UW_TEMP table test SQL is running against a temp table, not the real thing
1977  * @param string query
1978  * @return bool false if it is a good query
1979  */
1980 function isRunningAgainstTrueTable($query) {
1981         $query = strtoupper($query);
1982         if(strpos($query, '__UW_TEMP') === false) {
1983                 logThis('***ERROR: test query is NOT running against a temp table!!!! -> '.$query);
1984                 return true;
1985         }
1986         return false;
1987 }
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997 /**
1998  * cleans up temp tables created during schema test phase
1999  */
2000 function testCleanUp($dbType) {
2001         logThis('Cleaning up temporary tables...');
2002
2003         global $db;
2004         if(empty($db)) {
2005                 $db = &DBManagerFactory::getInstance();
2006         }
2007
2008         $error = '';
2009         switch($dbType) {
2010                 case 'mysql':
2011                         $q = 'SHOW TABLES LIKE "%__uw_temp"';
2012                         $r = $db->query($q, false, "Preflight Failed for: {$q}");
2013
2014                         // using raw mysql_command to use integer index
2015                         while($a = $db->fetchByAssoc($r)) {
2016                                 logThis('Dropping table: '.$a[0]);
2017                                 $qClean = "DROP TABLE {$a[0]}";
2018                                 $rClean = $db->query($qClean);
2019                         }
2020                 break;
2021
2022                 case 'mssql':
2023                 break;
2024
2025                 case 'oci8':
2026                 break;
2027         }
2028         logThis('Done cleaning up temp tables.');
2029         return $error;
2030 }
2031
2032
2033 function getFormattedError($error, $query) {
2034         $error = "<div><b>".$error;
2035         $error .= "</b>::{$query}</div>";
2036
2037         return $error;
2038 }
2039
2040
2041
2042 /**
2043  * parses a query finding the table name
2044  * @param string query The query
2045  * @return string table The table
2046  */
2047 function getTableFromQuery($query) {
2048         $standardQueries = array('ALTER TABLE', 'DROP TABLE', 'CREATE TABLE', 'INSERT INTO', 'UPDATE', 'DELETE FROM');
2049         $query = preg_replace("/[^A-Za-z0-9\_\s]/", "", $query);
2050         $query = trim(str_replace($standardQueries, '', $query));
2051
2052         $firstSpc = strpos($query, " ");
2053         $end = ($firstSpc > 0) ? $firstSpc : strlen($query);
2054         $table = substr($query, 0, $end);
2055
2056         return $table;
2057 }
2058
2059 //prelicense check
2060
2061 function preLicenseCheck() {
2062         require_once('modules/UpgradeWizard/uw_files.php');
2063
2064         global $sugar_config;
2065         global $mod_strings;
2066         global $sugar_version;
2067
2068         if(!isset($sugar_version) || empty($sugar_version)) {
2069                 require_once('./sugar_version.php');
2070         }
2071
2072 if(!isset($_SESSION['unzip_dir']) || empty($_SESSION['unzip_dir'])) {
2073                 logThis('unzipping files in upgrade archive...');
2074                 $errors                                 = array();
2075                 $base_upgrade_dir               = $sugar_config['upload_dir'] . "/upgrades";
2076                 $base_tmp_upgrade_dir   = "$base_upgrade_dir/temp";
2077                 $unzip_dir = '';
2078                 //also come up with mechanism to read from upgrade-progress file
2079                 if(!isset($_SESSION['install_file']) || empty($_SESSION['install_file']) || !is_file($_SESSION['install_file'])) {
2080                         /*
2081                         if ($handle = opendir(clean_path($sugar_config['upload_dir']))) {
2082                         while (false !== ($file = readdir($handle))) {
2083                         if($file !="." && $file !="..") {
2084                                    $far = explode(".",$file);
2085                                    if($far[sizeof($far)-1] == 'zip') {
2086                                                 echo $sugar_config['upload_dir'].'/'.$file;
2087                                                 $_SESSION['install_file'] =  $sugar_config['upload_dir'].'/'.$file;
2088                                    }
2089                          }
2090                         }
2091                 }
2092                 */
2093                         if (file_exists(clean_path($base_tmp_upgrade_dir)) && $handle = opendir(clean_path($base_tmp_upgrade_dir))) {
2094                                 while (false !== ($file = readdir($handle))) {
2095                                 if($file !="." && $file !="..") {
2096                                          //echo $base_tmp_upgrade_dir."/".$file.'</br>';
2097                                          if(is_file($base_tmp_upgrade_dir."/".$file."/manifest.php")){
2098                                                 require_once($base_tmp_upgrade_dir."/".$file."/manifest.php");
2099                                                 $package_name= $manifest['copy_files']['from_dir'];
2100                                                 //echo file_exists($base_tmp_upgrade_dir."/".$file."/".$package_name).'</br>';
2101                                                 if(file_exists($base_tmp_upgrade_dir."/".$file."/".$package_name) && file_exists($base_tmp_upgrade_dir."/".$file."/scripts") && file_exists($base_tmp_upgrade_dir."/".$file."/manifest.php")){
2102                                                         //echo 'Yeah this the directory '. $base_tmp_upgrade_dir."/".$file;
2103                                                         $unzip_dir = $base_tmp_upgrade_dir."/".$file;
2104                                                         if(file_exists($sugar_config['upload_dir'].'/upgrades/patch/'.$package_name.'.zip')){
2105                                                                 $_SESSION['install_file'] = $sugar_config['upload_dir'].'/upgrades/patch/'.$package_name.'.zip';
2106                                                                 break;
2107                                                         }
2108                                                 }
2109                                           }
2110                                 }
2111                         }
2112                         }
2113                 }
2114         if(!isset($_SESSION['install_file']) || empty($_SESSION['install_file'])){
2115                 unlinkTempFiles();
2116                 resetUwSession();
2117                 echo 'Upload File not found so redirecting to Upgrade Start ';
2118                 $redirect_new_wizard = $sugar_config['site_url' ].'/index.php?module=UpgradeWizard&action=index';
2119                 echo '<form name="redirect" action="' .$redirect_new_wizard. '"  method="POST">';
2120 $upgrade_directories_not_found =<<<eoq
2121         <table cellpadding="3" cellspacing="0" border="0">
2122                 <tr>
2123                         <th colspan="2" align="left">
2124                                 <span class='error'><b>'Upload file missing or has been deleted. Refresh the page to go back to UpgradeWizard start'</b></span>
2125                         </th>
2126                 </tr>
2127         </table>
2128 eoq;
2129 $uwMain = $upgrade_directories_not_found;
2130                                 return '';
2131         }
2132                 $install_file                   = urldecode( $_SESSION['install_file'] );
2133                 $show_files                             = true;
2134                 if(empty($unzip_dir)){
2135                         $unzip_dir                              = mk_temp_dir( $base_tmp_upgrade_dir );
2136                 }
2137                 $zip_from_dir                   = ".";
2138                 $zip_to_dir                             = ".";
2139                 $zip_force_copy                 = array();
2140
2141                 if(!$unzip_dir){
2142                         logThis('Could not create a temporary directory using mk_temp_dir( $base_tmp_upgrade_dir )');
2143                         die($mod_strings['ERR_UW_NO_CREATE_TMP_DIR']);
2144                 }
2145
2146                 //double check whether unzipped .
2147                 if(file_exists($unzip_dir ."/scripts") && file_exists($unzip_dir."/manifest.php")){
2148                 //already unzipped
2149                 }
2150                 else{
2151                         unzip( $install_file, $unzip_dir );
2152                 }
2153
2154                 // assumption -- already validated manifest.php at time of upload
2155                 require_once( "$unzip_dir/manifest.php" );
2156
2157                 if( isset( $manifest['copy_files']['from_dir'] ) && $manifest['copy_files']['from_dir'] != "" ){
2158                     $zip_from_dir   = $manifest['copy_files']['from_dir'];
2159                 }
2160                 if( isset( $manifest['copy_files']['to_dir'] ) && $manifest['copy_files']['to_dir'] != "" ){
2161                     $zip_to_dir     = $manifest['copy_files']['to_dir'];
2162                 }
2163                 if( isset( $manifest['copy_files']['force_copy'] ) && $manifest['copy_files']['force_copy'] != "" ){
2164                     $zip_force_copy     = $manifest['copy_files']['force_copy'];
2165                 }
2166                 if( isset( $manifest['version'] ) ){
2167                     $version    = $manifest['version'];
2168                 }
2169                 if( !is_writable( "config.php" ) ){
2170                         return $mod_strings['ERR_UW_CONFIG'];
2171                 }
2172
2173                 $_SESSION['unzip_dir'] = clean_path($unzip_dir);
2174                 $_SESSION['zip_from_dir'] = clean_path($zip_from_dir);
2175                 logThis('unzip done.');
2176         } else {
2177                 $unzip_dir = $_SESSION['unzip_dir'];
2178                 $zip_from_dir = $_SESSION['zip_from_dir'];
2179         }
2180
2181     //check if $_SESSION['unzip_dir'] and $_SESSION['zip_from_dir'] exist
2182         if(!isset($_SESSION['unzip_dir']) || !file_exists($_SESSION['unzip_dir'])
2183                 || !isset($_SESSION['install_file']) || empty($_SESSION['install_file']) || !file_exists($_SESSION['install_file'])){
2184                     //redirect to start
2185             unlinkTempFiles();
2186                 resetUwSession();
2187                 echo 'Upload File not found so redirecting to Upgrade Start ';
2188                 $redirect_new_wizard = $sugar_config['site_url' ].'/index.php?module=UpgradeWizard&action=index';
2189                 echo '<form name="redirect" action="' .$redirect_new_wizard. '"  method="POST">';
2190 $upgrade_directories_not_found =<<<eoq
2191         <table cellpadding="3" cellspacing="0" border="0">
2192                 <tr>
2193                         <th colspan="2" align="left">
2194                                 <span class='error'><b>'Upload file missing or has been deleted. Refresh the page to go back to UpgradeWizard start'</b></span>
2195                         </th>
2196                 </tr>
2197         </table>
2198 eoq;
2199 $uwMain = $upgrade_directories_not_found;
2200                                 return '';
2201         }
2202
2203         $parserFiles = array();
2204
2205         if(file_exists(clean_path($unzip_dir.'/'.$zip_from_dir."/include/SugarFields"))) {
2206                 $parserFiles = findAllFiles(clean_path($unzip_dir.'/'.$zip_from_dir."/include/SugarFields"), $parserFiles);
2207         }
2208
2209      $cwd = clean_path(getcwd());
2210         foreach($parserFiles as $file) {
2211                 $srcFile = clean_path($file);
2212                 //$targetFile = clean_path(getcwd() . '/' . $srcFile);
2213         if (strpos($srcFile,".svn") !== false) {
2214                   //do nothing
2215             }
2216             else{
2217             $targetFile = str_replace(clean_path($unzip_dir.'/'.$zip_from_dir), $cwd, $srcFile);
2218
2219                 if(!is_dir(dirname($targetFile))) {
2220                         mkdir_recursive(dirname($targetFile)); // make sure the directory exists
2221                 }
2222
2223                 if(!file_exists($targetFile))
2224                  {
2225                         // handle sugar_version.php
2226                         // C.L. - Added check for portal directory
2227                         if(strpos($targetFile, 'sugar_version.php') !== false && !preg_match('/\/portal\/sugar_version\.php$/i', $targetFile)) {
2228                                 logThis('Skipping "sugar_version.php" - file copy will occur at end of successful upgrade', $path);
2229                                 $_SESSION['sugar_version_file'] = $srcFile;
2230                                 continue;
2231                         }
2232
2233                         logThis('Copying file to destination: ' . $targetFile);
2234
2235                         if(!copy($srcFile, $targetFile)) {
2236                                 logThis('*** ERROR: could not copy file: ' . $targetFile);
2237                         } else {
2238                                 $copiedFiles[] = $targetFile;
2239                         }
2240                 } else {
2241                         logThis('Skipping file: ' . $targetFile);
2242                         //$skippedFiles[] = $targetFile;
2243                 }
2244            }
2245          }
2246
2247     //Also copy the SugarMerge files
2248         if(file_exists(clean_path($unzip_dir.'/'.$zip_from_dir."/UpgradeWizard510Files"))) {
2249                 $parserFiles = findAllFiles(clean_path($unzip_dir.'/'.$zip_from_dir."/UpgradeWizard510Files"), $parserFiles);
2250                 foreach($parserFiles as $file) {
2251                         $srcFile = clean_path($file);
2252                         //$targetFile = clean_path(getcwd() . '/' . $srcFile);
2253                 if (strpos($srcFile,".svn") !== false) {
2254                           //do nothing
2255                     }
2256                     else{
2257                             $targetFile = str_replace(clean_path($unzip_dir.'/'.$zip_from_dir."/UpgradeWizard510Files"), $cwd, $srcFile);
2258                                 if(!is_dir(dirname($targetFile))) {
2259                                         mkdir_recursive(dirname($targetFile)); // make sure the directory exists
2260                                 }
2261                                 logThis('updating UpgradeWizard code: '.$targetFile);
2262                                 copy_recursive($file, $targetFile);
2263                     }
2264                 }
2265     }
2266     logThis ('is SugarConfig there '.file_exists(clean_path($unzip_dir.'/'.$zip_from_dir."/include/SugarObjects/SugarConfig.php")));
2267         if(file_exists(clean_path($unzip_dir.'/'.$zip_from_dir."/include/SugarObjects/SugarConfig.php"))) {
2268                 $file = clean_path($unzip_dir.'/'.$zip_from_dir."/include/SugarObjects/SugarConfig.php");
2269                 $destFile = str_replace(clean_path($unzip_dir.'/'.$zip_from_dir), $cwd, $file);
2270                 if(!is_dir(dirname($destFile))) {
2271                         mkdir_recursive(dirname($destFile)); // make sure the directory exists
2272                 }
2273         copy($file,$destFile);
2274         //also copy include utils array utils
2275         $file = clean_path($unzip_dir.'/'.$zip_from_dir."/include/utils/array_utils.php");
2276                 $destFile = str_replace(clean_path($unzip_dir.'/'.$zip_from_dir), $cwd, $file);
2277                 if(!is_dir(dirname($destFile))) {
2278                         mkdir_recursive(dirname($destFile)); // make sure the directory exists
2279                 }
2280         copy($file,$destFile);
2281         }
2282 }
2283
2284
2285 function preflightCheck() {
2286         require_once('modules/UpgradeWizard/uw_files.php');
2287
2288         global $sugar_config;
2289         global $mod_strings;
2290         global $sugar_version;
2291
2292         if(!isset($sugar_version) || empty($sugar_version)) {
2293                 require_once('./sugar_version.php');
2294         }
2295
2296         unset($_SESSION['rebuild_relationships']);
2297         unset($_SESSION['rebuild_extensions']);
2298
2299         // don't bother if are rechecking
2300         $manualDiff                     = array();
2301         if(!isset($_SESSION['unzip_dir']) || empty($_SESSION['unzip_dir'])) {
2302                 logThis('unzipping files in upgrade archive...');
2303                 $errors                                 = array();
2304                 $base_upgrade_dir               = $sugar_config['upload_dir'] . "/upgrades";
2305                 $base_tmp_upgrade_dir   = "$base_upgrade_dir/temp";
2306                 $unzip_dir = '';
2307                 //Following is if User logged out unexpectedly and then logged into UpgradeWizard again.
2308                 //also come up with mechanism to read from upgrade-progress file.
2309                 if(!isset($_SESSION['install_file']) || empty($_SESSION['install_file']) || !is_file($_SESSION['install_file'])) {
2310                         if (file_exists(clean_path($base_tmp_upgrade_dir)) && $handle = opendir(clean_path($base_tmp_upgrade_dir))) {
2311                         while (false !== ($file = readdir($handle))) {
2312                                 if($file !="." && $file !="..") {
2313                                          //echo $base_tmp_upgrade_dir."/".$file.'</br>';
2314                                          if(is_file($base_tmp_upgrade_dir."/".$file."/manifest.php")){
2315                                                 require_once($base_tmp_upgrade_dir."/".$file."/manifest.php");
2316                                                 $package_name= $manifest['copy_files']['from_dir'];
2317                                                 //echo file_exists($base_tmp_upgrade_dir."/".$file."/".$package_name).'</br>';
2318                                                 if(file_exists($base_tmp_upgrade_dir."/".$file."/".$package_name) && file_exists($base_tmp_upgrade_dir."/".$file."/scripts") && file_exists($base_tmp_upgrade_dir."/".$file."/manifest.php")){
2319                                                         //echo 'Yeah this the directory '. $base_tmp_upgrade_dir."/".$file;
2320                                                         $unzip_dir = $base_tmp_upgrade_dir."/".$file;
2321                                                         if(file_exists($sugar_config['upload_dir'].'/upgrades/patch/'.$package_name.'.zip')){
2322                                                                 $_SESSION['install_file'] = $sugar_config['upload_dir'].'/upgrades/patch/'.$package_name.'.zip';
2323                                                                 break;
2324                                                         }
2325                                                 }
2326                                           }
2327                                 }
2328                         }
2329                         }
2330                 }
2331         if(!isset($_SESSION['install_file']) || empty($_SESSION['install_file'])){
2332                 unlinkTempFiles();
2333                 resetUwSession();
2334                 echo 'Upload File not found so redirecting to Upgrade Start ';
2335                 $redirect_new_wizard = $sugar_config['site_url' ].'/index.php?module=UpgradeWizard&action=index';
2336                 echo '<form name="redirect" action="' .$redirect_new_wizard. '"  method="POST">';
2337 $upgrade_directories_not_found =<<<eoq
2338         <table cellpadding="3" cellspacing="0" border="0">
2339                 <tr>
2340                         <th colspan="2" align="left">
2341                                 <span class='error'><b>'Upload file missing or has been deleted. Refresh the page to go back to UpgradeWizard start'</b></span>
2342                         </th>
2343                 </tr>
2344         </table>
2345 eoq;
2346 $uwMain = $upgrade_directories_not_found;
2347                                 return '';
2348
2349         }
2350                 $install_file                   = urldecode( $_SESSION['install_file'] );
2351                 $show_files                             = true;
2352                 if(empty($unzip_dir)){
2353                         $unzip_dir                              = mk_temp_dir( $base_tmp_upgrade_dir );
2354                 }
2355                 $zip_from_dir                   = ".";
2356                 $zip_to_dir                             = ".";
2357                 $zip_force_copy                 = array();
2358
2359                 if(!$unzip_dir){
2360                         logThis('Could not create a temporary directory using mk_temp_dir( $base_tmp_upgrade_dir )');
2361                         die($mod_strings['ERR_UW_NO_CREATE_TMP_DIR']);
2362                 }
2363
2364                 //double check whether unzipped .
2365                 if(file_exists($unzip_dir ."/scripts") && file_exists($unzip_dir."/manifest.php")){
2366                 //already unzipped
2367                 }
2368                 else{
2369                         unzip( $install_file, $unzip_dir );
2370                 }
2371
2372                 // assumption -- already validated manifest.php at time of upload
2373                 require_once( "$unzip_dir/manifest.php" );
2374
2375                 if( isset( $manifest['copy_files']['from_dir'] ) && $manifest['copy_files']['from_dir'] != "" ){
2376                     $zip_from_dir   = $manifest['copy_files']['from_dir'];
2377                 }
2378                 if( isset( $manifest['copy_files']['to_dir'] ) && $manifest['copy_files']['to_dir'] != "" ){
2379                     $zip_to_dir     = $manifest['copy_files']['to_dir'];
2380                 }
2381                 if( isset( $manifest['copy_files']['force_copy'] ) && $manifest['copy_files']['force_copy'] != "" ){
2382                     $zip_force_copy     = $manifest['copy_files']['force_copy'];
2383                 }
2384                 if( isset( $manifest['version'] ) ){
2385                     $version    = $manifest['version'];
2386                 }
2387                 if( !is_writable( "config.php" ) ){
2388                         return $mod_strings['ERR_UW_CONFIG'];
2389                 }
2390
2391                 $_SESSION['unzip_dir'] = clean_path($unzip_dir);
2392                 $_SESSION['zip_from_dir'] = clean_path($zip_from_dir);
2393
2394          //logThis('unzip done.');
2395         } else {
2396                 $unzip_dir = $_SESSION['unzip_dir'];
2397                 $zip_from_dir = $_SESSION['zip_from_dir'];
2398         }
2399         //check if $_SESSION['unzip_dir'] and $_SESSION['zip_from_dir'] exist
2400         if(!isset($_SESSION['unzip_dir']) || !file_exists($_SESSION['unzip_dir'])
2401                 || !isset($_SESSION['install_file']) || empty($_SESSION['install_file']) || !file_exists($_SESSION['install_file'])){
2402                     //redirect to start
2403             unlinkTempFiles();
2404                 resetUwSession();
2405                 echo 'Upload File not found so redirecting to Upgrade Start ';
2406                 $redirect_new_wizard = $sugar_config['site_url' ].'/index.php?module=UpgradeWizard&action=index';
2407                 echo '<form name="redirect" action="' .$redirect_new_wizard. '"  method="POST">';
2408 $upgrade_directories_not_found =<<<eoq
2409         <table cellpadding="3" cellspacing="0" border="0">
2410                 <tr>
2411                         <th colspan="2" align="left">
2412                                 <span class='error'><b>'Upload file missing or has been deleted. Refresh the page to go back to UpgradeWizard start'</b></span>
2413                         </th>
2414                 </tr>
2415         </table>
2416 eoq;
2417 $uwMain = $upgrade_directories_not_found;
2418                                 return '';
2419         }
2420         //copy minimum required files
2421         fileCopy('include/utils/sugar_file_utils.php');
2422
2423
2424         if(file_exists('include/utils/file_utils.php')){
2425
2426         }
2427         $upgradeFiles = findAllFiles(clean_path("$unzip_dir/$zip_from_dir"), array());
2428         $cache_html_files= array();
2429         if(is_dir("{$GLOBALS['sugar_config']['cache_dir']}layout")){
2430          //$cache_html_files = findAllFilesRelative( "cache/layout", array());
2431         }
2432
2433         // get md5 sums
2434         $md5_string = array();
2435         if(file_exists(clean_path(getcwd().'/files.md5'))){
2436                 require(clean_path(getcwd().'/files.md5'));
2437         }
2438
2439         // file preflight checks
2440         logThis('verifying md5 checksums for files...');
2441         foreach($upgradeFiles as $file) {
2442                 if(in_array(str_replace(clean_path("$unzip_dir/$zip_from_dir") . "/", '', $file), $uw_files))
2443                         continue; // skip already loaded files
2444
2445                 if(strpos($file, '.md5'))
2446                         continue; // skip md5 file
2447
2448                 // normalize file paths
2449                 $file = clean_path($file);
2450
2451                 // check that we can move/delete the upgraded file
2452                 if(!is_writable($file)) {
2453                         $errors[] = $mod_strings['ERR_UW_FILE_NOT_WRITABLE'].": ".$file;
2454                 }
2455                 // check that destination files are writable
2456                 $destFile = getcwd().str_replace(clean_path($unzip_dir.'/'.$zip_from_dir), '', $file);
2457
2458                 if(is_file($destFile)) { // of course it needs to exist first...
2459                         if(!is_writable($destFile)) {
2460                                 $errors[] = $mod_strings['ERR_UW_FILE_NOT_WRITABLE'].": ".$destFile;
2461                         }
2462                 }
2463
2464                 ///////////////////////////////////////////////////////////////////////
2465                 ////    DIFFS
2466                 // compare md5s and build up a manual merge list
2467                 $targetFile = clean_path(".".str_replace(getcwd(),'',$destFile));
2468                 $targetMd5 = '0';
2469                 if(is_file($destFile)) {
2470                         if(strpos($targetFile, '.php')) {
2471                                 // handle PHP files that were hit with the security regex
2472                                 $fp = '';
2473                                 if(function_exists('sugar_fopen')){
2474                                         $fp = sugar_fopen($destFile, 'r');
2475                                 }
2476                                 else{
2477                                         $fp = fopen($destFile, 'r');
2478                                 }
2479                                 $filesize = filesize($destFile);
2480                                 if($filesize > 0) {
2481                                         $fileContents = fread($fp, $filesize);
2482                                         $targetMd5 = md5($fileContents);
2483                                 }
2484                         } else {
2485                                 $targetMd5 = md5_file($destFile);
2486                         }
2487                 }
2488
2489                 if(isset($md5_string[$targetFile]) && $md5_string[$targetFile] != $targetMd5) {
2490                         logThis('found a file with a differing md5: ['.$targetFile.']');
2491                         $manualDiff[] = $destFile;
2492                 }
2493                 ////    END DIFFS
2494                 ///////////////////////////////////////////////////////////////////////
2495         }
2496         logThis('md5 verification done.');
2497         $errors['manual'] = $manualDiff;
2498
2499         return $errors;
2500 }
2501
2502 function fileCopy($file_path){
2503         if(file_exists(clean_path($_SESSION['unzip_dir'].'/'.$_SESSION['zip_from_dir'].'/'.$file_path))) {
2504                 $file = clean_path($_SESSION['unzip_dir'].'/'.$_SESSION['zip_from_dir'].'/'.$file_path);
2505                 $destFile = str_replace(clean_path($_SESSION['unzip_dir'].'/'.$_SESSION['zip_from_dir']),  clean_path(getcwd()), $file);
2506         if(!is_dir(dirname($destFile))) {
2507                 mkdir_recursive(dirname($destFile)); // make sure the directory exists
2508                 }
2509                 copy_recursive($file,$destFile);
2510         }
2511 }
2512 function getChecklist($steps, $step) {
2513         global $mod_strings;
2514
2515         $skip = array('start', 'cancel', 'uninstall','end');
2516         $j=0;
2517         $i=1;
2518         $ret  = '<table cellpadding="3" cellspacing="4" border="0">';
2519         $ret .= '<tr><th colspan="3" align="left">'.$mod_strings['LBL_UW_CHECKLIST'].':</th></tr>';
2520         foreach($steps['desc'] as $k => $desc) {
2521                 if(in_array($steps['files'][$j], $skip)) {
2522                         $j++;
2523                         continue;
2524                 }
2525
2526                 //$status = "<span class='error'>{$mod_strings['LBL_UW_INCOMPLETE']}</span>";
2527                 $desc_mod_pre = '';
2528                 $desc_mod_post = '';
2529                 /*
2530                 if(isset($_SESSION['step'][$steps['files'][$k]]) && $_SESSION['step'][$steps['files'][$k]] == 'success') {
2531                         //$status = $mod_strings['LBL_UW_COMPLETE'];
2532                 }
2533                 */
2534
2535                 if($k == $_REQUEST['step']) {
2536                         //$status = $mod_strings['LBL_UW_IN_PROGRESS'];
2537                         $desc_mod_pre = "<font color=blue><i>";
2538                         $desc_mod_post = "</i></font>";
2539                 }
2540
2541                 $ret .= "<tr><td>&nbsp;</td><td><b>{$i}: {$desc_mod_pre}{$desc}{$desc_mod_post}</b></td>";
2542                 $ret .= "<td id={$steps['files'][$j]}><i></i></td></tr>";
2543                 $i++;
2544                 $j++;
2545         }
2546         $ret .= "</table>";
2547         return $ret;
2548 }
2549
2550 function prepSystemForUpgrade() {
2551         global $sugar_config;
2552         global $sugar_flavor;
2553         global $mod_strings;
2554         global $subdirs;
2555         global $base_upgrade_dir;
2556         global $base_tmp_upgrade_dir;
2557
2558         ///////////////////////////////////////////////////////////////////////////////
2559         ////    Make sure variables exist
2560         if(!isset($base_upgrade_dir) || empty($base_upgrade_dir)){
2561                 $base_upgrade_dir       = getcwd().'/'.$sugar_config['upload_dir'] . "upgrades";
2562         }
2563         if(!isset($base_tmp_upgrade_dir) || empty($base_tmp_upgrade_dir)){
2564                 $base_tmp_upgrade_dir   = "$base_upgrade_dir/temp";
2565         }
2566         if(!isset($subdirs) || empty($subdirs)){
2567                 $subdirs = array('full', 'langpack', 'module', 'patch', 'theme', 'temp');
2568         }
2569
2570     $upgrade_progress_dir = getcwd().'/'.$GLOBALS['sugar_config']['upload_dir'].'upgrades/temp';
2571     $upgrade_progress_file = $upgrade_progress_dir.'/upgrade_progress.php';
2572     if(file_exists($upgrade_progress_file)){
2573         if(function_exists('get_upgrade_progress') && function_exists('didThisStepRunBefore')){
2574                 if(didThisStepRunBefore('end')){
2575                         include($upgrade_progress_file);
2576                         unset($upgrade_config);
2577                         unlink($upgrade_progress_file);
2578                 }
2579         }
2580     }
2581
2582     // increase the cuttoff time to 1 hour
2583         ini_set("max_execution_time", "3600");
2584
2585     // make sure dirs exist
2586         if($subdirs != null){
2587                 foreach($subdirs as $subdir) {
2588                     mkdir_recursive("$base_upgrade_dir/$subdir");
2589                 }
2590         }
2591         // array of special scripts that are executed during (un)installation-- key is type of script, value is filename
2592         if(!defined('SUGARCRM_PRE_INSTALL_FILE')) {
2593                 define('SUGARCRM_PRE_INSTALL_FILE', 'scripts/pre_install.php');
2594                 define('SUGARCRM_POST_INSTALL_FILE', 'scripts/post_install.php');
2595                 define('SUGARCRM_PRE_UNINSTALL_FILE', 'scripts/pre_uninstall.php');
2596                 define('SUGARCRM_POST_UNINSTALL_FILE', 'scripts/post_uninstall.php');
2597         }
2598
2599         $script_files = array(
2600                 "pre-install" => constant('SUGARCRM_PRE_INSTALL_FILE'),
2601                 "post-install" => constant('SUGARCRM_POST_INSTALL_FILE'),
2602                 "pre-uninstall" => constant('SUGARCRM_PRE_UNINSTALL_FILE'),
2603                 "post-uninstall" => constant('SUGARCRM_POST_UNINSTALL_FILE'),
2604         );
2605
2606         // check that the upload limit is set to 6M or greater
2607         define('SUGARCRM_MIN_UPLOAD_MAX_FILESIZE_BYTES', 6 * 1024 * 1024);  // 6 Megabytes
2608         $upload_max_filesize = ini_get('upload_max_filesize');
2609         $upload_max_filesize_bytes = return_bytes($upload_max_filesize);
2610
2611         if($upload_max_filesize_bytes < constant('SUGARCRM_MIN_UPLOAD_MAX_FILESIZE_BYTES')) {
2612                 $GLOBALS['log']->debug("detected upload_max_filesize: $upload_max_filesize");
2613
2614                 echo '<p class="error">'.$mod_strings['MSG_INCREASE_UPLOAD_MAX_FILESIZE'].' '.get_cfg_var('cfg_file_path')."</p>\n";
2615         }
2616 }
2617
2618 if ( !function_exists('extractFile') ) {
2619 function extractFile($zip_file, $file_in_zip) {
2620     global $base_tmp_upgrade_dir;
2621
2622         // strip cwd
2623         $absolute_base_tmp_upgrade_dir = clean_path($base_tmp_upgrade_dir);
2624         $relative_base_tmp_upgrade_dir = clean_path(str_replace(clean_path(getcwd()), '', $absolute_base_tmp_upgrade_dir));
2625
2626     // mk_temp_dir expects relative pathing
2627     $my_zip_dir = mk_temp_dir($relative_base_tmp_upgrade_dir);
2628
2629     unzip_file($zip_file, $file_in_zip, $my_zip_dir);
2630
2631     return("$my_zip_dir/$file_in_zip");
2632 }
2633 }
2634
2635 if ( !function_exists('extractManifest') ) {
2636 function extractManifest($zip_file) {
2637         logThis('extracting manifest.');
2638     return(extractFile($zip_file, "manifest.php"));
2639 }
2640 }
2641
2642 if ( !function_exists('getInstallType') ) {
2643 function getInstallType($type_string) {
2644     // detect file type
2645     global $subdirs;
2646         $subdirs = array('full', 'langpack', 'module', 'patch', 'theme', 'temp');
2647     foreach($subdirs as $subdir) {
2648         if(preg_match("#/$subdir/#", $type_string)) {
2649             return($subdir);
2650         }
2651     }
2652     // return empty if no match
2653     return("");
2654 }
2655 }
2656
2657 function getImageForType($type) {
2658     global $image_path;
2659     $icon = "";
2660     switch($type) {
2661         case "full":
2662             $icon = SugarThemeRegistry::current()->getImage("Upgrade", "");
2663             break;
2664         case "langpack":
2665             $icon = SugarThemeRegistry::current()->getImage("LanguagePacks", "");
2666             break;
2667         case "module":
2668             $icon = SugarThemeRegistry::current()->getImage("ModuleLoader", "");
2669             break;
2670         case "patch":
2671             $icon = SugarThemeRegistry::current()->getImage("PatchUpgrades", "");
2672             break;
2673         case "theme":
2674             $icon = SugarThemeRegistry::current()->getImage("Themes", "");
2675             break;
2676         default:
2677             break;
2678     }
2679     return($icon);
2680 }
2681
2682 if ( !function_exists('getLanguagePackName') ) {
2683 function getLanguagePackName($the_file) {
2684     require_once("$the_file");
2685     if(isset($app_list_strings["language_pack_name"])) {
2686         return($app_list_strings["language_pack_name"]);
2687     }
2688     return("");
2689 }
2690 }
2691
2692 function getUITextForType($type) {
2693     if($type == "full") {
2694         return("Full Upgrade");
2695     }
2696     if($type == "langpack") {
2697         return("Language Pack");
2698     }
2699     if($type == "module") {
2700         return("Module");
2701     }
2702     if($type == "patch") {
2703         return("Patch");
2704     }
2705     if($type == "theme") {
2706         return("Theme");
2707     }
2708 }
2709
2710 /**
2711  * @deprecated
2712  * @todo this function doesn't seemed to be used anymore; trying kill this off
2713  */
2714 function run_upgrade_wizard_sql($script) {
2715     global $unzip_dir;
2716     global $sugar_config;
2717
2718     $db_type = $sugar_config['dbconfig']['db_type'];
2719     $script = str_replace("%db_type%", $db_type, $script);
2720     if(!run_sql_file("$unzip_dir/$script")) {
2721         die("Error running sql file: $unzip_dir/$script");
2722     }
2723 }
2724
2725 if ( !function_exists('validate_manifest') ) {
2726 /**
2727  * Verifies a manifest from a patch or module to be compatible with the current Sugar version and flavor
2728  * @param array manifest Standard manifest array
2729  * @return string Error message, blank on success
2730  */
2731 function validate_manifest($manifest) {
2732         logThis('validating manifest.php file');
2733     // takes a manifest.php manifest array and validates contents
2734     global $subdirs;
2735     global $sugar_version;
2736     global $sugar_flavor;
2737         global $mod_strings;
2738
2739     if(!isset($manifest['type'])) {
2740         return $mod_strings['ERROR_MANIFEST_TYPE'];
2741     }
2742
2743     $type = $manifest['type'];
2744
2745     if(getInstallType("/$type/") == "") {
2746                 return $mod_strings['ERROR_PACKAGE_TYPE']. ": '" . $type . "'.";
2747     }
2748
2749     if(isset($manifest['acceptable_sugar_versions'])) {
2750         $version_ok = false;
2751         $matches_empty = true;
2752         if(isset($manifest['acceptable_sugar_versions']['exact_matches'])) {
2753             $matches_empty = false;
2754             foreach($manifest['acceptable_sugar_versions']['exact_matches'] as $match) {
2755                 if($match == $sugar_version) {
2756                     $version_ok = true;
2757                 }
2758             }
2759         }
2760         if(!$version_ok && isset($manifest['acceptable_sugar_versions']['regex_matches'])) {
2761             $matches_empty = false;
2762             foreach($manifest['acceptable_sugar_versions']['regex_matches'] as $match) {
2763                 if(preg_match("/$match/", $sugar_version)) {
2764                     $version_ok = true;
2765                 }
2766             }
2767         }
2768
2769         if(!$matches_empty && !$version_ok) {
2770             return $mod_strings['ERROR_VERSION_INCOMPATIBLE']."<br />".
2771             $mod_strings['ERR_UW_VERSION'].$sugar_version;
2772         }
2773     }
2774
2775     if(isset($manifest['acceptable_sugar_flavors']) && sizeof($manifest['acceptable_sugar_flavors']) > 0) {
2776         $flavor_ok = false;
2777         foreach($manifest['acceptable_sugar_flavors'] as $match) {
2778             if($match == $sugar_flavor) {
2779                 $flavor_ok = true;
2780             }
2781         }
2782         if(!$flavor_ok) {
2783             return $mod_strings['ERROR_FLAVOR_INCOMPATIBLE']."<br />".
2784             $mod_strings['ERR_UW_FLAVOR'].$sugar_flavor."<br />".
2785             $mod_strings['ERR_UW_FLAVOR_2'].$manifest['acceptable_sugar_flavors'][0];
2786         }
2787     }
2788
2789     return '';
2790 }
2791 }
2792
2793 function unlinkUploadFiles() {
2794         return;
2795 //      logThis('at unlinkUploadFiles()');
2796 //
2797 //      if(isset($_SESSION['install_file']) && !empty($_SESSION['install_file'])) {
2798 //              $upload = $_SESSION['install_file'];
2799 //
2800 //              if(is_file($upload)) {
2801 //                      logThis('unlinking ['.$upload.']');
2802 //                      @unlink($upload);
2803 //              }
2804 //      }
2805 }
2806
2807 if ( !function_exists('unlinkTempFiles') ) {
2808 /**
2809  * deletes files created by unzipping a package
2810  */
2811 function unlinkTempFiles() {
2812         global $sugar_config;
2813         global $path;
2814
2815         logThis('at unlinkTempFiles()');
2816         $tempDir='';
2817         $sugar_config['upload_dir']='cache/upload/';
2818         //if(isset($sugar_config['upload_dir']) && $sugar_config['upload_dir'] != null && $sugar_config['upload_dir']=='cache/upload/'){
2819                 $tempDir = clean_path(getcwd().'/'.$sugar_config['upload_dir'].'upgrades/temp');
2820 /*      }
2821         else{
2822                 $uploadDir = getcwd()."/".'cache/upload/';
2823                 $tempDir = clean_path(getcwd().'/'.$uploadDir.'upgrades/temp');
2824         }*/
2825         if(file_exists($tempDir) && is_dir($tempDir)){
2826                 $files = findAllFiles($tempDir, array(), false);
2827                 rsort($files);
2828                 foreach($files as $file) {
2829                         if(!is_dir($file)) {
2830                                 logThis('unlinking ['.$file.']', $path);
2831                                 @unlink($file);
2832                         }
2833                 }
2834                 // now do dirs
2835                 $files = findAllFiles($tempDir, array(), true);
2836                 foreach($files as $dir) {
2837                         if(is_dir($dir)) {
2838                                 logThis('removing dir ['.$dir.']', $path);
2839                                 @rmdir($dir);
2840                         }
2841                 }
2842                 $cacheFile = "modules/UpgradeWizard/_persistence.php";
2843                 if(is_file($cacheFile)) {
2844                         logThis("Unlinking Upgrade cache file: '_persistence.php'", $path);
2845                         @unlink($cacheFile);
2846                 }
2847         }
2848         logThis("finished!");
2849 }
2850 }
2851
2852 /**
2853  * finds all files in the passed path, but skips select directories
2854  * @param string dir Relative path
2855  * @param array the_array Collections of found files/dirs
2856  * @param bool include_dir True if we want to include directories in the
2857  * returned collection
2858  */
2859 function uwFindAllFiles($dir, $the_array, $include_dirs=false, $skip_dirs=array(), $echo=false) {
2860         // check skips
2861         foreach($skip_dirs as $skipMe) {
2862                 if(strpos(clean_path($dir), $skipMe) !== false) {
2863                         return $the_array;
2864                 }
2865         }
2866
2867         $d = dir($dir);
2868
2869         while($f = $d->read()) {
2870             if($f == "." || $f == "..") { // skip *nix self/parent
2871                 continue;
2872             }
2873
2874                 // for AJAX length count
2875         if($echo) {
2876                 echo '.';
2877                 ob_flush();
2878         }
2879
2880             if(is_dir("$dir/$f")) {
2881                         if($include_dirs) { // add the directory if flagged
2882                                 $the_array[] = clean_path("$dir/$f");
2883                         }
2884
2885                         // recurse in
2886                 $the_array = uwFindAllFiles("$dir/$f/", $the_array, $include_dirs, $skip_dirs, $echo);
2887             } else {
2888                 $the_array[] = clean_path("$dir/$f");
2889             }
2890
2891
2892         }
2893         rsort($the_array);
2894         return $the_array;
2895 }
2896
2897
2898
2899 /**
2900  * unset's UW's Session Vars
2901  */
2902 function resetUwSession() {
2903         logThis('resetting $_SESSION');
2904
2905         if(isset($_SESSION['committed']))
2906                 unset($_SESSION['committed']);
2907         if(isset($_SESSION['sugar_version_file']))
2908                 unset($_SESSION['sugar_version_file']);
2909         if(isset($_SESSION['upgrade_complete']))
2910                 unset($_SESSION['upgrade_complete']);
2911         if(isset($_SESSION['allTables']))
2912                 unset($_SESSION['allTables']);
2913         if(isset($_SESSION['alterCustomTableQueries']))
2914                 unset($_SESSION['alterCustomTableQueries']);
2915         if(isset($_SESSION['skip_zip_upload']))
2916                 unset($_SESSION['skip_zip_upload']);
2917         if(isset($_SESSION['sugar_version_file']))
2918                 unset($_SESSION['sugar_version_file']);
2919         if(isset($_SESSION['install_file']))
2920                 unset($_SESSION['install_file']);
2921         if(isset($_SESSION['unzip_dir']))
2922                 unset($_SESSION['unzip_dir']);
2923         if(isset($_SESSION['zip_from_dir']))
2924                 unset($_SESSION['zip_from_dir']);
2925         if(isset($_SESSION['overwrite_files']))
2926                 unset($_SESSION['overwrite_files']);
2927         if(isset($_SESSION['schema_change']))
2928                 unset($_SESSION['schema_change']);
2929         if(isset($_SESSION['uw_restore_dir']))
2930                 unset($_SESSION['uw_restore_dir']);
2931         if(isset($_SESSION['step']))
2932                 unset($_SESSION['step']);
2933         if(isset($_SESSION['files']))
2934                 unset($_SESSION['files']);
2935         if(isset($_SESSION['Upgraded451Wizard'])){
2936                 unset($_SESSION['Upgraded451Wizard']);
2937         }
2938         if(isset($_SESSION['Initial_451to500_Step'])){
2939                 unset($_SESSION['Initial_451to500_Step']);
2940         }
2941         if(isset($_SESSION['license_shown']))
2942                 unset($_SESSION['license_shown']);
2943     if(isset($_SESSION['sugarMergeRunResults']))
2944                 unset($_SESSION['sugarMergeRunResults']);
2945 }
2946
2947 /**
2948  * runs rebuild scripts
2949  */
2950 function UWrebuild() {
2951         global $db;
2952         global $path;
2953
2954         logThis('Rebuilding everything...', $path);
2955 //      require_once('ModuleInstall/ModuleInstaller.php');
2956 //      $mi = new ModuleInstaller();
2957 //      $mi->rebuild_all(true);
2958         require_once('modules/Administration/QuickRepairAndRebuild.php');
2959         $randc = new RepairAndClear();
2960     $randc->repairAndClearAll(array('clearAll'),array(translate('LBL_ALL_MODULES')), false, false);
2961
2962         $query = "DELETE FROM versions WHERE name='Rebuild Extensions'";
2963         $db->query($query);
2964         logThis('Registering rebuild record: '.$query, $path);
2965         logThis('Rebuild done.', $path);
2966
2967         // insert a new database row to show the rebuild extensions is done
2968         $id = create_guid();
2969         $gmdate = gmdate($GLOBALS['timedate']->get_db_date_time_format());
2970         $date_entered = db_convert("'$gmdate'", 'datetime');
2971         $query = 'INSERT INTO versions (id, deleted, date_entered, date_modified, modified_user_id, created_by, name, file_version, db_version) '
2972                 . "VALUES ('$id', '0', $date_entered, $date_entered, '1', '1', 'Rebuild Extensions', '4.0.0', '4.0.0')";
2973         $db->query($query);
2974         logThis('Registering rebuild record in versions table: '.$query, $path);
2975 }
2976
2977 function getCustomTables($dbType) {
2978         global $db;
2979
2980         $customTables = array();
2981
2982     switch($dbType) {
2983                 case 'mysql':
2984                 $query = "SHOW tables LIKE '%_cstm'";
2985                 $result = $db->query($query);//, true, 'Error getting custom tables');
2986             while ($row = $db->fetchByAssoc($result)){
2987                 $customTables[] = array_pop($row);
2988             }
2989             break;
2990         }
2991     return $customTables;
2992 }
2993
2994 function alterCustomTables($dbType, $customTables)
2995 {
2996         switch($dbType) {
2997                 case 'mysql':
2998                         $i = 0;
2999                         while( $i < count($customTables) ) {
3000                                 $alterCustomTableSql[] = "ALTER TABLE " . $customTables[$i] . " CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci";
3001                                 $i++;
3002                         }
3003                         break;
3004                 case 'oci8':
3005                         break;
3006         }
3007         return $alterCustomTableSql;
3008 }
3009
3010 function executeAlterCustomTablesSql($dbType, $queries) {
3011         global $db;
3012
3013         foreach($queries as $query){
3014                 if(!empty($query)){
3015                         logThis("Sending query: ".$query);
3016                     if($db->dbType == 'oci8') {
3017                 } else {
3018                     $query_result = $db->query($query);//.';', true, "An error has occured while performing db query.  See log file for details.<br>");
3019                 }
3020          }
3021         }
3022         return true;
3023 }
3024
3025 function getAllTables($dbType) {
3026         global $db;
3027
3028         $tables = array();
3029
3030     switch($dbType) {
3031                 case 'mysql':
3032                 $query = "SHOW tables";
3033                 $result = $db->query($query, true, 'Error getting custom tables');
3034             while ($row = $db->fetchByAssoc($result)){
3035                 $tables[] = array_pop($row);
3036             }
3037             break;
3038         }
3039     return $tables;
3040 }
3041
3042 function printAlterTableSql($tables)
3043 {
3044         $alterTableSql = '';
3045
3046         foreach($tables as $table)
3047                 $alterTableSql .= "ALTER TABLE " . $table . " CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;" . "\n";
3048
3049         return $alterTableSql;
3050 }
3051
3052 function executeConvertTablesSql($dbType, $tables) {
3053         global $db;
3054
3055         foreach($tables as $table){
3056                 $query = "ALTER TABLE " . $table . " CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci";
3057                 if(!empty($table)){
3058                         logThis("Sending query: ".$query);
3059                     if($db->dbType == 'oci8') {
3060                 } else {
3061                     $query_result = $db->query($query);//.';', true, "An error has occured while performing db query.  See log file for details.<br>");
3062                 }
3063          }
3064         }
3065         return true;
3066 }
3067
3068 function testThis() {
3069         $files = uwFindAllFiles(getcwd().'/test', array());
3070
3071         $out = "<table cellpadding='1' cellspacing='0' border='0'>\n";
3072
3073         $priorPath = '';
3074         foreach($files as $file) {
3075                 $relativeFile = clean_path(str_replace(getcwd().'/test', '', $file));
3076                 $relativeFile = ($relativeFile{0} == '/') ? substr($relativeFile, 1, strlen($relativeFile)) : $relativeFile;
3077
3078                 $relativePath = dirname($relativeFile);
3079
3080                 if($relativePath == $priorPath) { // same dir, new file
3081                         $out .= "<tr><td>".basename($relativeFile)."</td></tr>";
3082                         $priorPath = $relativePath;
3083                 } else { // new dir
3084
3085                 }
3086         }
3087
3088         $out .= "</table>";
3089
3090         echo $out;
3091 }
3092
3093
3094
3095
3096 function testThis2($dir, $id=0, $hide=false) {
3097         $path = $dir;
3098         $dh = opendir($dir);
3099         rewinddir($dh);
3100
3101         $doHide = ($hide) ? 'none' : '';
3102         $out = "<div id='{$id}' style='display:{$doHide};'>";
3103         $out .= "<table cellpadding='1' cellspacing='0' border='0' style='border:0px solid #ccc'>\n";
3104
3105         while($file = readdir($dh)) {
3106                 if($file == '.' || $file == '..' || $file == 'CVS' || $file == '.cvsignore')
3107                         continue;
3108
3109                 if(is_dir($path.'/'.$file)) {
3110                         $file = $path.'/'.$file;
3111                         $newI = create_guid();
3112                         $out .= "<tr><td valign='top'><a href='javascript:toggleNwFiles(\"{$newI}\");'><img border='0' src='".SugarThemeRegistry::current()->getImageURL('Workflow.gif')."'></a></td>\n";
3113                         $out .= "<td valign='top'><b><a href='javascript:toggleNwFiles(\"{$newI}\");'>".basename($file)."</a></b></td></tr>";
3114                         $out .= "<tr><td></td><td valign='top'>".testThis2($file, $newI, true)."</td></tr>";
3115                 } else {
3116                         $out .= "<tr><td valign='top'>&nbsp;</td>\n";
3117                         $out .= "<td valign='top'>".basename($file)."</td></tr>";
3118                 }
3119         }
3120
3121         $out .= "</tr></table>";
3122         $out .= "</div>";
3123
3124         closedir($dh);
3125         return $out;
3126 }
3127
3128
3129
3130
3131
3132 function testThis3(&$files, $id, $hide, $previousPath = '') {
3133         if(!is_array($files) || empty($files))
3134                 return '';
3135
3136         $out = '';
3137
3138         // expecting full path here
3139         foreach($files as $k => $file) {
3140                 $file = str_replace(getcwd(), '', $file);
3141                 $path = dirname($file);
3142                 $fileName = basename($file);
3143
3144                 if($fileName == 'CVS' || $fileName == '.cvsignore')
3145                         continue;
3146
3147                 if($path == $previousPath) { // same directory
3148                         // new row for each file
3149                         $out .= "<tr><td valign='top' align='left'>&nbsp;</td>";
3150                         $out .= "<td valign='top' align='left'>{$fileName}</td></tr>";
3151                 } else { // new directory
3152                         $newI = $k;
3153                         $out .= "<tr><td valign='top'><a href='javascript:toggleNwFiles(\"{$newI}\");'><img border='0' src='".SugarThemeRegistry::current()->getImageURL('Workflow.gif')."></a></td>\n";
3154                         $out .= "<td valign='top'><b><a href='javascript:toggleNwFiles(\"{$newI}\");'>".$fileName."</a></b></td></tr>";
3155                         $recurse = testThis3($files, $newI, true, $previousPath);
3156                         $out .= "<tr><td></td><td valign='top'>".$recurse."</td></tr>";
3157                 }
3158
3159                 $previousPath = $path;
3160         }
3161         $display = ($hide) ? 'none' : '';
3162         $ret = <<<eoq
3163         <div id="{$id}" style="display:{$display}">
3164         <table cellpadding='1' cellspacing='0' border='0' style='border:1px solid #ccc'>
3165                 {$out}
3166         </table>
3167         </div>
3168 eoq;
3169         return $ret;
3170 }
3171
3172
3173 function testThis4($filePath, $fileNodes=array(), $fileName='') {
3174         $path = dirname($filePath);
3175         $file = basename($filePath);
3176
3177         $exFile = explode('/', $path);
3178
3179         foreach($exFile as $pathSegment) {
3180                 if(is_array($fileNodes[$pathSegment])) { // path already processed
3181
3182                 } else { // newly found path
3183                         $fileNodes[$pathSegment] = array();
3184                 }
3185
3186                 if($fileName != '') {
3187                         $fileNodes[$pathSegment][] = $fileName;
3188                 }
3189         }
3190
3191         return $fileNodes;
3192 }
3193
3194
3195
3196 ///////////////////////////////////////////////////////////////////////////////
3197 ////    SYSTEM CHECK FUNCTIONS
3198 /**
3199  * generates an array with all files in the SugarCRM root directory, skipping
3200  * cache/
3201  * @return array files Array of files with absolute paths
3202  */
3203 function getFilesForPermsCheck() {
3204         global $sugar_config;
3205
3206         logThis('Got JSON call to find all files...');
3207         $filesNotWritable = array();
3208         $filesNWPerms = array();
3209
3210         // add directories here that should be skipped when doing file permissions checks (cache/upload is the nasty one)
3211         $skipDirs = array(
3212                 $sugar_config['upload_dir'],
3213         );
3214         $files = uwFindAllFiles(getcwd(), array(), true, $skipDirs, true);
3215         return $files;
3216 }
3217
3218 /**
3219  * checks files for permissions
3220  * @param array files Array of files with absolute paths
3221  * @return string result of check
3222  */
3223 function checkFiles($files, $echo=false) {
3224         global $mod_strings;
3225         $filesNotWritable = array();
3226         $i=0;
3227         $filesOut = "
3228                 <a href='javascript:void(0); toggleNwFiles(\"filesNw\");'>{$mod_strings['LBL_UW_SHOW_NW_FILES']}</a>
3229                 <div id='filesNw' style='display:none;'>
3230                 <table cellpadding='3' cellspacing='0' border='0'>
3231                 <tr>
3232                         <th align='left'>{$mod_strings['LBL_UW_FILE']}</th>
3233                         <th align='left'>{$mod_strings['LBL_UW_FILE_PERMS']}</th>
3234                         <th align='left'>{$mod_strings['LBL_UW_FILE_OWNER']}</th>
3235                         <th align='left'>{$mod_strings['LBL_UW_FILE_GROUP']}</th>
3236                 </tr>";
3237
3238         $isWindows = is_windows();
3239         foreach($files as $file) {
3240
3241                 if($isWindows) {
3242                         if(!is_writable_windows($file)) {
3243                                 logThis('WINDOWS: File ['.$file.'] not readable - saving for display');
3244                                 // don't warn yet - we're going to use this to check against replacement files
3245         // aw: commented out; it's a hack to allow upgrade wizard to continue on windows... will fix later
3246                                 /*$filesNotWritable[$i] = $file;
3247                                 $filesNWPerms[$i] = substr(sprintf('%o',fileperms($file)), -4);
3248                                 $filesOut .= "<tr>".
3249                                                                 "<td><span class='error'>{$file}</span></td>".
3250                                                                 "<td>{$filesNWPerms[$i]}</td>".
3251                                                                 "<td>".$mod_strings['ERR_UW_CANNOT_DETERMINE_USER']."</td>".
3252                                                                 "<td>".$mod_strings['ERR_UW_CANNOT_DETERMINE_GROUP']."</td>".
3253                                                           "</tr>";*/
3254                         }
3255                 } else {
3256                         if(!is_writable($file)) {
3257                                 logThis('File ['.$file.'] not writable - saving for display');
3258                                 // don't warn yet - we're going to use this to check against replacement files
3259                                 $filesNotWritable[$i] = $file;
3260                                 $filesNWPerms[$i] = substr(sprintf('%o',fileperms($file)), -4);
3261                                 $owner = posix_getpwuid(fileowner($file));
3262                                 $group = posix_getgrgid(filegroup($file));
3263                                 $filesOut .= "<tr>".
3264                                                                 "<td><span class='error'>{$file}</span></td>".
3265                                                                 "<td>{$filesNWPerms[$i]}</td>".
3266                                                                 "<td>".$owner['name']."</td>".
3267                                                                 "<td>".$group['name']."</td>".
3268                                                           "</tr>";
3269                         }
3270                 }
3271                 $i++;
3272         }
3273
3274         $filesOut .= '</table></div>';
3275         // not a stop error
3276         $errors['files']['filesNotWritable'] = (count($filesNotWritable) > 0) ? true : false;
3277         if(count($filesNotWritable) < 1) {
3278                 $filesOut = "{$mod_strings['LBL_UW_FILE_NO_ERRORS']}";
3279         }
3280
3281         return $filesOut;
3282 }
3283
3284 function deletePackageOnCancel(){
3285         global $mod_strings;
3286         global $sugar_config;
3287         logThis('running delete');
3288     if(!isset($_SESSION['install_file']) || ($_SESSION['install_file'] == "")) {
3289         logThis('ERROR: trying to delete non-existent file: ['.$_REQUEST['install_file'].']');
3290         $error = $mod_strings['ERR_UW_NO_FILE_UPLOADED'];
3291     }
3292     // delete file in upgrades/patch
3293     $delete_me = urldecode( $_SESSION['install_file'] );
3294     if(@unlink($delete_me)) {
3295         logThis('unlinking: '.$delete_me);
3296         $out = basename($delete_me).$mod_strings['LBL_UW_FILE_DELETED'];
3297     } else {
3298         logThis('ERROR: could not delete ['.$delete_me.']');
3299                 $error = $mod_strings['ERR_UW_FILE_NOT_DELETED'].$delete_me;
3300     }
3301
3302     // delete file in cache/upload
3303     $fileS = explode('/', $delete_me);
3304     $c = count($fileS);
3305     $fileName = (isset($fileS[$c-1]) && !empty($fileS[$c-1])) ? $fileS[$c-1] : $fileS[$c-2];
3306     $deleteUpload = getcwd().'/'.$sugar_config['upload_dir'].$fileName;
3307     logThis('Trying to delete '.$deleteUpload);
3308     if(!@unlink($deleteUpload)) {
3309         logThis('ERROR: could not delete: ['.$deleteUpload.']');
3310         $error = $mod_strings['ERR_UW_FILE_NOT_DELETED'].$sugar_config['upload_dir'].$fileName;
3311     }
3312     if(!empty($error)) {
3313                 $out = "<b><span class='error'>{$error}</span></b><br />";
3314     }
3315 }
3316
3317
3318 function parseAndExecuteSqlFile($sqlScript,$forStepQuery='',$resumeFromQuery=''){
3319         global $sugar_config;
3320         $alterTableSchema = '';
3321         $sqlErrors = array();
3322         if(!isset($_SESSION['sqlSkippedQueries'])){
3323                 $_SESSION['sqlSkippedQueries'] = array();
3324          }
3325         $db = & DBManagerFactory::getInstance();
3326         $is_mysql = false;
3327         if($sugar_config['dbconfig']['db_type'] == 'mysql') {
3328            $is_mysql = true;
3329         }
3330     if($sugar_config['dbconfig']['db_type'] == 'oci8'){
3331         $db->query("CREATE OR REPLACE FUNCTION blob_to_clob (blob_in IN BLOB)
3332                                         RETURN CLOB
3333                                         AS
3334                                           v_clob    CLOB;
3335                                           v_varchar VARCHAR2(32767);
3336                                           v_start   PLS_INTEGER := 1;
3337                                           v_buffer  PLS_INTEGER := 32767;
3338                                         BEGIN
3339                                           DBMS_LOB.CREATETEMPORARY(v_clob, TRUE);
3340
3341                                           FOR i IN 1..CEIL(DBMS_LOB.GETLENGTH(blob_in) / v_buffer)
3342                                           LOOP
3343
3344                                              v_varchar := UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(blob_in, v_buffer, v_start));
3345
3346                                                    DBMS_LOB.WRITEAPPEND(v_clob, LENGTH(v_varchar), v_varchar);
3347
3348                                                 v_start := v_start + v_buffer;
3349                                             END LOOP;
3350
3351                                            RETURN v_clob;
3352
3353                                         END blob_to_clob;");
3354     }
3355     if(strpos($resumeFromQuery,",") != false){
3356         $resumeFromQuery = explode(",",$resumeFromQuery);
3357         if(is_array($resumeFromQuery)){
3358                 //print_r('RES ARRAY '.$resumeFromQuery[0].'</br>');
3359         }
3360     }
3361         if(file_exists($sqlScript)) {
3362                 $fp = fopen($sqlScript, 'r');
3363                 $contents = fread($fp, filesize($sqlScript));
3364             $anyScriptChanges =$contents;
3365             $resumeAfterFound = false;
3366                 if(rewind($fp)) {
3367                         $completeLine = '';
3368                         $count = 0;
3369                         while($line = fgets($fp)) {
3370                                 if(strpos($line, '--') === false) {
3371                                         $completeLine .= " ".trim($line);
3372                                         if(strpos($line, ';') !== false) {
3373                                                 $query = '';
3374                                                 $query = str_replace(';','',$completeLine);
3375                                                 //if resume from query is not null then find out from where
3376                                                 //it should start executing the query.
3377
3378                                                 if($query != null && $resumeFromQuery != null){
3379                                                         if(!$resumeAfterFound){
3380                                                                 if(strpos($query,",") != false){
3381                                                                         $queArray = array();
3382                                                                         $queArray = explode(",",$query);
3383                                                                         for($i=0;$i<sizeof($resumeFromQuery);$i++){
3384                                                                                 if(strcmp(strtolower(trim($resumeFromQuery[$i])),strtolower(trim($queArray[$i])))==0){
3385                                                                                         //echo 'mat found '.$queArray[$i].'</br>';
3386                                                                                         $resumeAfterFound = true;
3387                                                                                 }
3388                                                                                 else{
3389                                                                                         $resumeAfterFound = false;
3390                                                                                         break;
3391                                                                                 }
3392                                                                         }//for
3393
3394                                                                 }
3395                                                                 elseif(strcmp(strtolower(trim($resumeFromQuery)),strtolower(trim($query)))==0){
3396                                                                         $resumeAfterFound = true;
3397                                                                 }
3398                                                         }
3399                                                         if($resumeAfterFound){
3400                                                                 $count++;
3401                                                         }
3402                                                         // if $count=1 means it is just found so skip the query. Run the next one
3403                                 if($query != null && $resumeAfterFound && $count >1){
3404                                         $tableName = '';
3405                                         if($is_mysql)
3406                                         {
3407                                                 $tableName = getAlterTable($query);
3408                                                 if(!empty($tableName))
3409                                                 {
3410                                                         $db->query('ALTER TABLE '.$tableName.' DISABLE KEYS');
3411                                                 }
3412                                         }
3413                                         $db->query($query);
3414                                         if($db->checkError()){
3415                                             //put in the array to use later on
3416                                             $_SESSION['sqlSkippedQueries'][] = $query;
3417                                         }
3418                                     if(!empty($tableName))
3419                                 {
3420                                     $db->query('ALTER TABLE '.$tableName.' ENABLE KEYS');
3421                                 }
3422                                         $progQuery[$forStepQuery]=$query;
3423                                         post_install_progress($progQuery,$action='set');
3424                                 }//if
3425                                                 }
3426                                                 elseif($query != null){
3427                                                         $tableName = '';
3428                                 if($is_mysql)
3429                                 {
3430                                     $tableName = getAlterTable($query);
3431                                     if(!empty($tableName))
3432                                     {
3433                                         $db->query('ALTER TABLE '.$tableName.' DISABLE KEYS');
3434                                     }
3435                                 }
3436                                         $db->query($query);
3437                                                         if(!empty($tableName))
3438                                 {
3439                                     $db->query('ALTER TABLE '.$tableName.' ENABLE KEYS');
3440                                 }
3441                                         $progQuery[$forStepQuery]=$query;
3442                                         post_install_progress($progQuery,$action='set');
3443                                         if($db->checkError()){
3444                                             //put in the array to use later on
3445                                             $_SESSION['sqlSkippedQueries'][] = $query;
3446                                         }
3447                                 }
3448                                 $completeLine = '';
3449                                         }
3450                                 }
3451                         }//while
3452                 }
3453         }
3454 }
3455
3456 function getAlterTable($query){
3457         $query = strtolower($query);
3458         if (preg_match("/^\s*alter\s+table\s+/", $query)) {
3459                 $sqlArray = explode(" ", $query);
3460                 $key = array_search('table', $sqlArray);
3461                 return $sqlArray[($key+1)];
3462         }else {
3463                 return '';
3464         }
3465 }
3466
3467 function set_upgrade_vars(){
3468         logThis('setting session variables...');
3469         $upgrade_progress_dir = getcwd().'/'.$GLOBALS['sugar_config']['upload_dir'].'upgrades/temp';
3470         if(!is_dir($upgrade_progress_dir)){
3471                 mkdir_recursive($upgrade_progress_dir);
3472         }
3473         $upgrade_progress_file = $upgrade_progress_dir.'/upgrade_progress.php';
3474         if(file_exists($upgrade_progress_file)){
3475                 include($upgrade_progress_file);
3476         }
3477         else{
3478                 fopen($upgrade_progress_file, 'w+');
3479         }
3480         if(!isset($upgrade_config) || $upgrade_config == null){
3481                 $upgrade_config = array();
3482                 $upgrade_config[1]['upgrade_vars']=array();
3483         }
3484     if(isset($upgrade_config[1]) && isset($upgrade_config[1]['upgrade_vars']) && !is_array($upgrade_config[1]['upgrade_vars'])){
3485         $upgrade_config[1]['upgrade_vars'] = array();
3486     }
3487
3488         if(!isset($upgrade_vars) || $upgrade_vars == NULL){
3489                 $upgrade_vars = array();
3490         }
3491         if(isset($_SESSION['unzip_dir']) && !empty($_SESSION['unzip_dir']) && file_exists($_SESSION['unzip_dir'])){
3492                 $upgrade_vars['unzip_dir']=$_SESSION['unzip_dir'];
3493         }
3494         if(isset($_SESSION['install_file']) && !empty($_SESSION['install_file']) && file_exists($_SESSION['install_file'])){
3495                 $upgrade_vars['install_file']=$_SESSION['install_file'];
3496         }
3497         if(isset($_SESSION['Upgraded451Wizard']) && !empty($_SESSION['Upgraded451Wizard'])){
3498                 $upgrade_vars['Upgraded451Wizard']=$_SESSION['Upgraded451Wizard'];
3499         }
3500         if(isset($_SESSION['license_shown']) && !empty($_SESSION['license_shown'])){
3501                 $upgrade_vars['license_shown']=$_SESSION['license_shown'];
3502         }
3503         if(isset($_SESSION['Initial_451to500_Step']) && !empty($_SESSION['Initial_451to500_Step'])){
3504                 $upgrade_vars['Initial_451to500_Step']=$_SESSION['Initial_451to500_Step'];
3505         }
3506         if(isset($_SESSION['zip_from_dir']) && !empty($_SESSION['zip_from_dir'])){
3507                 $upgrade_vars['zip_from_dir']=$_SESSION['zip_from_dir'];
3508         }
3509         //place into the upgrade_config array and rewrite config array only if new values are being inserted
3510         if(isset($upgrade_vars) && $upgrade_vars != null && sizeof($upgrade_vars) > 0){
3511                 foreach($upgrade_vars as $key=>$val){
3512                         if($key != null && $val != null){
3513                                 $upgrade_config[1]['upgrade_vars'][$key]=$upgrade_vars[$key];
3514                         }
3515                 }
3516                 ksort($upgrade_config);
3517                 if(is_writable($upgrade_progress_file) && write_array_to_file( "upgrade_config", $upgrade_config,
3518                         $upgrade_progress_file)) {
3519                        //writing to the file
3520                 }
3521     }
3522 }
3523
3524 function initialize_session_vars(){
3525   $upgrade_progress_dir = getcwd().'/'.$GLOBALS['sugar_config']['upload_dir'].'upgrades/temp';
3526   $upgrade_progress_file = $upgrade_progress_dir.'/upgrade_progress.php';
3527   if(file_exists($upgrade_progress_file)){
3528         include($upgrade_progress_file);
3529         if(isset($upgrade_config) && $upgrade_config != null && is_array($upgrade_config) && sizeof($upgrade_config) >0){
3530                 $currVarsArray=$upgrade_config[1]['upgrade_vars'];
3531                 //print_r($currVarsArray);
3532                 if(isset($currVarsArray) && $currVarsArray != null && is_array($currVarsArray) && sizeof($currVarsArray)>0){
3533                         foreach($currVarsArray as $key=>$val){
3534                                 if($key != null && $val !=null){
3535                                         //set session variables
3536                                         $_SESSION[$key]=$val;
3537                                         //set varibales
3538                                         "$".$key=$val;
3539                                 }
3540                         }
3541                 }
3542         }
3543   }
3544 }
3545 //track the upgrade progress on each step
3546 //track the upgrade progress on each step
3547 function set_upgrade_progress($currStep,$currState,$currStepSub='',$currStepSubState=''){
3548
3549         $upgrade_progress_dir = getcwd().'/'.$GLOBALS['sugar_config']['upload_dir'].'upgrades/temp';
3550         if(!is_dir($upgrade_progress_dir)){
3551                 mkdir_recursive($upgrade_progress_dir);
3552         }
3553         $upgrade_progress_file = $upgrade_progress_dir.'/upgrade_progress.php';
3554         if(file_exists($upgrade_progress_file)){
3555                 include($upgrade_progress_file);
3556         }
3557         else{
3558                 if(function_exists('sugar_fopen')){
3559                         sugar_fopen($upgrade_progress_file, 'w+');
3560                 }
3561                 else{
3562                         fopen($upgrade_progress_file, 'w+');
3563                 }
3564         }
3565         if(!isset($upgrade_config) || $upgrade_config == null){
3566                 $upgrade_config = array();
3567                 $upgrade_config[1]['upgrade_vars']=array();
3568         }
3569     if(!is_array($upgrade_config[1]['upgrade_vars'])){
3570         $upgrade_config[1]['upgrade_vars'] = array();
3571     }
3572         if($currStep != null && $currState != null){
3573                 if(sizeof($upgrade_config) > 0){
3574                         if($currStepSub != null && $currStepSubState !=null){
3575                                 //check if new status to be set or update
3576                                 //get the latest in array. since it has sub components prepare an array
3577                                 if(!empty($upgrade_config[sizeof($upgrade_config)][$currStep]) && is_array($upgrade_config[sizeof($upgrade_config)][$currStep])){
3578                                         $latestStepSub = currSubStep($upgrade_config[sizeof($upgrade_config)][$currStep]);
3579                                         if($latestStepSub == $currStepSub){
3580                                                 $upgrade_config[sizeof($upgrade_config)][$currStep][$latestStepSub]=$currStepSubState;
3581                                                 $upgrade_config[sizeof($upgrade_config)][$currStep][$currStep] = $currState;
3582                                         }
3583                                         else{
3584                                                 $upgrade_config[sizeof($upgrade_config)][$currStep][$currStepSub]=$currStepSubState;
3585                                                 $upgrade_config[sizeof($upgrade_config)][$currStep][$currStep] = $currState;
3586                                         }
3587                                 }
3588                                 else{
3589                                         $currArray = array();
3590                                         $currArray[$currStep] = $currState;
3591                                         $currArray[$currStepSub] = $currStepSubState;
3592                                         $upgrade_config[sizeof($upgrade_config)+1][$currStep] = $currArray;
3593                                 }
3594                         }
3595           else{
3596                                 //get the current upgrade progress
3597                                 $latestStep = get_upgrade_progress();
3598                                 //set the upgrade progress
3599                                 //echo 'latest '.$latestStep;
3600                                 if($latestStep == $currStep){
3601                                         //update the current step with new progress status
3602                                         //echo 'update it';
3603                                         $upgrade_config[sizeof($upgrade_config)][$latestStep]=$currState;
3604                                 }
3605                                 else{
3606                                         //it's a new step
3607                                         //echo 'new it';
3608                                         $upgrade_config[sizeof($upgrade_config)+1][$currStep]=$currState;
3609                                 }
3610                     // now check if there elements within array substeps
3611           }
3612                 }
3613                 else{
3614                         //set the upgrade progress  (just starting)
3615                         $upgrade_config[sizeof($upgrade_config)+1][$currStep]= $currState;
3616                 }
3617
3618                 if(is_writable($upgrade_progress_file) && write_array_to_file( "upgrade_config", $upgrade_config,
3619                 $upgrade_progress_file)) {
3620                //writing to the file
3621                 }
3622
3623         }
3624 }
3625
3626 function get_upgrade_progress(){
3627         $upgrade_progress_dir = getcwd().'/'.$GLOBALS['sugar_config']['upload_dir'].'upgrades/temp';
3628         $upgrade_progress_file = $upgrade_progress_dir.'/upgrade_progress.php';
3629         $currState = '';
3630         $upgrade_progress_file = $upgrade_progress_dir.'/upgrade_progress.php';
3631
3632         if(file_exists($upgrade_progress_file)){
3633                 include($upgrade_progress_file);
3634                 //echo  'upconf '.$upgrade_config;
3635                 if(!isset($upgrade_config) || $upgrade_config == null){
3636                         $upgrade_config = array();
3637                 }
3638                 if($upgrade_config != null && sizeof($upgrade_config) >1){
3639                         $currArr = $upgrade_config[sizeof($upgrade_config)];
3640                                 //echo 'size of '.sizeof($upgrade_config);
3641                         if(is_array($currArr)){
3642                            foreach($currArr as $key=>$val){
3643                                         $currState = $key;
3644                                 }
3645                         }
3646                 }
3647         }
3648         return $currState;
3649 }
3650 function currSubStep($currStep){
3651         $currSubStep = '';
3652         if(is_array($currStep)){
3653        foreach($currStep as $key=>$val){
3654                     if($key != null){
3655                         $currState = $key;
3656                         }
3657            }
3658         }
3659         return $currState;
3660 }
3661 function currUpgradeState($currState){
3662         $currState = '';
3663         if(is_array($currState)){
3664        foreach($currState as $key=>$val){
3665                         if(is_array($val)){
3666                                 foreach($val as $k=>$v){
3667                                         if($k != null){
3668                                                 $currState = $k;
3669                                         }
3670                                 }
3671                         }
3672                         else{
3673                                 $currState = $key;
3674                         }
3675                 }
3676         }
3677         return $currState;
3678 }
3679
3680 function didThisStepRunBefore($step,$SubStep=''){
3681         if($step == null) return;
3682         $upgrade_progress_dir = getcwd().'/'.$GLOBALS['sugar_config']['upload_dir'].'upgrades/temp';
3683         $upgrade_progress_file = $upgrade_progress_dir.'/upgrade_progress.php';
3684         $currState = '';
3685         $upgrade_progress_file = $upgrade_progress_dir.'/upgrade_progress.php';
3686         $stepRan = false;
3687         if(file_exists($upgrade_progress_file)){
3688                 include($upgrade_progress_file);
3689                 if(isset($upgrade_config) && $upgrade_config != null && is_array($upgrade_config) && sizeof($upgrade_config) >0){
3690                         for($i=1;$i<=sizeof($upgrade_config);$i++){
3691                           if(is_array($upgrade_config[$i])){
3692                                         foreach($upgrade_config[$i] as $key=>$val){
3693                                                 if($key==$step){
3694                                                         if(is_array($upgrade_config[$i][$step])){
3695                                                                 //now process
3696                                                                 foreach ($upgrade_config[$i][$step] as $k=>$v){
3697                                                                         if(is_array($v)){
3698                                                                                 foreach($v as $k1=>$v1){
3699                                                                                         if($SubStep != null){
3700                                                                                                 if($SubStep ==$k1 && $v1=='done'){
3701                                                                                                         //echo 'Found Inside '.$k1;
3702                                                                                                         $stepRan = true;
3703                                                                                                         break;
3704                                                                                                 }
3705                                                                                         }
3706                                                                                 }//foreach
3707                                                                         }
3708                                                                         elseif($SubStep !=null){
3709                                                                                 if($SubStep==$k && $v=='done'){
3710                                                                                         //echo 'Found1 '.$k;
3711                                                                                         $stepRan = true;
3712                                                                                         break;
3713                                                                                 }
3714                                                                         }
3715                                                                         elseif($step==$k && $v=='done'){
3716                                                                                 //echo 'Found2 '.$k;
3717                                                                                 $stepRan = true;
3718                                                                                 break;
3719                                                                         }
3720                                                                 }//foreach
3721                                                         }
3722                                                         elseif($val=='done'){
3723                                                                 //echo 'Foundmmmm '.$key;
3724                                                                 $stepRan = true;
3725                                                         }
3726                                                 }
3727                                         }//foreach
3728                                 }
3729                         }//for
3730                 }
3731         }
3732         return $stepRan;
3733 }
3734
3735
3736
3737 //get and set post install status
3738 function post_install_progress($progArray='',$action=''){
3739         if($action=='' || $action=='get'){
3740                 //get the state of post install
3741                 $upgrade_progress_dir = getcwd().'/'.$GLOBALS['sugar_config']['upload_dir'].'upgrades/temp';
3742                 $upgrade_progress_file = $upgrade_progress_dir.'/upgrade_progress.php';
3743         $currProg = array();
3744                 if(file_exists($upgrade_progress_file)){
3745                         include($upgrade_progress_file);
3746                         if(is_array($upgrade_config[sizeof($upgrade_config)]['commit']['post_install']) && sizeof($upgrade_config[sizeof($upgrade_config)]['commit']['post_install'])>0){
3747                                 foreach($upgrade_config[sizeof($upgrade_config)]['commit']['post_install'] as $k=>$v){
3748                                         $currProg[$k]=$v;
3749                                 }
3750                         }
3751                 }
3752                 return $currProg;
3753         }
3754         elseif($action=='set'){
3755                 $upgrade_progress_dir = getcwd().'/'.$GLOBALS['sugar_config']['upload_dir'].'upgrades/temp';
3756                 if(!is_dir($upgrade_progress_dir)){
3757                         mkdir($upgrade_progress_dir);
3758                 }
3759                 $upgrade_progress_file = $upgrade_progress_dir.'/upgrade_progress.php';
3760                 if(file_exists($upgrade_progress_file)){
3761                         include($upgrade_progress_file);
3762                 }
3763                 else{
3764                         fopen($upgrade_progress_file, 'w+');
3765                 }
3766                 if(!is_array($upgrade_config[sizeof($upgrade_config)]['commit']['post_install'])){
3767                         $upgrade_config[sizeof($upgrade_config)]['commit']['post_install']=array();
3768                         $upgrade_config[sizeof($upgrade_config)]['commit']['post_install']['post_install'] = 'in_progress';
3769                 }
3770                 if($progArray != null && is_array($progArray)){
3771                         foreach($progArray as $key=>$val){
3772                                 $upgrade_config[sizeof($upgrade_config)]['commit']['post_install'][$key]=$val;
3773                         }
3774                 }
3775                 if(is_writable($upgrade_progress_file) && write_array_to_file( "upgrade_config", $upgrade_config,
3776                 $upgrade_progress_file)) {
3777                //writing to the file
3778                 }
3779         }
3780 }
3781
3782
3783 // parse and run sql file
3784 function parseAndExecuteSqlFileExtended($sqlScript){
3785         global $sugar_config;
3786         $alterTableSchema = '';
3787         $db = & DBManagerFactory::getInstance();
3788         if(is_file($sqlScript)) {
3789                 $fp = fopen($sqlScript, 'r');
3790                 $contents = fread($fp, filesize($sqlScript));
3791             $anyScriptChanges =$contents;
3792                 if(rewind($fp)) {
3793                         $completeLine = '';
3794                         $count = 0;
3795                         while($line = fgets($fp)) {
3796                                 if(strpos($line, '--') === false) {
3797                                         $completeLine .= " ".trim($line);
3798                                         if(strpos($line, ';') !== false) {
3799                                                 $completeLine = str_replace(';','',$completeLine);
3800                             $currLine = explode(",",$completeLine);
3801                             //check if multiple statements are clubbed
3802                             if(sizeof($currLine) >1){
3803                                 $qarr = explode(" ",trim($currLine[0]));
3804                                 if(strtoupper(trim($qarr[0])) == 'CREATE' && strtoupper(trim($qarr[1])) == 'TABLE'){
3805                                     if(strtoupper(trim($qarr[2]) != null)){
3806                                         if($sugar_config['dbconfig']['db_type'] == 'oci8'){
3807                                                 $query= "select table_name from user_tables where table_name=strtoupper(trim($qarr[2]))";
3808                                                                                 $result = $db->query($query);
3809                                                                                 $row = $db->fetchByAssociation($result);
3810                                                                                 if($row['table_name'] != null){
3811                                                                                         //already exists
3812                                                                                 }
3813                                                                                 else{
3814                                                                                         //create table
3815                                                                                         $query= $completeLine;
3816                                                                                         $db->query($query);
3817                                                                                 }
3818                                         }
3819
3820                                     }
3821
3822                                 }
3823                                 else{
3824                                         $qType =trim($qarr[0])." ".trim($qarr[1])." ".trim($qarr[2]);
3825                                         echo trim($currLine[0])."<br />";
3826                                     for ($i = 1; $i <= sizeof($currLine)-1; $i++) {
3827                                                                    $query = $qType." ".trim($currLine[$i]);
3828                                                                    echo $query."<br />";
3829                                                                 }
3830                                 }
3831
3832                             }
3833                             else{
3834                                 echo  trim($currLine[0]);
3835                             }
3836
3837
3838                         //$q3 = $completeLine;
3839                                                 //''$r3 = $GLOBALS['db']->query($q3, false, "Preflight Failed for:");
3840                         //echo mysql_error();
3841                                                 $completeLine = '';
3842                                                 //break;
3843                                         }
3844                                 }
3845                         }
3846                 } else {
3847
3848                         //$sqlErrors[] = $mod_strings['ERR_UW_FILE_NOT_READABLE'].'::'.$sqlScript;
3849                 }
3850         }
3851 }
3852 function createTable(){
3853         if($sugar_config['dbconfig']['db_type'] == 'oci8'){
3854                 $query= "select table_name from user_tables where table_name=strtoupper(trim($qarr[2]))";
3855                 $result = $db->query($query);
3856                 $row = $db->fetchByAssociation($result);
3857                 if($row['table_name'] != null){
3858                         //already exists
3859                 }
3860                 else{
3861                         //create table
3862                         $query= $completeLine;
3863                         $db->query($query);
3864                 }
3865         }
3866 }
3867
3868
3869 function repairDBForUpgrade($execute=false,$path=''){
3870
3871         global $current_user, $beanFiles;
3872         global $dictionary;
3873         set_time_limit(3600);
3874
3875         $db = &DBManagerFactory::getInstance();
3876         $sql = '';
3877         VardefManager::clearVardef();
3878         require_once('include/ListView/ListView.php');
3879         foreach ($beanFiles as $bean => $file) {
3880                 require_once ($file);
3881                 $focus = new $bean ();
3882                 $sql .= $db->repairTable($focus, $execute);
3883
3884         }
3885         //echo $sql;
3886         $olddictionary = $dictionary;
3887         unset ($dictionary);
3888         include ('modules/TableDictionary.php');
3889         foreach ($dictionary as $meta) {
3890                 $tablename = $meta['table'];
3891                 $fielddefs = $meta['fields'];
3892                 $indices = $meta['indices'];
3893                 $sql .= $db->repairTableParams($tablename, $fielddefs, $indices, $execute);
3894         }
3895          $qry_str = "";
3896           foreach (explode("\n", $sql) as $line) {
3897                   if (!empty ($line) && substr($line, -2) != "*/") {
3898                         $line .= ";";
3899                   }
3900                   $qry_str .= $line . "\n";
3901            }
3902           $sql = str_replace(
3903           array(
3904                 "\n",
3905                 '&#039;',
3906            ),
3907           array(
3908                 '',
3909                 "'",
3910           ),
3911           preg_replace('#(/\*.+?\*/\n*)#', '', $qry_str)
3912           );
3913          logThis("*******START EXECUTING DB UPGRADE QUERIES***************",$path);
3914                 logThis($sql,$path);
3915          logThis("*******END EXECUTING DB UPGRADE QUERIES****************",$path);
3916          if(!$execute){
3917                 return $sql;
3918          }
3919 }
3920
3921
3922
3923 /**
3924  * upgradeUserPreferences
3925  * This method updates the user_preferences table and sets the pages/dashlets for users
3926  * which have ACL access to Trackers so that the Tracker dashlets are set in their user perferences
3927  *
3928  */
3929 function upgradeUserPreferences() {
3930
3931 }
3932
3933
3934 function add_custom_modules_favorites_search(){
3935     $module_directories = scandir('modules');
3936
3937         foreach($module_directories as $module_dir){
3938                 if($module_dir == '.' || $module_dir == '..' || !is_dir("modules/{$module_dir}")){
3939                         continue;
3940                 }
3941
3942                 $matches = array();
3943                 preg_match('/^[a-z0-9]{1,5}_[a-z0-9]+$/i' , $module_dir, $matches);
3944
3945                 // Make sure the module was created by module builder
3946                 if(empty($matches)){
3947                         continue;
3948                 }
3949
3950                 $full_module_dir = "modules/{$module_dir}/";
3951                 $read_searchdefs_from = "{$full_module_dir}/metadata/searchdefs.php";
3952                 $read_SearchFields_from = "{$full_module_dir}/metadata/SearchFields.php";
3953                 $read_custom_SearchFields_from = "custom/{$full_module_dir}/metadata/SearchFields.php";
3954
3955                 // Studio can possibly override this file, so we check for a custom version of it
3956                 if(file_exists("custom/{$full_module_dir}/metadata/searchdefs.php")){
3957                         $read_searchdefs_from = "custom/{$full_module_dir}/metadata/searchdefs.php";
3958                 }
3959
3960                 if(file_exists($read_searchdefs_from) && file_exists($read_SearchFields_from)){
3961                         $found_sf1 = false;
3962                         $found_sf2 = false;
3963                         require($read_searchdefs_from);
3964                         foreach($searchdefs[$module_dir]['layout']['basic_search'] as $sf_array){
3965                                 if(isset($sf_array['name']) && $sf_array['name'] == 'favorites_only'){
3966                                         $found_sf1 = true;
3967                                 }
3968                         }
3969
3970                         require($read_SearchFields_from);
3971                         if(isset($searchFields[$module_dir]['favorites_only'])){
3972                                 $found_sf2 = true;
3973                         }
3974
3975                         if(!$found_sf1 && !$found_sf2){
3976                                 $searchdefs[$module_dir]['layout']['basic_search']['favorites_only'] = array('name' => 'favorites_only','label' => 'LBL_FAVORITES_FILTER','type' => 'bool',);
3977                                 $searchdefs[$module_dir]['layout']['advanced_search']['favorites_only'] = array('name' => 'favorites_only','label' => 'LBL_FAVORITES_FILTER','type' => 'bool',);
3978                                 $searchFields[$module_dir]['favorites_only'] = array(
3979                                         'query_type'=>'format',
3980                                         'operator' => 'subquery',
3981                                         'subquery' => 'SELECT sugarfavorites.record_id FROM sugarfavorites
3982                                                                 WHERE sugarfavorites.deleted=0
3983                                                                         and sugarfavorites.module = \''.$module_dir.'\'
3984                                                                         and sugarfavorites.assigned_user_id = \'{0}\'',
3985                                         'db_field'=>array('id')
3986                                 );
3987
3988                                 if(!is_dir("custom/{$full_module_dir}/metadata")){
3989                                         mkdir_recursive("custom/{$full_module_dir}/metadata");
3990                                 }
3991                                 $success_sf1 = write_array_to_file('searchdefs', $searchdefs, "custom/{$full_module_dir}/metadata/searchdefs.php");
3992                                 $success_sf2 = write_array_to_file('searchFields', $searchFields, "{$full_module_dir}/metadata/SearchFields.php");
3993
3994                                 if(!$success_sf1){
3995                                         logThis("add_custom_modules_favorites_search failed for searchdefs.php for {$module_dir}");
3996                                 }
3997                                 if(!$success_sf2){
3998                                         logThis("add_custom_modules_favorites_search failed for SearchFields.php for {$module_dir}");
3999                                 }
4000                                 if($success_sf1 && $success_sf2){
4001                                         logThis("add_custom_modules_favorites_search successfully updated searchdefs and searchFields for {$module_dir}");
4002                                 }
4003                         }
4004                 }
4005         }
4006 }
4007
4008
4009 /**
4010  * upgradeModulesForTeamsets
4011  *
4012  * This method adds the team_set_id values to the module tables that have the new team_set_id column
4013  * added through the SugarCRM 5.5.x upgrade process.  It also adds the values into the team_sets and
4014  * team_sets_teams tables.
4015  *
4016  * @param filter Array of modules to process; empty by default
4017  */
4018 function upgradeModulesForTeamsets($filter=array()) {
4019     require('include/modules.php');
4020         foreach($beanList as $moduleName=>$beanName) {
4021                     if(!empty($filter) && array_search($moduleName, $filter) === false) {
4022                        continue;
4023                     }
4024                 if($moduleName == 'TeamMemberships' || $moduleName == 'ForecastOpportunities'){
4025                 continue;
4026             }
4027                         $bean = loadBean($moduleName);
4028                         if(empty($bean) ||
4029                            empty($bean->table_name)) {
4030                            continue;
4031                         }
4032
4033                         $FieldArray = $GLOBALS['db']->helper->get_columns($bean->table_name);
4034                         if(!isset($FieldArray['team_id'])) {
4035                            continue;
4036                         }
4037
4038                         upgradeTeamColumn($bean, 'team_id');
4039
4040         } //foreach
4041
4042     //Upgrade users table
4043         $bean = loadBean('Users');
4044         upgradeTeamColumn($bean, 'default_team');
4045         $result = $GLOBALS['db']->query("SELECT id FROM teams where deleted=0");
4046         while($row = $GLOBALS['db']->fetchByAssoc($result)) {
4047               $teamset = new TeamSet();
4048               $teamset->addTeams($row['id']);
4049         }
4050 }
4051
4052
4053 /**
4054  * upgradeTeamColumn
4055  * Helper function to create a team_set_id column and also set team_set_id column
4056  * to have the value of the $column_name parameter
4057  *
4058  * @param $bean SugarBean which we are adding team_set_id column to
4059  * @param $column_name The name of the column containing the default team_set_id value
4060  */
4061 function upgradeTeamColumn($bean, $column_name) {
4062         //first let's check to ensure that the team_set_id field is defined, if not it could be the case that this is an older
4063         //module that does not use the SugarObjects
4064         if(empty($bean->field_defs['team_set_id']) && $bean->module_dir != 'Trackers'){
4065
4066                 //at this point we could assume that since we have a team_id defined and not a team_set_id that we need to
4067                 //add that field and the corresponding relationships
4068                 $object = $bean->object_name;
4069                 $module = $bean->module_dir;
4070                 $object_name = $object;
4071                 $_object_name = strtolower($object_name);
4072
4073                 if(!empty($GLOBALS['dictionary'][$object]['table'])){
4074                         $table_name = $GLOBALS['dictionary'][$object]['table'];
4075                 }else{
4076                         $table_name = strtolower($module);
4077                 }
4078
4079                 $path = 'include/SugarObjects/implements/team_security/vardefs.php';
4080                 require($path);
4081                 //go through each entry in the vardefs from team_security and unset anything that is already set in the core module
4082                 //this will ensure we have the proper ordering.
4083                 $fieldDiff = array_diff_assoc($vardefs['fields'], $GLOBALS['dictionary'][$bean->object_name]['fields']);
4084
4085                 $file = 'custom/Extension/modules/' . $bean->module_dir. '/Ext/Vardefs/teams.php';
4086                 $contents = "<?php\n";
4087                 if(!empty($fieldDiff)){
4088                         foreach($fieldDiff as $key => $val){
4089                                 $contents .= "\n\$GLOBALS['dictionary']['". $object . "']['fields']['". $key . "']=" . var_export_helper($val) . ";";
4090                         }
4091                 }
4092                 $relationshipDiff = array_diff_assoc($vardefs['relationships'], $GLOBALS['dictionary'][$bean->object_name]['relationships']);
4093                 if(!empty($relationshipDiff)){
4094                         foreach($relationshipDiff as $key => $val){
4095                                 $contents .= "\n\$GLOBALS['dictionary']['". $object . "']['relationships']['". $key . "']=" . var_export_helper($val) . ";";
4096                         }
4097                 }
4098                 $indexDiff = array_diff_assoc($vardefs['indices'], $GLOBALS['dictionary'][$bean->object_name]['indices']);
4099                 if(!empty($indexDiff)){
4100                         foreach($indexDiff as $key => $val){
4101                                         $contents .= "\n\$GLOBALS['dictionary']['". $object . "']['indices']['". $key . "']=" . var_export_helper($val) . ";";
4102                         }
4103                 }
4104                 if( $fh = @sugar_fopen( $file, 'wt' ) )
4105             {
4106                 fputs( $fh, $contents);
4107                 fclose( $fh );
4108             }
4109
4110
4111                 //we have written out the teams.php into custom/Extension/modules/{$module_dir}/Ext/Vardefs/teams.php'
4112                 //now let's merge back into vardefs.ext.php
4113                 require_once('ModuleInstall/ModuleInstaller.php');
4114                 $mi = new ModuleInstaller();
4115                 $mi->merge_files('Ext/Vardefs/', 'vardefs.ext.php');
4116                 VardefManager::loadVardef($bean->module_dir, $bean->object_name, true);
4117                 $bean->field_defs = $GLOBALS['dictionary'][$bean->object_name]['fields'];
4118         }
4119
4120         if(isset($bean->field_defs['team_set_id'])) {
4121                 //Create the team_set_id column
4122                 $FieldArray = $GLOBALS['db']->helper->get_columns($bean->table_name);
4123                 if(!isset($FieldArray['team_set_id'])) {
4124                         $GLOBALS['db']->addColumn($bean->table_name, $bean->field_defs['team_set_id']);
4125                 }
4126                 $indexArray =  $GLOBALS['db']->helper->get_indices($bean->table_name);
4127                 $indexDef = array(
4128                                          array(
4129                                                 'name' => 'idx_'.strtolower($bean->table_name).'_tmst_id',
4130                                                 'type' => 'index',
4131                                                 'fields' => array('team_set_id')
4132                                          )
4133                                    );
4134                 if(!isset($indexArray['idx_'.strtolower($bean->table_name).'_tmst_id'])) {
4135                         $GLOBALS['db']->addIndexes($bean->table_name, $indexDef);
4136                 }
4137
4138                 //Update the table's team_set_id column to have the same values as team_id
4139             $GLOBALS['db']->query("UPDATE {$bean->table_name} SET team_set_id = {$column_name}");
4140         }
4141 }
4142
4143 /**
4144  *  Update the folder subscription table which confirms to the team security mechanism but
4145  *  the class SugarFolders does not extend SugarBean and is therefore never picked up by the
4146  *  upgradeModulesForTeamsets function.
4147  */
4148 function upgradeFolderSubscriptionsTeamSetId()
4149 {
4150     logThis("In upgradeFolderSubscriptionsTeamSetId()");
4151     $query = "UPDATE folders SET team_set_id = team_id";
4152     $result = $GLOBALS['db']->query($query);
4153     logThis("Finished upgradeFolderSubscriptionsTeamSetId()");
4154 }
4155
4156 /**
4157  * upgradeModulesForTeam
4158  *
4159  * This method update the associated_user_id, name, name_2 to the private team records on teams table
4160  * This function is used for upgrade process from 5.1.x and 5.2.x.
4161  *
4162  */
4163 function upgradeModulesForTeam() {
4164     logThis("In upgradeModulesForTeam()");
4165     $result = $GLOBALS['db']->query("SELECT id, user_name, first_name, last_name FROM users where deleted=0");
4166
4167     while($row = $GLOBALS['db']->fetchByAssoc($result)) {
4168         $results2 = $GLOBALS['db']->query("SELECT id FROM teams WHERE name = '({$row['user_name']})'");
4169         $assoc = '';
4170                 if(!$assoc = $GLOBALS['db']->fetchByAssoc($results2)) {
4171                         //if team does not exist, then lets create the team for this user
4172                         $team = new Team();
4173                         $user = new User();
4174                         $user->retrieve($row['id']);
4175                         $team->new_user_created($user);
4176                         $team_id = $team->id;
4177                 }else{
4178                         $team_id =$assoc['id'];
4179                 }
4180
4181                         //upgrade the team
4182                         $name = is_null($row['first_name'])?'':$row['first_name'];
4183                         $name_2 = is_null($row['last_name'])?'':$row['last_name'];
4184                         $associated_user_id = $row['id'];
4185
4186                         //Bug 32914
4187                         //Ensure team->name is not empty by using team->name_2 if available
4188                         if(empty($name) && !empty($name_2)) {
4189                            $name = $name_2;
4190                            $name_2 = '';
4191                         }
4192
4193                         $query = "UPDATE teams SET name = '{$name}', name_2 = '{$name_2}', associated_user_id = '{$associated_user_id}' WHERE id = '{$team_id}'";
4194                         $GLOBALS['db']->query($query);
4195     } //while
4196
4197     //Update the team_set_id and default_team columns
4198     $ce_to_pro_or_ent = (isset($_SESSION['upgrade_from_flavor']) && ($_SESSION['upgrade_from_flavor'] == 'SugarCE to SugarPro' || $_SESSION['upgrade_from_flavor'] == 'SugarCE to SugarEnt'));
4199
4200     //Update team_set_id
4201         if((isset($_SESSION['current_db_version']) && $_SESSION['current_db_version'] < '550') || $ce_to_pro_or_ent) {
4202            $GLOBALS['db']->query("update users set team_set_id = (select teams.id from teams where teams.associated_user_id = users.id)");
4203         }
4204
4205         //Update default_team
4206         if($ce_to_pro_or_ent) {
4207            $GLOBALS['db']->query("update users set default_team = (select teams.id from teams where teams.associated_user_id = users.id)");
4208         }
4209
4210 }
4211
4212
4213     function addNewSystemTabsFromUpgrade($from_dir){
4214         global $path;
4215         if(isset($_SESSION['upgrade_from_flavor'])){
4216
4217             //check to see if there are any new files that need to be added to systems tab
4218             //retrieve old modules list
4219             logThis('check to see if new modules exist',$path);
4220             $oldModuleList = array();
4221             $newModuleList = array();
4222             include($from_dir.'/include/modules.php');
4223             $oldModuleList = $moduleList;
4224             include('include/modules.php');
4225             $newModuleList = $moduleList;
4226
4227             //include tab controller
4228             require_once('modules/MySettings/TabController.php');
4229             $newTB = new TabController();
4230
4231             //make sure new modules list has a key we can reference directly
4232             $newModuleList = $newTB->get_key_array($newModuleList);
4233             $oldModuleList = $newTB->get_key_array($oldModuleList);
4234
4235             //iterate through list and remove commonalities to get new modules
4236             foreach ($newModuleList as $remove_mod){
4237                 if(in_array($remove_mod, $oldModuleList)){
4238                     unset($newModuleList[$remove_mod]);
4239                 }
4240             }
4241             //new modules list now has left over modules which are new to this install, so lets add them to the system tabs
4242             logThis('new modules to add are '.var_export($newModuleList,true),$path);
4243
4244             //grab the existing system tabs
4245             $tabs = $newTB->get_system_tabs();
4246
4247             //add the new tabs to the array
4248             foreach($newModuleList as $nm ){
4249               $tabs[$nm] = $nm;
4250             }
4251
4252             if(!file_exists('modules/iFrames/iFrame.php') && isset($tabs['iFrames'])){
4253                 unset($tabs['iFrames']);
4254             }
4255
4256                 //Set the default order
4257                 $default_order = array(
4258                         'Home'=>'Home',
4259                         'Accounts'=>'Accounts',
4260                         'Contacts'=>'Contacts',
4261                         'Opportunities'=>'Opportunities',
4262                         'Activities'=>'Activities',
4263                         'Documents'=>'Documents'
4264                 );
4265                 $tabs = array_merge($default_order, $tabs);
4266
4267             //now assign the modules to system tabs
4268             $newTB->set_system_tabs($tabs);
4269             logThis('module tabs updated',$path);
4270
4271         }
4272     }
4273
4274     /**
4275      * fix_dropdown_list
4276      * This method attempts to fix dropdown lists that were incorrectly named.
4277      * There were versions of SugarCRM that did not enforce naming convention rules
4278      * for the dropdown list field name.  This method attempts to resolve that by
4279      * fixing the language files that may have been affected and then updating the
4280      * fields_meta_data table accordingly.  It also refreshes any vardefs that may
4281      * have been affected.
4282      *
4283      */
4284         function fix_dropdown_list() {
4285         if(file_exists('custom/include/language')) {
4286            $files = array();
4287            $affected_modules = array();
4288            $affected_keys = array();
4289
4290            getFiles($files, 'custom/include/language', '/\.php$/i');
4291            foreach($files as $file) {
4292
4293               if(file_exists($file . '.bak')) {
4294                  $bak_mod_time = filemtime($file . '.bak');
4295                  $php_mod_time = filemtime($file);
4296                  //We're saying if the .php file was modified 30 seconds no more than php.bak file then we
4297                  //run these additional cleanup checks
4298                  if($php_mod_time - $bak_mod_time < 30) {
4299
4300                         $app_list_strings = array();
4301                         $GLOBALS['app_list_strings'] = array();
4302                         require($file . '.bak');
4303                         $bak_app_list_strings = array_merge($app_list_strings, $GLOBALS['app_list_strings']);
4304
4305                         $app_list_strings = array();
4306                         $GLOBALS['app_list_strings'] = array();
4307                         require($file);
4308                         $php_app_list_strings = array_merge($app_list_strings, $GLOBALS['app_list_strings']);
4309
4310                         //Get the file contents
4311                         $contents = file_get_contents($file);
4312
4313                         //Now simulate a fix for the file before we compare w/ the .php file
4314                         //we also append to the $contents
4315                         foreach($bak_app_list_strings as $key=>$entry) {
4316                                                    if(preg_match('/([^A-Za-z_])/', $key, $matches) && is_array($entry)) {
4317                                                           $new_key = preg_replace('/[^A-Za-z_]/', '_', $key);
4318                                                           $bak_app_list_strings[$new_key] = $bak_app_list_strings[$key];
4319                                                           unset($bak_app_list_strings[$key]);
4320                                                           //Now if the entry doesn't exists in the .php file, then add to contents
4321                                                           if(!isset($php_app_list_strings[$new_key])) {
4322                                                                  $contents .= "\n\$GLOBALS['app_list_strings']['{$new_key}'] = " . var_export_helper($bak_app_list_strings[$new_key]) . ";";
4323                                                           }
4324                                                    } //if
4325                         } //foreach
4326
4327                         //Now load the .php file to do the comparison
4328                         foreach($php_app_list_strings as $key=>$entry) {
4329                                 if(isset($bak_app_list_strings[$key])) {
4330                                         $diff = array_diff($bak_app_list_strings[$key], $entry);
4331                                         if(!empty($diff)) {
4332                                            //There is a difference, so copy the $bak_app_list_strings version into the .php file
4333                                            $contents .= "\n\$GLOBALS['app_list_strings']['{$key}'] = " . var_export_helper($bak_app_list_strings[$key]) . ";";
4334                                         } //if
4335                                 } //if
4336                         } //foreach
4337
4338                         //Now write out the file contents
4339                         //Create backup just in case
4340                         copy($file, $file . '.php_bak');
4341                                         $fp = @sugar_fopen($file, 'w');
4342                         if($fp) {
4343                                fwrite($fp, $contents);
4344                                fclose($fp);
4345                         } else {
4346                            $GLOBALS['log']->error("Unable to update file contents in fix_dropdown_list for {$file}");
4347                         } //if-else
4348                  }
4349               }
4350
4351               unset($GLOBALS['app_strings']);
4352               unset($GLOBALS['app_list_strings']);
4353               $app_list_strings = array();
4354                   require($file);
4355                   $touched = false;
4356                   $contents = file_get_contents($file);
4357                   if ( !isset($GLOBALS['app_list_strings']) ) {
4358                       $GLOBALS['app_list_strings'] = $app_list_strings;
4359                   }
4360                   else {
4361                       $GLOBALS['app_list_strings'] = array_merge($app_list_strings, $GLOBALS['app_list_strings']);
4362                   }
4363                   if(isset($GLOBALS['app_list_strings']) && is_array($GLOBALS['app_list_strings'])) {
4364                          foreach($GLOBALS['app_list_strings'] as $key=>$entry) {
4365                                 if(preg_match('/([^A-Za-z_])/', $key, $matches) && is_array($entry)) {
4366                                    $result = $GLOBALS['db']->query("SELECT custom_module FROM fields_meta_data WHERE ext1 = '{$key}'");
4367                                    if(!empty($result)) {
4368                                           while($row = $GLOBALS['db']->fetchByAssoc($result)) {
4369                                                     $custom_module = $row['custom_module'];
4370                                                     if(!empty($GLOBALS['beanList'][$custom_module])) {
4371                                                    $affected_modules[$custom_module] = $GLOBALS['beanList'][$custom_module];
4372                                                     }
4373                                           } //while
4374                                    }
4375
4376                                    //Replace all invalid characters with '_' character
4377                                    $new_key = preg_replace('/[^A-Za-z_]/', '_', $key);
4378                                    $affected_keys[$key] = $new_key;
4379
4380                                    $GLOBALS['app_list_strings'][$new_key] = $GLOBALS['app_list_strings'][$key];
4381                                    unset($GLOBALS['app_list_strings'][$key]);
4382
4383                                    $pattern_match = "/(\[\s*\'{$key}\'\s*\])/";
4384                                    $new_key = "['{$new_key}']";
4385                                    $out = preg_replace($pattern_match, $new_key, $contents);
4386                                    $contents = $out;
4387                                    $touched = true;
4388                                 } //if
4389                          } //foreach
4390
4391                  //This is a check for g => h instances where the file contents were incorrectly written
4392                  //and also fixes the scenario where via a UI upgrade, the app_list_strings were incorrectly
4393                  //merged with app_list_strings variables declared elsewhere
4394                          if(!$touched) {
4395                                    if(preg_match('/\$GLOBALS\s*\[\s*[\"|\']app_list_strings[\"|\']\s*\]\s*=\s*array\s*\(/', $contents)) {
4396                                           //Now also remove all the non-custom labels that were added
4397                                           if(preg_match('/language\/([^\.]+)\.lang\.php$/', $file, $matches)) {
4398                                                 $language = $matches[1];
4399
4400                                                 $app_list_strings = array();
4401
4402                                         if(file_exists("include/language/$language.lang.php")) {
4403                                                                    include("include/language/$language.lang.php");
4404                                                                 }
4405                                                                 if(file_exists("include/language/$language.lang.override.php")) {
4406                                                                    $app_list_strings =  _mergeCustomAppListStrings("include/language/$language.lang.override.php" , $app_list_strings) ;
4407                                                                 }
4408                                                                 if(file_exists("custom/application/Ext/Language/$language.ext.lang.php")) {
4409                                                                    $app_list_strings =  _mergeCustomAppListStrings("custom/application/Ext/Language/$language.ext.lang.php" , $app_list_strings) ;
4410                                                                 }
4411                                                                 if(file_exists("custom/application/Ext/Language/$language.lang.ext.php")) {
4412                                                                    $app_list_strings =  _mergeCustomAppListStrings("custom/application/Ext/Language/$language.lang.ext.php" , $app_list_strings) ;
4413                                                                 }
4414
4415                                                                 $all_non_custom_include_language_strings = $app_strings;
4416                                                                 $all_non_custom_include_language_list_strings = $app_list_strings;
4417
4418                                                                 $unset_keys = array();
4419                                                                 if(!empty($GLOBALS['app_list_strings'])) {
4420                                                                         foreach($GLOBALS['app_list_strings'] as $key=>$value) {
4421                                                                                 $diff = array();
4422                                                                                 if(isset($all_non_custom_include_language_list_strings[$key])) {
4423                                                                                         $diff = array_diff($all_non_custom_include_language_list_strings[$key], $GLOBALS['app_list_strings'][$key]);
4424                                                                                 }
4425
4426                                                                                 if(!empty($all_non_custom_include_language_list_strings[$key]) && empty($diff)) {
4427                                                                                         $unset_keys[] = $key;
4428                                                                                 }
4429                                                                         }
4430                                                                 }
4431
4432                                                                 foreach($unset_keys as $key) {
4433                                                                         unset($GLOBALS['app_list_strings'][$key]);
4434                                                                 }
4435
4436                                                                 if(!empty($GLOBALS['app_strings'])) {
4437                                                                 foreach($GLOBALS['app_strings'] as $key=>$value) {
4438                                                                                 if(!empty($all_non_custom_include_language_strings[$key])) {
4439                                                                                    unset($GLOBALS['app_strings'][$key]);
4440                                                                                 }
4441                                                                 }
4442                                                                 }
4443                                           } //if(preg_match...)
4444
4445                                       $out = "<?php \n";
4446                                       if(!empty($GLOBALS['app_strings'])) {
4447                                              foreach($GLOBALS['app_strings'] as $key=>$entry) {
4448                                                      $out .= "\n\$GLOBALS['app_strings']['$key']=" . var_export_helper($entry) . ";";
4449                                              }
4450                                       }
4451
4452                                                   foreach($GLOBALS['app_list_strings'] as $key=>$entry) {
4453                                                                   $out .= "\n\$GLOBALS['app_list_strings']['$key']=" . var_export_helper($entry) . ";";
4454                                                   } //foreach
4455
4456                                                   $touched = true;
4457                                    } //if(preg_match...)
4458                          } //if(!$touched)
4459
4460                          if($touched) {
4461                                  //Create a backup just in case
4462                                  copy($file, $file . '.bak');
4463                          $fp = @sugar_fopen($file, 'w');
4464                          if($fp) {
4465                                fwrite($fp, $out);
4466                                fclose($fp);
4467                          } else {
4468                            //If we can't update the file, just return
4469                            $GLOBALS['log']->error("Unable to update file contents in fix_dropdown_list.");
4470                            return;
4471                          }
4472                          } //if($touched)
4473                   } //if
4474
4475            } //foreach($files)
4476
4477            //Update db entries (the order matters here... need to process database changes first)
4478            if(!empty($affected_keys)) {
4479                   foreach($affected_keys as $old_key=>$new_key) {
4480                                   $GLOBALS['db']->query("UPDATE fields_meta_data SET ext1 = '{$new_key}' WHERE ext1 = '{$old_key}'");
4481                   }
4482            }
4483
4484            //Update vardef files for affected modules
4485            if(!empty($affected_modules)) {
4486                   foreach($affected_modules as $module=>$object) {
4487                           VardefManager::refreshVardefs($module, $object);
4488                   }
4489            }
4490         }
4491         }
4492
4493
4494         function update_iframe_dashlets(){
4495                 require_once('cache/dashlets/dashlets.php');
4496
4497                 $db = DBManagerFactory::getInstance();
4498                 $query = "SELECT id, contents, assigned_user_id FROM user_preferences WHERE deleted = 0 AND category = 'Home'";
4499                 $result = $db->query($query, true, "Unable to update new default dashlets! ");
4500                 while ($row = $db->fetchByAssoc($result)) {
4501                         $content = unserialize(base64_decode($row['contents']));
4502                         $assigned_user_id = $row['assigned_user_id'];
4503                         $record_id = $row['id'];
4504
4505                         $current_user = new User();
4506                         $current_user->retrieve($row['assigned_user_id']);
4507
4508                         if(!empty($content['dashlets']) && !empty($content['pages'])){
4509                                 $originalDashlets = $content['dashlets'];
4510                                 foreach($originalDashlets as $key => $ds){
4511                                     if(!empty($ds['options']['url']) && stristr($ds['options']['url'],'http://www.sugarcrm.com/crm/product/gopro')){
4512                                                 unset($originalDashlets[$key]);
4513                                         }
4514                                 }
4515                                 $current_user->setPreference('dashlets', $originalDashlets, 0, 'Home');
4516                         }
4517                 }
4518         }
4519
4520
4521     /**
4522      * convertImageToText
4523      * This method attempts to convert date type image to text on Microsoft SQL Server.
4524      * This method could NOT be used in any other type of datebases.
4525      */
4526         function convertImageToText($table_name,$column_name){
4527                 $set_lang = "SET LANGUAGE us_english";
4528                 $GLOBALS['db']->query($set_lang);
4529             if($GLOBALS['db']->checkError()){
4530             logThis('An error occurred when performing this query-->'.$set_lang);
4531         }
4532        $q="SELECT data_type
4533         FROM INFORMATION_SCHEMA.Tables T JOIN INFORMATION_SCHEMA.Columns C
4534         ON T.TABLE_NAME = C.TABLE_NAME where T.TABLE_NAME = '$table_name' and C.COLUMN_NAME = '$column_name'";
4535        $res= $GLOBALS['db']->query($q);
4536        if($GLOBALS['db']->checkError()){
4537             logThis('An error occurred when performing this query-->'.$q);
4538         }
4539        $row= $GLOBALS['db']->fetchByAssoc($res);
4540
4541      if(trim(strtolower($row['data_type'])) == 'image'){
4542         $addContent_temp = "alter table {$table_name} add {$column_name}_temp text null";
4543         $GLOBALS['db']->query($addContent_temp);
4544         if($GLOBALS['db']->checkError()){
4545             logThis('An error occurred when performing this query-->'.$addContent_temp);
4546         }
4547         $qN = "select count=datalength({$column_name}), id, {$column_name} from {$table_name}";
4548         $result = $GLOBALS['db']->query($qN);
4549         while($row = $GLOBALS['db']->fetchByAssoc($result)){
4550            if($row['count'] >8000){
4551                 $contentLength = $row['count'];
4552                 $start = 1;
4553                 $next=8000;
4554                 $convertedContent = '';
4555                 while($contentLength >0){
4556                     $stepsQuery = "select cont=convert(varchar(max), convert(varbinary(8000), substring({$column_name},{$start},{$next}))) from {$table_name} where id= '{$row['id']}'";
4557                     $steContQ = $GLOBALS['db']->query($stepsQuery);
4558                     if($GLOBALS['db']->checkError()){
4559                         logThis('An error occurred when performing this query-->'.$stepsQuery);
4560                     }
4561                     $stepCont = $GLOBALS['db']->fetchByAssoc($steContQ);
4562                     if(isset($stepCont['cont'])){
4563                         $convertedContent = $convertedContent.$stepCont['cont'];
4564                     }
4565                     $start = $start+$next;
4566                     $contentLength = $contentLength - $next;
4567                 }
4568                 $addContentDataText="update {$table_name} set {$column_name}_temp = '{$convertedContent}' where id= '{$row['id']}'";
4569                 $GLOBALS['db']->query($addContentDataText);
4570                 if($GLOBALS['db']->checkError()){
4571                     logThis('An error occurred when performing this query-->'.$addContentDataText);
4572                 }
4573            }
4574            else{
4575                 $addContentDataText="update {$table_name} set {$column_name}_temp =
4576                 convert(varchar(max), convert(varbinary(8000), {$column_name})) where id= '{$row['id']}'";
4577                 $GLOBALS['db']->query($addContentDataText);
4578                 if($GLOBALS['db']->checkError()){
4579                     logThis('An error occurred when performing this query-->'.$addContentDataText);
4580                 }
4581            }
4582         }
4583         //drop the contents now and change contents_temp to contents
4584         $dropColumn = "alter table {$table_name} drop column {$column_name}";
4585         $GLOBALS['db']->query($dropColumn);
4586         if($GLOBALS['db']->checkError()){
4587             logThis('An error occurred when performing this query-->'.$dropColumn);
4588         }
4589         $changeColumnName = "EXEC sp_rename '{$table_name}.[{$column_name}_temp]','{$column_name}','COLUMN'";
4590         $GLOBALS['db']->query($changeColumnName);
4591         if($GLOBALS['db']->checkError()){
4592             logThis('An error occurred when performing this query-->'.$changeColumnName);
4593         }
4594      }
4595     }
4596
4597          /**
4598      * clearHelpFiles
4599      * This method attempts to delete all English inline help files.
4600      * This method was introduced by 5.5.0RC2.
4601      */
4602     function clearHelpFiles(){
4603                 $modulePath = clean_path(getcwd() . '/modules');
4604                 $allHelpFiles = array();
4605                 getFiles($allHelpFiles, $modulePath, "/en_us.help.*/");
4606
4607                 foreach( $allHelpFiles as $the_file ){
4608                 if( is_file( $the_file ) ){
4609                     unlink( $the_file );
4610                     _logThis("Deleted file: $the_file", $path);
4611                 }
4612             }
4613         }
4614
4615
4616         /**
4617          * upgrade_connectors
4618          * @param $path String variable for the log path
4619          */
4620         function upgrade_connectors($path='') {
4621                 logThis('Begin upgrade_connectors', $path);
4622                 
4623                 $filePath = 'custom/modules/Connectors/connectors/sources/ext/soap/hoovers/config.php';
4624                 if(file_exists($filePath))
4625                 {
4626                    logThis("{$filePath} file", $path);  
4627                    require($filePath);
4628                    if(!is_null($config))
4629                    {
4630                           $modified = false;
4631                           if(isset($config['properties']['hoovers_endpoint']))
4632                           {
4633                                  $config['properties']['hoovers_endpoint'] = 'http://hapi.hoovers.com/HooversAPI-33';
4634                                  $modified = true;
4635                           }
4636                           
4637                           if(isset($config['properties']['hoovers_wsdl']))
4638                           {
4639                                  $config['properties']['hoovers_wsdl'] = 'http://hapi.hoovers.com/HooversAPI-33/hooversAPI/hooversAPI.wsdl';
4640                              $modified = true;
4641                           }
4642                           
4643                           if($modified)
4644                           {
4645                               if(!write_array_to_file('config', $config, $filePath)) {
4646                              logThis("Could not write new configuration to {$filePath} file", $path);   
4647                           } else {
4648                                  logThis('Modified file successfully with new configuration entries', $path);
4649                           }
4650                           }
4651                    }
4652                 }
4653
4654                 $filePath = 'custom/modules/Connectors/connectors/sources/ext/soap/hoovers/vardefs.php';
4655             if(file_exists($filePath))
4656                 {
4657                    logThis("Modifying {$filePath} file", $path);        
4658                    require($filePath);            
4659                    $fileContents = file_get_contents($filePath);
4660                    $out = str_replace('bal.specialtyCriteria.companyKeyword', 'bal.specialtyCriteria.companyName', $fileContents);
4661                    file_put_contents($filePath, $out);             
4662                 }
4663                 
4664                 logThis('End upgrade_connectors', $path);
4665         }
4666
4667
4668         function removeSilentUpgradeVarsCache(){
4669             global $silent_upgrade_vars_loaded;
4670
4671             $cacheFileDir = "{$GLOBALS['sugar_config']['cache_dir']}/silentUpgrader";
4672             $cacheFile = "{$cacheFileDir}/silentUpgradeCache.php";
4673
4674             if(file_exists($cacheFile)){
4675                 unlink($cacheFile);
4676             }
4677
4678             $silent_upgrade_vars_loaded = array(); // Set to empty to reset it
4679
4680             return true;
4681         }
4682
4683         function loadSilentUpgradeVars(){
4684             global $silent_upgrade_vars_loaded;
4685
4686             if(empty($silent_upgrade_vars_loaded)){
4687                 $cacheFile = "{$GLOBALS['sugar_config']['cache_dir']}/silentUpgrader/silentUpgradeCache.php";
4688                 // We have no pre existing vars
4689                 if(!file_exists($cacheFile)){
4690                     // Set the vars array so it's loaded
4691                     $silent_upgrade_vars_loaded = array('vars' => array());
4692                 }
4693                 else{
4694                     require_once($cacheFile);
4695                     $silent_upgrade_vars_loaded = $silent_upgrade_vars_cache;
4696                 }
4697             }
4698
4699             return true;
4700         }
4701
4702         function writeSilentUpgradeVars(){
4703             global $silent_upgrade_vars_loaded;
4704
4705             if(empty($silent_upgrade_vars_loaded)){
4706                 return false; // You should have set some values before trying to write the silent upgrade vars
4707             }
4708
4709             $cacheFileDir = "{$GLOBALS['sugar_config']['cache_dir']}/silentUpgrader";
4710             $cacheFile = "{$cacheFileDir}/silentUpgradeCache.php";
4711
4712             require_once('include/dir_inc.php');
4713             if(!mkdir_recursive($cacheFileDir)){
4714                 return false;
4715             }
4716             require_once('include/utils/file_utils.php');
4717             if(!write_array_to_file('silent_upgrade_vars_cache', $silent_upgrade_vars_loaded, $cacheFile, 'w')){
4718                 global $path;
4719                 logThis("WARNING: writeSilentUpgradeVars could not write to {$cacheFile}", $path);
4720                 return false;
4721             }
4722
4723             return true;
4724         }
4725
4726         function setSilentUpgradeVar($var, $value){
4727             if(!loadSilentUpgradeVars()){
4728                 return false;
4729             }
4730
4731             global $silent_upgrade_vars_loaded;
4732
4733             $silent_upgrade_vars_loaded['vars'][$var] = $value;
4734
4735             return true;
4736         }
4737
4738         function getSilentUpgradeVar($var){
4739             if(!loadSilentUpgradeVars()){
4740                 return false;
4741             }
4742
4743             global $silent_upgrade_vars_loaded;
4744
4745             if(!isset($silent_upgrade_vars_loaded['vars'][$var])){
4746                 return null;
4747             }
4748             else{
4749                 return $silent_upgrade_vars_loaded['vars'][$var];
4750             }
4751         }
4752
4753         /**
4754          * unlinkUpgradeFiles
4755          * This is a helper function to clean up 
4756          * 
4757          * @param $version String value of current system version (pre upgrade)
4758          */
4759         function unlinkUpgradeFiles($version)
4760         {
4761                 if(!isset($version))
4762                 {
4763                    return;
4764                 }
4765                 
4766                 logThis('start unlinking files from previous upgrade');
4767                 if($version < '614')
4768                 {
4769                    //list of files to remove
4770                    $files_to_remove = array('modules/Help/Forms.php');
4771                    
4772                    foreach($files_to_remove as $f)
4773                    {
4774                            if(file_exists($f))
4775                            {
4776                                   logThis('removing file: ' . $f);
4777                                   unlink($f);
4778                            }  
4779                    }
4780                 }
4781                 logThis('end unlinking files from previous upgrade');
4782         }       
4783         
4784 ?>