partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

commit 24fb374ba11f229f8e9e637f87eeb0b77f68add3
parent 457c879e8bd19b9591f047daaa0e0d8e7baa55c9
Author: Felicitus <felicitus@felicitus.org>
Date:   Wed, 24 Jun 2015 13:00:07 +0200

Updated Sf2 requirements check

Diffstat:
Mapp/SymfonyRequirements.php | 150++++++++++++++++++++++++++-----------------------------------------------------
Mapp/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"; }