Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like CKFinder_Connector_Utils_FileSystem often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use CKFinder_Connector_Utils_FileSystem, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 26 | class CKFinder_Connector_Utils_FileSystem |
||
| 27 | { |
||
| 28 | |||
| 29 | /** |
||
| 30 | * This function behaves similar to System.IO.Path.Combine in C#, the only diffrenece is that it also accepts null values and treat them as empty string |
||
| 31 | * |
||
| 32 | * @static |
||
| 33 | * @access public |
||
| 34 | * @param string $path1 first path |
||
| 35 | * @param string $path2 scecond path |
||
| 36 | * @return string |
||
| 37 | */ |
||
| 38 | function combinePaths($path1, $path2) |
||
| 39 | { |
||
| 40 | if (is_null($path1)) { |
||
| 41 | $path1 = ""; |
||
| 42 | } |
||
| 43 | if (is_null($path2)) { |
||
| 44 | $path2 = ""; |
||
| 45 | } |
||
| 46 | if (!strlen($path2)) { |
||
| 47 | if (strlen($path1)) { |
||
| 48 | $_lastCharP1 = substr($path1, -1, 1); |
||
| 49 | if ($_lastCharP1 != "/" && $_lastCharP1 != "\\") { |
||
| 50 | $path1 .= DIRECTORY_SEPARATOR; |
||
| 51 | } |
||
| 52 | } |
||
| 53 | } |
||
| 54 | else { |
||
| 55 | $_firstCharP2 = substr($path2, 0, 1); |
||
| 56 | if (strlen($path1)) { |
||
| 57 | if (strpos($path2, $path1)===0) { |
||
| 58 | return $path2; |
||
| 59 | } |
||
| 60 | $_lastCharP1 = substr($path1, -1, 1); |
||
| 61 | if ($_lastCharP1 != "/" && $_lastCharP1 != "\\" && $_firstCharP2 != "/" && $_firstCharP2 != "\\") { |
||
| 62 | $path1 .= DIRECTORY_SEPARATOR; |
||
| 63 | } |
||
| 64 | } |
||
| 65 | else { |
||
| 66 | return $path2; |
||
| 67 | } |
||
| 68 | } |
||
| 69 | return $path1 . $path2; |
||
| 70 | } |
||
| 71 | |||
| 72 | /** |
||
| 73 | * Check whether $fileName is a valid file name, return true on success |
||
| 74 | * |
||
| 75 | * @static |
||
| 76 | * @access public |
||
| 77 | * @param string $fileName |
||
| 78 | * @return boolean |
||
| 79 | */ |
||
| 80 | function checkFileName($fileName) |
||
| 81 | { |
||
| 82 | if (is_null($fileName) || !strlen($fileName) || substr($fileName,-1,1)=="." || false!==strpos($fileName, "..")) { |
||
| 83 | return false; |
||
| 84 | } |
||
| 85 | |||
| 86 | if (preg_match(CKFINDER_REGEX_INVALID_FILE, $fileName)) { |
||
| 87 | return false; |
||
| 88 | } |
||
| 89 | |||
| 90 | return true; |
||
| 91 | } |
||
| 92 | |||
| 93 | /** |
||
| 94 | * Unlink file/folder |
||
| 95 | * |
||
| 96 | * @static |
||
| 97 | * @access public |
||
| 98 | * @param string $path |
||
| 99 | * @return boolean |
||
| 100 | */ |
||
| 101 | function unlink($path) |
||
| 102 | { |
||
| 103 | /* make sure the path exists */ |
||
| 104 | if(!file_exists($path)) { |
||
| 105 | return false; |
||
| 106 | } |
||
| 107 | |||
| 108 | /* If it is a file or link, just delete it */ |
||
| 109 | if(is_file($path) || is_link($path)) { |
||
| 110 | return @unlink($path); |
||
| 111 | } |
||
| 112 | |||
| 113 | /* Scan the dir and recursively unlink */ |
||
| 114 | $files = CKFinder_Connector_Utils_FileSystem::php4_scandir($path); |
||
| 115 | if ($files) { |
||
| 116 | foreach($files as $filename) |
||
| 117 | { |
||
| 118 | if ($filename == '.' || $filename == '..') { |
||
| 119 | continue; |
||
| 120 | } |
||
| 121 | $file = str_replace('//','/',$path.'/'.$filename); |
||
| 122 | CKFinder_Connector_Utils_FileSystem::unlink($file); |
||
| 123 | } |
||
| 124 | } |
||
| 125 | |||
| 126 | /* Remove the parent dir */ |
||
| 127 | if(!@rmdir($path)) { |
||
| 128 | return false; |
||
| 129 | } |
||
| 130 | |||
| 131 | return true; |
||
| 132 | } |
||
| 133 | |||
| 134 | /** |
||
| 135 | * PHP4 Scandir |
||
| 136 | * @static |
||
| 137 | * @access public |
||
| 138 | * @param $directory directory name |
||
| 139 | */ |
||
| 140 | function php4_scandir($directory) |
||
| 141 | { |
||
| 142 | if (!is_dir($directory) || (false === $fh = @opendir($directory))) { |
||
| 143 | return false; |
||
| 144 | } |
||
| 145 | |||
| 146 | $files = array (); |
||
| 147 | while (false !== ($filename = readdir($fh))) { |
||
| 148 | $files[] = $filename; |
||
| 149 | } |
||
| 150 | |||
| 151 | closedir($fh); |
||
| 152 | |||
| 153 | return $files; |
||
| 154 | } |
||
| 155 | |||
| 156 | /** |
||
| 157 | * Return file name without extension (without dot & last part after dot) |
||
| 158 | * |
||
| 159 | * @static |
||
| 160 | * @access public |
||
| 161 | * @param string $fileName |
||
| 162 | * @return string |
||
| 163 | */ |
||
| 164 | function getFileNameWithoutExtension($fileName) |
||
| 165 | { |
||
| 166 | $dotPos = strrpos( $fileName, '.' ); |
||
| 167 | if (false === $dotPos) { |
||
| 168 | return $fileName; |
||
| 169 | } |
||
| 170 | |||
| 171 | return substr($fileName, 0, $dotPos); |
||
| 172 | } |
||
| 173 | |||
| 174 | /** |
||
| 175 | * Get file extension (only last part - e.g. extension of file.foo.bar.jpg = jpg) |
||
| 176 | * |
||
| 177 | * @static |
||
| 178 | * @access public |
||
| 179 | * @param string $fileName |
||
| 180 | * @return string |
||
| 181 | */ |
||
| 182 | function getExtension( $fileName ) |
||
| 183 | { |
||
| 184 | $dotPos = strrpos( $fileName, '.' ); |
||
| 185 | if (false === $dotPos) { |
||
| 186 | return ""; |
||
| 187 | } |
||
| 188 | |||
| 189 | return substr( $fileName, strrpos( $fileName, '.' ) +1 ) ; |
||
| 190 | } |
||
| 191 | |||
| 192 | /** |
||
| 193 | * Read file, split it into small chunks and send it to the browser |
||
| 194 | * |
||
| 195 | * @static |
||
| 196 | * @access public |
||
| 197 | * @param string $filename |
||
| 198 | * @return boolean |
||
| 199 | */ |
||
| 200 | function readfileChunked($filename) |
||
| 201 | { |
||
| 202 | $chunksize = 1024 * 10; // how many bytes per chunk |
||
| 203 | |||
| 204 | $handle = fopen($filename, 'rb'); |
||
| 205 | if ($handle === false) { |
||
| 206 | return false; |
||
| 207 | } |
||
| 208 | while (!feof($handle)) { |
||
| 209 | echo fread($handle, $chunksize); |
||
| 210 | @ob_flush(); |
||
| 211 | flush(); |
||
| 212 | @set_time_limit(8); |
||
| 213 | } |
||
| 214 | fclose($handle); |
||
| 215 | return true; |
||
| 216 | } |
||
| 217 | |||
| 218 | /** |
||
| 219 | * Replace accented UTF-8 characters by unaccented ASCII-7 "equivalents". |
||
| 220 | * The purpose of this function is to replace characters commonly found in Latin |
||
| 221 | * alphabets with something more or less equivalent from the ASCII range. This can |
||
| 222 | * be useful for converting a UTF-8 to something ready for a filename, for example. |
||
| 223 | * Following the use of this function, you would probably also pass the string |
||
| 224 | * through utf8_strip_non_ascii to clean out any other non-ASCII chars |
||
| 225 | * |
||
| 226 | * For a more complete implementation of transliteration, see the utf8_to_ascii package |
||
| 227 | * available from the phputf8 project downloads: |
||
| 228 | * http://prdownloads.sourceforge.net/phputf8 |
||
| 229 | * |
||
| 230 | * @param string UTF-8 string |
||
| 231 | * @param string UTF-8 with accented characters replaced by ASCII chars |
||
| 232 | * @return string accented chars replaced with ascii equivalents |
||
| 233 | * @author Andreas Gohr <[email protected]> |
||
| 234 | * @see http://sourceforge.net/projects/phputf8/ |
||
| 235 | */ |
||
| 236 | function convertToAscii($str) |
||
| 237 | { |
||
| 238 | static $UTF8_LOWER_ACCENTS = NULL; |
||
| 239 | static $UTF8_UPPER_ACCENTS = NULL; |
||
| 240 | |||
| 241 | if ( is_null($UTF8_LOWER_ACCENTS) ) { |
||
| 242 | $UTF8_LOWER_ACCENTS = array( |
||
| 243 | 'à' => 'a', 'ô' => 'o', 'ď' => 'd', 'ḟ' => 'f', 'ë' => 'e', 'š' => 's', 'ơ' => 'o', |
||
| 244 | 'ß' => 'ss', 'ă' => 'a', 'ř' => 'r', 'ț' => 't', 'ň' => 'n', 'ā' => 'a', 'ķ' => 'k', |
||
| 245 | 'ŝ' => 's', 'ỳ' => 'y', 'ņ' => 'n', 'ĺ' => 'l', 'ħ' => 'h', 'ṗ' => 'p', 'ó' => 'o', |
||
| 246 | 'ú' => 'u', 'ě' => 'e', 'é' => 'e', 'ç' => 'c', 'ẁ' => 'w', 'ċ' => 'c', 'õ' => 'o', |
||
| 247 | 'ṡ' => 's', 'ø' => 'o', 'ģ' => 'g', 'ŧ' => 't', 'ș' => 's', 'ė' => 'e', 'ĉ' => 'c', |
||
| 248 | 'ś' => 's', 'î' => 'i', 'ű' => 'u', 'ć' => 'c', 'ę' => 'e', 'ŵ' => 'w', 'ṫ' => 't', |
||
| 249 | 'ū' => 'u', 'č' => 'c', 'ö' => 'oe', 'è' => 'e', 'ŷ' => 'y', 'ą' => 'a', 'ł' => 'l', |
||
| 250 | 'ų' => 'u', 'ů' => 'u', 'ş' => 's', 'ğ' => 'g', 'ļ' => 'l', 'ƒ' => 'f', 'ž' => 'z', |
||
| 251 | 'ẃ' => 'w', 'ḃ' => 'b', 'å' => 'a', 'ì' => 'i', 'ï' => 'i', 'ḋ' => 'd', 'ť' => 't', |
||
| 252 | 'ŗ' => 'r', 'ä' => 'ae', 'í' => 'i', 'ŕ' => 'r', 'ê' => 'e', 'ü' => 'ue', 'ò' => 'o', |
||
| 253 | 'ē' => 'e', 'ñ' => 'n', 'ń' => 'n', 'ĥ' => 'h', 'ĝ' => 'g', 'đ' => 'd', 'ĵ' => 'j', |
||
| 254 | 'ÿ' => 'y', 'ũ' => 'u', 'ŭ' => 'u', 'ư' => 'u', 'ţ' => 't', 'ý' => 'y', 'ő' => 'o', |
||
| 255 | 'â' => 'a', 'ľ' => 'l', 'ẅ' => 'w', 'ż' => 'z', 'ī' => 'i', 'ã' => 'a', 'ġ' => 'g', |
||
| 256 | 'ṁ' => 'm', 'ō' => 'o', 'ĩ' => 'i', 'ù' => 'u', 'į' => 'i', 'ź' => 'z', 'á' => 'a', |
||
| 257 | 'û' => 'u', 'þ' => 'th', 'ð' => 'dh', 'æ' => 'ae', 'µ' => 'u', 'ĕ' => 'e', |
||
| 258 | ); |
||
| 259 | } |
||
| 260 | |||
| 261 | $str = str_replace( |
||
| 262 | array_keys($UTF8_LOWER_ACCENTS), |
||
| 263 | array_values($UTF8_LOWER_ACCENTS), |
||
| 264 | $str |
||
| 265 | ); |
||
| 266 | |||
| 267 | if ( is_null($UTF8_UPPER_ACCENTS) ) { |
||
| 268 | $UTF8_UPPER_ACCENTS = array( |
||
| 269 | 'À' => 'A', 'Ô' => 'O', 'Ď' => 'D', 'Ḟ' => 'F', 'Ë' => 'E', 'Š' => 'S', 'Ơ' => 'O', |
||
| 270 | 'Ă' => 'A', 'Ř' => 'R', 'Ț' => 'T', 'Ň' => 'N', 'Ā' => 'A', 'Ķ' => 'K', |
||
| 271 | 'Ŝ' => 'S', 'Ỳ' => 'Y', 'Ņ' => 'N', 'Ĺ' => 'L', 'Ħ' => 'H', 'Ṗ' => 'P', 'Ó' => 'O', |
||
| 272 | 'Ú' => 'U', 'Ě' => 'E', 'É' => 'E', 'Ç' => 'C', 'Ẁ' => 'W', 'Ċ' => 'C', 'Õ' => 'O', |
||
| 273 | 'Ṡ' => 'S', 'Ø' => 'O', 'Ģ' => 'G', 'Ŧ' => 'T', 'Ș' => 'S', 'Ė' => 'E', 'Ĉ' => 'C', |
||
| 274 | 'Ś' => 'S', 'Î' => 'I', 'Ű' => 'U', 'Ć' => 'C', 'Ę' => 'E', 'Ŵ' => 'W', 'Ṫ' => 'T', |
||
| 275 | 'Ū' => 'U', 'Č' => 'C', 'Ö' => 'Oe', 'È' => 'E', 'Ŷ' => 'Y', 'Ą' => 'A', 'Ł' => 'L', |
||
| 276 | 'Ų' => 'U', 'Ů' => 'U', 'Ş' => 'S', 'Ğ' => 'G', 'Ļ' => 'L', 'Ƒ' => 'F', 'Ž' => 'Z', |
||
| 277 | 'Ẃ' => 'W', 'Ḃ' => 'B', 'Å' => 'A', 'Ì' => 'I', 'Ï' => 'I', 'Ḋ' => 'D', 'Ť' => 'T', |
||
| 278 | 'Ŗ' => 'R', 'Ä' => 'Ae', 'Í' => 'I', 'Ŕ' => 'R', 'Ê' => 'E', 'Ü' => 'Ue', 'Ò' => 'O', |
||
| 279 | 'Ē' => 'E', 'Ñ' => 'N', 'Ń' => 'N', 'Ĥ' => 'H', 'Ĝ' => 'G', 'Đ' => 'D', 'Ĵ' => 'J', |
||
| 280 | 'Ÿ' => 'Y', 'Ũ' => 'U', 'Ŭ' => 'U', 'Ư' => 'U', 'Ţ' => 'T', 'Ý' => 'Y', 'Ő' => 'O', |
||
| 281 | 'Â' => 'A', 'Ľ' => 'L', 'Ẅ' => 'W', 'Ż' => 'Z', 'Ī' => 'I', 'Ã' => 'A', 'Ġ' => 'G', |
||
| 282 | 'Ṁ' => 'M', 'Ō' => 'O', 'Ĩ' => 'I', 'Ù' => 'U', 'Į' => 'I', 'Ź' => 'Z', 'Á' => 'A', |
||
| 283 | 'Û' => 'U', 'Þ' => 'Th', 'Ð' => 'Dh', 'Æ' => 'Ae', 'Ĕ' => 'E', |
||
| 284 | ); |
||
| 285 | } |
||
| 286 | $str = str_replace( |
||
| 287 | array_keys($UTF8_UPPER_ACCENTS), |
||
| 288 | array_values($UTF8_UPPER_ACCENTS), |
||
| 289 | $str |
||
| 290 | ); |
||
| 291 | return $str; |
||
| 292 | } |
||
| 293 | |||
| 294 | /** |
||
| 295 | * Convert file name from UTF-8 to system encoding |
||
| 296 | * |
||
| 297 | * @static |
||
| 298 | * @access public |
||
| 299 | * @param string $fileName |
||
| 300 | * @return string |
||
| 301 | */ |
||
| 302 | function convertToFilesystemEncoding($fileName) |
||
| 303 | { |
||
| 304 | $_config =& CKFinder_Connector_Core_Factory::getInstance("Core_Config"); |
||
| 305 | $encoding = $_config->getFilesystemEncoding(); |
||
| 306 | if (is_null($encoding) || strcasecmp($encoding, "UTF-8") == 0 || strcasecmp($encoding, "UTF8") == 0) { |
||
| 307 | return $fileName; |
||
| 308 | } |
||
| 309 | |||
| 310 | if (!function_exists("iconv")) { |
||
| 311 | if (strcasecmp($encoding, "ISO-8859-1") == 0 || strcasecmp($encoding, "ISO8859-1") == 0 || strcasecmp($encoding, "Latin1") == 0) { |
||
| 312 | return str_replace("\0", "_", utf8_decode($fileName)); |
||
| 313 | } else if (function_exists('mb_convert_encoding')) { |
||
| 314 | |||
| 315 | $encoded = @mb_convert_encoding($fileName, $encoding, 'UTF-8'); |
||
| 316 | if (@mb_strlen($fileName, "UTF-8") != @mb_strlen($encoded, $encoding)) { |
||
| 317 | return str_replace("\0", "_", preg_replace("/[^[:ascii:]]/u","_",$fileName)); |
||
| 318 | } |
||
| 319 | else { |
||
| 320 | return str_replace("\0", "_", $encoded); |
||
| 321 | } |
||
| 322 | } else { |
||
| 323 | return str_replace("\0", "_", preg_replace("/[^[:ascii:]]/u","_",$fileName)); |
||
| 324 | } |
||
| 325 | } |
||
| 326 | |||
| 327 | $converted = @iconv("UTF-8", $encoding . "//IGNORE//TRANSLIT", $fileName); |
||
| 328 | if ($converted === false) { |
||
| 329 | return str_replace("\0", "_", preg_replace("/[^[:ascii:]]/u","_",$fileName)); |
||
| 330 | } |
||
| 331 | |||
| 332 | return $converted; |
||
| 333 | } |
||
| 334 | |||
| 335 | /** |
||
| 336 | * Convert file name from system encoding into UTF-8 |
||
| 337 | * |
||
| 338 | * @static |
||
| 339 | * @access public |
||
| 340 | * @param string $fileName |
||
| 341 | * @return string |
||
| 342 | */ |
||
| 343 | function convertToConnectorEncoding($fileName) |
||
| 344 | { |
||
| 345 | $_config =& CKFinder_Connector_Core_Factory::getInstance("Core_Config"); |
||
| 346 | $encoding = $_config->getFilesystemEncoding(); |
||
| 347 | if (is_null($encoding) || strcasecmp($encoding, "UTF-8") == 0 || strcasecmp($encoding, "UTF8") == 0) { |
||
| 348 | return $fileName; |
||
| 349 | } |
||
| 350 | |||
| 351 | if (!function_exists("iconv")) { |
||
| 352 | if (strcasecmp($encoding, "ISO-8859-1") == 0 || strcasecmp($encoding, "ISO8859-1") == 0 || strcasecmp($encoding, "Latin1") == 0) { |
||
| 353 | return utf8_encode($fileName); |
||
| 354 | } else { |
||
| 355 | return $fileName; |
||
| 356 | } |
||
| 357 | } |
||
| 358 | |||
| 359 | $converted = @iconv($encoding, "UTF-8", $fileName); |
||
| 360 | |||
| 361 | if ($converted === false) { |
||
| 362 | return $fileName; |
||
| 363 | } |
||
| 364 | |||
| 365 | return $converted; |
||
| 366 | } |
||
| 367 | |||
| 368 | /** |
||
| 369 | * Find document root |
||
| 370 | * |
||
| 371 | * @return string |
||
| 372 | * @access public |
||
| 373 | */ |
||
| 374 | function getDocumentRootPath() |
||
| 375 | { |
||
| 376 | /** |
||
| 377 | * The absolute pathname of the currently executing script. |
||
| 378 | * Notatka: If a script is executed with the CLI, as a relative path, such as file.php or ../file.php, |
||
| 379 | * $_SERVER['SCRIPT_FILENAME'] will contain the relative path specified by the user. |
||
| 380 | */ |
||
| 381 | if (isset($_SERVER['SCRIPT_FILENAME'])) { |
||
| 382 | $sRealPath = dirname($_SERVER['SCRIPT_FILENAME']); |
||
| 383 | } |
||
| 384 | else { |
||
| 385 | /** |
||
| 386 | * realpath — Returns canonicalized absolute pathname |
||
| 387 | */ |
||
| 388 | $sRealPath = realpath( './' ) ; |
||
| 389 | } |
||
| 390 | |||
| 391 | /** |
||
| 392 | * The filename of the currently executing script, relative to the document root. |
||
| 393 | * For instance, $_SERVER['PHP_SELF'] in a script at the address http://example.com/test.php/foo.bar |
||
| 394 | * would be /test.php/foo.bar. |
||
| 395 | */ |
||
| 396 | $sSelfPath = dirname($_SERVER['PHP_SELF']); |
||
| 397 | |||
| 398 | return substr($sRealPath, 0, strlen($sRealPath) - strlen($sSelfPath)); |
||
| 399 | } |
||
| 400 | |||
| 401 | /** |
||
| 402 | * Create directory recursively |
||
| 403 | * |
||
| 404 | * @static |
||
| 405 | * @access public |
||
| 406 | * @param string $dir |
||
| 407 | * @param int $mode |
||
| 408 | * @return boolean |
||
| 409 | */ |
||
| 410 | function createDirectoryRecursively($dir) |
||
| 411 | { |
||
| 412 | if (is_dir($dir)) { |
||
| 413 | return true; |
||
| 414 | } |
||
| 415 | |||
| 416 | //attempt to create directory |
||
| 417 | $_config =& CKFinder_Connector_Core_Factory::getInstance("Core_Config"); |
||
| 418 | if ($perms = $_config->getChmodFolders()) { |
||
| 419 | $oldUmask = umask(0); |
||
| 420 | $bCreated = @mkdir($dir, $perms); |
||
| 421 | umask($oldUmask); |
||
| 422 | } |
||
| 423 | else { |
||
| 424 | $bCreated = @mkdir($dir); |
||
| 425 | } |
||
| 426 | |||
| 427 | if ($bCreated) { |
||
| 428 | return true; |
||
| 429 | } |
||
| 430 | |||
| 431 | //failed to create directory, perhaps we need to create parent directories first |
||
| 432 | if (!CKFinder_Connector_Utils_FileSystem::createDirectoryRecursively(dirname($dir))) { |
||
| 433 | return false; |
||
| 434 | } |
||
| 435 | |||
| 436 | //parent directories created successfully, let's try to create directory once again |
||
| 437 | if ($perms) { |
||
| 438 | $old_umask = umask(0); |
||
| 439 | $result = @mkdir($dir, $perms); |
||
| 440 | umask($old_umask); |
||
| 441 | } |
||
| 442 | else { |
||
| 443 | $result = @mkdir($dir); |
||
| 444 | } |
||
| 445 | |||
| 446 | return $result; |
||
| 447 | } |
||
| 448 | |||
| 449 | /** |
||
| 450 | * Detect HTML in the first KB to prevent against potential security issue with |
||
| 451 | * IE/Safari/Opera file type auto detection bug. |
||
| 452 | * Returns true if file contain insecure HTML code at the beginning. |
||
| 453 | * |
||
| 454 | * @static |
||
| 455 | * @access public |
||
| 456 | * @param string $filePath absolute path to file |
||
| 457 | * @return boolean |
||
| 458 | */ |
||
| 459 | function detectHtml($filePath) |
||
| 460 | { |
||
| 461 | $fp = @fopen($filePath, 'rb'); |
||
| 462 | if ( $fp === false || !flock( $fp, LOCK_SH ) ) { |
||
| 463 | return -1 ; |
||
| 464 | } |
||
| 465 | $chunk = fread($fp, 1024); |
||
| 466 | flock( $fp, LOCK_UN ) ; |
||
| 467 | fclose($fp); |
||
| 468 | |||
| 469 | $chunk = strtolower($chunk); |
||
| 470 | |||
| 471 | if (!$chunk) { |
||
| 472 | return false; |
||
| 473 | } |
||
| 474 | |||
| 475 | $chunk = trim($chunk); |
||
| 476 | |||
| 477 | if (preg_match("/<!DOCTYPE\W*X?HTML/sim", $chunk)) { |
||
| 478 | return true; |
||
| 479 | } |
||
| 480 | |||
| 481 | $tags = array('<body', '<head', '<html', '<img', '<pre', '<script', '<table', '<title'); |
||
| 482 | |||
| 483 | foreach( $tags as $tag ) { |
||
| 484 | if(false !== strpos($chunk, $tag)) { |
||
| 485 | return true ; |
||
| 486 | } |
||
| 487 | } |
||
| 488 | |||
| 489 | //type = javascript |
||
| 490 | if (preg_match('!type\s*=\s*[\'"]?\s*(?:\w*/)?(?:ecma|java)!sim', $chunk)) { |
||
| 491 | return true ; |
||
| 492 | } |
||
| 493 | |||
| 494 | //href = javascript |
||
| 495 | //src = javascript |
||
| 496 | //data = javascript |
||
| 497 | if (preg_match('!(?:href|src|data)\s*=\s*[\'"]?\s*(?:ecma|java)script:!sim',$chunk)) { |
||
| 498 | return true ; |
||
| 499 | } |
||
| 500 | |||
| 501 | //url(javascript |
||
| 502 | if (preg_match('!url\s*\(\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk)) { |
||
| 503 | return true ; |
||
| 504 | } |
||
| 505 | |||
| 506 | return false ; |
||
| 507 | } |
||
| 508 | |||
| 509 | /** |
||
| 510 | * Check file content. |
||
| 511 | * Currently this function validates only image files. |
||
| 512 | * Returns false if file is invalid. |
||
| 513 | * |
||
| 514 | * @static |
||
| 515 | * @access public |
||
| 516 | * @param string $filePath absolute path to file |
||
| 517 | * @param string $extension file extension |
||
| 518 | * @param integer $detectionLevel 0 = none, 1 = use getimagesize for images, 2 = use DetectHtml for images |
||
| 519 | * @return boolean |
||
| 520 | */ |
||
| 521 | function isImageValid($filePath, $extension) |
||
| 522 | { |
||
| 523 | if (!@is_readable($filePath)) { |
||
| 524 | return -1; |
||
| 525 | } |
||
| 526 | |||
| 527 | $imageCheckExtensions = array('gif', 'jpeg', 'jpg', 'png', 'psd', 'bmp', 'tiff'); |
||
| 528 | |||
| 529 | // version_compare is available since PHP4 >= 4.0.7 |
||
| 530 | if ( function_exists( 'version_compare' ) ) { |
||
| 531 | $sCurrentVersion = phpversion(); |
||
| 532 | if ( version_compare( $sCurrentVersion, "4.2.0" ) >= 0 ) { |
||
| 533 | $imageCheckExtensions[] = "tiff"; |
||
| 534 | $imageCheckExtensions[] = "tif"; |
||
| 535 | } |
||
| 536 | if ( version_compare( $sCurrentVersion, "4.3.0" ) >= 0 ) { |
||
| 537 | $imageCheckExtensions[] = "swc"; |
||
| 538 | } |
||
| 539 | if ( version_compare( $sCurrentVersion, "4.3.2" ) >= 0 ) { |
||
| 540 | $imageCheckExtensions[] = "jpc"; |
||
| 541 | $imageCheckExtensions[] = "jp2"; |
||
| 542 | $imageCheckExtensions[] = "jpx"; |
||
| 543 | $imageCheckExtensions[] = "jb2"; |
||
| 544 | $imageCheckExtensions[] = "xbm"; |
||
| 545 | $imageCheckExtensions[] = "wbmp"; |
||
| 546 | } |
||
| 547 | } |
||
| 548 | |||
| 549 | if ( !in_array( $extension, $imageCheckExtensions ) ) { |
||
| 550 | return true; |
||
| 551 | } |
||
| 552 | |||
| 553 | if ( @getimagesize( $filePath ) === false ) { |
||
| 554 | return false ; |
||
| 555 | } |
||
| 556 | |||
| 557 | return true; |
||
| 558 | } |
||
| 559 | |||
| 560 | /** |
||
| 561 | * Returns true if directory is not empty |
||
| 562 | * |
||
| 563 | * @access public |
||
| 564 | * @static |
||
| 565 | * @param string $serverPath |
||
| 566 | * @return boolean |
||
| 567 | */ |
||
| 568 | function hasChildren($serverPath) |
||
| 569 | { |
||
| 570 | if (!is_dir($serverPath) || (false === $fh = @opendir($serverPath))) { |
||
| 571 | return false; |
||
| 572 | } |
||
| 573 | |||
| 574 | $hasChildren = false; |
||
| 575 | while (false !== ($filename = readdir($fh))) { |
||
| 576 | if ($filename == '.' || $filename == '..') { |
||
| 577 | continue; |
||
| 578 | } else if (is_dir($serverPath . DIRECTORY_SEPARATOR . $filename)) { |
||
| 579 | //we have found valid directory |
||
| 580 | $hasChildren = true; |
||
| 581 | break; |
||
| 582 | } |
||
| 583 | } |
||
| 584 | |||
| 585 | closedir($fh); |
||
| 586 | |||
| 587 | return $hasChildren; |
||
| 588 | } |
||
| 589 | } |
||
| 590 |