Completed
Push — console-installer ( e2b50d...6ce748 )
by Adam
22:30
created

Installer::performInstallation()   F

Complexity

Conditions 22
Paths 11522

Size

Total Lines 402
Code Lines 204

Duplication

Lines 0
Ratio 0 %

Importance

Changes 9
Bugs 1 Features 0
Metric Value
cc 22
eloc 204
c 9
b 1
f 0
nc 11522
nop 0
dl 0
loc 402
rs 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Created by Adam Jakab.
4
 * Date: 26/04/16
5
 * Time: 14.35
6
 */
7
8
namespace SuiteCrm\Install;
9
10
/**
11
 * Class Installer
12
 * @package SuiteCrm\Install
13
 */
14
class Installer
15
{
16
    /** @var array */
17
    protected $config = [];
18
19
    /** @var LoggerManager */
20
    protected $loggerManager;
21
22
23
    /**
24
     * @param array $config
25
     * @param LoggerManager $logger
26
     */
27
    public function __construct($config, LoggerManager $logger)
28
    {
29
        $this->config = $config;
30
        $this->loggerManager = $logger;
31
    }
32
33
    public function install() {
34
        $this->log("Installer configuration: " . json_encode($this->config), 'info');
35
        $this->setPhpOptions();
36
        $this->setupSugarServerValues();
37
        $this->setupSugarGlobals();
38
        $this->setupSugarSessionVars();
39
        $this->setupSugarLogger();
40
        $this->performInstallation();
41
    }
42
43
    /**
44
     *  Main setup method
45
     */
46
    protected function performInstallation()
47
    {
48
        $startTime = microtime(TRUE);
49
50
        define('sugarEntry', TRUE);
51
52
        /** @var array $sugar_config */
53
        global $sugar_config;
54
55
        /** @var \DBManager $db */
56
        global $db;
57
58
        /** @var array $beanList */
59
        global $beanList;
60
61
        /** @var array $beanFiles */
62
        global $beanFiles;
63
64
        /** @var array $app_list_strings */
65
        global $app_list_strings;
66
67
        /** @var \TimeDate $timedate */
68
        global $timedate;
69
70
        /** @var \User $current_user */
71
        global $current_user;
72
73
        require_once(PROJECT_ROOT . '/sugar_version.php');
74
        require_once(PROJECT_ROOT . '/suitecrm_version.php');
75
        require_once(PROJECT_ROOT . '/include/utils.php');
76
        require_once(PROJECT_ROOT . '/include/TimeDate.php');
77
        require_once(PROJECT_ROOT . '/include/Localization/Localization.php');
78
        require_once(PROJECT_ROOT . '/include/SugarTheme/SugarTheme.php');
79
        require_once(PROJECT_ROOT . '/include/utils/LogicHook.php');
80
        require_once(PROJECT_ROOT . '/data/SugarBean.php');
81
        require_once(PROJECT_ROOT . '/include/entryPoint.php');
82
        require_once(PROJECT_ROOT . '/modules/TableDictionary.php');
83
84
        /** @var array $dictionary */
85
        /** @var string $sugar_version */
86
        /** @var string $sugar_db_version */
87
        /** @var string $suitecrm_version */
88
89
90
        $timedate = \TimeDate::getInstance();
91
        $locale = new \Localization();
92
93
        $install_script = TRUE;
94
        $current_language = 'en_us';
95
96
        //@todo: implement multi-language responses for web-installer (add --install-language option)
97
        $mod_strings = [];
98
        //@include(PROJECT_ROOT . '/install/language/en_us.lang.php');
99
        $app_list_strings = return_app_list_strings_language($current_language);
100
101
102
        $this->log("Running System Checks");
103
        $this->config = SystemChecker::runChecks($this->config);
104
105
        $this->log("Running Database Checks");
106
        $this->config = DatabaseChecker::runChecks($this->config);
107
108
        if (is_file("config.php")) {
109
            $this->log("Removing stale configuration file");
110
            unlink("config.php");
111
        }
112
113
        $this->log("Pausing TrackerManager");
114
        $trackerManager = \TrackerManager::getInstance();
115
        $trackerManager->pause();
116
117
        $this->log("Ensuring file/folder states");
118
        InstallUtils::ensureFileFolderStates();
119
120
        $this->log("Creating Default Sugar Configuration");
121
        $configOverride = array_merge($this->config, [
122
            'sugar_version' => $sugar_version,
123
            'suitecrm_version' => $suitecrm_version,
124
        ]);
125
        InstallUtils::createDefaultSugarConfig($configOverride);
126
        $this->log("SUGAR_CONFIG: " . print_r($sugar_config, TRUE), 'debug');
127
128
        $this->log("Handling Web Config");
129
        InstallUtils::handleWebConfig();
130
131
        $this->log("Handling Htaccess");
132
        InstallUtils::handleHtaccess();
133
134
        /**
135
         * Set up database
136
         */
137
        $connectionConfig = [
138
            "database-type" =>          $this->config['database-type'],
139
            "database-host" =>          $this->config['database-host'],
140
            "database-port" =>          $this->config['database-port'],
141
            "database-username" =>      $this->config['database-username'],
142
            "database-password" =>      $this->config['database-password'],
143
            "database-host-instance" => $this->config['database-host-instance'],
144
        ];
145
        //try to connect to database server without setting the database name
146
        $db = InstallUtils::getDatabaseConnection($connectionConfig);
147
        $databaseExists = $db->dbExists($this->config['database-name']);
148
        if ($this->config['install-create-database']) {
149
            if($databaseExists) {
150
                $this->log("Dropping Database: " . $this->config['database-name']);
151
                $db->dropDatabase($this->config['database-name']);
152
            }
153
            InstallUtils::installerHook('pre_handleDbCreateDatabase');
154
            $this->log("Creating Database: " . $this->config['database-name']);
155
            $db->createDatabase($this->config['database-name']);
156
            InstallUtils::installerHook('post_handleDbCreateDatabase');
157
        } else {
158
            if(!$databaseExists) {
159
                $sugar_config['dbconfig'] = '';//sugar_cleanup() trick
160
                throw new \Exception("Database does not exist! Use the --install-create-database option to create it.");
161
            } else {
162
                $this->log("Configuring Database Collation");
163
                InstallUtils::installerHook('pre_handleDbCharsetCollation');
164
                InstallUtils::handleDbCharsetCollation($this->config);
165
                InstallUtils::installerHook('post_handleDbCharsetCollation');
166
            }
167
        }
168
        //now we should have database
169
        $connectionConfig['database-name'] = $this->config['database-name'];
170
        $db = InstallUtils::getDatabaseConnection($connectionConfig);
171
172
        /**
173
         * @var string $beanName
174
         * @var string $beanFile
175
         */
176
        $this->log("Loading Bean files");
177
        foreach ($beanFiles as $beanName => $beanFile) {
178
            $this->log("Requiring bean[$beanName] file: $beanFile", "debug");
179
            require_once($beanFile);
180
        }
181
182
        $this->log("Cleaning Vardefs");
183
        \VardefManager::clearVardef();
184
185
        /** @var \DBManager $db */
186
        $db = InstallUtils::getDatabaseConnection($this->config);
187
188
        /**
189
         * Loop through all the Beans and create their tables
190
         */
191
        $this->log("Creating Database Tables");
192
193
        $processed_tables = []; //for keeping track of the tables we have worked on
194
        $nonStandardModules = []; //?useful?
195
196
        /**
197
         * We must place AOW_WorkFlow right after the Relationship module, otherwise
198
         * if we have empty database we will get tons of sql failures
199
         */
200
        $beanFiles = array_merge(
201
            [
202
                'ACLAction' => $beanFiles['ACLAction'],
203
                'ACLRole' => $beanFiles['ACLRole'],
204
                'Relationship' => $beanFiles['Relationship'],
205
                'AOW_WorkFlow' => $beanFiles['AOW_WorkFlow'],
206
            ],
207
            $beanFiles
208
        );
209
210
        $doNotInitModules = [
211
            'Scheduler',
212
            'SchedulersJob',
213
            'ProjectTask',
214
            'jjwg_Maps',
215
            'jjwg_Address_Cache',
216
            'jjwg_Areas',
217
            'jjwg_Markers'
218
        ];
219
220
        InstallUtils::installerHook('pre_createAllModuleTables');
221
        foreach ($beanFiles as $beanName => $beanFile) {
222
            /** @var \SugarBean $focus */
223
            if (in_array($beanName, $doNotInitModules)) {
224
                $focus = new $beanName(FALSE);
225
            } else {
226
                $focus = new $beanName();
227
            }
228
229
            if ($beanName == 'Configurator') {
230
                continue;
231
            }
232
233
            $table_name = $focus->table_name;
234
235
            $this->log("Processing Module: " . $beanName . "(" . $focus->table_name . ")", 'info');
236
237
            // check to see if we have already setup this table
238
            if (!in_array($table_name, $processed_tables)) {
239
                if (!file_exists("modules/" . $focus->module_dir . "/vardefs.php")) {
240
                    continue;
241
                }
242
                if (!in_array($beanName, $nonStandardModules)) {
243
                    require_once("modules/" . $focus->module_dir . "/vardefs.php"); // load up $dictionary
244
                    if ($dictionary[$focus->object_name]['table'] == 'does_not_exist') {
0 ignored issues
show
Bug introduced by
The variable $dictionary seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
245
                        continue; // support new vardef definitions
246
                    }
247
                }
248
                else {
249
                    continue; //no further processing needed for ignored beans.
250
                }
251
252
                // table has not been setup...we will do it now and remember that
253
                $processed_tables[] = $table_name;
254
255
                $focus->db->database = $db->database; // set db connection so we do not need to reconnect
256
257
                if ($this->config['install-drop-tables'] == true) {
258
                    InstallUtils::dropBeanTables($db, $focus);
259
                }
260
261
                InstallUtils::createBeanTables($db, $focus);
262
263
                //$this->log("creating Relationship Meta for ".$focus->getObjectName());
264
                InstallUtils::installerHook('pre_createModuleTable', array('module' => $focus->getObjectName()));
265
                \SugarBean::createRelationshipMeta(
266
                    $focus->getObjectName(), $db, $table_name, '', $focus->module_dir
267
                );
268
                InstallUtils::installerHook('post_createModuleTable', array('module' => $focus->getObjectName()));
269
            }
270
        }
271
        InstallUtils::installerHook('post_createAllModuleTables');
272
273
274
        /**
275
         * Create Relationships tables
276
         */
277
        $this->log("Creating Relationships");
278
        ksort($dictionary);
279
        foreach ($dictionary as $rel_name => $rel_data) {
280
            $table = $rel_data['table'];
281
            $this->log("Processing Relationship: " . $rel_name . "(" . $table . ")", 'info');
282
            if ($this->config['install-drop-tables'] == true) {
283
                if ($db->tableExists($table)) {
284
                    $db->dropTableName($table);
285
                }
286
            }
287
288
            if (!$db->tableExists($table)) {
289
                $fields = isset($rel_data['fields']) ? $rel_data['fields'] : [];
290
                $indices = isset($rel_data['indices']) ? $rel_data['indices'] : [];
291
                $db->createTableParams($table, $fields, $indices);
292
            }
293
294
            \SugarBean::createRelationshipMeta($rel_name, $db, $table, $dictionary, '');
295
        }
296
297
298
        /**
299
         * Create Default Settings
300
         */
301
        $this->log("Creating Default Settings");
302
        InstallUtils::installerHook('pre_createDefaultSettings');
303
        $configOverride = array_merge($configOverride, [
304
            'language' => $current_language,
305
            'sugar_db_version' => $sugar_db_version,
306
        ]);
307
        InstallUtils::loadFixtures($db, $configOverride, 'fixtures/config.yml');
308
        InstallUtils::installerHook('post_createDefaultSettings');
309
310
311
        /**
312
         * Create Administrator User
313
         */
314
        $this->log("Creating Administrator User");
315
        InstallUtils::installerHook('pre_createUsers');
316
        $current_user = InstallUtils::createAdministratorUser($db, $this->config);
317
        InstallUtils::installerHook('post_createUsers');
318
319
320
        /**
321
         * Rebuild Shedulers
322
         */
323
        $this->log("Rebuilding Schedulers");
324
        InstallUtils::installerHook('pre_createDefaultSchedulers');
325
        InstallUtils::loadFixtures($db, $configOverride, 'fixtures/schedulers.yml');
326
        InstallUtils::installerHook('post_createDefaultSchedulers');
327
328
329
        /**
330
         * @todo: check this - setup_installed_lang_packs in $config is not set anywhere
331
         * Update upgrade history - language packs
332
         */
333
        if (!empty($this->config['setup_installed_lang_packs'])) {
334
            $this->log("Registering Language Packs");
335
            InstallUtils::registerLanguagePacks($this->config);
336
        }
337
338
        /**
339
         *  Enable Sugar Feeds
340
         */
341
        $this->log("Enabling Sugar Feeds");
342
        InstallUtils::enableSugarFeeds();
343
344
345
        /**
346
         * Handle Sugar Versions - this has disappeared from branch 2016-04-27 - @todo: check and remove
347
         */
348
        //$this->log("Handling Version Info");
349
        //require_once(PROJECT_ROOT . '/modules/Versions/InstallDefaultVersions.php');
350
351
352
        /**
353
         * Advanced Password Seeds
354
         */
355
        $this->log("Handling Advanced Password Configuration");
356
        InstallUtils::registerAdvancedPasswordConfiguration($this->config);
357
358
359
        /**
360
         * Administration Variables
361
         */
362
        $this->log("Handling Administration Variables");
363
        InstallUtils::registerAdministrationVariables($this->config);
364
365
366
        /**
367
         * Setting Default Tabs
368
         */
369
        $this->log("Configuring Default Tabs");
370
        InstallUtils::installerHook('pre_setSystemTabs');
371
        InstallUtils::configureDefaultTabs($this->config);
372
        InstallUtils::installerHook('post_setSystemTabs');
373
374
375
        /**
376
         * SuiteCrm
377
         */
378
        $this->log("Registering SuiteCrm Configuration");
379
        InstallUtils::registerSuiteCrmConfiguration($configOverride);
380
        $this->log("SuiteCrm Extra Installs");
381
        InstallUtils::executeExtraInstallation($this->config);
382
383
384
        /**
385
         * Modules Post Install - ALL DISABLED  - REMOVE ME!
386
         */
387
        $this->log("Executing Modules Post Install");
388
        InstallUtils::modulesPostInstall();
389
390
391
        /**
392
         * Install Demo Data
393
         */
394
        if ($this->config['install-demo-data']) {
395
            $this->log("Installing Demo Data");
396
            InstallUtils::installerHook('pre_installDemoData');
397
            InstallUtils::installDemoData();
398
            InstallUtils::installerHook('post_installDemoData');
399
        }
400
401
        /**
402
         * Save User
403
         *
404
         * Old note: set all of these default parameters since the Users save action
405
         * will undo the defaults otherwise
406
         *
407
         * My note: @todo: this is horrible - extract needed functionality from '/modules/Users/Save.php'
408
         */
409
        $this->log("Updating Admin User");
410
        // set locale settings
411
        $current_user->setPreference('datef', 'Y-m-d');
412
        $current_user->setPreference('timef', 'H:i:s');
413
        $current_user->setPreference('timezone', date_default_timezone_get());
414
        // set some POST data for '/modules/Users/Save.php'
415
        $_POST['dateformat'] = 'Y-m-d';//$sugar_config['default_date_format']
416
        $_POST['timeformat'] = 'H:i:s';//$sugar_config['default_time_format']
417
        $_POST['record'] = $current_user->id;
418
        $_POST['is_admin'] = 'on';
419
        $_POST['use_real_names'] = TRUE;
420
        $_POST['reminder_checked'] = '0';
421
        $_POST['email_reminder_checked'] = '0';
422
        $_POST['reminder_time'] = 1800;
423
        $_POST['email_reminder_time'] = 3600;
424
        $_POST['mailmerge_on'] = 'on';
425
        $_POST['receive_notifications'] = $current_user->receive_notifications;
426
        $_POST['user_theme'] = (string) \SugarThemeRegistry::getDefault();
427
        require(PROJECT_ROOT . '/modules/Users/Save.php');
428
429
430
        /**
431
         * Post Install Modules Hook
432
         */
433
        $this->log("Calling Post-Install Modules Hook");
434
        InstallUtils::installerHook('post_installModules');
435
436
437
        //BAN ALL MODULES BY DEFAULT: ['addAjaxBannedModules'][] = '';
438
439
440
        /**
441
         * DONE
442
         */
443
        $endTime = microtime(TRUE);
444
        $deltaTime = $endTime - $startTime;
445
        $this->log(str_repeat("-", 80));
446
        $this->log("Installation complete(" . floor($deltaTime) . "s).");
447
    }
448
449
    /**
450
     * Setup Session variables prior to executing installation
451
     */
452
    protected function setupSugarSessionVars()
453
    {
454
        if ((function_exists('session_status') && session_status() == PHP_SESSION_NONE) || session_id() == '') {
455
            session_start();
456
        }
457
    }
458
459
    /**
460
     * Setup Globals prior to requiring Sugar application files
461
     */
462
    protected function setupSugarGlobals()
463
    {
464
        $GLOBALS['installing'] = TRUE;
465
        define('SUGARCRM_IS_INSTALLING', $GLOBALS['installing']);
466
    }
467
468
    /**
469
     * Mostly for avoiding undefined index notices
470
     */
471
    protected function setupSugarServerValues()
472
    {
473
        $_SERVER['SERVER_SOFTWARE'] = isset($this->config['server-software']) ? $this->config['server-software'] : null;
474
    }
475
476
    /**
477
     * Set up our own LoggerManager for the installation
478
     */
479
    protected function setupSugarLogger()
480
    {
481
        $GLOBALS['log'] = $this->loggerManager;
482
    }
483
484
    /**
485
     * Set Php options
486
     */
487
    protected function setPhpOptions()
488
    {
489
        error_reporting(E_ALL);
490
        ini_set('display_errors', 1);
491
        ini_set("output_buffering", "0");
492
493
        // http://us3.php.net/manual/en/ref.pcre.php#ini.pcre.backtrack-limit
494
        // starting with 5.2.0, backtrack_limit breaks JSON decoding
495
        $backtrack_limit = ini_get('pcre.backtrack_limit');
496
        if (!empty($backtrack_limit)) {
497
            ini_set('pcre.backtrack_limit', '-1');
498
        }
499
    }
500
501
    /**
502
     * @param string $msg
503
     * @param string $level - available: debug|info|warn|deprecated|error|fatal|security|off
504
     */
505
    public function log($msg, $level = 'warn')
506
    {
507
        $this->loggerManager->log($msg, $level);
508
    }
509
}