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.
7 * This program is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Affero General Public License version 3 as published by the
9 * Free Software Foundation with the addition of the following permission added
10 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
19 * You should have received a copy of the GNU Affero General Public License along with
20 * this program; if not, see http://www.gnu.org/licenses or write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
27 * The interactive user interfaces in modified source and object code versions
28 * of this program must display Appropriate Legal Notices, as required under
29 * Section 5 of the GNU Affero General Public License version 3.
31 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32 * these Appropriate Legal Notices must retain the display of the "Powered by
33 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34 * technical reasons, the Appropriate Legal Notices must display the words
35 * "Powered by SugarCRM".
36 ********************************************************************************/
38 /*********************************************************************************
41 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. All Rights
42 * Reserved. Contributor(s): ______________________________________..
43 * *******************************************************************************/
48 function ajaxSqlProgress($persistence, $sql, $type) {
51 // $type is sql_to_check or sql_to_run
52 $whatsLeft = count($persistence[$type]);
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>";
63 $persistence['sql_check_done'] = true;
70 ///////////////////////////////////////////////////////////////////////////////
73 * does post-post-install stuff
74 * @param array persistence
75 * @return array persistence
77 function commitAjaxFinalTouches($persistence) {
81 global $sugar_version;
83 if(empty($sugar_version)) {
84 require('sugar_version.php');
87 // convert to UTF8 if needed
88 if(!empty($persistence['allTables']))
89 executeConvertTablesSql($GLOBALS['db']->dbType, $persistence['allTables']);
92 logThis('Performing UWrebuild()...');
94 logThis('UWrebuild() done.');
97 registerUpgrade($persistence);
99 // flag to say upgrade has completed
100 $persistence['upgrade_complete'] = true;
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";
111 foreach($persistence['skipped_files'] as $file) {
116 $nowDate = $timedate->nowDbDate();
117 $nowTime = $timedate->asDbTime($timedate->getNow());
118 $nowDateTime = $nowDate.' '.$nowTime;
120 if($_REQUEST['addTaskReminder'] == 'remind') {
121 logThis('Adding Task for admin for manual merge.');
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;
137 if($_REQUEST['addEmailReminder'] == 'remind') {
138 logThis('Sending Reminder for admin for manual merge.');
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;
156 //// HANDLE REMINDERS
157 ///////////////////////////////////////////////////////////////////////////////
170 * runs one line of sql
171 * @param array $persistence
172 * @return array $persistence
174 function commitAjaxRunSql($persistence) {
177 if(!isset($persistence['commit_sql_errors'])) {
178 $persistence['commit_sql_errors'] = array();
181 // This flag is determined by the preflight check in the installer
182 if($persistence['schema_change'] == 'sugar') {
184 if(isset($persistence['sql_to_run'])
185 && count($persistence['sql_to_run']) > 0
186 && !empty($persistence['sql_to_run'])) {
188 $sql = array_shift($persistence['sql_to_run']);
192 logThis("[RUNNING SQL QUERY] {$sql}");
196 switch($db->dbType) {
198 $error = mysql_error();
210 logThis('************************************************************');
211 logThis('*** ERROR: SQL Commit Error!');
212 logThis('*** Query: [ '.$sql.' ]');
213 logThis('************************************************************');
214 $persistence['commit_sql_errors'][] = getFormattedError($error, $sql);
216 $persistence = ajaxSqlProgress($persistence, $sql, 'sql_to_run');
234 * returns errors found during SQL operations
235 * @param array persistence
236 * @return string Error message or empty string on success
238 function commitAjaxGetSqlErrors($persistence) {
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) {
251 $out = $mod_strings['LBL_UW_COMMIT_ALL_SQL_SUCCESSFULLY_RUN'];
260 * parses the sql upgrade file for sequential querying
261 * @param array persistence
262 * @return array persistence
264 function commitAjaxPrepSql($persistence) {
265 return preflightCheckJsonPrepSchemaCheck($persistence, false);
270 * handles post-install tasks
272 function commitAjaxPostInstall($persistence) {
274 global $sugar_config;
275 global $sugar_version;
277 if(empty($sugar_version)) {
278 require('sugar_version.php');
281 // update versions info
282 if(!updateVersions($sugar_version)) {
283 echo $mod_strings['ERR_UW_COMMIT_UPDATE_VERSIONS'];
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');
297 require( "sugar_version.php" );
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'];
304 $res = ob_get_contents();
305 $postInstallResults .= (empty($res)) ? $mod_strings['LBL_UW_SUCCESS'] : $res;
306 $postInstallResults .= "</div>";
309 echo $postInstallResults;
312 logThis('post_install() done.');
315 ///////////////////////////////////////////////////////////////////////////////
319 ///////////////////////////////////////////////////////////////////////////////
320 //// PREFLIGHT JSON STYLE
322 function preflightCheckJsonFindUpgradeFiles($persistence) {
323 global $sugar_config;
326 unset($persistence['rebuild_relationships']);
327 unset($persistence['rebuild_extensions']);
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...');
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'] );
339 $unzip_dir = clean_path(mk_temp_dir( $base_tmp_upgrade_dir ));
342 $zip_force_copy = array();
344 unzip( $install_file, $unzip_dir );
346 // assumption -- already validated manifest.php at time of upload
347 include( "$unzip_dir/manifest.php" );
349 if( isset( $manifest['copy_files']['from_dir'] ) && $manifest['copy_files']['from_dir'] != "" ){
350 $zip_from_dir = $manifest['copy_files']['from_dir'];
352 if( isset( $manifest['copy_files']['to_dir'] ) && $manifest['copy_files']['to_dir'] != "" ){
353 $zip_to_dir = $manifest['copy_files']['to_dir'];
355 if( isset( $manifest['copy_files']['force_copy'] ) && $manifest['copy_files']['force_copy'] != "" ){
356 $zip_force_copy = $manifest['copy_files']['force_copy'];
358 if( isset( $manifest['version'] ) ){
359 $version = $manifest['version'];
361 if( !is_writable( "config.php" ) ){
362 logThis('BAD error');
363 return $mod_strings['ERR_UW_CONFIG'];
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);
370 logThis('unzip done.');
372 $unzip_dir = $persistence['unzip_dir'];
373 $zip_from_dir = $persistence['zip_from_dir'];
376 $persistence['upgrade_files'] = uwFindAllFiles(clean_path("$unzip_dir/$zip_from_dir"), array(), true, array(), true);
381 function preflightCheckJsonDiffFiles($persistence) {
382 global $sugar_version;
385 if(!isset($sugar_version) || empty($sugar_version)) {
390 $md5_string = array();
391 $finalZipDir = $persistence['unzip_dir'].'/'.$persistence['zip_from_dir'];
393 if(is_file(getcwd().'/files.md5'))
394 require(getcwd().'/files.md5');
396 // initialize pass array
397 $manualDiff = array();
399 // file preflight checks
400 logThis('verifying md5 checksums for files...');
401 $cache_html_files = findAllFilesRelative( "{$GLOBALS['sugar_config']['cache_dir']}layout", array());
403 foreach($persistence['upgrade_files'] as $file) {
404 if(strpos($file, '.md5'))
405 continue; // skip md5 file
407 // normalize file paths
408 $file = clean_path($file);
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;
414 // check that destination files are writable
415 $destFile = getcwd().str_replace($finalZipDir, '', $file);
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;
423 ///////////////////////////////////////////////////////////////////////
425 // compare md5s and build up a manual merge list
426 $targetFile = clean_path(".".str_replace(getcwd(),'',$destFile));
428 if(is_file($destFile)) {
429 if(strpos($targetFile, '.php')) {
430 // handle PHP files that were hit with the security regex
431 $filesize = filesize($destFile);
433 $fileContents = file_get_contents($destFile);
434 $targetMd5 = md5($fileContents);
437 $targetMd5 = md5_file($destFile);
441 if(isset($md5_string[$targetFile]) && $md5_string[$targetFile] != $targetMd5) {
442 logThis('found a file with a differing md5: ['.$targetFile.']');
443 $manualDiff[] = $destFile;
446 ///////////////////////////////////////////////////////////////////////
449 logThis('md5 verification done.');
451 $persistence['manual'] = $manualDiff;
452 $persistence['diff_errors'] = $errors;
458 function preflightCheckJsonGetDiff($persistence) {
460 global $current_user;
462 $out = $mod_strings['LBL_UW_PREFLIGHT_TESTS_PASSED'];
465 $disableEmail = (empty($current_user->email1)) ? 'DISABLED' : 'CHECKED';
467 if(count($persistence['manual']) > 0) {
468 $preserveFiles = array();
471 <script type="text/javascript" language="Javascript">
472 function preflightToggleAll(cb) {
473 var checkAll = false;
474 var form = document.getElementById('diffs');
476 if(cb.checked == true) {
480 for(i=0; i<form.elements.length; i++) {
481 if(form.elements[i].type == 'checkbox') {
482 form.elements[i].checked = checkAll;
489 <table cellpadding='0' cellspacing='0' border='0'>
492 <input type='checkbox' name='addTask' id='addTask' CHECKED>
495 {$mod_strings['LBL_UW_PREFLIGHT_ADD_TASK']}
500 <input type='checkbox' name='addEmail' id='addEmail' $disableEmail>
503 {$mod_strings['LBL_UW_PREFLIGHT_EMAIL_REMINDER']}
508 <form name='diffs' id='diffs'>
509 <p><a href='javascript:void(0); toggleNwFiles("diffsHide");'>{$mod_strings['LBL_UW_SHOW_DIFFS']}</a></p>
510 <div id='diffsHide' style='display:none'>
511 <table cellpadding='0' cellspacing='0' border='0'>
513 <td valign='top' colspan='2'>
514 {$mod_strings['LBL_UW_PREFLIGHT_FILES_DESC']}
519 <td valign='top' colspan='2'>
520 <input type='checkbox' onchange='preflightToggleAll(this);'> <i><b>{$mod_strings['LBL_UW_PREFLIGHT_TOGGLE_ALL']}</b></i>
525 foreach($persistence['manual'] as $diff) {
526 $diff = clean_path($diff);
527 $persistence['files']['manual'][] = $diff;
529 $checked = (isAutoOverwriteFile($diff)) ? 'CHECKED' : '';
531 if(empty($checked)) {
532 $preserveFiles[] = $diff;
535 $diffs .= "<tr><td valign='top'>";
536 $diffs .= "<input type='checkbox' name='diff_files[]' value='{$diff}' $checked>";
537 $diffs .= "</td><td valign='top'>";
538 $diffs .= str_replace(getcwd(), '.', $diff);
539 $diffs .= "</td></tr>";
541 $diffs .= "</table>";
542 $diffs .= "</div></p>";
545 // list preserved files (templates, etc.)
547 foreach($preserveFiles as $pf) {
548 if(empty($preserve)) {
549 $preserve .= "<table cellpadding='0' cellspacing='0' border='0'><tr><td><b>";
550 $preserve .= $mod_strings['LBL_UW_PREFLIGHT_PRESERVE_FILES'];
551 $preserve .= "</b></td></tr>";
553 $preserve .= "<tr><td valign='top'><i>".str_replace(getcwd(), '.', $pf)."</i></td></tr>";
555 if(!empty($preserve)) {
556 $preserve .= '</table><br>';
558 $diffs = $preserve.$diffs;
559 } else { // NO FILE DIFFS REQUIRED
560 $diffs = $mod_strings['LBL_UW_PREFLIGHT_NO_DIFFS'];
569 * loads the sql file into an array
570 * @param array persistence
571 * @param bool preflight Flag to load for Preflight or Commit
572 * @return array persistence
574 function preflightCheckJsonPrepSchemaCheck($persistence, $preflight=true) {
577 global $sugar_db_version;
580 unset($persistence['sql_to_run']);
582 $persistence['sql_to_check'] = array();
583 $persistence['sql_to_check_backup'] = array();
585 if(isset($persistence['sql_check_done'])) {
586 // reset flag to not check (on Recheck)
587 unset($persistence['sql_check_done']);
588 unset($persistence['sql_errors']);
591 // get schema script if not loaded
593 logThis('starting schema preflight check...');
595 logThis('Preparing SQL statements for sequential execution...');
597 if(!isset($sugar_db_version) || empty($sugar_db_version)) {
598 include('./sugar_version.php');
601 if(!isset($manifest['version']) || empty($manifest['version'])) {
602 include($persistence['unzip_dir'].'/manifest.php');
605 $current_version = substr(preg_replace("#[^0-9]#", "", $sugar_db_version),0,3);
606 $targetVersion = substr(preg_replace("#[^0-9]#", "", $manifest['version']),0,3);
607 $sqlScript = $persistence['unzip_dir'].'/scripts/'.$current_version.'_to_'.$targetVersion.'_'.$db->dbType.'.sql';
609 $newTables = array();
612 logThis('looking for schema script at: '.$sqlScript);
613 if(is_file($sqlScript)) {
614 logThis('found schema upgrade script: '.$sqlScript);
615 $fp = sugar_fopen($sqlScript, 'r');
619 while($line = fgets($fp)) {
620 if(strpos($line, '--') === false) {
621 $completeLine .= " ".trim($line);
622 if(strpos($line, ';') !== false) {
623 $completeLine = str_replace(';','',$completeLine);
624 $persistence['sql_to_check'][] = $completeLine;
625 $completeLine = ''; //reset for next loop
630 $persistence['sql_total'] = count($persistence['sql_to_check']);
632 logThis('*** ERROR: could not read schema script: '.$sqlScript);
633 $persistence['sql_errors'][] = $mod_strings['ERR_UW_FILE_NOT_READABLE'].'::'.$sqlScript;
637 // load a new array if for commit
639 $persistence['sql_to_check_backup'] = $persistence['sql_to_check'];
640 $persistence['sql_to_run'] = $persistence['sql_to_check'];
641 echo "1% ".$mod_strings['LBL_UW_DONE'];
643 $persistence['sql_to_run'] = $persistence['sql_to_check'];
644 unset($persistence['sql_to_check']);
650 function preflightCheckJsonSchemaCheck($persistence) {
654 if(!isset($persistence['sql_check_done']) || $persistence['sql_check_done'] != true) {
655 // must keep sql in order
656 $completeLine = array_shift($persistence['sql_to_check']);
657 $whatsLeft = count($persistence['sql_to_check']);
659 // populate newTables array to prevent "getting sample data" from non-existent tables
660 $newTables = array();
661 if(strtoupper(substr($completeLine,1,5)) == 'CREAT')
662 $newTables[] = getTableFromQuery($completeLine);
664 $bad = verifySqlStatement(trim($completeLine), $db->dbType, $newTables);
667 logThis('*** ERROR: schema change script has errors: '.$completeLine);
668 $persistence['sql_errors'][] = $bad;
671 $persistence = ajaxSqlProgress($persistence, $completeLine, 'sql_to_check');
673 $persistence['sql_to_check'] = $persistence['sql_to_check_backup'];
681 function preflightCheckJsonGetSchemaErrors($persistence) {
684 if(isset($persistence['sql_errors']) && count($persistence['sql_errors'] > 0)) {
685 $out = "<b class='error'>{$mod_strings['ERR_UW_PREFLIGHT_ERRORS']}:</b> ";
686 $out .= "<a href='javascript:void(0);toggleNwFiles(\"sqlErrors\");'>{$mod_strings['LBL_UW_SHOW_SQL_ERRORS']}</a><div id='sqlErrors' style='display:none'>";
687 foreach($persistence['sql_errors'] as $sqlError) {
688 $out .= "<br><span class='error'>{$sqlError}</span>";
690 $out .= "</div><hr />";
695 // reset errors if Rechecking
696 if(isset($persistence['sql_errors']))
697 //unset($persistence['sql_errors']);
705 function preflightCheckJsonFillSchema() {
708 global $sugar_db_version;
712 if(empty($sugar_db_version)) {
713 include('sugar_version');
715 if(empty($manifest)) {
716 include($persistence['unzip_dir'].'/manifest.php');
719 ///////////////////////////////////////////////////////////////////////////////
720 //// SCHEMA SCRIPT HANDLING
722 $alterTableSchemaOut = '';
723 $current_version = substr(preg_replace("#[^0-9]#", "", $sugar_db_version),0,3);
724 $targetVersion = substr(preg_replace("#[^0-9]#", "", $manifest['version']),0,3);
725 $sqlScript = $persistence['unzip_dir'].'/scripts/'.$current_version.'_to_'.$targetVersion.'_'.$db->dbType.'.sql';
726 $newTables = array();
728 logThis('looking for SQL script for DISPLAY at '.$sqlScript);
729 if(file_exists($sqlScript)) {
730 $contents = sugar_file_get_contents($sqlScript);
731 $schema = "<p><a href='javascript:void(0); toggleNwFiles(\"schemashow\");'>{$mod_strings['LBL_UW_SHOW_SCHEMA']}</a>";
732 $schema .= "<div id='schemashow' style='display:none;'>";
733 $schema .= "<textarea readonly cols='80' rows='10'>{$contents}</textarea>";
734 $schema .= "</div></p>";
736 //// END SCHEMA SCRIPT HANDLING
737 ///////////////////////////////////////////////////////////////////////////////
745 function preflightCheckJsonAlterTableCharset() {
747 global $sugar_db_version;
750 if(empty($sugar_db_version))
751 include('sugar_version.php');
753 $current_version = substr(preg_replace("#[^0-9]#", "", $sugar_db_version),0,3);
755 if(version_compare($current_version, '450', "<")) {
756 if(isset($persistence['allTables']) && !empty($persistence['allTables'])) {
757 $alterTableContents = printAlterTableSql($persistence['allTables']);
758 $alterTableSchema = "<p><a href='javascript:void(0); toggleNwFiles(\"alterTableSchemashow\");'>{$mod_strings['LBL_UW_CHARSET_SCHEMA_CHANGE']}</a>";
759 $alterTableSchema .= "<div id='alterTableSchemashow' style='display:none;'>";
760 $alterTableSchema .= "<textarea readonly cols='80' rows='10'>{$alterTableContents}</textarea>";
761 $alterTableSchema .= "</div></p>";
764 $alterTableSchema = '<i>'.$mod_strings['LBL_UW_PREFLIGHT_NOT_NEEDED'].'</i>';
768 echo $alterTableSchema;
773 ///////////////////////////////////////////////////////////////////////////////
774 //// SYSTEMCHECK AJAX FUNCTIONS
776 function systemCheckJsonGetFiles($persistence) {
777 global $sugar_config;
780 // add directories here that should be skipped when doing file permissions checks (cache/upload is the nasty one)
782 $sugar_config['upload_dir'],
786 if(!isset($persistence['dirs_checked'])) {
787 $the_array = array();
791 while($f = $d->read()) {
792 if($f == "." || $f == "..") // skip *nix self/parent
795 if(is_dir("$dir/$f"))
796 $the_array[] = clean_path("$dir/$f");
798 $files[] = clean_path("$dir/$f");
801 $persistence['files_to_check'] = $files;
802 $persistence['dirs_to_check'] = $the_array;
803 $persistence['dirs_total'] = count($the_array);
804 $persistence['dirs_checked'] = false;
806 $out = "1% {$mod_strings['LBL_UW_DONE']}";
809 } elseif($persistence['dirs_checked'] == false) {
810 $dir = array_pop($persistence['dirs_to_check']);
812 $files = uwFindAllFiles($dir, array(), true, $skipDirs);
814 $persistence['files_to_check'] = array_merge($persistence['files_to_check'], $files);
816 $whatsLeft = count($persistence['dirs_to_check']);
818 if(!isset($persistence['dirs_to_check']) || $whatsLeft < 1) {
820 $persistence['dirs_checked'] = true;
823 $out = round((($persistence['dirs_total'] - $whatsLeft) / 21) * 100, 1)."% {$mod_strings['LBL_UW_DONE']}";
824 $out .= " [{$mod_strings['LBL_UW_SYSTEM_CHECK_CHECKING_JSON']} {$dir}]";
837 * checks files for permissions
838 * @param array files Array of files with absolute paths
839 * @return string result of check
841 function systemCheckJsonCheckFiles($persistence) {
845 $filesNotWritable = array();
848 <a href='javascript:void(0); toggleNwFiles(\"filesNw\");'>{$mod_strings['LBL_UW_SHOW_NW_FILES']}</a>
849 <div id='filesNw' style='display:none;'>
850 <table cellpadding='3' cellspacing='0' border='0'>
852 <th align='left'>{$mod_strings['LBL_UW_FILE']}</th>
853 <th align='left'>{$mod_strings['LBL_UW_FILE_PERMS']}</th>
854 <th align='left'>{$mod_strings['LBL_UW_FILE_OWNER']}</th>
855 <th align='left'>{$mod_strings['LBL_UW_FILE_GROUP']}</th>
858 $isWindows = is_windows();
859 foreach($persistence['files_to_check'] as $file) {
860 // while($file = array_pop($persistence['files_to_check'])) {
862 // admin deletes a bad file mid-check:
863 if(!file_exists($file))
867 if(!is_writable_windows($file)) {
868 logThis('WINDOWS: File ['.$file.'] not readable - saving for display');
869 // don't warn yet - we're going to use this to check against replacement files
870 $filesNotWritable[$i] = $file;
871 $filesNWPerms[$i] = substr(sprintf('%o',fileperms($file)), -4);
873 "<td valign='top'><span class='error'>{$file}</span></td>".
874 "<td valign='top'>{$filesNWPerms[$i]}</td>".
875 "<td valign='top'>".$mod_strings['ERR_UW_CANNOT_DETERMINE_USER']."</td>".
876 "<td valign='top'>".$mod_strings['ERR_UW_CANNOT_DETERMINE_GROUP']."</td>".
880 if(!is_writable($file)) {
881 logThis('File ['.$file.'] not writable - saving for display');
882 // don't warn yet - we're going to use this to check against replacement files
883 $filesNotWritable[$i] = $file;
884 $filesNWPerms[$i] = substr(sprintf('%o',fileperms($file)), -4);
885 $owner = posix_getpwuid(fileowner($file));
886 $group = posix_getgrgid(filegroup($file));
888 "<td valign='top'><span class='error'>{$file}</span></td>".
889 "<td valign='top'>{$filesNWPerms[$i]}</td>".
890 "<td valign='top'>".$owner['name']."</td>".
891 "<td valign='top'>".$group['name']."</td>".
898 $filesOut .= '</table></div>';
900 $persistence['filesNotWritable'] = (count($filesNotWritable) > 0) ? true : false;
902 if(count($filesNotWritable) < 1) {
903 $filesOut = "{$mod_strings['LBL_UW_FILE_NO_ERRORS']}";
904 $persistence['step']['systemCheck'] = 'success';