source: releases/0.91beta/plugins/ImageManager/Classes/ImageManager.php

Last change on this file was 652, checked in by ray, 13 years ago

release 0.91beta with changed namespace

File size: 16.4 KB
Line 
1<?php
2/**
3 * ImageManager, list images, directories, and thumbnails.
4 * @author $Author: Wei Zhuo $
5 * @version $Id: ImageManager.php 27 2004-04-01 08:31:57Z Wei Zhuo $
6 * @package ImageManager
7 */
8
9require_once('Files.php');
10
11// uncomment to turn on debugging
12
13// _ddtOn();
14
15/**
16 * ImageManager Class.
17 * @author $Author: Wei Zhuo $
18 * @version $Id: ImageManager.php 27 2004-04-01 08:31:57Z Wei Zhuo $
19 */
20class ImageManager
21{
22        /**
23         * Configuration array.
24         */
25        var $config;
26
27        /**
28         * Array of directory information.
29         */
30        var $dirs;
31
32        /**
33         * Constructor. Create a new Image Manager instance.
34         * @param array $config configuration array, see config.inc.php
35         */
36        function ImageManager($config)
37        {
38                $this->config = $config;
39        }
40
41        /**
42         * Get the images base directory.
43         * @return string base dir, see config.inc.php
44         */
45        function getImagesDir()
46        {
47                Return $this->config['images_dir'];
48        }
49
50        /**
51         * Get the images base URL.
52         * @return string base url, see config.inc.php
53         */
54        function getImagesURL()
55        {
56                Return $this->config['images_url'];
57        }
58
59        function isValidBase()
60        {
61                return is_dir($this->getImagesDir());
62        }
63
64        /**
65         * Get the tmp file prefix.
66         * @return string tmp file prefix.
67         */
68        function getTmpPrefix()
69        {
70                Return $this->config['tmp_prefix'];
71        }
72
73        /**
74         * Get the sub directories in the base dir.
75         * Each array element contain
76         * the relative path (relative to the base dir) as key and the
77         * full path as value.
78         * @return array of sub directries
79         * <code>array('path name' => 'full directory path', ...)</code>
80         */
81        function getDirs()
82        {
83                if(is_null($this->dirs))
84                {
85                        $dirs = $this->_dirs($this->getImagesDir(),'/');
86                        ksort($dirs);
87                        $this->dirs = $dirs;
88                }
89                return $this->dirs;
90        }
91
92        /**
93         * Recursively travese the directories to get a list
94         * of accessable directories.
95         * @param string $base the full path to the current directory
96         * @param string $path the relative path name
97         * @return array of accessiable sub-directories
98         * <code>array('path name' => 'full directory path', ...)</code>
99         */
100        function _dirs($base, $path)
101        {
102                $base = Files::fixPath($base);
103                $dirs = array();
104
105                if($this->isValidBase() == false)
106                        return $dirs;
107
108                $d = @dir($base);
109               
110                while (false !== ($entry = $d->read()))
111                {
112                        //If it is a directory, and it doesn't start with
113                        // a dot, and if is it not the thumbnail directory
114                        if(is_dir($base.$entry)
115                                && substr($entry,0,1) != '.'
116                                && $this->isThumbDir($entry) == false)
117                        {
118                                $relative = Files::fixPath($path.$entry);
119                                $fullpath = Files::fixPath($base.$entry);
120                                $dirs[$relative] = $fullpath;
121                                $dirs = array_merge($dirs, $this->_dirs($fullpath, $relative));
122                        }
123                }
124                $d->close();
125
126                Return $dirs;
127        }
128
129        /**
130         * Get all the files and directories of a relative path.
131         * @param string $path relative path to be base path.
132         * @return array of file and path information.
133         * <code>array(0=>array('relative'=>'fullpath',...), 1=>array('filename'=>fileinfo array(),...)</code>
134         * fileinfo array: <code>array('url'=>'full url',
135         *                       'relative'=>'relative to base',
136         *                        'fullpath'=>'full file path',
137         *                        'image'=>imageInfo array() false if not image,
138         *                        'stat' => filestat)</code>
139         */
140        function getFiles($path)
141        {
142                $files = array();
143                $dirs = array();
144
145                if($this->isValidBase() == false)
146                        return array($files,$dirs);
147
148                $path = Files::fixPath($path);
149                $base = Files::fixPath($this->getImagesDir());
150                $fullpath = Files::makePath($base,$path);
151
152
153                $d = @dir($fullpath);
154               
155                while (false !== ($entry = $d->read()))
156                {
157                        //not a dot file or directory
158                        if(substr($entry,0,1) != '.')
159                        {
160                                if(is_dir($fullpath.$entry)
161                                        && $this->isThumbDir($entry) == false)
162                                {
163                                        $relative = Files::fixPath($path.$entry);
164                                        $full = Files::fixPath($fullpath.$entry);
165                                        $count = $this->countFiles($full);
166                                        $dirs[$relative] = array('fullpath'=>$full,'entry'=>$entry,'count'=>$count);
167                                }
168                                else if(is_file($fullpath.$entry) && $this->isThumb($entry)==false && $this->isTmpFile($entry) == false)
169                                {
170                                        $img = $this->getImageInfo($fullpath.$entry);
171
172                                        if(!(!is_array($img)&&$this->config['validate_images']))
173                                        {
174                                                $file['url'] = Files::makePath($this->config['base_url'],$path).$entry;
175                                                $file['relative'] = $path.$entry;
176                                                $file['fullpath'] = $fullpath.$entry;
177                                                $file['image'] = $img;
178                                                $file['stat'] = stat($fullpath.$entry);
179                                                $files[$entry] = $file;
180                                        }
181                                }
182                        }
183                }
184                $d->close();
185                ksort($dirs);
186                ksort($files);
187               
188                Return array($dirs, $files);
189        }       
190
191        /**
192         * Count the number of files and directories in a given folder
193         * minus the thumbnail folders and thumbnails.
194         */
195        function countFiles($path)
196        {
197                $total = 0;
198
199                if(is_dir($path))
200                {
201                        $d = @dir($path);
202
203                        while (false !== ($entry = $d->read()))
204                        {
205                                //echo $entry."<br>";
206                                if(substr($entry,0,1) != '.'
207                                        && $this->isThumbDir($entry) == false
208                                        && $this->isTmpFile($entry) == false
209                                        && $this->isThumb($entry) == false)
210                                {
211                                        $total++;
212                                }
213                        }
214                        $d->close();
215                }
216                return $total;
217        }
218
219        /**
220         * Get image size information.
221         * @param string $file the image file
222         * @return array of getImageSize information,
223         *  false if the file is not an image.
224         */
225        function getImageInfo($file)
226        {
227                Return @getImageSize($file);
228        }
229
230        /**
231         * Check if the file contains the thumbnail prefix.
232         * @param string $file filename to be checked
233         * @return true if the file contains the thumbnail prefix, false otherwise.
234         */
235        function isThumb($file)
236        {
237                $len = strlen($this->config['thumbnail_prefix']);
238                if(substr($file,0,$len)==$this->config['thumbnail_prefix'])
239                        Return true;
240                else
241                        Return false;
242        }
243
244        /**
245         * Check if the given directory is a thumbnail directory.
246         * @param string $entry directory name
247         * @return true if it is a thumbnail directory, false otherwise
248         */
249        function isThumbDir($entry)
250        {
251                if($this->config['thumbnail_dir'] == false
252                        || strlen(trim($this->config['thumbnail_dir'])) == 0)
253                        Return false;           
254                else
255                        Return ($entry == $this->config['thumbnail_dir']);
256        }
257
258        /**
259         * Check if the given file is a tmp file.
260         * @param string $file file name
261         * @return boolean true if it is a tmp file, false otherwise
262         */
263        function isTmpFile($file)
264        {
265                $len = strlen($this->config['tmp_prefix']);
266                if(substr($file,0,$len)==$this->config['tmp_prefix'])
267                        Return true;
268                else
269                        Return false;           
270        }
271
272        /**
273         * For a given image file, get the respective thumbnail filename
274         * no file existence check is done.
275         * @param string $fullpathfile the full path to the image file
276         * @return string of the thumbnail file
277         */
278        function getThumbName($fullpathfile)
279        {
280                $path_parts = pathinfo($fullpathfile);
281               
282                $thumbnail = $this->config['thumbnail_prefix'].$path_parts['basename'];
283
284                if( strlen(trim($this->config['thumbnail_dir'])) == 0 || $this->config['safe_mode'] == true)
285                {
286                        Return Files::makeFile($path_parts['dirname'],$thumbnail);
287                }
288                else
289                {
290                                $path = Files::makePath($path_parts['dirname'],$this->config['thumbnail_dir']);
291                                if(!is_dir($path))
292                                        Files::createFolder($path);
293                                Return Files::makeFile($path,$thumbnail);
294                }
295        }
296       
297        /**
298         * Similar to getThumbName, but returns the URL, base on the
299         * given base_url in config.inc.php
300         * @param string $relative the relative image file name,
301         * relative to the base_dir path
302         * @return string the url of the thumbnail
303         */
304        function getThumbURL($relative)
305        {
306
307                _ddt( __FILE__, __LINE__, "getThumbURL(): relative is '$relative'" );
308
309                $path_parts = pathinfo($relative);
310                $thumbnail = $this->config['thumbnail_prefix'].$path_parts['basename'];
311                if($path_parts['dirname']=='\\') $path_parts['dirname']='/';
312
313                if($this->config['safe_mode'] == true
314                        || strlen(trim($this->config['thumbnail_dir'])) == 0)
315                {
316                        Return Files::makeFile($this->getImagesURL(),$thumbnail);
317                }
318                else
319                {
320                        if(strlen(trim($this->config['thumbnail_dir'])) > 0)
321                        {
322                                $path = Files::makePath($path_parts['dirname'],$this->config['thumbnail_dir']);
323                                $url_path = Files::makePath($this->getImagesURL(), $path);
324
325                                _ddt( __FILE__, __LINE__, "getThumbURL(): url_path is '$url_path'" );
326
327                                Return Files::makeFile($url_path,$thumbnail);
328                        }
329                        else //should this ever happen?
330                        {
331                                //error_log('ImageManager: Error in creating thumbnail url');
332                        }
333
334                }
335        }
336
337
338        /**
339         * For a given image file, get the respective resized filename
340         * no file existence check is done.
341         * @param string $fullpathfile the full path to the image file
342         * @param integer $width the intended width
343         * @param integer $height the intended height
344         * @param boolean $mkDir whether to attempt to make the resized_dir if it doesn't exist
345         * @return string of the resized filename
346         */
347        function getResizedName($fullpathfile, $width, $height, $mkDir = TRUE)
348        {
349                $path_parts = pathinfo($fullpathfile);
350
351                $thumbnail = $this->config['resized_prefix']."_{$width}x{$height}_{$path_parts['basename']}";
352
353                if( strlen(trim($this->config['resized_dir'])) == 0 || $this->config['safe_mode'] == true )
354                {
355                        Return Files::makeFile($path_parts['dirname'],$thumbnail);
356                }
357                else
358                {
359                        $path = Files::makePath($path_parts['dirname'],$this->config['resized_dir']);
360                        if($mkDir && !is_dir($path))
361                                Files::createFolder($path);
362                        Return Files::makeFile($path,$thumbnail);
363                }
364        }
365
366        /**
367         * Check if the given path is part of the subdirectories
368         * under the base_dir.
369         * @param string $path the relative path to be checked
370         * @return boolean true if the path exists, false otherwise
371         */
372        function validRelativePath($path)
373        {
374                $dirs = $this->getDirs();
375                if($path == '/')
376                        Return true;
377                //check the path given in the url against the
378                //list of paths in the system.
379                for($i = 0; $i < count($dirs); $i++)
380                {
381                        $key = key($dirs);
382                        //we found the path
383                        if($key == $path)
384                                Return true;
385               
386                        next($dirs);
387                }               
388                Return false;
389        }
390
391        /**
392         * Process uploaded files, assumes the file is in
393         * $_FILES['upload'] and $_POST['dir'] is set.
394         * The dir must be relative to the base_dir and exists.
395         * If 'validate_images' is set to true, only file with
396         * image dimensions will be accepted.
397         * @return null
398         */
399        function processUploads()
400        {
401                if($this->isValidBase() == false)
402                        return;
403
404                $relative = null;
405
406                if(isset($_POST['dir']))
407                        $relative = rawurldecode($_POST['dir']);
408                else
409                        return;
410
411                //check for the file, and must have valid relative path
412                if(isset($_FILES['upload']) && $this->validRelativePath($relative))
413                {
414                        $this->_processFiles($relative, $_FILES['upload']);
415                }
416        }
417
418        /**
419         * Process upload files. The file must be an
420         * uploaded file. If 'validate_images' is set to
421         * true, only images will be processed. Any duplicate
422         * file will be renamed. See Files::copyFile for details
423         * on renaming.
424         * @param string $relative the relative path where the file
425         * should be copied to.
426         * @param array $file the uploaded file from $_FILES
427         * @return boolean true if the file was processed successfully,
428         * false otherwise
429         */
430        function _processFiles($relative, $file)
431        {
432               
433                if($file['error']!=0)
434                {
435                        Return false;
436                }
437
438                if(!is_file($file['tmp_name']))
439                {
440                        Return false;
441                }
442
443                if(!is_uploaded_file($file['tmp_name']))
444                {
445                        Files::delFile($file['tmp_name']);
446                        Return false;
447                }
448               
449
450                if($this->config['validate_images'] == true)
451                {
452                        $imgInfo = @getImageSize($file['tmp_name']);
453                        if(!is_array($imgInfo))
454                        {
455                                Files::delFile($file['tmp_name']);
456                                Return false;
457                        }
458                }
459
460                //now copy the file
461                $path = Files::makePath($this->getImagesDir(),$relative);
462                $result = Files::copyFile($file['tmp_name'], $path, $file['name']);
463
464                //no copy error
465                if(!is_int($result))
466                {
467                        Files::delFile($file['tmp_name']);
468                        Return true;
469                }
470
471                //delete tmp files.
472                Files::delFile($file['tmp_name']);
473                Return false;
474        }
475
476        /**
477         * Get the URL of the relative file.
478         * basically appends the relative file to the
479         * base_url given in config.inc.php
480         * @param string $relative a file the relative to the base_dir
481         * @return string the URL of the relative file.
482         */
483        function getFileURL($relative)
484        {
485                Return Files::makeFile($this->getImagesURL(),$relative);
486        }
487
488        /**
489         * Get the fullpath to a relative file.
490         * @param string $relative the relative file.
491         * @return string the full path, .ie. the base_dir + relative.
492         */
493        function getFullPath($relative)
494        {
495                Return Files::makeFile($this->getImagesDir(),$relative);;
496        }
497
498        /**
499         * Get the default thumbnail.
500         * @return string default thumbnail, empty string if
501         * the thumbnail doesn't exist.
502         */
503        function getDefaultThumb()
504        {
505
506                // FIXME: hack
507
508                Return $this->config['default_thumbnail'];
509
510                if(is_file($this->config['default_thumbnail']))
511                        {
512                        Return $this->config['default_thumbnail'];
513                        }
514                else
515                        Return '';
516        }
517
518
519        /**
520         * Get the thumbnail url to be displayed.
521         * If the thumbnail exists, and it is up-to-date
522         * the thumbnail url will be returns. If the
523         * file is not an image, a default image will be returned.
524         * If it is an image file, and no thumbnail exists or
525         * the thumbnail is out-of-date (i.e. the thumbnail
526         * modified time is less than the original file)
527         * then a thumbs.php?img=filename.jpg is returned.
528         * The thumbs.php url will generate a new thumbnail
529         * on the fly. If the image is less than the dimensions
530         * of the thumbnails, the image will be display instead.
531         * @param string $relative the relative image file.
532         * @return string the url of the thumbnail, be it
533         * actually thumbnail or a script to generate the
534         * thumbnail on the fly.
535         */
536        function getThumbnail($relative)
537        {
538
539                global $IMConfig;
540
541                _ddt( __FILE__, __LINE__, "getThumbnail(): top with '$relative'" );
542
543                $fullpath = Files::makeFile($this->getImagesDir(),$relative);
544
545                //not a file???
546                if(!is_file($fullpath))
547                        Return $this->getDefaultThumb();
548
549                $imgInfo = @getImageSize($fullpath);
550               
551                //not an image
552                if(!is_array($imgInfo))
553                        Return $this->getDefaultThumb();
554
555                //the original image is smaller than thumbnails,
556                //so just return the url to the original image.
557                if ($imgInfo[0] <= $this->config['thumbnail_width']
558                 && $imgInfo[1] <= $this->config['thumbnail_height'])
559                        Return $this->getFileURL($relative);
560
561                $thumbnail = $this->getThumbName($fullpath);
562               
563                //check for thumbnails, if exists and
564                // it is up-to-date, return the thumbnail url
565                if(is_file($thumbnail))
566                {
567                        if(filemtime($thumbnail) >= filemtime($fullpath))
568                                {
569                                _ddt( __FILE__, __LINE__, "getThumbnail(): returning url '" . $this->getThumbURL($relative) . "'" );
570
571                                Return $this->getThumbURL($relative);
572                                }
573                }
574
575                //well, no thumbnail was found, so ask the thumbs.php
576                //to generate the thumbnail on the fly.
577                Return $IMConfig['backend_url'] . '__function=thumbs&img='.rawurlencode($relative);
578        }
579
580        /**
581         * Delete and specified files.
582         * @return boolean true if delete, false otherwise
583         */
584        function deleteFiles()
585        {
586                if(isset($_GET['delf']))
587                        $this->_delFile(rawurldecode($_GET['delf']));
588        }
589
590        /**
591         * Delete and specified directories.
592         * @return boolean true if delete, false otherwise
593         */
594        function deleteDirs()
595        {
596                 if(isset($_GET['deld']))
597                        return $this->_delDir(rawurldecode($_GET['deld']));             
598                 else
599                         Return false;
600        }
601
602        /**
603         * Delete the relative file, and any thumbnails.
604         * @param string $relative the relative file.
605         * @return boolean true if deleted, false otherwise.
606         */
607        function _delFile($relative)
608        {
609                $fullpath = Files::makeFile($this->getImagesDir(),$relative);
610               
611                //check that the file is an image
612                if($this->config['validate_images'] == true)
613                {
614                        if(!is_array($this->getImageInfo($fullpath)))
615                                return false; //hmmm not an Image!!???
616                }
617
618                $thumbnail = $this->getThumbName($fullpath);
619
620                if(Files::delFile($fullpath))
621                        Return Files::delFile($thumbnail);
622                else
623                        Return false;
624        }
625
626        /**
627         * Delete directories recursively.
628         * @param string $relative the relative path to be deleted.
629         * @return boolean true if deleted, false otherwise.
630         */
631        function _delDir($relative)
632        {
633                $fullpath = Files::makePath($this->getImagesDir(),$relative);
634                if($this->countFiles($fullpath) <= 0)
635                        return Files::delFolder($fullpath,true); //delete recursively.
636                else
637                        Return false;
638        }
639
640        /**
641         * Create new directories.
642         * If in safe_mode, nothing happens.
643         * @return boolean true if created, false otherwise.
644         */
645        function processNewDir()
646        {
647                if($this->config['safe_mode'] == true)
648                        Return false;
649
650                if(isset($_GET['newDir']) && isset($_GET['dir']))
651                {
652                        $newDir = rawurldecode($_GET['newDir']);
653                        $dir = rawurldecode($_GET['dir']);
654                        $path = Files::makePath($this->getImagesDir(),$dir);
655                        $fullpath = Files::makePath($path, Files::escape($newDir));
656                        if(is_dir($fullpath))
657                                Return false;
658
659                        Return Files::createFolder($fullpath);
660                }
661        }
662}
663
664?>
Note: See TracBrowser for help on using the repository browser.