Controller::startAppSession()   B
last analyzed

Complexity

Conditions 7
Paths 9

Size

Total Lines 41
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 28
nc 9
nop 0
dl 0
loc 41
rs 8.5386
c 0
b 0
f 0
1
<?php
2
    defined('ROOT_PATH') || exit('Access denied');
3
    /**
4
     * TNH Framework
5
     *
6
     * A simple PHP framework using HMVC architecture
7
     *
8
     * This content is released under the MIT License (MIT)
9
     *
10
     * Copyright (c) 2017 TNH Framework
11
     *
12
     * Permission is hereby granted, free of charge, to any person obtaining a copy
13
     * of this software and associated documentation files (the "Software"), to deal
14
     * in the Software without restriction, including without limitation the rights
15
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
     * copies of the Software, and to permit persons to whom the Software is
17
     * furnished to do so, subject to the following conditions:
18
     *
19
     * The above copyright notice and this permission notice shall be included in all
20
     * copies or substantial portions of the Software.
21
     *
22
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
     * SOFTWARE.
29
     */
30
31
    class Controller extends BaseClass {
32
		
33
        /**
34
         * The name of the module if this controller belong to an module
35
         * @var string
36
         */
37
        public $moduleName = null;
38
39
        /**
40
         * The singleton of the super object
41
         * @var Controller
42
         */
43
        private static $instance;
44
45
46
        /**
47
         * Class constructor
48
         */
49
        public function __construct() {
50
            parent::__construct();
51
			
52
            //instance of the super object
53
            self::$instance = & $this;
54
55
            //Load the resources loaded during the application bootstrap
56
            $this->logger->debug('Adding the loaded classes to the super instance');
57
            foreach (class_loaded() as $var => $class) {
58
                $this->$var = & class_loader($class);
59
            }
60
61
            //set the cache instance using the configuration
62
            $this->setCacheIfEnabled();
63
			
64
            //set module using the router
65
            $this->setModuleNameFromRouter();
66
67
            //load the required resources
68
            $this->loadRequiredResources();
69
70
            //set application supported languages
71
            $this->setAppSupportedLanguages();
72
			
73
            //set application session configuration and then started it
74
            $this->logger->debug('Starting application session handler');
75
            $this->startAppSession();
76
77
            //dispatch the loaded instance of super controller event
78
            $this->eventdispatcher->dispatch('SUPER_CONTROLLER_CREATED');
79
        }
80
81
82
        /**
83
         * This is a very useful method it's used to get the super object instance
84
         * @return object the super object instance
85
         */
86
        public static function &getInstance(){
87
            return self::$instance;
88
        }
89
90
        /**
91
         * This method is used to set the session configuration
92
         * using the configured value and start the session if not yet started
93
         *
94
         * @codeCoverageIgnore
95
         */
96
         private function startAppSession() {
97
            //$_SESSION is not available on cli mode 
98
            if (!IS_CLI) {
99
                //set session params
100
                $sessionName = $this->config->get('session_name');
101
                $this->logger->info('Session name: ' . $sessionName);
102
                if ($sessionName) {
103
                    session_name($sessionName);
104
                }
105
106
                //Set app session handler configuration
107
                $this->setAppSessionConfig();
108
109
                $lifetime = $this->config->get('session_cookie_lifetime', 0);
110
                $path = $this->config->get('session_cookie_path', '/');
111
                $domain = $this->config->get('session_cookie_domain', '');
112
                $secure = $this->config->get('session_cookie_secure', false);
113
                if (is_https()) {
114
                    $secure = true;
115
                }
116
                session_set_cookie_params(
117
                    $lifetime,
118
                    $path,
119
                    $domain,
120
                    $secure,
121
                    $httponly = true /*for security for access to cookie via javascript or XSS attack*/
122
                );
123
                //to prevent attack of Session Fixation 
124
                //thank to https://www.phparch.com/2018/01/php-sessions-in-depth/
125
                ini_set('session.use_strict_mode ', 1);
126
                ini_set('session.use_only_cookies', 1);
127
                ini_set('session.use_trans_sid ', 0);
128
                
129
                $this->logger->info('Session cookie lifetime: ' . $lifetime);
130
                $this->logger->info('Session cookie path: ' . $path);
131
                $this->logger->info('Session cookie domain: ' . $domain);
132
                $this->logger->info('Session is secure: ' . ($secure ? 'TRUE' : 'FALSE'));
133
                
134
                if ((session_status() !== PHP_SESSION_ACTIVE) || !session_id()) {
135
                    $this->logger->info('Session not yet started, start it now');
136
                    session_start();
137
                }
138
            }
139
        }
140
141
        /**
142
         * Set the session handler configuration
143
         * @codeCoverageIgnore
144
         */
145
        private function setAppSessionConfig() {
146
             //the default is to store in the files
147
            $sessionHandler = $this->config->get('session_handler', 'files');
148
            $this->logger->info('Session handler: ' . $sessionHandler);
149
            if ($sessionHandler == 'files') {
150
                $sessionSavePath = $this->config->get('session_save_path');
151
                if ($sessionSavePath) {
152
                    if (!is_dir($sessionSavePath)) {
153
                        mkdir($sessionSavePath, 1773);
154
                    }
155
                    $this->logger->info('Session save path: ' . $sessionSavePath);
156
                    session_save_path($sessionSavePath);
157
                }
158
            } else if ($sessionHandler == 'database') {
159
                //load database session handle library
160
                //Database Session handler Model
161
                require_once CORE_CLASSES_MODEL_PATH . 'DBSessionHandlerModel.php';
162
                $dbSessionHandler = & class_loader('DBSessionHandler', 'classes');
163
                session_set_save_handler($dbSessionHandler, true);
164
                $this->logger->info('Session database handler model: ' . $this->config->get('session_save_path'));
165
            } else {
166
                show_error('Invalid session handler configuration');
167
            }
168
        }
169
170
        /**
171
         * This method is used to set the module name
172
         */
173
        private function setModuleNameFromRouter() {
174
            //set the module using the router instance
175
            if (isset($this->router) && $this->router->getModule()) {
176
                $this->moduleName = $this->router->getModule();
177
            }
178
        }
179
180
        /**
181
         * Set the cache instance if is enabled in the configuration
182
         */
183
        private function setCacheIfEnabled() {
184
            $this->logger->debug('Setting the cache handler instance');
185
            //set cache handler instance
186
            if ($this->config->get('cache_enable', false)) {
187
                $cache = strtolower($this->config->get('cache_handler'));
188
                if (property_exists($this, $cache)) {
189
                    $this->cache = $this->{$cache};
0 ignored issues
show
Bug Best Practice introduced by
The property cache does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
190
                    unset($this->{$cache});
191
                } 
192
            }
193
        }
194
195
196
        /**
197
         * This method is used to load the required resources for framework to work
198
         * @return void 
199
         */
200
        private function loadRequiredResources() {
201
            $this->logger->debug('Loading the required classes into super instance');
202
            $this->eventdispatcher = & class_loader('EventDispatcher', 'classes');
0 ignored issues
show
Bug Best Practice introduced by
The property eventdispatcher does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
203
            $this->loader = & class_loader('Loader', 'classes');
204
            $this->lang = & class_loader('Lang', 'classes');
205
            $this->request = & class_loader('Request', 'classes');
206
            //dispatch the request instance created event
207
            $this->eventdispatcher->dispatch('REQUEST_CREATED');
208
            $this->session = & class_loader('Session', 'classes');
209
            $this->response = & class_loader('Response', 'classes');
210
        }
211
212
        /**
213
         * Set the application supported languages
214
         */
215
        private function setAppSupportedLanguages() {
216
            //add the supported languages ('key', 'display name')
217
            $languages = $this->config->get('languages', array());
218
            foreach ($languages as $key => $displayName) {
219
                $this->lang->addLang($key, $displayName);
220
            }
221
            unset($languages);
222
        }
223
224
    }
225