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