]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/UpgradeWizard/uw_ajax.php
Release 6.1.4
[Github/sugarcrm.git] / modules / UpgradeWizard / uw_ajax.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  * Description:
41  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. All Rights
42  * Reserved. Contributor(s): ______________________________________..
43  * *******************************************************************************/
44
45
46 ////    COMMON
47
48 function ajaxSqlProgress($persistence, $sql, $type) {
49         global $mod_strings;
50
51         // $type is sql_to_check or sql_to_run
52         $whatsLeft = count($persistence[$type]);
53
54         ob_start();
55         $out  = "<b>{$mod_strings['LBL_UW_PREFLIGHT_QUERY']}</b><br />";
56         $out .= round((($persistence['sql_total'] - $whatsLeft) / $persistence['sql_total']) * 100, 1)."%
57                                 {$mod_strings['LBL_UW_DONE']} - {$mod_strings['LBL_UW_PREFLIGHT_QUERIES_LEFT']}: {$whatsLeft}";
58         $out .= "<br /><textarea cols='60' rows='3' DISABLED>{$sql}</textarea>";
59         echo $out;
60         ob_flush();
61
62         if($whatsLeft < 1) {
63                 $persistence['sql_check_done'] = true;
64         }
65
66         return $persistence;
67 }
68
69
70 ///////////////////////////////////////////////////////////////////////////////
71 ////    COMMIT AJAX
72 /**
73  * does post-post-install stuff
74  * @param array persistence
75  * @return array persistence
76  */
77 function commitAjaxFinalTouches($persistence) {
78         global $current_user;
79         global $locale;
80         global $mod_strings;
81         global $sugar_version;
82
83         if(empty($sugar_version)) {
84                 require('sugar_version.php');
85         }
86
87         // convert to UTF8 if needed
88         if(!empty($persistence['allTables']))
89                 executeConvertTablesSql($db->dbType, $persistence['allTables']);
90
91         // rebuild
92         logThis('Performing UWrebuild()...');
93         UWrebuild();
94         logThis('UWrebuild() done.');
95
96         // upgrade history
97         registerUpgrade($persistence);
98
99         // flag to say upgrade has completed
100         $persistence['upgrade_complete'] = true;
101
102         // reminders if needed
103         ///////////////////////////////////////////////////////////////////////////////
104         ////    HANDLE REMINDERS
105         if(count($persistence['skipped_files']) > 0) {
106                 $desc  = $mod_strings['LBL_UW_COMMIT_ADD_TASK_OVERVIEW']."\n\n";
107                 $desc .= $mod_strings['LBL_UW_COMMIT_ADD_TASK_DESC_1'];
108                 $desc .= $persistence['uw_restore_dir']."\n\n";
109                 $desc .= $mod_strings['LBL_UW_COMMIT_ADD_TASK_DESC_2']."\n\n";
110
111                 foreach($persistence['skipped_files'] as $file) {
112                         $desc .= $file."\n";
113                 }
114
115                 //MFH #13468
116                 $nowDate = gmdate($timedate->dbDateFormat);
117                 $nowTime = gmdate($timedate->dbTimeFormat);
118                 $nowDateTime = $nowDate.' '.$nowTime;
119
120                 if($_REQUEST['addTaskReminder'] == 'remind') {
121                         logThis('Adding Task for admin for manual merge.');
122                         
123                         $task = new Task();
124                         $task->name = $mod_strings['LBL_UW_COMMIT_ADD_TASK_NAME'];
125                         $task->description = $desc;
126                         $task->date_due = $nowDate;
127                         $task->time_due = $nowTime;
128                         $task->priority = 'High';
129                         $task->status = 'Not Started';
130                         $task->assigned_user_id = $current_user->id;
131                         $task->created_by = $current_user->id;
132                         $task->date_entered = $nowDateTime;
133                         $task->date_modified = $nowDateTime;
134                         $task->save();
135                 }
136
137                 if($_REQUEST['addEmailReminder'] == 'remind') {
138                         logThis('Sending Reminder for admin for manual merge.');
139                         
140                         $email = new Email();
141                         $email->assigned_user_id = $current_user->id;
142                         $email->name = $mod_strings['LBL_UW_COMMIT_ADD_TASK_NAME'];
143                         $email->description = $desc;
144                         $email->description_html = nl2br($desc);
145                         $email->from_name = $current_user->full_name;
146                         $email->from_addr = $current_user->email1;
147                         $email->to_addrs_arr = $email->parse_addrs($current_user->email1,'','','');
148                         $email->cc_addrs_arr = array();
149                         $email->bcc_addrs_arr = array();
150                         $email->date_entered = $nowDateTime;
151                         $email->date_modified = $nowDateTime;
152                         $email->send();
153                         $email->save();
154                 }
155         }
156         ////    HANDLE REMINDERS
157         ///////////////////////////////////////////////////////////////////////////////
158
159         // clean up
160         unlinkTempFiles();
161
162         ob_start();
163         echo 'done';
164         ob_flush();
165
166         return $persistence;
167 }
168
169 /**
170  * runs one line of sql
171  * @param array $persistence
172  * @return array $persistence
173  */
174 function commitAjaxRunSql($persistence) {
175         global $db;
176
177         if(!isset($persistence['commit_sql_errors'])) {
178                 $persistence['commit_sql_errors'] = array();
179         }
180
181         // This flag is determined by the preflight check in the installer
182         if($persistence['schema_change'] == 'sugar') {
183
184                 if(isset($persistence['sql_to_run'])
185                         && count($persistence['sql_to_run']) > 0
186                         && !empty($persistence['sql_to_run'])) {
187
188                         $sql = array_shift($persistence['sql_to_run']);
189                         $sql = trim($sql);
190
191                         if(!empty($sql)) {
192                                 logThis("[RUNNING SQL QUERY] {$sql}");
193                                 $db->query($sql);
194
195                                 $error = '';
196                                 switch($db->dbType) {
197                                         case 'mysql':
198                                                 $error = mysql_error();
199                                         break;
200
201                                         case 'oci8':
202                                         break;
203
204                                         case 'mssql':
205
206                                         break;
207                                 }
208
209                                 if(!empty($error)) {
210                                         logThis('************************************************************');
211                                         logThis('*** ERROR: SQL Commit Error!');
212                                         logThis('*** Query: [ '.$sql.' ]');
213                                         logThis('************************************************************');
214                                         $persistence['commit_sql_errors'][] = getFormattedError($error, $sql);
215                                 }
216                                 $persistence = ajaxSqlProgress($persistence, $sql, 'sql_to_run');
217                         }
218
219                 } else {
220                         ob_start();
221                         echo 'done';
222                         ob_flush();
223                 }
224         } else {
225                 ob_start();
226                 echo 'done';
227                 ob_flush();
228         }
229
230         return $persistence;
231 }
232
233 /**
234  * returns errors found during SQL operations
235  * @param array persistence
236  * @return string Error message or empty string on success
237  */
238 function commitAjaxGetSqlErrors($persistence) {
239         global $mod_strings;
240
241         $out = '';
242         if(isset($persistence['commit_sql_errors']) && !empty($persistence['commit_sql_errors'])) {
243                 $out = "<div class='error'>";
244                 foreach($persistence['commit_sql_errors'] as $error) {
245                         $out .= $error;
246                 }
247                 $out .= "</div>";
248         }
249
250         if(empty($out)) {
251                 $out = $mod_strings['LBL_UW_COMMIT_ALL_SQL_SUCCESSFULLY_RUN'];
252         }
253
254         ob_start();
255         echo $out;
256         ob_flush();
257 }
258
259 /**
260  * parses the sql upgrade file for sequential querying
261  * @param array persistence
262  * @return array persistence
263  */
264 function commitAjaxPrepSql($persistence) {
265         return preflightCheckJsonPrepSchemaCheck($persistence, false);
266 }
267
268
269 /**
270  * handles post-install tasks
271  */
272 function commitAjaxPostInstall($persistence) {
273         global $mod_strings;
274         global $sugar_config;
275         global $sugar_version;
276
277         if(empty($sugar_version)) {
278                 require('sugar_version.php');
279         }
280
281         // update versions info
282         if(!updateVersions($sugar_version)) {
283                 echo $mod_strings['ERR_UW_COMMIT_UPDATE_VERSIONS'];
284         }
285
286         logThis('Starting post_install()...');
287         $postInstallResults = "<b>{$mod_strings['LBL_UW_COMMIT_POSTINSTALL_RESULTS']}</b><br />
288                                                         <a href='javascript:toggleNwFiles(\"postInstallResults\");'>{$mod_strings['LBL_UW_SHOW']}</a><br />
289                                                         <div id='postInstallResults' style='display:none'>";
290         $file = $persistence['unzip_dir']. "/" . constant('SUGARCRM_POST_INSTALL_FILE');
291         if(is_file($file)) {
292                 include($file);
293                 ob_start();
294                 post_install();
295         }
296
297         require( "sugar_version.php" );
298
299         if (!rebuildConfigFile($sugar_config, $sugar_version)) {
300                 logThis('*** ERROR: could not write config.php! - upgrade will fail!');
301                 $errors[] = $mod_strings['ERR_UW_CONFIG_WRITE'];
302         }
303
304         $res = ob_get_contents();
305         $postInstallResults .= (empty($res)) ? $mod_strings['LBL_UW_SUCCESS'] : $res;
306         $postInstallResults .= "</div>";
307
308         ob_start();
309         echo $postInstallResults;
310         ob_flush();
311
312         logThis('post_install() done.');
313 }
314 ////    END COMMIT AJAX
315 ///////////////////////////////////////////////////////////////////////////////
316
317
318
319 ///////////////////////////////////////////////////////////////////////////////
320 ////    PREFLIGHT JSON STYLE
321
322 function preflightCheckJsonFindUpgradeFiles($persistence) {
323         global $sugar_config;
324         global $mod_strings;
325
326         unset($persistence['rebuild_relationships']);
327         unset($persistence['rebuild_extensions']);
328
329         // don't bother if are rechecking
330         $manualDiff                     = array();
331         if(!isset($persistence['unzip_dir']) || empty($persistence['unzip_dir'])) {
332                 logThis('unzipping files in upgrade archive...');
333
334                 $errors                                 = array();
335                 $base_upgrade_dir      = $sugar_config['upload_dir'] . "/upgrades";
336                 $base_tmp_upgrade_dir  = "$base_upgrade_dir/temp";
337                 $install_file                   = urldecode( $persistence['install_file'] );
338                 $show_files                             = true;
339                 $unzip_dir                              = clean_path(mk_temp_dir( $base_tmp_upgrade_dir ));
340                 $zip_from_dir                   = ".";
341                 $zip_to_dir                     = ".";
342                 $zip_force_copy                 = array();
343
344                 unzip( $install_file, $unzip_dir );
345
346                 // assumption -- already validated manifest.php at time of upload
347                 include( "$unzip_dir/manifest.php" );
348
349                 if( isset( $manifest['copy_files']['from_dir'] ) && $manifest['copy_files']['from_dir'] != "" ){
350                     $zip_from_dir   = $manifest['copy_files']['from_dir'];
351                 }
352                 if( isset( $manifest['copy_files']['to_dir'] ) && $manifest['copy_files']['to_dir'] != "" ){
353                     $zip_to_dir     = $manifest['copy_files']['to_dir'];
354                 }
355                 if( isset( $manifest['copy_files']['force_copy'] ) && $manifest['copy_files']['force_copy'] != "" ){
356                     $zip_force_copy     = $manifest['copy_files']['force_copy'];
357                 }
358                 if( isset( $manifest['version'] ) ){
359                     $version    = $manifest['version'];
360                 }
361                 if( !is_writable( "config.php" ) ){
362                         logThis('BAD error');
363                         return $mod_strings['ERR_UW_CONFIG'];
364                 }
365
366                 logThis('setting "unzip_dir" to '.$unzip_dir);
367                 $persistence['unzip_dir'] = clean_path($unzip_dir);
368                 $persistence['zip_from_dir'] = clean_path($zip_from_dir);
369
370                 logThis('unzip done.');
371         } else {
372                 $unzip_dir = $persistence['unzip_dir'];
373                 $zip_from_dir = $persistence['zip_from_dir'];
374         }
375
376         $persistence['upgrade_files'] = uwFindAllFiles(clean_path("$unzip_dir/$zip_from_dir"), array(), true, array(), true);
377
378         return $persistence;
379 }
380
381 function preflightCheckJsonDiffFiles($persistence) {
382         global $sugar_version;
383         global $mod_strings;
384
385         if(!isset($sugar_version) || empty($sugar_version)) {
386                 
387         }
388
389         // get md5 sums
390         $md5_string = array();
391         $finalZipDir = $persistence['unzip_dir'].'/'.$persistence['zip_from_dir'];
392
393         if(is_file(getcwd().'/files.md5'))
394                 require(getcwd().'/files.md5');
395
396         // initialize pass array
397         $manualDiff = array();
398
399         // file preflight checks
400         logThis('verifying md5 checksums for files...');
401         $cache_html_files = findAllFilesRelative( "{$GLOBALS['sugar_config']['cache_dir']}layout", array());
402
403         foreach($persistence['upgrade_files'] as $file) {
404                 if(strpos($file, '.md5'))
405                         continue; // skip md5 file
406
407                 // normalize file paths
408                 $file = clean_path($file);
409
410                 // check that we can move/delete the upgraded file
411                 if(!is_writable($file)) {
412                         $errors[] = $mod_strings['ERR_UW_FILE_NOT_WRITABLE'].": ".$file;
413                 }
414                 // check that destination files are writable
415                 $destFile = getcwd().str_replace($finalZipDir, '', $file);
416
417                 if(is_file($destFile)) { // of course it needs to exist first...
418                         if(!is_writable($destFile)) {
419                                 $errors[] = $mod_strings['ERR_UW_FILE_NOT_WRITABLE'].": ".$destFile;
420                         }
421                 }
422
423                 ///////////////////////////////////////////////////////////////////////
424                 ////    DIFFS
425                 // compare md5s and build up a manual merge list
426                 $targetFile = clean_path(".".str_replace(getcwd(),'',$destFile));
427                 $targetMd5 = '0';
428                 if(is_file($destFile)) {
429                         if(strpos($targetFile, '.php')) {
430                                 // handle PHP files that were hit with the security regex
431                                 $fp = sugar_fopen($destFile, 'r');
432                                 $filesize = filesize($destFile);
433                                 if($filesize > 0) {
434                                         $fileContents = fread($fp, $filesize);
435                                         $targetMd5 = md5($fileContents);
436                                 }
437                         } else {
438                                 $targetMd5 = md5_file($destFile);
439                         }
440                 }
441
442                 if(isset($md5_string[$targetFile]) && $md5_string[$targetFile] != $targetMd5) {
443                         logThis('found a file with a differing md5: ['.$targetFile.']');
444                         $manualDiff[] = $destFile;
445                 }
446                 ////    END DIFFS
447                 ///////////////////////////////////////////////////////////////////////
448                 echo ".";
449         }
450         logThis('md5 verification done.');
451
452         $persistence['manual'] = $manualDiff;
453         $persistence['diff_errors'] = $errors;
454
455         return $persistence;
456 }
457
458
459 function preflightCheckJsonGetDiff($persistence) {
460         global $mod_strings;
461         global $current_user;
462
463         $out  = $mod_strings['LBL_UW_PREFLIGHT_TESTS_PASSED'];
464         $stop = false;
465
466         $disableEmail = (empty($current_user->email1)) ? 'DISABLED' : 'CHECKED';
467
468         if(count($persistence['manual']) > 0) {
469                 $preserveFiles = array();
470
471                 $diffs =<<<eoq
472                         <script type="text/javascript" language="Javascript">
473                                 function preflightToggleAll(cb) {
474                                         var checkAll = false;
475                                         var form = document.getElementById('diffs');
476
477                                         if(cb.checked == true) {
478                                                 checkAll = true;
479                                         }
480
481                                         for(i=0; i<form.elements.length; i++) {
482                                                 if(form.elements[i].type == 'checkbox') {
483                                                         form.elements[i].checked = checkAll;
484                                                 }
485                                         }
486                                         return;
487                                 }
488                         </script>
489
490                         <table cellpadding='0' cellspacing='0' border='0'>
491                                 <tr>
492                                         <td valign='top'>
493                                                 <input type='checkbox' name='addTask' id='addTask' CHECKED>
494                                         </td>
495                                         <td valign='top'>
496                                                 {$mod_strings['LBL_UW_PREFLIGHT_ADD_TASK']}
497                                         </td>
498                                 </tr>
499                                 <tr>
500                                         <td valign='top'>
501                                                 <input type='checkbox' name='addEmail' id='addEmail' $disableEmail>
502                                         </td>
503                                         <td valign='top'>
504                                                 {$mod_strings['LBL_UW_PREFLIGHT_EMAIL_REMINDER']}
505                                         </td>
506                                 </tr>
507                         </table>
508
509                         <form name='diffs' id='diffs'>
510                         <p><a href='javascript:void(0); toggleNwFiles("diffsHide");'>{$mod_strings['LBL_UW_SHOW_DIFFS']}</a></p>
511                         <div id='diffsHide' style='display:none'>
512                                 <table cellpadding='0' cellspacing='0' border='0'>
513                                         <tr>
514                                                 <td valign='top' colspan='2'>
515                                                         {$mod_strings['LBL_UW_PREFLIGHT_FILES_DESC']}
516                                                         <br />&nbsp;
517                                                 </td>
518                                         </tr>
519                                         <tr>
520                                                 <td valign='top' colspan='2'>
521                                                         <input type='checkbox' onchange='preflightToggleAll(this);'>&nbsp;<i><b>{$mod_strings['LBL_UW_PREFLIGHT_TOGGLE_ALL']}</b></i>
522                                                         <br />&nbsp;
523                                                 </td>
524                                         </tr>
525 eoq;
526                 foreach($persistence['manual'] as $diff) {
527                         $diff = clean_path($diff);
528                         $persistence['files']['manual'][] = $diff;
529
530                         $checked = (isAutoOverwriteFile($diff)) ? 'CHECKED' : '';
531
532                         if(empty($checked)) {
533                                 $preserveFiles[] = $diff;
534                         }
535
536                         $diffs .= "<tr><td valign='top'>";
537                         $diffs .= "<input type='checkbox' name='diff_files[]' value='{$diff}' $checked>";
538                         $diffs .= "</td><td valign='top'>";
539                         $diffs .= str_replace(getcwd(), '.', $diff);
540                         $diffs .= "</td></tr>";
541                 }
542                 $diffs .= "</table>";
543                 $diffs .= "</div></p>";
544                 $diffs .= "</form>";
545
546                 // list preserved files (templates, etc.)
547                 $preserve = '';
548                 foreach($preserveFiles as $pf) {
549                         if(empty($preserve)) {
550                                 $preserve .= "<table cellpadding='0' cellspacing='0' border='0'><tr><td><b>";
551                                 $preserve .= $mod_strings['LBL_UW_PREFLIGHT_PRESERVE_FILES'];
552                                 $preserve .= "</b></td></tr>";
553                         }
554                         $preserve .= "<tr><td valign='top'><i>".str_replace(getcwd(), '.', $pf)."</i></td></tr>";
555                 }
556                 if(!empty($preserve)) {
557                         $preserve .= '</table><br>';
558                 }
559                 $diffs = $preserve.$diffs;
560         } else { // NO FILE DIFFS REQUIRED
561                 $diffs = $mod_strings['LBL_UW_PREFLIGHT_NO_DIFFS'];
562         }
563
564         echo $diffs;
565
566         return $persistence;
567 }
568
569 /**
570  * loads the sql file into an array
571  * @param array persistence
572  * @param bool preflight Flag to load for Preflight or Commit
573  * @return array persistence
574  */
575 function preflightCheckJsonPrepSchemaCheck($persistence, $preflight=true) {
576         global $mod_strings;
577         global $db;
578         global $sugar_db_version;
579         global $manifest;
580
581         unset($persistence['sql_to_run']);
582
583         $persistence['sql_to_check'] = array();
584         $persistence['sql_to_check_backup'] = array();
585
586         if(isset($persistence['sql_check_done'])) {
587                 // reset flag to not check (on Recheck)
588                 unset($persistence['sql_check_done']);
589                 unset($persistence['sql_errors']);
590         }
591
592         // get schema script if not loaded
593         if($preflight)
594                 logThis('starting schema preflight check...');
595         else
596                 logThis('Preparing SQL statements for sequential execution...');
597
598         if(!isset($sugar_db_version) || empty($sugar_db_version)) {
599                 include('./sugar_version.php');
600         }
601
602         if(!isset($manifest['version']) || empty($manifest['version'])) {
603                 include($persistence['unzip_dir'].'/manifest.php');
604         }
605
606         $current_version = substr(preg_replace("#[^0-9]#", "", $sugar_db_version),0,3);
607         $targetVersion =  substr(preg_replace("#[^0-9]#", "", $manifest['version']),0,3);
608         $sqlScript = $persistence['unzip_dir'].'/scripts/'.$current_version.'_to_'.$targetVersion.'_'.$db->dbType.'.sql';
609
610         $newTables = array();
611
612
613         logThis('looking for schema script at: '.$sqlScript);
614         if(is_file($sqlScript)) {
615                 logThis('found schema upgrade script: '.$sqlScript);
616                 $fp = sugar_fopen($sqlScript, 'r');
617                 $contents = fread($fp, filesize($sqlScript));
618
619                 if(rewind($fp)) {
620                         $completeLine = '';
621                         while($line = fgets($fp)) {
622                                 if(strpos($line, '--') === false) {
623                                         $completeLine .= " ".trim($line);
624                                         if(strpos($line, ';') !== false) {
625                                                 $completeLine = str_replace(';','',$completeLine);
626                                                 $persistence['sql_to_check'][] = $completeLine;
627                                                 $completeLine = ''; //reset for next loop
628                                         }
629                                 }
630                         }
631
632                         $persistence['sql_total'] = count($persistence['sql_to_check']);
633                 } else {
634                         logThis('*** ERROR: could not read schema script: '.$sqlScript);
635                         $persistence['sql_errors'][] = $mod_strings['ERR_UW_FILE_NOT_READABLE'].'::'.$sqlScript;
636                 }
637         }
638
639         // load a new array if for commit
640         if($preflight) {
641                 $persistence['sql_to_check_backup'] = $persistence['sql_to_check'];
642                 $persistence['sql_to_run'] = $persistence['sql_to_check'];
643                 echo "1% ".$mod_strings['LBL_UW_DONE'];
644         } else {
645                 $persistence['sql_to_run'] = $persistence['sql_to_check'];
646                 unset($persistence['sql_to_check']);
647         }
648
649         return $persistence;
650 }
651
652 function preflightCheckJsonSchemaCheck($persistence) {
653         global $mod_strings;
654         global $db;
655
656         if(!isset($persistence['sql_check_done']) || $persistence['sql_check_done'] != true) {
657                 // must keep sql in order
658                 $completeLine = array_shift($persistence['sql_to_check']);
659                 $whatsLeft = count($persistence['sql_to_check']);
660
661                 // populate newTables array to prevent "getting sample data" from non-existent tables
662                 $newTables = array();
663                 if(strtoupper(substr($completeLine,1,5)) == 'CREAT')
664                         $newTables[] = getTableFromQuery($completeLine);
665
666                 $bad = verifySqlStatement(trim($completeLine), $db->dbType, $newTables);
667
668                 if(!empty($bad)) {
669                         logThis('*** ERROR: schema change script has errors: '.$completeLine);
670                         $persistence['sql_errors'][] = $bad;
671                 }
672
673                 $persistence = ajaxSqlProgress($persistence, $completeLine, 'sql_to_check');
674         } else {
675                 $persistence['sql_to_check'] = $persistence['sql_to_check_backup'];
676                 echo 'done';
677         }
678
679         return $persistence;
680 }
681
682
683 function preflightCheckJsonGetSchemaErrors($persistence) {
684         global $mod_strings;
685
686         if(isset($persistence['sql_errors']) && count($persistence['sql_errors'] > 0)) {
687                 $out = "<b class='error'>{$mod_strings['ERR_UW_PREFLIGHT_ERRORS']}:</b> ";
688                 $out .= "<a href='javascript:void(0);toggleNwFiles(\"sqlErrors\");'>{$mod_strings['LBL_UW_SHOW_SQL_ERRORS']}</a><div id='sqlErrors' style='display:none'>";
689                 foreach($persistence['sql_errors'] as $sqlError) {
690                         $out .= "<br><span class='error'>{$sqlError}</span>";
691                 }
692                 $out .= "</div><hr />";
693         } else {
694                 $out = '';
695         }
696
697         // reset errors if Rechecking
698         if(isset($persistence['sql_errors']))
699                 //unset($persistence['sql_errors']);
700
701         echo $out;
702
703         return $persistence;
704 }
705
706
707 function preflightCheckJsonFillSchema() {
708         global $mod_strings;
709         global $persistence;
710         global $sugar_db_version;
711         global $manifest;
712         global $db;
713
714         if(empty($sugar_db_version)) {
715                 include('sugar_version');
716         }
717         if(empty($manifest)) {
718                 include($persistence['unzip_dir'].'/manifest.php');
719         }
720
721         ///////////////////////////////////////////////////////////////////////////////
722         ////    SCHEMA SCRIPT HANDLING
723         $schema = '';
724         $alterTableSchemaOut = '';
725         $current_version = substr(preg_replace("#[^0-9]#", "", $sugar_db_version),0,3);
726         $targetVersion =  substr(preg_replace("#[^0-9]#", "", $manifest['version']),0,3);
727         $sqlScript = $persistence['unzip_dir'].'/scripts/'.$current_version.'_to_'.$targetVersion.'_'.$db->dbType.'.sql';
728         $newTables = array();
729
730         logThis('looking for SQL script for DISPLAY at '.$sqlScript);
731         if(file_exists($sqlScript)) {
732                 $fp = sugar_fopen($sqlScript, 'r');
733                 $contents = fread($fp, filesize($sqlScript));
734                 $schema  = "<p><a href='javascript:void(0); toggleNwFiles(\"schemashow\");'>{$mod_strings['LBL_UW_SHOW_SCHEMA']}</a>";
735                 $schema .= "<div id='schemashow' style='display:none;'>";
736                 $schema .= "<textarea readonly cols='80' rows='10'>{$contents}</textarea>";
737                 $schema .= "</div></p>";
738         }
739         ////    END SCHEMA SCRIPT HANDLING
740         ///////////////////////////////////////////////////////////////////////////////
741
742         ob_start();
743         echo $schema;
744         ob_flush();
745 }
746
747
748 function preflightCheckJsonAlterTableCharset() {
749         global $mod_strings;
750         global $sugar_db_version;
751         global $persistence;
752
753         if(empty($sugar_db_version))
754                 include('sugar_version.php');
755
756         $current_version = substr(preg_replace("#[^0-9]#", "", $sugar_db_version),0,3);
757
758         if(version_compare($current_version, '450', "<")) {
759                 if(isset($persistence['allTables']) && !empty($persistence['allTables'])) {
760                         $alterTableContents = printAlterTableSql($persistence['allTables']);
761                         $alterTableSchema  = "<p><a href='javascript:void(0); toggleNwFiles(\"alterTableSchemashow\");'>{$mod_strings['LBL_UW_CHARSET_SCHEMA_CHANGE']}</a>";
762                         $alterTableSchema .= "<div id='alterTableSchemashow' style='display:none;'>";
763                         $alterTableSchema .= "<textarea readonly cols='80' rows='10'>{$alterTableContents}</textarea>";
764                         $alterTableSchema .= "</div></p>";
765                 }
766         } else {
767                 $alterTableSchema = '<i>'.$mod_strings['LBL_UW_PREFLIGHT_NOT_NEEDED'].'</i>';
768         }
769
770         ob_start();
771         echo $alterTableSchema;
772         ob_flush();
773 }
774
775
776 ///////////////////////////////////////////////////////////////////////////////
777 ////    SYSTEMCHECK AJAX FUNCTIONS
778
779 function systemCheckJsonGetFiles($persistence) {
780         global $sugar_config;
781         global $mod_strings;
782
783         // add directories here that should be skipped when doing file permissions checks (cache/upload is the nasty one)
784         $skipDirs = array(
785                 $sugar_config['upload_dir'],
786                 getcwd().'/themes',
787         );
788
789         if(!isset($persistence['dirs_checked'])) {
790                 $the_array = array();
791                 $files = array();
792                 $dir = getcwd();
793                 $d = dir($dir);
794                 while($f = $d->read()) {
795                     if($f == "." || $f == "..") // skip *nix self/parent
796                         continue;
797
798                     if(is_dir("$dir/$f"))
799                                 $the_array[] = clean_path("$dir/$f");
800                         else {
801                                 $files[] = clean_path("$dir/$f");
802                         }
803                 }
804                 $persistence['files_to_check'] = $files;
805                 $persistence['dirs_to_check'] = $the_array;
806                 $persistence['dirs_total']      = count($the_array);
807                 $persistence['dirs_checked'] = false;
808
809                 $out = "1% {$mod_strings['LBL_UW_DONE']}";
810
811                 return $persistence;
812         } elseif($persistence['dirs_checked'] == false) {
813                 $dir = array_pop($persistence['dirs_to_check']);
814
815                 $files = uwFindAllFiles($dir, array(), true, $skipDirs);
816
817                 $persistence['files_to_check'] = array_merge($persistence['files_to_check'], $files);
818
819                 $whatsLeft = count($persistence['dirs_to_check']);
820
821                 if(!isset($persistence['dirs_to_check']) || $whatsLeft < 1) {
822                         $whatsLeft = 0;
823                         $persistence['dirs_checked'] = true;
824                 }
825
826                 $out  = round((($persistence['dirs_total'] - $whatsLeft) / 21) * 100, 1)."% {$mod_strings['LBL_UW_DONE']}";
827                 $out .= " [{$mod_strings['LBL_UW_SYSTEM_CHECK_CHECKING_JSON']} {$dir}]";
828         } else {
829                 $out = "Done";
830         }
831
832         echo trim($out);
833
834         return $persistence;
835 }
836
837
838
839 /**
840  * checks files for permissions
841  * @param array files Array of files with absolute paths
842  * @return string result of check
843  */
844 function systemCheckJsonCheckFiles($persistence) {
845         global $mod_strings;
846         global $persistence;
847
848         $filesNotWritable = array();
849         $i=0;
850         $filesOut = "
851                 <a href='javascript:void(0); toggleNwFiles(\"filesNw\");'>{$mod_strings['LBL_UW_SHOW_NW_FILES']}</a>
852                 <div id='filesNw' style='display:none;'>
853                 <table cellpadding='3' cellspacing='0' border='0'>
854                 <tr>
855                         <th align='left'>{$mod_strings['LBL_UW_FILE']}</th>
856                         <th align='left'>{$mod_strings['LBL_UW_FILE_PERMS']}</th>
857                         <th align='left'>{$mod_strings['LBL_UW_FILE_OWNER']}</th>
858                         <th align='left'>{$mod_strings['LBL_UW_FILE_GROUP']}</th>
859                 </tr>";
860
861         $isWindows = is_windows();
862         foreach($persistence['files_to_check'] as $file) {
863         //      while($file = array_pop($persistence['files_to_check'])) {
864
865                 // admin deletes a bad file mid-check:
866                 if(!file_exists($file))
867                         continue;
868
869                 if($isWindows) {
870                         if(!is_writable_windows($file)) {
871                                 logThis('WINDOWS: File ['.$file.'] not readable - saving for display');
872                                 // don't warn yet - we're going to use this to check against replacement files
873                                 $filesNotWritable[$i] = $file;
874                                 $filesNWPerms[$i] = substr(sprintf('%o',fileperms($file)), -4);
875                                 $filesOut .= "<tr>".
876                                                                 "<td valign='top'><span class='error'>{$file}</span></td>".
877                                                                 "<td valign='top'>{$filesNWPerms[$i]}</td>".
878                                                                 "<td valign='top'>".$mod_strings['ERR_UW_CANNOT_DETERMINE_USER']."</td>".
879                                                                 "<td valign='top'>".$mod_strings['ERR_UW_CANNOT_DETERMINE_GROUP']."</td>".
880                                                           "</tr>";
881                         }
882                 } else {
883                         if(!is_writable($file)) {
884                                 logThis('File ['.$file.'] not writable - saving for display');
885                                 // don't warn yet - we're going to use this to check against replacement files
886                                 $filesNotWritable[$i] = $file;
887                                 $filesNWPerms[$i] = substr(sprintf('%o',fileperms($file)), -4);
888                                 $owner = posix_getpwuid(fileowner($file));
889                                 $group = posix_getgrgid(filegroup($file));
890                                 $filesOut .= "<tr>".
891                                                                 "<td valign='top'><span class='error'>{$file}</span></td>".
892                                                                 "<td valign='top'>{$filesNWPerms[$i]}</td>".
893                                                                 "<td valign='top'>".$owner['name']."</td>".
894                                                                 "<td valign='top'>".$group['name']."</td>".
895                                                           "</tr>";
896                         }
897                 }
898                 $i++;
899         }
900
901         $filesOut .= '</table></div>';
902         // not a stop error
903         $persistence['filesNotWritable'] = (count($filesNotWritable) > 0) ? true : false;
904
905         if(count($filesNotWritable) < 1) {
906                 $filesOut = "{$mod_strings['LBL_UW_FILE_NO_ERRORS']}";
907                 $persistence['step']['systemCheck'] = 'success';
908         }
909
910         echo $filesOut;
911         return $persistence;
912 }
913
914
915 ?>