3 * MediaUtils plugin for Nucleus CMS
4 * Version 0.9.6 (1.0 RC2) for PHP5
5 * Written By Mocchi, Apr. 04, 2011
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
14 static public $lib_path = '';
16 static public $cookiename = 'blogid';
17 static public $blogid = FALSE;
18 static public $blogs = array();
19 static public $bshortname = '';
21 static public $prefix = TRUE;
22 static public $maxsize = 2097152;
23 static public $suffixes = array();
25 static public $algorism = 'md5';
26 static public $image_mime
27 = array('image/jpeg' => '.jpeg',
28 'image/png' => '.png',
29 /* 'image/bmp' => '.bmp', not implemented*/
30 'image/gif' => '.gif');
34 * @access Public MediaUtils::error
35 * @param String $message Error message
38 static public function error ($message) {
40 header("HTTP/1.0 404 Not Found");
45 * send resampled image via HTTP
46 * @access Public MediaUtils::responseResampledImage
47 * @param Object $medium Medium Object
50 static public function responseResampledImage ($medium) {
51 if (!class_exists('Medium', FALSE)) {
52 include(self::$lib_path . '/Medium.php');
55 if ('Medium' !== get_class($medium)) {
56 self::error ('NP_MediaUtils: Fail to generate resampled image');
60 if (FALSE === ($resampledimage = $medium->getResampledBinary(self::$image_mime))) {
61 unset ($resampledimage);
62 self::error ('NP_MediaUtils: Fail to generate resampled image');
66 header ('Content-type: ' . $medium->mime);
68 unset ($resampledimage);
73 * Store resampled image binary to filesystem as file
74 * @access Public MediaUtils::storeResampledImage
75 * @param String $root root directory for media
76 * @param String $path Relative path from root to destination
77 * @param Object $medium Medium Object
78 * @return Boolean TRUE/FALSE
80 static public function storeResampledImage ($root, $target, $medium) {
81 if (!class_exists('Medium', FALSE)) {
82 include(self::$lib_path . '/Medium.php');
85 if ('Medium' !== get_class($medium)) {
89 if (FALSE === ($resampledimage = $medium->getResampledBinary(self::$image_mime))) {
90 unset ($resampledimage);
94 if (FALSE === ($handle = @fopen ("{$root}/{$target}", 'w'))) {
95 unset ($resampledimage);
99 if (@fwrite ($handle, $resampledimage) === FALSE) {
100 unset ($resampledimage);
101 @unlink ("{$root}/{$target}");
105 unset ($resampledimage);
108 if (@chmod ("{$root}/{$target}", 0744) === FALSE) {
109 @unlink ("{$root}/{$target}");
117 * Check the path as directory and writable
118 * @access Public MediaUtils::checkDir
119 * @param String Fullpath
120 * @return Boolean TRUE/FALSE
122 static public function checkDir ($fullpath) {
123 $fullpath = (string) $fullpath;
125 if (file_exists ($fullpath)) {
126 if (is_dir ($fullpath) && is_writable ($fullpath)) {
132 if (!@mkdir ($fullpath, 0777)) {
141 * Return file data list
142 * @access Public MediaUtils::getMediaList
143 * @param String $root path to media root directory
144 * @param Boolean $hidden show hidden files (.*) or not
145 * @param Boolean $recursive follow recursively or not
146 * @param Boolean $prefix analyze its prefix or not
147 * @param String $suffix limit by suffix
148 * @param String $path relative path from root to destination
149 * @return Array Array(Medium)
151 static public function getMediaList ($root, $hidden=TRUE, $recursive=TRUE, $suffix='', $path='', $media=array()) {
152 $root = (string) $root;
153 $hidden = (boolean) $hidden;
154 $recursive = (boolean) $recursive;
155 $suffix = (string) $suffix;
156 $path = (string) $path;
157 $media = (array) $media;
159 if (!class_exists('Medium', FALSE)) {
160 include(self::$lib_path . '/Medium.php');
163 $root = rtrim($root, '/');
164 if(!$root || !file_exists($root)) {
170 $path = trim($path, '/');
171 $fullpath = "{$root}/{$path}";
174 if (FALSE === ($handle = @opendir($fullpath))) {
177 while(FALSE !== ($filename = readdir($handle))) {
178 if ($filename !== '.' && $filename !== '..') {
179 if (($hidden && preg_match("#^\.#", $filename))
180 || ($suffix && !preg_match("#\.$suffix$#", $filename))) {
184 if($recursive && filetype("{$fullpath}/{$filename}") === "dir") {
185 $media = self::getMediaList($root, $hidden, $recursive, $suffix, trim("{$path}/{$filename}", '/'), $media);
186 } else if ($path !== '' && filetype("{$fullpath}/{$filename}") === "file") {
187 $media[] = new Medium($root, trim("{$path}/{$filename}", '/'), self::$prefix);
198 * @access Public MediaUtils::purgeDir
199 * @param String $root path to media root directory
200 * @param String $path relative path from root to destination
201 * @return Array/FALSE $logs
204 static public function purgeDir($root, $path='', $logs=array()) {
205 $root = (string) $root;
206 $path = (string) $path;
207 $logs = (array) $logs;
209 $root = rtrim($root, '/');
210 if(!$root || !file_exists($root)) {
216 $path = trim($path, '/');
217 $fullpath = "{$root}/{$path}";
220 if (FALSE === ($handle = @opendir($fullpath))) {
223 while(FALSE !== ($filename = readdir($handle))) {
224 if ($filename !== '.' && $filename !== '..') {
225 if(filetype("{$fullpath}/{$filename}") === "dir") {
226 $logs = self::purgeDir($root, "{$path}/{$filename}", $logs);
228 if(!unlink("{$root}/{$path}/{$filename}")) {
229 $logs[] = "Exists: {$path}/{$filename}";
231 $logs[] = "Removed: {$path}/{$filename}";
237 if(!rmdir("{$root}/{$path}")) {
238 $logs[] = "Exists: {$path}";
240 $logs[] = "Removed: {$path}";
246 * Return path list under root
247 * @access Public MediaUtils::getPathList
248 * @param String $root full path to root directory
249 * @param String $path certain path to search
250 * @param Boolean $private use private directory or not
251 * @param Boolean $recursize search recursively or not
252 * @param Boolean $hidden do not list up the directory started with piriod or not
253 * @return String $name
256 static public function getPathList($root, $path='', $private=FALSE, $hidden=TRUE, $recursive=TRUE) {
257 $root = (string) $root;
258 $path = (string) $path;
259 $hidden = (boolean) $hidden;
260 $recursive = (boolean) $recursive;
264 $root = rtrim($root, '/');
265 if(!$root || !file_exists($root)) {
271 $path = trim($path, '/');
272 $fullpath = "{$root}/{$path}";
275 if (FALSE === ($handle = @opendir($fullpath))) {
278 while (FALSE !== ($filename = readdir($handle))) {
279 if (in_array($filename, array('.', '..', 'CVS'))) {
281 } else if (is_file("{$fullpath}/{$filename}")) {
283 } else if ($hidden && preg_match('#^\.#', $filename)) {
285 } else if ($private && is_numeric($filename) && $path==''&& $private != $filename) {
290 $relpath = $filename;
292 $relpath = "{$path}/{$filename}";
295 $paths = self::getPathData($root, $relpath, $private, $hidden, $recursive, $paths);
299 if ($path=='' && $private) {
300 if (!array_key_exists($private, $paths)) {
301 $paths[$private] = array('root'=>$root , 'path'=>$private, 'files'=>0, 'dirs'=>0);
303 $paths[$private]['label'] = 'PRIVATE';
306 ksort($paths, SORT_STRING);
312 * @access Public MediaUtils::getPathData
313 * @param String $root full path to root directory
314 * @param String $path relative path from root to target directory
315 * @param Boolean $private use private directory or not
316 * @param Boolean $hidden do not list up the directory started with piriod or not
317 * @param Boolean $recursive search recursively or not
318 * @return Array Array('root', 'parent', 'name', 'files', 'dirs', 'label')
320 static public function getPathData($root, $path, $private=FALSE, $hidden=TRUE, $recursive=FALSE, $paths=array()) {
321 $root = (string) $root;
322 $path = (string) $path;
323 $private = (boolean) $private;
324 $hidden = (boolean) $hidden;
325 $recursive = (boolean) $recursive;
330 $root = rtrim($root, '/');
331 if(!$root || !file_exists($root)) {
337 $path = trim($path, '/');
338 $fullpath = "{$root}/{$path}";
341 if (FALSE === ($handle = @opendir($fullpath))) {
344 while (FALSE !== ($filename = readdir($handle))) {
345 if (in_array($filename, array('.', '..', 'CVS'))) {
347 } else if (!is_dir("{$fullpath}/{$filename}")) {
348 if (!$hidden || !preg_match('#^\.#', $filename)){
352 } else if ($hidden && preg_match('#^\.#', $filename)) {
359 $relpath = $filename;
361 $relpath = "{$path}/{$filename}";
365 $paths = self::getPathData($root, $relpath, $private, $recursive, $hidden, $paths);
370 $paths[$path]['root'] = $root;
371 $paths[$path]['parent'] = trim(str_replace(basename($fullpath), '', $path), '/');
372 $paths[$path]['name'] = basename($fullpath);
373 $paths[$path]['files'] = $cnt_files;
374 $paths[$path]['dirs'] = $cnt_dirs;
376 $paths[$path]['label'] = preg_replace("#^$private#", 'PRIVATE', $path);
378 $paths[$path]['label'] = $path;
385 * Store uploaded binary to filesystem
386 * @access Public MediaUtils::uploadMedium
387 * @param String $root path to edia root directory
388 * @param String $path relative path from root to target directory
389 * @param Array $medium uploaded binary data.
390 * @param String/FALSE $overwrite overwrite or not if the file already exists
391 * @param Object $manager Nucleus Manager Object
392 * @return String $log Return '' if success, others is error messages
395 static public function uploadMedium ($root, $path, &$temp, $overwrite='', &$manager='') {
396 $root = (string) $root;
397 $path = (string) $path;
398 $temp = (array) $temp;
399 $overwrite = (string) $overwrite;
400 $manager = (object) $manager;
403 * $temp should be derived from $_FILE
405 foreach(array('name', 'tmp_name','size', 'error') as $key) {
406 if (!array_key_exists($key, $temp)) {
407 return 'NP_MediaUtils: Miss uploaded file.';
411 $root = rtrim($root, '/');
412 if(!$root || !file_exists($root) || !$path) {
413 return 'NP_MediaUtils: Destination is invalid.';
415 $path = trim($path, '/');
418 * see http://www.php.net/manual/en/features.file-upload.errors.php
420 switch ($temp['error']) {
423 case UPLOAD_ERR_INI_SIZE:
424 case UPLOAD_ERR_FORM_SIZE:
425 return 'NP_MediaUtils: Binary is too big.';
426 case UPLOAD_ERR_PARTIAL:
427 case UPLOAD_ERR_NO_FILE:
428 case UPLOAD_ERR_NO_TMP_DIR:
429 case UPLOAD_ERR_CANT_WRITE:
430 case UPLOAD_ERR_EXTENSION :
432 return 'NP_MediaUtils: Request rejected';
435 if (preg_match ("#(\\\\|/|\\n)#", $temp['name'])) {
436 return 'NP_MediaUtils: invalid filename';
439 if ($temp['size'] > self::$maxsize) {
440 return 'NP_MediaUtils: Binary is too big';
443 if (!empty(self::$suffixes) && is_array(self::$suffixes)) {
444 preg_match("#\.(.+)$#", $temp['name'], $match);
445 $suffix = strtolower($match[1]);
446 if (!in_array($suffix, self::$suffixes)) {
447 return 'NP_MediaUtils: Forbidden file suffix';
451 if (!self::checkDir("{$root}/{$path}")) {
452 return 'NP_MediaUtils: Invalid target directory';
456 if (!preg_match("#\.($suffix)$#", strtolower($overwrite), $match)) {
457 return 'NP_MediaUtils: suffix is not the same.';
459 $temp['name'] = $overwrite;
460 } else if (self::$prefix) {
461 $temp['name'] = strftime ("%Y%m%d-", time ()) . $temp['name'];
464 if (!$overwrite && file_exists("{$root}/{$path}/{$temp['name']}")) {
465 return 'NP_MediaUtils: The same filename already exists in this target directory.';
469 $manager->notify('PreMediaUpload',array('collection' => &$path, 'uploadfile' => $temp['tmp_name'], 'filename' => $temp['name']));
472 if (is_uploaded_file($temp['tmp_name'])) {
473 if (!@move_uploaded_file($temp['tmp_name'], "{$root}/{$path}/{$temp['name']}")) {
474 return 'NP_MediaUtils: Fail to move uploaded binary to file sytem.';
476 } else if (!copy($temp['tmp_name'], "{$root}/{$path}/{$temp['name']}")) {
477 return 'NP_MediaUtils: Fail to copy uploaded binary to file sytem.';
480 $oldumask = umask(0000);
481 @chmod("{$root}/{$path}/{$temp['name']}", 0644);
485 $manager->notify('PostMediaUpload',array('collection' => $path, 'mediadir' => $root, 'filename' => $temp['name']));