Account Suspended
Account Suspended
This Account has been suspended.
Contact your hosting provider for more information.
 All Data Structures Functions Variables Pages
InstallUtil.php
1 <?php
2  /*********************************************************************************
3  * Zurmo is a customer relationship management program developed by
4  * Zurmo, Inc. Copyright (C) 2017 Zurmo Inc.
5  *
6  * Zurmo is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  *
13  * Zurmo is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  *
23  * You can contact Zurmo, Inc. with a mailing address at 27 North Wacker Drive
24  * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.
25  *
26  * The interactive user interfaces in original and modified versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  *
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the Zurmo
32  * logo and Zurmo copyright notice. If the display of the logo is not reasonably
33  * feasible for technical reasons, the Appropriate Legal Notices must display the words
34  * "Copyright Zurmo Inc. 2017. All rights reserved".
35  ********************************************************************************/
36 
43  {
44  public static function getSupportedDatabaseTypes()
45  {
46  return array('mysql');
47  }
48 
50  // Methods that only check things. They don't change anything.
51  // The aim is that when everything that can be checked passes
52  // its checks, the subsequent methods that modify things should
53  // be expected to succeed.
54 
55  public static function canAssertionsBeEnabledAtRuntime()
56  {
57  $assertionsEnabled = ini_get('zend.assertions');
58  if ($assertionsEnabled == -1)
59  {
60  return false;
61  }
62  return true;
63  }
64 
69  public static function checkWebServer(array $minimumRequiredVersions, /* out */ &$actualVersion)
70  {
71  $matches = array();
72  $serverName = $_SERVER['SERVER_SOFTWARE'];
73  if (strrpos($serverName, 'Microsoft-IIS') !== false && strrpos($serverName, 'Microsoft-IIS') >= 0)
74  {
75  if (preg_match('/([^\/]+)\/(\d+\.\d)?/', $_SERVER['SERVER_SOFTWARE'], $matches)) // Not Coding Standard
76  {
77  $serverName = strtolower($matches[1]);
78  $actualVersion = $matches[2];
79  if (array_key_exists($serverName, $minimumRequiredVersions))
80  {
81  return static::checkVersion($minimumRequiredVersions[$serverName], $actualVersion);
82  }
83  }
84  }
85  elseif (strrpos($serverName, 'Apache') !== false && strrpos($serverName, 'Apache') >= 0)
86  {
87  if (preg_match('/([^\/]+)\/(\d+\.\d+(.\d+))?/', $_SERVER['SERVER_SOFTWARE'], $matches)) // Not Coding Standard
88  {
89  $serverName = strtolower($matches[1]);
90  $actualVersion = $matches[2];
91  if (array_key_exists($serverName, $minimumRequiredVersions))
92  {
93  return static::checkVersion($minimumRequiredVersions[$serverName], $actualVersion);
94  }
95  }
96  }
97  return false;
98  }
99 
103  public static function checkApacheModDeflate()
104  {
105  }
106 
110  public static function checkPhp($minimumRequiredVersion, /* out */ &$actualVersion)
111  {
112  $actualVersion = PHP_VERSION;
113  return static::checkVersion($minimumRequiredVersion, $actualVersion);
114  }
115 
119  public static function checkPhpTimezoneSetting()
120  {
121  $timezone = ini_get('date.timezone');
122  return !empty($timezone);
123  }
124 
125  public static function isMysqliInstalled()
126  {
127  return extension_loaded("mysqli");
128  }
129 
130  public static function isPdoInstalled()
131  {
132  return extension_loaded("pdo");
133  }
134 
135  public static function isPdoMysqlInstalled()
136  {
137  return extension_loaded("pdo_mysql");
138  }
139 
140  public static function isLdapInstalled()
141  {
142  return extension_loaded("ldap");
143  }
144 
145  public static function isMbStringInstalled()
146  {
147  return function_exists('mb_strlen');
148  }
149 
150  public static function isMcryptInstalled()
151  {
152  return extension_loaded('mcrypt');
153  }
154 
158  public static function checkPhpMaxMemorySetting($minimumMemoryRequireBytes, /* out */ & $actualMemoryLimitBytes)
159  {
160  $memoryLimit = ini_get('memory_limit');
161  $actualMemoryLimitBytes = static::getBytes($memoryLimit);
162  return $minimumMemoryRequireBytes <= $actualMemoryLimitBytes;
163  }
164 
168  public static function checkPhpUploadSizeSetting($minimumUploadRequireBytes, /* out */ & $actualUploadLimitBytes)
169  {
170  $maxFileSize = ini_get('upload_max_filesize');
171  $actualUploadLimitBytes = static::getBytes($maxFileSize);
172  return $minimumUploadRequireBytes <= $actualUploadLimitBytes;
173  }
174 
178  public static function checkPhpPostSizeSetting($minimumPostRequireBytes, /* out */ & $actualPostLimitBytes)
179  {
180  $maxPostSize = ini_get('post_max_size');
181  $actualPostLimitBytes = static::getBytes($maxPostSize);
182  return $minimumPostRequireBytes <= $actualPostLimitBytes;
183  }
184 
188  public static function isFileUploadsOn()
189  {
190  $value = ini_get('file_uploads');
191  if ($value)
192  {
193  return true;
194  }
195  return false;
196  }
197 
198  protected static function getBytes($size)
199  {
200  if (preg_match('/\d+[G|M|K]/i', $size)) // Not Coding Standard
201  {
202  switch (strtoupper(substr(trim($size), -1)))
203  {
204  case 'G':
205  return (int)$size * 1024 * 1024 * 1024;
206 
207  case 'M':
208  return (int)$size * 1024 * 1024;
209 
210  case 'K':
211  return (int)$size * 1024;
212 
213  default:
214  return (int)$size;
215  }
216  }
217  else
218  {
219  return 0;
220  }
221  }
222 
226  public static function checkDatabase($databaseType,
227  $databaseHostname,
228  $databaseUsername,
229  $databasePassword,
230  $databasePort,
231  $minimumRequiredVersion,
232  /* out */ &$actualVersion)
233  {
234  $actualVersion = DatabaseCompatibilityUtil::getDatabaseVersion($databaseType,
235  $databaseHostname,
236  $databaseUsername,
237  $databasePassword,
238  $databasePort);
239  return static::checkVersion($minimumRequiredVersion, $actualVersion);
240  }
241 
245  public static function checkAPC($minimumRequiredVersion, /* out */ &$actualVersion)
246  {
247  $actualVersion = phpversion('apc');
248  if ($actualVersion !== false && $actualVersion !== null)
249  {
250  return static::checkVersion($minimumRequiredVersion, $actualVersion);
251  }
252  return false;
253  }
254 
258  public static function checkSoap()
259  {
260  return extension_loaded("soap");
261  }
262 
267  public static function checkSPL()
268  {
269  return extension_loaded("SPL");
270  }
271 
276  public static function checkPCRE()
277  {
278  return extension_loaded("pcre");
279  }
280 
284  public static function checkCtype()
285  {
286  return extension_loaded("ctype");
287  }
288 
292  public static function checkImap()
293  {
294  return extension_loaded("imap");
295  }
296 
300  public static function checkZip()
301  {
302  return extension_loaded("zip");
303  }
304 
309  public static function checkServerVariable(&$error)
310  {
311  $vars = array('HTTP_HOST', 'SERVER_NAME', 'SERVER_PORT', 'SCRIPT_NAME', 'SCRIPT_FILENAME', 'PHP_SELF', 'HTTP_ACCEPT', 'HTTP_USER_AGENT');
312  $missing = array();
313  foreach ($vars as $var)
314  {
315  if (!isset($_SERVER[$var]))
316  {
317  $missing[] = $var;
318  }
319  }
320  if (!empty($missing))
321  {
322  $error = Zurmo::t('InstallModule', '$_SERVER does not have {vars}.', array('{vars}' => implode(', ', $missing)));
323  return false;
324  }
325 
326  if (!isset($_SERVER["REQUEST_URI"]) && isset($_SERVER["QUERY_STRING"]))
327  {
328  $error = Zurmo::t('InstallModule', 'Either $_SERVER["REQUEST_URI"] or $_SERVER["QUERY_STRING"] must exist.');
329  return false;
330  }
331 
332  if (!isset($_SERVER["PATH_INFO"]) && strpos($_SERVER["PHP_SELF"], $_SERVER["SCRIPT_NAME"]) !== 0)
333  {
334  $error = Zurmo::t('InstallModule', 'Unable to determine URL path info. Please make sure $_SERVER["PATH_INFO"]' .
335  ' (or $_SERVER["PHP_SELF"] and $_SERVER["SCRIPT_NAME"]) contains proper value.');
336  return false;
337  }
338  return true;
339  }
340 
344  public static function checkMemcache($minimumRequiredVersion, /* out */ &$actualVersion)
345  {
346  $actualVersion = phpversion('memcache');
347  if ($actualVersion != false && extension_loaded('memcache'))
348  {
349  return static::checkVersion($minimumRequiredVersion, $actualVersion);
350  }
351  return false;
352  }
353 
357  public static function checkMemcached($minimumRequiredVersion, /* out */ &$actualVersion)
358  {
359  $actualVersion = phpversion('memcached');
360  if ($actualVersion != false && extension_loaded('memcached'))
361  {
362  return static::checkVersion($minimumRequiredVersion, $actualVersion);
363  }
364  return false;
365  }
366 
370  public static function checkCurl($minimumRequiredVersion, /* out */ &$actualVersion)
371  {
372  if (!in_array('curl', get_loaded_extensions()))
373  {
374  return false;
375  }
376  $versionInfo = curl_version();
377  $actualVersion = $versionInfo['version'];
378  if ($actualVersion !== null)
379  {
380  return static::checkVersion($minimumRequiredVersion, $actualVersion);
381  }
382  return false;
383  }
384 
385  public static function checkYii($minimumRequiredVersion, /* out */ &$actualVersion)
386  {
387  $actualVersion = Yii::getVersion();
388  if ($actualVersion !== null)
389  {
390  return static::checkVersion($minimumRequiredVersion, $actualVersion);
391  }
392  return false;
393  }
394 
395  public static function checkRedBean($minimumRequiredVersion, /* out */ &$actualVersion)
396  {
397  $actualVersion = ZurmoRedBean::getVersion();
398  if ($actualVersion !== null)
399  {
400  return static::checkVersion($minimumRequiredVersion, $actualVersion);
401  }
402  return false;
403  }
404 
408  public static function checkMemcacheConnection($host, $port)
409  {
410  assert('is_string($host) && $host != ""');
411  assert('is_int ($port) && $port >= 1024');
412  $errorNumber = 0;
413  $errorString = '';
414  $timeout = 2;
415  $connection = @fsockopen($host, $port, $errorNumber, $errorString, $timeout);
416  if ($connection !== false)
417  {
418  fclose($connection);
419  return true;
420  }
421  return array($errorNumber, $errorString);
422  }
423 
427  public static function checkDatabaseMaxAllowedPacketsSize($databaseType,
428  $databaseHostname,
429  $databaseUsername,
430  $databasePassword,
431  $databasePort,
432  $minimumRequireBytes,
433  /* out */ & $actualBytes)
434  {
435  assert('in_array($databaseType, static::getSupportedDatabaseTypes())');
437  $databaseHostname,
438  $databaseUsername,
439  $databasePassword,
440  $databasePort);
441  return $minimumRequireBytes <= $actualBytes;
442  }
443 
447  public static function checkDatabaseMaxSpRecursionDepth($databaseType,
448  $databaseHostname,
449  $databaseUsername,
450  $databasePassword,
451  $databasePort,
452  $minimumRequiredMaxSpRecursionDepth,
453  /* out */ & $maxSpRecursionDepth)
454  {
455  assert('in_array($databaseType, static::getSupportedDatabaseTypes())');
456  $maxSpRecursionDepth = DatabaseCompatibilityUtil::getDatabaseMaxSpRecursionDepth($databaseType,
457  $databaseHostname,
458  $databaseUsername,
459  $databasePassword,
460  $databasePort);
461  return $minimumRequiredMaxSpRecursionDepth <= $maxSpRecursionDepth;
462  }
463 
467  public static function checkDatabaseThreadStackValue($databaseType,
468  $databaseHostname,
469  $databaseUsername,
470  $databasePassword,
471  $databasePort,
472  $minimumRequiredThreadStackValue,
473  /* out */ & $threadStackValue)
474  {
475  assert('in_array($databaseType, static::getSupportedDatabaseTypes())');
476  $threadStackValue = DatabaseCompatibilityUtil::getDatabaseThreadStackValue($databaseType,
477  $databaseHostname,
478  $databaseUsername,
479  $databasePassword,
480  $databasePort);
481  return $minimumRequiredThreadStackValue <= $threadStackValue;
482  }
483 
487  public static function checkDatabaseOptimizerSearchDepthValue($databaseType,
488  $databaseHostname,
489  $databaseUsername,
490  $databasePassword,
491  $databasePort,
492  /* out */ & $optimizerSearchDepth)
493  {
494  assert('in_array($databaseType, static::getSupportedDatabaseTypes())');
495  $optimizerSearchDepth = DatabaseCompatibilityUtil::getDatabaseOptimizerSearchDepthValue($databaseType,
496  $databaseHostname,
497  $databaseUsername,
498  $databasePassword,
499  $databasePort);
500  return $optimizerSearchDepth == 0;
501  }
502 
506  public static function checkDatabaseDefaultCollation($databaseType,
507  $databaseHostname,
508  $databaseName,
509  $databaseUsername,
510  $databasePassword,
511  $databasePort,
512  $notAllowedDatabaseCollations,
513  /* out */ & $databaseDefaultCollation)
514  {
515  assert('in_array($databaseType, static::getSupportedDatabaseTypes())');
516  assert('is_array($notAllowedDatabaseCollations)');
517  $databaseDefaultCollation = DatabaseCompatibilityUtil::getDatabaseDefaultCollation($databaseType,
518  $databaseHostname,
519  $databaseName,
520  $databaseUsername,
521  $databasePassword,
522  $databasePort);
523  return !in_array($databaseDefaultCollation, $notAllowedDatabaseCollations);
524  }
525 
529  public static function checkDatabaseLoadLocalInFile($databaseType,
530  $databaseHostname,
531  $databaseUsername,
532  $databasePassword,
533  $databasePort)
534  {
535  assert('in_array($databaseType, static::getSupportedDatabaseTypes())');
536  $loadLocalInFileValue = DatabaseCompatibilityUtil::getDatabaseSupportsLoadLocalInFile($databaseType,
537  $databaseHostname,
538  $databaseUsername,
539  $databasePassword,
540  $databasePort);
541  if (strtolower($loadLocalInFileValue) == 'on' || $loadLocalInFileValue == '1')
542  {
543  return true;
544  }
545  else
546  {
547  return false;
548  }
549  }
550 
554  public static function checkDatabaseLogBinValue($databaseType,
555  $databaseHostname,
556  $databaseUsername,
557  $databasePassword,
558  $databasePort,
559  /* out */ & $logBinValue)
560  {
561  assert('in_array($databaseType, static::getSupportedDatabaseTypes())');
562  $logBinValue = DatabaseCompatibilityUtil::getDatabaseLogBinValue($databaseType,
563  $databaseHostname,
564  $databaseUsername,
565  $databasePassword,
566  $databasePort);
567  if (strtolower($logBinValue) == 'on' || $logBinValue == '1')
568  {
569  return false;
570  }
571  else
572  {
573  return true;
574  }
575  }
576 
581  public static function checkDatabaseLogBinTrustFunctionCreatorsValue($databaseType,
582  $databaseHostname,
583  $databaseUsername,
584  $databasePassword,
585  $databasePort,
586  /* out */ & $logBinTrustFunctionCreatorsValue)
587  {
588  assert('in_array($databaseType, static::getSupportedDatabaseTypes())');
590  $databaseType,
591  $databaseHostname,
592  $databaseUsername,
593  $databasePassword,
594  $databasePort);
595  if (strtolower($logBinTrustFunctionCreatorsValue) == 'on' || $logBinTrustFunctionCreatorsValue == '1')
596  {
597  return true;
598  }
599  else
600  {
601  return false;
602  }
603  }
604 
608  public static function connectToDatabase($databaseType, $host, $databaseName, $username, $password, $port)
609  {
610  assert('in_array($databaseType, static::getSupportedDatabaseTypes())');
611  assert('is_string($host) && $host != ""');
612  assert('is_string($databaseName) && $databaseName != ""');
613  assert('is_string($username) && $username != ""');
614  assert('is_string($password)');
615  $connectionString = "$databaseType:host=$host;port=$port;dbname=$databaseName"; // Not Coding Standard
616  RedBeanDatabase::setup($connectionString, $username, $password);
617  }
618 
622  public static function createSuperUser($username, $password)
623  {
624  $user = new User();
625  $user->username = $username;
626  $user->firstName = 'Super';
627  $user->lastName = 'User';
628  $user->setPassword($password);
629  $user->setIsRootUser();
630  if (Yii::app()->edition == 'Commercial')
631  {
632  $user->hideFromLeaderboard = true;
633  $user->hideFromSelecting = true;
634  }
635  $saved = $user->save();
636  if (!$saved)
637  {
638  throw new FailedToSaveModelException();
639  }
640 
641  $group = Group::getByName(Group::SUPER_ADMINISTRATORS_GROUP_NAME);
642  $group->users->add($user);
643  $saved = $group->save();
644  if (!$saved)
645  {
646  throw new FailedToSaveModelException();
647  }
648  return $user;
649  }
650 
656  {
657  return static::createSystemUser(BaseControlUserConfigUtil::USERNAME);
658  }
659 
664  public static function generateRandomPasswordForSystemUser()
665  {
666  return md5(time() . mt_rand(1, 10000));
667  }
668 
679  public static function createSystemUser($username, $password = null, $hideFromSelecting = true,
680  $hideFromLeaderboard = true, $firstName = null, $lastName = null)
681  {
682  if (!isset($password))
683  {
684  $password = static::generateRandomPasswordForSystemUser();
685  }
686  if (!isset($firstName))
687  {
688  $firstName = 'System';
689  }
690  if (!isset($lastName))
691  {
692  $lastName = 'User';
693  }
694  $user = new User();
695  $user->username = $username;
696  $user->firstName = $firstName;
697  $user->lastName = $lastName;
698  $user->hideFromSelecting = $hideFromSelecting;
699  $user->hideFromLeaderboard = $hideFromLeaderboard;
700  $user->setIsSystemUser();
701  $user->setPassword($password);
702  $saved = $user->save();
703  if (!$saved)
704  {
705  throw new FailedToSaveModelException();
706  }
707  $user->setRight('UsersModule', UsersModule::RIGHT_LOGIN_VIA_MOBILE, Right::DENY);
708  $user->setRight('UsersModule', UsersModule::RIGHT_LOGIN_VIA_WEB, Right::DENY);
709  $user->setRight('UsersModule', UsersModule::RIGHT_LOGIN_VIA_WEB_API, Right::DENY);
710  $saved = $user->save();
711  if (!$saved)
712  {
713  throw new FailedToSaveModelException();
714  }
715  $group = Group::getByName(Group::SUPER_ADMINISTRATORS_GROUP_NAME);
716  $group->users->add($user);
717  $saved = $group->save();
718  if (!$saved)
719  {
720  throw new FailedToSaveModelException();
721  }
722  return $user;
723  }
724 
725  public static function autoBuildDatabase(& $messageLogger, $autoBuildTestModels = false)
726  {
727  ZurmoDatabaseCompatibilityUtil::createStoredFunctionsAndProcedures();
728  ZurmoDatabaseCompatibilityUtil::createActualPermissionsCacheTable();
729  ZurmoDatabaseCompatibilityUtil::createNamedSecurableActualPermissionsCacheTable();
730  ZurmoDatabaseCompatibilityUtil::createActualRightsCacheTable();
731  $messageLogger->addInfoMessage(Zurmo::t('InstallModule', 'Searching for models'));
732  $rootModels = PathUtil::getAllCanHaveBeanModelClassNames();
733  $messageLogger->addInfoMessage(Zurmo::t('InstallModule', 'Models catalog built.'));
736  if ($autoBuildTestModels)
737  {
738  TestSuite::buildDependentTestModels($messageLogger);
739  }
740  }
741 
745  public static function writeConfiguration($instanceRoot,
746  $databaseType, $databaseHost, $databaseName, $username, $password, $port,
747  $memcacheHost = null, $memcachePort = null, $minifyScripts = true,
748  $language,
749  $perInstanceFilename = 'perInstance.php', $debugFilename = 'debug.php',
750  $hostInfo, $scriptUrl,
751  $submitCrashToSentry = false)
752  {
753  assert('is_dir($instanceRoot)');
754  assert('in_array($databaseType, static::getSupportedDatabaseTypes())');
755  assert('is_string($databaseHost) && $databaseHost != ""');
756  assert('is_string($databaseName) && $databaseName != ""');
757  assert('is_string($username) && $username != ""');
758  assert('is_string($password)');
759  assert('is_string($port) || is_int($port)');
760  assert('is_string($memcacheHost) || $memcacheHost == null');
761  assert('(is_int ($memcachePort) && $memcachePort >= 1024) || $memcachePort == null');
762  assert('is_string($language) && $language != ""');
763  assert('is_string($hostInfo) || $hostInfo == ""');
764  assert('is_string($scriptUrl) || $scriptUrl == ""');
765 
766  $perInstanceConfigFileDist = "$instanceRoot/protected/config/perInstanceDIST.php";
767  $debugConfigFileDist = "$instanceRoot/protected/config/debugDIST.php";
768 
769  $perInstanceConfigFile = "$instanceRoot/protected/config/$perInstanceFilename";
770  $debugConfigFile = "$instanceRoot/protected/config/$debugFilename";
771 
772  copy($perInstanceConfigFileDist, $perInstanceConfigFile);
773  copy($debugConfigFileDist, $debugConfigFile);
774  chmod($perInstanceConfigFile, 0777);
775  chmod($debugConfigFile, 0777);
776 
777  // NOTE: These keep the tidy formatting of the files they are modifying - the whitespace matters!
778  $contents = file_get_contents($debugConfigFile);
779  $contents = preg_replace('/\$debugOn\s*=\s*true;/',
780  '$debugOn = false;',
781  $contents);
782  if (!$submitCrashToSentry)
783  {
784  $contents = preg_replace('/\$submitCrashToSentry\s*=\s*true;/',
785  '$submitCrashToSentry = false;',
786  $contents);
787  }
788  $setIncludePathServiceHelper = new SetIncludePathServiceHelper();
789  if ($minifyScripts && $setIncludePathServiceHelper->runCheckAndGetIfSuccessful())
790  {
791  $contents = preg_replace('/\$minifyScripts\s*=\s*false;/',
792  '$minifyScripts = true;',
793  $contents);
794  }
795  // Check if user setup memcache host and port
796  if ($memcacheHost && $memcachePort)
797  {
798  $phpVersion = explode('.', phpversion());
799  if ($phpVersion[0] >= 7)
800  {
801  // Check if memcached extension is installed
802  $memcachedServiceHelper = new MemcachedServiceHelper();
803  if ($memcachedServiceHelper->runCheckAndGetIfSuccessful())
804  {
805  $contents = preg_replace('/\$memcacheLevelCaching\s*=\s*false;/',
806  '$memcacheLevelCaching = true;',
807  $contents);
808  }
809  }
810  else
811  {
812  // Check if memcache extension is installed
813  $memcacheServiceHelper = new MemcacheServiceHelper();
814  if ($memcacheServiceHelper->runCheckAndGetIfSuccessful())
815  {
816  $contents = preg_replace('/\$memcacheLevelCaching\s*=\s*false;/',
817  '$memcacheLevelCaching = true;',
818  $contents);
819  }
820  }
821  }
822 
823  $installSettingsForm = new InstallSettingsForm();
824  $installSettingsForm->databaseHostname = $databaseHost;
825  $installSettingsForm->databaseUsername = $username;
826  $installSettingsForm->databasePassword = $password;
827  $installSettingsForm->databasePort = $port;
828  $maxSpRecursionDepthServiceHelper = new DatabaseMaxSpRecursionDepthServiceHelper($installSettingsForm);
829  if ($maxSpRecursionDepthServiceHelper->runCheckAndGetIfSuccessful())
830  {
831  $contents = preg_replace('/\$securityOptimized\s*=\s*false;/',
832  '$securityOptimized = true;',
833  $contents);
834  }
835  else
836  {
837  $contents = preg_replace('/\$securityOptimized\s*=\s*true;/',
838  '$securityOptimized = false;',
839  $contents);
840  }
841 
842  file_put_contents($debugConfigFile, $contents);
843 
844  $contents = file_get_contents($perInstanceConfigFile);
845  $contents = preg_replace('/\$language\s*=\s*\'[a-z]+\';/', // Not Coding Standard
846  "\$language = '$language';",
847  $contents);
848  $contents = preg_replace('/\$connectionString\s*=\s*\'[a-z]+:host=[^;]+;port=[^;]+;dbname=[^;]+;/', // Not Coding Standard
849  "\$connectionString = '$databaseType:host=$databaseHost;port=$port;dbname=$databaseName';", // Not Coding Standard
850  $contents);
851  $contents = preg_replace('/\$username\s*=\s*\'[^\']+\';/', // Not Coding Standard
852  "\$username = '$username';",
853  $contents);
854  $contents = preg_replace('/\$password\s*=\s*\'[^\']+\';/', // Not Coding Standard
855  "\$password = '$password';",
856  $contents);
857  $contents = preg_replace('/\$memcacheServers\s*=\s*array\(.*?array\(\s+\'host\'\s*=>\s*\'[^\']+\',\s*\'port\'\s*=>\s*\d{4,},/s', // Not Coding Standard
858  "\$memcacheServers = array( // An empty array means memcache is not used.
859  array(
860  'host' => '$memcacheHost',
861  'port' => $memcachePort, ",
862  $contents);
863  $contents = preg_replace('/\/\/\$instanceConfig\[\'components\'\]\[\'request\'\]\[\'hostInfo\'\]\s*=\s*\'.*?\';/', // Not Coding Standard
864  "\$instanceConfig['components']['request']['hostInfo'] = '$hostInfo';",
865  $contents);
866  $contents = preg_replace('/\/\/\$instanceConfig\[\'components\'\]\[\'request\'\]\[\'scriptUrl\'\]\s*=\s*\'.*?\';/', // Not Coding Standard
867  "\$instanceConfig['components']['request']['scriptUrl'] = '$scriptUrl';",
868  $contents);
869  $contents = preg_replace('/\s+\/\/ REMOVE THE REMAINDER OF THIS FILE FOR PRODUCTION.*?>/s', // Not Coding Standard
870  "\n?>",
871  $contents);
872  file_put_contents($perInstanceConfigFile, $contents);
873  }
874 
880  public static function setZurmoTokenAndWriteToPerInstanceFile($instanceRoot, $perInstanceFilename = 'perInstance.php')
881  {
882  assert('is_dir($instanceRoot)');
883 
884  if (!defined('ZURMO_TOKEN') || ZURMO_TOKEN == 'defaultValue')
885  {
886  $perInstanceConfigFile = "$instanceRoot/protected/config/$perInstanceFilename";
887  $contents = file_get_contents($perInstanceConfigFile);
888 
889  $zurmoToken = substr(md5(microtime() * mt_rand()), 0, 15);
890 
891  $contents = preg_replace('/define\(\'ZURMO_TOKEN\', \'defaultValue\'\);/',
892  "define('ZURMO_TOKEN', '$zurmoToken');",
893  $contents);
894 
895  file_put_contents($perInstanceConfigFile, $contents);
896  return $zurmoToken;
897  }
898  return ZURMO_TOKEN;
899  }
900 
901  public static function isDebugConfigWritable($instanceRoot)
902  {
903  $debugConfigFileDist = "$instanceRoot/protected/config/debugDIST.php";
904 
905  if (defined('IS_TEST'))
906  {
907  $debugConfigFile = "$instanceRoot/protected/config/debugTest.php";
908  }
909  else
910  {
911  $debugConfigFile = "$instanceRoot/protected/config/debug.php";
912  }
913  copy($debugConfigFileDist, $debugConfigFile);
914  $isWritable = is_writable($debugConfigFile);
915  unlink($debugConfigFile);
916 
917  return $isWritable;
918  }
919 
920  public static function doesDebugConfigExist($instanceRoot)
921  {
922  $debugConfigFile = "$instanceRoot/protected/config/debug.php";
923 
924  if (file_exists($debugConfigFile) && is_writable($debugConfigFile))
925  {
926  return true;
927  }
928 
929  return false;
930  }
931 
932  public static function isPerInstanceConfigWritable($instanceRoot)
933  {
934  $perInstanceConfigFileDist = "$instanceRoot/protected/config/perInstanceDIST.php";
935  if (defined('IS_TEST'))
936  {
937  $perInstanceConfigFile = "$instanceRoot/protected/config/perInstanceTest.php";
938  }
939  else
940  {
941  $perInstanceConfigFile = "$instanceRoot/protected/config/perInstance.php";
942  }
943 
944  copy($perInstanceConfigFileDist, $perInstanceConfigFile);
945  $isWritable = is_writable($perInstanceConfigFile);
946  unlink($perInstanceConfigFile);
947 
948  return $isWritable;
949  }
950 
951  public static function isApplicationLogRuntimeWritable($instanceRoot)
952  {
953  $applicationLogFile = "$instanceRoot/protected/runtime/application.log";
954  $runtimeDirectory = "$instanceRoot/protected/runtime";
955 
956  if (file_exists($applicationLogFile) && is_writable($applicationLogFile))
957  {
958  return true;
959  }
960  elseif (is_writable($runtimeDirectory))
961  {
962  //The application.log file may not exist yet.
963  return true;
964  }
965 
966  return false;
967  }
968 
969  public static function isMinScriptCacheRuntimeDirectoryWritable($instanceRoot)
970  {
971  $minScriptCacheRuntimeDirectory = "$instanceRoot/protected/runtime/minScript/cache";
972 
973  if (is_dir($minScriptCacheRuntimeDirectory) && is_writable($minScriptCacheRuntimeDirectory))
974  {
975  return true;
976  }
977 
978  return false;
979  }
980 
984  public static function writeInstallComplete($instanceRoot)
985  {
986  assert('is_dir($instanceRoot)');
987  if (defined('IS_TEST'))
988  {
989  $perInstanceConfigFile = "$instanceRoot/protected/config/perInstanceTest.php";
990  }
991  else
992  {
993  $perInstanceConfigFile = "$instanceRoot/protected/config/perInstance.php";
994  };
995  // NOTE: These keep the tidy formatting of the files they are modifying - the whitespace matters!
996  $contents = file_get_contents($perInstanceConfigFile);
997  $contents = preg_replace('/\$installed\s*=\s*false;/',
998  '$installed = true;',
999  $contents);
1000  file_put_contents($perInstanceConfigFile, $contents);
1001  }
1002 
1003  public static function isVersion($version)
1004  {
1005  return preg_match('/^\d+\.\d+(.\d+)?/', $version) == 1; // Not Coding Standard
1006  }
1007 
1008  protected static function checkVersion($minimumRequiredVersion, $actualVersion)
1009  {
1010  assert('static::isVersion($minimumRequiredVersion)');
1011  if (!static::isVersion($actualVersion))
1012  {
1013  return false;
1014  }
1015  if (preg_match('/^\d+\.\d+$/', $actualVersion) == 1) // Not Coding Standard
1016  {
1017  $actualVersion .= '.0';
1018  }
1019  return version_compare($actualVersion, $minimumRequiredVersion) >= 0;
1020  }
1021 
1022  protected static function getVersionFromPhpInfo($regEx)
1023  {
1024  ob_start();
1025  phpinfo();
1026  $phpInfo = trim(ob_get_clean());
1027  $matches = array();
1028  if (preg_match("/$regEx/si", $phpInfo, $matches) == 1)
1029  {
1030  return $matches[1];
1031  }
1032  return false;
1033  }
1034 
1041  public static function runInstallation($form, & $messageStreamer)
1042  {
1043  Yii::app()->params['isFreshInstall'] = true;
1044  assert('$form instanceof InstallSettingsForm');
1045  assert('$messageStreamer instanceof MessageStreamer');
1046 
1047  if (defined('IS_TEST'))
1048  {
1049  $perInstanceFilename = "perInstanceTest.php";
1050  $debugFilename = "debugTest.php";
1051  }
1052  else
1053  {
1054  @set_time_limit(1200);
1055  $perInstanceFilename = "perInstance.php";
1056  $debugFilename = "debug.php";
1057  }
1058 
1059  $messageStreamer->add(Zurmo::t('InstallModule', 'Connecting to Database.'));
1060  static::connectToDatabase($form->databaseType,
1061  $form->databaseHostname,
1062  $form->databaseName,
1063  $form->databaseUsername,
1064  $form->databasePassword,
1065  $form->databasePort);
1066  ForgetAllCacheUtil::forgetAllCaches();
1067  $messageStreamer->add(Zurmo::t('InstallModule', 'Dropping existing tables.'));
1068  ZurmoRedBean::$writer->wipeAll();
1069  $messageStreamer->add(Zurmo::t('InstallModule', 'Creating super user.'));
1070 
1071  $messageLogger = new MessageLogger($messageStreamer);
1072  $messageLogger->logDateTimeStamp = false;
1073  Yii::app()->custom->runBeforeInstallationAutoBuildDatabase($messageLogger);
1074  $messageStreamer->add(Zurmo::t('InstallModule', 'Starting database schema creation.'));
1075  $startTime = microtime(true);
1076  $messageStreamer->add('debugOn:' . BooleanUtil::boolToString(YII_DEBUG));
1077  $messageStreamer->add('phpLevelCaching:' . BooleanUtil::boolToString(PHP_CACHING_ON));
1078  $messageStreamer->add('memcacheLevelCaching:' . BooleanUtil::boolToString(MEMCACHE_ON));
1079  static::autoBuildDatabase($messageLogger, false);
1080  $endTime = microtime(true);
1081  $messageStreamer->add(Zurmo::t('InstallModule', 'Total autobuild time: {formattedTime} seconds.',
1082  array('{formattedTime}' => number_format(($endTime - $startTime), 3))));
1083  if (SHOW_QUERY_DATA)
1084  {
1085  $messageStreamer->add(FooterView::getTotalAndDuplicateQueryCountContent());
1086  $messageStreamer->add(PageView::makeNonHtmlDuplicateCountAndQueryContent());
1087  }
1088  $messageStreamer->add(Zurmo::t('InstallModule', 'Database schema creation complete.'));
1089  $messageStreamer->add(Zurmo::t('InstallModule', 'Rebuilding Permissions.'));
1091  $messageStreamer->add(Zurmo::t('InstallModule', 'Rebuilding Read Permissions Subscription tables.'));
1093  $messageStreamer->add(Zurmo::t('InstallModule', 'Writing Configuration File.'));
1094 
1095  static::writeConfiguration(INSTANCE_ROOT,
1096  $form->databaseType,
1097  $form->databaseHostname,
1098  $form->databaseName,
1099  $form->databaseUsername,
1100  $form->databasePassword,
1101  $form->databasePort,
1102  $form->memcacheHostname,
1103  (int)$form->memcachePortNumber,
1104  true,
1105  Yii::app()->language,
1106  $perInstanceFilename,
1107  $debugFilename,
1108  $form->hostInfo,
1109  $form->scriptUrl,
1110  $form->submitCrashToSentry);
1111  static::setZurmoTokenAndWriteToPerInstanceFile(INSTANCE_ROOT);
1113  static::createSuperUser('super', $form->superUserPassword);
1114  $messageStreamer->add(Zurmo::t('InstallModule', 'Setting up default data.'));
1115  DefaultDataUtil::load($messageLogger);
1116  static::createBaseControlUserConfigUtilUserAccount();
1117  Yii::app()->custom->runAfterInstallationDefaultDataLoad($messageLogger);
1118 
1119  // Send notification to super admin to delete test.php file in case if this
1120  // installation is used in production mode.
1121  $message = new NotificationMessage();
1122  $message->textContent = Zurmo::t('InstallModule', 'If this website is in production mode, please remove the app/test.php file.');
1124  NotificationsUtil::submit($message, $rules);
1125 
1126  // If minify is disabled, inform user that they should fix issues and enable minify
1127  $setIncludePathServiceHelper = new SetIncludePathServiceHelper();
1128  if (!$setIncludePathServiceHelper->runCheckAndGetIfSuccessful())
1129  {
1130  $message = new NotificationMessage();
1131  $message->textContent = Zurmo::t('InstallModule', 'Minify has been disabled due to a system issue. Try to resolve the problem and re-enable Minify.');
1132  $rules = new EnableMinifyNotificationRules();
1133  NotificationsUtil::submit($message, $rules);
1134  }
1135  $messageStreamer->add(Zurmo::t('InstallModule', 'Installation Complete.'));
1136  Yii::app()->params['isFreshInstall'] = false;
1137  }
1138 
1143  public static function getMaxAllowedFileSize()
1144  {
1145  //todo: cache this information.
1146  $actualPostLimitBytes = null;
1147  static::checkPhpPostSizeSetting(1, $actualPostLimitBytes);
1148  $actualUploadLimitBytes = null;
1149  static::checkPhpUploadSizeSetting(1, $actualUploadLimitBytes);
1151  return min($actualPostLimitBytes, $actualUploadLimitBytes, $actualMaxAllowedBytes);
1152  }
1153 
1158  public static function runFromInstallCommand($args, $validateForm = false)
1159  {
1160  assert('is_array($args)');
1161  $form = new InstallSettingsForm();
1162  $phpVersion = explode('.', phpversion());
1163  if ($phpVersion[0] >= 7)
1164  {
1165  $memcachedServiceHelper = new MemcachedServiceHelper();
1166  if (!$memcachedServiceHelper->runCheckAndGetIfSuccessful())
1167  {
1168  $form->setMemcacheIsNotAvailable();
1169  }
1170  }
1171  else
1172  {
1173  $memcacheServiceHelper = new MemcacheServiceHelper();
1174  if (!$memcacheServiceHelper->runCheckAndGetIfSuccessful())
1175  {
1176  $form->setMemcacheIsNotAvailable();
1177  }
1178  }
1179  $template = "{message}\n";
1180  $messageStreamer = new MessageStreamer($template);
1181  $messageStreamer->setExtraRenderBytes(0);
1182  $messageStreamer->add(Zurmo::t('InstallModule', 'Connecting to Database.'));
1183 
1184  $form->databaseHostname = $args[0];
1185  $form->databaseName = $args[1];
1186  $form->databaseUsername = $args[2];
1187  $form->databasePassword = $args[3];
1188  $form->databasePort = $args[4];
1189  $form->superUserPassword = $args[5];
1190  $form->removeExistingData = 1;
1191 
1192  if (!empty($args[6]))
1193  {
1194  $form->hostInfo = $args[6];
1195  Yii::app()->getRequest()->setHostInfo($form->hostInfo);
1196  }
1197  if (!empty($args[7]))
1198  {
1199  $form->scriptUrl = $args[7];
1200  }
1201 
1202  $formHasErrors = false;
1203  if ($validateForm)
1204  {
1205  $form->validate();
1206  if ($form->hasErrors())
1207  {
1208  $errors = $form->getErrors();
1209  foreach ($errors as $fieldErrors)
1210  {
1211  foreach ($fieldErrors as $fieldError)
1212  {
1213  $messageStreamer->add($fieldError);
1214  }
1215  }
1216  $formHasErrors = true;
1217  }
1218  }
1219 
1220  if (!$formHasErrors)
1221  {
1222  static::runInstallation($form, $messageStreamer);
1223  if (isset($args[8]))
1224  {
1225  $messageStreamer->add(Zurmo::t('InstallModule', 'Starting to load demo data.'));
1226  $messageLogger = new MessageLogger($messageStreamer);
1227  $messageLogger->logDateTimeStamp = false;
1228  $startTime = microtime(true);
1229  if (isset($args[9]))
1230  {
1231  DemoDataUtil::load($messageLogger, intval($args[9]));
1232  }
1233  else
1234  {
1235  DemoDataUtil::load($messageLogger, 6);
1236  }
1237  $endTime = microtime(true);
1238  $messageStreamer->add(Zurmo::t('InstallModule', 'Total demodata build time: {formattedTime} seconds.',
1239  array('{formattedTime}' => number_format(($endTime - $startTime), 3))));
1240  if (SHOW_QUERY_DATA)
1241  {
1242  $messageStreamer->add(FooterView::getTotalAndDuplicateQueryCountContent());
1243  $messageStreamer->add(PageView::makeNonHtmlDuplicateCountAndQueryContent());
1244  }
1245  $messageStreamer->add(Zurmo::t('InstallModule', 'Finished loading demo data.'));
1246  }
1247 
1248  if (empty($args[6]) || empty($args[7]))
1249  {
1250  // Send notification to super admin that need to setup hostInfo and scriptUrl params in perInstance.php
1251  $message = new NotificationMessage();
1252  $message->textContent = Zurmo::t('InstallModule', 'The system has detected that the hostInfo and/or scriptUrl are ' .
1253  'not set up. Please open the perInstance.php config file and ' .
1254  'set up these parameters.');
1255  $rules = new HostInfoAndScriptUrlNotSetupNotificationRules();
1256  NotificationsUtil::submit($message, $rules);
1257  }
1258 
1259  $messageStreamer->add(Zurmo::t('InstallModule', 'Locking Installation.'));
1260  static::writeInstallComplete(INSTANCE_ROOT);
1261  $messageStreamer->add(Zurmo::t('InstallModule', 'Installation Complete.'));
1262  }
1263  }
1264 
1269  public static function runAutoBuildFromUpdateSchemaCommand($messageLogger)
1270  {
1271  assert('$messageLogger instanceof MessageLogger');
1272  ForgetAllCacheUtil::forgetAllCaches();
1273  static::autoBuildDatabase($messageLogger);
1274  // Send notification to super admin to clean assets folder(optional).
1275  $message = new NotificationMessage();
1276  $message->textContent = Zurmo::t('InstallModule', 'Please delete all files from assets folder on server.');
1277  $rules = new ClearAssetsFolderNotificationRules();
1278  NotificationsUtil::submit($message, $rules);
1279  return true;
1280  }
1281 
1282  public static function getDefaultHostInfo()
1283  {
1284  $hostInfo = "";
1285  if (isset($_SERVER['HTTP_HOST']) && $_SERVER['HTTP_HOST'] !='')
1286  {
1287  $hostInfo = 'http://' . $_SERVER['HTTP_HOST'];
1288  }
1289  elseif (isset($_SERVER['SERVER_NAME']) && $_SERVER['SERVER_NAME'] != '')
1290  {
1291  $hostInfo = 'http://' . $_SERVER['SERVER_NAME'];
1292  }
1293  return $hostInfo;
1294  }
1295 
1296  public static function getDefaultScriptUrl($route = '')
1297  {
1298  if (isset($_SERVER['PHP_SELF']))
1299  {
1300  $url = rtrim($_SERVER['PHP_SELF'], '/');
1301  $route = rtrim($route, '/');
1302 
1303  if ($route != '')
1304  {
1305  $url = rtrim($url, $route);
1306  }
1307  return $url;
1308  }
1309  else
1310  {
1311  return '';
1312  }
1313  }
1314  }
1315 ?>
static runFromInstallCommand($args, $validateForm=false)
static checkDatabaseLogBinValue($databaseType, $databaseHostname, $databaseUsername, $databasePassword, $databasePort, &$logBinValue)
static generateTablesFromModelClassNames(array $modelClassNames, &$messageLogger)
static checkSoap()
static checkPhp($minimumRequiredVersion, &$actualVersion)
static checkMemcache($minimumRequiredVersion, &$actualVersion)
static getDatabaseMaxAllowedPacketsSize($databaseType, $databaseHostname, $databaseUsername, $databasePassword, $databasePort)
static rebuild($overwriteExistingTables=true, $forcePhp=false, $messageStreamer=null)
static checkDatabaseOptimizerSearchDepthValue($databaseType, $databaseHostname, $databaseUsername, $databasePassword, $databasePort, &$optimizerSearchDepth)
static generateRandomPasswordForSystemUser()
static setup($dsn, $username, $password)
Definition: User.php:37
static checkWebServer(array $minimumRequiredVersions, &$actualVersion)
Definition: InstallUtil.php:69
static setZurmoTokenAndWriteToPerInstanceFile($instanceRoot, $perInstanceFilename= 'perInstance.php')
static checkMemcached($minimumRequiredVersion, &$actualVersion)
static checkCtype()
static checkCurl($minimumRequiredVersion, &$actualVersion)
static checkDatabaseLoadLocalInFile($databaseType, $databaseHostname, $databaseUsername, $databasePassword, $databasePort)
static checkDatabaseDefaultCollation($databaseType, $databaseHostname, $databaseName, $databaseUsername, $databasePassword, $databasePort, $notAllowedDatabaseCollations, &$databaseDefaultCollation)
static load(&$messageLogger, $loadMagnitude=null)
static writeInstallComplete($instanceRoot)
static getDatabaseLogBinTrustFunctionCreatorsValue($databaseType, $databaseHostname, $databaseUsername, $databasePassword, $databasePort)
static getDatabaseLogBinValue($databaseType, $databaseHostname, $databaseUsername, $databasePassword, $databasePort)
static isFileUploadsOn()
static writeConfiguration($instanceRoot, $databaseType, $databaseHost, $databaseName, $username, $password, $port, $memcacheHost=null, $memcachePort=null, $minifyScripts=true, $language, $perInstanceFilename= 'perInstance.php', $debugFilename= 'debug.php', $hostInfo, $scriptUrl, $submitCrashToSentry=false)
static checkDatabaseLogBinTrustFunctionCreatorsValue($databaseType, $databaseHostname, $databaseUsername, $databasePassword, $databasePort, &$logBinTrustFunctionCreatorsValue)
static runAutoBuildFromUpdateSchemaCommand($messageLogger)
static checkPCRE()
static checkPhpTimezoneSetting()
static checkDatabaseMaxSpRecursionDepth($databaseType, $databaseHostname, $databaseUsername, $databasePassword, $databasePort, $minimumRequiredMaxSpRecursionDepth, &$maxSpRecursionDepth)
static checkApacheModDeflate()
static setPasswordSaltAndWriteToPerInstanceFile($instanceRoot, $perInstanceFilename= 'perInstance.php')
static getDatabaseThreadStackValue($databaseType, $databaseHostname, $databaseUsername, $databasePassword, $databasePort)
static createSuperUser($username, $password)
static checkAPC($minimumRequiredVersion, &$actualVersion)
static checkDatabase($databaseType, $databaseHostname, $databaseUsername, $databasePassword, $databasePort, $minimumRequiredVersion, &$actualVersion)
static runInstallation($form, &$messageStreamer)
static checkPhpUploadSizeSetting($minimumUploadRequireBytes, &$actualUploadLimitBytes)
static getByName($name)
Definition: Group.php:57
static checkDatabaseThreadStackValue($databaseType, $databaseHostname, $databaseUsername, $databasePassword, $databasePort, $minimumRequiredThreadStackValue, &$threadStackValue)
static getDatabaseOptimizerSearchDepthValue($databaseType, $databaseHostname, $databaseUsername, $databasePassword, $databasePort)
static getDatabaseMaxSpRecursionDepth($databaseType, $databaseHostname, $databaseUsername, $databasePassword, $databasePort)
static connectToDatabase($databaseType, $host, $databaseName, $username, $password, $port)
static checkDatabaseMaxAllowedPacketsSize($databaseType, $databaseHostname, $databaseUsername, $databasePassword, $databasePort, $minimumRequireBytes, &$actualBytes)
static checkZip()
static createSystemUser($username, $password=null, $hideFromSelecting=true, $hideFromLeaderboard=true, $firstName=null, $lastName=null)
static createBaseControlUserConfigUtilUserAccount()
static checkPhpPostSizeSetting($minimumPostRequireBytes, &$actualPostLimitBytes)
static getDatabaseDefaultCollation($databaseType, $databaseHostname, $databaseName, $databaseUsername, $databasePassword, $databasePort)
static boolToString($var)
Definition: BooleanUtil.php:64
static getMaxAllowedFileSize()
static submit(NotificationMessage $message, NotificationRules $rules)
static checkImap()
static checkPhpMaxMemorySetting($minimumMemoryRequireBytes, &$actualMemoryLimitBytes)
static getDatabaseVersion($databaseType, $databaseHostname, $databaseUsername, $databasePassword, $databasePort)
static checkServerVariable(&$error)
static checkSPL()
static checkMemcacheConnection($host, $port)
Generated on Tue Jul 7 2020 07:10:33
Account Suspended
Account Suspended
This Account has been suspended.
Contact your hosting provider for more information.