PageRenderTime 85ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 1ms

/modules/UpgradeWizard/uw_utils.php

https://bitbucket.org/cviolette/sugarcrm
PHP | 4475 lines | 3282 code | 539 blank | 654 comment | 836 complexity | 9837434d4d6640181bbc0908b18d8abc MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  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. * Helper function for upgrade - get path from upload:// name
  39. * @param string $path
  40. * return string
  41. */
  42. function getUploadRelativeName($path)
  43. {
  44. if(class_exists('UploadFile')) {
  45. return UploadFile::realpath($path);
  46. }
  47. if(substr($path, 0, 9) == "upload://") {
  48. $path = rtrim($GLOBALS['sugar_config']['upload_dir'], "/\\")."/".substr($path, 9);
  49. }
  50. return $path;
  51. }
  52. /**
  53. * Backs-up files that are targeted for patch/upgrade to a restore directory
  54. * @param string rest_dir Full path to the directory containing the original, replaced files.
  55. * @param string install_file Full path to the uploaded patch/upgrade zip file
  56. * @param string unzip_dir Full path to the unzipped files in a temporary directory
  57. * @param string zip_from_dir Name of directory that the unzipped files containing the actuall replacement files
  58. * @param array errors Collection of errors to be displayed at end of process
  59. * @param string path Optional full path to the log file.
  60. * @return array errors
  61. */
  62. function commitMakeBackupFiles($rest_dir, $install_file, $unzip_dir, $zip_from_dir, $errors, $path='') {
  63. global $mod_strings;
  64. // create restore file directory
  65. sugar_mkdir($rest_dir, 0775, true);
  66. if(file_exists($rest_dir) && is_dir($rest_dir)){
  67. logThis('backing up files to be overwritten...', $path);
  68. $newFiles = findAllFiles(clean_path($unzip_dir . '/' . $zip_from_dir), array());
  69. // keep this around for canceling
  70. $_SESSION['uw_restore_dir'] = getUploadRelativeName($rest_dir);
  71. foreach ($newFiles as $file) {
  72. if (strpos($file, 'md5'))
  73. continue;
  74. // get name of current file to place in restore directory
  75. $cleanFile = str_replace(clean_path($unzip_dir . '/' . $zip_from_dir), '', $file);
  76. // make sure the directory exists
  77. $cleanDir = $rest_dir . '/' . dirname($cleanFile);
  78. sugar_mkdir($cleanDir, 0775, true);
  79. $oldFile = clean_path(getcwd() . '/' . $cleanFile);
  80. // only copy restore files for replacements - ignore new files from patch
  81. if (is_file($oldFile)) {
  82. if (is_writable($rest_dir)) {
  83. logThis('Backing up file: ' . $oldFile, $path);
  84. if (!copy($oldFile, $rest_dir . '/' . $cleanFile)) {
  85. logThis('*** ERROR: could not backup file: ' . $oldFile, $path);
  86. $errors[] = "{$mod_strings['LBL_UW_BACKUP']}::{$mod_strings['ERR_UW_FILE_NOT_COPIED']}: {$oldFile}";
  87. } else {
  88. $backupFilesExist = true;
  89. }
  90. } else {
  91. logThis('*** ERROR: directory not writable: ' . $rest_dir, $path);
  92. $errors[] = "{$mod_strings['LBL_UW_BACKUP']}::{$mod_strings['ERR_UW_DIR_NOT_WRITABLE']}: {$oldFile}";
  93. }
  94. }
  95. }
  96. }
  97. logThis('file backup done.', $path);
  98. return $errors;
  99. }
  100. /**
  101. * Copies files from the unzipped patch to the destination.
  102. * @param string unzip_dir Full path to the temporary directory created during unzip operation.
  103. * @param string zip_from_dir Name of folder containing the unzipped files; usually the name of the Patch without the
  104. * extension.
  105. * @param string path Optional full path to alternate upgradeWizard log file.
  106. * @return array Two element array containing to $copiedFiles and $skippedFiles.
  107. */
  108. function commitCopyNewFiles($unzip_dir, $zip_from_dir, $path='') {
  109. logThis('Starting file copy process...', $path);
  110. global $sugar_version;
  111. $backwardModules='';
  112. if(substr($sugar_version,0,1) >= 5){
  113. $modules = getAllModules();
  114. $backwardModules = array();
  115. foreach($modules as $mod){
  116. if(is_dir(clean_path(getcwd().'/modules/'.$mod.'/.500'))){
  117. $files = array();
  118. $files= findAllFiles(clean_path(getcwd().'/modules/'.$mod.'/.500'),$files);
  119. if(sizeof($files) >0){
  120. //backward compatibility is on
  121. $backwardModules[] = $mod;
  122. }
  123. }
  124. }
  125. }
  126. $newFiles = findAllFiles(clean_path($unzip_dir . '/' . $zip_from_dir), array());
  127. $zipPath = clean_path($unzip_dir . '/' . $zip_from_dir);
  128. // handle special do-not-overwrite conditions
  129. $doNotOverwrite = array();
  130. $doNotOverwrite[] = '__stub';
  131. if(isset($_REQUEST['overwrite_files_serial'])) {
  132. $doNotOverwrite = explode('::', $_REQUEST['overwrite_files_serial']);
  133. }
  134. $copiedFiles = array();
  135. $skippedFiles = array();
  136. foreach($newFiles as $file) {
  137. $cleanFile = str_replace($zipPath, '', $file);
  138. $srcFile = $zipPath . $cleanFile;
  139. $targetFile = clean_path(getcwd() . '/' . $cleanFile);
  140. if($backwardModules != null && sizeof($backwardModules) >0){
  141. foreach($backwardModules as $mod){
  142. $splitPath = explode('/',trim($cleanFile));
  143. if('modules' == trim($splitPath[1]) && $mod == trim($splitPath[2])){
  144. $cleanFile = str_replace('/modules/'.$mod, '/modules/'.$mod.'/.500', $cleanFile);
  145. $targetFile = clean_path(getcwd() . '/' . $cleanFile);
  146. }
  147. }
  148. }
  149. if(!is_dir(dirname($targetFile))) {
  150. mkdir_recursive(dirname($targetFile)); // make sure the directory exists
  151. }
  152. if((!file_exists($targetFile)) || /* brand new file */
  153. (!in_array($targetFile, $doNotOverwrite)) /* manual diff file */
  154. ) {
  155. // handle sugar_version.php
  156. if(strpos($targetFile, 'sugar_version.php') !== false && !preg_match('/\/portal\/sugar_version\.php$/i', $targetFile)) {
  157. logThis('Skipping "sugar_version.php" - file copy will occur at end of successful upgrade', $path);
  158. $_SESSION['sugar_version_file'] = $srcFile;
  159. continue;
  160. }
  161. //logThis('Copying file to destination: ' . $targetFile, $path);
  162. if(!copy($srcFile, $targetFile)) {
  163. logThis('*** ERROR: could not copy file: ' . $targetFile, $path);
  164. } else {
  165. $copiedFiles[] = $targetFile;
  166. }
  167. } else {
  168. //logThis('Skipping file: ' . $targetFile, $path);
  169. $skippedFiles[] = $targetFile;
  170. }
  171. }
  172. logThis('File copy done.', $path);
  173. $ret = array();
  174. $ret['copiedFiles'] = $copiedFiles;
  175. $ret['skippedFiles'] = $skippedFiles;
  176. return $ret;
  177. }
  178. //On cancel put back the copied files from 500 to 451 state
  179. function copyFilesOnCancel($step){
  180. //place hoder for cancel action
  181. }
  182. function removeFileFromPath($file,$path, $deleteNot=array()){
  183. $removed = 0;
  184. $cur = $path . '/' . $file;
  185. if(file_exists($cur)){
  186. $del = true;
  187. foreach($deleteNot as $dn){
  188. if($cur == $dn){
  189. $del = false;
  190. }
  191. }
  192. if($del){
  193. unlink($cur);
  194. $removed++;
  195. }
  196. }
  197. if(!file_exists($path))return $removed;
  198. $d = dir($path);
  199. while(false !== ($e = $d->read())){ // Fixed bug. !== is required to literally match the type and value of false, so that a filename that could evaluate and cast to false, ie "false" or "0", still allows the while loop to continue. From example at http://www.php.net/manual/en/function.dir.php
  200. $next = $path . '/'. $e;
  201. if(substr($e, 0, 1) != '.' && is_dir($next)){
  202. $removed += removeFileFromPath($file, $next, $deleteNot);
  203. }
  204. }
  205. $d->close(); // from example at http://www.php.net/manual/en/function.dir.php
  206. return $removed;
  207. }
  208. /**
  209. * This function copies/overwrites between directories
  210. *
  211. * @param string the directory name to remove
  212. * @param boolean whether to just empty the given directory, without deleting the given directory.
  213. * @return boolean True/False whether the directory was deleted.
  214. */
  215. function copyRecursiveBetweenDirectories($from,$to){
  216. if(file_exists($from)){
  217. $modifiedFiles = array();
  218. $modifiedFiles = findAllFiles(clean_path($from), $modifiedFiles);
  219. $cwd = clean_path(getcwd());
  220. foreach($modifiedFiles as $file) {
  221. $srcFile = clean_path($file);
  222. if (strpos($srcFile,".svn") === false) {
  223. $targetFile = str_replace($from, $to, $srcFile);
  224. if(!is_dir(dirname($targetFile))) {
  225. mkdir_recursive(dirname($targetFile)); // make sure the directory exists
  226. }
  227. // handle sugar_version.php
  228. if(strpos($targetFile, 'sugar_version.php') !== false && !preg_match('/\/portal\/sugar_version\.php$/i', $targetFile)) {
  229. logThis('Skipping "sugar_version.php" - file copy will occur at end of successful upgrade', $targetFile);
  230. $_SESSION['sugar_version_file'] = $srcFile;
  231. continue;
  232. }
  233. if(!copy($srcFile, $targetFile)) {
  234. logThis("*** ERROR: could not copy file $srcFile to $targetFile");
  235. }
  236. }
  237. }
  238. }
  239. }
  240. function deleteDirectory($dirname,$only_empty=false) {
  241. if (!is_dir($dirname))
  242. return false;
  243. $dscan = array(realpath($dirname));
  244. $darr = array();
  245. while (!empty($dscan)) {
  246. $dcur = array_pop($dscan);
  247. $darr[] = $dcur;
  248. if ($d=opendir($dcur)) {
  249. while ($f=readdir($d)) {
  250. if ($f=='.' || $f=='..')
  251. continue;
  252. $f=$dcur.'/'.$f;
  253. if (is_dir($f))
  254. $dscan[] = $f;
  255. else
  256. unlink($f);
  257. }
  258. closedir($d);
  259. }
  260. }
  261. $i_until = ($only_empty)? 1 : 0;
  262. for ($i=count($darr)-1; $i>=$i_until; $i--) {
  263. if (rmdir($darr[$i]))
  264. logThis('Success :Copying file to destination: ' . $darr[$i]);
  265. else
  266. logThis('Copy problem:Copying file to destination: ' . $darr[$i]);
  267. }
  268. return (($only_empty)? (count(scandir)<=2) : (!is_dir($dirname)));
  269. }
  270. /**
  271. * Get all the customized modules. Compare the file md5s with the base md5s
  272. * If a file has been modified then put the module in the list of customized
  273. * modules. Show the list in the preflight check UI.
  274. */
  275. function deleteAndOverWriteSelectedFiles($unzip_dir, $zip_from_dir,$delete_dirs){
  276. if($delete_dirs != null){
  277. foreach($delete_dirs as $del_dir){
  278. deleteDirectory($del_dir);
  279. $newFiles = findAllFiles(clean_path($unzip_dir . '/' . $zip_from_dir.'/'.$del_dir), array());
  280. $zipPath = clean_path($unzip_dir . '/' . $zip_from_dir.'/'.$del_dir);
  281. $copiedFiles = array();
  282. $skippedFiles = array();
  283. foreach($newFiles as $file) {
  284. $cleanFile = str_replace($zipPath, '', $file);
  285. $srcFile = $zipPath . $cleanFile;
  286. $targetFile = clean_path(getcwd() . '/' . $cleanFile);
  287. if(!is_dir(dirname($targetFile))) {
  288. mkdir_recursive(dirname($targetFile)); // make sure the directory exists
  289. }
  290. if(!file_exists($targetFile)){
  291. // handle sugar_version.php
  292. if(strpos($targetFile, 'sugar_version.php') !== false) {
  293. logThis('Skipping sugar_version.php - file copy will occur at end of successful upgrade');
  294. $_SESSION['sugar_version_file'] = $srcFile;
  295. continue;
  296. }
  297. //logThis('Copying file to destination: ' . $targetFile);
  298. if(!copy($srcFile, $targetFile)) {
  299. logThis('*** ERROR: could not copy file: ' . $targetFile);
  300. } else {
  301. $copiedFiles[] = $targetFile;
  302. }
  303. } else {
  304. //logThis('Skipping file: ' . $targetFile);
  305. $skippedFiles[] = $targetFile;
  306. }
  307. }
  308. }
  309. }
  310. $ret = array();
  311. $ret['copiedFiles'] = $copiedFiles;
  312. $ret['skippedFiles'] = $skippedFiles;
  313. return $ret;
  314. }
  315. //Default is empty the directory. For removing set it to false
  316. // to use this function to totally remove a directory, write:
  317. // recursive_remove_directory('path/to/directory/to/delete',FALSE);
  318. // to use this function to empty a directory, write:
  319. // recursive_remove_directory('path/to/full_directory');
  320. function recursive_empty_or_remove_directory($directory, $exclude_dirs=null,$exclude_files=null,$empty=TRUE)
  321. {
  322. // if the path has a slash at the end we remove it here
  323. if(substr($directory,-1) == '/')
  324. {
  325. $directory = substr($directory,0,-1);
  326. }
  327. // if the path is not valid or is not a directory ...
  328. if(!file_exists($directory) || !is_dir($directory))
  329. {
  330. // ... we return false and exit the function
  331. return FALSE;
  332. // ... if the path is not readable
  333. }elseif(!is_readable($directory))
  334. {
  335. // ... we return false and exit the function
  336. return FALSE;
  337. // ... else if the path is readable
  338. }else{
  339. // we open the directory
  340. $handle = opendir($directory);
  341. // and scan through the items inside
  342. while (FALSE !== ($item = readdir($handle)))
  343. {
  344. // if the filepointer is not the current directory
  345. // or the parent directory
  346. if($item != '.' && $item != '..')
  347. {
  348. // we build the new path to delete
  349. $path = $directory.'/'.$item;
  350. // if the new path is a directory
  351. //add another check if the dir is in the list to exclude delete
  352. if(is_dir($path) && $exclude_dirs != null && in_array($path,$exclude_dirs)){
  353. //do nothing
  354. }
  355. else if(is_dir($path))
  356. {
  357. // we call this function with the new path
  358. recursive_empty_or_remove_directory($path);
  359. }
  360. // if the new path is a file
  361. else{
  362. // we remove the file
  363. if($exclude_files != null && in_array($path,$exclude_files)){
  364. //do nothing
  365. }
  366. else{
  367. unlink($path);
  368. }
  369. }
  370. }
  371. }
  372. // close the directory
  373. closedir($handle);
  374. // if the option to empty is not set to true
  375. if($empty == FALSE)
  376. {
  377. // try to delete the now empty directory
  378. if(!rmdir($directory))
  379. {
  380. // return false if not possible
  381. return FALSE;
  382. }
  383. }
  384. // return success
  385. return TRUE;
  386. }
  387. }
  388. // ------------------------------------------------------------
  389. function getAllCustomizedModules() {
  390. require_once('files.md5');
  391. $return_array = array();
  392. $modules = getAllModules();
  393. foreach($modules as $mod) {
  394. //find all files in each module if the files have been modified
  395. //as compared to the base version then add the module to the
  396. //customized modules array
  397. $modFiles = findAllFiles(clean_path(getcwd())."/modules/$mod", array());
  398. foreach($modFiles as $file){
  399. $fileContents = file_get_contents($file);
  400. $file = str_replace(clean_path(getcwd()),'',$file);
  401. if($md5_string['./' . $file]){
  402. if(md5($fileContents) != $md5_string['./' . $file]) {
  403. //A file has been customized in the module. Put the module into the
  404. // customized modules array.
  405. echo 'Changed File'.$file;
  406. $return_array[$mod];
  407. break;
  408. }
  409. }
  410. else{
  411. // This is a new file in user's version and indicates that module has been
  412. //customized. Put the module in the customized array.
  413. echo 'New File'.$file;
  414. $return_array[$mod];
  415. break;
  416. }
  417. }
  418. } //foreach
  419. return $return_array;
  420. }
  421. /**
  422. * Array of all Modules in the version bein upgraded
  423. * This method returns an Array of all modules
  424. * @return $modules Array of modules.
  425. */
  426. function getAllModules() {
  427. $modules = array();
  428. $d = dir('modules');
  429. while($e = $d->read()){
  430. if(substr($e, 0, 1) == '.' || !is_dir('modules/' . $e))continue;
  431. $modules[] = $e;
  432. }
  433. return $modules;
  434. }
  435. //Remove files with the smae md5
  436. function removeMd5MatchingFiles($deleteNot=array()){
  437. $md5_string = array();
  438. if(file_exists(clean_path(getcwd().'/files.md5'))){
  439. require(clean_path(getcwd().'/files.md5'));
  440. }
  441. $modulesAll = getAllModules();
  442. foreach($modulesAll as $mod){
  443. $allModFiles = array();
  444. if(is_dir('modules/'.$mod)){
  445. $allModFiles = findAllFiles('modules/'.$mod,$allModFiles);
  446. foreach($allModFiles as $file){
  447. if(file_exists($file) && !in_array(basename($file),$deleteNot)){
  448. if(isset($md5_string['./'.$file])) {
  449. $fileContents = file_get_contents($file);
  450. if(md5($fileContents) == $md5_string['./'.$file]) {
  451. unlink($file);
  452. }
  453. }
  454. }
  455. }
  456. }
  457. }
  458. }
  459. /**
  460. * Handles requirements for creating reminder Tasks and Emails
  461. * @param array skippedFiles Array of files that were not overwriten and must be manually mereged.
  462. * @param string path Optional full path to alternate upgradeWizard log.
  463. */
  464. function commitHandleReminders($skippedFiles, $path='') {
  465. global $mod_strings;
  466. global $current_user;
  467. if(empty($mod_strings))
  468. $mod_strings = return_module_language('en_us', 'UpgradeWizard');
  469. if(empty($current_user->id)) {
  470. $current_user->getSystemUser();
  471. }
  472. if(count($skippedFiles) > 0) {
  473. $desc = $mod_strings['LBL_UW_COMMIT_ADD_TASK_OVERVIEW'] . "\n\n";
  474. $desc .= $mod_strings['LBL_UW_COMMIT_ADD_TASK_DESC_1'];
  475. $desc .= $_SESSION['uw_restore_dir'] . "\n\n";
  476. $desc .= $mod_strings['LBL_UW_COMMIT_ADD_TASK_DESC_2'] . "\n\n";
  477. foreach($skippedFiles as $file) {
  478. $desc .= $file . "\n";
  479. }
  480. //MFH #13468
  481. /// Not using new TimeDate stuff here because it needs to be compatible with 6.0
  482. $nowDate = gmdate('Y-m-d');
  483. $nowTime = gmdate('H:i:s');
  484. $nowDateTime = $nowDate . ' ' . $nowTime;
  485. if($_REQUEST['addTaskReminder'] == 'remind') {
  486. logThis('Adding Task for admin for manual merge.', $path);
  487. $task = new Task();
  488. $task->name = $mod_strings['LBL_UW_COMMIT_ADD_TASK_NAME'];
  489. $task->description = $desc;
  490. $task->date_due = $nowDate;
  491. $task->time_due = $nowTime;
  492. $task->priority = 'High';
  493. $task->status = 'Not Started';
  494. $task->assigned_user_id = $current_user->id;
  495. $task->created_by = $current_user->id;
  496. $task->date_entered = $nowDateTime;
  497. $task->date_modified = $nowDateTime;
  498. $task->save();
  499. }
  500. if($_REQUEST['addEmailReminder'] == 'remind') {
  501. logThis('Sending Reminder for admin for manual merge.', $path);
  502. $email = new Email();
  503. $email->assigned_user_id = $current_user->id;
  504. $email->name = $mod_strings['LBL_UW_COMMIT_ADD_TASK_NAME'];
  505. $email->description = $desc;
  506. $email->description_html = nl2br($desc);
  507. $email->from_name = $current_user->full_name;
  508. $email->from_addr = $current_user->email1;
  509. $email->to_addrs_arr = $email->parse_addrs($current_user->email1, '', '', '');
  510. $email->cc_addrs_arr = array();
  511. $email->bcc_addrs_arr = array();
  512. $email->date_entered = $nowDateTime;
  513. $email->date_modified = $nowDateTime;
  514. $email->send();
  515. $email->save();
  516. }
  517. }
  518. }
  519. function deleteCache(){
  520. //Clean modules from cache
  521. $cachedir = sugar_cached('modules');
  522. if(is_dir($cachedir)){
  523. $allModFiles = array();
  524. $allModFiles = findAllFiles($cachedir,$allModFiles, true);
  525. foreach($allModFiles as $file) {
  526. if(file_exists($file)) {
  527. if(is_dir($file)) {
  528. rmdir_recursive($file);
  529. } else {
  530. unlink($file);
  531. }
  532. }
  533. }
  534. }
  535. //Clean jsLanguage from cache
  536. $cachedir = sugar_cached('jsLanguage');
  537. if(is_dir($cachedir)){
  538. $allModFiles = array();
  539. $allModFiles = findAllFiles($cachedir,$allModFiles);
  540. foreach($allModFiles as $file){
  541. if(file_exists($file)){
  542. unlink($file);
  543. }
  544. }
  545. }
  546. //Clean smarty from cache
  547. $cachedir = sugar_cached('smarty');
  548. if(is_dir($cachedir)){
  549. $allModFiles = array();
  550. $allModFiles = findAllFiles($cachedir,$allModFiles);
  551. foreach($allModFiles as $file){
  552. if(file_exists($file)){
  553. unlink($file);
  554. }
  555. }
  556. }
  557. //Rebuild dashlets cache
  558. require_once('include/Dashlets/DashletCacheBuilder.php');
  559. $dc = new DashletCacheBuilder();
  560. $dc->buildCache();
  561. }
  562. function deleteChance(){
  563. //Clean folder from cache
  564. if(is_dir('include/SugarObjects/templates/chance')){
  565. rmdir_recursive('include/SugarObjects/templates/chance');
  566. }
  567. if(is_dir('include/SugarObjects/templates/chance')){
  568. if(!isset($_SESSION['chance'])){
  569. $_SESSION['chance'] = '';
  570. }
  571. $_SESSION['chance'] = 'include/SugarObjects/templates/chance';
  572. //rename('include/SugarObjects/templates/chance','include/SugarObjects/templates/chance_removeit');
  573. }
  574. }
  575. /**
  576. * upgradeUWFiles
  577. * This function copies upgrade wizard files from new patch if that dir exists
  578. *
  579. * @param $file String path to uploaded zip file
  580. */
  581. function upgradeUWFiles($file) {
  582. $cacheUploadUpgradesTemp = mk_temp_dir(sugar_cached("upgrades/temp"));
  583. unzip($file, $cacheUploadUpgradesTemp);
  584. if(!file_exists("$cacheUploadUpgradesTemp/manifest.php")) {
  585. logThis("*** ERROR: no manifest file detected while bootstraping upgrade wizard files!");
  586. return;
  587. } else {
  588. include("$cacheUploadUpgradesTemp/manifest.php");
  589. }
  590. $allFiles = array();
  591. $from_dir = "{$cacheUploadUpgradesTemp}/{$manifest['copy_files']['from_dir']}";
  592. // Localization
  593. if(file_exists("$from_dir/include/Localization/Localization.php")) {
  594. $allFiles[] = "$from_dir/include/Localization/Localization.php";
  595. }
  596. // upgradeWizard
  597. if(file_exists("$from_dir/modules/UpgradeWizard")) {
  598. $allFiles[] = findAllFiles("$from_dir/modules/UpgradeWizard", $allFiles);
  599. }
  600. // moduleInstaller
  601. if(file_exists("$from_dir/ModuleInstall")) {
  602. $allFiles[] = findAllFiles("$from_dir/ModuleInstall", $allFiles);
  603. }
  604. if(file_exists("$from_dir/include/javascript/yui")) {
  605. $allFiles[] = findAllFiles("$from_dir/include/javascript/yui", $allFiles);
  606. }
  607. if(file_exists("$from_dir/HandleAjaxCall.php")) {
  608. $allFiles[] = "$from_dir/HandleAjaxCall.php";
  609. }
  610. if(file_exists("$from_dir/include/SugarTheme")) {
  611. $allFiles[] = findAllFiles("$from_dir/include/SugarTheme", $allFiles);
  612. }
  613. if(file_exists("$from_dir/include/SugarCache")) {
  614. $allFiles[] = findAllFiles("$from_dir/include/SugarCache", $allFiles);
  615. }
  616. if(file_exists("$from_dir/include/utils/external_cache.php")) {
  617. $allFiles[] = "$from_dir/include/utils/external_cache.php";
  618. }
  619. if(file_exists("$from_dir/include/upload_file.php")) {
  620. $allFiles[] = "$from_dir/include/upload_file.php";
  621. }
  622. if(file_exists("$from_dir/include/file_utils.php")) {
  623. $allFiles[] = "$from_dir/include/file_utils.php";
  624. }
  625. if(file_exists("$from_dir/include/upload_file.php")) {
  626. $allFiles[] = "$from_dir/include/upload_file.php";
  627. }
  628. if(file_exists("$from_dir/include/utils/sugar_file_utils.php")) {
  629. $allFiles[] = "$from_dir/include/utils/sugar_file_utils.php";
  630. }
  631. // users
  632. if(file_exists("$from_dir/modules/Users")) {
  633. $allFiles[] = findAllFiles("$from_dir/modules/Users", $allFiles);
  634. }
  635. upgradeUWFilesCopy($allFiles, $from_dir);
  636. }
  637. /**
  638. * upgradeUWFilesCopy
  639. *
  640. * This function recursively copies files from the upgradeUWFiles Array
  641. * @see upgradeUWFiles
  642. *
  643. * @param array $allFiles Array of files to copy over after zip file has been uploaded
  644. * @param string $from_dir Source directory
  645. */
  646. function upgradeUWFilesCopy($allFiles, $from_dir)
  647. {
  648. foreach($allFiles as $file)
  649. {
  650. if(is_array($file))
  651. {
  652. upgradeUWFilesCopy($file, $from_dir);
  653. } else {
  654. $destFile = str_replace($from_dir."/", "", $file);
  655. if(!is_dir(dirname($destFile))) {
  656. mkdir_recursive(dirname($destFile)); // make sure the directory exists
  657. }
  658. if(stristr($file,'uw_main.tpl'))
  659. logThis('Skipping "'.$file.'" - file copy will during commit step.');
  660. else {
  661. logThis('updating UpgradeWizard code: '.$destFile);
  662. copy_recursive($file, $destFile);
  663. }
  664. }
  665. }
  666. }
  667. /**
  668. * gets valid patch file names that exist in upload/upgrade/patch/
  669. */
  670. function getValidPatchName($returnFull = true) {
  671. global $base_upgrade_dir;
  672. global $mod_strings;
  673. global $uh;
  674. global $sugar_version;
  675. global $sugar_config;
  676. $uh = new UpgradeHistory();
  677. list($base_upgrade_dir, $base_tmp_upgrade_dir) = getUWDirs();
  678. $return = array();
  679. // scan for new files (that are not installed)
  680. logThis('finding new files for upgrade');
  681. $upgrade_content = '';
  682. $upgrade_contents = findAllFiles($base_upgrade_dir, array(), false, 'zip');
  683. //other variations of zip file i.e. ZIP, zIp,zIP,Zip,ZIp,ZiP
  684. $ready = "<ul>\n";
  685. $ready .= "
  686. <table>
  687. <tr>
  688. <td></td>
  689. <td align=left>
  690. <b>{$mod_strings['LBL_ML_NAME']}</b>
  691. </td>
  692. <td align=left>
  693. <b>{$mod_strings['LBL_ML_TYPE']}</b>
  694. </td>
  695. <td align=left>
  696. <b>{$mod_strings['LBL_ML_VERSION']}</b>
  697. </td>
  698. <td align=left>
  699. <b>{$mod_strings['LBL_ML_PUBLISHED']}</b>
  700. </td>
  701. <td align=left>
  702. <b>{$mod_strings['LBL_ML_UNINSTALLABLE']}</b>
  703. </td>
  704. <td align=left>
  705. <b>{$mod_strings['LBL_ML_DESCRIPTION']}</b>
  706. </td>
  707. </tr>";
  708. $disabled = '';
  709. // assume old patches are there.
  710. $upgradeToVersion = array(); // fill with valid patches - we will only use the latest qualified found patch
  711. // cn: bug 10609 - notices for uninitialized variables
  712. $icon = '';
  713. $name = '';
  714. $type = '';
  715. $version = '';
  716. $published_date = '';
  717. $uninstallable = '';
  718. $description = '';
  719. $disabled = '';
  720. foreach($upgrade_contents as $upgrade_content) {
  721. if(!preg_match("#.*\.zip\$#i", $upgrade_content)) {
  722. continue;
  723. }
  724. $the_base = basename($upgrade_content);
  725. $the_md5 = md5_file($upgrade_content);
  726. $md5_matches = $uh->findByMd5($the_md5);
  727. /* If a patch is in the /patch dir AND has no record in the upgrade_history table we assume that it's the one we want.
  728. * Edge-case: manual upgrade with a FTP of a patch; UH table has no entry for it. Assume nothing. :( */
  729. if(0 == sizeof($md5_matches)) {
  730. $target_manifest = remove_file_extension( $upgrade_content ) . '-manifest.php';
  731. require_once($target_manifest);
  732. if(empty($manifest['version'])) {
  733. logThis("*** Potential error: patch found with no version [ {$upgrade_content} ]");
  734. continue;
  735. }
  736. if(!isset($manifest['type']) || $manifest['type'] != 'patch') {
  737. logThis("*** Potential error: patch found with either no 'type' or non-patch type [ {$upgrade_content} ]");
  738. continue;
  739. }
  740. $upgradeToVersion[$manifest['version']] = urlencode($upgrade_content);
  741. $name = empty($manifest['name']) ? $upgrade_content : $manifest['name'];
  742. $version = empty($manifest['version']) ? '' : $manifest['version'];
  743. $published_date = empty($manifest['published_date']) ? '' : $manifest['published_date'];
  744. $icon = '';
  745. $description = empty($manifest['description']) ? 'None' : $manifest['description'];
  746. $uninstallable = empty($manifest['is_uninstallable']) ? 'No' : 'Yes';
  747. $type = getUITextForType( $manifest['type'] );
  748. $manifest_type = $manifest['type'];
  749. if(empty($manifest['icon'])) {
  750. $icon = getImageForType( $manifest['type'] );
  751. } else {
  752. $path_parts = pathinfo( $manifest['icon'] );
  753. $icon = "<!--not_in_theme!--><img src=\"" . remove_file_extension( $upgrade_content ) . "-icon." . $path_parts['extension'] . "\">";
  754. }
  755. }
  756. }
  757. // cn: bug 10488 use the NEWEST upgrade/patch available when running upgrade wizard.
  758. ksort($upgradeToVersion);
  759. $upgradeToVersion = array_values($upgradeToVersion);
  760. $newest = array_pop($upgradeToVersion);
  761. $_SESSION['install_file'] = urldecode($newest); // in-case it was there from a prior.
  762. logThis("*** UW using [ {$_SESSION['install_file']} ] as source for patch files.");
  763. $cleanUpgradeContent = urlencode($_SESSION['install_file']);
  764. // cn: 10606 - cannot upload a patch file since this returned always.
  765. if(!empty($cleanUpgradeContent)) {
  766. $ready .= "<tr><td>$icon</td><td>$name</td><td>$type</td><td>$version</td><td>$published_date</td><td>$uninstallable</td><td>$description</td>\n";
  767. $ready .=<<<eoq
  768. <td>
  769. <form action="index.php" method="post">
  770. <input type="hidden" name="module" value="UpgradeWizard">
  771. <input type="hidden" name="action" value="index">
  772. <input type="hidden" name="step" value="{$_REQUEST['step']}">
  773. <input type="hidden" name="run" value="delete">
  774. <input type=hidden name="install_file" value="{$cleanUpgradeContent}" />
  775. <input type=submit value="{$mod_strings['LBL_BUTTON_DELETE']}" />
  776. </form>
  777. </td></table>
  778. eoq;
  779. $disabled = "DISABLED";
  780. }
  781. if(empty($cleanUpgradeContent)){
  782. $ready .= "<tr><td colspan='7'><i>None</i></td>\n";
  783. $ready .= "</table>\n";
  784. }
  785. $ready .= "<br></ul>\n";
  786. $return['ready'] = $ready;
  787. $return['disabled'] = $disabled;
  788. if($returnFull) {
  789. return $return;
  790. }
  791. }
  792. /**
  793. * finalizes upgrade by setting upgrade versions in DB (config table) and sugar_version.php
  794. * @return bool true on success
  795. */
  796. function updateVersions($version) {
  797. global $db;
  798. global $sugar_config;
  799. global $path;
  800. logThis('At updateVersions()... updating config table and sugar_version.php.', $path);
  801. // handle file copy
  802. if(isset($_SESSION['sugar_version_file']) && !empty($_SESSION['sugar_version_file'])) {
  803. if(!copy($_SESSION['sugar_version_file'], clean_path(getcwd().'/sugar_version.php'))) {
  804. logThis('*** ERROR: sugar_version.php could not be copied to destination! Cannot complete upgrade', $path);
  805. return false;
  806. } else {
  807. logThis('sugar_version.php successfully updated!', $path);
  808. }
  809. } else {
  810. logThis('*** ERROR: no sugar_version.php file location found! - cannot complete upgrade...', $path);
  811. return false;
  812. }
  813. $q1 = "DELETE FROM config WHERE category = 'info' AND name = 'sugar_version'";
  814. $q2 = "INSERT INTO config (category, name, value) VALUES ('info', 'sugar_version', '{$version}')";
  815. logThis('Deleting old DB version info from config table.', $path);
  816. $db->query($q1);
  817. logThis('Inserting updated version info into config table.', $path);
  818. $db->query($q2);
  819. logThis('updateVersions() complete.', $path);
  820. return true;
  821. }
  822. /**
  823. * gets a module's lang pack - does not need to be a SugarModule
  824. * @param lang string Language
  825. * @param module string Path to language folder
  826. * @return array mod_strings
  827. */
  828. function getModuleLanguagePack($lang, $module) {
  829. $mod_strings = array();
  830. if(!empty($lang) && !empty($module)) {
  831. $langPack = clean_path(getcwd().'/'.$module.'/language/'.$lang.'.lang.php');
  832. $langPackEn = clean_path(getcwd().'/'.$module.'/language/en_us.lang.php');
  833. if (file_exists($langPack))
  834. {
  835. include($langPack);
  836. }
  837. elseif (file_exists($langPackEn))
  838. {
  839. include($langPackEn);
  840. }
  841. }
  842. return $mod_strings;
  843. }
  844. /**
  845. * checks system compliance for 4.5+ codebase
  846. * @return array Mixed values
  847. */
  848. function checkSystemCompliance() {
  849. global $sugar_config;
  850. global $current_language;
  851. global $db;
  852. global $mod_strings;
  853. global $app_strings;
  854. if(!defined('SUGARCRM_MIN_MEM')) {
  855. define('SUGARCRM_MIN_MEM', 40);
  856. }
  857. $installer_mod_strings = getModuleLanguagePack($current_language, './install');
  858. $ret = array();
  859. $ret['error_found'] = false;
  860. // PHP version
  861. $php_version = constant('PHP_VERSION');
  862. $check_php_version_result = check_php_version($php_version);
  863. switch($check_php_version_result) {
  864. case -1:
  865. $ret['phpVersion'] = "<b><span class=stop>{$installer_mod_strings['ERR_CHECKSYS_PHP_INVALID_VER']} {$php_version} )</span></b>";
  866. $ret['error_found'] = true;
  867. break;
  868. case 0:
  869. $ret['phpVersion'] = "<b><span class=go>{$installer_mod_strings['ERR_CHECKSYS_PHP_UNSUPPORTED']} {$php_version} )</span></b>";
  870. break;
  871. case 1:
  872. $ret['phpVersion'] = "<b><span class=go>{$installer_mod_strings['LBL_CHECKSYS_PHP_OK']} {$php_version} )</span></b>";
  873. break;
  874. }
  875. // database and connect
  876. $canInstall = $db->canInstall();
  877. if ($canInstall !== true)
  878. {
  879. $ret['error_found'] = true;
  880. if (count($canInstall) == 1)
  881. {
  882. $ret['dbVersion'] = "<b><span class=stop>" . $installer_mod_strings[$canInstall[0]] . "</span></b>";
  883. }
  884. else
  885. {
  886. $ret['dbVersion'] = "<b><span class=stop>" . sprintf($installer_mod_strings[$canInstall[0]], $canInstall[1]) . "</span></b>";
  887. }
  888. }
  889. // XML Parsing
  890. if(function_exists('xml_parser_create')) {
  891. $ret['xmlStatus'] = "<b><span class=go>{$installer_mod_strings['LBL_CHECKSYS_OK']}</span></b>";
  892. } else {
  893. $ret['xmlStatus'] = "<b><span class=stop>{$installer_mod_strings['LBL_CHECKSYS_NOT_AVAILABLE']}</span></b>";
  894. $ret['error_found'] = true;
  895. }
  896. // cURL
  897. if(function_exists('curl_init')) {
  898. $ret['curlStatus'] = "<b><span class=go>{$installer_mod_strings['LBL_CHECKSYS_OK']}</span></b>";
  899. } else {
  900. $ret['curlStatus'] = "<b><span class=go>{$installer_mod_strings['ERR_CHECKSYS_CURL']}</span></b>";
  901. $ret['error_found'] = false;
  902. }
  903. // mbstrings
  904. if(function_exists('mb_strlen')) {
  905. $ret['mbstringStatus'] = "<b><span class=go>{$installer_mod_strings['LBL_CHECKSYS_OK']}</span></b>";
  906. } else {
  907. $ret['mbstringStatus'] = "<b><span class=stop>{$installer_mod_strings['ERR_CHECKSYS_MBSTRING']}</span></b>";
  908. $ret['error_found'] = true;
  909. }
  910. // imap
  911. if(function_exists('imap_open')) {
  912. $ret['imapStatus'] = "<b><span class=go>{$installer_mod_strings['LBL_CHECKSYS_OK']}</span></b>";
  913. } else {
  914. $ret['imapStatus'] = "<b><span class=go>{$installer_mod_strings['ERR_CHECKSYS_IMAP']}</span></b>";
  915. $ret['error_found'] = false;
  916. }
  917. // safe mode
  918. if('1' == ini_get('safe_mode')) {
  919. $ret['safeModeStatus'] = "<b><span class=stop>{$installer_mod_strings['ERR_CHECKSYS_SAFE_MODE']}</span></b>";
  920. $ret['error_found'] = true;
  921. } else {
  922. $ret['safeModeStatus'] = "<b><span class=go>{$installer_mod_strings['LBL_CHECKSYS_OK']}</span></b>";
  923. }
  924. // call time pass by ref
  925. if('1' == ini_get('allow_call_time_pass_reference')) {
  926. $ret['callTimeStatus'] = "<b><span class=stop>{$installer_mod_strings['ERR_CHECKSYS_CALL_TIME']}</span></b>";
  927. //continue upgrading
  928. } else {
  929. $ret['callTimeStatus'] = "<b><span class=go>{$installer_mod_strings['LBL_CHECKSYS_OK']}</span></b>";
  930. }
  931. // memory limit
  932. $ret['memory_msg'] = "";
  933. $memory_limit = "-1";//ini_get('memory_limit');
  934. $sugarMinMem = constant('SUGARCRM_MIN_MEM');
  935. // logic based on: http://us2.php.net/manual/en/ini.core.php#ini.memory-limit
  936. if( $memory_limit == "" ){ // memory_limit disabled at compile time, no memory limit
  937. $ret['memory_msg'] = "<b><span class=\"go\">{$installer_mod_strings['LBL_CHECKSYS_MEM_OK']}</span></b>";
  938. } elseif( $memory_limit == "-1" ){ // memory_limit enabled, but set to unlimited
  939. $ret['memory_msg'] = "<b><span class=\"go\">{$installer_mod_strings['LBL_CHECKSYS_MEM_UNLIMITED']}</span></b>";
  940. } else {
  941. rtrim($memory_limit, 'M');
  942. $memory_limit_int = (int) $memory_limit;
  943. if( $memory_limit_int < constant('SUGARCRM_MIN_MEM') ){
  944. $ret['memory_msg'] = "<b><span class=\"stop\">{$installer_mod_strings['ERR_CHECKSYS_MEM_LIMIT_1']}" . constant('SUGARCRM_MIN_MEM') . "{$installer_mod_strings['ERR_CHECKSYS_MEM_LIMIT_2']}</span></b>";
  945. $ret['error_found'] = true;
  946. } else {
  947. $ret['memory_msg'] = "<b><span class=\"go\">{$installer_mod_strings['LBL_CHECKSYS_OK']} ({$memory_limit})</span></b>";
  948. }
  949. }
  950. // zip support
  951. if (!class_exists("ZipArchive"))
  952. {
  953. $ret['ZipStatus'] = "<b><span class=stop>{$installer_mod_strings['ERR_CHECKSYS_ZIP']}</span></b>";
  954. $ret['error_found'] = true;
  955. } else {
  956. $ret['ZipStatus'] = "<b><span class=go>{$installer_mod_strings['LBL_CHECKSYS_OK']}</span></b>";
  957. }
  958. // Suhosin allow to use upload://
  959. $ret['stream_msg'] = '';
  960. if (UploadStream::getSuhosinStatus() == true)
  961. {
  962. $ret['stream_msg'] = "<b><span class=\"go\">{$installer_mod_strings['LBL_CHECKSYS_OK']}</span></b>";
  963. }
  964. else
  965. {
  966. $ret['stream_msg'] = "<b><span class=\"stop\">{$app_strings['ERR_SUHOSIN']}</span></b>";
  967. $ret['error_found'] = true;
  968. }
  969. /* mbstring.func_overload
  970. $ret['mbstring.func_overload'] = '';
  971. $mb = ini_get('mbstring.func_overload');
  972. if($mb > 1) {
  973. $ret['mbstring.func_overload'] = "<b><span class=\"stop\">{$mod_strings['ERR_UW_MBSTRING_FUNC_OVERLOAD']}</b>";
  974. $ret['error_found'] = true;
  975. }
  976. */
  977. return $ret;
  978. }
  979. /**
  980. * is a file that we blow away automagically
  981. */
  982. function isAutoOverwriteFile($file) {
  983. $overwriteDirs = array(
  984. './sugar_version.php',
  985. './modules/UpgradeWizard/uw_main.tpl',
  986. );
  987. $file = trim('.'.str_replace(clean_path(getcwd()), '', $file));
  988. if(in_array($file, $overwriteDirs)) {
  989. return true;
  990. }
  991. $fileExtension = substr(strrchr($file, "."), 1);
  992. if($fileExtension == 'tpl' || $fileExtension == 'html') {
  993. return false;
  994. }
  995. return true;
  996. }
  997. /**
  998. * flatfile logger
  999. */
  1000. function logThis($entry, $path='') {
  1001. global $mod_strings;
  1002. if(file_exists('include/utils/sugar_file_utils.php')){
  1003. require_once('include/utils/sugar_file_utils.php');
  1004. }
  1005. $log = empty($path) ? clean_path(getcwd().'/upgradeWizard.log') : clean_path($path);
  1006. // create if not exists
  1007. if(!file_exists($log)) {
  1008. if(function_exists('sugar_fopen')){
  1009. $fp = @sugar_fopen($log, 'w+'); // attempts to create file
  1010. }
  1011. else{
  1012. $fp = fopen($log, 'w+'); // attempts to create file
  1013. }
  1014. if(!is_resource($fp)) {
  1015. $GLOBALS['log']->fatal('UpgradeWizard could not create the upgradeWizard.log file');
  1016. die($mod_strings['ERR_UW_LOG_FILE_UNWRITABLE']);
  1017. }
  1018. } else {
  1019. if(function_exists('sugar_fopen')){
  1020. $fp = @sugar_fopen($log, 'a+'); // write pointer at end of file
  1021. }
  1022. else{
  1023. $fp = @fopen($log, 'a+'); // write pointer at end of file
  1024. }
  1025. if(!is_resource($fp)) {
  1026. $GLOBALS['log']->fatal('UpgradeWizard could not open/lock upgradeWizard.log file');
  1027. die($mod_strings['ERR_UW_LOG_FILE_UNWRITABLE']);
  1028. }
  1029. }
  1030. $line = date('r').' [UpgradeWizard] - '.$entry."\n";
  1031. if(@fwrite($fp, $line) === false) {
  1032. $GLOBALS['log']->fatal('UpgradeWizard could not write to upgradeWizard.log: '.$entry);
  1033. die($mod_strings['ERR_UW_LOG_FILE_UNWRITABLE']);
  1034. }
  1035. if(is_resource($fp)) {
  1036. fclose($fp);
  1037. }
  1038. }
  1039. /**
  1040. * @params : none
  1041. * @author: nsingh
  1042. * @desc This function is to be used in the upgrade process to preserve changes/customaizations made to pre 5.1 quickcreate layout.
  1043. * Prior to 5.1 we have been using editviewdefs as the base for quickcreatedefs. If a custom field was added to edit view layout, it
  1044. * was automatically picked up by the quick create. [Addresses Bug 21469]
  1045. * This function will check if customizations were made, and will create quickcreatedefs.php in the /cutom/working/$module_name directory.
  1046. **/
  1047. function updateQuickCreateDefs(){
  1048. $d = dir('modules');
  1049. $studio_modules = array();
  1050. while($e = $d->read()){ //collect all studio modules.
  1051. if(substr($e, 0, 1) == '.' || !is_dir('modules/' . $e))continue;
  1052. if(file_exists('modules/' . $e . '/metadata/studio.php'))
  1053. {
  1054. array_push($studio_modules, $e);
  1055. }
  1056. }
  1057. foreach( $studio_modules as $modname ){ //for each studio enabled module
  1058. //Check !exists modules/$modname/metadata/quickcreatedefs.php &&
  1059. //exists custom/$modname/editviewdefs.php (module was customized) &&
  1060. //!exists custom/$modname/quickcreateviewdefs.php
  1061. $editviewdefs = "custom/working/modules/".$modname."/metadata/editviewdefs.php";
  1062. $quickcreatedefs = "custom/working/modules/".$modname."/metadata/quickcreatedefs.php";
  1063. if ( !file_exists("modules/".$modname."/metadata/quickcreatedefs.php") &&
  1064. file_exists($editviewdefs) &&
  1065. !file_exists($quickcreatedefs) ){
  1066. //clone editviewdef and save it in custom/working/modules/metadata
  1067. $GLOBALS['log']->debug("Copying editviewdefs.php as quickcreatedefs.php for the $modname module in custom/working/modules/$modname/metadata!");
  1068. if(copy( $editviewdefs, $quickcreatedefs)){
  1069. if(file_exists($quickcreatedefs) && is_readable($quickcreatedefs)){
  1070. $file = file($quickcreatedefs);
  1071. //replace 'EditView' with 'QuickCreate'
  1072. $fp = fopen($quickcreatedefs,'w');
  1073. foreach($file as &$line){
  1074. if(preg_match('/^\s*\'EditView\'\s*=>\s*$/', $line) > 0){
  1075. $line = "'QuickCreate' =>\n";
  1076. }
  1077. fwrite($fp, $line);
  1078. }
  1079. //write back.
  1080. fclose($fp);
  1081. }
  1082. else{
  1083. $GLOBALS['log']->debug("Failed to replace 'EditView' with QuickCreate because $quickcreatedefs is either not readable or does not exist.");
  1084. }
  1085. }else{
  1086. $GLOBALS['log']->debug("Failed to copy $editviewdefs to $quickcreatedefs!");
  1087. }
  1088. }
  1089. }
  1090. }
  1091. /**
  1092. * test perms for CREATE queries
  1093. */
  1094. function testPermsCreate($db, $out) {
  1095. logThis('Checking CREATE TABLE permissions...');
  1096. global $mod_strings;
  1097. if(!$db->checkPrivilege("CREATE TABLE")) {
  1098. logThis('cannot CREATE TABLE!');
  1099. $out['db']['dbNoCreate'] = true;
  1100. $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_CREATE']}</span></td></tr>";
  1101. }
  1102. return $out;
  1103. }
  1104. /**
  1105. * test perms for INSERT
  1106. */
  1107. function testPermsInsert($db, $out, $skip=false) {
  1108. logThis('Checking INSERT INTO permissions...');
  1109. global $mod_strings;
  1110. if(!$db->checkPrivilege("INSERT")) {
  1111. logThis('cannot INSERT INTO!');
  1112. $out['db']['dbNoInsert'] = true;
  1113. $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_INSERT']}</span></td></tr>";
  1114. }
  1115. return $out;
  1116. }
  1117. /**
  1118. * test perms for UPDATE TABLE
  1119. */
  1120. function testPermsUpdate($db, $out, $skip=false) {
  1121. logThis('Checking UPDATE TABLE permissions...');
  1122. global $mod_strings;
  1123. if(!$db->checkPrivilege("UPDATE")) {
  1124. logThis('cannot UPDATE TABLE!');
  1125. $out['db']['dbNoUpdate'] = true;
  1126. $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_UPDATE']}</span></td></tr>";
  1127. }
  1128. return $out;
  1129. }
  1130. /**
  1131. * test perms for SELECT
  1132. */
  1133. function testPermsSelect($db, $out, $skip=false) {
  1134. logThis('Checking SELECT permissions...');
  1135. global $mod_strings;
  1136. if(!$db->checkPrivilege("SELECT")) {
  1137. logThis('cannot SELECT!');
  1138. $out['db']['dbNoSelect'] = true;
  1139. $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_SELECT']}</span></td></tr>";
  1140. }
  1141. return $out;
  1142. }
  1143. /**
  1144. * test perms for DELETE
  1145. */
  1146. function testPermsDelete($db, $out, $skip=false) {
  1147. logThis('Checking DELETE FROM permissions...');
  1148. global $mod_strings;
  1149. if(!$db->checkPrivilege("DELETE")) {
  1150. logThis('cannot DELETE FROM!');
  1151. $out['db']['dbNoDelete'] = true;
  1152. $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_DELETE']}</span></td></tr>";
  1153. }
  1154. return $out;
  1155. }
  1156. /**
  1157. * test perms for ALTER TABLE ADD COLUMN
  1158. */
  1159. function testPermsAlterTableAdd($db, $out, $skip=false) {
  1160. logThis('Checking ALTER TABLE ADD COLUMN permissions...');
  1161. global $mod_strings;
  1162. if(!$db->checkPrivilege("ADD COLUMN")) {
  1163. logThis('cannot ADD COLUMN!');
  1164. $out['db']['dbNoAddColumn'] = true;
  1165. $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_ADD_COLUMN']}</span></td></tr>";
  1166. }
  1167. return $out;
  1168. }
  1169. /**
  1170. * test perms for ALTER TABLE ADD COLUMN
  1171. */
  1172. function testPermsAlterTableChange($db, $out, $skip=false) {
  1173. logThis('Checking ALTER TABLE CHANGE COLUMN permissions...');
  1174. global $mod_strings;
  1175. if(!$db->checkPrivilege("CHANGE COLUMN")) {
  1176. logThis('cannot CHANGE COLUMN!');
  1177. $out['db']['dbNoChangeColumn'] = true;
  1178. $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_CHANGE_COLUMN']}</span></td></tr>";
  1179. }
  1180. return $out;
  1181. }
  1182. /**
  1183. * test perms for ALTER TABLE DROP COLUMN
  1184. */
  1185. function testPermsAlterTableDrop($db, $out, $skip=false) {
  1186. logThis('Checking ALTER TABLE DROP COLUMN permissions...');
  1187. global $mod_strings;
  1188. if(!$db->checkPrivilege("DROP COLUMN")) {
  1189. logThis('cannot DROP COLUMN!');
  1190. $out['db']['dbNoDropColumn'] = true;
  1191. $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_DROP_COLUMN']}</span></td></tr>";
  1192. }
  1193. return $out;
  1194. }
  1195. /**
  1196. * test perms for DROP TABLE
  1197. */
  1198. function testPermsDropTable($db, $out, $skip=false) {
  1199. logThis('Checking DROP TABLE permissions...');
  1200. global $mod_strings;
  1201. if(!$db->checkPrivilege("DROP TABLE")) {
  1202. logThis('cannot DROP TABLE!');
  1203. $out['db']['dbNoDropTable'] = true;
  1204. $out['dbOut'] .= "<tr><td align='left'><span class='error'>{$mod_strings['LBL_UW_DB_NO_DROP_TABLE']}</span></td></tr>";
  1205. }
  1206. return $out;
  1207. }
  1208. function getFormattedError($error, $query) {
  1209. $error = "<div><b>".$error;
  1210. $error .= "</b>::{$query}</div>";
  1211. return $error;
  1212. }
  1213. /**
  1214. * parses a query finding the table name
  1215. * @param string query The query
  1216. * @return string table The table
  1217. */
  1218. function getTableFromQuery($query) {
  1219. $standardQueries = array('ALTER TABLE', 'DROP TABLE', 'CREATE TABLE', 'INSERT INTO', 'UPDATE', 'DELETE FROM');
  1220. $query = preg_replace("/[^A-Za-z0-9\_\s]/", "", $query);
  1221. $query = trim(str_replace($standardQueries, '', $query));
  1222. $firstSpc = strpos($query, " ");
  1223. $end = ($firstSpc > 0) ? $firstSpc : strlen($query);
  1224. $table = substr($query, 0, $end);
  1225. return $table;
  1226. }
  1227. //prelicense check
  1228. function preLicenseCheck() {
  1229. require_once('modules/UpgradeWizard/uw_files.php');
  1230. global $sugar_config;
  1231. global $mod_strings;
  1232. global $sugar_version;
  1233. if(!isset($sugar_version) || empty($sugar_version)) {
  1234. require_once('./sugar_version.php');
  1235. }
  1236. if(!isset($_SESSION['unzip_dir']) || empty($_SESSION['unzip_dir'])) {
  1237. logThis('unzipping files in upgrade archive...');
  1238. $errors = array();
  1239. list($base_upgrade_dir, $base_tmp_upgrade_dir) = getUWDirs();
  1240. $unzip_dir = '';
  1241. //also come up with mechanism to read from upgrade-progress file
  1242. if(!isset($_SESSION['install_file']) || empty($_SESSION['install_file']) || !is_file($_SESSION['install_file'])) {
  1243. if (file_exists(clean_path($base_tmp_upgrade_dir)) && $handle = opendir(clean_path($base_tmp_upgrade_dir))) {
  1244. while (false !== ($file = readdir($handle))) {
  1245. if($file !="." && $file !="..") {
  1246. if(is_file($base_tmp_upgrade_dir."/".$file."/manifest.php")){
  1247. require_once($base_tmp_upgrade_dir."/".$file."/manifest.php");
  1248. $package_name= $manifest['copy_files']['from_dir'];
  1249. if(file_exists($base_tmp_upgrade_dir."/".$file."/".$package_name) && file_exists($base_tmp_upgrade_dir."/".$file."/scripts") && file_exists($base_tmp_upgrade_dir."/".$file."/manifest.php")){
  1250. $unzip_dir = $base_tmp_upgrade_dir."/".$file;
  1251. if(file_exists("$base_upgrade_dir/patch/".$package_name.'.zip')){
  1252. $_SESSION['install_file'] = $package_name.".zip";
  1253. break;
  1254. }
  1255. }
  1256. }
  1257. }
  1258. }
  1259. }
  1260. }
  1261. if(empty($_SESSION['install_file'])){
  1262. unlinkUWTempFiles();
  1263. resetUwSession();
  1264. echo 'Upload File not found so redirecting to Upgrade Start ';
  1265. $redirect_new_wizard = $sugar_config['site_url' ].'/index.php?module=UpgradeWizard&action=index';
  1266. echo '<form name="redirect" action="' .$redirect_new_wizard. '" method="POST">';
  1267. $upgrade_directories_not_found =<<<eoq
  1268. <table cellpadding="3" cellspacing="0" border="0">
  1269. <tr>
  1270. <th colspan="2" align="left">
  1271. <span class='error'><b>'Upload file missing or has been deleted. Refresh the page to go back to UpgradeWizard start'</b></span>
  1272. </th>
  1273. </tr>
  1274. </table>
  1275. eoq;
  1276. $uwMain = $upgrade_directories_not_found;
  1277. return '';
  1278. }
  1279. $install_file = "$base_upgrade_dir/patch/".basename(urldecode( $_SESSION['install_file'] ));
  1280. $show_files = true;
  1281. if(empty($unzip_dir)){
  1282. $unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
  1283. }
  1284. $zip_from_dir = ".";
  1285. $zip_to_dir = ".";
  1286. $zip_force_copy = array();
  1287. if(!$unzip_dir){
  1288. logThis('Could not create a temporary directory using mk_temp_dir( $base_tmp_upgrade_dir )');
  1289. die($mod_strings['ERR_UW_NO_CREATE_TMP_DIR']);
  1290. }
  1291. //double check whether unzipped .
  1292. if(file_exists($unzip_dir ."/scripts") && file_exists($unzip_dir."/manifest.php")){
  1293. //already unzipped
  1294. }
  1295. else{
  1296. unzip( $install_file, $unzip_dir );
  1297. }
  1298. // assumption -- already validated manifest.php at time of upload
  1299. require_once( "$unzip_dir/manifest.php" );
  1300. if( isset( $manifest['copy_files']['from_dir'] ) && $manifest['copy_files']['from_dir'] != "" ){
  1301. $zip_from_dir = $manifest['copy_files']['from_dir'];
  1302. }
  1303. if( isset( $manifest['copy_files']['to_dir'] ) && $manifest['copy_files']['to_dir'] != "" ){
  1304. $zip_to_dir = $manifest['copy_files']['to_dir'];
  1305. }
  1306. if( isset( $manifest['copy_files']['force_copy'] ) && $manifest['copy_files']['force_copy'] != "" ){
  1307. $zip_force_copy = $manifest['copy_files']['force_copy'];
  1308. }
  1309. if( isset( $manifest['version'] ) ){
  1310. $version = $manifest['version'];
  1311. }
  1312. if( !is_writable( "config.php" ) ){
  1313. return $mod_strings['ERR_UW_CONFIG'];
  1314. }
  1315. $_SESSION['unzip_dir'] = clean_path($unzip_dir);
  1316. $_SESSION['zip_from_dir'] = clean_path($

Large files files are truncated, but you can click here to view the full file