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.
7 * This program is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Affero General Public License version 3 as published by the
9 * Free Software Foundation with the addition of the following permission added
10 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
19 * You should have received a copy of the GNU Affero General Public License along with
20 * this program; if not, see http://www.gnu.org/licenses or write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
27 * The interactive user interfaces in modified source and object code versions
28 * of this program must display Appropriate Legal Notices, as required under
29 * Section 5 of the GNU Affero General Public License version 3.
31 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32 * these Appropriate Legal Notices must retain the display of the "Powered by
33 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34 * technical reasons, the Appropriate Legal Notices must display the words
35 * "Powered by SugarCRM".
36 ********************************************************************************/
38 /*********************************************************************************
40 * $Description: TODO: To be written. Portions created by SugarCRM are Copyright
41 * (C) SugarCRM, Inc. All Rights Reserved. Contributor(s):
42 * ______________________________________..
43 * *******************************************************************************/
45 require_once('include/utils/zip_utils.php');
47 require_once('include/upload_file.php');
51 ///////////////////////////////////////////////////////////////////////////////
54 * returns lowercase lang encoding
55 * @return string encoding or blank on false
57 function parseAcceptLanguage() {
58 $lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
59 if(strpos($lang, ';')) {
60 $exLang = explode(';', $lang);
61 return strtolower(str_replace('-','_',$exLang[0]));
64 if(preg_match("#\w{2}\-?\_?\w{2}#", $lang, $match)) {
65 return strtolower(str_replace('-','_',$match[0]));
72 ///////////////////////////////////////////////////////////////////////////////
73 //// FROM localization.php
75 * copies the temporary unzip'd files to their final destination
76 * removes unzip'd files from system if $uninstall=true
77 * @param bool uninstall true if uninstalling a language pack
78 * @return array sugar_config
80 function commitLanguagePack($uninstall=false) {
83 global $base_upgrade_dir;
84 global $base_tmp_upgrade_dir;
87 $manifest = urldecode($_REQUEST['manifest']);
88 $zipFile = urldecode($_REQUEST['zipFile']);
91 $unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
94 $zip_force_copy = array();
96 if($uninstall == false && isset($_SESSION['INSTALLED_LANG_PACKS']) && in_array($zipFile, $_SESSION['INSTALLED_LANG_PACKS'])) {
100 // unzip lang pack to temp dir
101 if(isset($zipFile) && !empty($zipFile)) {
102 if(is_file($zipFile)) {
103 unzip( $zipFile, $unzip_dir );
105 echo $mod_strings['ERR_LANG_MISSING_FILE'].$zipFile;
106 die(); // no point going any further
110 // filter for special to/from dir conditions (langpacks generally don't have them)
111 if(isset($manifest) && !empty($manifest)) {
112 if(is_file($manifest)) {
114 if( isset( $manifest['copy_files']['from_dir'] ) && $manifest['copy_files']['from_dir'] != "" ){
115 $zip_from_dir = $manifest['copy_files']['from_dir'];
117 if( isset( $manifest['copy_files']['to_dir'] ) && $manifest['copy_files']['to_dir'] != "" ){
118 $zip_to_dir = $manifest['copy_files']['to_dir'];
120 if( isset( $manifest['copy_files']['force_copy'] ) && $manifest['copy_files']['force_copy'] != "" ){
121 $zip_force_copy = $manifest['copy_files']['force_copy'];
123 if( isset( $manifest['version'] ) ){
124 $version = $manifest['version'];
127 $errors[] = $mod_strings['ERR_LANG_MISSING_FILE'].$manifest;
132 // find name of language pack: find single file in include/language/xx_xx.lang.php
133 $d = dir( "$unzip_dir/$zip_from_dir/include/language" );
134 while( $f = $d->read() ){
135 if( $f == "." || $f == ".." ){
138 else if( preg_match("/(.*)\.lang\.php\$/", $f, $match) ){
139 $new_lang_name = $match[1];
142 if( $new_lang_name == "" ){
143 die( $mod_strings['ERR_LANG_NO_LANG_FILE'].$zipFile );
145 $new_lang_desc = getLanguagePackName( "$unzip_dir/$zip_from_dir/include/language/$new_lang_name.lang.php" );
146 if( $new_lang_desc == "" ){
147 die( "No language pack description found at include/language/$new_lang_name.lang.php inside $install_file." );
149 // add language to available languages
150 $sugar_config['languages'][$new_lang_name] = ($new_lang_desc);
152 // get an array of all files to be moved
153 $filesFrom = array();
154 $filesFrom = findAllFiles($unzip_dir, $filesFrom);
158 ///////////////////////////////////////////////////////////////////////////
161 // unlink all pack files
162 foreach($filesFrom as $fileFrom) {
163 //echo "deleting: ".getcwd().substr($fileFrom, strlen($unzip_dir), strlen($fileFrom))."<br>";
164 @unlink(getcwd().substr($fileFrom, strlen($unzip_dir), strlen($fileFrom)));
167 // remove session entry
168 if(isset($_SESSION['INSTALLED_LANG_PACKS']) && is_array($_SESSION['INSTALLED_LANG_PACKS'])) {
169 foreach($_SESSION['INSTALLED_LANG_PACKS'] as $k => $langPack) {
170 if($langPack == $zipFile) {
171 unset($_SESSION['INSTALLED_LANG_PACKS'][$k]);
172 unset($_SESSION['INSTALLED_LANG_PACKS_VERSION'][$k]);
173 unset($_SESSION['INSTALLED_LANG_PACKS_MANIFEST'][$k]);
178 // remove language from config
179 $new_langs = array();
180 $old_langs = $sugar_config['languages'];
181 foreach( $old_langs as $key => $value ){
182 if( $key != $removedLang ){
183 $new_langs += array( $key => $value );
186 $sugar_config['languages'] = $new_langs;
189 // copy filesFrom to filesTo
190 foreach($filesFrom as $fileFrom) {
191 @copy($fileFrom, getcwd().substr($fileFrom, strlen($unzip_dir), strlen($fileFrom)));
194 $_SESSION['INSTALLED_LANG_PACKS'][$new_lang_name] = $zipFile;
195 $_SESSION['INSTALLED_LANG_PACKS_VERSION'][$new_lang_name] = $version;
196 $serial_manifest = array();
197 $serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
198 $serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
199 $serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
200 $_SESSION['INSTALLED_LANG_PACKS_MANIFEST'][$new_lang_name] = base64_encode(serialize($serial_manifest));
203 writeSugarConfig($sugar_config);
205 return $sugar_config;
208 function commitPatch($unlink = false, $type = 'patch'){
209 require_once('ModuleInstall/ModuleInstaller.php');
210 require_once('include/entryPoint.php');
214 global $base_upgrade_dir;
215 global $base_tmp_upgrade_dir;
217 $GLOBALS['db'] = $db;
220 global $current_user;
221 $current_user = new User();
222 $current_user->is_admin = '1';
223 $old_mod_strings = $mod_strings;
224 if(is_dir($base_upgrade_dir)) {
225 $files = findAllFiles("$base_upgrade_dir/$type", $files);
226 $mi = new ModuleInstaller();
228 $mod_strings = return_module_language('en', "Administration");
230 foreach($files as $file) {
231 if(!preg_match('#.*\.zip\$#', $file)) {
234 // handle manifest.php
235 $target_manifest = remove_file_extension( $file ) . '-manifest.php';
237 include($target_manifest);
239 $unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
240 unzip($file, $unzip_dir );
241 if(file_exists("$unzip_dir/scripts/pre_install.php")){
242 require_once("$unzip_dir/scripts/pre_install.php");
245 if( isset( $manifest['copy_files']['from_dir'] ) && $manifest['copy_files']['from_dir'] != "" ){
246 $zip_from_dir = $manifest['copy_files']['from_dir'];
248 $source = "$unzip_dir/$zip_from_dir";
250 copy_recursive($source, $dest);
252 if(file_exists("$unzip_dir/scripts/post_install.php")){
253 require_once("$unzip_dir/scripts/post_install.php");
256 $new_upgrade = new UpgradeHistory();
257 $new_upgrade->filename = $file;
258 $new_upgrade->md5sum = md5_file($file);
259 $new_upgrade->type = $manifest['type'];
260 $new_upgrade->version = $manifest['version'];
261 $new_upgrade->status = "installed";
262 //$new_upgrade->author = $manifest['author'];
263 $new_upgrade->name = $manifest['name'];
264 $new_upgrade->description = $manifest['description'];
265 $serial_manifest = array();
266 $serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
267 $serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
268 $serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
269 $new_upgrade->manifest = base64_encode(serialize($serial_manifest));
270 $new_upgrade->save();
274 $mod_strings = $old_mod_strings;
277 function commitModules($unlink = false, $type = 'module'){
278 require_once('ModuleInstall/ModuleInstaller.php');
279 require_once('include/entryPoint.php');
283 global $base_upgrade_dir;
284 global $base_tmp_upgrade_dir;
286 $GLOBALS['db'] = $db;
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();
297 $mod_strings = return_module_language('en', "Administration");
299 foreach($files as $file) {
300 if(!preg_match('#.*\.zip\$', $file)) {
303 $lic_name = 'accept_lic_'.str_replace('.', '_', urlencode(basename($file)));
306 if(isset($_REQUEST[$lic_name])){
307 if($_REQUEST[$lic_name] == 'yes'){
310 $can_install = false;
314 // handle manifest.php
315 $target_manifest = remove_file_extension( $file ) . '-manifest.php';
316 if($type == 'langpack'){
317 $_REQUEST['manifest'] = $target_manifest;
318 $_REQUEST['zipFile'] = $file;
319 commitLanguagePack();
322 include($target_manifest);
324 $unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
325 unzip($file, $unzip_dir );
326 $_REQUEST['install_file'] = $file;
327 $mi->install($unzip_dir);
328 $new_upgrade = new UpgradeHistory();
329 $new_upgrade->filename = $file;
330 $new_upgrade->md5sum = md5_file($file);
331 $new_upgrade->type = $manifest['type'];
332 $new_upgrade->version = $manifest['version'];
333 $new_upgrade->status = "installed";
334 // $new_upgrade->author = $manifest['author'];
335 $new_upgrade->name = $manifest['name'];
336 $new_upgrade->description = $manifest['description'];
337 $new_upgrade->id_name = (isset($installdefs['id_name'])) ? $installdefs['id_name'] : '';
338 $serial_manifest = array();
339 $serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
340 $serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
341 $serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
342 $new_upgrade->manifest = base64_encode(serialize($serial_manifest));
343 $new_upgrade->save();
348 $mod_strings = $old_mod_strings;
352 * creates UpgradeHistory entries
353 * @param mode string Install or Uninstall
355 function updateUpgradeHistory() {
356 if(isset($_SESSION['INSTALLED_LANG_PACKS']) && count($_SESSION['INSTALLED_LANG_PACKS']) > 0) {
357 foreach($_SESSION['INSTALLED_LANG_PACKS'] as $k => $zipFile) {
358 $new_upgrade = new UpgradeHistory();
359 $new_upgrade->filename = $zipFile;
360 $new_upgrade->md5sum = md5_file($zipFile);
361 $new_upgrade->type = 'langpack';
362 $new_upgrade->version = $_SESSION['INSTALLED_LANG_PACKS_VERSION'][$k];
363 $new_upgrade->status = "installed";
364 $new_upgrade->manifest = $_SESSION['INSTALLED_LANG_PACKS_MANIFEST'][$k];
365 $new_upgrade->save();
372 * removes the installed language pack, but the zip is still in the cache dir
374 function removeLanguagePack() {
376 global $sugar_config;
379 $manifest = urldecode($_REQUEST['manifest']);
380 $zipFile = urldecode($_REQUEST['zipFile']);
382 if(isset($manifest) && !empty($manifest)) {
383 if(is_file($manifest)) {
384 if(!unlink($manifest)) {
385 $errors[] = $mod_strings['ERR_LANG_CANNOT_DELETE_FILE'].$manifest;
388 $errors[] = $mod_strings['ERR_LANG_MISSING_FILE'].$manifest;
390 unset($_SESSION['packages_to_install'][$manifest]);
392 if(isset($zipFile) && !empty($zipFile)) {
393 if(is_file($zipFile)) {
394 if(!unlink($zipFile)) {
395 $errors[] = $mod_strings['ERR_LANG_CANNOT_DELETE_FILE'].$zipFile;
398 $errors[] = $mod_strings['ERR_LANG_MISSING_FILE'].$zipFile;
401 if(count($errors > 0)) {
402 echo "<p class='error'>";
403 foreach($errors as $error) {
409 unlinkTempFiles($manifest, $zipFile);
415 * takes the current value of $sugar_config and writes it out to config.php (sorta the same as the final step)
416 * @param array sugar_config
418 function writeSugarConfig($sugar_config) {
419 ksort($sugar_config);
420 $sugar_config_string = "<?php\n" .
421 '// created: ' . date('Y-m-d H:i:s') . "\n" .
423 var_export($sugar_config, true) .
425 if(is_writable('config.php') && write_array_to_file( "sugar_config", $sugar_config, "config.php")) {
431 * uninstalls the Language pack
433 function uninstallLangPack() {
434 global $sugar_config;
436 // remove language from config
437 $new_langs = array();
438 $old_langs = $sugar_config['languages'];
439 foreach( $old_langs as $key => $value ){
440 if( $key != $_REQUEST['new_lang_name'] ){
441 $new_langs += array( $key => $value );
444 $sugar_config['languages'] = $new_langs;
446 writeSugarConfig($sugar_config);
450 * retrieves the name of the language
452 if ( !function_exists('getLanguagePackName') ) {
453 function getLanguagePackName($the_file) {
454 require_once( "$the_file" );
455 if( isset( $app_list_strings["language_pack_name"] ) ){
456 return( $app_list_strings["language_pack_name"] );
462 function getInstalledLangPacks($showButtons=true) {
466 $ret = "<tr><td colspan=7 align=left>{$mod_strings['LBL_LANG_PACK_INSTALLED']}</td></tr>";
467 //$ret .="<table width='100%' cellpadding='0' cellspacing='0' border='0'>";
469 <td width='15%' ><b>{$mod_strings['LBL_ML_NAME']}</b></td>
470 <td width='15%' ><b>{$mod_strings['LBL_ML_VERSION']}</b></td>
471 <td width='15%' ><b>{$mod_strings['LBL_ML_PUBLISHED']}</b></td>
472 <td width='15%' ><b>{$mod_strings['LBL_ML_UNINSTALLABLE']}</b></td>
473 <td width='15%' ><b>{$mod_strings['LBL_ML_DESCRIPTION']}</b></td>
474 <td width='15%' ></td>
475 <td width='15%' ></td>
478 $files = findAllFiles(sugar_cached("upload/upgrades"), $files);
480 if(isset($_SESSION['INSTALLED_LANG_PACKS']) && !empty($_SESSION['INSTALLED_LANG_PACKS'])){
481 if(count($_SESSION['INSTALLED_LANG_PACKS'] > 0)) {
482 foreach($_SESSION['INSTALLED_LANG_PACKS'] as $file) {
483 // handle manifest.php
484 $target_manifest = remove_file_extension( $file ) . '-manifest.php';
485 include($target_manifest);
487 $name = empty($manifest['name']) ? $file : $manifest['name'];
488 $version = empty($manifest['version']) ? '' : $manifest['version'];
489 $published_date = empty($manifest['published_date']) ? '' : $manifest['published_date'];
491 $description = empty($manifest['description']) ? 'None' : $manifest['description'];
492 $uninstallable = empty($manifest['is_uninstallable']) ? 'No' : 'Yes';
493 $manifest_type = $manifest['type'];
495 $deletePackage = getPackButton('uninstall', $target_manifest, $file, $next_step, $uninstallable, $showButtons);
496 //$ret .="<table width='100%' cellpadding='0' cellspacing='0' border='0'>";
498 $ret .= "<td width='15%' >".$name."</td>";
499 $ret .= "<td width='15%' >".$version."</td>";
500 $ret .= "<td width='15%' >".$published_date."</td>";
501 $ret .= "<td width='15%' >".$uninstallable."</td>";
502 $ret .= "<td width='15%' >".$description."</td>";
503 $ret .= "<td width='15%' ></td>";
504 $ret .= "<td width='15%' >{$deletePackage}</td>";
508 $ret .= "</tr><td colspan=7><i>{$mod_strings['LBL_LANG_NO_PACKS']}</i></td></tr>";
511 $ret .= "</tr><td colspan=7><i>{$mod_strings['LBL_LANG_NO_PACKS']}</i></td></tr>";
517 function uninstallLanguagePack() {
518 return commitLanguagePack(true);
522 function getSugarConfigLanguageArray($langZip) {
523 global $sugar_config;
525 include(remove_file_extension($langZip)."-manifest.php");
527 if(isset($installdefs['id']) && isset($manifest['name'])) {
528 $ret = $installdefs['id']."::".$manifest['name']."::".$manifest['version'];
536 ///////////////////////////////////////////////////////////////////////////////
537 //// FROM performSetup.php
539 function getInstallDbInstance()
541 return DBManagerFactory::getTypeInstance($_SESSION['setup_db_type'], array("db_manager" => $_SESSION['setup_db_manager']));
544 function getDbConnection()
547 "db_host_name" => $_SESSION['setup_db_host_name'],
548 "db_user_name" => $_SESSION['setup_db_admin_user_name'],
549 "db_password" => $_SESSION['setup_db_admin_password'],
550 "db_host_instance" => $_SESSION['setup_db_host_instance'],
551 "db_port" => $_SESSION['setup_db_port_num'],
553 if(empty($_SESSION['setup_db_create_database'])) {
554 $dbconfig["db_name"] = $_SESSION['setup_db_database_name'];
557 $db = getInstallDbInstance();
558 if(!empty($_SESSION['setup_db_options'])) {
559 $db->setOptions($_SESSION['setup_db_options']);
561 $db->connect($dbconfig, true);
566 * creates the Sugar DB user (if not admin)
568 function handleDbCreateSugarUser() {
570 global $setup_db_database_name;
571 global $setup_db_host_name;
572 global $setup_db_host_instance;
573 global $setup_db_port_num;
574 global $setup_db_admin_user_name;
575 global $setup_db_admin_password;
576 global $sugar_config;
577 global $setup_db_sugarsales_user;
578 global $setup_site_host_name;
579 global $setup_db_sugarsales_password;
581 echo $mod_strings['LBL_PERFORM_CREATE_DB_USER'];
583 $db = getDbConnection();
584 $db->createDbUser($setup_db_database_name, $setup_site_host_name, $setup_db_sugarsales_user, $setup_db_sugarsales_password);
585 $err = $db->lastError();
587 echo $mod_strings['LBL_PERFORM_DONE'];
589 echo "<div style='color:red;'>";
590 echo "An error occured when creating user:<br>";
593 installLog("An error occured when creating user: $err");
598 * ensures that the charset and collation for a given database is set
601 function handleDbCharsetCollation() {
603 global $setup_db_database_name;
604 global $setup_db_host_name;
605 global $setup_db_admin_user_name;
606 global $setup_db_admin_password;
607 global $sugar_config;
609 if($_SESSION['setup_db_type'] == 'mysql') {
610 $db = getDbConnection();
611 $db->query("ALTER DATABASE `{$setup_db_database_name}` DEFAULT CHARACTER SET utf8", true);
612 $db->query("ALTER DATABASE `{$setup_db_database_name}` DEFAULT COLLATE utf8_general_ci", true);
618 * creates the new database
620 function handleDbCreateDatabase() {
622 global $setup_db_database_name;
623 global $setup_db_host_name;
624 global $setup_db_host_instance;
625 global $setup_db_port_num;
626 global $setup_db_admin_user_name;
627 global $setup_db_admin_password;
628 global $sugar_config;
630 echo "{$mod_strings['LBL_PERFORM_CREATE_DB_1']} {$setup_db_database_name} {$mod_strings['LBL_PERFORM_CREATE_DB_2']} {$setup_db_host_name}...";
631 $db = getDbConnection();
632 if($db->dbExists($setup_db_database_name)) {
633 $db->dropDatabase($setup_db_database_name);
635 $db->createDatabase($setup_db_database_name);
637 echo $mod_strings['LBL_PERFORM_DONE'];
642 * handles creation of Log4PHP properties file
643 * This function has been deprecated. Use SugarLogger.
645 function handleLog4Php() {
649 function installLog($entry) {
652 '.gmdate("Y-m-d H:i:s").'...';
653 $log = clean_path(getcwd().'/install.log');
655 // create if not exists
656 if(!file_exists($log)) {
657 $fp = @sugar_fopen($log, 'w+'); // attempts to create file
658 if(!is_resource($fp)) {
659 $GLOBALS['log']->fatal('could not create the install.log file');
662 $fp = @sugar_fopen($log, 'a+'); // write pointer at end of file
663 if(!is_resource($fp)) {
664 $GLOBALS['log']->fatal('could not open/lock install.log file');
670 if(@fwrite($fp, $nl.$entry) === false) {
671 $GLOBALS['log']->fatal('could not write to install.log: '.$entry);
674 if(is_resource($fp)) {
682 * takes session vars and creates config.php
683 * @return array bottle collection of error messages
685 function handleSugarConfig() {
689 global $setup_db_host_name;
690 global $setup_db_host_instance;
691 global $setup_db_port_num;
692 global $setup_db_sugarsales_user;
693 global $setup_db_sugarsales_password;
694 global $setup_db_database_name;
695 global $setup_site_host_name;
696 global $setup_site_log_dir;
697 global $setup_site_log_file;
698 global $setup_site_session_path;
699 global $setup_site_guid;
700 global $setup_site_url;
701 global $setup_sugar_version;
702 global $sugar_config;
703 global $setup_site_log_level;
705 echo "<b>{$mod_strings['LBL_PERFORM_CONFIG_PHP']} (config.php)</b><br>";
706 ///////////////////////////////////////////////////////////////////////////////
707 //// $sugar_config SETTINGS
708 if( is_file('config.php') ){
709 $is_writable = is_writable('config.php');
710 // require is needed here (config.php is sometimes require'd from install.php)
711 require('config.php');
713 $is_writable = is_writable('.');
716 // build default sugar_config and merge with new values
717 $sugar_config = sugarArrayMerge(get_sugar_config_defaults(), $sugar_config);
718 // always lock the installer
719 $sugar_config['installer_locked'] = true;
720 // we're setting these since the user was given a fair chance to change them
721 $sugar_config['dbconfig']['db_host_name'] = $setup_db_host_name;
722 if(!empty($setup_db_host_instance)) {
723 $sugar_config['dbconfig']['db_host_instance'] = $setup_db_host_instance;
725 $sugar_config['dbconfig']['db_host_instance'] = '';
727 if(!isset($_SESSION['setup_db_manager'])) {
728 $_SESSION['setup_db_manager'] = DBManagerFactory::getManagerByType($_SESSION['setup_db_type']);
730 $sugar_config['dbconfig']['db_user_name'] = $setup_db_sugarsales_user;
731 $sugar_config['dbconfig']['db_password'] = $setup_db_sugarsales_password;
732 $sugar_config['dbconfig']['db_name'] = $setup_db_database_name;
733 $sugar_config['dbconfig']['db_type'] = $_SESSION['setup_db_type'];
734 $sugar_config['dbconfig']['db_port'] = $setup_db_port_num;
735 $sugar_config['dbconfig']['db_manager'] = $_SESSION['setup_db_manager'];
736 if(!empty($_SESSION['setup_db_options'])) {
737 $sugar_config['dbconfigoption'] = array_merge($sugar_config['dbconfigoption'], $_SESSION['setup_db_options']);
740 $sugar_config['cache_dir'] = $cache_dir;
741 $sugar_config['default_charset'] = $mod_strings['DEFAULT_CHARSET'];
742 $sugar_config['default_email_client'] = 'sugar';
743 $sugar_config['default_email_editor'] = 'html';
744 $sugar_config['host_name'] = $setup_site_host_name;
745 $sugar_config['js_custom_version'] = '';
746 $sugar_config['use_real_names'] = true;
747 $sugar_config['log_dir'] = $setup_site_log_dir;
748 $sugar_config['log_file'] = $setup_site_log_file;
750 /*nsingh(bug 22402): Consolidate logger settings under $config['logger'] as liked by the new logger! If log4pphp exists,
751 these settings will be overwritten by those in log4php.properties when the user access admin->system settings.*/
752 $sugar_config['logger'] =
753 array ('level'=>$setup_site_log_level,
756 'name' => 'sugarcrm',
757 'dateFormat' => '%c',
760 'suffix' => '%m_%Y'),
762 $sugar_config['session_dir'] = $setup_site_session_path;
763 $sugar_config['site_url'] = $setup_site_url;
764 $sugar_config['sugar_version'] = $setup_sugar_version;
765 $sugar_config['tmp_dir'] = $cache_dir.'xml/';
766 $sugar_config['upload_dir'] = 'upload/';
767 // $sugar_config['use_php_code_json'] = returnPhpJsonStatus(); // true on error
768 if( isset($_SESSION['setup_site_sugarbeet_anonymous_stats']) ){
769 $sugar_config['sugarbeet'] = $_SESSION['setup_site_sugarbeet_anonymous_stats'];
771 $sugar_config['demoData'] = $_SESSION['demoData'];
772 if( isset( $setup_site_guid ) ){
773 $sugar_config['unique_key'] = $setup_site_guid;
775 if(empty($sugar_config['unique_key'])){
776 $sugar_config['unique_key'] = md5( create_guid() );
778 // add installed langs to config
779 // entry in upgrade_history comes AFTER table creation
780 if(isset($_SESSION['INSTALLED_LANG_PACKS']) && is_array($_SESSION['INSTALLED_LANG_PACKS']) && !empty($_SESSION['INSTALLED_LANG_PACKS'])) {
781 foreach($_SESSION['INSTALLED_LANG_PACKS'] as $langZip) {
782 $lang = getSugarConfigLanguageArray($langZip);
784 $exLang = explode('::', $lang);
785 if(is_array($exLang) && count($exLang) == 3) {
786 $sugar_config['languages'][$exLang[0]] = $exLang[1];
791 if(file_exists('install/lang.config.php')){
792 include('install/lang.config.php');
793 if(!empty($config['languages'])){
794 foreach($config['languages'] as $lang=>$label){
795 $sugar_config['languages'][$lang] = $label;
800 ksort($sugar_config);
801 $sugar_config_string = "<?php\n" .
802 '// created: ' . date('Y-m-d H:i:s') . "\n" .
804 var_export($sugar_config, true) .
806 if($is_writable && write_array_to_file( "sugar_config", $sugar_config, "config.php")) {
810 echo "<p>{$mod_strings['ERR_PERFORM_CONFIG_PHP_1']}</p>\n";
811 echo "<p>{$mod_strings['ERR_PERFORM_CONFIG_PHP_2']}</p>\n";
812 echo "<TEXTAREA rows=\"15\" cols=\"80\">".$sugar_config_string."</TEXTAREA>";
813 echo "<p>{$mod_strings['ERR_PERFORM_CONFIG_PHP_3']}</p>";
815 $bottle[] = $mod_strings['ERR_PERFORM_CONFIG_PHP_4'];
819 //Now merge the config_si.php settings into config.php
820 if(file_exists('config.php') && file_exists('config_si.php'))
822 require_once('modules/UpgradeWizard/uw_utils.php');
823 merge_config_si_settings(false, 'config.php', 'config_si.php');
827 //// END $sugar_config
828 ///////////////////////////////////////////////////////////////////////////////
832 * (re)write the .htaccess file to prevent browser access to the log file
834 function handleHtaccess(){
836 $ignoreCase = (substr_count(strtolower($_SERVER['SERVER_SOFTWARE']), 'apache/2') > 0)?'(?i)':'';
837 $htaccess_file = ".htaccess";
839 $restrict_str = <<<EOQ
841 # BEGIN SUGARCRM RESTRICTIONS
842 RedirectMatch 403 {$ignoreCase}.*\.log$
843 RedirectMatch 403 {$ignoreCase}/+not_imported_.*\.txt
844 RedirectMatch 403 {$ignoreCase}/+(soap|cache|xtemplate|data|examples|include|log4php|metadata|modules)/+.*\.(php|tpl)
845 RedirectMatch 403 {$ignoreCase}/+emailmandelivery\.php
846 RedirectMatch 403 {$ignoreCase}/+upload
847 RedirectMatch 403 {$ignoreCase}/+custom/+blowfish
848 RedirectMatch 403 {$ignoreCase}/+cache/+diagnostic
849 RedirectMatch 403 {$ignoreCase}/+files\.md5$
850 # END SUGARCRM RESTRICTIONS
852 if(file_exists($htaccess_file)){
853 $fp = fopen($htaccess_file, 'r');
855 while($line = fgets($fp)){
857 if(preg_match("/\s*#\s*BEGIN\s*SUGARCRM\s*RESTRICTIONS/i", $line))$skip = true;
858 if(!$skip)$contents .= $line;
859 if(preg_match("/\s*#\s*END\s*SUGARCRM\s*RESTRICTIONS/i", $line))$skip = false;
862 $status = file_put_contents($htaccess_file, $contents . $restrict_str);
864 echo "<p>{$mod_strings['ERR_PERFORM_HTACCESS_1']}<span class=stop>{$htaccess_file}</span> {$mod_strings['ERR_PERFORM_HTACCESS_2']}</p>\n";
865 echo "<p>{$mod_strings['ERR_PERFORM_HTACCESS_3']}</p>\n";
872 * (re)write the web.config file to prevent browser access to the log file
874 function handleWebConfig()
876 if ( !isset($_SERVER['IIS_UrlRewriteModule']) ) {
880 global $setup_site_log_dir;
881 global $setup_site_log_file;
882 global $sugar_config;
884 // Bug 36968 - Fallback to using $sugar_config values when we are not calling this from the installer
885 if (empty($setup_site_log_file)) {
886 $setup_site_log_file = $sugar_config['log_file'];
887 if ( empty($sugar_config['log_file']) ) {
888 $setup_site_log_file = 'sugarcrm.log';
891 if (empty($setup_site_log_dir)) {
892 $setup_site_log_dir = $sugar_config['log_dir'];
893 if ( empty($sugar_config['log_dir']) ) {
894 $setup_site_log_dir = '.';
898 $prefix = $setup_site_log_dir.empty($setup_site_log_dir)?'':'/';
901 $config_array = array(
902 array('1'=> $prefix.str_replace('.','\\.',$setup_site_log_file).'\\.*' ,'2'=>'log_file_restricted.html'),
903 array('1'=> $prefix.'install.log' ,'2'=>'log_file_restricted.html'),
904 array('1'=> $prefix.'upgradeWizard.log' ,'2'=>'log_file_restricted.html'),
905 array('1'=> $prefix.'emailman.log' ,'2'=>'log_file_restricted.html'),
906 array('1'=>'not_imported_.*.txt' ,'2'=>'log_file_restricted.html'),
907 array('1'=>'XTemplate/(.*)/(.*).php' ,'2'=>'index.php'),
908 array('1'=>'data/(.*).php' ,'2'=>'index.php'),
909 array('1'=>'examples/(.*).php' ,'2'=>'index.php'),
910 array('1'=>'include/(.*).php' ,'2'=>'index.php'),
911 array('1'=>'include/(.*)/(.*).php' ,'2'=>'index.php'),
912 array('1'=>'log4php/(.*).php' ,'2'=>'index.php'),
913 array('1'=>'log4php/(.*)/(.*)' ,'2'=>'index.php'),
914 array('1'=>'metadata/(.*)/(.*).php' ,'2'=>'index.php'),
915 array('1'=>'modules/(.*)/(.*).php' ,'2'=>'index.php'),
916 array('1'=>'soap/(.*).php' ,'2'=>'index.php'),
917 array('1'=>'emailmandelivery.php' ,'2'=>'index.php'),
918 array('1'=>'cron.php' ,'2'=>'index.php'),
919 array('1'=> $sugar_config['upload_dir'].'.*' ,'2'=>'index.php'),
923 $xmldoc = new XMLWriter();
924 $xmldoc->openURI('web.config');
925 $xmldoc->setIndent(true);
926 $xmldoc->setIndentString(' ');
927 $xmldoc->startDocument('1.0','UTF-8');
928 $xmldoc->startElement('configuration');
929 $xmldoc->startElement('system.webServer');
930 $xmldoc->startElement('rewrite');
931 $xmldoc->startElement('rules');
932 for ($i = 0; $i < count($config_array); $i++) {
933 $xmldoc->startElement('rule');
934 $xmldoc->writeAttribute('name', "redirect$i");
935 $xmldoc->writeAttribute('stopProcessing', 'true');
936 $xmldoc->startElement('match');
937 $xmldoc->writeAttribute('url', $config_array[$i]['1']);
938 $xmldoc->endElement();
939 $xmldoc->startElement('action');
940 $xmldoc->writeAttribute('type', 'Redirect');
941 $xmldoc->writeAttribute('url', $config_array[$i]['2']);
942 $xmldoc->writeAttribute('redirectType', 'Found');
943 $xmldoc->endElement();
944 $xmldoc->endElement();
946 $xmldoc->endElement();
947 $xmldoc->endElement();
948 $xmldoc->endElement();
949 $xmldoc->endElement();
950 $xmldoc->endDocument();
955 * Drop old tables if table exists and told to drop it
957 function drop_table_install( &$focus ){
961 $result = $db->tableExists($focus->table_name);
964 $focus->drop_tables();
965 $GLOBALS['log']->info("Dropped old ".$focus->table_name." table.");
969 $GLOBALS['log']->info("Did not need to drop old ".$focus->table_name." table. It doesn't exist.");
974 // Creating new tables if they don't exist.
975 function create_table_if_not_exist( &$focus ){
977 $table_created = false;
979 // normal code follows
980 $result = $db->tableExists($focus->table_name);
982 $GLOBALS['log']->info("Table ".$focus->table_name." already exists.");
984 $focus->create_tables();
985 $GLOBALS['log']->info("Created ".$focus->table_name." table.");
986 $table_created = true;
988 return $table_created;
993 function create_default_users(){
995 global $setup_site_admin_password;
996 global $setup_site_admin_user_name;
997 global $create_default_user;
998 global $sugar_config;
999 global $current_user;
1000 require_once('install/UserDemoData.php');
1002 //Create default admin user
1003 $current_user = new User();
1004 $current_user->id = 1;
1005 $current_user->new_with_id = true;
1006 $current_user->last_name = 'Administrator';
1007 //$user->user_name = 'admin';
1008 $current_user->user_name = $setup_site_admin_user_name;
1009 $current_user->title = "Administrator";
1010 $current_user->status = 'Active';
1011 $current_user->is_admin = true;
1012 $current_user->employee_status = 'Active';
1013 //$user->user_password = $user->encrypt_password($setup_site_admin_password);
1014 $current_user->user_hash = strtolower(md5($setup_site_admin_password));
1015 $current_user->email = '';
1016 $current_user->picture = UserDemoData::_copy_user_image($current_user->id);
1017 $current_user->save();
1019 // echo 'Creating RSS Feeds';
1020 //$feed = new Feed();
1021 //$feed->createRSSHomePage($user->id);
1024 // We need to change the admin user to a fixed id of 1.
1025 // $query = "update users set id='1' where user_name='$user->user_name'";
1026 // $result = $db->query($query, true, "Error updating admin user ID: ");
1028 $GLOBALS['log']->info("Created ".$current_user->table_name." table. for user $current_user->id");
1030 if( $create_default_user ){
1031 $default_user = new User();
1032 $default_user->last_name = $sugar_config['default_user_name'];
1033 $default_user->user_name = $sugar_config['default_user_name'];
1034 $default_user->status = 'Active';
1035 if( isset($sugar_config['default_user_is_admin']) && $sugar_config['default_user_is_admin'] ){
1036 $default_user->is_admin = true;
1038 //$default_user->user_password = $default_user->encrypt_password($sugar_config['default_password']);
1039 $default_user->user_hash = strtolower(md5($sugar_config['default_password']));
1040 $default_user->save();
1041 //$feed->createRSSHomePage($user->id);
1045 function set_admin_password( $password ) {
1049 $encrypted_password = $user->encrypt_password($password);
1050 $user_hash = strtolower(md5($password));
1052 //$query = "update users set user_password='$encrypted_password', user_hash='$user_hash' where id='1'";
1053 $query = "update users set user_hash='$user_hash' where id='1'";
1058 function insert_default_settings(){
1060 global $setup_sugar_version;
1061 global $sugar_db_version;
1064 $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'fromaddress', 'do_not_reply@example.com')");
1065 $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'fromname', 'SugarCRM')");
1066 $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'send_by_default', '1')");
1067 $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'on', '1')");
1068 $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'send_from_assigning_user', '0')");
1069 /* cn: moved to OutboundEmail class
1070 $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpserver', 'localhost')");
1071 $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpport', '25')");
1072 $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'sendtype', 'smtp')");
1073 $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpuser', '')");
1074 $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtppass', '')");
1075 $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpauth_req', '0')");
1077 $db->query("INSERT INTO config (category, name, value) VALUES ('info', 'sugar_version', '" . $sugar_db_version . "')");
1078 $db->query("INSERT INTO config (category, name, value) VALUES ('MySettings', 'tab', '')");
1079 $db->query("INSERT INTO config (category, name, value) VALUES ('portal', 'on', '0')");
1083 //insert default tracker settings
1084 $db->query("INSERT INTO config (category, name, value) VALUES ('tracker', 'Tracker', '1')");
1088 $db->query( "INSERT INTO config (category, name, value) VALUES ( 'system', 'skypeout_on', '1')" );
1099 // Returns true if the given file/dir has been made writable (or is already
1101 function make_writable($file)
1105 if(is_file($file) || is_dir($file))
1107 if(is_writable($file))
1113 $original_fileperms = fileperms($file);
1115 // add user writable permission
1116 $new_fileperms = $original_fileperms | 0x0080;
1117 @sugar_chmod($file, $new_fileperms);
1119 if(is_writable($file))
1125 // add group writable permission
1126 $new_fileperms = $original_fileperms | 0x0010;
1127 @chmod($file, $new_fileperms);
1129 if(is_writable($file))
1135 // add world writable permission
1136 $new_fileperms = $original_fileperms | 0x0002;
1137 @chmod($file, $new_fileperms);
1139 if(is_writable($file))
1151 function recursive_make_writable($start_file)
1153 $ret_val = make_writable($start_file);
1155 if($ret_val && is_dir($start_file))
1157 // PHP 4 alternative to scandir()
1159 $dh = opendir($start_file);
1160 $filename = readdir($dh);
1161 while(!empty($filename))
1163 if($filename != '.' && $filename != '..' && $filename != '.svn')
1165 $files[] = $filename;
1168 $filename = readdir($dh);
1171 foreach($files as $file)
1173 $ret_val = recursive_make_writable($start_file . '/' . $file);
1177 $_SESSION['unwriteable_module_files'][dirname($file)] = dirname($file);
1178 $fnl_ret_val = false;
1185 $unwriteable_directory = is_dir($start_file) ? $start_file : dirname($start_file);
1186 if($unwriteable_directory[0] == '.'){$unwriteable_directory = substr($unwriteable_directory,1);}
1187 $_SESSION['unwriteable_module_files'][$unwriteable_directory] = $unwriteable_directory;
1188 $_SESSION['unwriteable_module_files']['failed'] = true;
1194 function recursive_is_writable($start_file)
1196 $ret_val = is_writable($start_file);
1198 if($ret_val && is_dir($start_file))
1200 // PHP 4 alternative to scandir()
1202 $dh = opendir($start_file);
1203 $filename = readdir($dh);
1204 while(!empty($filename))
1206 if($filename != '.' && $filename != '..' && $filename != '.svn')
1208 $files[] = $filename;
1211 $filename = readdir($dh);
1214 foreach($files as $file)
1216 $ret_val = recursive_is_writable($start_file . '/' . $file);
1228 // one place for form validation/conversion to boolean
1229 function get_boolean_from_request( $field ){
1230 if( !isset($_REQUEST[$field]) ){
1234 if( ($_REQUEST[$field] == 'on') || ($_REQUEST[$field] == 'yes') ){
1242 function stripslashes_checkstrings($value){
1243 if(is_string($value)){
1244 return stripslashes($value);
1250 function print_debug_array( $name, $debug_array ){
1251 ksort( $debug_array );
1253 print( "$name vars:\n" );
1256 foreach( $debug_array as $key => $value ){
1257 if( stristr( $key, "password" ) ){
1260 print( " [$key] => $value\n" );
1266 function print_debug_comment(){
1267 if( !empty($_REQUEST['debug']) ){
1268 $_SESSION['debug'] = $_REQUEST['debug'];
1271 if( !empty($_SESSION['debug']) && ($_SESSION['debug'] == 'true') ){
1272 print( "<!-- debug is on (to turn off, hit any page with 'debug=false' as a URL parameter.\n" );
1274 print_debug_array( "Session", $_SESSION );
1275 print_debug_array( "Request", $_REQUEST );
1276 print_debug_array( "Post", $_POST );
1277 print_debug_array( "Get", $_GET );
1283 function validate_systemOptions() {
1284 global $mod_strings;
1286 $db = DBManagerFactory::getTypeInstance($_SESSION['setup_db_type']);
1288 $errors[] = "<span class='error'>".$mod_strings['ERR_DB_INVALID']."</span>";
1290 $_SESSION['setup_db_manager'] = get_class($db);
1296 function validate_dbConfig() {
1297 global $mod_strings;
1298 require_once('install/checkDBSettings.php');
1299 return checkDBSettings(true);
1303 function validate_siteConfig($type){
1304 global $mod_strings;
1308 if(empty($_SESSION['setup_system_name'])){
1309 $errors[] = "<span class='error'>".$mod_strings['LBL_REQUIRED_SYSTEM_NAME']."</span>";
1311 if($_SESSION['setup_site_url'] == ''){
1312 $errors[] = "<span class='error'>".$mod_strings['ERR_URL_BLANK']."</span>";
1315 if($_SESSION['setup_site_admin_user_name'] == '') {
1316 $errors[] = "<span class='error'>".$mod_strings['ERR_ADMIN_USER_NAME_BLANK']."</span>";
1319 if($_SESSION['setup_site_admin_password'] == ''){
1320 $errors[] = "<span class='error'>".$mod_strings['ERR_ADMIN_PASS_BLANK']."</span>";
1323 if($_SESSION['setup_site_admin_password'] != $_SESSION['setup_site_admin_password_retype']){
1324 $errors[] = "<span class='error'>".$mod_strings['ERR_PASSWORD_MISMATCH']."</span>";
1327 if(!empty($_SESSION['setup_site_custom_session_path']) && $_SESSION['setup_site_session_path'] == ''){
1328 $errors[] = "<span class='error'>".$mod_strings['ERR_SESSION_PATH']."</span>";
1331 if(!empty($_SESSION['setup_site_custom_session_path']) && $_SESSION['setup_site_session_path'] != ''){
1332 if(is_dir($_SESSION['setup_site_session_path'])){
1333 if(!is_writable($_SESSION['setup_site_session_path'])){
1334 $errors[] = "<span class='error'>".$mod_strings['ERR_SESSION_DIRECTORY']."</span>";
1338 $errors[] = "<span class='error'>".$mod_strings['ERR_SESSION_DIRECTORY_NOT_EXISTS']."</span>";
1342 if(!empty($_SESSION['setup_site_custom_log_dir']) && $_SESSION['setup_site_log_dir'] == ''){
1343 $errors[] = "<span class='error'>".$mod_strings['ERR_LOG_DIRECTORY_NOT_EXISTS']."</span>";
1346 if(!empty($_SESSION['setup_site_custom_log_dir']) && $_SESSION['setup_site_log_dir'] != ''){
1347 if(is_dir($_SESSION['setup_site_log_dir'])){
1348 if(!is_writable($_SESSION['setup_site_log_dir'])) {
1349 $errors[] = "<span class='error'>".$mod_strings['ERR_LOG_DIRECTORY_NOT_WRITABLE']."</span>";
1353 $errors[] = "<span class='error'>".$mod_strings['ERR_LOG_DIRECTORY_NOT_EXISTS']."</span>";
1357 if(!empty($_SESSION['setup_site_specify_guid']) && $_SESSION['setup_site_guid'] == ''){
1358 $errors[] = "<span class='error'>".$mod_strings['ERR_SITE_GUID']."</span>";
1366 function pullSilentInstallVarsIntoSession() {
1367 global $mod_strings;
1368 global $sugar_config;
1371 if( file_exists('config_si.php') ){
1372 require_once('config_si.php');
1374 else if( empty($sugar_config_si) ){
1375 die( $mod_strings['ERR_SI_NO_CONFIG'] );
1378 $config_subset = array (
1379 'setup_site_url' => isset($sugar_config['site_url']) ? $sugar_config['site_url'] : '',
1380 'setup_db_host_name' => isset($sugar_config['dbconfig']['db_host_name']) ? $sugar_config['dbconfig']['db_host_name'] : '',
1381 'setup_db_host_instance' => isset($sugar_config['dbconfig']['db_host_instance']) ? $sugar_config['dbconfig']['db_host_instance'] : '',
1382 'setup_db_sugarsales_user' => isset($sugar_config['dbconfig']['db_user_name']) ? $sugar_config['dbconfig']['db_user_name'] : '',
1383 'setup_db_sugarsales_password' => isset($sugar_config['dbconfig']['db_password']) ? $sugar_config['dbconfig']['db_password'] : '',
1384 'setup_db_database_name' => isset($sugar_config['dbconfig']['db_name']) ? $sugar_config['dbconfig']['db_name'] : '',
1385 'setup_db_type' => isset($sugar_config['dbconfig']['db_type']) ? $sugar_config['dbconfig']['db_type'] : '',
1386 'setup_db_port_num' => isset($sugar_config['dbconfig']['db_port']) ? $sugar_config['dbconfig']['db_port'] : '',
1387 'setup_db_options' => !empty($sugar_config['dbconfigoptions']) ? $sugar_config['dbconfigoptions'] : array(),
1389 // third array of values derived from above values
1391 'setup_site_admin_password_retype' => $sugar_config_si['setup_site_admin_password'],
1392 'setup_db_sugarsales_password_retype' => $config_subset['setup_db_sugarsales_password'],
1395 $needles = array('setup_db_create_database','setup_db_create_sugarsales_user','setup_license_key_users',
1396 'setup_license_key_expire_date','setup_license_key', 'setup_num_lic_oc',
1397 'default_currency_iso4217', 'default_currency_name', 'default_currency_significant_digits',
1398 'default_currency_symbol', 'default_date_format', 'default_time_format', 'default_decimal_seperator',
1399 'default_export_charset', 'default_language', 'default_locale_name_format', 'default_number_grouping_seperator',
1400 'export_delimiter', 'cache_dir', 'setup_db_options');
1401 copyFromArray($sugar_config_si, $needles, $derived);
1402 $all_config_vars = array_merge( $config_subset, $sugar_config_si, $derived );
1404 // bug 16860 tyoung - trim leading and trailing whitespace from license_key
1405 if (isset($all_config_vars['setup_license_key'])) {
1406 $all_config_vars['setup_license_key'] = trim($all_config_vars['setup_license_key']);
1409 foreach( $all_config_vars as $key => $value ){
1410 $_SESSION[$key] = $value;
1415 * given an array it will check to determine if the key exists in the array, if so
1416 * it will addd to the return array
1418 * @param intput_array haystack to check
1419 * @param needles list of needles to search for
1420 * @param output_array the array to add the keys to
1422 function copyFromArray($input_array, $needles, $output_array){
1423 foreach($needles as $needle){
1424 if(isset($input_array[$needle])){
1425 $output_array[$needle] = $input_array[$needle];
1433 * handles language pack uploads - code based off of upload_file->final_move()
1434 * puts it into the cache/upload dir to be handed off to langPackUnpack();
1436 * @param object file UploadFile object
1437 * @return bool true if successful
1439 function langPackFinalMove($file) {
1440 global $sugar_config;
1441 //."upgrades/langpack/"
1442 $destination = $sugar_config['upload_dir'].$file->stored_file_name;
1443 if(!move_uploaded_file($_FILES[$file->field_name]['tmp_name'], $destination)) {
1444 die ("ERROR: can't move_uploaded_file to $destination. You should try making the directory writable by the webserver");
1449 function getLicenseDisplay($type, $manifest, $zipFile, $next_step, $license_file, $clean_file) {
1450 return PackageManagerDisplay::getLicenseDisplay($license_file, 'install.php', $next_step, $zipFile, $type, $manifest, $clean_file);
1455 * creates the remove/delete form for langpack page
1456 * @param string type commit/remove
1457 * @param string manifest path to manifest file
1458 * @param string zipFile path to uploaded zip file
1459 * @param int nextstep current step
1460 * @return string ret <form> for this package
1462 function getPackButton($type, $manifest, $zipFile, $next_step, $uninstallable='Yes', $showButtons=true) {
1463 global $mod_strings;
1465 $button = $mod_strings['LBL_LANG_BUTTON_COMMIT'];
1466 if($type == 'remove') {
1467 $button = $mod_strings['LBL_LANG_BUTTON_REMOVE'];
1468 } elseif($type == 'uninstall') {
1469 $button = $mod_strings['LBL_LANG_BUTTON_UNINSTALL'];
1472 $disabled = ($uninstallable == 'Yes') ? false : true;
1474 $ret = "<form name='delete{$zipFile}' action='install.php' method='POST'>
1475 <input type='hidden' name='current_step' value='{$next_step}'>
1476 <input type='hidden' name='goto' value='{$mod_strings['LBL_CHECKSYS_RECHECK']}'>
1477 <input type='hidden' name='languagePackAction' value='{$type}'>
1478 <input type='hidden' name='manifest' value='".urlencode($manifest)."'>
1479 <input type='hidden' name='zipFile' value='".urlencode($zipFile)."'>
1480 <input type='hidden' name='install_type' value='custom'>";
1481 if(!$disabled && $showButtons) {
1482 $ret .= "<input type='submit' value='{$button}' class='button'>";
1489 * finds all installed languages and returns an array with the names
1490 * @return array langs array of installed languages
1492 function getInstalledLanguages() {
1493 $langDir = 'include/language/';
1494 $dh = opendir($langDir);
1497 while($file = readdir($dh)) {
1498 if(substr($file, -3) == 'php') {
1507 * searches upgrade dir for lang pack files.
1509 * @return string HTML of available lang packs
1511 function getLangPacks($display_commit = true, $types = array('langpack'), $notice_text = '') {
1512 global $mod_strings;
1514 global $base_upgrade_dir;
1516 if(empty($notice_text)){
1517 $notice_text = $mod_strings['LBL_LANG_PACK_READY'];
1519 $ret = "<tr><td colspan=7 align=left>{$notice_text}</td></tr>";
1520 //$ret .="<table width='100%' cellpadding='0' cellspacing='0' border='0'>";
1522 <td width='20%' ><b>{$mod_strings['LBL_ML_NAME']}</b></td>
1523 <td width='15%' ><b>{$mod_strings['LBL_ML_VERSION']}</b></td>
1524 <td width='15%' ><b>{$mod_strings['LBL_ML_PUBLISHED']}</b></td>
1525 <td width='15%' ><b>{$mod_strings['LBL_ML_UNINSTALLABLE']}</b></td>
1526 <td width='20%' ><b>{$mod_strings['LBL_ML_DESCRIPTION']}</b></td>
1527 <td width='7%' ></td>
1528 <td width='1%' ></td>
1529 <td width='7%' ></td>
1533 // duh, new installs won't have the upgrade folders
1534 if(!is_dir($base_upgrade_dir)) {
1535 mkdir_recursive( $base_upgrade_dir);
1537 $subdirs = array('full', 'langpack', 'module', 'patch', 'theme', 'temp');
1538 foreach( $subdirs as $subdir ){
1539 mkdir_recursive( "$base_upgrade_dir/$subdir" );
1542 $files = findAllFiles($base_upgrade_dir, $files);
1544 unset($_SESSION['hidden_input']);
1546 foreach($files as $file) {
1547 if(!preg_match("#.*\.zip\$#", $file)) {
1551 // skip installed lang packs
1552 if(isset($_SESSION['INSTALLED_LANG_PACKS']) && in_array($file, $_SESSION['INSTALLED_LANG_PACKS'])) {
1556 // handle manifest.php
1557 $target_manifest = remove_file_extension( $file ) . '-manifest.php';
1558 $license_file = remove_file_extension( $file ) . '-license.txt';
1559 include($target_manifest);
1562 if(!in_array(strtolower($manifest['type']), $types))
1566 $md5_matches = array();
1567 if($manifest['type'] == 'module'){
1568 $uh = new UpgradeHistory();
1569 $upgrade_content = clean_path($file);
1570 $the_base = basename($upgrade_content);
1571 $the_md5 = md5_file($upgrade_content);
1572 $md5_matches = $uh->findByMd5($the_md5);
1575 if($manifest['type']!= 'module' || 0 == sizeof($md5_matches)){
1576 $name = empty($manifest['name']) ? $file : $manifest['name'];
1577 $version = empty($manifest['version']) ? '' : $manifest['version'];
1578 $published_date = empty($manifest['published_date']) ? '' : $manifest['published_date'];
1580 $description = empty($manifest['description']) ? 'None' : $manifest['description'];
1581 $uninstallable = empty($manifest['is_uninstallable']) ? 'No' : 'Yes';
1582 $manifest_type = $manifest['type'];
1583 $commitPackage = getPackButton('commit', $target_manifest, $file, $next_step);
1584 $deletePackage = getPackButton('remove', $target_manifest, $file, $next_step);
1585 //$ret .="<table width='100%' cellpadding='0' cellspacing='0' border='0'>";
1587 $ret .= "<td width='20%' >".$name."</td>";
1588 $ret .= "<td width='15%' >".$version."</td>";
1589 $ret .= "<td width='15%' >".$published_date."</td>";
1590 $ret .= "<td width='15%' >".$uninstallable."</td>";
1591 $ret .= "<td width='20%' >".$description."</td>";
1594 $ret .= "<td width='7%'>{$commitPackage}</td>";
1595 $ret .= "<td width='1%'></td>";
1596 $ret .= "<td width='7%'>{$deletePackage}</td>";
1597 $ret .= "</td></tr>";
1599 $clean_field_name = "accept_lic_".str_replace('.', '_', urlencode(basename($file)));
1601 if(is_file($license_file)){
1603 $ret .= "<tr><td colspan=6>";
1604 $ret .= getLicenseDisplay('commit', $target_manifest, $file, $next_step, $license_file, $clean_field_name);
1605 $ret .= "</td></tr>";
1606 $hidden_input .= "<input type='hidden' name='$clean_field_name' id='$clean_field_name' value='no'>";
1608 $hidden_input .= "<input type='hidden' name='$clean_field_name' id='$clean_field_name' value='yes'>";
1612 $_SESSION['hidden_input'] = $hidden_input;
1614 if(count($files) > 0 ) {
1615 $ret .= "</tr><td colspan=7>";
1616 $ret .= "<form name='commit' action='install.php' method='POST'>
1617 <input type='hidden' name='current_step' value='{$next_step}'>
1618 <input type='hidden' name='goto' value='Re-check'>
1619 <input type='hidden' name='languagePackAction' value='commit'>
1620 <input type='hidden' name='install_type' value='custom'>
1623 $ret .= "</td></tr>";
1625 $ret .= "</tr><td colspan=7><i>{$mod_strings['LBL_LANG_NO_PACKS']}</i></td></tr>";
1630 if ( !function_exists('extractFile') ) {
1631 function extractFile( $zip_file, $file_in_zip, $base_tmp_upgrade_dir){
1632 $my_zip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
1633 unzip_file( $zip_file, $file_in_zip, $my_zip_dir );
1634 return( "$my_zip_dir/$file_in_zip" );
1638 if ( !function_exists('extractManifest') ) {
1639 function extractManifest( $zip_file,$base_tmp_upgrade_dir ) {
1640 return( extractFile( $zip_file, "manifest.php",$base_tmp_upgrade_dir ) );
1644 if ( !function_exists('unlinkTempFiles') ) {
1645 function unlinkTempFiles($manifest='', $zipFile='') {
1646 global $sugar_config;
1648 @unlink($_FILES['language_pack']['tmp_name']);
1649 if(!empty($manifest))
1651 if(!empty($zipFile)) {
1652 //@unlink($zipFile);
1653 $tmpZipFile = substr($zipFile, strpos($zipFile, 'langpack/') + 9, strlen($zipFile));
1654 @unlink($sugar_config['upload_dir'].$tmpZipFile);
1657 rmdir_recursive($sugar_config['upload_dir']."upgrades/temp");
1658 sugar_mkdir($sugar_config['upload_dir']."upgrades/temp");
1662 function langPackUnpack($unpack_type, $full_file)
1664 global $sugar_config;
1665 global $base_upgrade_dir;
1666 global $base_tmp_upgrade_dir;
1668 $manifest = array();
1669 if(!empty($full_file)){
1670 $base_filename = pathinfo(urldecode($full_file), PATHINFO_FILENAME );
1672 return "Empty filename supplied";
1674 $manifest_file = extractManifest($full_file, $base_tmp_upgrade_dir);
1675 if($unpack_type == 'module')
1676 $license_file = extractFile($full_file, 'LICENSE.txt', $base_tmp_upgrade_dir);
1678 if(is_file($manifest_file)) {
1680 if($unpack_type == 'module' && is_file($license_file)){
1681 copy($license_file, $base_upgrade_dir.'/'.$unpack_type.'/'.$base_filename."-license.txt");
1683 copy($manifest_file, $base_upgrade_dir.'/'.$unpack_type.'/'.$base_filename."-manifest.php");
1685 require_once( $manifest_file );
1686 validate_manifest( $manifest );
1687 $upgrade_zip_type = $manifest['type'];
1689 mkdir_recursive( "$base_upgrade_dir/$upgrade_zip_type" );
1690 $target_path = "$base_upgrade_dir/$upgrade_zip_type/$base_filename";
1691 $target_manifest = $target_path . "-manifest.php";
1693 if( isset($manifest['icon']) && $manifest['icon'] != "" ) {
1694 $icon_location = extractFile( $full_file, $manifest['icon'], $base_tmp_upgrade_dir );
1695 $path_parts = pathinfo( $icon_location );
1696 copy( $icon_location, $target_path . "-icon." . $path_parts['extension'] );
1699 // move file from uploads to cache
1700 // FIXME: where should it be?
1701 if( copy( $full_file , $target_path.".zip" ) ){
1702 copy( $manifest_file, $target_manifest );
1703 unlink($full_file); // remove tempFile
1704 return "The file $base_filename has been uploaded.<br>\n";
1706 unlinkTempFiles($manifest_file, $full_file);
1707 return "There was an error uploading the file, please try again!<br>\n";
1710 die("The zip file is missing a manifest.php file. Cannot proceed.");
1712 unlinkTempFiles($manifest_file, '');
1715 if ( !function_exists('validate_manifest') ) {
1716 function validate_manifest( $manifest ){
1717 // takes a manifest.php manifest array and validates contents
1719 global $sugar_version;
1720 global $sugar_flavor;
1721 global $mod_strings;
1723 if( !isset($manifest['type']) ){
1724 die($mod_strings['ERROR_MANIFEST_TYPE']);
1726 $type = $manifest['type'];
1727 if( getInstallType( "/$type/" ) == "" ){
1728 die($mod_strings['ERROR_PACKAGE_TYPE']. ": '" . $type . "'." );
1731 return true; // making this a bit more relaxed since we updated the language extraction and merge capabilities
1734 if( isset($manifest['acceptable_sugar_versions']) ){
1735 $version_ok = false;
1736 $matches_empty = true;
1737 if( isset($manifest['acceptable_sugar_versions']['exact_matches']) ){
1738 $matches_empty = false;
1739 foreach( $manifest['acceptable_sugar_versions']['exact_matches'] as $match ){
1740 if( $match == $sugar_version ){
1745 if( !$version_ok && isset($manifest['acceptable_sugar_versions']['regex_matches']) ){
1746 $matches_empty = false;
1747 foreach( $manifest['acceptable_sugar_versions']['regex_matches'] as $match ){
1748 if( preg_match( "/$match/", $sugar_version ) ){
1754 if( !$matches_empty && !$version_ok ){
1755 die( $mod_strings['ERROR_VERSION_INCOMPATIBLE'] . $sugar_version );
1759 if( isset($manifest['acceptable_sugar_flavors']) && sizeof($manifest['acceptable_sugar_flavors']) > 0 ){
1761 foreach( $manifest['acceptable_sugar_flavors'] as $match ){
1762 if( $match == $sugar_flavor ){
1767 //die( $mod_strings['ERROR_FLAVOR_INCOMPATIBLE'] . $sugar_flavor );
1773 if ( !function_exists('getInstallType') ) {
1774 function getInstallType( $type_string ){
1776 $subdirs = array('full', 'langpack', 'module', 'patch', 'theme', 'temp');
1777 foreach( $subdirs as $subdir ){
1778 if( preg_match( "#/$subdir/#", $type_string ) ){
1782 // return empty if no match
1789 //mysqli connector has a separate parameter for port.. We need to separate it out from the host name
1790 function getHostPortFromString($hostname=''){
1792 $pos=strpos($hostname,':');
1794 //no need to process as string is empty or does not contain ':' delimiter
1798 $hostArr = explode(':', $hostname);
1804 function getLicenseContents($filename)
1807 if(file_exists($filename) && filesize($filename) >0){
1808 $license_file = trim(file_get_contents($filename));
1810 return $license_file;
1820 ///////////////////////////////////////////////////////////////////////////////
1821 //// FROM POPULATE SEED DATA
1823 'qa', 'dev', 'beans',
1824 'info', 'sales', 'support',
1825 'kid', 'the', 'section',
1826 'sugar', 'hr', 'im',
1827 'kid', 'vegan', 'phone',
1830 ".com", ".org", ".net", ".tv", ".cn", ".co.jp", ".us",
1831 ".edu", ".tw", ".de", ".it", ".co.uk", ".info", ".biz",
1836 * creates a random, DNS-clean webaddress
1838 function createWebAddress() {
1842 $one = $seed[rand(0, count($seed)-1)];
1843 $two = $seed[rand(0, count($seed)-1)];
1844 $tld = $tlds[rand(0, count($tlds)-1)];
1846 return "www.{$one}{$two}{$tld}";
1850 * creates a random email address
1853 function createEmailAddress() {
1857 $part[0] = $seed[rand(0, count($seed)-1)];
1858 $part[1] = $seed[rand(0, count($seed)-1)];
1859 $part[2] = $seed[rand(0, count($seed)-1)];
1861 $tld = $tlds[rand(0, count($tlds)-1)];
1866 for($i=0; $i<$len; $i++) {
1867 $ret .= (empty($ret)) ? '' : '.';
1872 $ret .= rand(10, 99);
1875 return "{$ret}@example{$tld}";
1879 function add_digits($quantity, &$string, $min = 0, $max = 9) {
1880 for($i=0; $i < $quantity; $i++) {
1881 $string .= mt_rand($min,$max);
1885 function create_phone_number() {
1887 add_digits(3, $phone);
1889 add_digits(3, $phone);
1891 add_digits(4, $phone);
1896 function create_date($year=null,$mnth=null,$day=null)
1899 $now = $timedate->getNow();
1900 if ($day==null) $day=$now->day+mt_rand(0,365);
1901 return $timedate->asDbDate($now->get_day_begin($day, $mnth, $year));
1904 function create_current_date_time()
1907 return $timedate->nowDb();
1910 function create_time($hr=null,$min=null,$sec=null)
1913 $date = TimeDate::fromTimestamp(0);
1914 if ($hr==null) $hr=mt_rand(6,19);
1915 if ($min==null) $min=(mt_rand(0,3)*15);
1916 if ($sec==null) $sec=0;
1917 return $timedate->asDbTime($date->setDate(2007, 10, 7)->setTime($hr, $min, $sec));
1920 function create_past_date()
1923 $now = $timedate->getNow(true);
1924 $day=$now->day-mt_rand(1, 365);
1925 return $timedate->asUserDate($now->get_day_begin($day));
1929 * This method will look for a file modules_post_install.php in the root directory and based on the
1930 * contents of this file, it will silently install any modules as specified in this array.
1932 function post_install_modules(){
1933 if(is_file('modules_post_install.php')){
1934 global $current_user, $mod_strings;
1935 $current_user = new User();
1936 $current_user->is_admin = '1';
1937 require_once('ModuleInstall/PackageManager/PackageManager.php');
1938 require_once('modules_post_install.php');
1939 //we now have the $modules_to_install array in memory
1940 $pm = new PackageManager();
1941 $old_mod_strings = $mod_strings;
1942 foreach($modules_to_install as $module_to_install){
1943 if(is_file($module_to_install)){
1944 $pm->performSetup($module_to_install, 'module', false);
1945 $file_to_install = sugar_cached('upload/upgrades/module/').basename($module_to_install);
1946 $_REQUEST['install_file'] = $file_to_install;
1947 $pm->performInstall($file_to_install);
1950 $mod_strings = $old_mod_strings;
1954 function get_help_button_url(){
1955 $help_url = 'http://www.sugarcrm.com/docs/Administration_Guides/CommunityEdition_Admin_Guide_5.0/toc.html';
1960 function create_db_user_creds($numChars=10){
1961 $numChars = 7; // number of chars in the password
1962 //chars to select from
1963 $charBKT = "abcdefghijklmnpqrstuvwxyz123456789ABCDEFGHIJKLMNPQRSTUVWXYZ";
1964 // seed the random number generator
1965 srand((double)microtime()*1000000);
1967 for ($i=0;$i<$numChars;$i++) // loop and create password
1968 $password = $password . substr ($charBKT, rand() % strlen($charBKT), 1);
1974 function addDefaultRoles($defaultRoles = array()) {
1978 foreach($defaultRoles as $roleName=>$role){
1979 $ACLField = new ACLField();
1980 $role1= new ACLRole();
1981 $role1->name = $roleName;
1982 $role1->description = $roleName." Role";
1983 $role1_id=$role1->save();
1984 foreach($role as $category=>$actions){
1985 foreach($actions as $name=>$access_override){
1986 if($name=='fields'){
1987 foreach($access_override as $field_id=>$access){
1988 $ACLField->setAccessControl($category, $role1_id, $field_id, $access);
1991 $queryACL="SELECT id FROM acl_actions where category='$category' and name='$name'";
1992 $result = $db->query($queryACL);
1993 $actionId=$db->fetchByAssoc($result);
1994 if (isset($actionId['id']) && !empty($actionId['id'])){
1995 $role1->setAction($role1_id, $actionId['id'], $access_override);
2004 * Fully enable SugarFeeds, enabling the user feed and all available modules that have SugarFeed data.
2006 function enableSugarFeeds()
2008 $admin = new Administration();
2009 $admin->saveSetting('sugarfeed','enabled','1');
2011 foreach ( SugarFeed::getAllFeedModules() as $module )
2012 SugarFeed::activateModuleFeed($module);
2014 check_logic_hook_file('Users','after_login', array(1, 'SugarFeed old feed entry remover', 'modules/SugarFeed/SugarFeedFlush.php', 'SugarFeedFlush', 'flushStaleEntries'));
2017 function create_writable_dir($dirname)
2019 if ((is_dir($dirname)) || @sugar_mkdir($dirname,0555)) {
2020 $ok = make_writable($dirname);
2023 installLog("ERROR: Cannot create writable dir $dirname");
2028 * Enable the InsideView connector for the four default modules.
2030 function enableInsideViewConnector()
2032 // Load up the existing mapping and hand it to the InsideView connector to have it setup the correct logic hooks
2033 $mapFile = 'modules/Connectors/connectors/sources/ext/rest/insideview/mapping.php';
2034 if ( file_exists('custom/'.$mapFile) ) {
2035 require('custom/'.$mapFile);
2040 require_once('modules/Connectors/connectors/sources/ext/rest/insideview/insideview.php');
2041 $source = new ext_rest_insideview();
2043 // $mapping is brought in from the mapping.php file above
2044 $source->saveMappingHook($mapping);