PageRenderTime 62ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/install/install_utils.php

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