PageRenderTime 44ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 1ms

/install/install_utils.php

https://bitbucket.org/cviolette/sugarcrm
PHP | 2124 lines | 1582 code | 279 blank | 263 comment | 291 complexity | 70e8cd44bc5535ad2d0e256ca8052172 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: TODO: To be written. Portions created by SugarCRM are Copyright
  39. * (C) SugarCRM, Inc. All Rights Reserved. Contributor(s):
  40. * ______________________________________..
  41. * *******************************************************************************/
  42. require_once('include/utils/zip_utils.php');
  43. require_once('include/upload_file.php');
  44. ////////////////
  45. //// GLOBAL utility
  46. /**
  47. * Calls a custom function (if it exists) based on the first parameter,
  48. * and returns result of function call, or 'undefined' if the function doesn't exist
  49. * @param string function name to call in custom install hooks
  50. * @return mixed function call result, or 'undefined'
  51. */
  52. function installerHook($function_name, $options = array()){
  53. if(!isset($GLOBALS['customInstallHooksExist'])){
  54. if(file_exists('custom/install/install_hooks.php')){
  55. installLog("installerHook: Found custom/install/install_hooks.php");
  56. require_once('custom/install/install_hooks.php');
  57. $GLOBALS['customInstallHooksExist'] = true;
  58. }
  59. else{
  60. installLog("installerHook: Could not find custom/install/install_hooks.php");
  61. $GLOBALS['customInstallHooksExist'] = false;
  62. }
  63. }
  64. if($GLOBALS['customInstallHooksExist'] === false){
  65. return 'undefined';
  66. }
  67. else{
  68. if(function_exists($function_name)){
  69. installLog("installerHook: function {$function_name} found, calling and returning the return value");
  70. return $function_name($options);
  71. }
  72. else{
  73. installLog("installerHook: function {$function_name} not found in custom install hooks file");
  74. return 'undefined';
  75. }
  76. }
  77. }
  78. ///////////////////////////////////////////////////////////////////////////////
  79. //// FROM welcome.php
  80. /**
  81. * returns lowercase lang encoding
  82. * @return string encoding or blank on false
  83. */
  84. function parseAcceptLanguage() {
  85. $lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
  86. if(strpos($lang, ';')) {
  87. $exLang = explode(';', $lang);
  88. return strtolower(str_replace('-','_',$exLang[0]));
  89. } else {
  90. $match = array();
  91. if(preg_match("#\w{2}\-?\_?\w{2}#", $lang, $match)) {
  92. return strtolower(str_replace('-','_',$match[0]));
  93. }
  94. }
  95. return '';
  96. }
  97. ///////////////////////////////////////////////////////////////////////////////
  98. //// FROM localization.php
  99. /**
  100. * copies the temporary unzip'd files to their final destination
  101. * removes unzip'd files from system if $uninstall=true
  102. * @param bool uninstall true if uninstalling a language pack
  103. * @return array sugar_config
  104. */
  105. function commitLanguagePack($uninstall=false) {
  106. global $sugar_config;
  107. global $mod_strings;
  108. global $base_upgrade_dir;
  109. global $base_tmp_upgrade_dir;
  110. $errors = array();
  111. $manifest = urldecode($_REQUEST['manifest']);
  112. $zipFile = urldecode($_REQUEST['zipFile']);
  113. $version = "";
  114. $show_files = true;
  115. $unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
  116. $zip_from_dir = ".";
  117. $zip_to_dir = ".";
  118. $zip_force_copy = array();
  119. if($uninstall == false && isset($_SESSION['INSTALLED_LANG_PACKS']) && in_array($zipFile, $_SESSION['INSTALLED_LANG_PACKS'])) {
  120. return;
  121. }
  122. // unzip lang pack to temp dir
  123. if(isset($zipFile) && !empty($zipFile)) {
  124. if(is_file($zipFile)) {
  125. unzip( $zipFile, $unzip_dir );
  126. } else {
  127. echo $mod_strings['ERR_LANG_MISSING_FILE'].$zipFile;
  128. die(); // no point going any further
  129. }
  130. }
  131. // filter for special to/from dir conditions (langpacks generally don't have them)
  132. if(isset($manifest) && !empty($manifest)) {
  133. if(is_file($manifest)) {
  134. include($manifest);
  135. if( isset( $manifest['copy_files']['from_dir'] ) && $manifest['copy_files']['from_dir'] != "" ){
  136. $zip_from_dir = $manifest['copy_files']['from_dir'];
  137. }
  138. if( isset( $manifest['copy_files']['to_dir'] ) && $manifest['copy_files']['to_dir'] != "" ){
  139. $zip_to_dir = $manifest['copy_files']['to_dir'];
  140. }
  141. if( isset( $manifest['copy_files']['force_copy'] ) && $manifest['copy_files']['force_copy'] != "" ){
  142. $zip_force_copy = $manifest['copy_files']['force_copy'];
  143. }
  144. if( isset( $manifest['version'] ) ){
  145. $version = $manifest['version'];
  146. }
  147. } else {
  148. $errors[] = $mod_strings['ERR_LANG_MISSING_FILE'].$manifest;
  149. }
  150. }
  151. // find name of language pack: find single file in include/language/xx_xx.lang.php
  152. $d = dir( "$unzip_dir/$zip_from_dir/include/language" );
  153. while( $f = $d->read() ){
  154. if( $f == "." || $f == ".." ){
  155. continue;
  156. }
  157. else if( preg_match("/(.*)\.lang\.php\$/", $f, $match) ){
  158. $new_lang_name = $match[1];
  159. }
  160. }
  161. if( $new_lang_name == "" ){
  162. die( $mod_strings['ERR_LANG_NO_LANG_FILE'].$zipFile );
  163. }
  164. $new_lang_desc = getLanguagePackName( "$unzip_dir/$zip_from_dir/include/language/$new_lang_name.lang.php" );
  165. if( $new_lang_desc == "" ){
  166. die( "No language pack description found at include/language/$new_lang_name.lang.php inside $install_file." );
  167. }
  168. // add language to available languages
  169. $sugar_config['languages'][$new_lang_name] = ($new_lang_desc);
  170. // get an array of all files to be moved
  171. $filesFrom = array();
  172. $filesFrom = findAllFiles($unzip_dir, $filesFrom);
  173. ///////////////////////////////////////////////////////////////////////////
  174. //// FINALIZE
  175. if($uninstall) {
  176. // unlink all pack files
  177. foreach($filesFrom as $fileFrom) {
  178. //echo "deleting: ".getcwd().substr($fileFrom, strlen($unzip_dir), strlen($fileFrom))."<br>";
  179. @unlink(getcwd().substr($fileFrom, strlen($unzip_dir), strlen($fileFrom)));
  180. }
  181. // remove session entry
  182. if(isset($_SESSION['INSTALLED_LANG_PACKS']) && is_array($_SESSION['INSTALLED_LANG_PACKS'])) {
  183. foreach($_SESSION['INSTALLED_LANG_PACKS'] as $k => $langPack) {
  184. if($langPack == $zipFile) {
  185. unset($_SESSION['INSTALLED_LANG_PACKS'][$k]);
  186. unset($_SESSION['INSTALLED_LANG_PACKS_VERSION'][$k]);
  187. unset($_SESSION['INSTALLED_LANG_PACKS_MANIFEST'][$k]);
  188. $removedLang = $k;
  189. }
  190. }
  191. // remove language from config
  192. $new_langs = array();
  193. $old_langs = $sugar_config['languages'];
  194. foreach( $old_langs as $key => $value ){
  195. if( $key != $removedLang ){
  196. $new_langs += array( $key => $value );
  197. }
  198. }
  199. $sugar_config['languages'] = $new_langs;
  200. }
  201. } else {
  202. // copy filesFrom to filesTo
  203. foreach($filesFrom as $fileFrom) {
  204. @copy($fileFrom, getcwd().substr($fileFrom, strlen($unzip_dir), strlen($fileFrom)));
  205. }
  206. $_SESSION['INSTALLED_LANG_PACKS'][$new_lang_name] = $zipFile;
  207. $_SESSION['INSTALLED_LANG_PACKS_VERSION'][$new_lang_name] = $version;
  208. $serial_manifest = array();
  209. $serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
  210. $serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
  211. $serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
  212. $_SESSION['INSTALLED_LANG_PACKS_MANIFEST'][$new_lang_name] = base64_encode(serialize($serial_manifest));
  213. }
  214. writeSugarConfig($sugar_config);
  215. return $sugar_config;
  216. }
  217. function commitPatch($unlink = false, $type = 'patch'){
  218. require_once('ModuleInstall/ModuleInstaller.php');
  219. require_once('include/entryPoint.php');
  220. global $mod_strings;
  221. global $base_upgrade_dir;
  222. global $base_tmp_upgrade_dir;
  223. global $db;
  224. $GLOBALS['db'] = $db;
  225. $errors = array();
  226. $files = array();
  227. global $current_user;
  228. $current_user = new User();
  229. $current_user->is_admin = '1';
  230. $old_mod_strings = $mod_strings;
  231. if(is_dir($base_upgrade_dir)) {
  232. $files = findAllFiles("$base_upgrade_dir/$type", $files);
  233. $mi = new ModuleInstaller();
  234. $mi->silent = true;
  235. $mod_strings = return_module_language('en', "Administration");
  236. foreach($files as $file) {
  237. if(!preg_match('#.*\.zip\$#', $file)) {
  238. continue;
  239. }
  240. // handle manifest.php
  241. $target_manifest = remove_file_extension( $file ) . '-manifest.php';
  242. include($target_manifest);
  243. $unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
  244. unzip($file, $unzip_dir );
  245. if(file_exists("$unzip_dir/scripts/pre_install.php")){
  246. require_once("$unzip_dir/scripts/pre_install.php");
  247. pre_install();
  248. }
  249. if( isset( $manifest['copy_files']['from_dir'] ) && $manifest['copy_files']['from_dir'] != "" ){
  250. $zip_from_dir = $manifest['copy_files']['from_dir'];
  251. }
  252. $source = "$unzip_dir/$zip_from_dir";
  253. $dest = getcwd();
  254. copy_recursive($source, $dest);
  255. if(file_exists("$unzip_dir/scripts/post_install.php")){
  256. require_once("$unzip_dir/scripts/post_install.php");
  257. post_install();
  258. }
  259. $new_upgrade = new UpgradeHistory();
  260. $new_upgrade->filename = $file;
  261. $new_upgrade->md5sum = md5_file($file);
  262. $new_upgrade->type = $manifest['type'];
  263. $new_upgrade->version = $manifest['version'];
  264. $new_upgrade->status = "installed";
  265. //$new_upgrade->author = $manifest['author'];
  266. $new_upgrade->name = $manifest['name'];
  267. $new_upgrade->description = $manifest['description'];
  268. $serial_manifest = array();
  269. $serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
  270. $serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
  271. $serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
  272. $new_upgrade->manifest = base64_encode(serialize($serial_manifest));
  273. $new_upgrade->save();
  274. unlink($file);
  275. }//rof
  276. }//fi
  277. $mod_strings = $old_mod_strings;
  278. }
  279. function commitModules($unlink = false, $type = 'module'){
  280. require_once('ModuleInstall/ModuleInstaller.php');
  281. require_once('include/entryPoint.php');
  282. global $mod_strings;
  283. global $base_upgrade_dir;
  284. global $base_tmp_upgrade_dir;
  285. global $db;
  286. $GLOBALS['db'] = $db;
  287. $errors = array();
  288. $files = array();
  289. global $current_user;
  290. $current_user = new User();
  291. $current_user->is_admin = '1';
  292. $old_mod_strings = $mod_strings;
  293. if(is_dir(sugar_cached("upload/upgrades"))) {
  294. $files = findAllFiles(sugar_cached("upload/upgrades/$type"), $files);
  295. $mi = new ModuleInstaller();
  296. $mi->silent = true;
  297. $mod_strings = return_module_language('en', "Administration");
  298. foreach($files as $file) {
  299. if(!preg_match('#.*\.zip\$', $file)) {
  300. continue;
  301. }
  302. $lic_name = 'accept_lic_'.str_replace('.', '_', urlencode(basename($file)));
  303. $can_install = true;
  304. if(isset($_REQUEST[$lic_name])){
  305. if($_REQUEST[$lic_name] == 'yes'){
  306. $can_install = true;
  307. }else{
  308. $can_install = false;
  309. }
  310. }
  311. if($can_install){
  312. // handle manifest.php
  313. $target_manifest = remove_file_extension( $file ) . '-manifest.php';
  314. if($type == 'langpack'){
  315. $_REQUEST['manifest'] = $target_manifest;
  316. $_REQUEST['zipFile'] = $file;
  317. commitLanguagePack();
  318. continue;
  319. }
  320. include($target_manifest);
  321. $unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
  322. unzip($file, $unzip_dir );
  323. $_REQUEST['install_file'] = $file;
  324. $mi->install($unzip_dir);
  325. $new_upgrade = new UpgradeHistory();
  326. $new_upgrade->filename = $file;
  327. $new_upgrade->md5sum = md5_file($file);
  328. $new_upgrade->type = $manifest['type'];
  329. $new_upgrade->version = $manifest['version'];
  330. $new_upgrade->status = "installed";
  331. // $new_upgrade->author = $manifest['author'];
  332. $new_upgrade->name = $manifest['name'];
  333. $new_upgrade->description = $manifest['description'];
  334. $new_upgrade->id_name = (isset($installdefs['id_name'])) ? $installdefs['id_name'] : '';
  335. $serial_manifest = array();
  336. $serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
  337. $serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
  338. $serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
  339. $new_upgrade->manifest = base64_encode(serialize($serial_manifest));
  340. $new_upgrade->save();
  341. //unlink($file);
  342. }//fi
  343. }//rof
  344. }//fi
  345. $mod_strings = $old_mod_strings;
  346. }
  347. /**
  348. * creates UpgradeHistory entries
  349. * @param mode string Install or Uninstall
  350. */
  351. function updateUpgradeHistory() {
  352. if(isset($_SESSION['INSTALLED_LANG_PACKS']) && count($_SESSION['INSTALLED_LANG_PACKS']) > 0) {
  353. foreach($_SESSION['INSTALLED_LANG_PACKS'] as $k => $zipFile) {
  354. $new_upgrade = new UpgradeHistory();
  355. $new_upgrade->filename = $zipFile;
  356. $new_upgrade->md5sum = md5_file($zipFile);
  357. $new_upgrade->type = 'langpack';
  358. $new_upgrade->version = $_SESSION['INSTALLED_LANG_PACKS_VERSION'][$k];
  359. $new_upgrade->status = "installed";
  360. $new_upgrade->manifest = $_SESSION['INSTALLED_LANG_PACKS_MANIFEST'][$k];
  361. $new_upgrade->save();
  362. }
  363. }
  364. }
  365. /**
  366. * removes the installed language pack, but the zip is still in the cache dir
  367. */
  368. function removeLanguagePack() {
  369. global $mod_strings;
  370. global $sugar_config;
  371. $errors = array();
  372. $manifest = urldecode($_REQUEST['manifest']);
  373. $zipFile = urldecode($_REQUEST['zipFile']);
  374. if(isset($manifest) && !empty($manifest)) {
  375. if(is_file($manifest)) {
  376. if(!unlink($manifest)) {
  377. $errors[] = $mod_strings['ERR_LANG_CANNOT_DELETE_FILE'].$manifest;
  378. }
  379. } else {
  380. $errors[] = $mod_strings['ERR_LANG_MISSING_FILE'].$manifest;
  381. }
  382. unset($_SESSION['packages_to_install'][$manifest]);
  383. }
  384. if(isset($zipFile) && !empty($zipFile)) {
  385. if(is_file($zipFile)) {
  386. if(!unlink($zipFile)) {
  387. $errors[] = $mod_strings['ERR_LANG_CANNOT_DELETE_FILE'].$zipFile;
  388. }
  389. } else {
  390. $errors[] = $mod_strings['ERR_LANG_MISSING_FILE'].$zipFile;
  391. }
  392. }
  393. if(count($errors > 0)) {
  394. echo "<p class='error'>";
  395. foreach($errors as $error) {
  396. echo "{$error}<br>";
  397. }
  398. echo "</p>";
  399. }
  400. unlinkTempFiles($manifest, $zipFile);
  401. }
  402. /**
  403. * takes the current value of $sugar_config and writes it out to config.php (sorta the same as the final step)
  404. * @param array sugar_config
  405. */
  406. function writeSugarConfig($sugar_config) {
  407. ksort($sugar_config);
  408. $sugar_config_string = "<?php\n" .
  409. '// created: ' . date('Y-m-d H:i:s') . "\n" .
  410. '$sugar_config = ' .
  411. var_export($sugar_config, true) .
  412. ";\n?>\n";
  413. if(is_writable('config.php')) {
  414. write_array_to_file( "sugar_config", $sugar_config, "config.php");
  415. }
  416. }
  417. /**
  418. * uninstalls the Language pack
  419. */
  420. function uninstallLangPack() {
  421. global $sugar_config;
  422. // remove language from config
  423. $new_langs = array();
  424. $old_langs = $sugar_config['languages'];
  425. foreach( $old_langs as $key => $value ){
  426. if( $key != $_REQUEST['new_lang_name'] ){
  427. $new_langs += array( $key => $value );
  428. }
  429. }
  430. $sugar_config['languages'] = $new_langs;
  431. writeSugarConfig($sugar_config);
  432. }
  433. /**
  434. * retrieves the name of the language
  435. */
  436. if ( !function_exists('getLanguagePackName') ) {
  437. function getLanguagePackName($the_file) {
  438. require_once( "$the_file" );
  439. if( isset( $app_list_strings["language_pack_name"] ) ){
  440. return( $app_list_strings["language_pack_name"] );
  441. }
  442. return( "" );
  443. }
  444. }
  445. function getInstalledLangPacks($showButtons=true) {
  446. global $mod_strings;
  447. global $next_step;
  448. $ret = "<tr><td colspan=7 align=left>{$mod_strings['LBL_LANG_PACK_INSTALLED']}</td></tr>";
  449. //$ret .="<table width='100%' cellpadding='0' cellspacing='0' border='0'>";
  450. $ret .= "<tr>
  451. <td width='15%' ><b>{$mod_strings['LBL_ML_NAME']}</b></td>
  452. <td width='15%' ><b>{$mod_strings['LBL_ML_VERSION']}</b></td>
  453. <td width='15%' ><b>{$mod_strings['LBL_ML_PUBLISHED']}</b></td>
  454. <td width='15%' ><b>{$mod_strings['LBL_ML_UNINSTALLABLE']}</b></td>
  455. <td width='15%' ><b>{$mod_strings['LBL_ML_DESCRIPTION']}</b></td>
  456. <td width='15%' ></td>
  457. <td width='15%' ></td>
  458. </tr>\n";
  459. $files = array();
  460. $files = findAllFiles(sugar_cached("upload/upgrades"), $files);
  461. if(isset($_SESSION['INSTALLED_LANG_PACKS']) && !empty($_SESSION['INSTALLED_LANG_PACKS'])){
  462. if(count($_SESSION['INSTALLED_LANG_PACKS'] > 0)) {
  463. foreach($_SESSION['INSTALLED_LANG_PACKS'] as $file) {
  464. // handle manifest.php
  465. $target_manifest = remove_file_extension( $file ) . '-manifest.php';
  466. include($target_manifest);
  467. $name = empty($manifest['name']) ? $file : $manifest['name'];
  468. $version = empty($manifest['version']) ? '' : $manifest['version'];
  469. $published_date = empty($manifest['published_date']) ? '' : $manifest['published_date'];
  470. $icon = '';
  471. $description = empty($manifest['description']) ? 'None' : $manifest['description'];
  472. $uninstallable = empty($manifest['is_uninstallable']) ? 'No' : 'Yes';
  473. $manifest_type = $manifest['type'];
  474. $deletePackage = getPackButton('uninstall', $target_manifest, $file, $next_step, $uninstallable, $showButtons);
  475. //$ret .="<table width='100%' cellpadding='0' cellspacing='0' border='0'>";
  476. $ret .= "<tr>";
  477. $ret .= "<td width='15%' >".$name."</td>";
  478. $ret .= "<td width='15%' >".$version."</td>";
  479. $ret .= "<td width='15%' >".$published_date."</td>";
  480. $ret .= "<td width='15%' >".$uninstallable."</td>";
  481. $ret .= "<td width='15%' >".$description."</td>";
  482. $ret .= "<td width='15%' ></td>";
  483. $ret .= "<td width='15%' >{$deletePackage}</td>";
  484. $ret .= "</tr>";
  485. }
  486. } else {
  487. $ret .= "</tr><td colspan=7><i>{$mod_strings['LBL_LANG_NO_PACKS']}</i></td></tr>";
  488. }
  489. } else {
  490. $ret .= "</tr><td colspan=7><i>{$mod_strings['LBL_LANG_NO_PACKS']}</i></td></tr>";
  491. }
  492. return $ret;
  493. }
  494. function uninstallLanguagePack() {
  495. return commitLanguagePack(true);
  496. }
  497. function getSugarConfigLanguageArray($langZip) {
  498. global $sugar_config;
  499. include(remove_file_extension($langZip)."-manifest.php");
  500. $ret = '';
  501. if(isset($installdefs['id']) && isset($manifest['name'])) {
  502. $ret = $installdefs['id']."::".$manifest['name']."::".$manifest['version'];
  503. }
  504. return $ret;
  505. }
  506. ///////////////////////////////////////////////////////////////////////////////
  507. //// FROM performSetup.php
  508. function getInstallDbInstance()
  509. {
  510. return DBManagerFactory::getTypeInstance($_SESSION['setup_db_type'], array("db_manager" => $_SESSION['setup_db_manager']));
  511. }
  512. function getDbConnection()
  513. {
  514. $dbconfig = array(
  515. "db_host_name" => $_SESSION['setup_db_host_name'],
  516. "db_user_name" => $_SESSION['setup_db_admin_user_name'],
  517. "db_password" => $_SESSION['setup_db_admin_password'],
  518. "db_host_instance" => $_SESSION['setup_db_host_instance'],
  519. "db_port" => $_SESSION['setup_db_port_num'],
  520. );
  521. if(empty($_SESSION['setup_db_create_database'])) {
  522. $dbconfig["db_name"] = $_SESSION['setup_db_database_name'];
  523. }
  524. $db = getInstallDbInstance();
  525. if(!empty($_SESSION['setup_db_options'])) {
  526. $db->setOptions($_SESSION['setup_db_options']);
  527. }
  528. $db->connect($dbconfig, true);
  529. return $db;
  530. }
  531. /**
  532. * creates the Sugar DB user (if not admin)
  533. */
  534. function handleDbCreateSugarUser() {
  535. global $mod_strings;
  536. global $setup_db_database_name;
  537. global $setup_db_host_name;
  538. global $setup_db_host_instance;
  539. global $setup_db_port_num;
  540. global $setup_db_admin_user_name;
  541. global $setup_db_admin_password;
  542. global $sugar_config;
  543. global $setup_db_sugarsales_user;
  544. global $setup_site_host_name;
  545. global $setup_db_sugarsales_password;
  546. echo $mod_strings['LBL_PERFORM_CREATE_DB_USER'];
  547. $db = getDbConnection();
  548. $db->createDbUser($setup_db_database_name, $setup_site_host_name, $setup_db_sugarsales_user, $setup_db_sugarsales_password);
  549. $err = $db->lastError();
  550. if($err == '') {
  551. echo $mod_strings['LBL_PERFORM_DONE'];
  552. } else {
  553. echo "<div style='color:red;'>";
  554. echo "An error occured when creating user:<br>";
  555. echo "$err<br>";
  556. echo "</div>";
  557. installLog("An error occured when creating user: $err");
  558. }
  559. }
  560. /**
  561. * ensures that the charset and collation for a given database is set
  562. * MYSQL ONLY
  563. */
  564. function handleDbCharsetCollation() {
  565. global $mod_strings;
  566. global $setup_db_database_name;
  567. global $setup_db_host_name;
  568. global $setup_db_admin_user_name;
  569. global $setup_db_admin_password;
  570. global $sugar_config;
  571. if($_SESSION['setup_db_type'] == 'mysql') {
  572. $db = getDbConnection();
  573. $db->query("ALTER DATABASE `{$setup_db_database_name}` DEFAULT CHARACTER SET utf8", true);
  574. $db->query("ALTER DATABASE `{$setup_db_database_name}` DEFAULT COLLATE utf8_general_ci", true);
  575. }
  576. }
  577. /**
  578. * creates the new database
  579. */
  580. function handleDbCreateDatabase() {
  581. global $mod_strings;
  582. global $setup_db_database_name;
  583. global $setup_db_host_name;
  584. global $setup_db_host_instance;
  585. global $setup_db_port_num;
  586. global $setup_db_admin_user_name;
  587. global $setup_db_admin_password;
  588. global $sugar_config;
  589. echo "{$mod_strings['LBL_PERFORM_CREATE_DB_1']} {$setup_db_database_name} {$mod_strings['LBL_PERFORM_CREATE_DB_2']} {$setup_db_host_name}...";
  590. $db = getDbConnection();
  591. if($db->dbExists($setup_db_database_name)) {
  592. $db->dropDatabase($setup_db_database_name);
  593. }
  594. $db->createDatabase($setup_db_database_name);
  595. echo $mod_strings['LBL_PERFORM_DONE'];
  596. }
  597. /**
  598. * handles creation of Log4PHP properties file
  599. * This function has been deprecated. Use SugarLogger.
  600. */
  601. function handleLog4Php() {
  602. return;
  603. }
  604. function installLog($entry) {
  605. global $mod_strings;
  606. $nl = '
  607. '.gmdate("Y-m-d H:i:s").'...';
  608. $log = clean_path(getcwd().'/install.log');
  609. // create if not exists
  610. if(!file_exists($log)) {
  611. $fp = @sugar_fopen($log, 'w+'); // attempts to create file
  612. if(!is_resource($fp)) {
  613. $GLOBALS['log']->fatal('could not create the install.log file');
  614. }
  615. } else {
  616. $fp = @sugar_fopen($log, 'a+'); // write pointer at end of file
  617. if(!is_resource($fp)) {
  618. $GLOBALS['log']->fatal('could not open/lock install.log file');
  619. }
  620. }
  621. if(@fwrite($fp, $nl.$entry) === false) {
  622. $GLOBALS['log']->fatal('could not write to install.log: '.$entry);
  623. }
  624. if(is_resource($fp)) {
  625. fclose($fp);
  626. }
  627. }
  628. /**
  629. * takes session vars and creates config.php
  630. * @return array bottle collection of error messages
  631. */
  632. function handleSugarConfig() {
  633. global $bottle;
  634. global $cache_dir;
  635. global $mod_strings;
  636. global $setup_db_host_name;
  637. global $setup_db_host_instance;
  638. global $setup_db_port_num;
  639. global $setup_db_sugarsales_user;
  640. global $setup_db_sugarsales_password;
  641. global $setup_db_database_name;
  642. global $setup_site_host_name;
  643. global $setup_site_log_dir;
  644. global $setup_site_log_file;
  645. global $setup_site_session_path;
  646. global $setup_site_guid;
  647. global $setup_site_url;
  648. global $setup_sugar_version;
  649. global $sugar_config;
  650. global $setup_site_log_level;
  651. echo "<b>{$mod_strings['LBL_PERFORM_CONFIG_PHP']} (config.php)</b><br>";
  652. ///////////////////////////////////////////////////////////////////////////////
  653. //// $sugar_config SETTINGS
  654. if( is_file('config.php') ){
  655. $is_writable = is_writable('config.php');
  656. // require is needed here (config.php is sometimes require'd from install.php)
  657. require('config.php');
  658. } else {
  659. $is_writable = is_writable('.');
  660. }
  661. // build default sugar_config and merge with new values
  662. $sugar_config = sugarArrayMerge(get_sugar_config_defaults(), $sugar_config);
  663. // always lock the installer
  664. $sugar_config['installer_locked'] = true;
  665. // we're setting these since the user was given a fair chance to change them
  666. $sugar_config['dbconfig']['db_host_name'] = $setup_db_host_name;
  667. if(!empty($setup_db_host_instance)) {
  668. $sugar_config['dbconfig']['db_host_instance'] = $setup_db_host_instance;
  669. } else {
  670. $sugar_config['dbconfig']['db_host_instance'] = '';
  671. }
  672. if(!isset($_SESSION['setup_db_manager'])) {
  673. $_SESSION['setup_db_manager'] = DBManagerFactory::getManagerByType($_SESSION['setup_db_type']);
  674. }
  675. $sugar_config['dbconfig']['db_user_name'] = $setup_db_sugarsales_user;
  676. $sugar_config['dbconfig']['db_password'] = $setup_db_sugarsales_password;
  677. $sugar_config['dbconfig']['db_name'] = $setup_db_database_name;
  678. $sugar_config['dbconfig']['db_type'] = $_SESSION['setup_db_type'];
  679. $sugar_config['dbconfig']['db_port'] = $setup_db_port_num;
  680. $sugar_config['dbconfig']['db_manager'] = $_SESSION['setup_db_manager'];
  681. if(!empty($_SESSION['setup_db_options'])) {
  682. $sugar_config['dbconfigoption'] = array_merge($sugar_config['dbconfigoption'], $_SESSION['setup_db_options']);
  683. }
  684. $sugar_config['cache_dir'] = $cache_dir;
  685. $sugar_config['default_charset'] = $mod_strings['DEFAULT_CHARSET'];
  686. $sugar_config['default_email_client'] = 'sugar';
  687. $sugar_config['default_email_editor'] = 'html';
  688. $sugar_config['host_name'] = $setup_site_host_name;
  689. $sugar_config['js_custom_version'] = '';
  690. $sugar_config['use_real_names'] = true;
  691. $sugar_config['disable_convert_lead'] = false;
  692. $sugar_config['log_dir'] = $setup_site_log_dir;
  693. $sugar_config['log_file'] = $setup_site_log_file;
  694. //Setup FTS
  695. if(!empty($_SESSION['fts_type']))
  696. $sugar_config['full_text_engine'] = array($_SESSION['fts_type'] => array('host'=> $_SESSION['fts_host'], 'port' => $_SESSION['fts_port']));
  697. // for silent install
  698. if(!empty($_SESSION['setup_fts_type']))
  699. {
  700. $sugar_config['full_text_engine'] = array($_SESSION['setup_fts_type'] => array('host'=> $_SESSION['setup_fts_host'], 'port' => $_SESSION['setup_fts_port']));
  701. if (isset($_SESSION['setup_fts_hide_config']))
  702. {
  703. $sugar_config['hide_full_text_engine_config'] = $_SESSION['setup_fts_hide_config'];
  704. }
  705. }
  706. /*nsingh(bug 22402): Consolidate logger settings under $config['logger'] as liked by the new logger! If log4pphp exists,
  707. these settings will be overwritten by those in log4php.properties when the user access admin->system settings.*/
  708. $sugar_config['logger'] =
  709. array ('level'=>$setup_site_log_level,
  710. 'file' => array(
  711. 'ext' => '.log',
  712. 'name' => 'sugarcrm',
  713. 'dateFormat' => '%c',
  714. 'maxSize' => '10MB',
  715. 'maxLogs' => 10,
  716. 'suffix' => ''), // bug51583, change default suffix to blank for backwards comptability
  717. );
  718. $sugar_config['session_dir'] = $setup_site_session_path;
  719. $sugar_config['site_url'] = $setup_site_url;
  720. $sugar_config['sugar_version'] = $setup_sugar_version;
  721. $sugar_config['tmp_dir'] = $cache_dir.'xml/';
  722. $sugar_config['upload_dir'] = 'upload/';
  723. // $sugar_config['use_php_code_json'] = returnPhpJsonStatus(); // true on error
  724. if( isset($_SESSION['setup_site_sugarbeet_anonymous_stats']) ){
  725. $sugar_config['sugarbeet'] = $_SESSION['setup_site_sugarbeet_anonymous_stats'];
  726. }
  727. $sugar_config['demoData'] = $_SESSION['demoData'];
  728. if( isset( $setup_site_guid ) ){
  729. $sugar_config['unique_key'] = $setup_site_guid;
  730. }
  731. if(empty($sugar_config['unique_key'])){
  732. $sugar_config['unique_key'] = md5( create_guid() );
  733. }
  734. // add installed langs to config
  735. // entry in upgrade_history comes AFTER table creation
  736. if(isset($_SESSION['INSTALLED_LANG_PACKS']) && is_array($_SESSION['INSTALLED_LANG_PACKS']) && !empty($_SESSION['INSTALLED_LANG_PACKS'])) {
  737. foreach($_SESSION['INSTALLED_LANG_PACKS'] as $langZip) {
  738. $lang = getSugarConfigLanguageArray($langZip);
  739. if(!empty($lang)) {
  740. $exLang = explode('::', $lang);
  741. if(is_array($exLang) && count($exLang) == 3) {
  742. $sugar_config['languages'][$exLang[0]] = $exLang[1];
  743. }
  744. }
  745. }
  746. }
  747. if(file_exists('install/lang.config.php')){
  748. include('install/lang.config.php');
  749. if(!empty($config['languages'])){
  750. foreach($config['languages'] as $lang=>$label){
  751. $sugar_config['languages'][$lang] = $label;
  752. }
  753. }
  754. }
  755. ksort($sugar_config);
  756. $sugar_config_string = "<?php\n" .
  757. '// created: ' . date('Y-m-d H:i:s') . "\n" .
  758. '$sugar_config = ' .
  759. var_export($sugar_config, true) .
  760. ";\n?>\n";
  761. if($is_writable && write_array_to_file( "sugar_config", $sugar_config, "config.php")) {
  762. // was 'Done'
  763. } else {
  764. echo 'failed<br>';
  765. echo "<p>{$mod_strings['ERR_PERFORM_CONFIG_PHP_1']}</p>\n";
  766. echo "<p>{$mod_strings['ERR_PERFORM_CONFIG_PHP_2']}</p>\n";
  767. echo "<TEXTAREA rows=\"15\" cols=\"80\">".$sugar_config_string."</TEXTAREA>";
  768. echo "<p>{$mod_strings['ERR_PERFORM_CONFIG_PHP_3']}</p>";
  769. $bottle[] = $mod_strings['ERR_PERFORM_CONFIG_PHP_4'];
  770. }
  771. //Now merge the config_si.php settings into config.php
  772. if(file_exists('config.php') && file_exists('config_si.php'))
  773. {
  774. require_once('modules/UpgradeWizard/uw_utils.php');
  775. merge_config_si_settings(false, 'config.php', 'config_si.php');
  776. }
  777. //// END $sugar_config
  778. ///////////////////////////////////////////////////////////////////////////////
  779. return $bottle;
  780. }
  781. /**
  782. * (re)write the .htaccess file to prevent browser access to the log file
  783. */
  784. function handleHtaccess(){
  785. global $mod_strings;
  786. $ignoreCase = (substr_count(strtolower($_SERVER['SERVER_SOFTWARE']), 'apache/2') > 0)?'(?i)':'';
  787. $htaccess_file = ".htaccess";
  788. $contents = '';
  789. $restrict_str = <<<EOQ
  790. # BEGIN SUGARCRM RESTRICTIONS
  791. EOQ;
  792. if (ini_get('suhosin.perdir') !== false && strpos(ini_get('suhosin.perdir'), 'e') !== false)
  793. {
  794. $restrict_str .= "php_value suhosin.executor.include.whitelist upload\n";
  795. }
  796. $restrict_str .= <<<EOQ
  797. RedirectMatch 403 {$ignoreCase}.*\.log$
  798. RedirectMatch 403 {$ignoreCase}/+not_imported_.*\.txt
  799. RedirectMatch 403 {$ignoreCase}/+(soap|cache|xtemplate|data|examples|include|log4php|metadata|modules)/+.*\.(php|tpl)
  800. RedirectMatch 403 {$ignoreCase}/+emailmandelivery\.php
  801. RedirectMatch 403 {$ignoreCase}/+upload
  802. RedirectMatch 403 {$ignoreCase}/+custom/+blowfish
  803. RedirectMatch 403 {$ignoreCase}/+cache/+diagnostic
  804. RedirectMatch 403 {$ignoreCase}/+files\.md5$
  805. # END SUGARCRM RESTRICTIONS
  806. EOQ;
  807. $cache_headers = <<<EOQ
  808. <FilesMatch "\.(jpg|png|gif|js|css|ico)$">
  809. <IfModule mod_headers.c>
  810. Header set ETag ""
  811. Header set Cache-Control "max-age=2592000"
  812. Header set Expires "01 Jan 2112 00:00:00 GMT"
  813. </IfModule>
  814. </FilesMatch>
  815. <IfModule mod_expires.c>
  816. ExpiresByType text/css "access plus 1 month"
  817. ExpiresByType text/javascript "access plus 1 month"
  818. ExpiresByType application/x-javascript "access plus 1 month"
  819. ExpiresByType image/gif "access plus 1 month"
  820. ExpiresByType image/jpg "access plus 1 month"
  821. ExpiresByType image/png "access plus 1 month"
  822. </IfModule>
  823. EOQ;
  824. if(file_exists($htaccess_file)){
  825. $fp = fopen($htaccess_file, 'r');
  826. $skip = false;
  827. while($line = fgets($fp)){
  828. if(preg_match("/\s*#\s*BEGIN\s*SUGARCRM\s*RESTRICTIONS/i", $line))$skip = true;
  829. if(!$skip)$contents .= $line;
  830. if(preg_match("/\s*#\s*END\s*SUGARCRM\s*RESTRICTIONS/i", $line))$skip = false;
  831. }
  832. }
  833. $status = file_put_contents($htaccess_file, $contents . $restrict_str . $cache_headers);
  834. if( !$status ) {
  835. echo "<p>{$mod_strings['ERR_PERFORM_HTACCESS_1']}<span class=stop>{$htaccess_file}</span> {$mod_strings['ERR_PERFORM_HTACCESS_2']}</p>\n";
  836. echo "<p>{$mod_strings['ERR_PERFORM_HTACCESS_3']}</p>\n";
  837. echo $restrict_str;
  838. }
  839. return $status;
  840. }
  841. /**
  842. * (re)write the web.config file to prevent browser access to the log file
  843. */
  844. function handleWebConfig()
  845. {
  846. if ( !isset($_SERVER['IIS_UrlRewriteModule']) ) {
  847. return;
  848. }
  849. global $setup_site_log_dir;
  850. global $setup_site_log_file;
  851. global $sugar_config;
  852. // Bug 36968 - Fallback to using $sugar_config values when we are not calling this from the installer
  853. if (empty($setup_site_log_file)) {
  854. $setup_site_log_file = $sugar_config['log_file'];
  855. if ( empty($sugar_config['log_file']) ) {
  856. $setup_site_log_file = 'sugarcrm.log';
  857. }
  858. }
  859. if (empty($setup_site_log_dir)) {
  860. $setup_site_log_dir = $sugar_config['log_dir'];
  861. if ( empty($sugar_config['log_dir']) ) {
  862. $setup_site_log_dir = '.';
  863. }
  864. }
  865. $prefix = $setup_site_log_dir.empty($setup_site_log_dir)?'':'/';
  866. $config_array = array(
  867. array('1'=> $prefix.str_replace('.','\\.',$setup_site_log_file).'\\.*' ,'2'=>'log_file_restricted.html'),
  868. array('1'=> $prefix.'install.log' ,'2'=>'log_file_restricted.html'),
  869. array('1'=> $prefix.'upgradeWizard.log' ,'2'=>'log_file_restricted.html'),
  870. array('1'=> $prefix.'emailman.log' ,'2'=>'log_file_restricted.html'),
  871. array('1'=>'not_imported_.*.txt' ,'2'=>'log_file_restricted.html'),
  872. array('1'=>'XTemplate/(.*)/(.*).php' ,'2'=>'index.php'),
  873. array('1'=>'data/(.*).php' ,'2'=>'index.php'),
  874. array('1'=>'examples/(.*).php' ,'2'=>'index.php'),
  875. array('1'=>'include/(.*).php' ,'2'=>'index.php'),
  876. array('1'=>'include/(.*)/(.*).php' ,'2'=>'index.php'),
  877. array('1'=>'log4php/(.*).php' ,'2'=>'index.php'),
  878. array('1'=>'log4php/(.*)/(.*)' ,'2'=>'index.php'),
  879. array('1'=>'metadata/(.*)/(.*).php' ,'2'=>'index.php'),
  880. array('1'=>'modules/(.*)/(.*).php' ,'2'=>'index.php'),
  881. array('1'=>'soap/(.*).php' ,'2'=>'index.php'),
  882. array('1'=>'emailmandelivery.php' ,'2'=>'index.php'),
  883. array('1'=>'cron.php' ,'2'=>'index.php'),
  884. array('1'=> $sugar_config['upload_dir'].'.*' ,'2'=>'index.php'),
  885. );
  886. $xmldoc = new XMLWriter();
  887. $xmldoc->openURI('web.config');
  888. $xmldoc->setIndent(true);
  889. $xmldoc->setIndentString(' ');
  890. $xmldoc->startDocument('1.0','UTF-8');
  891. $xmldoc->startElement('configuration');
  892. $xmldoc->startElement('system.webServer');
  893. $xmldoc->startElement('rewrite');
  894. $xmldoc->startElement('rules');
  895. for ($i = 0; $i < count($config_array); $i++) {
  896. $xmldoc->startElement('rule');
  897. $xmldoc->writeAttribute('name', "redirect$i");
  898. $xmldoc->writeAttribute('stopProcessing', 'true');
  899. $xmldoc->startElement('match');
  900. $xmldoc->writeAttribute('url', $config_array[$i]['1']);
  901. $xmldoc->endElement();
  902. $xmldoc->startElement('action');
  903. $xmldoc->writeAttribute('type', 'Redirect');
  904. $xmldoc->writeAttribute('url', $config_array[$i]['2']);
  905. $xmldoc->writeAttribute('redirectType', 'Found');
  906. $xmldoc->endElement();
  907. $xmldoc->endElement();
  908. }
  909. $xmldoc->endElement();
  910. $xmldoc->endElement();
  911. $xmldoc->startElement('caching');
  912. $xmldoc->startElement('profiles');
  913. $xmldoc->startElement('remove');
  914. $xmldoc->writeAttribute('extension', ".php");
  915. $xmldoc->endElement();
  916. $xmldoc->endElement();
  917. $xmldoc->endElement();
  918. $xmldoc->startElement('staticContent');
  919. $xmldoc->startElement("clientCache");
  920. $xmldoc->writeAttribute('cacheControlMode', 'UseMaxAge');
  921. $xmldoc->writeAttribute('cacheControlMaxAge', '30.00:00:00');
  922. $xmldoc->endElement();
  923. $xmldoc->endElement();
  924. $xmldoc->endElement();
  925. $xmldoc->endElement();
  926. $xmldoc->endDocument();
  927. $xmldoc->flush();
  928. }
  929. /**
  930. * Drop old tables if table exists and told to drop it
  931. */
  932. function drop_table_install( &$focus ){
  933. global $db;
  934. global $dictionary;
  935. $result = $db->tableExists($focus->table_name);
  936. if( $result ){
  937. $focus->drop_tables();
  938. $GLOBALS['log']->info("Dropped old ".$focus->table_name." table.");
  939. return 1;
  940. }
  941. else {
  942. $GLOBALS['log']->info("Did not need to drop old ".$focus->table_name." table. It doesn't exist.");
  943. return 0;
  944. }
  945. }
  946. // Creating new tables if they don't exist.
  947. function create_table_if_not_exist( &$focus ){
  948. global $db;
  949. $table_created = false;
  950. // normal code follows
  951. $result = $db->tableExists($focus->table_name);
  952. if($result){
  953. $GLOBALS['log']->info("Table ".$focus->table_name." already exists.");
  954. } else {
  955. $focus->create_tables();
  956. $GLOBALS['log']->info("Created ".$focus->table_name." table.");
  957. $table_created = true;
  958. }
  959. return $table_created;
  960. }
  961. function create_default_users(){
  962. global $db;
  963. global $setup_site_admin_password;
  964. global $setup_site_admin_user_name;
  965. global $create_default_user;
  966. global $sugar_config;
  967. require_once('install/UserDemoData.php');
  968. //Create default admin user
  969. $user = new User();
  970. $user->id = 1;
  971. $user->new_with_id = true;
  972. $user->last_name = 'Administrator';
  973. $user->user_name = $setup_site_admin_user_name;
  974. $user->title = "Administrator";
  975. $user->status = 'Active';
  976. $user->is_admin = true;
  977. $user->employee_status = 'Active';
  978. $user->user_hash = User::getPasswordHash($setup_site_admin_password);
  979. $user->email = '';
  980. $user->picture = UserDemoData::_copy_user_image($user->id);
  981. $user->save();
  982. //Bug#53793: Keep default current user in the global variable in order to store 'created_by' info as default user
  983. // while installation is proceed.
  984. $GLOBALS['current_user'] = $user;
  985. if( $create_default_user ){
  986. $default_user = new User();
  987. $default_user->last_name = $sugar_config['default_user_name'];
  988. $default_user->user_name = $sugar_config['default_user_name'];
  989. $default_user->status = 'Active';
  990. if( isset($sugar_config['default_user_is_admin']) && $sugar_config['default_user_is_admin'] ){
  991. $default_user->is_admin = true;
  992. }
  993. $default_user->user_hash = User::getPasswordHash($sugar_config['default_password']);
  994. $default_user->save();
  995. }
  996. }
  997. function set_admin_password( $password ) {
  998. global $db;
  999. $user_hash = User::getPasswordHash($password);
  1000. $query = "update users set user_hash='$user_hash' where id='1'";
  1001. $db->query($query);
  1002. }
  1003. function insert_default_settings(){
  1004. global $db;
  1005. global $setup_sugar_version;
  1006. global $sugar_db_version;
  1007. $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'fromaddress', 'do_not_reply@example.com')");
  1008. $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'fromname', 'SugarCRM')");
  1009. $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'send_by_default', '1')");
  1010. $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'on', '1')");
  1011. $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'send_from_assigning_user', '0')");
  1012. /* cn: moved to OutboundEmail class
  1013. $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpserver', 'localhost')");
  1014. $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpport', '25')");
  1015. $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'sendtype', 'smtp')");
  1016. $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpuser', '')");
  1017. $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtppass', '')");
  1018. $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpauth_req', '0')");
  1019. */
  1020. $db->query("INSERT INTO config (category, name, value) VALUES ('info', 'sugar_version', '" . $sugar_db_version . "')");
  1021. $db->query("INSERT INTO config (category, name, value) VALUES ('MySettings', 'tab', '')");
  1022. $db->query("INSERT INTO config (category, name, value) VALUES ('portal', 'on', '0')");
  1023. //insert default tracker settings
  1024. $db->query("INSERT INTO config (category, name, value) VALUES ('tracker', 'Tracker', '1')");
  1025. $db->query( "INSERT INTO config (category, name, value) VALUES ( 'system', 'skypeout_on', '1')" );
  1026. }
  1027. // Returns true if the given file/dir has been made writable (or is already
  1028. // writable).
  1029. function make_writable($file)
  1030. {
  1031. $ret_val = false;
  1032. if(is_file($file) || is_dir($file))
  1033. {
  1034. if(is_writable($file))
  1035. {
  1036. $ret_val = true;
  1037. }
  1038. else
  1039. {
  1040. $original_fileperms = fileperms($file);
  1041. // add user writable permission
  1042. $new_fileperms = $original_fileperms | 0x0080;
  1043. @sugar_chmod($file, $new_fileperms);
  1044. clearstatcache();
  1045. if(is_writable($file))
  1046. {
  1047. $ret_val = true;
  1048. }
  1049. else
  1050. {
  1051. // add group writable permission
  1052. $new_fileperms = $original_fileperms | 0x0010;
  1053. @chmod($file, $new_fileperms);
  1054. clearstatcache();
  1055. if(is_writable($file))
  1056. {
  1057. $ret_val = true;
  1058. }
  1059. else
  1060. {
  1061. // add world writable permission
  1062. $new_fileperms = $original_fileperms | 0x0002;
  1063. @chmod($file, $new_fileperms);
  1064. clearstatcache();
  1065. if(is_writable($file))
  1066. {
  1067. $ret_val = true;
  1068. }
  1069. }
  1070. }
  1071. }
  1072. }
  1073. return $ret_val;
  1074. }
  1075. function recursive_make_writable($start_file)
  1076. {
  1077. $ret_val = make_writable($start_file);
  1078. if($ret_val && is_dir($start_file))
  1079. {
  1080. // PHP 4 alternative to scandir()
  1081. $files = array();
  1082. $dh = opendir($start_file);
  1083. $filename = readdir($dh);
  1084. while(!empty($filename))
  1085. {
  1086. if($filename != '.' && $filename != '..' && $filename != '.svn')
  1087. {
  1088. $files[] = $filename;
  1089. }
  1090. $filename = readdir($dh);
  1091. }
  1092. foreach($files as $file)
  1093. {
  1094. $ret_val = recursive_make_writable($start_file . '/' . $file);
  1095. if(!$ret_val)
  1096. {
  1097. $_SESSION['unwriteable_module_files'][dirname($file)] = dirname($file);
  1098. $fnl_ret_val = false;
  1099. //break;
  1100. }
  1101. }
  1102. }
  1103. if(!$ret_val)
  1104. {
  1105. $unwriteable_directory = is_dir($start_file) ? $start_file : dirname($start_file);
  1106. if($unwriteable_directory[0] == '.'){$unwriteable_directory = substr($unwriteable_directory,1);}
  1107. $_SESSION['unwriteable_module_files'][$unwriteable_directory] = $unwriteable_directory;
  1108. $_SESSION['unwriteable_module_files']['failed'] = true;
  1109. }
  1110. return $ret_val;
  1111. }
  1112. function recursive_is_writable($start_file)
  1113. {
  1114. $ret_val = is_writable($start_file);
  1115. if($ret_val && is_dir($start_file))
  1116. {
  1117. // PHP 4 alternative to scandir()
  1118. $files = array();
  1119. $dh = opendir($start_file);
  1120. $filename = readdir($dh);
  1121. while(!empty($filename))
  1122. {
  1123. if($filename != '.' && $filename != '..' && $filename != '.svn')
  1124. {
  1125. $files[] = $filename;
  1126. }
  1127. $filename = readdir($dh);
  1128. }
  1129. foreach($files as $file)
  1130. {
  1131. $ret_val = recursive_is_writable($start_file . '/' . $file);
  1132. if(!$ret_val)
  1133. {
  1134. break;
  1135. }
  1136. }
  1137. }
  1138. return $ret_val;
  1139. }
  1140. // one place for form validation/conversion to boolean
  1141. function get_boolean_from_request( $field ){
  1142. if( !isset($_REQUEST[$field]) ){
  1143. return( false );
  1144. }
  1145. if( ($_REQUEST[$field] == 'on') || ($_REQUEST[$field] == 'yes') ){
  1146. return(true);
  1147. }
  1148. else {
  1149. return(false);
  1150. }
  1151. }
  1152. function stripslashes_checkstrings($value){
  1153. if(is_string($value)){
  1154. return stripslashes($value);
  1155. }
  1156. return $value;
  1157. }
  1158. function print_debug_array( $name, $debug_array ){
  1159. ksort( $debug_array );
  1160. print( "$name vars:\n" );
  1161. print( "(\n" );
  1162. foreach( $debug_array as $key => $value ){
  1163. if( stristr( $key, "password" ) ){
  1164. $value = "WAS SET";
  1165. }
  1166. print( " [$key] => $value\n" );
  1167. }
  1168. print( ")\n" );
  1169. }
  1170. function print_debug_comment(){
  1171. if( !empty($_REQUEST['debug']) ){
  1172. $_SESSION['debug'] = $_REQUEST['debug'];
  1173. }
  1174. if( !empty($_SESSION['debug']) && ($_SESSION['debug'] == 'true') ){
  1175. print( "<!-- debug is on (to turn off, hit any page with 'debug=false' as a URL parameter.\n" );
  1176. print_debug_array( "Session", $_SESSION );
  1177. print_debug_array( "Request", $_REQUEST );
  1178. print_debug_array( "Post", $_POST );
  1179. print_debug_array( "Get", $_GET );
  1180. print_r( "-->\n" );
  1181. }
  1182. }
  1183. function validate_systemOptions() {
  1184. global $mod_strings;
  1185. $errors = array();
  1186. if(!empty($_SESSION['setup_db_type']) && trim($_SESSION['setup_db_type']) != '') {
  1187. $db = DBManagerFactory::getTypeInstance($_SESSION['setup_db_type']);
  1188. if(!empty($db)) {
  1189. $_SESSION['setup_db_manager'] = get_class($db);
  1190. return $errors;
  1191. }
  1192. }
  1193. $errors[] = "<span class='error'>".$mod_strings['ERR_DB_INVALID']."</span>";
  1194. return $errors;
  1195. }
  1196. function validate_dbConfig() {
  1197. global $mod_strings;
  1198. require_once('install/checkDBSettings.php');
  1199. return checkDBSettings(true);
  1200. }
  1201. function validate_siteConfig($type){
  1202. global $mod_strings;
  1203. $errors = array();
  1204. if($type=='a'){
  1205. if(empty($_SESSION['setup_system_name'])){
  1206. $errors[] = "<span class='error'>".$mod_strings['LBL_REQUIRED_SYSTEM_NAME']."</span>";
  1207. }
  1208. if($_SESSION['setup_site_url'] == ''){
  1209. $errors[] = "<span class='error'>".$mod_strings['ERR_URL_BLANK']."</span>";
  1210. }
  1211. if($_SESSION['setup_site_admin_user_name'] == '') {
  1212. $errors[] = "<span class='error'>".$mod_strings['ERR_ADMIN_USER_NAME_BLANK']."</span>";
  1213. }
  1214. if($_SESSION['setup_site_admin_password'] == ''){
  1215. $errors[] = "<span class='error'>".$mod_strings['ERR_ADMIN_PASS_BLANK']."</span>";
  1216. }
  1217. if($_SESSION['setup_site_admin_password'] != $_SESSION['setup_site_admin_password_retype']){
  1218. $errors[] = "<span class='error'>".$mod_strings['ERR_PASSWORD_MISMATCH']."</span>";
  1219. }
  1220. }else{
  1221. if(!empty($_SESSION['setup_site_custom_session_path']) && $_SESSION['setup_site_session_path'] == ''){
  1222. $errors[] = "<span class='error'>".$mod_strings['ERR_SESSION_PATH']."</span>";
  1223. }
  1224. if(!empty($_SESSION['setup_site_custom_session_path']) && $_SESSION['setup_site_session_path'] != ''){
  1225. if(is_dir($_SESSION['setup_site_session_path'])){
  1226. if(!is_writable($_SESSION['setup_site_session_path'])){
  1227. $errors[] = "<span class='error'>".$mod_strings['ERR_SESSION_DIRECTORY']."</span>";
  1228. }
  1229. }
  1230. else {
  1231. $errors[] = "<span class='error'>".$mod_strings['ERR_SESSION_DIRECTORY_NOT_EXISTS']."</span>";
  1232. }
  1233. }
  1234. if(!empty($_SESSION['setup_site_custom_log_dir']) && $_SESSION['setup_site_log_dir'] == ''){
  1235. $errors[] = "<span class='error'>".$mod_strings['ERR_LOG_DIRECTORY_NOT_EXISTS']."</span>";
  1236. }
  1237. if(!empty($_SESSION['setup_site_custom_log_dir']) && $_SESSION['setup_site_log_dir'] != ''){
  1238. if(is_dir($_SESSION['setup_site_log_dir'])){
  1239. if(!is_writable($_SESSION['setup_site_log_dir'])) {
  1240. $errors[] = "<span class='error'>".$mod_strings['ERR_LOG_DIRECTORY_NOT_WRITABLE']."</span>";
  1241. }
  1242. }
  1243. else {
  1244. $errors[] = "<span class='error'>".$mod_strings['ERR_LOG_DIRECTORY_NOT_EXISTS']."</span>";
  1245. }
  1246. }
  1247. if(!empty($_SESSION['setup_site_specify_guid']) && $_SESSION['setup_site_guid'] == ''){
  1248. $errors[] = "<span class='error'>".$mod_strings['ERR_SITE_GUID']."</span>";
  1249. }
  1250. }
  1251. return $errors;
  1252. }
  1253. function pullSilentInstallVarsIntoSession() {
  1254. global $mod_strings;
  1255. global $sugar_config;
  1256. if( file_exists('config_si.php') ){
  1257. require_once('config_si.php');
  1258. }
  1259. else if( empty($sugar_config_si) ){
  1260. die( $mod_strings['ERR_SI_NO_CONFIG'] );
  1261. }
  1262. $config_subset = array (
  1263. 'setup_site_url' => isset($sugar_config['site_url']) ? $sugar_config['site_url'] : '',
  1264. 'setup_db_host_name' => isset($sugar_config['dbconfig']['db_host_name']) ? $sugar_config['dbconfig']['db_host_name'] : '',
  1265. 'setup_db_host_instance' => isset($sugar_config['dbconfig']['db_host_instance']) ? $sugar_config['dbconfig']['db_host_instance'] : '',
  1266. 'setup_db_sugarsales_user' => isset($sugar_config['dbconfig']['db_user_name']) ? $sugar_config['dbconfig']['db_user_name'] : '',
  1267. 'setup_db_sugarsales_password' => isset($sugar_config['dbconfig']['db_password']) ? $sugar_config['dbconfig']['db_password'] : '',
  1268. 'setup_db_database_name' => isset($sugar_config['dbconfig']['db_name']) ? $sugar_config['dbconfig']['db_name'] : '',
  1269. 'setup_db_type' => isset($sugar_config['dbconfig']['db_type']) ? $sugar_config['dbconfig']['db_type'] : '',
  1270. 'setup_db_port_num' => isset($sugar_config['dbconfig']['db_port']) ? $sugar_config['dbconfig']['db_port'] : '',
  1271. 'setup_db_options' => !empty($sugar_config['dbconfigoptions']) ? $sugar_config['dbconfigoptions'] : array(),
  1272. );
  1273. // third array of values derived from above values
  1274. $derived = array (
  1275. 'setup_site_admin_password_retype' => $sugar_config_si['setup_site_admin_password'],
  1276. 'setup_db_sugarsales_password_retype' => $config_subset['setup_db_sugarsales_password'],
  1277. );
  1278. $needles = array('setup_db_create_database','setup_db_create_sugarsales_user','setup_license_key_users',
  1279. 'setup_license_key_expire_date','setup_license_key', 'setup_num_lic_oc',
  1280. 'default_currency_iso4217', 'default_currency_name', 'default_currency_significant_digits',
  1281. 'default_currency_symbol', 'default_date_format', 'default_time_format', 'default_decimal_seperator',
  1282. 'default_export_charset', 'default_language', 'default_locale_name_format', 'default_number_grouping_seperator',
  1283. 'export_delimiter', 'cache_dir', 'setup_db_options');
  1284. copyFromArray($sugar_config_si, $needles, $derived);
  1285. $all_config_vars = array_merge( $config_subset, $sugar_config_si, $derived );
  1286. // bug 16860 tyoung - trim leading and trailing whitespace from license_key
  1287. if (isset($all_config_vars['setup_license_key'])) {
  1288. $all_config_vars['setup_license_key'] = trim($all_config_vars['setup_license_key']);
  1289. }
  1290. foreach( $all_config_vars as $key => $value ){
  1291. $_SESSION[$key] = $value;
  1292. }
  1293. }
  1294. /**
  1295. * given an array it will check to determine if the key exists in the array, if so
  1296. * it will addd to the return array
  1297. *
  1298. * @param intput_array haystack to check
  1299. * @param needles list of needles to search for
  1300. * @param output_array the array to add the keys to
  1301. */
  1302. function copyFromArray($input_array, $needles, $output_array){
  1303. foreach($needles as $needle){
  1304. if(isset($input_array[$needle])){
  1305. $output_array[$needle] = $input_array[$needle];
  1306. }
  1307. }
  1308. }
  1309. /**
  1310. * handles language pack uploads - code based off of upload_file->final_move()
  1311. * puts it into the cache/upload dir to be handed off to langPackUnpack();
  1312. *
  1313. * @param object file UploadFile object
  1314. * @return bool true if successful
  1315. */
  1316. function langPackFinalMove($file) {
  1317. global $sugar_config;
  1318. //."upgrades/langpack/"
  1319. $destination = $sugar_config['upload_dir'].$file->stored_file_name;
  1320. if(!move_uploaded_file($_FILES[$file->field_name]['tmp_name'], $destination)) {
  1321. die ("ERROR: can't move_uploaded_file to $destination. You should try making the directory writable by the webserver");
  1322. }
  1323. return true;
  1324. }
  1325. function getLicenseDisplay($type, $manifest, $zipFile, $next_step, $license_file, $clean_file) {
  1326. return PackageManagerDisplay::getLicenseDisplay($license_file, 'install.php', $next_step, $zipFile, $type, $manifest, $clean_file);
  1327. }
  1328. /**
  1329. * creates the remove/delete form for langpack page
  1330. * @param string type commit/remove
  1331. * @param string manifest path to manifest file
  1332. * @param string zipFile path to uploaded zip file
  1333. * @param int nextstep current step
  1334. * @return string ret <form> for this package
  1335. */
  1336. function getPackButton($type, $manifest, $zipFile, $next_step, $uninstallable='Yes', $showButtons=true) {
  1337. global $mod_strings;
  1338. $button = $mod_strings['LBL_LANG_BUTTON_COMMIT'];
  1339. if($type == 'remove') {
  1340. $button = $mod_strings['LBL_LANG_BUTTON_REMOVE'];
  1341. } elseif($type == 'uninstall') {
  1342. $button = $mod_strings['LBL_LANG_BUTTON_UNINSTALL'];
  1343. }
  1344. $disabled = ($uninstallable == 'Yes') ? false : true;
  1345. $ret = "<form name='delete{$zipFile}' action='install.php' method='POST'>
  1346. <input type='hidden' name='current_step' value='{$next_step}'>
  1347. <input type='hidden' name='goto' value='{$mod_strings['LBL_CHECKSYS_RECHECK']}'>
  1348. <input type='hidden' name='languagePackAction' value='{$type}'>
  1349. <input type='hidden' name='manifest' value='".urlencode($manifest)."'>
  1350. <input type='hidden' name='zipFile' value='".urlencode($zipFile)."'>
  1351. <input type='hidden' name='install_type' value='custom'>";
  1352. if(!$disabled && $showButtons) {
  1353. $ret .= "<input type='submit' value='{$button}' class='button'>";
  1354. }
  1355. $ret .= "</form>";
  1356. return $ret;
  1357. }
  1358. /**
  1359. * finds all installed languages and returns an array with the names
  1360. * @return array langs array of installed languages
  1361. */
  1362. function getInstalledLanguages() {
  1363. $langDir = 'include/language/';
  1364. $dh = opendir($langDir);
  1365. $langs = array();
  1366. while($file = readdir($dh)) {
  1367. if(substr($file, -3) == 'php') {
  1368. }
  1369. }
  1370. }
  1371. /**
  1372. * searches upgrade dir for lang pack files.
  1373. *
  1374. * @return string HTML of available lang packs
  1375. */
  1376. function getLangPacks($display_commit = true, $types = array('langpack'), $notice_text = '') {
  1377. global $mod_strings;
  1378. global $next_step;
  1379. global $base_upgrade_dir;
  1380. if(empty($notice_text)){
  1381. $notice_text = $mod_strings['LBL_LANG_PACK_READY'];
  1382. }
  1383. $ret = "<tr><td colspan=7 align=left>{$notice_text}</td></tr>";
  1384. //$ret .="<table width='100%' cellpadding='0' cellspacing='0' border='0'>";
  1385. $ret .= "<tr>
  1386. <td width='20%' ><b>{$mod_strings['LBL_ML_NAME']}</b></td>
  1387. <td width='15%' ><b>{$mod_strings['LBL_ML_VERSION']}</b></td>
  1388. <td width='15%' ><b>{$mod_strings['LBL_ML_PUBLISHED']}</b></td>
  1389. <td width='15%' ><b>{$mod_strings['LBL_ML_UNINSTALLABLE']}</b></td>
  1390. <td width='20%' ><b>{$mod_strings['LBL_ML_DESCRIPTION']}</b></td>
  1391. <td width='7%' ></td>
  1392. <td width='1%' ></td>
  1393. <td width='7%' ></td>
  1394. </tr>\n";
  1395. $files = array();
  1396. // duh, new installs won't have the upgrade folders
  1397. if(!is_dir($base_upgrade_dir)) {
  1398. mkdir_recursive( $base_upgrade_dir);
  1399. }
  1400. $subdirs = array('full', 'langpack', 'module', 'patch', 'theme', 'temp');
  1401. foreach( $subdirs as $subdir ){
  1402. mkdir_recursive( "$base_upgrade_dir/$subdir" );
  1403. }
  1404. $files = findAllFiles($base_upgrade_dir, $files);
  1405. $hidden_input = '';
  1406. unset($_SESSION['hidden_input']);
  1407. foreach($files as $file) {
  1408. if(!preg_match("#.*\.zip\$#", $file)) {
  1409. continue;
  1410. }
  1411. // skip installed lang packs
  1412. if(isset($_SESSION['INSTALLED_LANG_PACKS']) && in_array($file, $_SESSION['INSTALLED_LANG_PACKS'])) {
  1413. continue;
  1414. }
  1415. // handle manifest.php
  1416. $target_manifest = remove_file_extension( $file ) . '-manifest.php';
  1417. $license_file = remove_file_extension( $file ) . '-license.txt';
  1418. include($target_manifest);
  1419. if(!empty($types)){
  1420. if(!in_array(strtolower($manifest['type']), $types))
  1421. continue;
  1422. }
  1423. $md5_matches = array();
  1424. if($manifest['type'] == 'module'){
  1425. $uh = new UpgradeHistory();
  1426. $upgrade_content = clean_path($file);
  1427. $the_base = basename($upgrade_content);
  1428. $the_md5 = md5_file($upgrade_content);
  1429. $md5_matches = $uh->findByMd5($the_md5);
  1430. }
  1431. if($manifest['type']!= 'module' || 0 == sizeof($md5_matches)){
  1432. $name = empty($manifest['name']) ? $file : $manifest['name'];
  1433. $version = empty($manifest['version']) ? '' : $manifest['version'];
  1434. $published_date = empty($manifest['published_date']) ? '' : $manifest['published_date'];
  1435. $icon = '';
  1436. $description = empty($manifest['description']) ? 'None' : $manifest['description'];
  1437. $uninstallable = empty($manifest['is_uninstallable']) ? 'No' : 'Yes';
  1438. $manifest_type = $manifest['type'];
  1439. $commitPackage = getPackButton('commit', $target_manifest, $file, $next_step);
  1440. $deletePackage = getPackButton('remove', $target_manifest, $file, $next_step);
  1441. //$ret .="<table width='100%' cellpadding='0' cellspacing='0' border='0'>";
  1442. $ret .= "<tr>";
  1443. $ret .= "<td width='20%' >".$name."</td>";
  1444. $ret .= "<td width='15%' >".$version."</td>";
  1445. $ret .= "<td width='15%' >".$published_date."</td>";
  1446. $ret .= "<td width='15%' >".$uninstallable."</td>";
  1447. $ret .= "<td width='20%' >".$description."</td>";
  1448. if($display_commit)
  1449. $ret .= "<td width='7%'>{$commitPackage}</td>";
  1450. $ret .= "<td width='1%'></td>";
  1451. $ret .= "<td width='7%'>{$deletePackage}</td>";
  1452. $ret .= "</td></tr>";
  1453. $clean_field_name = "accept_lic_".str_replace('.', '_', urlencode(basename($file)));
  1454. if(is_file($license_file)){
  1455. //rrs
  1456. $ret .= "<tr><td colspan=6>";
  1457. $ret .= getLicenseDisplay('commit', $target_manifest, $file, $next_step, $license_file, $clean_field_name);
  1458. $ret .= "</td></tr>";
  1459. $hidden_input .= "<input type='hidden' name='$clean_field_name' id='$clean_field_name' value='no'>";
  1460. }else{
  1461. $hidden_input .= "<input type='hidden' name='$clean_field_name' id='$clean_field_name' value='yes'>";
  1462. }
  1463. }//fi
  1464. }//rof
  1465. $_SESSION['hidden_input'] = $hidden_input;
  1466. if(count($files) > 0 ) {
  1467. $ret .= "</tr><td colspan=7>";
  1468. $ret .= "<form name='commit' action='install.php' method='POST'>
  1469. <input type='hidden' name='current_step' value='{$next_step}'>
  1470. <input type='hidden' name='goto' value='Re-check'>
  1471. <input type='hidden' name='languagePackAction' value='commit'>
  1472. <input type='hidden' name='install_type' value='custom'>
  1473. </form>
  1474. ";
  1475. $ret .= "</td></tr>";
  1476. } else {
  1477. $ret .= "</tr><td colspan=7><i>{$mod_strings['LBL_LANG_NO_PACKS']}</i></td></tr>";
  1478. }
  1479. return $ret;
  1480. }
  1481. if ( !function_exists('extractFile') ) {
  1482. function extractFile( $zip_file, $file_in_zip, $base_tmp_upgrade_dir){
  1483. $my_zip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
  1484. unzip_file( $zip_file, $file_in_zip, $my_zip_dir );
  1485. return( "$my_zip_dir/$file_in_zip" );
  1486. }
  1487. }
  1488. if ( !function_exists('extractManifest') ) {
  1489. function extractManifest( $zip_file,$base_tmp_upgrade_dir ) {
  1490. return( extractFile( $zip_file, "manifest.php",$base_tmp_upgrade_dir ) );
  1491. }
  1492. }
  1493. if ( !function_exists('unlinkTempFiles') ) {
  1494. function unlinkTempFiles($manifest='', $zipFile='') {
  1495. global $sugar_config;
  1496. @unlink($_FILES['language_pack']['tmp_name']);
  1497. if(!empty($manifest))
  1498. @unlink($manifest);
  1499. if(!empty($zipFile)) {
  1500. //@unlink($zipFile);
  1501. $tmpZipFile = substr($zipFile, strpos($zipFile, 'langpack/') + 9, strlen($zipFile));
  1502. @unlink($sugar_config['upload_dir'].$tmpZipFile);
  1503. }
  1504. rmdir_recursive($sugar_config['upload_dir']."upgrades/temp");
  1505. sugar_mkdir($sugar_config['upload_dir']."upgrades/temp");
  1506. }
  1507. }
  1508. function langPackUnpack($unpack_type, $full_file)
  1509. {
  1510. global $sugar_config;
  1511. global $base_upgrade_dir;
  1512. global $base_tmp_upgrade_dir;
  1513. $manifest = array();
  1514. if(!empty($full_file)){
  1515. $base_filename = pathinfo(urldecode($full_file), PATHINFO_FILENAME );
  1516. } else {
  1517. return "Empty filename supplied";
  1518. }
  1519. $manifest_file = extractManifest($full_file, $base_tmp_upgrade_dir);
  1520. if($unpack_type == 'module')
  1521. $license_file = extractFile($full_file, 'LICENSE.txt', $base_tmp_upgrade_dir);
  1522. if(is_file($manifest_file)) {
  1523. if($unpack_type == 'module' && is_file($license_file)){
  1524. copy($license_file, $base_upgrade_dir.'/'.$unpack_type.'/'.$base_filename."-license.txt");
  1525. }
  1526. copy($manifest_file, $base_upgrade_dir.'/'.$unpack_type.'/'.$base_filename."-manifest.php");
  1527. require_once( $manifest_file );
  1528. validate_manifest( $manifest );
  1529. $upgrade_zip_type = $manifest['type'];
  1530. mkdir_recursive( "$base_upgrade_dir/$upgrade_zip_type" );
  1531. $target_path = "$base_upgrade_dir/$upgrade_zip_type/$base_filename";
  1532. $target_manifest = $target_path . "-manifest.php";
  1533. if( isset($manifest['icon']) && $manifest['icon'] != "" ) {
  1534. $icon_location = extractFile( $full_file, $manifest['icon'], $base_tmp_upgrade_dir );
  1535. $path_parts = pathinfo( $icon_location );
  1536. copy( $icon_location, $target_path . "-icon." . $path_parts['extension'] );
  1537. }
  1538. // move file from uploads to cache
  1539. // FIXME: where should it be?
  1540. if( copy( $full_file , $target_path.".zip" ) ){
  1541. copy( $manifest_file, $target_manifest );
  1542. unlink($full_file); // remove tempFile
  1543. return "The file $base_filename has been uploaded.<br>\n";
  1544. } else {
  1545. unlinkTempFiles($manifest_file, $full_file);
  1546. return "There was an error uploading the file, please try again!<br>\n";
  1547. }
  1548. } else {
  1549. die("The zip file is missing a manifest.php file. Cannot proceed.");
  1550. }
  1551. unlinkTempFiles($manifest_file, '');
  1552. }
  1553. if ( !function_exists('validate_manifest') ) {
  1554. function validate_manifest( $manifest ){
  1555. // takes a manifest.php manifest array and validates contents
  1556. global $subdirs;
  1557. global $sugar_version;
  1558. global $sugar_flavor;
  1559. global $mod_strings;
  1560. if( !isset($manifest['type']) ){
  1561. die($mod_strings['ERROR_MANIFEST_TYPE']);
  1562. }
  1563. $type = $manifest['type'];
  1564. if( getInstallType( "/$type/" ) == "" ){
  1565. die($mod_strings['ERROR_PACKAGE_TYPE']. ": '" . $type . "'." );
  1566. }
  1567. return true; // making this a bit more relaxed since we updated the language extraction and merge capabilities
  1568. /*
  1569. if( isset($manifest['acceptable_sugar_versions']) ){
  1570. $version_ok = false;
  1571. $matches_empty = true;
  1572. if( isset($manifest['acceptable_sugar_versions']['exact_matches']) ){
  1573. $matches_empty = false;
  1574. foreach( $manifest['acceptable_sugar_versions']['exact_matches'] as $match ){
  1575. if( $match == $sugar_version ){
  1576. $version_ok = true;
  1577. }
  1578. }
  1579. }
  1580. if( !$version_ok && isset($manifest['acceptable_sugar_versions']['regex_matches']) ){
  1581. $matches_empty = false;
  1582. foreach( $manifest['acceptable_sugar_versions']['regex_matches'] as $match ){
  1583. if( preg_match( "/$match/", $sugar_version ) ){
  1584. $version_ok = true;
  1585. }
  1586. }
  1587. }
  1588. if( !$matches_empty && !$version_ok ){
  1589. die( $mod_strings['ERROR_VERSION_INCOMPATIBLE'] . $sugar_version );
  1590. }
  1591. }
  1592. if( isset($manifest['acceptable_sugar_flavors']) && sizeof($manifest['acceptable_sugar_flavors']) > 0 ){
  1593. $flavor_ok = false;
  1594. foreach( $manifest['acceptable_sugar_flavors'] as $match ){
  1595. if( $match == $sugar_flavor ){
  1596. $flavor_ok = true;
  1597. }
  1598. }
  1599. if( !$flavor_ok ){
  1600. //die( $mod_strings['ERROR_FLAVOR_INCOMPATIBLE'] . $sugar_flavor );
  1601. }
  1602. }*/
  1603. }
  1604. }
  1605. if ( !function_exists('getInstallType') ) {
  1606. function getInstallType( $type_string ){
  1607. // detect file type
  1608. $subdirs = array('full', 'langpack', 'module', 'patch', 'theme', 'temp');
  1609. foreach( $subdirs as $subdir ){
  1610. if( preg_match( "#/$subdir/#", $type_string ) ){
  1611. return( $subdir );
  1612. }
  1613. }
  1614. // return empty if no match
  1615. return( "" );
  1616. }
  1617. }
  1618. //mysqli connector has a separate parameter for port.. We need to separate it out from the host name
  1619. function getHostPortFromString($hostname=''){
  1620. $pos=strpos($hostname,':');
  1621. if($pos === false){
  1622. //no need to process as string is empty or does not contain ':' delimiter
  1623. return '';
  1624. }
  1625. $hostArr = explode(':', $hostname);
  1626. return $hostArr;
  1627. }
  1628. function getLicenseContents($filename)
  1629. {
  1630. $license_file = '';
  1631. if(file_exists($filename) && filesize($filename) >0){
  1632. $license_file = trim(file_get_contents($filename));
  1633. }
  1634. return $license_file;
  1635. }
  1636. ///////////////////////////////////////////////////////////////////////////////
  1637. //// FROM POPULATE SEED DATA
  1638. $seed = array(
  1639. 'qa', 'dev', 'beans',
  1640. 'info', 'sales', 'support',
  1641. 'kid', 'the', 'section',
  1642. 'sugar', 'hr', 'im',
  1643. 'kid', 'vegan', 'phone',
  1644. );
  1645. $tlds = array(
  1646. ".com", ".org", ".net", ".tv", ".cn", ".co.jp", ".us",
  1647. ".edu", ".tw", ".de", ".it", ".co.uk", ".info", ".biz",
  1648. ".name",
  1649. );
  1650. /**
  1651. * creates a random, DNS-clean webaddress
  1652. */
  1653. function createWebAddress() {
  1654. global $seed;
  1655. global $tlds;
  1656. $one = $seed[rand(0, count($seed)-1)];
  1657. $two = $seed[rand(0, count($seed)-1)];
  1658. $tld = $tlds[rand(0, count($tlds)-1)];
  1659. return "www.{$one}{$two}{$tld}";
  1660. }
  1661. /**
  1662. * creates a random email address
  1663. * @return string
  1664. */
  1665. function createEmailAddress() {
  1666. global $seed;
  1667. global $tlds;
  1668. $part[0] = $seed[rand(0, count($seed)-1)];
  1669. $part[1] = $seed[rand(0, count($seed)-1)];
  1670. $part[2] = $seed[rand(0, count($seed)-1)];
  1671. $tld = $tlds[rand(0, count($tlds)-1)];
  1672. $len = rand(1,3);
  1673. $ret = '';
  1674. for($i=0; $i<$len; $i++) {
  1675. $ret .= (empty($ret)) ? '' : '.';
  1676. $ret .= $part[$i];
  1677. }
  1678. if($len == 1) {
  1679. $ret .= rand(10, 99);
  1680. }
  1681. return "{$ret}@example{$tld}";
  1682. }
  1683. function add_digits($quantity, &$string, $min = 0, $max = 9) {
  1684. for($i=0; $i < $quantity; $i++) {
  1685. $string .= mt_rand($min,$max);
  1686. }
  1687. }
  1688. function create_phone_number() {
  1689. $phone = "(";
  1690. add_digits(3, $phone);
  1691. $phone .= ") ";
  1692. add_digits(3, $phone);
  1693. $phone .= "-";
  1694. add_digits(4, $phone);
  1695. return $phone;
  1696. }
  1697. function create_date($year=null,$mnth=null,$day=null)
  1698. {
  1699. global $timedate;
  1700. $now = $timedate->getNow();
  1701. if ($day==null) $day=$now->day+mt_rand(0,365);
  1702. return $timedate->asDbDate($now->get_day_begin($day, $mnth, $year));
  1703. }
  1704. function create_current_date_time()
  1705. {
  1706. global $timedate;
  1707. return $timedate->nowDb();
  1708. }
  1709. function create_time($hr=null,$min=null,$sec=null)
  1710. {
  1711. global $timedate;
  1712. $date = TimeDate::fromTimestamp(0);
  1713. if ($hr==null) $hr=mt_rand(6,19);
  1714. if ($min==null) $min=(mt_rand(0,3)*15);
  1715. if ($sec==null) $sec=0;
  1716. return $timedate->asDbTime($date->setDate(2007, 10, 7)->setTime($hr, $min, $sec));
  1717. }
  1718. function create_past_date()
  1719. {
  1720. global $timedate;
  1721. $now = $timedate->getNow(true);
  1722. $day=$now->day-mt_rand(1, 365);
  1723. return $timedate->asDbDate($now->get_day_begin($day));
  1724. }
  1725. /**
  1726. * This method will look for a file modules_post_install.php in the root directory and based on the
  1727. * contents of this file, it will silently install any modules as specified in this array.
  1728. */
  1729. function post_install_modules(){
  1730. if(is_file('modules_post_install.php')){
  1731. global $current_user, $mod_strings;
  1732. $current_user = new User();
  1733. $current_user->is_admin = '1';
  1734. require_once('ModuleInstall/PackageManager/PackageManager.php');
  1735. require_once('modules_post_install.php');
  1736. //we now have the $modules_to_install array in memory
  1737. $pm = new PackageManager();
  1738. $old_mod_strings = $mod_strings;
  1739. foreach($modules_to_install as $module_to_install){
  1740. if(is_file($module_to_install)){
  1741. $pm->performSetup($module_to_install, 'module', false);
  1742. $file_to_install = sugar_cached('upload/upgrades/module/').basename($module_to_install);
  1743. $_REQUEST['install_file'] = $file_to_install;
  1744. $pm->performInstall($file_to_install);
  1745. }
  1746. }
  1747. $mod_strings = $old_mod_strings;
  1748. }
  1749. }
  1750. function get_help_button_url(){
  1751. $help_url = 'http://www.sugarcrm.com/docs/Administration_Guides/CommunityEdition_Admin_Guide_5.0/toc.html';
  1752. return $help_url;
  1753. }
  1754. function create_db_user_creds($numChars=10){
  1755. $numChars = 7; // number of chars in the password
  1756. //chars to select from
  1757. $charBKT = "abcdefghijklmnpqrstuvwxyz123456789ABCDEFGHIJKLMNPQRSTUVWXYZ";
  1758. // seed the random number generator
  1759. srand((double)microtime()*1000000);
  1760. $password="";
  1761. for ($i=0;$i<$numChars;$i++) // loop and create password
  1762. $password = $password . substr ($charBKT, rand() % strlen($charBKT), 1);
  1763. return $password;
  1764. }
  1765. function addDefaultRoles($defaultRoles = array()) {
  1766. global $db;
  1767. foreach($defaultRoles as $roleName=>$role){
  1768. $ACLField = new ACLField();
  1769. $role1= new ACLRole();
  1770. $role1->name = $roleName;
  1771. $role1->description = $roleName." Role";
  1772. $role1_id=$role1->save();
  1773. foreach($role as $category=>$actions){
  1774. foreach($actions as $name=>$access_override){
  1775. if($name=='fields'){
  1776. foreach($access_override as $field_id=>$access){
  1777. $ACLField->setAccessControl($category, $role1_id, $field_id, $access);
  1778. }
  1779. }else{
  1780. $queryACL="SELECT id FROM acl_actions where category='$category' and name='$name'";
  1781. $result = $db->query($queryACL);
  1782. $actionId=$db->fetchByAssoc($result);
  1783. if (isset($actionId['id']) && !empty($actionId['id'])){
  1784. $role1->setAction($role1_id, $actionId['id'], $access_override);
  1785. }
  1786. }
  1787. }
  1788. }
  1789. }
  1790. }
  1791. /**
  1792. * Fully enable SugarFeeds, enabling the user feed and all available modules that have SugarFeed data.
  1793. */
  1794. function enableSugarFeeds()
  1795. {
  1796. $admin = new Administration();
  1797. $admin->saveSetting('sugarfeed','enabled','1');
  1798. foreach ( SugarFeed::getAllFeedModules() as $module )
  1799. SugarFeed::activateModuleFeed($module);
  1800. check_logic_hook_file('Users','after_login', array(1, 'SugarFeed old feed entry remover', 'modules/SugarFeed/SugarFeedFlush.php', 'SugarFeedFlush', 'flushStaleEntries'));
  1801. }
  1802. function create_writable_dir($dirname)
  1803. {
  1804. if ((is_dir($dirname)) || @sugar_mkdir($dirname,0755)) {
  1805. $ok = make_writable($dirname);
  1806. }
  1807. if(empty($ok)) {
  1808. installLog("ERROR: Cannot create writable dir $dirname");
  1809. }
  1810. }
  1811. /**
  1812. * Enable the InsideView connector for the four default modules.
  1813. */
  1814. function enableInsideViewConnector()
  1815. {
  1816. // Load up the existing mapping and hand it to the InsideView connector to have it setup the correct logic hooks
  1817. $mapFile = 'modules/Connectors/connectors/sources/ext/rest/insideview/mapping.php';
  1818. if ( file_exists('custom/'.$mapFile) ) {
  1819. require('custom/'.$mapFile);
  1820. } else {
  1821. require($mapFile);
  1822. }
  1823. require_once('modules/Connectors/connectors/sources/ext/rest/insideview/insideview.php');
  1824. $source = new ext_rest_insideview();
  1825. // $mapping is brought in from the mapping.php file above
  1826. $source->saveMappingHook($mapping);
  1827. }