OSDN Git Service

4fffced689481073c2d54e4d0d59a810b63bd3f3
[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 1525 2011-06-21 10:20:19Z 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 /**\r
24   * Represents the media objects for a certain member\r
25   */\r
26 class Media\r
27 {\r
28         /**\r
29          * Gets the list of collections available to the currently logged\r
30          * in member\r
31          *\r
32          * @returns array of dirname => display name\r
33          */\r
34         public function getCollectionList($exceptReadOnly = false)\r
35         {\r
36                 global $member, $DIR_MEDIA;\r
37                 \r
38                 $collections = array();\r
39                 \r
40                 // add private directory for member\r
41                 $collections[$member->getID()] = PRIVATE_COLLECTION;\r
42 \r
43                 // add global collections\r
44                 if (!is_dir($DIR_MEDIA)) return $collections;\r
45 \r
46                 $dirhandle = opendir($DIR_MEDIA);\r
47                 while ($dirname = readdir($dirhandle)) {\r
48                         // only add non-numeric (numeric=private) dirs\r
49                         if (@is_dir($DIR_MEDIA . $dirname) &&\r
50                                 ($dirname != '.') &&\r
51                                 ($dirname != '..') &&\r
52                                 ($dirname != 'CVS') &&\r
53                                 (!is_numeric($dirname)))  {\r
54                                 if (@is_writable($DIR_MEDIA . $dirname))\r
55                                         $collections[$dirname] = $dirname;\r
56                                 else if ($exceptReadOnly == false)\r
57                                         $collections[$dirname] = $dirname . ' ' . READ_ONLY_MEDIA_FOLDER;\r
58                         }\r
59                 }\r
60                 closedir($dirhandle);\r
61 \r
62                 return $collections;\r
63 \r
64         }\r
65 \r
66         /**\r
67           * Returns an array of MediaObject objects for a certain collection\r
68           *\r
69           * @param $collection\r
70           *             name of the collection\r
71           * @param $filter\r
72           *             filter on filename (defaults to none)\r
73           */\r
74         function getMediaListByCollection($collection, $filter = '') {\r
75                 global $DIR_MEDIA;\r
76 \r
77                 $filelist = array();\r
78 \r
79                 // 1. go through all objects and add them to the filelist\r
80 \r
81                 $mediadir = $DIR_MEDIA . $collection . '/';\r
82 \r
83                 // return if dir does not exist\r
84                 if (!is_dir($mediadir)) return $filelist;\r
85 \r
86                 $dirhandle = opendir($mediadir);\r
87                 while ($filename = readdir($dirhandle)) {\r
88                         // only add files that match the filter\r
89                         if (!@is_dir($filename) && Media::checkFilter($filename, $filter))\r
90                                 array_push($filelist, new MediaObject($collection, $filename, filemtime($mediadir . $filename)));\r
91                 }\r
92                 closedir($dirhandle);\r
93 \r
94                 // sort array so newer files are shown first\r
95                 usort($filelist, 'sort_media');\r
96 \r
97                 return $filelist;\r
98         }\r
99 \r
100         function checkFilter($strText, $strFilter) {\r
101                 if ($strFilter == '')\r
102                         return 1;\r
103                 else\r
104                         return is_integer(i18n::strpos(strtolower($strText), strtolower($strFilter)));\r
105         }\r
106 \r
107         /**\r
108           * checks if a collection exists with the given name, and if it's\r
109           * allowed for the currently logged in member to upload files to it\r
110           */\r
111         function isValidCollection($collectionName, $exceptReadOnly = false) {\r
112                 global $member, $DIR_MEDIA;\r
113 \r
114                 // allow creating new private directory\r
115                 if ($collectionName === (string)$member->getID())\r
116                         return true;\r
117                         \r
118                 $collections = Media::getCollectionList($exceptReadOnly);\r
119                 $dirname = $collections[$collectionName];\r
120                 if ($dirname == NULL || $dirname === PRIVATE_COLLECTION)\r
121                         return false;  \r
122 \r
123                 // other collections should exist and be writable\r
124                 $collectionDir = $DIR_MEDIA . $collectionName;\r
125                 if ($exceptReadOnly)\r
126                         return (@is_dir($collectionDir) && @is_writable($collectionDir));\r
127 \r
128                 // other collections should exist\r
129                 return @is_dir($collectionDir);\r
130        }\r
131 \r
132         /**\r
133           * Adds an uploaded file to the media archive\r
134           *\r
135           * @param collection\r
136           *             collection\r
137           * @param uploadfile\r
138           *             the postFileInfo(..) array\r
139           * @param filename\r
140           *             the filename that should be used to save the file as\r
141           *             (date prefix should be already added here)\r
142           */\r
143         function addMediaObject($collection, $uploadfile, $filename) {\r
144                 global $DIR_MEDIA, $manager;\r
145 \r
146                 // clean filename of characters that may cause trouble in a filename using cleanFileName() function from globalfunctions.php\r
147                 $filename = cleanFileName($filename);\r
148                 // should already have tested for allowable types before calling this method. This will only catch files with no extension at all\r
149                 if ($filename === false) \r
150                         return _ERROR_BADFILETYPE;\r
151                 \r
152                 // trigger PreMediaUpload event\r
153                 $manager->notify('PreMediaUpload',array('collection' => &$collection, 'uploadfile' => $uploadfile, 'filename' => &$filename));\r
154 \r
155                 // don't allow uploads to unknown or forbidden collections\r
156                 $exceptReadOnly = true;\r
157                 if (!Media::isValidCollection($collection,$exceptReadOnly))\r
158                         return _ERROR_DISALLOWED;\r
159 \r
160                 // check dir permissions (try to create dir if it does not exist)\r
161                 $mediadir = $DIR_MEDIA . $collection;\r
162 \r
163                 // try to create new private media directories if needed\r
164                 if (!@is_dir($mediadir) && is_numeric($collection)) {\r
165                         $oldumask = umask(0000);\r
166                         if (!@mkdir($mediadir, 0777))\r
167                                 return _ERROR_BADPERMISSIONS;\r
168                         umask($oldumask);\r
169                 }\r
170 \r
171                 // if dir still not exists, the action is disallowed\r
172                 if (!@is_dir($mediadir))\r
173                         return _ERROR_DISALLOWED;\r
174 \r
175                 if (!is_writeable($mediadir))\r
176                         return _ERROR_BADPERMISSIONS;\r
177 \r
178                 // add trailing slash (don't add it earlier since it causes mkdir to fail on some systems)\r
179                 $mediadir .= '/';\r
180 \r
181                 if (file_exists($mediadir . $filename))\r
182                         return _ERROR_UPLOADDUPLICATE;\r
183 \r
184                 // move file to directory\r
185                 if (is_uploaded_file($uploadfile)) {\r
186                         if (!@move_uploaded_file($uploadfile, $mediadir . $filename))\r
187                                 return _ERROR_UPLOADMOVEP;\r
188                 } else {\r
189                         if (!copy($uploadfile, $mediadir . $filename))\r
190                                 return _ERROR_UPLOADCOPY ;\r
191                 }\r
192 \r
193                 // chmod uploaded file\r
194                 $oldumask = umask(0000);\r
195                 @chmod($mediadir . $filename, 0644);\r
196                 umask($oldumask);\r
197 \r
198                 $manager->notify('PostMediaUpload',array('collection' => $collection, 'mediadir' => $mediadir, 'filename' => $filename));\r
199 \r
200                 return '';\r
201 \r
202         }\r
203 \r
204         /**\r
205          * Adds an uploaded file to the media dir.\r
206          *\r
207          * @param $collection\r
208          *              collection to use\r
209          * @param $filename\r
210          *              the filename that should be used to save the file as\r
211          *              (date prefix should be already added here)\r
212          * @param &$data\r
213          *              File data (binary)\r
214          *\r
215          * NOTE: does not check if $collection is valid.\r
216          */\r
217         function addMediaObjectRaw($collection, $filename, &$data) {\r
218                 global $DIR_MEDIA;\r
219 \r
220                 // check dir permissions (try to create dir if it does not exist)\r
221                 $mediadir = $DIR_MEDIA . $collection;\r
222 \r
223                 // try to create new private media directories if needed\r
224                 if (!@is_dir($mediadir) && is_numeric($collection)) {\r
225                         $oldumask = umask(0000);\r
226                         if (!@mkdir($mediadir, 0777))\r
227                                 return _ERROR_BADPERMISSIONS;\r
228                         umask($oldumask);\r
229                 }\r
230 \r
231                 // if dir still not exists, the action is disallowed\r
232                 if (!@is_dir($mediadir))\r
233                         return _ERROR_DISALLOWED;\r
234 \r
235                 if (!is_writeable($mediadir))\r
236                         return _ERROR_BADPERMISSIONS;\r
237 \r
238                 // add trailing slash (don't add it earlier since it causes mkdir to fail on some systems)\r
239                 $mediadir .= '/';\r
240 \r
241                 if (file_exists($mediadir . $filename))\r
242                         return _ERROR_UPLOADDUPLICATE;\r
243 \r
244                 // create file\r
245                 $fh = @fopen($mediadir . $filename, 'wb');\r
246                 if (!$fh)\r
247                         return _ERROR_UPLOADFAILED;\r
248                 $ok = @fwrite($fh, $data);\r
249                 @fclose($fh);\r
250                 if (!$ok)\r
251                         return _ERROR_UPLOADFAILED;\r
252 \r
253                 // chmod uploaded file\r
254                 $oldumask = umask(0000);\r
255                 @chmod($mediadir . $filename, 0644);\r
256                 umask($oldumask);\r
257 \r
258                 return '';\r
259 \r
260         }\r
261 \r
262 }\r
263 \r
264 /**\r
265   * Represents the characteristics of one single media-object\r
266   *\r
267   * Description of properties:\r
268   *  - filename: filename, without paths\r
269   *  - timestamp: last modification (unix timestamp)\r
270   *  - collection: collection to which the file belongs (can also be a owner ID, for private collections)\r
271   *  - private: true if the media belongs to a private member collection\r
272   */\r
273 class MediaObject\r
274 {\r
275         public $private;\r
276         public $collection;\r
277         public $filename;\r
278         public $timestamp;\r
279         \r
280         public function __construct($collection, $filename, $timestamp)\r
281         {\r
282                 $this->private = is_numeric($collection);\r
283                 $this->collection = $collection;\r
284                 $this->filename = $filename;\r
285                 $this->timestamp = $timestamp;\r
286                 return;\r
287         }\r
288 }\r
289 \r
290 /**\r
291   * User-defined sort method to sort an array of MediaObjects\r
292   */\r
293 function sort_media($a, $b) {\r
294         if ($a->timestamp == $b->timestamp) return 0;\r
295         return ($a->timestamp > $b->timestamp) ? -1 : 1;\r
296 }\r