1<?php
2
3/**
4 * OrangeHRM is a comprehensive Human Resource Management (HRM) System that captures
5 * all the essential functionalities required for any enterprise.
6 * Copyright (C) 2006 OrangeHRM Inc., http://www.orangehrm.com
7 *
8 * OrangeHRM is free software; you can redistribute it and/or modify it under the terms of
9 * the GNU General Public License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * OrangeHRM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with this program;
17 * if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA  02110-1301, USA
19 *
20 */
21
22
23/**
24 *Related class to web installer.
25 *This class will validate server configurations.
26 */
27class BasicConfigurations{
28
29private $interuptContinue;
30function __construct()
31{
32  require_once(ROOT_PATH . '/installer/environmentCheck/SystemValidator.php');
33  $this->interuptContinue = false;
34  $this->systemValidator = new SystemValidator();
35}
36
37function getMessages(){
38    if (!isset($messageList)) {
39        $messageList = new Messages();
40    }
41    return $messageList;
42}
43
44/**
45 * This class will validate server configurations.
46 * If any thing not suitable return true from variable '$interuptContinue'
47 * '$interuptContinue' is variable. Its true means error found and interupt continue to next level.
48 * If it is false then not interupt and continue installation.
49 * If error found set '$interuptContinue' as "TRUE".
50 */
51public function isFailBasicConfigurations(){
52
53
54	//01 important to check. If false interupt
55	$this->IsPHPVersionCompatible();
56	//02 important to check. If false interupt
57	$this->IsMySqlClientCompatible();
58	//03 important to check. If false interupt
59	$this->IsMySqlServerCompatible();
60	//04 important to check. If false interupt
61	$this->IsInnoDBSupport();
62	//05 important to check. If false interupt
63	$this->IsWritableLibConfs();
64
65	//06-function
66	$this->IsWritableSymfonyConfig();
67	//07-function
68	$this->IsWritableSymfonyCache();
69	//08-function
70	$this->IsWritableSymfonyLog();
71	//09-function
72	$this->IsMaximumSessionIdle();
73	//10-function
74	$this->IsRegisterGlobalsOff();
75
76	//11 Display messages with case statement filter.
77	$this->checkMemory();
78
79	//12-function
80	$this->IsGgExtensionEnable();
81
82	if($this->isApacheServer()) {
83	    //17- function
84	    $this->IsApacheExpiresModule();
85	    //18- function
86	    $this->IsApacheHeadersModule();
87	    //19 - function
88	    $this->IsEnableRewriteMod();
89	}
90
91	//20 - function
92//	$this->MySQLEventStatus(); // removed my sql status check because it is not needed for OS
93
94	//21 -function
95	$this->isCurlEnabled();
96
97	//22 -function
98	$this->isSimpleXMLEnabled();
99
100	$this->getMessages()->displayMessage(Messages::SEPERATOR);
101	$this->dbConfigurationCheck();
102	$this->getMessages()->displayMessage(Messages::SEPERATOR);
103
104	return $this->interuptContinue;
105}
106
107//01-function
108function IsPHPVersionCompatible() {
109               if (version_compare(PHP_VERSION, Messages::PHP_MIN_VERSION) < 0) {
110                   $this->interuptContinue = true;
111		   $this->getMessages()->displayMessage(Messages::PHP_FAIL_MESSAGE." Installed version is ".PHP_VERSION);
112               } else {
113		   $this->getMessages()->displayMessage(Messages::PHP_OK_MESSAGE." (ver ".PHP_VERSION.")");
114	       }
115}
116
117//02-function
118function IsMySqlClientCompatible() {
119
120                if(function_exists('mysqli_get_client_info')) {
121            $mysqlClient = mysqli_get_client_info();
122                    $versionPattern = '/[0-9]+\.[0-9]+\.[0-9]+/';
123
124                    preg_match($versionPattern, $mysqlClient, $matches);
125                    $mysql_client_version = $matches[0];
126
127                    if (version_compare($mysql_client_version, Messages::MYSQL_MIN_VERSION) < 0) {
128		       $this->getMessages()->displayMessage(Messages::MYSQL_CLIENT_RECOMMEND_MESSAGE."(reported ver ".$mysqlClient.")");
129                    } else
130		       $this->getMessages()->displayMessage(Messages::MYSQL_CLIENT_OK_MESSAGE);
131                } else {
132		    $this->getMessages()->displayMessage(Messages::MYSQL_CLIENT_FAIL_MESSAGE);
133                    $this->interuptContinue = true;
134                }
135
136       }
137//03-function
138function IsMySqlServerCompatible() {
139        $conn = $this->getConnection($_SESSION['dbInfo']);
140        if ($conn) {
141            $mysqlServer = mysqli_get_server_info($conn);
142
143            if (version_compare($mysqlServer, "5.1.6") >= 0) {
144                $this->getMessages()->displayMessage(Messages::MYSQL_SERVER_OK_MESSAGE . " ($mysqlServer)");
145            } else {
146                $this->getMessages()->displayMessage(Messages::MYSQL_SERVER_RECOMMEND_MESSAGE . " (reported ver " . $mysqlServer . ")");
147            }
148        } else {
149            $this->getMessages()->displayMessage(Messages::MYSQL_SERVER_FAIL_MESSAGE);
150            $this->interuptContinue = true;
151        }
152
153}
154
155//04-function
156function IsInnoDBSupport() {
157               $conn = $this->getConnection($_SESSION['dbInfo']);
158
159               if ($conn) {
160		            $mysqlServer = mysqli_query($conn, "show engines");
161
162
163		            while ($engines = mysqli_fetch_assoc($mysqlServer)) {
164		                if ($engines['Engine'] == 'InnoDB') {
165		                    if ($engines['Support'] == 'DISABLED') {
166		                        $this->getMessages()->displayMessage("MySQL InnoDB Support - Disabled!");
167					$this->interuptContinue = true;
168		                    } elseif ($engines['Support'] == 'DEFAULT') {
169		                        $this->getMessages()->displayMessage("MySQL InnoDB Support - Default");
170		                    } elseif ($engines['Support'] == 'YES') {
171		                        $this->getMessages()->displayMessage("MySQL InnoDB Support - Enabled");
172		                    } elseif ($engines['Support'] == 'NO') {
173		                        $this->getMessages()->displayMessage("MySQL InnoDB Support - available!");
174					$this->interuptContinue = true;
175		                    } else {
176		                        $this->getMessages()->displayMessage("MySQL InnoDB Support - Unknown Error!");
177					$this->interuptContinue = true;
178		                    }
179		                }
180		            }
181
182               } else {
183                 $this->getMessages()->displayMessage("MySQL InnoDB Support - Cannot connect to the database");
184                 $this->interuptContinue = true;
185               }
186            }
187//05-function
188function IsWritableLibConfs() {
189               if(is_writable(ROOT_PATH . '/lib/confs')) {
190		   $this->getMessages()->displayMessage(Messages::WritableLibConfs_OK_MESSAGE);
191				} else {
192		  $this->getMessages()->displayMessage(Messages::WritableLibConfs_FAIL_MESSAGE);
193                  $this->interuptContinue = true;
194               }
195           }
196//06-function
197function IsWritableSymfonyConfig(){
198               if(is_writable(ROOT_PATH . '/symfony/config')) {
199                  $this->getMessages()->displayMessage(Messages::WritableSymfonyConfig_OK_MESSAGE);
200				} else {
201                  $this->getMessages()->displayMessage(Messages::WritableSymfonyConfig_FAIL_MESSAGE);
202                  $this->interuptContinue = true;
203               }
204         }
205//07-function
206function IsWritableSymfonyCache(){
207               if(is_writable(ROOT_PATH . '/symfony/cache')) {
208		  $this->getMessages()->displayMessage(Messages::WritableSymfonyCache_OK_MESSAGE);
209				} else {
210		  $this->getMessages()->displayMessage(Messages::WritableSymfonyCache_FAIL_MESSAGE);
211                  $this->interuptContinue = true;
212               }
213           }
214//08-function
215 function IsWritableSymfonyLog(){
216               if(is_writable(ROOT_PATH . '/symfony/log')) {
217		  $this->getMessages()->displayMessage(Messages::WritableSymfonyLog_OK_MESSAGE);
218		  }
219	       else{
220                  $this->getMessages()->displayMessage(Messages::WritableSymfonyLog_FAIL_MESSAGE);
221                  $this->interuptContinue = true;
222               }
223            }
224
225//09-function
226 function IsMaximumSessionIdle(){
227	       $gc_maxlifetime_min = floor(ini_get("session.gc_maxlifetime")/60);
228	       $gc_maxlifetime_sec = ini_get(" session.gc_maxlifetime") % 60;
229	       $time_span = "($gc_maxlifetime_min minutes and $gc_maxlifetime_sec seconds)";
230               if ($gc_maxlifetime_min > 15) {
231                  $this->getMessages()->displayMessage(Messages::MaximumSessionIdle_OK_MESSAGE.$time_span);
232	       } else if ($gc_maxlifetime_min > 2){
233		  $this->getMessages()->displayMessage(Messages::MaximumSessionIdle_SHORT_MESSAGE.$time_span);
234	       } else {
235                  $this->getMessages()->displayMessage(Messages::MaximumSessionIdle_TOO_SHORT_MESSAGE.$time_span);
236                  $this->interuptContinue = true;
237               }
238            }
239
240//10-function
241 function IsRegisterGlobalsOff(){
242	       echo "Register Globals turned-off -";
243	       $registerGlobalsValue = (bool) ini_get("register_globals");
244               if ($registerGlobalsValue) {
245                  $this->getMessages()->displayMessage(Messages::RegisterGlobalsOff_FAIL_MESSAGE);
246		  $this->interuptContinue = true;
247	       } else {
248		  $this->getMessages()->displayMessage(Messages::RegisterGlobalsOff_OK_MESSAGE);
249               }
250            }
251
252//11 - function
253function checkMemory() {
254    $limit = 9;
255    $recommended = 16;
256    $maxMemory = null;
257
258    $status = '';
259
260    $result = checkPHPMemory($limit, $recommended, $maxMemory);
261
262	switch ($result) {
263		case INSTALLUTIL_MEMORY_NO_LIMIT:
264			$status = "OK (No Limit)";
265			break;
266
267		case INSTALLUTIL_MEMORY_UNLIMITED:
268			$status = "OK (Unlimited)";
269			break;
270
271		case INSTALLUTIL_MEMORY_HARD_LIMIT_FAIL:
272			$status = "Warning at least ${limit}M required (${maxMemory} available, Recommended ${recommended}M)";
273			$this->interuptContinue = true;
274			break;
275
276		case INSTALLUTIL_MEMORY_SOFT_LIMIT_FAIL:
277			$status= "OK (Recommended ${recommended}M)";
278			break;
279
280		case INSTALLUTIL_MEMORY_OK:
281			$status = "OK";
282			break;
283	}
284
285	$this->getMessages()->displayMessage("Memory allocated for PHP script - ".$status);
286}
287
288//12-function
289 function IsGgExtensionEnable(){
290            if (extension_loaded('gd') && function_exists('gd_info')) {
291		   $this->getMessages()->displayMessage(Messages::GgExtensionEnable_OK_MESSAGE);
292           } else  {
293		   $this->getMessages()->displayMessage(Messages::GgExtensionEnable_FAIL_MESSAGE);
294                   $this->interuptContinue = true;
295           }
296}
297//13- function
298 function IsPHPExifEnable(){
299            if (function_exists('exif_read_data')) {
300                    $this->getMessages()->displayMessage(Messages::PHPExifEnable_OK_MESSAGE);
301            } else  {
302		    $this->getMessages()->displayMessage(Messages::PHPExifEnable_FAIL_MESSAGE);
303		    $this->interuptContinue = true;
304            }
305}
306
307//14- function
308  function IsPHPAPCEnable(){
309            if (extension_loaded('apc') && ini_get('apc.enabled')) {
310                   $this->getMessages()->displayMessage(Messages::PHPAPCEnable_OK_MESSAGE);
311             } else  {
312           	   $this->getMessages()->displayMessage(Messages::PHPAPCEnable_FAIL_MESSAGE);
313           }
314}
315
316//16- function - execute in IsApacheExpiresModule().
317  function getAppacheModules(){
318          if (function_exists('apache_get_modules')) {
319              $apacheModules = apache_get_modules();
320		return $apacheModules;
321          }
322
323  }
324
325
326//17- function
327 function IsApacheExpiresModule(){
328     $apacheModules = $this->getAppacheModules();
329
330     if (empty($apacheModules)) {
331         $this->getMessages()->displayMessage(Messages::ApacheExpiresModule_UNABLE_MESSAGE);
332     } else if (in_array('mod_expires', $apacheModules)) {
333         $this->getMessages()->displayMessage(Messages::ApacheExpiresModule_OK_MESSAGE);
334     } else  {
335         $this->getMessages()->displayMessage(Messages::ApacheExpiresModule_DISABLE_MESSAGE);
336     }
337
338
339}
340
341//18- function
342 function IsApacheHeadersModule(){
343     if (empty($apacheModules)) {
344         $this->getMessages()->displayMessage(Messages::ApacheHeadersModule_UNABLE_MESSAGE);
345     } else if (in_array('mod_headers', $apacheModules)) {
346         $this->getMessages()->displayMessage(Messages::ApacheHeadersModule_ENABLE_MESSAGE);
347     } else{
348         $this->getMessages()->displayMessage(Messages::ApacheHeadersModule_DISABLE_MESSAGE);
349     }
350}
351
352//19 - function
353function IsEnableRewriteMod(){
354    if (empty($apacheModules)) {
355        $this->getMessages()->displayMessage(Messages::EnableRewriteMod_UNABLE_MESSAGE);
356    } else if (in_array('mod_rewrite', $apacheModules)) {
357        $this->getMessages()->displayMessage(Messages::EnableRewriteMod_OK_MESSAGE);
358    } else  {
359        $this->interuptContinue = true;
360        $this->getMessages()->displayMessage(Messages::EnableRewriteMod_DISABLE_MESSAGE);
361    }
362}
363
364//20 - function
365function MySQLEventStatus(){
366        $conn = $this->getConnection($_SESSION['dbInfo']);
367        if ($conn) {
368            $result = mysqli_query($conn, "SHOW VARIABLES LIKE 'EVENT_SCHEDULER'");
369            $row = mysqli_fetch_assoc($result);
370                    $schedulerStatus = $row['Value'];
371
372                    if ($schedulerStatus == 'ON') {
373			$this->getMessages()->displayMessage(Messages::MySQLEventStatus_OK_MESSAGE);
374                    } else {
375			$this->getMessages()->displayMessage(Messages::MySQLEventStatus_DISABLE_MESSAGE);
376                    }
377
378               } else {
379		    $this->getMessages()->displayMessage(Messages::MySQLEventStatus_FAIL_MESSAGE);
380		    $this->interuptContinue = true;
381               }
382
383 }
384
385 //21 - function
386function isCurlEnabled() {
387    if (extension_loaded('curl')) {
388        $this->getMessages()->displayMessage(Messages::CURLStatus_OK_MESSAGE);
389    } else {
390        $this->getMessages()->displayMessage(Messages::CURLStatus_DISABLE_MESSAGE);
391        $this->interuptContinue = true;
392    }
393}
394
395    //22 - function
396    function isSimpleXMLEnabled() {
397        if (extension_loaded('SimpleXML') && extension_loaded('libxml') && extension_loaded('xml')) {
398            $this->getMessages()->displayMessage(Messages::SimpleXMLStatus_OK_MESSAGE);
399        } else {
400            $this->getMessages()->displayMessage(Messages::SimpleXMLStatus_DISABLE_MESSAGE);
401            $this->interuptContinue = true;
402        }
403    }
404
405    /**
406     * Check script execute in apache server
407     * @return bool
408     */
409 private function isApacheServer() {
410    $isApache = false;
411    $sapiName = php_sapi_name();
412    switch ($sapiName) {
413        case 'apache':
414        case 'apache2filter':
415        case 'apache2handler':
416            $isApache = true;
417        break;
418    }
419    return $isApache;
420 }
421
422/*
423 *check Database connection and validation parts.
424 *details compare with config.ini file or user inputs.
425 *$_SESSION['dbInfo'] set this variable in DetailsHandler.php file , DetailsHandler class->setConfigurationFromParameter()
426 */
427function dbConfigurationCheck()
428{
429
430	 $dbInfo = $_SESSION['dbInfo'];
431        $conn = $this->getConnection($dbInfo);
432        if ($conn) {
433                if (!($this->systemValidator->isMySqlCompatible($dbInfo['dbHostName'], $dbInfo['dbUserName'], $dbInfo['dbPassword'], $dbInfo['dbHostPort']))){
434                    $_SESSION['dbError'] = $this->systemValidator->getMysqlErrorMessage($dbInfo['dbHostName'], $dbInfo['dbUserName'], $dbInfo['dbPassword'], $dbInfo['dbHostPort']);
435		}
436
437                elseif ($_SESSION['dbCreateMethod'] == 'new' && mysqli_select_db($conn, $dbInfo['dbName'])){
438                    $_SESSION['dbError'] = "Database (" . $_SESSION['dbInfo']['dbName'] . ") already exists";
439		    $this->interuptContinue = true;
440                    }
441                elseif ($_SESSION['dbCreateMethod'] == 'new' && !isset($_SESSION['chkSameUser'])) {
442			mysqli_select_db($conn, 'mysql');
443	                $rset = mysqli_query($conn, "SELECT USER FROM user WHERE USER = '" . $dbInfo['dbOHRMUserName'] . "'");
444
445                    if (mysqli_num_rows($rset) > 0){
446                        $_SESSION['dbError'] = 'OrangehrmDatabase User name already exists';
447			$this->interuptContinue = true;
448		    }
449                }
450            } else
451                $_SESSION['dbError'] = Messages::DB_WRONG_INFO;
452
453	 if(isset($_SESSION['dbError']))
454	 {
455		$this->getMessages()->displayMessage($_SESSION['dbError']);
456		$this->interuptContinue = true;
457	 }else
458	 {
459		 $this->getMessages()->displayMessage(Messages::DB_CONFIG_SUCCESS);
460	 }
461   }
462
463    /**
464     * @param $dbInfo
465     * @return bool|mysqli
466     */
467    private function getConnection($dbInfo)
468    {
469        $conn = false;
470
471        if (function_exists('mysqli_connect')) {
472
473            $conn = mysqli_connect(
474                $dbInfo['dbHostName'],
475                $dbInfo['dbUserName'],
476                $dbInfo['dbPassword'],
477                null,
478                $dbInfo['dbHostPort']
479            );
480
481            if (mysqli_connect_error()) {
482                print_r($dbInfo);
483            } else {
484                $conn->set_charset("utf8mb4");
485            }
486        }
487
488        return $conn;
489    }
490}
491
492
493