OSDN Git Service

MERGE: リビジョン1870。Media/MediaObjectクラスの機能拡張
[nucleus-jp/nucleus-next.git] / nucleus / libs / MEDIA.php
1 <?php\r
2 /*\r
3  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)\r
4  * Copyright (C) 2002-2012 The Nucleus Group\r
5  *\r
6  * This program is free software; you can redistribute it and/or\r
7  * modify it under the terms of the GNU General Public License\r
8  * as published by the Free Software Foundation; either version 2\r
9  * of the License, or (at your option) any later version.\r
10  * (see nucleus/documentation/index.html#license for more info)\r
11  */\r
12 /**\r
13  * Media classes for nucleus\r
14  *\r
15  * @license http://nucleuscms.org/license.txt GNU General Public License\r
16  * @copyright Copyright (C) 2002-2012 The Nucleus Group\r
17  * @version $Id: MEDIA.php 1870 2012-05-22 14:57:15Z sakamocchi $\r
18  */\r
19 \r
20 define('PRIVATE_COLLECTION',            'Private Collection');\r
21 define('READ_ONLY_MEDIA_FOLDER',        '(Read Only)');\r
22 \r
23 class Media\r
24 {\r
25         static public $thumbdir = '.thumb';\r
26         static public $algorism = 'md5';\r
27         static public $image_mime = array(\r
28                 'image/jpeg'    => '.jpeg',\r
29                 'image/png'             => '.png',\r
30                 'image/gif'             => '.gif',\r
31         );\r
32         \r
33         /**\r
34          * Media::getCollectionList()\r
35          * Gets the list of collections available to the currently logged\r
36          * in member\r
37          * \r
38          * @param       boolean $exceptReadOnly\r
39          * @return array        dirname => display name\r
40          */\r
41         static public function getCollectionList($exceptReadOnly = FALSE)\r
42         {\r
43                 global $member, $DIR_MEDIA;\r
44                 \r
45                 $collections = array();\r
46                 \r
47                 // add private directory for member\r
48                 $collections[$member->getID()] = PRIVATE_COLLECTION;\r
49                 \r
50                 // add global collections\r
51                 if ( !is_dir($DIR_MEDIA) )\r
52                 {\r
53                         return $collections;\r
54                 }\r
55                 \r
56                 $dirhandle = opendir($DIR_MEDIA);\r
57                 while ( $dirname = readdir($dirhandle) )\r
58                 {\r
59                         // only add non-numeric (numeric=private) dirs\r
60                         if ( @is_dir($DIR_MEDIA . $dirname) &&\r
61                                 ($dirname != '.') &&\r
62                                 ($dirname != '..') &&\r
63                                 ($dirname != self::$thumbdir) &&\r
64                                 (!is_numeric($dirname)) )\r
65                                 {\r
66                                 if ( @is_writable($DIR_MEDIA . $dirname) )\r
67                                 {\r
68                                         $collections[$dirname] = $dirname;\r
69                                 }\r
70                                 else if ( $exceptReadOnly == FALSE )\r
71                                 {\r
72                                         $collections[$dirname] = $dirname . ' ' . READ_ONLY_MEDIA_FOLDER;\r
73                                 }\r
74                         }\r
75                 }\r
76                 closedir($dirhandle);\r
77                 \r
78                 return $collections;\r
79         }\r
80         \r
81         /**\r
82          * Media::getMediaListByCollection()\r
83          * Returns an array of MediaObject objects for a certain collection\r
84          *\r
85          * @param       string  $collection     name of the collection\r
86          * @param       string  $filter         filter on filename (defaults to none)\r
87          * @return      void\r
88          */\r
89         static public function getMediaListByCollection($collection, $filter = '')\r
90         {\r
91                 global $CONF, $DIR_MEDIA;\r
92                 \r
93                 $filelist = array();\r
94                 \r
95                 // 1. go through all objects and add them to the filelist\r
96                 $mediadir = $DIR_MEDIA . $collection . '/';\r
97                 \r
98                 // return if dir does not exist\r
99                 if ( !is_dir($mediadir) )\r
100                 {\r
101                         return $filelist;\r
102                 }\r
103                 \r
104                 $dirhandle = opendir($mediadir);\r
105                 while ( $filename = readdir($dirhandle) )\r
106                 {\r
107                         // only add files that match the filter\r
108                         if ( !is_dir($mediadir . $filename) && self::checkFilter($filename, $filter) )\r
109                         {\r
110                                 array_push($filelist, new MediaObject($collection, $filename, $DIR_MEDIA));\r
111                         }\r
112                 }\r
113                 closedir($dirhandle);\r
114                 \r
115                 /* sort array */\r
116                 if ( !$CONF['MediaPrefix'] )\r
117                 {\r
118                         usort($filelist,  array(__CLASS__, 'sort_media_by_timestamp'));\r
119                 }\r
120                 else\r
121                 {\r
122                         usort($filelist,  array(__CLASS__, 'sort_media_by_filename'));\r
123                 }\r
124                 \r
125                 return $filelist;\r
126         }\r
127         \r
128         /**\r
129          * Media::checkFilter()\r
130          * \r
131          * @param       string  $strText\r
132          * @param       string  $strFilter\r
133          * @return      boolean\r
134          */\r
135         static public function checkFilter($strText, $strFilter)\r
136         {\r
137                 if ( $strFilter == '' )\r
138                 {\r
139                         return 1;\r
140                 }\r
141                 else\r
142                 {\r
143                         return is_integer(i18n::strpos(strtolower($strText), strtolower($strFilter)));\r
144                 }\r
145         }\r
146         \r
147         /**\r
148          * Media::isValidCollection()\r
149          * checks if a collection exists with the given name, and if it's\r
150          * allowed for the currently logged in member to upload files to it\r
151          * \r
152          * @param       string  $collectionName\r
153          * @param       string  $exceptReadOnly\r
154          * @return      boolean\r
155          */\r
156         static public function isValidCollection($collectionName, $exceptReadOnly = FALSE)\r
157         {\r
158                 global $member, $DIR_MEDIA;\r
159                 \r
160                 // allow creating new private directory\r
161                 if ( $collectionName === (string)$member->getID() )\r
162                 {\r
163                         return TRUE;\r
164                 }\r
165                 \r
166                 $collections = self::getCollectionList($exceptReadOnly);\r
167                 $dirname = $collections[$collectionName];\r
168                 \r
169                 if ( $dirname == NULL || $dirname === PRIVATE_COLLECTION )\r
170                 {\r
171                         return FALSE;\r
172                 }\r
173                 \r
174                 // other collections should exist and be writable\r
175                 $collectionDir = $DIR_MEDIA . $collectionName;\r
176                 if ( $exceptReadOnly )\r
177                 {\r
178                         return ( @is_dir($collectionDir) && @is_writable($collectionDir) );\r
179                 }\r
180                 \r
181                 // other collections should exist\r
182                 return @is_dir($collectionDir);\r
183         }\r
184         \r
185         /**\r
186          * Media::addMediaObject()\r
187          * Adds an uploaded file to the media archive\r
188          *\r
189          * @param       string  $collection     collection\r
190          * @param       array   $uploadfile     the postFileInfo(..) array\r
191          * @param       string  $filename       the filename that should be used to save the file as\r
192          *                                                              (date prefix should be already added here)\r
193          * @return      string  blank if success, message if failed\r
194          */\r
195         static public function addMediaObject($collection, $uploadfile, $filename)\r
196         {\r
197                 global $DIR_MEDIA, $manager;\r
198                 \r
199                 // clean filename of characters that may cause trouble in a filename using cleanFileName() function from globalfunctions.php\r
200                 $filename = cleanFileName($filename);\r
201                 \r
202                 // should already have tested for allowable types before calling this method. This will only catch files with no extension at all\r
203                 if ( $filename === FALSE )\r
204                 {\r
205                         return _ERROR_BADFILETYPE;\r
206                 }\r
207                 \r
208                 // trigger PreMediaUpload event\r
209                 $manager->notify('PreMediaUpload',array('collection' => &$collection, 'uploadfile' => $uploadfile, 'filename' => &$filename));\r
210                 \r
211                 // don't allow uploads to unknown or forbidden collections\r
212                 $exceptReadOnly = TRUE;\r
213                 if ( !self::isValidCollection($collection,$exceptReadOnly) )\r
214                 {\r
215                         return _ERROR_DISALLOWED;\r
216                 }\r
217                 \r
218                 // check dir permissions (try to create dir if it does not exist)\r
219                 $mediadir = $DIR_MEDIA . $collection;\r
220                 \r
221                 // try to create new private media directories if needed\r
222                 if ( !@is_dir($mediadir) && is_numeric($collection) )\r
223                 {\r
224                         $oldumask = umask(0000);\r
225                         if ( !@mkdir($mediadir, 0777) )\r
226                         {\r
227                                 return _ERROR_BADPERMISSIONS;\r
228                         }\r
229                         umask($oldumask);\r
230                 }\r
231                 \r
232                 // if dir still not exists, the action is disallowed\r
233                 if ( !@is_dir($mediadir) )\r
234                 {\r
235                         return _ERROR_DISALLOWED;\r
236                 }\r
237                 \r
238                 if ( !is_writeable($mediadir) )\r
239                 {\r
240                         return _ERROR_BADPERMISSIONS;\r
241                 }\r
242                 \r
243                 // add trailing slash (don't add it earlier since it causes mkdir to fail on some systems)\r
244                 $mediadir .= '/';\r
245                 \r
246                 if ( file_exists($mediadir . $filename) )\r
247                 {\r
248                         return _ERROR_UPLOADDUPLICATE;\r
249                 }\r
250                 \r
251                 // move file to directory\r
252                 if ( is_uploaded_file($uploadfile) )\r
253                 {\r
254                         if ( !@move_uploaded_file($uploadfile, $mediadir . $filename) )\r
255                         {\r
256                                 return _ERROR_UPLOADMOVEP;\r
257                         }\r
258                 }\r
259                 else\r
260                 {\r
261                         if ( !copy($uploadfile, $mediadir . $filename) )\r
262                         {\r
263                                 return _ERROR_UPLOADCOPY ;\r
264                         }\r
265                 }\r
266                 \r
267                 // chmod uploaded file\r
268                 $oldumask = umask(0000);\r
269                 @chmod($mediadir . $filename, 0644);\r
270                 umask($oldumask);\r
271                 \r
272                 $manager->notify('PostMediaUpload',array('collection' => $collection, 'mediadir' => $mediadir, 'filename' => $filename));\r
273                 \r
274                 return '';\r
275         }\r
276         \r
277         /**\r
278          * Media::addMediaObjectRaw()\r
279          * Adds an uploaded file to the media dir.\r
280          * \r
281          * NOTE: does not check if $collection is valid.\r
282          * \r
283          * @param       string  $collection     collection to use\r
284          * @param       string  $filename       the filename that should be used to save the file\r
285          *                                                              as (date prefix should be already added here)\r
286          * @param       &$data  File data (binary)\r
287          * @return      string  blank if success, message if failed\r
288          */\r
289         static public function addMediaObjectRaw($collection, $filename, &$data)\r
290         {\r
291                 global $DIR_MEDIA;\r
292                 \r
293                 // check dir permissions (try to create dir if it does not exist)\r
294                 $mediadir = $DIR_MEDIA . $collection;\r
295                 \r
296                 // try to create new private media directories if needed\r
297                 if ( !@is_dir($mediadir) && is_numeric($collection) )\r
298                 {\r
299                         $oldumask = umask(0000);\r
300                         if ( !@mkdir($mediadir, 0777) )\r
301                         {\r
302                                 return _ERROR_BADPERMISSIONS;\r
303                         }\r
304                         umask($oldumask);\r
305                 }\r
306                 \r
307                 // if dir still not exists, the action is disallowed\r
308                 if ( !@is_dir($mediadir) )\r
309                 {\r
310                         return _ERROR_DISALLOWED;\r
311                 }\r
312                 \r
313                 if ( !is_writeable($mediadir) )\r
314                 {\r
315                         return _ERROR_BADPERMISSIONS;\r
316                 }\r
317                 \r
318                 // add trailing slash (don't add it earlier since it causes mkdir to fail on some systems)\r
319                 $mediadir .= '/';\r
320                 \r
321                 if ( file_exists($mediadir . $filename) )\r
322                 {\r
323                         return _ERROR_UPLOADDUPLICATE;\r
324                 }\r
325                 \r
326                 // create file\r
327                 $fh = @fopen($mediadir . $filename, 'wb');\r
328                 if ( !$fh )\r
329                 {\r
330                         return _ERROR_UPLOADFAILED;\r
331                 }\r
332                 $ok = @fwrite($fh, $data);\r
333                 @fclose($fh);\r
334                 if ( !$ok )\r
335                 {\r
336                         return _ERROR_UPLOADFAILED;\r
337                 }\r
338                 \r
339                 // chmod uploaded file\r
340                 $oldumask = umask(0000);\r
341                 @chmod($mediadir . $filename, 0644);\r
342                 umask($oldumask);\r
343                 \r
344                 return '';\r
345         }\r
346         \r
347         /**\r
348          * Media::responseResampledImage()\r
349          * send resampled image via HTTP\r
350          * \r
351          * @param       object  $medium         Medium Object\r
352          * @exit\r
353          */\r
354         static public function responseResampledImage($medium, $maxwidth=0, $maxheight=0)\r
355         {\r
356                 if ( get_class($medium) !== 'Medium' )\r
357                 {\r
358                         header("HTTP/1.1 500 Internal Server Error");\r
359                         exit('Nucleus CMS: Fail to generate resampled image');\r
360                         return;\r
361                 }\r
362                 \r
363                 $resampledimage = $medium->getResampledBinary($maxwidth, $maxheight);\r
364                 if ( $resampledimage === FALSE )\r
365                 {\r
366                         unset($resampledimage);\r
367                         header("HTTP/1.1 503 Service Unavailable");\r
368                         exit('Nucleus CMS: Fail to generate resampled image');\r
369                         return;\r
370                 }\r
371                 \r
372                 header("Content-type: {$medium->mime}");\r
373                 echo $resampledimage;\r
374                 \r
375                 unset($resampledimage);\r
376                 \r
377                 exit;\r
378         }\r
379         \r
380         /**\r
381          * Media::storeResampledImage()\r
382          * Store resampled image binary to filesystem as file\r
383          * \r
384          * @param       object  $medium         medium Object\r
385          * @param       integer $maxwidth       maximum width\r
386          * @param       integer $maxheight      maximum height\r
387          * @param       string  $path           directory path for destination\r
388          * @param       string  $name           file name for destination\r
389          * @return      boolean\r
390          */\r
391         static public function storeResampledImage($medium, $maxwidth=0, $maxheight=0, $path='', $name='')\r
392         {\r
393                 global $DIR_MEDIA;\r
394                 \r
395                 if ( get_class($medium) !== 'Medium' )\r
396                 {\r
397                         return FALSE;\r
398                 }\r
399                 \r
400                 if ( $path !== '' )\r
401                 {\r
402                         $path = realpath($path);\r
403                         if ( !file_exists($path)\r
404                           || strpos($path, $DIR_MEDIA) !== 0 )\r
405                         {\r
406                                 return FALSE;\r
407                         }\r
408                 }\r
409                 else\r
410                 {\r
411                         $path = '$DIR_MEDIA/' . self::$thumbdir;\r
412                 }\r
413                 \r
414                 if ( $name === '' )\r
415                 {\r
416                         $name = $medium->getHashedname();\r
417                 }\r
418                 \r
419                 $resampledimage = $medium->getResampledBinary($maxwidth, $maxheight);\r
420                 if ( !$resampledimage )\r
421                 {\r
422                         unset($resampledimage);\r
423                         return FALSE;\r
424                 }\r
425                 \r
426                 $handle = @fopen("{$path}/{$name}", 'w');\r
427                 if ( !$handle )\r
428                 {\r
429                         unset ($resampledimage);\r
430                         return FALSE;\r
431                 }\r
432                 \r
433                 if ( !@fwrite($handle, $resampledimage) )\r
434                 {\r
435                         unset($resampledimage);\r
436                         @unlink("{$path}/{$name}");\r
437                         return FALSE;\r
438                 }\r
439                 \r
440                 unset($resampledimage);\r
441                 fclose($handle);\r
442                 \r
443                 if ( !@chmod("{$path}/{$name}", 0774) )\r
444                 {\r
445                         @unlink("{$path}/{$name}");\r
446                         return FALSE;\r
447                 }\r
448                 \r
449                 return TRUE;\r
450         }\r
451         \r
452         /**\r
453          * Media::sort_media_by_timestamp()\r
454          * User-defined sort method to sort an array of MediaObjects\r
455          * \r
456          * @param       object  $a\r
457          * @param       object  $b\r
458          * @return      boolean\r
459          */\r
460         static private function sort_media_by_timestamp($a, $b)\r
461         {\r
462                 if ($a->timestamp == $b->timestamp) return 0;\r
463                 return ($a->timestamp > $b->timestamp) ? -1 : 1;\r
464         }\r
465         \r
466         /**\r
467          * Media::sort_media_by_filename()\r
468          * User-defined sort method to sort an array of MediaObjects\r
469          * \r
470          * @param       object  $a\r
471          * @param       object  $b\r
472          * @return      boolean\r
473          */\r
474         static private function sort_media_by_filename($a, $b)\r
475         {\r
476                 if ($a->filename == $b->filename) return 0;\r
477                 return ($a->filename > $b->filename) ? -1 : 1;\r
478         }\r
479 }\r
480 \r
481 class MediaObject\r
482 {\r
483         public $mime = '';\r
484         \r
485         public $root = '';\r
486         public $path = '';\r
487         public $private;\r
488         public $collection;\r
489         public $filename = '';\r
490         \r
491         public $prefix = '';\r
492         public $name = '';\r
493         public $suffix = '';\r
494         \r
495         public $timestamp = 0;\r
496         public $size = 0;\r
497         \r
498         public $width = 0;\r
499         public $height = 0;\r
500         public $resampledwidth = 0;\r
501         public $resampledheight = 0;\r
502         \r
503         /**\r
504          * MediaObject::__construct()\r
505          * \r
506          * @param       string          $collection     \r
507          * @param       string          $filename       \r
508          * @param       string          $root           fullpath to media directory\r
509          */\r
510         public function __construct($collection, $filename, $root=0)\r
511         {\r
512                 global $CONF, $DIR_MEDIA;\r
513                 \r
514                 /* for backward compatibility */\r
515                 if ( is_numeric($root) )\r
516                 {\r
517                         $root = $DIR_MEDIA;\r
518                 }\r
519                 \r
520                 $root = preg_replace('#/*$#', '', $root);\r
521                 \r
522                 /* get and validate fullpath for the medium */\r
523                 if ( !file_exists($root)\r
524                   || FALSE === ($fullpath = realpath("{$root}/{$collection}/{$filename}"))\r
525                   || strpos($fullpath, $root) !== 0\r
526                   || !file_exists($fullpath) )\r
527                 {\r
528                         return FALSE;\r
529                 }\r
530                 \r
531                 /* store fundamentals */\r
532                 $this->root = $root;\r
533                 $this->private = (integer) $collection;\r
534                 $this->collection = $collection;\r
535                 $this->filename = basename($fullpath);\r
536                 $this->timestamp = filemtime($fullpath);\r
537                 \r
538                 /* store relative directory path from root directory for media */\r
539                 $this->path = preg_replace(array("#{$this->root}/#", "#/{$this->filename}#"), '', $fullpath);\r
540                 if ( $this->path === $this->name )\r
541                 {\r
542                         $this->path = ''; \r
543                 }\r
544                 \r
545                 return;\r
546         }\r
547         \r
548         /**\r
549          * MediaObject::refine()\r
550          * refine data\r
551          * \r
552          * @param       void\r
553          * @return      void\r
554          */\r
555         public function refine()\r
556         {\r
557                 global $CONF;\r
558                 \r
559                 /* store size (byte order) */\r
560                 $this->size = filesize("{$this->root}/{$this->path}/{$this->filename}");\r
561                 \r
562                 /* get width and height if this is image binary */\r
563                 if ( FALSE === ($info = @getimagesize ("{$this->root}/{$this->path}/{$this->filename}")) )\r
564                 {\r
565                         $this->mime = 'application/octet-stream';\r
566                         $this->width = 0;\r
567                         $this->height = 0;\r
568                 }\r
569                 else\r
570                 {\r
571                         $this->mime = $info['mime'];\r
572                         $this->width = $info[0];\r
573                         $this->height = $info[1];\r
574                 }\r
575                 \r
576                 /* utilise Fileinfo subsystem if available */\r
577                 if ( defined('FILEINFO_MIME_TYPE') && function_exists ('finfo_open')\r
578                   && (FALSE !== ($info = finfo_open(FILEINFO_MIME_TYPE))) )\r
579                 {\r
580                         $this->mime = finfo_file($info, "{$this->root}/{$this->path}/{$this->filename}");\r
581                 }\r
582                 \r
583                 /* store data with parsed filename */\r
584                 if ( preg_match('#^(.*)\.([a-zA-Z0-9]{2,})$#', $this->filename, $info) === 1 )\r
585                 {\r
586                         $this->name = $info[1];\r
587                         $this->suffix = $info[2];\r
588                         \r
589                         if ( $CONF['MediaPrefix'] && preg_match('#^([0-9]{8})\-(.*)$#', $this->name, $info) == 1 )\r
590                         {\r
591                                 $this->prefix = preg_replace('#^([0-9]{4})([0-9]{2})([0-9]{2})$#', '$1/$2/$3', $info[1]);\r
592                                 $this->name = $info[2];\r
593                         }\r
594                 }\r
595                 \r
596                 return;\r
597         }\r
598         \r
599         /**\r
600          * MediaObject::setResampledSize()\r
601          * Set resampled size\r
602          * \r
603          * @param       integer $maxwidth\r
604          * @param       integer $maxheight\r
605          * @return      boolean\r
606          */\r
607         public function setResampledSize($maxwidth=0, $maxheight=0)\r
608         {\r
609                 if ( ($maxwidth == 0) && ($maxheight == 0) )\r
610                 {\r
611                         return FALSE;\r
612                 }\r
613                 else if ( $this->width == 0 || $this->height  == 0 )\r
614                 {\r
615                         return FALSE;\r
616                 }\r
617                 else if ($this->width < $maxwidth && $this->height < $maxheight )\r
618                 {\r
619                         $this->resampledwidth = $this->width;\r
620                         $this->resampledheight = $this->height;\r
621                 }\r
622                 else if ( $maxheight == 0 || $this->width > $this->height )\r
623                 {\r
624                         $this->resampledheight = intval ($this->height * $maxwidth / $this->width);\r
625                         $this->resampledwidth = $maxwidth;\r
626                 }\r
627                 else if ( $maxwidth == 0 || $this->width <= $this->height )\r
628                 {\r
629                         $this->resampledwidth = intval ($this->width * $maxheight / $this->height);\r
630                         $this->resampledheight = $maxheight;\r
631                 }\r
632                 return TRUE;\r
633         }\r
634         \r
635         /**\r
636          * MediaObject::getResampledBinary()\r
637          * Return resampled image binary\r
638          * \r
639          * @param       void\r
640          * @return      mixed   binary if success, FALSE if failed\r
641          */\r
642         public function getResampledBinary($maxwidth=0, $maxheight=0)\r
643         {\r
644                 static $gdinfo = array();\r
645                 static $original;\r
646                 static $resampledimage;\r
647                 \r
648                 if ( !$this->setResampledSize($maxwidth, $maxheight) )\r
649                 {\r
650                         return FALSE;\r
651                 }\r
652                 \r
653                 if ( $gdinfo = array() )\r
654                 {\r
655                         $gdinfo = gd_info();\r
656                 }\r
657                 \r
658                 if ( $this->path !== '' )\r
659                 {\r
660                         $fullpath = "{$this->root}/{$this->path}/{$this->name}";\r
661                 }\r
662                 else\r
663                 {\r
664                         $fullpath = "{$this->root}/{$this->name}";\r
665                 }\r
666                 if ( !file_exists($fullpath) )\r
667                 {\r
668                         return FALSE;\r
669                 }\r
670                 \r
671                 if ( !array_key_exists($this->mime, Media::$image_mime)\r
672                   || $this->width == 0\r
673                   || $this->height == 0\r
674                   || $this->resampledwidth == 0\r
675                   || $this->resampledheight == 0 )\r
676                 {\r
677                         return FALSE;\r
678                 }\r
679                 \r
680                 /* check current available memory */\r
681                 $memorymax = trim(ini_get("memory_limit"));\r
682                 switch ( strtolower ($memorymax[strlen($memorymax)-1]) )\r
683                 {\r
684                         case 'g':\r
685                                 $memorymax *= 1024;\r
686                         case 'm':\r
687                                 $memorymax *= 1024;\r
688                         case 'k':\r
689                                 $memorymax *= 1024;\r
690                 }\r
691                 \r
692                 /*\r
693                  * this code is based on analyze if gd.c in php source code\r
694                  * if you can read C/C++, please check these elements and notify us if you have some ideas\r
695                  */\r
696                 if ( (memory_get_usage()\r
697                    + ($this->resampledwidth * $this->resampledheight * 5 + $this->resampledheight * 24 + 10000)\r
698                    + ($this->width * $this->height * 5 + $this->height * 24 + 10000))\r
699                   > $memorymax )\r
700                 {\r
701                         return FALSE;\r
702                 }\r
703                 \r
704                 switch ( $this->mime )\r
705                 {\r
706                         case 'image/gif':\r
707                                 if ( (!array_key_exists('GIF Read Support', $gdinfo) || !isset($gdinfo['GIF Read Support']))\r
708                                   || (!array_key_exists('GIF Create Support', $gdinfo) || !isset($gdinfo['GIF Create Support'])) )\r
709                                 {\r
710                                         return FALSE;\r
711                                 }\r
712                                 $function = 'imagecreatefromgif';\r
713                                 break;\r
714                         case 'image/jpeg':\r
715                                 if ( (!array_key_exists('JPEG Support', $gdinfo) || !isset($gdinfo['JPEG Support']))\r
716                                   && (!array_key_exists('JPG Support', $gdinfo) || !isset($gdinfo['JPG Support'])) )\r
717                                 {\r
718                                         return FALSE;\r
719                                 }\r
720                                 $function = 'imagecreatefromjpeg';\r
721                                 break;\r
722                         case 'image/png':\r
723                                 if ( !array_key_exists('PNG Support', $gdinfo) || !isset($gdinfo['PNG Support']) )\r
724                                 {\r
725                                         return FALSE;\r
726                                 }\r
727                                 $function = 'imagecreatefrompng';\r
728                                 break;\r
729                         default:\r
730                                 return FALSE;\r
731                 }\r
732                 \r
733                 if ( !is_callable($function) )\r
734                 {\r
735                         return FALSE;\r
736                 }\r
737                 \r
738                 $original = call_user_func_array($function, array(&$fullpath));\r
739                 if ( !$original )\r
740                 {\r
741                         return FALSE;\r
742                 }\r
743                 \r
744                 $resampledimage = imagecreatetruecolor($this->resampledwidth, $this->resampledheight);\r
745                 if ( !$resampledimage )\r
746                 {\r
747                         imagedestroy($original);\r
748                         return FALSE;\r
749                 }\r
750                 \r
751                 @set_time_limit(ini_get('max_execution_time'));\r
752                 if ( !ImageCopyResampled($resampledimage, $original, 0, 0, 0, 0, $this->resampledwidth, $this->resampledheight, $this->width, $this->height) )\r
753                 {\r
754                         return FALSE;\r
755                 }\r
756                 \r
757                 imagedestroy($original);\r
758                 \r
759                 ob_start();\r
760                 \r
761                 switch ( $this->mime )\r
762                 {\r
763                         case 'image/gif':\r
764                                 imagegif($resampledimage);\r
765                                 break;\r
766                         case 'image/jpeg':\r
767                                 imagejpeg($resampledimage);\r
768                                 break;\r
769                         case 'image/png':\r
770                                 imagepng($resampledimage);\r
771                                 break;\r
772                         case 'image/bmp':\r
773                         case 'image/x-ms-bmp':\r
774                                 imagepng($resampledimage);\r
775                                 break;\r
776                         default:\r
777                                 return FALSE;\r
778                 }\r
779                 \r
780                 imagedestroy($resampledimage);\r
781                 \r
782                 return ob_get_clean();\r
783         }\r
784         \r
785         public function getHashedName()\r
786         {\r
787                 return (string) hash(Media::$algorism, "{$this->path}/{$this->name}", FALSE);\r
788         }\r
789 }\r