| Total Complexity | 46 |
| Total Lines | 326 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like WideImage 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.
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 WideImage, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 38 | class WideImage |
||
| 39 | { |
||
| 40 | const SIDE_TOP_LEFT = 1; |
||
| 41 | const SIDE_TOP = 2; |
||
| 42 | const SIDE_TOP_RIGHT = 4; |
||
| 43 | const SIDE_RIGHT = 8; |
||
| 44 | const SIDE_BOTTOM_RIGHT = 16; |
||
| 45 | const SIDE_BOTTOM = 32; |
||
| 46 | const SIDE_BOTTOM_LEFT = 64; |
||
| 47 | const SIDE_LEFT = 128; |
||
| 48 | const SIDE_ALL = 255; |
||
| 49 | |||
| 50 | /** |
||
| 51 | * @var string Path to the library base directory |
||
| 52 | */ |
||
| 53 | protected static $path = null; |
||
| 54 | |||
| 55 | /** |
||
| 56 | * Returns the library version |
||
| 57 | * @return string The library version |
||
| 58 | */ |
||
| 59 | public static function version() |
||
| 60 | { |
||
| 61 | return '##DEV##'; |
||
| 62 | } |
||
| 63 | |||
| 64 | /** |
||
| 65 | * Returns the path to the library |
||
| 66 | * @return string |
||
| 67 | */ |
||
| 68 | public static function path() |
||
| 69 | { |
||
| 70 | if (static::$path === null) { |
||
|
|
|||
| 71 | static::$path = __DIR__ . DIRECTORY_SEPARATOR; |
||
| 72 | } |
||
| 73 | |||
| 74 | return static::$path; |
||
| 75 | } |
||
| 76 | |||
| 77 | /** |
||
| 78 | * Checks whether the gd library is loaded, and throws an exception otherwise |
||
| 79 | */ |
||
| 80 | public static function checkGD() |
||
| 81 | { |
||
| 82 | if (!extension_loaded('gd')) { |
||
| 83 | throw new Exception("WideImage requires the GD extension, but it's apparently not loaded."); |
||
| 84 | } |
||
| 85 | } |
||
| 86 | |||
| 87 | /** |
||
| 88 | * Registers a custom mapper for image loading and saving |
||
| 89 | * |
||
| 90 | * Example: |
||
| 91 | * <code> |
||
| 92 | * \WideImage\WideImage::registerCustomMapper('\\WideImage\\Mapper\\TGA', 'image/tga', 'tga'); |
||
| 93 | * </code> |
||
| 94 | * |
||
| 95 | * @param string $mapper_class_name |
||
| 96 | * @param string $mime_type |
||
| 97 | * @param string $extension |
||
| 98 | */ |
||
| 99 | public static function registerCustomMapper($mapper_class_name, $mime_type, $extension) |
||
| 100 | { |
||
| 101 | MapperFactory::registerMapper($mapper_class_name, $mime_type, strtoupper($extension)); |
||
| 102 | } |
||
| 103 | |||
| 104 | /** |
||
| 105 | * Loads an image from a file, URL, HTML input file field, binary string, or a valid image handle. |
||
| 106 | * The image format is auto-detected. |
||
| 107 | * |
||
| 108 | * Currently supported formats: PNG, GIF, JPG, BMP, TGA, GD, GD2. |
||
| 109 | * |
||
| 110 | * This function analyzes the input and decides whether to use WideImage::loadFromHandle(), |
||
| 111 | * WideImage::loadFromFile(), WideImage::loadFromUpload() or WideImage::loadFromString(), |
||
| 112 | * all of which you can also call directly to spare WideImage some guessing. |
||
| 113 | * |
||
| 114 | * Arrays are supported for upload fields; it returns an array of loaded images. |
||
| 115 | * To load only a single image from an array field, use WideImage::loadFromUpload('img', $i), |
||
| 116 | * where $i is the index of the image you want to load. |
||
| 117 | * |
||
| 118 | * <code> |
||
| 119 | * $img = WideImage::load('http://url/image.png'); // image URL |
||
| 120 | * $img = WideImage::load('/path/to/image.png'); // local file path |
||
| 121 | * $img = WideImage::load('img'); // upload field name |
||
| 122 | * $img = WideImage::load(imagecreatetruecolor(10, 10)); // a GD resource |
||
| 123 | * $img = WideImage::load($image_data); // binary string containing image data |
||
| 124 | * </code> |
||
| 125 | * |
||
| 126 | * @param mixed $source File name, url, HTML file input field name, binary string, or a GD image resource |
||
| 127 | * @return \WideImage\Image|\WideImage\PaletteImage|\WideImage\TrueColorImage |
||
| 128 | */ |
||
| 129 | public static function load($source) |
||
| 130 | { |
||
| 131 | $predictedSourceType = ''; |
||
| 132 | |||
| 133 | if ($source == '') { |
||
| 134 | $predictedSourceType = 'String'; |
||
| 135 | } |
||
| 136 | |||
| 137 | // Creating image via a valid resource |
||
| 138 | if (!$predictedSourceType && static::isValidImageHandle($source)) { |
||
| 139 | $predictedSourceType = 'Handle'; |
||
| 140 | } |
||
| 141 | |||
| 142 | // Check for binary string |
||
| 143 | if (!$predictedSourceType) { |
||
| 144 | // search first $binLength bytes (at a maximum) for ord<32 characters (binary image data) |
||
| 145 | $binLength = 64; |
||
| 146 | $sourceLength = strlen($source); |
||
| 147 | $maxlen = ($sourceLength > $binLength) ? $binLength : $sourceLength; |
||
| 148 | |||
| 149 | for ($i = 0; $i < $maxlen; $i++) { |
||
| 150 | if (ord($source[$i]) < 32) { |
||
| 151 | $predictedSourceType = 'String'; |
||
| 152 | break; |
||
| 153 | } |
||
| 154 | } |
||
| 155 | } |
||
| 156 | |||
| 157 | // Uploaded image (array uploads not supported) |
||
| 158 | if (isset($_FILES[$source]) && isset($_FILES[$source]['tmp_name'])) { |
||
| 159 | $predictedSourceType = 'Upload'; |
||
| 160 | } |
||
| 161 | |||
| 162 | // Otherwise, must be a file or an URL |
||
| 163 | if (!$predictedSourceType) { |
||
| 164 | $predictedSourceType = 'File'; |
||
| 165 | } |
||
| 166 | |||
| 167 | return call_user_func(array(__CLASS__, 'loadFrom' . $predictedSourceType), $source); |
||
| 168 | } |
||
| 169 | |||
| 170 | /** |
||
| 171 | * Create and load an image from a file or URL. The image format is auto-detected. |
||
| 172 | * |
||
| 173 | * @param string $uri File or url |
||
| 174 | * @return \WideImage\Image|\WideImage\PaletteImage|\WideImage\TrueColorImage |
||
| 175 | */ |
||
| 176 | public static function loadFromFile($uri) |
||
| 177 | { |
||
| 178 | $data = file_get_contents($uri); |
||
| 179 | $handle = @imagecreatefromstring($data); |
||
| 180 | |||
| 181 | if (!static::isValidImageHandle($handle)) { |
||
| 182 | try { |
||
| 183 | // try to find a mapper first |
||
| 184 | $mapper = MapperFactory::selectMapper($uri); |
||
| 185 | |||
| 186 | if ($mapper) { |
||
| 187 | $handle = $mapper->load($uri); |
||
| 188 | } |
||
| 189 | } catch (UnsupportedFormatException $e) { |
||
| 190 | // mapper not found |
||
| 191 | } |
||
| 192 | |||
| 193 | // try all custom mappers |
||
| 194 | if (!static::isValidImageHandle($handle)) { |
||
| 195 | $custom_mappers = MapperFactory::getCustomMappers(); |
||
| 196 | |||
| 197 | foreach ($custom_mappers as $mime_type => $mapper_class) { |
||
| 198 | $mapper = MapperFactory::selectMapper(null, $mime_type); |
||
| 199 | $handle = $mapper->loadFromString($data); |
||
| 200 | |||
| 201 | if (static::isValidImageHandle($handle)) { |
||
| 202 | break; |
||
| 203 | } |
||
| 204 | } |
||
| 205 | } |
||
| 206 | } |
||
| 207 | |||
| 208 | if (!static::isValidImageHandle($handle)) { |
||
| 209 | throw new InvalidImageSourceException("File '{$uri}' appears to be an invalid image source."); |
||
| 210 | } |
||
| 211 | |||
| 212 | return static::loadFromHandle($handle); |
||
| 213 | } |
||
| 214 | |||
| 215 | /** |
||
| 216 | * Create and load an image from a string. Format is auto-detected. |
||
| 217 | * |
||
| 218 | * @param string $string Binary data, i.e. from BLOB field in the database |
||
| 219 | * @return \WideImage\Image|\WideImage\PaletteImage|\WideImage\TrueColorImage |
||
| 220 | */ |
||
| 221 | public static function loadFromString($string) |
||
| 247 | } |
||
| 248 | |||
| 249 | /** |
||
| 250 | * Create and load an image from an image handle. |
||
| 251 | * |
||
| 252 | * <b>Note:</b> the resulting image object takes ownership of the passed |
||
| 253 | * handle. When the newly-created image object is destroyed, the handle is |
||
| 254 | * destroyed too, so it's not a valid image handle anymore. In order to |
||
| 255 | * preserve the handle for use after object destruction, you have to call |
||
| 256 | * \WideImage\Image::releaseHandle() on the created image instance prior to its |
||
| 257 | * destruction. |
||
| 258 | * |
||
| 259 | * <code> |
||
| 260 | * $handle = imagecreatefrompng('file.png'); |
||
| 261 | * $image = WideImage::loadFromHandle($handle); |
||
| 262 | * </code> |
||
| 263 | * |
||
| 264 | * @param resource $handle A valid GD image resource |
||
| 265 | * @return \WideImage\Image|\WideImage\PaletteImage|\WideImage\TrueColorImage |
||
| 266 | */ |
||
| 267 | public static function loadFromHandle($handle) |
||
| 278 | } |
||
| 279 | |||
| 280 | /** |
||
| 281 | * This method loads a file from the $_FILES array. The image format is auto-detected. |
||
| 282 | * |
||
| 283 | * You only have to pass the field name as the parameter. For array fields, this function will |
||
| 284 | * return an array of image objects, unless you specify the $index parameter, which will |
||
| 285 | * load the desired image. |
||
| 286 | * |
||
| 287 | * @param $field_name Name of the key in $_FILES array |
||
| 288 | * @param int $index The index of the file to load (if the input field is an array) |
||
| 289 | * @return \WideImage\Image The loaded image |
||
| 290 | */ |
||
| 291 | public static function loadFromUpload($field_name, $index = null) |
||
| 292 | { |
||
| 293 | if (!array_key_exists($field_name, $_FILES)) { |
||
| 294 | throw new InvalidImageSourceException("Upload field '{$field_name}' doesn't exist."); |
||
| 295 | } |
||
| 296 | |||
| 297 | if (is_array($_FILES[$field_name]['tmp_name'])) { |
||
| 298 | if (isset($_FILES[$field_name]['tmp_name'][$index])) { |
||
| 299 | $filename = $_FILES[$field_name]['tmp_name'][$index]; |
||
| 300 | } else { |
||
| 301 | $result = array(); |
||
| 302 | |||
| 303 | foreach ($_FILES[$field_name]['tmp_name'] as $idx => $tmp_name) { |
||
| 304 | $result[$idx] = static::loadFromFile($tmp_name); |
||
| 305 | } |
||
| 306 | |||
| 307 | return $result; |
||
| 308 | } |
||
| 309 | } else { |
||
| 310 | $filename = $_FILES[$field_name]['tmp_name']; |
||
| 311 | } |
||
| 312 | |||
| 313 | if (!file_exists($filename)) { |
||
| 314 | throw new InvalidImageSourceException("Uploaded file doesn't exist."); |
||
| 315 | } |
||
| 316 | |||
| 317 | return static::loadFromFile($filename); |
||
| 318 | } |
||
| 319 | |||
| 320 | /** |
||
| 321 | * Factory method for creating a palette image |
||
| 322 | * |
||
| 323 | * @param int $width |
||
| 324 | * @param int $height |
||
| 325 | * @return \WideImage\PaletteImage |
||
| 326 | */ |
||
| 327 | public static function createPaletteImage($width, $height) |
||
| 328 | { |
||
| 329 | return PaletteImage::create($width, $height); |
||
| 330 | } |
||
| 331 | |||
| 332 | /** |
||
| 333 | * Factory method for creating a true-color image |
||
| 334 | * |
||
| 335 | * @param int $width |
||
| 336 | * @param int $height |
||
| 337 | * @return \WideImage\TrueColorImage |
||
| 338 | */ |
||
| 339 | public static function createTrueColorImage($width, $height) |
||
| 342 | } |
||
| 343 | |||
| 344 | /** |
||
| 345 | * Check whether the given handle is a valid GD resource |
||
| 346 | * |
||
| 347 | * @param mixed $handle The variable to check |
||
| 348 | * @return bool |
||
| 349 | */ |
||
| 350 | public static function isValidImageHandle($handle) |
||
| 353 | } |
||
| 354 | |||
| 355 | /** |
||
| 356 | * Throws exception if the handle isn't a valid GD resource |
||
| 357 | * |
||
| 358 | * @param mixed $handle The variable to check |
||
| 359 | */ |
||
| 360 | public static function assertValidImageHandle($handle) |
||
| 364 | } |
||
| 365 | } |
||
| 366 | } |
||
| 372 |