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