commit 24fb374ba11f229f8e9e637f87eeb0b77f68add3
parent 457c879e8bd19b9591f047daaa0e0d8e7baa55c9
Author: Felicitus <felicitus@felicitus.org>
Date: Wed, 24 Jun 2015 13:00:07 +0200
Updated Sf2 requirements check
Diffstat:
M | app/SymfonyRequirements.php | | | 150 | ++++++++++++++++++++++++++----------------------------------------------------- |
M | app/check.php | | | 148 | ++++++++++++++++++------------------------------------------------------------- |
2 files changed, 83 insertions(+), 215 deletions(-)
diff --git a/app/SymfonyRequirements.php b/app/SymfonyRequirements.php
@@ -41,25 +41,25 @@ class Requirement
/**
* Constructor that initializes the requirement.
*
- * @param bool $fulfilled Whether the requirement is fulfilled
+ * @param Boolean $fulfilled Whether the requirement is fulfilled
* @param string $testMessage The message for testing the requirement
* @param string $helpHtml The help text formatted in HTML for resolving the problem
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
- * @param bool $optional Whether this is only an optional recommendation not a mandatory requirement
+ * @param Boolean $optional Whether this is only an optional recommendation not a mandatory requirement
*/
public function __construct($fulfilled, $testMessage, $helpHtml, $helpText = null, $optional = false)
{
- $this->fulfilled = (bool) $fulfilled;
+ $this->fulfilled = (Boolean) $fulfilled;
$this->testMessage = (string) $testMessage;
$this->helpHtml = (string) $helpHtml;
$this->helpText = null === $helpText ? strip_tags($this->helpHtml) : (string) $helpText;
- $this->optional = (bool) $optional;
+ $this->optional = (Boolean) $optional;
}
/**
* Returns whether the requirement is fulfilled.
*
- * @return bool true if fulfilled, otherwise false
+ * @return Boolean true if fulfilled, otherwise false
*/
public function isFulfilled()
{
@@ -99,7 +99,7 @@ class Requirement
/**
* Returns whether this is only an optional recommendation and not a mandatory requirement.
*
- * @return bool true if optional, false if mandatory
+ * @return Boolean true if optional, false if mandatory
*/
public function isOptional()
{
@@ -117,16 +117,16 @@ class PhpIniRequirement extends Requirement
/**
* Constructor that initializes the requirement.
*
- * @param string $cfgName The configuration name used for ini_get()
- * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false,
- * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
- * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
- * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
- * Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
- * @param string|null $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived)
- * @param string|null $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived)
- * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
- * @param bool $optional Whether this is only an optional recommendation not a mandatory requirement
+ * @param string $cfgName The configuration name used for ini_get()
+ * @param Boolean|callback $evaluation Either a Boolean indicating whether the configuration should evaluate to true or false,
+ * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
+ * @param Boolean $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
+ * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
+ * Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
+ * @param string|null $testMessage The message for testing the requirement (when null and $evaluation is a Boolean a default message is derived)
+ * @param string|null $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a Boolean a default help is derived)
+ * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
+ * @param Boolean $optional Whether this is only an optional recommendation not a mandatory requirement
*/
public function __construct($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null, $optional = false)
{
@@ -193,7 +193,7 @@ class RequirementCollection implements IteratorAggregate
/**
* Adds a mandatory requirement.
*
- * @param bool $fulfilled Whether the requirement is fulfilled
+ * @param Boolean $fulfilled Whether the requirement is fulfilled
* @param string $testMessage The message for testing the requirement
* @param string $helpHtml The help text formatted in HTML for resolving the problem
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
@@ -206,7 +206,7 @@ class RequirementCollection implements IteratorAggregate
/**
* Adds an optional recommendation.
*
- * @param bool $fulfilled Whether the recommendation is fulfilled
+ * @param Boolean $fulfilled Whether the recommendation is fulfilled
* @param string $testMessage The message for testing the recommendation
* @param string $helpHtml The help text formatted in HTML for resolving the problem
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
@@ -219,15 +219,15 @@ class RequirementCollection implements IteratorAggregate
/**
* Adds a mandatory requirement in form of a php.ini configuration.
*
- * @param string $cfgName The configuration name used for ini_get()
- * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false,
- * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
- * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
- * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
- * Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
- * @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived)
- * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived)
- * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
+ * @param string $cfgName The configuration name used for ini_get()
+ * @param Boolean|callback $evaluation Either a Boolean indicating whether the configuration should evaluate to true or false,
+ * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
+ * @param Boolean $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
+ * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
+ * Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
+ * @param string $testMessage The message for testing the requirement (when null and $evaluation is a Boolean a default message is derived)
+ * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a Boolean a default help is derived)
+ * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
*/
public function addPhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null)
{
@@ -237,15 +237,15 @@ class RequirementCollection implements IteratorAggregate
/**
* Adds an optional recommendation in form of a php.ini configuration.
*
- * @param string $cfgName The configuration name used for ini_get()
- * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false,
- * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
- * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
- * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
- * Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
- * @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived)
- * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived)
- * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
+ * @param string $cfgName The configuration name used for ini_get()
+ * @param Boolean|callback $evaluation Either a Boolean indicating whether the configuration should evaluate to true or false,
+ * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
+ * @param Boolean $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
+ * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
+ * Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
+ * @param string $testMessage The message for testing the requirement (when null and $evaluation is a Boolean a default message is derived)
+ * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a Boolean a default help is derived)
+ * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
*/
public function addPhpIniRecommendation($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null)
{
@@ -343,7 +343,7 @@ class RequirementCollection implements IteratorAggregate
/**
* Returns whether a php.ini configuration is not correct.
*
- * @return bool php.ini configuration problem?
+ * @return Boolean php.ini configuration problem?
*/
public function hasPhpIniConfigIssue()
{
@@ -405,24 +405,22 @@ class SymfonyRequirements extends RequirementCollection
$this->addRequirement(
is_dir(__DIR__.'/../vendor/composer'),
'Vendor libraries must be installed',
- 'Vendor libraries are missing. Install composer following instructions from <a href="http://getcomposer.org/">http://getcomposer.org/</a>. '.
+ 'Vendor libraries are missing. Install composer following instructions from <a href="http://getcomposer.org/">http://getcomposer.org/</a>. ' .
'Then run "<strong>php composer.phar install</strong>" to install them.'
);
- $cacheDir = is_dir(__DIR__.'/../var/cache') ? __DIR__.'/../var/cache' : __DIR__.'/cache';
+ $baseDir = basename(__DIR__);
$this->addRequirement(
- is_writable($cacheDir),
- 'app/cache/ or var/cache/ directory must be writable',
- 'Change the permissions of either "<strong>app/cache/</strong>" or "<strong>var/cache/</strong>" directory so that the web server can write into it.'
+ is_writable(__DIR__.'/cache'),
+ "$baseDir/cache/ directory must be writable",
+ "Change the permissions of the \"<strong>$baseDir/cache/</strong>\" directory so that the web server can write into it."
);
- $logsDir = is_dir(__DIR__.'/../var/logs') ? __DIR__.'/../var/logs' : __DIR__.'/logs';
-
$this->addRequirement(
- is_writable($logsDir),
- 'app/logs/ or var/logs/ directory must be writable',
- 'Change the permissions of either "<strong>app/logs/</strong>" or "<strong>var/logs/</strong>" directory so that the web server can write into it.'
+ is_writable(__DIR__.'/logs'),
+ "$baseDir/logs/ directory must be writable",
+ "Change the permissions of the \"<strong>$baseDir/logs/</strong>\" directory so that the web server can write into it."
);
$this->addPhpIniRequirement(
@@ -440,8 +438,8 @@ class SymfonyRequirements extends RequirementCollection
}
$this->addRequirement(
- isset($timezones[@date_default_timezone_get()]),
- sprintf('Configured default timezone "%s" must be supported by your installation of PHP', @date_default_timezone_get()),
+ isset($timezones[date_default_timezone_get()]),
+ sprintf('Configured default timezone "%s" must be supported by your installation of PHP', date_default_timezone_get()),
'Your default timezone is not supported by PHP. Check for typos in your <strong>php.ini</strong> file and have a look at the list of deprecated timezones at <a href="http://php.net/manual/en/timezones.others.php">http://php.net/manual/en/timezones.others.php</a>.'
);
}
@@ -530,16 +528,6 @@ class SymfonyRequirements extends RequirementCollection
'Install the <strong>PCRE</strong> extension (version 8.0+).'
);
- if (extension_loaded('mbstring')) {
- $this->addPhpIniRequirement(
- 'mbstring.func_overload',
- create_function('$cfgValue', 'return (int) $cfgValue === 0;'),
- true,
- 'string functions should not be overloaded',
- 'Set "<strong>mbstring.func_overload</strong>" to <strong>0</strong> in php.ini<a href="#phpini">*</a> to disable function overloading by the mbstring extension.'
- );
- }
-
/* optional recommendations follow */
if (file_exists(__DIR__.'/../vendor/composer')) {
@@ -623,12 +611,6 @@ class SymfonyRequirements extends RequirementCollection
'Install and enable the <strong>XML</strong> extension.'
);
- $this->addRecommendation(
- function_exists('filter_var'),
- 'filter_var() should be available',
- 'Install and enable the <strong>filter</strong> extension.'
- );
-
if (!defined('PHP_WINDOWS_VERSION_BUILD')) {
$this->addRecommendation(
function_exists('posix_isatty'),
@@ -685,8 +667,6 @@ class SymfonyRequirements extends RequirementCollection
||
(extension_loaded('apc') && ini_get('apc.enabled'))
||
- (extension_loaded('Zend Optimizer+') && ini_get('zend_optimizerplus.enable'))
- ||
(extension_loaded('Zend OPcache') && ini_get('opcache.enable'))
||
(extension_loaded('xcache') && ini_get('xcache.cacher'))
@@ -697,17 +677,9 @@ class SymfonyRequirements extends RequirementCollection
$this->addRecommendation(
$accelerator,
'a PHP accelerator should be installed',
- 'Install and/or enable a <strong>PHP accelerator</strong> (highly recommended).'
+ 'Install and enable a <strong>PHP accelerator</strong> like APC (highly recommended).'
);
- if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
- $this->addRecommendation(
- $this->getRealpathCacheSize() > 1000,
- 'realpath_cache_size should be above 1024 in php.ini',
- 'Set "<strong>realpath_cache_size</strong>" to e.g. "<strong>1024</strong>" in php.ini<a href="#phpini">*</a> to improve performance on windows.'
- );
- }
-
$this->addPhpIniRecommendation('short_open_tag', false);
$this->addPhpIniRecommendation('magic_quotes_gpc', false, true);
@@ -725,34 +697,10 @@ class SymfonyRequirements extends RequirementCollection
if (class_exists('PDO')) {
$drivers = PDO::getAvailableDrivers();
$this->addRecommendation(
- count($drivers) > 0,
+ count($drivers),
sprintf('PDO should have some drivers installed (currently available: %s)', count($drivers) ? implode(', ', $drivers) : 'none'),
'Install <strong>PDO drivers</strong> (mandatory for Doctrine).'
);
}
}
-
- /**
- * Loads realpath_cache_size from php.ini and converts it to int.
- *
- * (e.g. 16k is converted to 16384 int)
- *
- * @return int
- */
- protected function getRealpathCacheSize()
- {
- $size = ini_get('realpath_cache_size');
- $size = trim($size);
- $unit = strtolower(substr($size, -1, 1));
- switch ($unit) {
- case 'g':
- return $size * 1024 * 1024 * 1024;
- case 'm':
- return $size * 1024 * 1024;
- case 'k':
- return $size * 1024;
- default:
- return (int) $size;
- }
- }
}
diff --git a/app/check.php b/app/check.php
@@ -2,141 +2,61 @@
require_once dirname(__FILE__).'/SymfonyRequirements.php';
-$lineSize = 70;
$symfonyRequirements = new SymfonyRequirements();
+
$iniPath = $symfonyRequirements->getPhpIniConfigPath();
-echo_title('Symfony2 Requirements Checker');
+echo "********************************\n";
+echo "* *\n";
+echo "* Symfony requirements check *\n";
+echo "* *\n";
+echo "********************************\n\n";
-echo '> PHP is using the following php.ini file:'.PHP_EOL;
-if ($iniPath) {
- echo_style('green', ' '.$iniPath);
-} else {
- echo_style('warning', ' WARNING: No configuration file (php.ini) used by PHP!');
-}
+echo $iniPath ? sprintf("* Configuration file used by PHP: %s\n\n", $iniPath) : "* WARNING: No configuration file (php.ini) used by PHP!\n\n";
-echo PHP_EOL.PHP_EOL;
+echo "** ATTENTION **\n";
+echo "* The PHP CLI can use a different php.ini file\n";
+echo "* than the one used with your web server.\n";
+if ('\\' == DIRECTORY_SEPARATOR) {
+ echo "* (especially on the Windows platform)\n";
+}
+echo "* To be on the safe side, please also launch the requirements check\n";
+echo "* from your web server using the web/config.php script.\n";
-echo '> Checking Symfony requirements:'.PHP_EOL.' ';
+echo_title('Mandatory requirements');
-$messages = array();
+$checkPassed = true;
foreach ($symfonyRequirements->getRequirements() as $req) {
/** @var $req Requirement */
- if ($helpText = get_error_message($req, $lineSize)) {
- echo_style('red', 'E');
- $messages['error'][] = $helpText;
- } else {
- echo_style('green', '.');
+ echo_requirement($req);
+ if (!$req->isFulfilled()) {
+ $checkPassed = false;
}
}
-$checkPassed = empty($messages['error']);
+echo_title('Optional recommendations');
foreach ($symfonyRequirements->getRecommendations() as $req) {
- if ($helpText = get_error_message($req, $lineSize)) {
- echo_style('yellow', 'W');
- $messages['warning'][] = $helpText;
- } else {
- echo_style('green', '.');
- }
-}
-
-if ($checkPassed) {
- echo_block('success', 'OK', 'Your system is ready to run Symfony2 projects', true);
-} else {
- echo_block('error', 'ERROR', 'Your system is not ready to run Symfony2 projects', true);
-
- echo_title('Fix the following mandatory requirements', 'red');
-
- foreach ($messages['error'] as $helpText) {
- echo ' * '.$helpText.PHP_EOL;
- }
+ echo_requirement($req);
}
-if (!empty($messages['warning'])) {
- echo_title('Optional recommendations to improve your setup', 'yellow');
-
- foreach ($messages['warning'] as $helpText) {
- echo ' * '.$helpText.PHP_EOL;
- }
-}
-
-echo PHP_EOL;
-echo_style('title', 'Note');
-echo ' The command console could use a different php.ini file'.PHP_EOL;
-echo_style('title', '~~~~');
-echo ' than the one used with your web server. To be on the'.PHP_EOL;
-echo ' safe side, please check the requirements from your web'.PHP_EOL;
-echo ' server using the ';
-echo_style('yellow', 'web/config.php');
-echo ' script.'.PHP_EOL;
-echo PHP_EOL;
-
exit($checkPassed ? 0 : 1);
-function get_error_message(Requirement $requirement, $lineSize)
+/**
+ * Prints a Requirement instance
+ */
+function echo_requirement(Requirement $requirement)
{
- if ($requirement->isFulfilled()) {
- return;
- }
+ $result = $requirement->isFulfilled() ? 'OK' : ($requirement->isOptional() ? 'WARNING' : 'ERROR');
+ echo ' ' . str_pad($result, 9);
+ echo $requirement->getTestMessage() . "\n";
- $errorMessage = wordwrap($requirement->getTestMessage(), $lineSize - 3, PHP_EOL.' ').PHP_EOL;
- $errorMessage .= ' > '.wordwrap($requirement->getHelpText(), $lineSize - 5, PHP_EOL.' > ').PHP_EOL;
-
- return $errorMessage;
-}
-
-function echo_title($title, $style = null)
-{
- $style = $style ?: 'title';
-
- echo PHP_EOL;
- echo_style($style, $title.PHP_EOL);
- echo_style($style, str_repeat('~', strlen($title)).PHP_EOL);
- echo PHP_EOL;
-}
-
-function echo_style($style, $message)
-{
- // ANSI color codes
- $styles = array(
- 'reset' => "\033[0m",
- 'red' => "\033[31m",
- 'green' => "\033[32m",
- 'yellow' => "\033[33m",
- 'error' => "\033[37;41m",
- 'success' => "\033[37;42m",
- 'title' => "\033[34m",
- );
- $supports = has_color_support();
-
- echo($supports ? $styles[$style] : '').$message.($supports ? $styles['reset'] : '');
-}
-
-function echo_block($style, $title, $message)
-{
- $message = ' '.trim($message).' ';
- $width = strlen($message);
-
- echo PHP_EOL.PHP_EOL;
-
- echo_style($style, str_repeat(' ', $width).PHP_EOL);
- echo_style($style, str_pad(' ['.$title.']', $width, ' ', STR_PAD_RIGHT).PHP_EOL);
- echo_style($style, str_pad($message, $width, ' ', STR_PAD_RIGHT).PHP_EOL);
- echo_style($style, str_repeat(' ', $width).PHP_EOL);
+ if (!$requirement->isFulfilled()) {
+ echo sprintf(" %s\n\n", $requirement->getHelpText());
+ }
}
-function has_color_support()
+function echo_title($title)
{
- static $support;
-
- if (null === $support) {
- if (DIRECTORY_SEPARATOR == '\\') {
- $support = false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI');
- } else {
- $support = function_exists('posix_isatty') && @posix_isatty(STDOUT);
- }
- }
-
- return $support;
+ echo "\n** $title **\n\n";
}