PageRenderTime 57ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/UpgradeWizard/uw_ajax.php

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