PartKeeprRequirements.php (7116B)
1 <?php 2 3 class PartKeeprRequirements extends SymfonyRequirements 4 { 5 /** 6 * Constructor that initializes the requirements. 7 */ 8 public function __construct() 9 { 10 parent::__construct(); 11 12 $this->addRequirement( 13 ini_get('allow_url_fopen') || function_exists('curl_init'), 14 sprintf('No way to remotely load files detected'), 15 sprintf('Either set <strong>allow_url_fopen=true</strong> or install the cURL extension') 16 ); 17 18 $this->addRequirement( 19 function_exists('imagecreate'), 20 sprintf('GD library not found'), 21 sprintf('Install the GD library extension') 22 ); 23 24 $this->addRequirement( 25 function_exists('imagettftext'), 26 sprintf('GD library has no FreeType support'), 27 sprintf('Install the FreeType extension and make sure GD extention can use it') 28 ); 29 30 $this->addRequirement( 31 function_exists('ldap_connect'), 32 sprintf('LDAP library not found'), 33 sprintf('Install the LDAP library extension') 34 ); 35 36 $this->addRequirement( 37 function_exists('curl_init'), 38 sprintf('CURL library not found'), 39 sprintf('Install the CURL library extension') 40 ); 41 42 $this->addPhpIniRequirement( 43 'memory_limit', 44 $this->getBytesIniSetting('memory_limit') > 128000000, 45 false, 46 'Memory Limit too small', 47 sprintf( 48 'The php.ini memory_limit directive must be set to 128MB or higher. Your limit is set to %s', 49 ini_get('memory_limit') 50 ) 51 ); 52 53 $this->checkWritable(realpath(dirname(__FILE__).'/../data/')); 54 $this->checkWritable(realpath(dirname(__FILE__).'/../app/')); 55 $this->checkWritable(realpath(dirname(__FILE__).'/../web/')); 56 57 $this->addRecommendation( 58 function_exists('apc_fetch'), 59 sprintf('PHP APCu cache not found'), 60 sprintf('For best performance install the PHP APCu cache') 61 ); 62 63 $this->addPhpIniRecommendation( 64 'max_execution_time', 65 ini_get('max_execution_time') > 30, 66 true, 67 sprintf('Maximum Execution Time might be too low'), 68 sprintf( 69 'Your maximum execution time is set to %d seconds, which might be too low for low-end systems. If you encounter problems, please increase the value.', 70 ini_get('max_execution_time') 71 ) 72 ); 73 74 $this->addRequirement( 75 function_exists('mb_convert_case'), 76 sprintf('The PHP function mb_convert_case does not exist.'), 77 sprintf('Please compile PHP with the mbstring functions in case you are using Gentoo, or install php-mbstring on RedHat, Fedora or CentOS.') 78 ); 79 80 $this->addRequirement( 81 function_exists('bcscale'), 82 sprintf('BCMath library not found'), 83 sprintf('Install the BCMath library extension') 84 ); 85 86 if (ini_get('opcache.enable')) { 87 if (version_compare(phpversion(), '7.0', '<')) { 88 $this->addPhpIniRequirement( 89 'opcache.save_comments', 90 1, 91 false, 92 'opcache.save_comments must be on', 93 sprintf('The php.ini opcache.save_comments directive must be set to 1.') 94 ); 95 96 $this->addPhpIniRequirement( 97 'opcache.load_comments', 98 1, 99 false, 100 'opcache.load_comments must be on', 101 sprintf('The php.ini opcache.load_comments directive must be set to 1.') 102 ); 103 } 104 } 105 } 106 107 /** 108 * Checks if a path is writable. If not, generates a requirement. 109 * 110 * @param $path string The path to check 111 */ 112 protected function checkWritable($path) 113 { 114 try { 115 $this->isWritableRecursive($path); 116 } catch (\Exception $e) { 117 $this->addRequirement( 118 false, 119 sprintf( 120 'Directory %s and all subfolders/files must be writable.<br/><br/>If you already set the subfolders and files writable, you might have SELinux installed. Read <a href="https://wiki.partkeepr.org/wiki/SELinux" target="_blank">the PartKeepr SELinux Wiki Article</a> for further information.<br/>', 121 $path 122 ), 123 $e->getMessage() 124 ); 125 } 126 } 127 128 /** 129 * Returns a php.ini setting with parsed byte values. 130 * 131 * Example: If you specify memory_limit=64M, this method will return 67108864 bytes. 132 * 133 * @param $setting string The php.ini setting 134 * 135 * @return int The byts 136 */ 137 protected function getBytesIniSetting($setting) 138 { 139 return (int) $this->returnBytes(ini_get($setting)); 140 } 141 142 /** 143 * Parses a value with g,m or k modifiers and returns the effective bytes. 144 * 145 * @param $val string The value to parse 146 * 147 * @return int|string The bytes 148 */ 149 protected function returnBytes($val) 150 { 151 $val = trim($val); 152 $last = strtolower($val[strlen($val) - 1]); 153 $vali = (int) substr($val, 0, -1); 154 switch ($last) { 155 // The 'G' modifier is available since PHP 5.1.0 156 case 'g': 157 $vali *= 1073741824; 158 break; 159 case 'm': 160 $vali *= 1048576; 161 break; 162 case 'k': 163 $vali *= 1024; 164 break; 165 default: 166 $vali = (int) $val; 167 } 168 169 return $vali; 170 } 171 172 /** 173 * Checks if the given directory and all contained files within it is writable by the current user. 174 * 175 * @param string $dir The directory to check 176 * 177 * @throws \Exception If the directory is not writable 178 * 179 * @return bool True if the path is writable 180 */ 181 protected function isWritableRecursive($dir) 182 { 183 if (!is_writable($dir)) { 184 throw new \Exception($dir.' is not writable.'); 185 } 186 187 $folder = opendir($dir); 188 while ($file = readdir($folder)) { 189 if ($file != '.' && $file != '..') { 190 if (!is_writable($dir.'/'.$file)) { 191 closedir($folder); 192 193 throw new \Exception($dir.'/'.$file.' is not writable.'); 194 } else { 195 // Skip hidden directories 196 if ((is_dir($dir.'/'.$file)) && ($file[0] == '.')) { 197 continue; 198 } 199 if (is_dir($dir.'/'.$file)) { 200 if (!$this->isWritableRecursive($dir.'/'.$file)) { 201 closedir($folder); 202 203 throw new \Exception($dir.'/'.$file.'is not writable.'); 204 } 205 } 206 } 207 } 208 } 209 210 return true; 211 } 212 }