Issues (4069)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

install/install_utils.php (21 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

Code
1
<?php
2
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3
/*********************************************************************************
4
 * SugarCRM Community Edition is a customer relationship management program developed by
5
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
6
7
 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
8
 * Copyright (C) 2011 - 2014 Salesagility Ltd.
9
 *
10
 * This program is free software; you can redistribute it and/or modify it under
11
 * the terms of the GNU Affero General Public License version 3 as published by the
12
 * Free Software Foundation with the addition of the following permission added
13
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
14
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
15
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
16
 *
17
 * This program is distributed in the hope that it will be useful, but WITHOUT
18
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
20
 * details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License along with
23
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
24
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25
 * 02110-1301 USA.
26
 *
27
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
28
 * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected].
29
 *
30
 * The interactive user interfaces in modified source and object code versions
31
 * of this program must display Appropriate Legal Notices, as required under
32
 * Section 5 of the GNU Affero General Public License version 3.
33
 *
34
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
35
 * these Appropriate Legal Notices must retain the display of the "Powered by
36
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
37
 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
38
 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
39
 ********************************************************************************/
40
41
/*********************************************************************************
42
43
 * $Description: TODO: To be written. Portions created by SugarCRM are Copyright
44
 * (C) SugarCRM, Inc. All Rights Reserved. Contributor(s):
45
 * ______________________________________..
46
 * *******************************************************************************/
47
48
require_once('include/utils/zip_utils.php');
49
50
require_once('include/upload_file.php');
51
52
53
////////////////
54
////  GLOBAL utility
55
/**
56
 * Calls a custom function (if it exists) based on the first parameter,
57
 *   and returns result of function call, or 'undefined' if the function doesn't exist
58
 * @param string function name to call in custom install hooks
59
 * @return mixed function call result, or 'undefined'
60
 */
61
function installerHook($function_name, $options = array()){
62
    if(!isset($GLOBALS['customInstallHooksExist'])){
63
        if(file_exists('custom/install/install_hooks.php')){
64
            installLog("installerHook: Found custom/install/install_hooks.php");
65
            require_once('custom/install/install_hooks.php');
66
            $GLOBALS['customInstallHooksExist'] = true;
67
        }
68
        else{
69
            installLog("installerHook: Could not find custom/install/install_hooks.php");
70
            $GLOBALS['customInstallHooksExist'] = false;
71
        }
72
    }
73
74
    if($GLOBALS['customInstallHooksExist'] === false){
75
        return 'undefined';
76
    }
77
    else{
78
        if(function_exists($function_name)){
79
            installLog("installerHook: function {$function_name} found, calling and returning the return value");
80
            return $function_name($options);
81
        }
82
        else{
83
            installLog("installerHook: function {$function_name} not found in custom install hooks file");
84
            return 'undefined';
85
        }
86
    }
87
}
88
89
///////////////////////////////////////////////////////////////////////////////
90
////    FROM welcome.php
91
/**
92
 * returns lowercase lang encoding
93
 * @return string   encoding or blank on false
94
 */
95
function parseAcceptLanguage() {
96
    $lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
97
    if(strpos($lang, ';')) {
98
        $exLang = explode(';', $lang);
99
        return strtolower(str_replace('-','_',$exLang[0]));
100
    } else {
101
        $match = array();
102
        if(preg_match("#\w{2}\-?\_?\w{2}#", $lang, $match)) {
103
            return strtolower(str_replace('-','_',$match[0]));
104
        }
105
    }
106
    return '';
107
}
108
109
110
///////////////////////////////////////////////////////////////////////////////
111
////    FROM localization.php
112
/**
113
 * copies the temporary unzip'd files to their final destination
114
 * removes unzip'd files from system if $uninstall=true
115
 * @param bool uninstall true if uninstalling a language pack
116
 * @return array sugar_config
117
 */
118
function commitLanguagePack($uninstall=false) {
119
    global $sugar_config;
120
    global $mod_strings;
121
    global $base_upgrade_dir;
122
    global $base_tmp_upgrade_dir;
123
124
    $errors         = array();
125
    $manifest       = urldecode($_REQUEST['manifest']);
126
    $zipFile        = urldecode($_REQUEST['zipFile']);
127
    $version        = "";
128
    $show_files     = true;
129
    $unzip_dir      = mk_temp_dir( $base_tmp_upgrade_dir );
130
    $zip_from_dir   = ".";
131
    $zip_to_dir     = ".";
132
    $zip_force_copy = array();
133
134
    if($uninstall == false && isset($_SESSION['INSTALLED_LANG_PACKS']) && in_array($zipFile, $_SESSION['INSTALLED_LANG_PACKS'])) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
135
        return;
136
    }
137
138
    // unzip lang pack to temp dir
139
    if(isset($zipFile) && !empty($zipFile)) {
140
        if(is_file($zipFile)) {
141
            unzip( $zipFile, $unzip_dir );
142
        } else {
143
            echo $mod_strings['ERR_LANG_MISSING_FILE'].$zipFile;
144
            die(); // no point going any further
145
        }
146
    }
147
148
    // filter for special to/from dir conditions (langpacks generally don't have them)
149
    if(isset($manifest) && !empty($manifest)) {
150
        if(is_file($manifest)) {
151
            include($manifest);
152
            if( isset( $manifest['copy_files']['from_dir'] ) && $manifest['copy_files']['from_dir'] != "" ){
153
                $zip_from_dir   = $manifest['copy_files']['from_dir'];
154
            }
155
            if( isset( $manifest['copy_files']['to_dir'] ) && $manifest['copy_files']['to_dir'] != "" ){
156
                $zip_to_dir     = $manifest['copy_files']['to_dir'];
157
            }
158
            if( isset( $manifest['copy_files']['force_copy'] ) && $manifest['copy_files']['force_copy'] != "" ){
159
                $zip_force_copy     = $manifest['copy_files']['force_copy'];
160
            }
161
            if( isset( $manifest['version'] ) ){
162
                $version    = $manifest['version'];
163
            }
164
        } else {
165
            $errors[] = $mod_strings['ERR_LANG_MISSING_FILE'].$manifest;
166
        }
167
    }
168
169
170
    // find name of language pack: find single file in include/language/xx_xx.lang.php
171
    $d = dir( "$unzip_dir/$zip_from_dir/include/language" );
172
    while( $f = $d->read() ){
173
        if( $f == "." || $f == ".." ){
174
            continue;
175
        }
176
        else if( preg_match("/(.*)\.lang\.php\$/", $f, $match) ){
177
            $new_lang_name = $match[1];
178
        }
179
    }
180
    if( $new_lang_name == "" ){
181
        die( $mod_strings['ERR_LANG_NO_LANG_FILE'].$zipFile );
182
    }
183
    $new_lang_desc = getLanguagePackName( "$unzip_dir/$zip_from_dir/include/language/$new_lang_name.lang.php" );
184
    if( $new_lang_desc == "" ){
185
        die( "No language pack description found at include/language/$new_lang_name.lang.php inside $install_file." );
186
    }
187
    // add language to available languages
188
    $sugar_config['languages'][$new_lang_name] = ($new_lang_desc);
189
190
    // get an array of all files to be moved
191
    $filesFrom = array();
192
    $filesFrom = findAllFiles($unzip_dir, $filesFrom);
193
194
195
196
    ///////////////////////////////////////////////////////////////////////////
197
    ////    FINALIZE
198
    if($uninstall) {
199
        // unlink all pack files
200
        foreach($filesFrom as $fileFrom) {
201
            //echo "deleting: ".getcwd().substr($fileFrom, strlen($unzip_dir), strlen($fileFrom))."<br>";
202
            @unlink(getcwd().substr($fileFrom, strlen($unzip_dir), strlen($fileFrom)));
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
203
        }
204
205
        // remove session entry
206
        if(isset($_SESSION['INSTALLED_LANG_PACKS']) && is_array($_SESSION['INSTALLED_LANG_PACKS'])) {
207
            foreach($_SESSION['INSTALLED_LANG_PACKS'] as $k => $langPack) {
208
                if($langPack == $zipFile) {
209
                    unset($_SESSION['INSTALLED_LANG_PACKS'][$k]);
210
                    unset($_SESSION['INSTALLED_LANG_PACKS_VERSION'][$k]);
211
                    unset($_SESSION['INSTALLED_LANG_PACKS_MANIFEST'][$k]);
212
                    $removedLang = $k;
213
                }
214
            }
215
216
            // remove language from config
217
            $new_langs = array();
218
            $old_langs = $sugar_config['languages'];
219
            foreach( $old_langs as $key => $value ){
220
                if( $key != $removedLang ){
221
                    $new_langs += array( $key => $value );
222
                }
223
            }
224
            $sugar_config['languages'] = $new_langs;
225
        }
226
    } else {
227
        // copy filesFrom to filesTo
228
        foreach($filesFrom as $fileFrom) {
229
            @copy($fileFrom, getcwd().substr($fileFrom, strlen($unzip_dir), strlen($fileFrom)));
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
230
        }
231
232
        $_SESSION['INSTALLED_LANG_PACKS'][$new_lang_name] = $zipFile;
233
        $_SESSION['INSTALLED_LANG_PACKS_VERSION'][$new_lang_name] = $version;
234
        $serial_manifest = array();
235
        $serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
236
        $serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
0 ignored issues
show
The variable $installdefs seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
237
        $serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
0 ignored issues
show
The variable $upgrade_manifest does not exist. Did you mean $manifest?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
238
        $_SESSION['INSTALLED_LANG_PACKS_MANIFEST'][$new_lang_name] = base64_encode(serialize($serial_manifest));
239
    }
240
241
    writeSugarConfig($sugar_config);
242
243
    return $sugar_config;
244
}
245
246
function commitPatch($unlink = false, $type = 'patch'){
247
    require_once('ModuleInstall/ModuleInstaller.php');
248
    require_once('include/entryPoint.php');
249
250
251
    global $mod_strings;
252
    global $base_upgrade_dir;
253
    global $base_tmp_upgrade_dir;
254
    global $db;
255
    $GLOBALS['db'] = $db;
256
    $errors = array();
257
    $files = array();
258
     global $current_user;
259
    $current_user = new User();
260
    $current_user->is_admin = '1';
261
    $old_mod_strings = $mod_strings;
262
    if(is_dir($base_upgrade_dir)) {
263
            $files = findAllFiles("$base_upgrade_dir/$type", $files);
264
            $mi = new ModuleInstaller();
265
            $mi->silent = true;
266
            $mod_strings = return_module_language('en', "Administration");
267
268
            foreach($files as $file) {
269
                if(!preg_match('#.*\.zip\$#', $file)) {
270
                    continue;
271
                }
272
                // handle manifest.php
273
                $target_manifest = remove_file_extension( $file ) . '-manifest.php';
274
275
                include($target_manifest);
276
277
                $unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
278
                unzip($file, $unzip_dir );
279
                if(file_exists("$unzip_dir/scripts/pre_install.php")){
280
                    require_once("$unzip_dir/scripts/pre_install.php");
281
                    pre_install();
282
                }
283
                if( isset( $manifest['copy_files']['from_dir'] ) && $manifest['copy_files']['from_dir'] != "" ){
284
                    $zip_from_dir   = $manifest['copy_files']['from_dir'];
285
                }
286
                $source = "$unzip_dir/$zip_from_dir";
287
                $dest = getcwd();
288
                copy_recursive($source, $dest);
289
290
                if(file_exists("$unzip_dir/scripts/post_install.php")){
291
                    require_once("$unzip_dir/scripts/post_install.php");
292
                    post_install();
293
                }
294
                $new_upgrade = new UpgradeHistory();
295
                $new_upgrade->filename      = $file;
296
                $new_upgrade->md5sum        = md5_file($file);
297
                $new_upgrade->type          = $manifest['type'];
298
                $new_upgrade->version       = $manifest['version'];
299
                $new_upgrade->status        = "installed";
300
                //$new_upgrade->author        = $manifest['author'];
301
                $new_upgrade->name          = $manifest['name'];
302
                $new_upgrade->description   = $manifest['description'];
303
                $serial_manifest = array();
304
                $serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
305
                $serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
306
                $serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
307
                $new_upgrade->manifest   = base64_encode(serialize($serial_manifest));
308
                $new_upgrade->save();
309
                unlink($file);
310
            }//rof
311
    }//fi
312
    $mod_strings = $old_mod_strings;
313
}
314
315
function commitModules($unlink = false, $type = 'module'){
316
    require_once('ModuleInstall/ModuleInstaller.php');
317
    require_once('include/entryPoint.php');
318
319
320
    global $mod_strings;
321
    global $base_upgrade_dir;
322
    global $base_tmp_upgrade_dir;
323
    global $db;
324
    $GLOBALS['db'] = $db;
325
    $errors = array();
326
    $files = array();
327
     global $current_user;
328
    $current_user = new User();
329
    $current_user->is_admin = '1';
330
    $old_mod_strings = $mod_strings;
331
    if(is_dir(sugar_cached("upload/upgrades"))) {
332
            $files = findAllFiles(sugar_cached("upload/upgrades/$type"), $files);
333
            $mi = new ModuleInstaller();
334
            $mi->silent = true;
335
            $mod_strings = return_module_language('en', "Administration");
336
337
            foreach($files as $file) {
338
                if(!preg_match('#.*\.zip\$', $file)) {
339
                    continue;
340
                }
341
                $lic_name = 'accept_lic_'.str_replace('.', '_', urlencode(basename($file)));
342
343
                $can_install = true;
344
                if(isset($_REQUEST[$lic_name])){
345
                    if($_REQUEST[$lic_name] == 'yes'){
346
                        $can_install = true;
347
                    }else{
348
                        $can_install = false;
349
                    }
350
                }
351
                if($can_install){
352
                    // handle manifest.php
353
                    $target_manifest = remove_file_extension( $file ) . '-manifest.php';
354
                    if($type == 'langpack'){
355
                        $_REQUEST['manifest'] = $target_manifest;
356
                        $_REQUEST['zipFile'] = $file;
357
                        commitLanguagePack();
358
                        continue;
359
                    }
360
                    include($target_manifest);
361
362
                    $unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
363
                    unzip($file, $unzip_dir );
364
                    $_REQUEST['install_file'] = $file;
365
                    $mi->install($unzip_dir);
366
                    $new_upgrade = new UpgradeHistory();
367
                    $new_upgrade->filename      = $file;
368
                    $new_upgrade->md5sum        = md5_file($file);
369
                    $new_upgrade->type          = $manifest['type'];
370
                    $new_upgrade->version       = $manifest['version'];
371
                    $new_upgrade->status        = "installed";
372
                   // $new_upgrade->author        = $manifest['author'];
373
                    $new_upgrade->name          = $manifest['name'];
374
                    $new_upgrade->description   = $manifest['description'];
375
                    $new_upgrade->id_name       = (isset($installdefs['id_name'])) ? $installdefs['id_name'] : '';
376
                    $serial_manifest = array();
377
                    $serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
378
                    $serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
379
                    $serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
380
                    $new_upgrade->manifest   = base64_encode(serialize($serial_manifest));
381
                    $new_upgrade->save();
382
                    //unlink($file);
383
                }//fi
384
            }//rof
385
    }//fi
386
    $mod_strings = $old_mod_strings;
387
}
388
389
/**
390
 * creates UpgradeHistory entries
391
 * @param mode string Install or Uninstall
392
 */
393
function updateUpgradeHistory() {
394
    if(isset($_SESSION['INSTALLED_LANG_PACKS']) && count($_SESSION['INSTALLED_LANG_PACKS']) > 0) {
395
        foreach($_SESSION['INSTALLED_LANG_PACKS'] as $k => $zipFile) {
396
            $new_upgrade = new UpgradeHistory();
397
            $new_upgrade->filename      = $zipFile;
398
            $new_upgrade->md5sum        = md5_file($zipFile);
399
            $new_upgrade->type          = 'langpack';
400
            $new_upgrade->version       = $_SESSION['INSTALLED_LANG_PACKS_VERSION'][$k];
401
            $new_upgrade->status        = "installed";
402
            $new_upgrade->manifest      = $_SESSION['INSTALLED_LANG_PACKS_MANIFEST'][$k];
403
            $new_upgrade->save();
404
        }
405
    }
406
}
407
408
409
/**
410
 * removes the installed language pack, but the zip is still in the cache dir
411
 */
412
function removeLanguagePack() {
413
    global $mod_strings;
414
    global $sugar_config;
415
416
    $errors = array();
417
    $manifest = urldecode($_REQUEST['manifest']);
418
    $zipFile = urldecode($_REQUEST['zipFile']);
419
420
    if(isset($manifest) && !empty($manifest)) {
421
        if(is_file($manifest)) {
422
            if(!unlink($manifest)) {
423
                $errors[] = $mod_strings['ERR_LANG_CANNOT_DELETE_FILE'].$manifest;
424
            }
425
        } else {
426
            $errors[] = $mod_strings['ERR_LANG_MISSING_FILE'].$manifest;
427
        }
428
        unset($_SESSION['packages_to_install'][$manifest]);
429
    }
430
    if(isset($zipFile) && !empty($zipFile)) {
431
        if(is_file($zipFile)) {
432
            if(!unlink($zipFile)) {
433
                $errors[] = $mod_strings['ERR_LANG_CANNOT_DELETE_FILE'].$zipFile;
434
            }
435
        } else {
436
            $errors[] = $mod_strings['ERR_LANG_MISSING_FILE'].$zipFile;
437
        }
438
    }
439
    if(count($errors > 0)) {
440
        echo "<p class='error'>";
441
        foreach($errors as $error) {
442
            echo "{$error}<br>";
443
        }
444
        echo "</p>";
445
    }
446
447
    unlinkTempFiles($manifest, $zipFile);
448
}
449
450
451
452
/**
453
 * takes the current value of $sugar_config and writes it out to config.php (sorta the same as the final step)
454
 * @param array sugar_config
455
 */
456
function writeSugarConfig($sugar_config) {
457
    ksort($sugar_config);
458
    $sugar_config_string = "<?php\n" .
459
        '// created: ' . date('Y-m-d H:i:s') . "\n" .
460
        '$sugar_config = ' .
461
        var_export($sugar_config, true) .
462
        ";\n?>\n";
463
    if(is_writable('config.php')) {
464
        write_array_to_file( "sugar_config", $sugar_config, "config.php");
465
    }
466
}
467
468
469
/**
470
 * uninstalls the Language pack
471
 */
472
function uninstallLangPack() {
473
    global $sugar_config;
474
475
    // remove language from config
476
    $new_langs = array();
477
    $old_langs = $sugar_config['languages'];
478
    foreach( $old_langs as $key => $value ){
479
        if( $key != $_REQUEST['new_lang_name'] ){
480
            $new_langs += array( $key => $value );
481
        }
482
    }
483
    $sugar_config['languages'] = $new_langs;
484
485
    writeSugarConfig($sugar_config);
486
}
487
488
/**
489
 * retrieves the name of the language
490
 */
491
if ( !function_exists('getLanguagePackName') ) {
492
function getLanguagePackName($the_file) {
493
    require_once( "$the_file" );
494
    if( isset( $app_list_strings["language_pack_name"] ) ){
0 ignored issues
show
The variable $app_list_strings seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
495
        return( $app_list_strings["language_pack_name"] );
496
    }
497
    return( "" );
498
}
499
}
500
501
function getInstalledLangPacks($showButtons=true) {
502
    global $mod_strings;
503
    global $next_step;
504
505
    $ret  = "<tr><td colspan=7 align=left>{$mod_strings['LBL_LANG_PACK_INSTALLED']}</td></tr>";
506
    //$ret .="<table width='100%' cellpadding='0' cellspacing='0' border='0'>";
507
    $ret .= "<tr>
508
                <td width='15%' ><b>{$mod_strings['LBL_ML_NAME']}</b></td>
509
                <td width='15%' ><b>{$mod_strings['LBL_ML_VERSION']}</b></td>
510
                <td width='15%' ><b>{$mod_strings['LBL_ML_PUBLISHED']}</b></td>
511
                <td width='15%' ><b>{$mod_strings['LBL_ML_UNINSTALLABLE']}</b></td>
512
                <td width='15%' ><b>{$mod_strings['LBL_ML_DESCRIPTION']}</b></td>
513
                <td width='15%' ></td>
514
                <td width='15%' ></td>
515
            </tr>\n";
516
    $files = array();
517
    $files = findAllFiles(sugar_cached("upload/upgrades"), $files);
518
519
    if(isset($_SESSION['INSTALLED_LANG_PACKS']) && !empty($_SESSION['INSTALLED_LANG_PACKS'])){
520
        if(count($_SESSION['INSTALLED_LANG_PACKS'] > 0)) {
521
            foreach($_SESSION['INSTALLED_LANG_PACKS'] as $file) {
522
                // handle manifest.php
523
                $target_manifest = remove_file_extension( $file ) . '-manifest.php';
524
                include($target_manifest);
525
526
                $name = empty($manifest['name']) ? $file : $manifest['name'];
527
                $version = empty($manifest['version']) ? '' : $manifest['version'];
528
                $published_date = empty($manifest['published_date']) ? '' : $manifest['published_date'];
529
                $icon = '';
530
                $description = empty($manifest['description']) ? 'None' : $manifest['description'];
531
                $uninstallable = empty($manifest['is_uninstallable']) ? 'No' : 'Yes';
532
                $manifest_type = $manifest['type'];
533
534
                $deletePackage = getPackButton('uninstall', $target_manifest, $file, $next_step, $uninstallable, $showButtons);
535
                //$ret .="<table width='100%' cellpadding='0' cellspacing='0' border='0'>";
536
                $ret .= "<tr>";
537
                $ret .= "<td width='15%' >".$name."</td>";
538
                $ret .= "<td width='15%' >".$version."</td>";
539
                $ret .= "<td width='15%' >".$published_date."</td>";
540
                $ret .= "<td width='15%' >".$uninstallable."</td>";
541
                $ret .= "<td width='15%' >".$description."</td>";
542
                $ret .= "<td width='15%' ></td>";
543
                $ret .= "<td width='15%' >{$deletePackage}</td>";
544
                $ret .= "</tr>";
545
            }
546
        } else {
547
            $ret .= "</tr><td colspan=7><i>{$mod_strings['LBL_LANG_NO_PACKS']}</i></td></tr>";
548
        }
549
    } else {
550
        $ret .= "</tr><td colspan=7><i>{$mod_strings['LBL_LANG_NO_PACKS']}</i></td></tr>";
551
    }
552
    return $ret;
553
}
554
555
556
function uninstallLanguagePack() {
557
    return commitLanguagePack(true);
558
}
559
560
561
function getSugarConfigLanguageArray($langZip) {
562
    global $sugar_config;
563
564
    include(remove_file_extension($langZip)."-manifest.php");
565
    $ret = '';
566
    if(isset($installdefs['id']) && isset($manifest['name'])) {
0 ignored issues
show
The variable $installdefs seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
The variable $manifest seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
567
        $ret = $installdefs['id']."::".$manifest['name']."::".$manifest['version'];
568
    }
569
570
    return $ret;
571
}
572
573
574
575
///////////////////////////////////////////////////////////////////////////////
576
////    FROM performSetup.php
577
578
function getInstallDbInstance()
579
{
580
    return DBManagerFactory::getTypeInstance($_SESSION['setup_db_type'], array("db_manager" => $_SESSION['setup_db_manager']));
581
}
582
583
function getDbConnection()
584
{
585
    $dbconfig = array(
586
                "db_host_name" => $_SESSION['setup_db_host_name'],
587
                "db_user_name" => $_SESSION['setup_db_admin_user_name'],
588
                "db_password" => $_SESSION['setup_db_admin_password'],
589
                "db_host_instance" => $_SESSION['setup_db_host_instance'],
590
                "db_port" => $_SESSION['setup_db_port_num'],
591
    );
592
    if(empty($_SESSION['setup_db_create_database'])) {
593
            $dbconfig["db_name"] = $_SESSION['setup_db_database_name'];
594
    }
595
596
    $db = getInstallDbInstance();
597
    if(!empty($_SESSION['setup_db_options'])) {
598
        $db->setOptions($_SESSION['setup_db_options']);
599
    }
600
    $db->connect($dbconfig, true);
601
    return $db;
602
}
603
604
/**
605
 * creates the Sugar DB user (if not admin)
606
 */
607
function handleDbCreateSugarUser() {
608
    global $mod_strings;
609
    global $setup_db_database_name;
610
    global $setup_db_host_name;
611
    global $setup_db_host_instance;
612
    global $setup_db_port_num;
613
    global $setup_db_admin_user_name;
614
    global $setup_db_admin_password;
615
    global $sugar_config;
616
    global $setup_db_sugarsales_user;
617
    global $setup_site_host_name;
618
    global $setup_db_sugarsales_password;
619
620
    echo $mod_strings['LBL_PERFORM_CREATE_DB_USER'];
621
622
    $db = getDbConnection();
623
    $db->createDbUser($setup_db_database_name, $setup_site_host_name, $setup_db_sugarsales_user, $setup_db_sugarsales_password);
624
    $err = $db->lastError();
625
    if($err == '')  {
626
        echo $mod_strings['LBL_PERFORM_DONE'];
627
    } else {
628
          echo "<div style='color:red;'>";
629
          echo "An error occurred when creating user:<br>";
630
          echo "$err<br>";
631
          echo "</div>";
632
          installLog("An error occurred when creating user: $err");
633
    }
634
}
635
636
/**
637
 * ensures that the charset and collation for a given database is set
638
 * MYSQL ONLY
639
 */
640
function handleDbCharsetCollation() {
641
    global $mod_strings;
642
    global $setup_db_database_name;
643
    global $setup_db_host_name;
644
    global $setup_db_admin_user_name;
645
    global $setup_db_admin_password;
646
    global $sugar_config;
647
648
    if($_SESSION['setup_db_type'] == 'mysql') {
649
         $db = getDbConnection();
650
         $db->query("ALTER DATABASE `{$setup_db_database_name}` DEFAULT CHARACTER SET utf8", true);
651
         $db->query("ALTER DATABASE `{$setup_db_database_name}` DEFAULT COLLATE utf8_general_ci", true);
652
    }
653
}
654
655
656
/**
657
 * creates the new database
658
 */
659
function handleDbCreateDatabase() {
660
    global $mod_strings;
661
    global $setup_db_database_name;
662
    global $setup_db_host_name;
663
    global $setup_db_host_instance;
664
    global $setup_db_port_num;
665
    global $setup_db_admin_user_name;
666
    global $setup_db_admin_password;
667
    global $sugar_config;
668
669
    echo "{$mod_strings['LBL_PERFORM_CREATE_DB_1']} {$setup_db_database_name} {$mod_strings['LBL_PERFORM_CREATE_DB_2']} {$setup_db_host_name}...";
670
    $db = getDbConnection();
671
    if($db->dbExists($setup_db_database_name)) {
672
        $db->dropDatabase($setup_db_database_name);
673
    }
674
    $db->createDatabase($setup_db_database_name);
675
676
    echo $mod_strings['LBL_PERFORM_DONE'];
677
}
678
679
680
/**
681
 * handles creation of Log4PHP properties file
682
 * This function has been deprecated.  Use SugarLogger.
683
 */
684
function handleLog4Php() {
685
    return;
686
}
687
688
function installLog($entry) {
689
    global $mod_strings;
690
    $nl = '
691
'.gmdate("Y-m-d H:i:s").'...';
692
    $log = clean_path(getcwd().'/install.log');
693
694
    // create if not exists
695
    if(!file_exists($log)) {
696
        $fp = @sugar_fopen($log, 'w+'); // attempts to create file
697
        if(!is_resource($fp)) {
698
            $GLOBALS['log']->fatal('could not create the install.log file');
699
        }
700
    } else {
701
        $fp = @sugar_fopen($log, 'a+'); // write pointer at end of file
702
        if(!is_resource($fp)) {
703
            $GLOBALS['log']->fatal('could not open/lock install.log file');
704
        }
705
    }
706
707
708
709
    if(@fwrite($fp, $nl.$entry) === false) {
710
        $GLOBALS['log']->fatal('could not write to install.log: '.$entry);
711
    }
712
713
    if(is_resource($fp)) {
714
        fclose($fp);
715
    }
716
}
717
718
719
720
/**
721
 * takes session vars and creates config.php
722
 * @return array bottle collection of error messages
723
 */
724
function handleSugarConfig() {
725
    global $bottle;
726
    global $cache_dir;
727
    global $mod_strings;
728
    global $setup_db_host_name;
729
    global $setup_db_host_instance;
730
    global $setup_db_port_num;
731
    global $setup_db_sugarsales_user;
732
    global $setup_db_sugarsales_password;
733
    global $setup_db_database_name;
734
    global $setup_site_host_name;
735
    global $setup_site_log_dir;
736
    global $setup_site_log_file;
737
    global $setup_site_session_path;
738
    global $setup_site_guid;
739
    global $setup_site_url;
740
    global $setup_sugar_version;
741
    global $sugar_config;
742
    global $setup_site_log_level;
743
744
    echo "<b>{$mod_strings['LBL_PERFORM_CONFIG_PHP']} (config.php)</b><br>";
745
    ///////////////////////////////////////////////////////////////////////////////
746
    ////    $sugar_config SETTINGS
747
    if( is_file('config.php') ){
748
        $is_writable = is_writable('config.php');
749
        // require is needed here (config.php is sometimes require'd from install.php)
750
        require('config.php');
751
    } else {
752
        $is_writable = is_writable('.');
753
    }
754
755
    // build default sugar_config and merge with new values
756
    $sugar_config = sugarArrayMerge(get_sugar_config_defaults(), $sugar_config);
757
    // always lock the installer
758
    $sugar_config['installer_locked'] = true;
759
    // we're setting these since the user was given a fair chance to change them
760
    $sugar_config['dbconfig']['db_host_name']       = $setup_db_host_name;
761
    if(!empty($setup_db_host_instance)) {
762
        $sugar_config['dbconfig']['db_host_instance']   = $setup_db_host_instance;
763
    } else {
764
        $sugar_config['dbconfig']['db_host_instance'] = '';
765
    }
766
    if(!isset($_SESSION['setup_db_manager'])) {
767
        $_SESSION['setup_db_manager'] = DBManagerFactory::getManagerByType($_SESSION['setup_db_type']);
768
    }
769
    $sugar_config['dbconfig']['db_user_name']       = $setup_db_sugarsales_user;
770
    $sugar_config['dbconfig']['db_password']        = $setup_db_sugarsales_password;
771
    $sugar_config['dbconfig']['db_name']            = $setup_db_database_name;
772
    $sugar_config['dbconfig']['db_type']            = $_SESSION['setup_db_type'];
773
    $sugar_config['dbconfig']['db_port']            = $setup_db_port_num;
774
    $sugar_config['dbconfig']['db_manager']         = $_SESSION['setup_db_manager'];
775
    if(!empty($_SESSION['setup_db_options'])) {
776
        $sugar_config['dbconfigoption']                 = array_merge($sugar_config['dbconfigoption'], $_SESSION['setup_db_options']);
777
    }
778
779
    $sugar_config['cache_dir']                      = $cache_dir;
780
    $sugar_config['default_charset']                = $mod_strings['DEFAULT_CHARSET'];
781
    $sugar_config['default_email_client']           = 'sugar';
782
    $sugar_config['default_email_editor']           = 'html';
783
    $sugar_config['host_name']                      = $setup_site_host_name;
784
    $sugar_config['js_custom_version']              = '';
785
    $sugar_config['use_real_names']                 = true;
786
    $sugar_config['disable_convert_lead']           = false;
787
    $sugar_config['log_dir']                        = $setup_site_log_dir;
788
    $sugar_config['log_file']                       = $setup_site_log_file;
789
    $sugar_config['enable_line_editing_detail']     = true;
790
    $sugar_config['enable_line_editing_list']       = true;
791
792
    // Setup FTS
793
    if (!empty($_SESSION['setup_fts_type'])) {
794
        $sugar_config['full_text_engine'] = array(
795
            $_SESSION['setup_fts_type'] => getFtsSettings()
796
        );
797
        if (isset($_SESSION['setup_fts_hide_config'])) {
798
            $sugar_config['hide_full_text_engine_config'] = $_SESSION['setup_fts_hide_config'];
799
        }
800
    }
801
802
	/*nsingh(bug 22402): Consolidate logger settings under $config['logger'] as liked by the new logger! If log4pphp exists,
803
		these settings will be overwritten by those in log4php.properties when the user access admin->system settings.*/
804
    $sugar_config['logger']	=
805
    	array ('level'=>$setup_site_log_level,
806
    	 'file' => array(
807
			'ext' => '.log',
808
			'name' => 'suitecrm',
809
			'dateFormat' => '%c',
810
			'maxSize' => '10MB',
811
			'maxLogs' => 10,
812
			'suffix' => ''), // bug51583, change default suffix to blank for backwards comptability
813
  	);
814
815
    $sugar_config['session_dir']                    = $setup_site_session_path;
816
    $sugar_config['site_url']                       = $setup_site_url;
817
    $sugar_config['sugar_version']                  = $setup_sugar_version;
818
    $sugar_config['tmp_dir']                        = $cache_dir.'xml/';
819
    $sugar_config['upload_dir']                 = 'upload/';
820
//    $sugar_config['use_php_code_json']              = returnPhpJsonStatus(); // true on error
821
    if( isset($_SESSION['setup_site_sugarbeet_anonymous_stats']) ){
822
        $sugar_config['sugarbeet']      = $_SESSION['setup_site_sugarbeet_anonymous_stats'];
823
    }
824
    $sugar_config['demoData'] = $_SESSION['demoData'];
825
    if( isset( $setup_site_guid ) ){
826
        $sugar_config['unique_key'] = $setup_site_guid;
827
    }
828
    if(empty($sugar_config['unique_key'])){
829
        $sugar_config['unique_key'] = md5( create_guid() );
830
    }
831
    // add installed langs to config
832
    // entry in upgrade_history comes AFTER table creation
833
    if(isset($_SESSION['INSTALLED_LANG_PACKS']) && is_array($_SESSION['INSTALLED_LANG_PACKS']) && !empty($_SESSION['INSTALLED_LANG_PACKS'])) {
834
        foreach($_SESSION['INSTALLED_LANG_PACKS'] as $langZip) {
835
            $lang = getSugarConfigLanguageArray($langZip);
836
            if(!empty($lang)) {
837
                $exLang = explode('::', $lang);
838
                if(is_array($exLang) && count($exLang) == 3) {
839
                    $sugar_config['languages'][$exLang[0]] = $exLang[1];
840
                }
841
            }
842
        }
843
    }
844
    if(file_exists('install/lang.config.php')){
845
        include('install/lang.config.php');
846
        if(!empty($config['languages'])){
0 ignored issues
show
The variable $config does not exist. Did you mean $sugar_config?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
847
            foreach($config['languages'] as $lang=>$label){
848
                $sugar_config['languages'][$lang] = $label;
849
            }
850
        }
851
    }
852
853
    ksort($sugar_config);
854
    $sugar_config_string = "<?php\n" .
855
        '// created: ' . date('Y-m-d H:i:s') . "\n" .
856
        '$sugar_config = ' .
857
        var_export($sugar_config, true) .
858
        ";\n?>\n";
859
    if($is_writable && write_array_to_file( "sugar_config", $sugar_config, "config.php")) {
0 ignored issues
show
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
860
        // was 'Done'
861
    } else {
862
        echo 'failed<br>';
863
        echo "<p>{$mod_strings['ERR_PERFORM_CONFIG_PHP_1']}</p>\n";
864
        echo "<p>{$mod_strings['ERR_PERFORM_CONFIG_PHP_2']}</p>\n";
865
        echo "<TEXTAREA  rows=\"15\" cols=\"80\">".$sugar_config_string."</TEXTAREA>";
866
        echo "<p>{$mod_strings['ERR_PERFORM_CONFIG_PHP_3']}</p>";
867
868
        $bottle[] = $mod_strings['ERR_PERFORM_CONFIG_PHP_4'];
869
    }
870
871
872
    //Now merge the config_si.php settings into config.php
873
    if(file_exists('config.php') && file_exists('config_si.php'))
874
    {
875
       require_once('modules/UpgradeWizard/uw_utils.php');
876
       merge_config_si_settings(false, 'config.php', 'config_si.php');
877
    }
878
879
880
    ////    END $sugar_config
881
    ///////////////////////////////////////////////////////////////////////////////
882
    return $bottle;
883
}
884
885
/**
886
 * Get FTS settings
887
 * @return array
888
 */
889
function getFtsSettings()
890
{
891
    // Base settings
892
    $ftsSettings = array(
893
        'host' => $_SESSION['setup_fts_host'],
894
        'port' => $_SESSION['setup_fts_port'],
895
    );
896
897
    // Add optional settings
898
    $ftsOptional = array(
899
        'curl',
900
        'transport',
901
        'index_settings',
902
        'index_strategy',
903
    );
904
905
    foreach ($ftsOptional as $ftsOpt) {
906
        $ftsConfigKey = "setup_fts_{$ftsOpt}";
907
        if (!empty($_SESSION[$ftsConfigKey])) {
908
            $ftsSettings[$ftsOpt] = $_SESSION[$ftsConfigKey];
909
        }
910
    }
911
912
    return $ftsSettings;
913
}
914
915
/**
916
 * (re)write the .htaccess file to prevent browser access to the log file
917
 */
918
function handleHtaccess(){
919
global $mod_strings;
920
global $sugar_config;
921
$ignoreCase = (substr_count(strtolower($_SERVER['SERVER_SOFTWARE']), 'apache/2') > 0)?'(?i)':'';
922
$htaccess_file   = ".htaccess";
923
$contents = '';
924
$basePath = parse_url($sugar_config['site_url'], PHP_URL_PATH);
925
if(empty($basePath)) $basePath = '/';
926
$restrict_str = <<<EOQ
927
928
# BEGIN SUGARCRM RESTRICTIONS
929
930
EOQ;
931
if (ini_get('suhosin.perdir') !== false && strpos(ini_get('suhosin.perdir'), 'e') !== false)
932
{
933
    $restrict_str .= "php_value suhosin.executor.include.whitelist upload\n";
934
}
935
$restrict_str .= <<<EOQ
936
RedirectMatch 403 {$ignoreCase}.*\.log$
937
RedirectMatch 403 {$ignoreCase}/+not_imported_.*\.txt
938
RedirectMatch 403 {$ignoreCase}/+(soap|cache|xtemplate|data|examples|include|log4php|metadata|modules)/+.*\.(php|tpl)
939
RedirectMatch 403 {$ignoreCase}/+emailmandelivery\.php
940
RedirectMatch 403 {$ignoreCase}/+upload
941
RedirectMatch 403 {$ignoreCase}/+custom/+blowfish
942
RedirectMatch 403 {$ignoreCase}/+cache/+diagnostic
943
RedirectMatch 403 {$ignoreCase}/+files\.md5$
944
# END SUGARCRM RESTRICTIONS
945
EOQ;
946
947
$cache_headers = <<<EOQ
948
949
<IfModule mod_rewrite.c>
950
    Options +FollowSymLinks
951
    RewriteEngine On
952
    RewriteBase {$basePath}
953
    RewriteRule ^cache/jsLanguage/(.._..).js$ index.php?entryPoint=jslang&module=app_strings&lang=$1 [L,QSA]
954
    RewriteRule ^cache/jsLanguage/(\w*)/(.._..).js$ index.php?entryPoint=jslang&module=$1&lang=$2 [L,QSA]
955
</IfModule>
956
<FilesMatch "\.(jpg|png|gif|js|css|ico)$">
957
        <IfModule mod_headers.c>
958
                Header set ETag ""
959
                Header set Cache-Control "max-age=2592000"
960
                Header set Expires "01 Jan 2112 00:00:00 GMT"
961
        </IfModule>
962
</FilesMatch>
963
<IfModule mod_expires.c>
964
        ExpiresByType text/css "access plus 1 month"
965
        ExpiresByType text/javascript "access plus 1 month"
966
        ExpiresByType application/x-javascript "access plus 1 month"
967
        ExpiresByType image/gif "access plus 1 month"
968
        ExpiresByType image/jpg "access plus 1 month"
969
        ExpiresByType image/png "access plus 1 month"
970
</IfModule>
971
EOQ;
972
    if(file_exists($htaccess_file)){
973
        $fp = fopen($htaccess_file, 'r');
974
        $skip = false;
975
        while($line = fgets($fp)){
976
977
            if(preg_match("/\s*#\s*BEGIN\s*SUGARCRM\s*RESTRICTIONS/i", $line))$skip = true;
978
            if(!$skip)$contents .= $line;
979
            if(preg_match("/\s*#\s*END\s*SUGARCRM\s*RESTRICTIONS/i", $line))$skip = false;
980
        }
981
    }
982
    $status =  file_put_contents($htaccess_file, $contents . $restrict_str . $cache_headers);
983
    if( !$status ) {
984
        echo "<p>{$mod_strings['ERR_PERFORM_HTACCESS_1']}<span class=stop>{$htaccess_file}</span> {$mod_strings['ERR_PERFORM_HTACCESS_2']}</p>\n";
985
        echo "<p>{$mod_strings['ERR_PERFORM_HTACCESS_3']}</p>\n";
986
        echo $restrict_str;
987
    }
988
    return $status;
989
}
990
991
/**
992
 * (re)write the web.config file to prevent browser access to the log file
993
 */
994
function handleWebConfig()
995
{
996
    if ( !isset($_SERVER['IIS_UrlRewriteModule']) ) {
997
        return;
998
    }
999
1000
    global $setup_site_log_dir;
1001
    global $setup_site_log_file;
1002
    global $sugar_config;
1003
1004
    // Bug 36968 - Fallback to using $sugar_config values when we are not calling this from the installer
1005
    if (empty($setup_site_log_file)) {
1006
        $setup_site_log_file = $sugar_config['log_file'];
1007
        if ( empty($sugar_config['log_file']) ) {
1008
            $setup_site_log_file = 'suitecrm.log';
1009
        }
1010
    }
1011
    if (empty($setup_site_log_dir)) {
1012
        $setup_site_log_dir = $sugar_config['log_dir'];
1013
        if ( empty($sugar_config['log_dir']) ) {
1014
            $setup_site_log_dir = '.';
1015
        }
1016
    }
1017
1018
    $prefix = $setup_site_log_dir.empty($setup_site_log_dir)?'':'/';
1019
1020
1021
    $config_array = array(
1022
    array('1'=> $prefix.str_replace('.','\\.',$setup_site_log_file).'\\.*' ,'2'=>'log_file_restricted.html'),
1023
    array('1'=> $prefix.'install.log' ,'2'=>'log_file_restricted.html'),
1024
    array('1'=> $prefix.'upgradeWizard.log' ,'2'=>'log_file_restricted.html'),
1025
    array('1'=> $prefix.'emailman.log' ,'2'=>'log_file_restricted.html'),
1026
    array('1'=>'not_imported_.*.txt' ,'2'=>'log_file_restricted.html'),
1027
    array('1'=>'XTemplate/(.*)/(.*).php' ,'2'=>'index.php'),
1028
    array('1'=>'data/(.*).php' ,'2'=>'index.php'),
1029
    array('1'=>'examples/(.*).php' ,'2'=>'index.php'),
1030
    array('1'=>'include/(.*).php' ,'2'=>'index.php'),
1031
    array('1'=>'include/(.*)/(.*).php' ,'2'=>'index.php'),
1032
    array('1'=>'log4php/(.*).php' ,'2'=>'index.php'),
1033
    array('1'=>'log4php/(.*)/(.*)' ,'2'=>'index.php'),
1034
    array('1'=>'metadata/(.*)/(.*).php' ,'2'=>'index.php'),
1035
    array('1'=>'modules/(.*)/(.*).php' ,'2'=>'index.php'),
1036
    array('1'=>'soap/(.*).php' ,'2'=>'index.php'),
1037
    array('1'=>'emailmandelivery.php' ,'2'=>'index.php'),
1038
    array('1'=>'cron.php' ,'2'=>'index.php'),
1039
    array('1'=> $sugar_config['upload_dir'].'.*' ,'2'=>'index.php'),
1040
    );
1041
1042
1043
    $xmldoc = new XMLWriter();
1044
    $xmldoc->openURI('web.config');
1045
    $xmldoc->setIndent(true);
1046
    $xmldoc->setIndentString(' ');
1047
    $xmldoc->startDocument('1.0','UTF-8');
1048
    $xmldoc->startElement('configuration');
1049
        $xmldoc->startElement('system.webServer');
1050
            $xmldoc->startElement('rewrite');
1051
                $xmldoc->startElement('rules');
1052
                for ($i = 0; $i < count($config_array); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1053
                    $xmldoc->startElement('rule');
1054
                        $xmldoc->writeAttribute('name', "redirect$i");
1055
                        $xmldoc->writeAttribute('stopProcessing', 'true');
1056
                        $xmldoc->startElement('match');
1057
                            $xmldoc->writeAttribute('url', $config_array[$i]['1']);
1058
                        $xmldoc->endElement();
1059
                        $xmldoc->startElement('action');
1060
                            $xmldoc->writeAttribute('type', 'Redirect');
1061
                            $xmldoc->writeAttribute('url', $config_array[$i]['2']);
1062
                            $xmldoc->writeAttribute('redirectType', 'Found');
1063
                        $xmldoc->endElement();
1064
                    $xmldoc->endElement();
1065
                }
1066
                $xmldoc->endElement();
1067
            $xmldoc->endElement();
1068
            $xmldoc->startElement('caching');
1069
                $xmldoc->startElement('profiles');
1070
                    $xmldoc->startElement('remove');
1071
                        $xmldoc->writeAttribute('extension', ".php");
1072
                    $xmldoc->endElement();
1073
                $xmldoc->endElement();
1074
            $xmldoc->endElement();
1075
            $xmldoc->startElement('staticContent');
1076
                $xmldoc->startElement("clientCache");
1077
                    $xmldoc->writeAttribute('cacheControlMode', 'UseMaxAge');
1078
                    $xmldoc->writeAttribute('cacheControlMaxAge', '30.00:00:00');
1079
                $xmldoc->endElement();
1080
            $xmldoc->endElement();
1081
        $xmldoc->endElement();
1082
    $xmldoc->endElement();
1083
    $xmldoc->endDocument();
1084
    $xmldoc->flush();
1085
}
1086
1087
/**
1088
 * Drop old tables if table exists and told to drop it
1089
 */
1090
function drop_table_install( &$focus ){
1091
    global $db;
1092
    global $dictionary;
1093
1094
    $result = $db->tableExists($focus->table_name);
1095
1096
    if( $result ){
1097
        $focus->drop_tables();
1098
        $GLOBALS['log']->info("Dropped old ".$focus->table_name." table.");
1099
        return 1;
1100
    }
1101
    else {
1102
        $GLOBALS['log']->info("Did not need to drop old ".$focus->table_name." table.  It doesn't exist.");
1103
        return 0;
1104
    }
1105
}
1106
1107
// Creating new tables if they don't exist.
1108
function create_table_if_not_exist( &$focus ){
1109
    global  $db;
1110
    $table_created = false;
1111
1112
    // normal code follows
1113
    $result = $db->tableExists($focus->table_name);
1114
    if($result){
1115
        $GLOBALS['log']->info("Table ".$focus->table_name." already exists.");
1116
    } else {
1117
        $focus->create_tables();
1118
        $GLOBALS['log']->info("Created ".$focus->table_name." table.");
1119
        $table_created = true;
1120
    }
1121
    return $table_created;
1122
}
1123
1124
1125
1126
function create_default_users(){
1127
    global $db;
1128
    global $setup_site_admin_password;
1129
    global $setup_site_admin_user_name;
1130
    global $create_default_user;
1131
    global $sugar_config;
1132
1133
    require_once('install/UserDemoData.php');
1134
1135
    //Create default admin user
1136
    $user = new User();
1137
    $user->id = 1;
1138
    $user->new_with_id = true;
1139
    $user->last_name = 'Administrator';
1140
    $user->user_name = $setup_site_admin_user_name;
1141
    $user->title = "Administrator";
1142
    $user->status = 'Active';
1143
    $user->is_admin = true;
1144
    $user->employee_status = 'Active';
1145
    $user->user_hash = User::getPasswordHash($setup_site_admin_password);
1146
    $user->email = '';
1147
    $user->picture = UserDemoData::_copy_user_image($user->id);
1148
    $user->save();
1149
    //Bug#53793: Keep default current user in the global variable in order to store 'created_by' info as default user
1150
    //           while installation is proceed.
1151
    $GLOBALS['current_user'] = $user;
1152
1153
1154
    if( $create_default_user ){
1155
        $default_user = new User();
1156
        $default_user->last_name = $sugar_config['default_user_name'];
1157
        $default_user->user_name = $sugar_config['default_user_name'];
1158
        $default_user->status = 'Active';
1159
        if( isset($sugar_config['default_user_is_admin']) && $sugar_config['default_user_is_admin'] ){
1160
            $default_user->is_admin = true;
1161
        }
1162
        $default_user->user_hash = User::getPasswordHash($sugar_config['default_password']);
1163
        $default_user->save();
1164
    }
1165
}
1166
1167
function set_admin_password( $password ) {
1168
    global $db;
1169
1170
    $user_hash = User::getPasswordHash($password);
1171
1172
    $query = "update users set user_hash='$user_hash' where id='1'";
1173
1174
    $db->query($query);
1175
}
1176
1177
function insert_default_settings(){
1178
    global $db;
1179
    global $setup_sugar_version;
1180
    global $sugar_db_version;
1181
1182
1183
    $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'fromaddress', '[email protected]')");
1184
    $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'fromname', 'SuiteCRM')");
1185
    $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'send_by_default', '1')");
1186
    $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'on', '1')");
1187
    $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'send_from_assigning_user', '0')");
1188
    /* cn: moved to OutboundEmail class
1189
    $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpserver', 'localhost')");
1190
    $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpport', '25')");
1191
    $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'sendtype', 'smtp')");
1192
    $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpuser', '')");
1193
    $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtppass', '')");
1194
    $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpauth_req', '0')");
1195
    */
1196
    $db->query("INSERT INTO config (category, name, value) VALUES ('info', 'sugar_version', '" . $sugar_db_version . "')");
1197
    $db->query("INSERT INTO config (category, name, value) VALUES ('MySettings', 'tab', '')");
1198
    $db->query("INSERT INTO config (category, name, value) VALUES ('portal', 'on', '0')");
1199
1200
1201
1202
    //insert default tracker settings
1203
    $db->query("INSERT INTO config (category, name, value) VALUES ('tracker', 'Tracker', '1')");
1204
1205
1206
1207
    $db->query( "INSERT INTO config (category, name, value) VALUES ( 'system', 'skypeout_on', '1')" );
1208
1209
}
1210
1211
1212
1213
1214
1215
1216
1217
1218
// Returns true if the given file/dir has been made writable (or is already
1219
// writable).
1220
function make_writable($file)
1221
{
1222
1223
    $ret_val = false;
1224
    if(is_file($file) || is_dir($file))
1225
    {
1226
        if(is_writable($file))
1227
        {
1228
            $ret_val = true;
1229
        }
1230
        else
1231
        {
1232
            $original_fileperms = fileperms($file);
1233
1234
            // add user writable permission
1235
            $new_fileperms = $original_fileperms | 0x0080;
1236
            @sugar_chmod($file, $new_fileperms);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1237
            clearstatcache();
1238
            if(is_writable($file))
1239
            {
1240
                $ret_val = true;
1241
            }
1242
            else
1243
            {
1244
                // add group writable permission
1245
                $new_fileperms = $original_fileperms | 0x0010;
1246
                @chmod($file, $new_fileperms);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1247
                clearstatcache();
1248
                if(is_writable($file))
1249
                {
1250
                    $ret_val = true;
1251
                }
1252
                else
1253
                {
1254
                    // add world writable permission
1255
                    $new_fileperms = $original_fileperms | 0x0002;
1256
                    @chmod($file, $new_fileperms);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1257
                    clearstatcache();
1258
                    if(is_writable($file))
1259
                    {
1260
                        $ret_val = true;
1261
                    }
1262
                }
1263
            }
1264
        }
1265
    }
1266
1267
    return $ret_val;
1268
}
1269
1270
function recursive_make_writable($start_file)
1271
    {
1272
    $ret_val = make_writable($start_file);
1273
1274
    if($ret_val && is_dir($start_file))
1275
    {
1276
        // PHP 4 alternative to scandir()
1277
        $files = array();
1278
        $dh = opendir($start_file);
1279
        $filename = readdir($dh);
1280
        while(!empty($filename))
1281
        {
1282
            if($filename != '.' && $filename != '..' && $filename != '.svn')
1283
            {
1284
                $files[] = $filename;
1285
            }
1286
1287
            $filename = readdir($dh);
1288
        }
1289
1290
        foreach($files as $file)
1291
        {
1292
            $ret_val = recursive_make_writable($start_file . '/' . $file);
1293
1294
            if(!$ret_val)
1295
            {
1296
                $_SESSION['unwriteable_module_files'][dirname($file)] = dirname($file);
1297
                $fnl_ret_val = false;
1298
                //break;
1299
            }
1300
        }
1301
    }
1302
            if(!$ret_val)
1303
            {
1304
                $unwriteable_directory = is_dir($start_file) ? $start_file : dirname($start_file);
1305
                if($unwriteable_directory[0] == '.'){$unwriteable_directory = substr($unwriteable_directory,1);}
1306
                $_SESSION['unwriteable_module_files'][$unwriteable_directory] = $unwriteable_directory;
1307
                $_SESSION['unwriteable_module_files']['failed'] = true;
1308
            }
1309
1310
    return $ret_val;
1311
}
1312
1313
function recursive_is_writable($start_file)
1314
{
1315
    $ret_val = is_writable($start_file);
1316
1317
    if($ret_val && is_dir($start_file))
1318
    {
1319
        // PHP 4 alternative to scandir()
1320
        $files = array();
1321
        $dh = opendir($start_file);
1322
        $filename = readdir($dh);
1323
        while(!empty($filename))
1324
        {
1325
            if($filename != '.' && $filename != '..' && $filename != '.svn')
1326
            {
1327
                $files[] = $filename;
1328
            }
1329
1330
            $filename = readdir($dh);
1331
        }
1332
1333
        foreach($files as $file)
1334
        {
1335
            $ret_val = recursive_is_writable($start_file . '/' . $file);
1336
1337
            if(!$ret_val)
1338
            {
1339
                break;
1340
            }
1341
        }
1342
    }
1343
1344
    return $ret_val;
1345
}
1346
1347
// one place for form validation/conversion to boolean
1348
function get_boolean_from_request( $field ){
1349
    if( !isset($_REQUEST[$field]) ){
1350
        return( false );
1351
    }
1352
1353
    if( ($_REQUEST[$field] == 'on') || ($_REQUEST[$field] == 'yes') ){
1354
        return(true);
1355
    }
1356
    else {
1357
        return(false);
1358
    }
1359
}
1360
1361
function stripslashes_checkstrings($value){
1362
   if(is_string($value)){
1363
      return stripslashes($value);
1364
   }
1365
   return $value;
1366
}
1367
1368
1369
function print_debug_array( $name, $debug_array ){
1370
    ksort( $debug_array );
1371
1372
    print( "$name vars:\n" );
1373
    print( "(\n" );
1374
1375
    foreach( $debug_array as $key => $value ){
1376
        if( stristr( $key, "password" ) ){
1377
            $value = "WAS SET";
1378
        }
1379
        print( "    [$key] => $value\n" );
1380
    }
1381
1382
    print( ")\n" );
1383
}
1384
1385
function print_debug_comment(){
1386
    if( !empty($_REQUEST['debug']) ){
1387
        $_SESSION['debug'] = $_REQUEST['debug'];
1388
    }
1389
1390
    if( !empty($_SESSION['debug']) && ($_SESSION['debug'] == 'true') ){
1391
        print( "<!-- debug is on (to turn off, hit any page with 'debug=false' as a URL parameter.\n" );
1392
1393
        print_debug_array( "Session",   $_SESSION );
1394
        print_debug_array( "Request",   $_REQUEST );
1395
        print_debug_array( "Post",      $_POST );
1396
        print_debug_array( "Get",       $_GET );
1397
1398
        print_r( "-->\n" );
1399
    }
1400
}
1401
1402
function validate_systemOptions() {
1403
    global $mod_strings;
1404
    $errors = array();
1405
    if(!empty($_SESSION['setup_db_type']) && trim($_SESSION['setup_db_type']) != '') {
1406
        $db = DBManagerFactory::getTypeInstance($_SESSION['setup_db_type']);
1407
        if(!empty($db)) {
1408
            $_SESSION['setup_db_manager'] = get_class($db);
1409
            return $errors;
1410
        }
1411
    }
1412
    $errors[] = "<span class='error'>".$mod_strings['ERR_DB_INVALID']."</span>";
1413
    return $errors;
1414
}
1415
1416
1417
function validate_dbConfig() {
1418
    require_once('install/checkDBSettings.php');
1419
    return checkDBSettings(true);
1420
}
1421
1422
function validate_siteConfig($type){
1423
    global $mod_strings;
1424
   $errors = array();
1425
1426
   if($type=='a'){
1427
       if(empty($_SESSION['setup_system_name'])){
1428
            $errors[] = "<span class='error'>".$mod_strings['LBL_REQUIRED_SYSTEM_NAME']."</span>";
1429
       }
1430
       if($_SESSION['setup_site_url'] == ''){
1431
          $errors[] = "<span class='error'>".$mod_strings['ERR_URL_BLANK']."</span>";
1432
       }
1433
1434
       if($_SESSION['setup_site_admin_user_name'] == '') {
1435
          $errors[] = "<span class='error'>".$mod_strings['ERR_ADMIN_USER_NAME_BLANK']."</span>";
1436
       }
1437
1438
       if($_SESSION['setup_site_admin_password'] == ''){
1439
          $errors[] = "<span class='error'>".$mod_strings['ERR_ADMIN_PASS_BLANK']."</span>";
1440
       }
1441
1442
       if($_SESSION['setup_site_admin_password'] != $_SESSION['setup_site_admin_password_retype']){
1443
          $errors[] = "<span class='error'>".$mod_strings['ERR_PASSWORD_MISMATCH']."</span>";
1444
       }
1445
   }else{
1446
       if(!empty($_SESSION['setup_site_custom_session_path']) && $_SESSION['setup_site_session_path'] == ''){
1447
          $errors[] = "<span class='error'>".$mod_strings['ERR_SESSION_PATH']."</span>";
1448
       }
1449
1450
       if(!empty($_SESSION['setup_site_custom_session_path']) && $_SESSION['setup_site_session_path'] != ''){
1451
          if(is_dir($_SESSION['setup_site_session_path'])){
1452
             if(!is_writable($_SESSION['setup_site_session_path'])){
1453
                $errors[] = "<span class='error'>".$mod_strings['ERR_SESSION_DIRECTORY']."</span>";
1454
             }
1455
          }
1456
          else {
1457
             $errors[] = "<span class='error'>".$mod_strings['ERR_SESSION_DIRECTORY_NOT_EXISTS']."</span>";
1458
          }
1459
       }
1460
1461
       if(!empty($_SESSION['setup_site_custom_log_dir']) && $_SESSION['setup_site_log_dir'] == ''){
1462
          $errors[] = "<span class='error'>".$mod_strings['ERR_LOG_DIRECTORY_NOT_EXISTS']."</span>";
1463
       }
1464
1465
       if(!empty($_SESSION['setup_site_custom_log_dir']) && $_SESSION['setup_site_log_dir'] != ''){
1466
          if(is_dir($_SESSION['setup_site_log_dir'])){
1467
             if(!is_writable($_SESSION['setup_site_log_dir'])) {
1468
                $errors[] = "<span class='error'>".$mod_strings['ERR_LOG_DIRECTORY_NOT_WRITABLE']."</span>";
1469
             }
1470
          }
1471
          else {
1472
             $errors[] = "<span class='error'>".$mod_strings['ERR_LOG_DIRECTORY_NOT_EXISTS']."</span>";
1473
          }
1474
       }
1475
1476
       if(!empty($_SESSION['setup_site_specify_guid']) && $_SESSION['setup_site_guid'] == ''){
1477
          $errors[] = "<span class='error'>".$mod_strings['ERR_SITE_GUID']."</span>";
1478
       }
1479
   }
1480
1481
   return $errors;
1482
}
1483
1484
1485
function pullSilentInstallVarsIntoSession() {
1486
    global $mod_strings;
1487
    global $sugar_config;
1488
1489
    if( file_exists('config_si.php') ){
1490
        require_once('config_si.php');
1491
    }
1492
    else if( empty($sugar_config_si) ){
0 ignored issues
show
The variable $sugar_config_si does not exist. Did you mean $sugar_config?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
1493
        die( $mod_strings['ERR_SI_NO_CONFIG'] );
1494
    }
1495
1496
    $config_subset = array (
1497
        'setup_site_url'                => isset($sugar_config['site_url']) ? $sugar_config['site_url'] : '',
1498
        'setup_db_host_name'            => isset($sugar_config['dbconfig']['db_host_name']) ? $sugar_config['dbconfig']['db_host_name'] : '',
1499
        'setup_db_host_instance'        => isset($sugar_config['dbconfig']['db_host_instance']) ? $sugar_config['dbconfig']['db_host_instance'] : '',
1500
        'setup_db_sugarsales_user'      => isset($sugar_config['dbconfig']['db_user_name']) ? $sugar_config['dbconfig']['db_user_name'] : '',
1501
        'setup_db_sugarsales_password'  => isset($sugar_config['dbconfig']['db_password']) ? $sugar_config['dbconfig']['db_password'] : '',
1502
        'setup_db_database_name'        => isset($sugar_config['dbconfig']['db_name']) ? $sugar_config['dbconfig']['db_name'] : '',
1503
        'setup_db_type'                 => isset($sugar_config['dbconfig']['db_type']) ? $sugar_config['dbconfig']['db_type'] : '',
1504
        'setup_db_port_num'             => isset($sugar_config['dbconfig']['db_port']) ? $sugar_config['dbconfig']['db_port'] : '',
1505
        'setup_db_options'              => !empty($sugar_config['dbconfigoptions']) ? $sugar_config['dbconfigoptions'] : array(),
1506
    );
1507
    // third array of values derived from above values
1508
    $derived = array (
1509
        'setup_site_admin_password_retype'      => $sugar_config_si['setup_site_admin_password'],
1510
        'setup_db_sugarsales_password_retype'   => $config_subset['setup_db_sugarsales_password'],
1511
    );
1512
1513
    $needles = array('demoData','setup_db_create_database','setup_db_create_sugarsales_user','setup_license_key_users',
1514
                     'setup_license_key_expire_date','setup_license_key', 'setup_num_lic_oc',
1515
                     'default_currency_iso4217', 'default_currency_name', 'default_currency_significant_digits',
1516
                     'default_currency_symbol',  'default_date_format', 'default_time_format', 'default_decimal_seperator',
1517
                     'default_export_charset', 'default_language', 'default_locale_name_format', 'default_number_grouping_seperator',
1518
                     'export_delimiter', 'cache_dir', 'setup_db_options',
1519
                     'setup_fts_type', 'setup_fts_host', 'setup_fts_port', 'setup_fts_index_settings'. 'setup_fts_transport');
1520
    copyFromArray($sugar_config_si, $needles, $derived);
0 ignored issues
show
The call to the function copyFromArray() seems unnecessary as the function has no side-effects.
Loading history...
1521
    $all_config_vars = array_merge( $config_subset, $sugar_config_si, $derived );
1522
1523
    // bug 16860 tyoung -  trim leading and trailing whitespace from license_key
1524
    if (isset($all_config_vars['setup_license_key'])) {
1525
        $all_config_vars['setup_license_key'] = trim($all_config_vars['setup_license_key']);
1526
    }
1527
1528
    foreach( $all_config_vars as $key => $value ){
1529
        $_SESSION[$key] = $value;
1530
    }
1531
}
1532
1533
/**
1534
 * given an array it will check to determine if the key exists in the array, if so
1535
 * it will addd to the return array
1536
 *
1537
 * @param intput_array haystack to check
1538
 * @param needles list of needles to search for
1539
 * @param output_array the array to add the keys to
1540
 */
1541
function copyFromArray($input_array, $needles, $output_array){
1542
    foreach($needles as $needle){
1543
         if(isset($input_array[$needle])){
1544
            $output_array[$needle]  = $input_array[$needle];
1545
         }
1546
    }
1547
}
1548
1549
1550
1551
/**
1552
 * handles language pack uploads - code based off of upload_file->final_move()
1553
 * puts it into the cache/upload dir to be handed off to langPackUnpack();
1554
 *
1555
 * @param object file UploadFile object
1556
 * @return bool true if successful
1557
 */
1558
function langPackFinalMove($file) {
1559
    global $sugar_config;
1560
    //."upgrades/langpack/"
1561
    $destination = $sugar_config['upload_dir'].$file->stored_file_name;
1562
    if(!move_uploaded_file($_FILES[$file->field_name]['tmp_name'], $destination)) {
1563
        die ("ERROR: can't move_uploaded_file to $destination. You should try making the directory writable by the webserver");
1564
    }
1565
    return true;
1566
}
1567
1568
function getLicenseDisplay($type, $manifest, $zipFile, $next_step, $license_file, $clean_file) {
1569
    return PackageManagerDisplay::getLicenseDisplay($license_file, 'install.php', $next_step, $zipFile, $type, $manifest, $clean_file);
1570
}
1571
1572
1573
/**
1574
 * creates the remove/delete form for langpack page
1575
 * @param string type commit/remove
1576
 * @param string manifest path to manifest file
1577
 * @param string zipFile path to uploaded zip file
1578
 * @param int nextstep current step
1579
 * @return string ret <form> for this package
1580
 */
1581
function getPackButton($type, $manifest, $zipFile, $next_step, $uninstallable='Yes', $showButtons=true) {
1582
    global $mod_strings;
1583
1584
    $button = $mod_strings['LBL_LANG_BUTTON_COMMIT'];
1585
    if($type == 'remove') {
1586
        $button = $mod_strings['LBL_LANG_BUTTON_REMOVE'];
1587
    } elseif($type == 'uninstall') {
1588
        $button = $mod_strings['LBL_LANG_BUTTON_UNINSTALL'];
1589
    }
1590
1591
    $disabled = ($uninstallable == 'Yes') ? false : true;
1592
1593
    $ret = "<form name='delete{$zipFile}' action='install.php' method='POST'>
1594
                <input type='hidden' name='current_step' value='{$next_step}'>
1595
                <input type='hidden' name='goto' value='{$mod_strings['LBL_CHECKSYS_RECHECK']}'>
1596
                <input type='hidden' name='languagePackAction' value='{$type}'>
1597
                <input type='hidden' name='manifest' value='".urlencode($manifest)."'>
1598
                <input type='hidden' name='zipFile' value='".urlencode($zipFile)."'>
1599
                <input type='hidden' name='install_type' value='custom'>";
1600
    if(!$disabled && $showButtons) {
1601
        $ret .= "<input type='submit' value='{$button}' class='button'>";
1602
    }
1603
    $ret .= "</form>";
1604
    return $ret;
1605
}
1606
1607
/**
1608
 * finds all installed languages and returns an array with the names
1609
 * @return array langs array of installed languages
1610
 */
1611
function getInstalledLanguages() {
1612
    $langDir = 'include/language/';
1613
    $dh = opendir($langDir);
1614
1615
    $langs = array();
1616
    while($file = readdir($dh)) {
1617
        if(substr($file, -3) == 'php') {
0 ignored issues
show
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
1618
1619
        }
1620
    }
1621
}
1622
1623
1624
1625
/**
1626
 * searches upgrade dir for lang pack files.
1627
 *
1628
 * @return string HTML of available lang packs
1629
 */
1630
function getLangPacks($display_commit = true, $types = array('langpack'), $notice_text = '') {
1631
    global $mod_strings;
1632
    global $next_step;
1633
    global $base_upgrade_dir;
1634
1635
    if(empty($notice_text)){
1636
        $notice_text =  $mod_strings['LBL_LANG_PACK_READY'];
1637
    }
1638
    $ret = "<tr><td colspan=7 align=left>{$notice_text}</td></tr>";
1639
    //$ret .="<table width='100%' cellpadding='0' cellspacing='0' border='0'>";
1640
    $ret .= "<tr>
1641
                <td width='20%' ><b>{$mod_strings['LBL_ML_NAME']}</b></td>
1642
                <td width='15%' ><b>{$mod_strings['LBL_ML_VERSION']}</b></td>
1643
                <td width='15%' ><b>{$mod_strings['LBL_ML_PUBLISHED']}</b></td>
1644
                <td width='15%' ><b>{$mod_strings['LBL_ML_UNINSTALLABLE']}</b></td>
1645
                <td width='20%' ><b>{$mod_strings['LBL_ML_DESCRIPTION']}</b></td>
1646
                <td width='7%' ></td>
1647
                <td width='1%' ></td>
1648
                <td width='7%' ></td>
1649
            </tr>\n";
1650
    $files = array();
1651
1652
    // duh, new installs won't have the upgrade folders
1653
   if(!is_dir($base_upgrade_dir)) {
1654
        mkdir_recursive( $base_upgrade_dir);
1655
    }
1656
    $subdirs = array('full', 'langpack', 'module', 'patch', 'theme', 'temp');
1657
    foreach( $subdirs as $subdir ){
1658
        mkdir_recursive( "$base_upgrade_dir/$subdir" );
1659
    }
1660
1661
    $files = findAllFiles($base_upgrade_dir, $files);
1662
    $hidden_input = '';
1663
    unset($_SESSION['hidden_input']);
1664
1665
    foreach($files as $file) {
1666
        if(!preg_match("#.*\.zip\$#", $file)) {
1667
            continue;
1668
        }
1669
1670
        // skip installed lang packs
1671
        if(isset($_SESSION['INSTALLED_LANG_PACKS']) && in_array($file, $_SESSION['INSTALLED_LANG_PACKS'])) {
1672
            continue;
1673
        }
1674
1675
        // handle manifest.php
1676
        $target_manifest = remove_file_extension( $file ) . '-manifest.php';
1677
        $license_file = remove_file_extension( $file ) . '-license.txt';
1678
        include($target_manifest);
1679
1680
        if(!empty($types)){
1681
            if(!in_array(strtolower($manifest['type']), $types))
1682
                continue;
1683
        }
1684
1685
        $md5_matches = array();
1686
        if($manifest['type'] == 'module'){
1687
            $uh = new UpgradeHistory();
1688
            $upgrade_content = clean_path($file);
1689
            $the_base = basename($upgrade_content);
1690
            $the_md5 = md5_file($upgrade_content);
1691
            $md5_matches = $uh->findByMd5($the_md5);
1692
        }
1693
1694
        if($manifest['type']!= 'module' || 0 == sizeof($md5_matches)){
1695
            $name = empty($manifest['name']) ? $file : $manifest['name'];
1696
            $version = empty($manifest['version']) ? '' : $manifest['version'];
1697
            $published_date = empty($manifest['published_date']) ? '' : $manifest['published_date'];
1698
            $icon = '';
1699
            $description = empty($manifest['description']) ? 'None' : $manifest['description'];
1700
            $uninstallable = empty($manifest['is_uninstallable']) ? 'No' : 'Yes';
1701
            $manifest_type = $manifest['type'];
1702
            $commitPackage = getPackButton('commit', $target_manifest, $file, $next_step);
1703
            $deletePackage = getPackButton('remove', $target_manifest, $file, $next_step);
1704
            //$ret .="<table width='100%' cellpadding='0' cellspacing='0' border='0'>";
1705
            $ret .= "<tr>";
1706
            $ret .= "<td width='20%' >".$name."</td>";
1707
            $ret .= "<td width='15%' >".$version."</td>";
1708
            $ret .= "<td width='15%' >".$published_date."</td>";
1709
            $ret .= "<td width='15%' >".$uninstallable."</td>";
1710
            $ret .= "<td width='20%' >".$description."</td>";
1711
1712
            if($display_commit)
1713
                $ret .= "<td width='7%'>{$commitPackage}</td>";
1714
            $ret .= "<td width='1%'></td>";
1715
            $ret .= "<td width='7%'>{$deletePackage}</td>";
1716
            $ret .= "</td></tr>";
1717
1718
            $clean_field_name = "accept_lic_".str_replace('.', '_', urlencode(basename($file)));
1719
1720
            if(is_file($license_file)){
1721
                //rrs
1722
                $ret .= "<tr><td colspan=6>";
1723
                $ret .= getLicenseDisplay('commit', $target_manifest, $file, $next_step, $license_file, $clean_field_name);
1724
                $ret .= "</td></tr>";
1725
                $hidden_input .= "<input type='hidden' name='$clean_field_name' id='$clean_field_name' value='no'>";
1726
            }else{
1727
                $hidden_input .= "<input type='hidden' name='$clean_field_name' id='$clean_field_name' value='yes'>";
1728
            }
1729
        }//fi
1730
    }//rof
1731
    $_SESSION['hidden_input'] = $hidden_input;
1732
1733
    if(count($files) > 0 ) {
1734
        $ret .= "</tr><td colspan=7>";
1735
        $ret .= "<form name='commit' action='install.php' method='POST'>
1736
                    <input type='hidden' name='current_step' value='{$next_step}'>
1737
                    <input type='hidden' name='goto' value='Re-check'>
1738
                    <input type='hidden' name='languagePackAction' value='commit'>
1739
                    <input type='hidden' name='install_type' value='custom'>
1740
                 </form>
1741
                ";
1742
        $ret .= "</td></tr>";
1743
    } else {
1744
        $ret .= "</tr><td colspan=7><i>{$mod_strings['LBL_LANG_NO_PACKS']}</i></td></tr>";
1745
    }
1746
    return $ret;
1747
}
1748
1749
if ( !function_exists('extractFile') ) {
1750
function extractFile( $zip_file, $file_in_zip, $base_tmp_upgrade_dir){
1751
    $my_zip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
1752
    unzip_file( $zip_file, $file_in_zip, $my_zip_dir );
1753
    return( "$my_zip_dir/$file_in_zip" );
1754
}
1755
}
1756
1757
if ( !function_exists('extractManifest') ) {
1758
function extractManifest( $zip_file,$base_tmp_upgrade_dir ) {
1759
    return( extractFile( $zip_file, "manifest.php",$base_tmp_upgrade_dir ) );
1760
}
1761
}
1762
1763
if ( !function_exists('unlinkTempFiles') ) {
1764
function unlinkTempFiles($manifest='', $zipFile='') {
1765
    global $sugar_config;
1766
1767
    @unlink($_FILES['language_pack']['tmp_name']);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1768
    if(!empty($manifest))
1769
        @unlink($manifest);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1770
    if(!empty($zipFile)) {
1771
        //@unlink($zipFile);
1772
        $tmpZipFile = substr($zipFile, strpos($zipFile, 'langpack/') + 9, strlen($zipFile));
1773
        @unlink($sugar_config['upload_dir'].$tmpZipFile);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1774
    }
1775
1776
    rmdir_recursive($sugar_config['upload_dir']."upgrades/temp");
1777
    sugar_mkdir($sugar_config['upload_dir']."upgrades/temp");
1778
}
1779
}
1780
1781
function langPackUnpack($unpack_type, $full_file)
1782
{
1783
    global $sugar_config;
1784
    global $base_upgrade_dir;
1785
    global $base_tmp_upgrade_dir;
1786
1787
    $manifest = array();
1788
    if(!empty($full_file)){
1789
        $base_filename = pathinfo(urldecode($full_file), PATHINFO_FILENAME );
1790
    } else {
1791
        return "Empty filename supplied";
1792
    }
1793
    $manifest_file = extractManifest($full_file, $base_tmp_upgrade_dir);
1794
    if($unpack_type == 'module')
1795
        $license_file = extractFile($full_file, 'LICENSE.txt', $base_tmp_upgrade_dir);
1796
1797
    if(is_file($manifest_file)) {
1798
1799
        if($unpack_type == 'module' && is_file($license_file)){
1800
            copy($license_file, $base_upgrade_dir.'/'.$unpack_type.'/'.$base_filename."-license.txt");
1801
        }
1802
        copy($manifest_file, $base_upgrade_dir.'/'.$unpack_type.'/'.$base_filename."-manifest.php");
1803
1804
        require_once( $manifest_file );
1805
        validate_manifest( $manifest );
1806
        $upgrade_zip_type = $manifest['type'];
1807
1808
        mkdir_recursive( "$base_upgrade_dir/$upgrade_zip_type" );
1809
        $target_path = "$base_upgrade_dir/$upgrade_zip_type/$base_filename";
1810
        $target_manifest = $target_path . "-manifest.php";
1811
1812
        if( isset($manifest['icon']) && $manifest['icon'] != "" ) {
1813
            $icon_location = extractFile( $full_file, $manifest['icon'], $base_tmp_upgrade_dir );
1814
            $path_parts = pathinfo( $icon_location );
1815
            copy( $icon_location, $target_path . "-icon." . $path_parts['extension'] );
1816
        }
1817
1818
        // move file from uploads to cache
1819
        // FIXME: where should it be?
1820
        if( copy( $full_file , $target_path.".zip" ) ){
1821
            copy( $manifest_file, $target_manifest );
1822
            unlink($full_file); // remove tempFile
1823
            return "The file $base_filename has been uploaded.<br>\n";
1824
        } else {
1825
            unlinkTempFiles($manifest_file, $full_file);
1826
            return "There was an error uploading the file, please try again!<br>\n";
1827
        }
1828
    } else {
1829
        die("The zip file is missing a manifest.php file.  Cannot proceed.");
1830
    }
1831
    unlinkTempFiles($manifest_file, '');
0 ignored issues
show
unlinkTempFiles($manifest_file, ''); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
1832
}
1833
1834
if ( !function_exists('validate_manifest') ) {
1835
function validate_manifest( $manifest ){
1836
    // takes a manifest.php manifest array and validates contents
1837
    global $subdirs;
1838
    global $sugar_version;
1839
    global $sugar_flavor;
1840
    global $mod_strings;
1841
1842
    if( !isset($manifest['type']) ){
1843
        die($mod_strings['ERROR_MANIFEST_TYPE']);
1844
    }
1845
    $type = $manifest['type'];
1846
    if( getInstallType( "/$type/" ) == "" ){
1847
        die($mod_strings['ERROR_PACKAGE_TYPE']. ": '" . $type . "'." );
1848
    }
1849
1850
    return true; // making this a bit more relaxed since we updated the language extraction and merge capabilities
1851
1852
    /*
1853
    if( isset($manifest['acceptable_sugar_versions']) ){
1854
        $version_ok = false;
1855
        $matches_empty = true;
1856
        if( isset($manifest['acceptable_sugar_versions']['exact_matches']) ){
1857
            $matches_empty = false;
1858
            foreach( $manifest['acceptable_sugar_versions']['exact_matches'] as $match ){
1859
                if( $match == $sugar_version ){
1860
                    $version_ok = true;
1861
                }
1862
            }
1863
        }
1864
        if( !$version_ok && isset($manifest['acceptable_sugar_versions']['regex_matches']) ){
1865
            $matches_empty = false;
1866
            foreach( $manifest['acceptable_sugar_versions']['regex_matches'] as $match ){
1867
                if( preg_match( "/$match/", $sugar_version ) ){
1868
                    $version_ok = true;
1869
                }
1870
            }
1871
        }
1872
1873
        if( !$matches_empty && !$version_ok ){
1874
            die( $mod_strings['ERROR_VERSION_INCOMPATIBLE'] . $sugar_version );
1875
        }
1876
    }
1877
1878
    if( isset($manifest['acceptable_sugar_flavors']) && sizeof($manifest['acceptable_sugar_flavors']) > 0 ){
1879
        $flavor_ok = false;
1880
        foreach( $manifest['acceptable_sugar_flavors'] as $match ){
1881
            if( $match == $sugar_flavor ){
1882
                $flavor_ok = true;
1883
            }
1884
        }
1885
        if( !$flavor_ok ){
1886
            //die( $mod_strings['ERROR_FLAVOR_INCOMPATIBLE'] . $sugar_flavor );
1887
        }
1888
    }*/
1889
}
1890
}
1891
1892
if ( !function_exists('getInstallType') ) {
1893
function getInstallType( $type_string ){
1894
    // detect file type
1895
    $subdirs = array('full', 'langpack', 'module', 'patch', 'theme', 'temp');
1896
    foreach( $subdirs as $subdir ){
1897
        if( preg_match( "#/$subdir/#", $type_string ) ){
1898
            return( $subdir );
1899
        }
1900
    }
1901
    // return empty if no match
1902
    return( "" );
1903
}
1904
}
1905
1906
1907
1908
//mysqli connector has a separate parameter for port.. We need to separate it out from the host name
1909
function getHostPortFromString($hostname=''){
1910
1911
    $pos=strpos($hostname,':');
1912
    if($pos === false){
1913
        //no need to process as string is empty or does not contain ':' delimiter
1914
        return '';
1915
    }
1916
1917
    $hostArr = explode(':', $hostname);
1918
1919
    return $hostArr;
1920
1921
}
1922
1923
function getLicenseContents($filename)
1924
{
1925
    $license_file = '';
1926
    if(file_exists($filename) && filesize($filename) >0){
1927
        $license_file = trim(file_get_contents($filename));
1928
    }
1929
    return $license_file;
1930
}
1931
1932
1933
1934
1935
1936
1937
1938
1939
///////////////////////////////////////////////////////////////////////////////
1940
////    FROM POPULATE SEED DATA
1941
$seed = array(
1942
    'qa',       'dev',          'beans',
1943
    'info',     'sales',        'support',
1944
    'kid',      'the',          'section',
1945
    'sugar',    'hr',           'im',
1946
    'kid',      'vegan',        'phone',
1947
);
1948
$tlds = array(
1949
    ".com", ".org", ".net", ".tv", ".cn", ".co.jp", ".us",
1950
    ".edu", ".tw", ".de", ".it", ".co.uk", ".info", ".biz",
1951
    ".name",
1952
);
1953
1954
/**
1955
 * creates a random, DNS-clean webaddress
1956
 */
1957
function createWebAddress() {
1958
    global $seed;
1959
    global $tlds;
1960
1961
    $one = $seed[rand(0, count($seed)-1)];
1962
    $two = $seed[rand(0, count($seed)-1)];
1963
    $tld = $tlds[rand(0, count($tlds)-1)];
1964
1965
    return "www.{$one}{$two}{$tld}";
1966
}
1967
1968
/**
1969
 * creates a random email address
1970
 * @return string
1971
 */
1972
function createEmailAddress() {
1973
    global $seed;
1974
    global $tlds;
1975
1976
    $part[0] = $seed[rand(0, count($seed)-1)];
1977
    $part[1] = $seed[rand(0, count($seed)-1)];
1978
    $part[2] = $seed[rand(0, count($seed)-1)];
1979
1980
    $tld = $tlds[rand(0, count($tlds)-1)];
1981
1982
    $len = rand(1,3);
1983
1984
    $ret = '';
1985
    for($i=0; $i<$len; $i++) {
1986
        $ret .= (empty($ret)) ? '' : '.';
1987
        $ret .= $part[$i];
1988
    }
1989
1990
    if($len == 1) {
1991
        $ret .= rand(10, 99);
1992
    }
1993
1994
    return "{$ret}@example{$tld}";
1995
}
1996
1997
1998
function add_digits($quantity, &$string, $min = 0, $max = 9) {
1999
    for($i=0; $i < $quantity; $i++) {
2000
        $string .= mt_rand($min,$max);
2001
    }
2002
}
2003
2004
function create_phone_number() {
2005
    $phone = "(";
2006
    add_digits(3, $phone);
2007
    $phone .= ") ";
2008
    add_digits(3, $phone);
2009
    $phone .= "-";
2010
    add_digits(4, $phone);
2011
2012
    return $phone;
2013
}
2014
2015
function create_date($year=null,$mnth=null,$day=null)
2016
{
2017 1
    global $timedate;
2018 1
    $now = $timedate->getNow();
2019 1
    if ($day==null) $day=$now->day+mt_rand(0,365);
2020 1
    return $timedate->asDbDate($now->get_day_begin($day, $mnth, $year));
2021
}
2022
2023
function create_current_date_time()
2024
{
2025
    global $timedate;
2026
    return $timedate->nowDb();
2027
}
2028
2029
function create_time($hr=null,$min=null,$sec=null)
2030
{
2031 1
    global $timedate;
2032 1
    $date = TimeDate::getInstance()->fromTimestamp(0);
2033 1
    if ($hr==null) $hr=mt_rand(6,19);
2034 1
    if ($min==null) $min=(mt_rand(0,3)*15);
2035 1
    if ($sec==null) $sec=0;
2036 1
    return $timedate->asDbTime($date->setDate(2007, 10, 7)->setTime($hr, $min, $sec));
2037
}
2038
2039
function create_past_date()
2040
{
2041
    global $timedate;
2042
    $now = $timedate->getNow(true);
2043
    $day=$now->day-mt_rand(1, 365);
2044
    return $timedate->asDbDate($now->get_day_begin($day));
2045
}
2046
2047
/**
2048
*   This method will look for a file modules_post_install.php in the root directory and based on the
2049
*   contents of this file, it will silently install any modules as specified in this array.
2050
*/
2051
function post_install_modules(){
2052
    if(is_file('modules_post_install.php')){
2053
        global $current_user, $mod_strings;
2054
        $current_user = new User();
2055
        $current_user->is_admin = '1';
2056
        require_once('ModuleInstall/PackageManager/PackageManager.php');
2057
        require_once('modules_post_install.php');
2058
        //we now have the $modules_to_install array in memory
2059
        $pm = new PackageManager();
2060
        $old_mod_strings = $mod_strings;
2061
        foreach($modules_to_install as $module_to_install){
2062
            if(is_file($module_to_install)){
2063
                $pm->performSetup($module_to_install, 'module', false);
2064
                $file_to_install = sugar_cached('upload/upgrades/module/').basename($module_to_install);
2065
                $_REQUEST['install_file'] = $file_to_install;
2066
                $pm->performInstall($file_to_install);
2067
            }
2068
        }
2069
        $mod_strings = $old_mod_strings;
2070
    }
2071
}
2072
2073
function get_help_button_url(){
2074
    $help_url = 'http://www.sugarcrm.com/docs/Administration_Guides/CommunityEdition_Admin_Guide_5.0/toc.html';
2075
2076
    return $help_url;
2077
}
2078
2079
function create_db_user_creds($numChars=10){
2080
$numChars = 7; // number of chars in the password
2081
//chars to select from
2082
$charBKT = "abcdefghijklmnpqrstuvwxyz123456789ABCDEFGHIJKLMNPQRSTUVWXYZ";
2083
// seed the random number generator
2084
srand((double)microtime()*1000000);
2085
$password="";
2086
for ($i=0;$i<$numChars;$i++)  // loop and create password
2087
            $password = $password . substr ($charBKT, rand() % strlen($charBKT), 1);
2088
2089
return $password;
2090
2091
}
2092
2093
function addDefaultRoles($defaultRoles = array()) {
2094
    global $db;
2095
2096
2097
    foreach($defaultRoles as $roleName=>$role){
2098
        $ACLField = new ACLField();
2099
        $role1= new ACLRole();
2100
        $role1->name = $roleName;
2101
        $role1->description = $roleName." Role";
2102
        $role1_id=$role1->save();
2103
        foreach($role as $category=>$actions){
2104
            foreach($actions as $name=>$access_override){
2105
                if($name=='fields'){
2106
                    foreach($access_override as $field_id=>$access){
2107
                        $ACLField->setAccessControl($category, $role1_id, $field_id, $access);
2108
                    }
2109
                }else{
2110
                    $queryACL="SELECT id FROM acl_actions where category='$category' and name='$name'";
2111
                    $result = $db->query($queryACL);
2112
                    $actionId=$db->fetchByAssoc($result);
2113
                    if (isset($actionId['id']) && !empty($actionId['id'])){
2114
                        $role1->setAction($role1_id, $actionId['id'], $access_override);
2115
                    }
2116
                }
2117
            }
2118
        }
2119
    }
2120
}
2121
2122
/**
2123
 * Fully enable SugarFeeds, enabling the user feed and all available modules that have SugarFeed data.
2124
 */
2125
function enableSugarFeeds()
2126
{
2127
    $admin = new Administration();
2128
    $admin->saveSetting('sugarfeed','enabled','1');
2129
2130
    foreach ( SugarFeed::getAllFeedModules() as $module )
2131
        SugarFeed::activateModuleFeed($module);
2132
2133
    check_logic_hook_file('Users','after_login', array(1, 'SugarFeed old feed entry remover', 'modules/SugarFeed/SugarFeedFlush.php', 'SugarFeedFlush', 'flushStaleEntries'));
2134
}
2135
2136
function create_writable_dir($dirname)
2137
{
2138
    if ((is_dir($dirname)) || @sugar_mkdir($dirname,0755)) {
2139
        $ok = make_writable($dirname);
2140
    }
2141
    if(empty($ok)) {
2142
        installLog("ERROR: Cannot create writable dir $dirname");
2143
    }
2144
}
2145
2146
/**
2147
 * Enable the InsideView connector for the four default modules.
2148
 */
2149
function enableInsideViewConnector()
2150
{
2151
    // Load up the existing mapping and hand it to the InsideView connector to have it setup the correct logic hooks
2152
    $mapFile = 'modules/Connectors/connectors/sources/ext/rest/insideview/mapping.php';
2153
    if ( file_exists('custom/'.$mapFile) ) {
2154
        require('custom/'.$mapFile);
2155
    } else {
2156
        require($mapFile);
2157
    }
2158
2159
    require_once('modules/Connectors/connectors/sources/ext/rest/insideview/insideview.php');
2160
    $source = new ext_rest_insideview();
2161
2162
    // $mapping is brought in from the mapping.php file above
2163
    $source->saveMappingHook($mapping);
2164
}
2165