OSDN Git Service

MEDIA::isValidCollection()
[nucleus-jp/nucleus-jp-ancient.git] / utf8 / nucleus / libs / MEDIA.php
1 <?php
2 /*
3  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
4  * Copyright (C) 2002-2007 The Nucleus Group
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  * (see nucleus/documentation/index.html#license for more info)
11  */
12 /**
13  * Media classes for nucleus
14  *
15  * @license http://nucleuscms.org/license.txt GNU General Public License
16  * @copyright Copyright (C) 2002-2007 The Nucleus Group
17  * @version $Id: MEDIA.php,v 1.6 2007-02-04 06:28:46 kimitake Exp $
18  * $NucleusJP: MEDIA.php,v 1.5 2006/07/17 20:03:44 kimitake Exp $
19  */
20
21
22 /**
23   * Represents the media objects for a certain member
24   */
25 class MEDIA {
26
27         /**
28           * Gets the list of collections available to the currently logged
29           * in member
30           *
31           * @returns array of dirname => display name
32           */
33         function getCollectionList() {
34                 global $member, $DIR_MEDIA;
35
36                 $collections = array();
37
38                 // add private directory for member
39                 $collections[$member->getID()] = 'Private Collection';
40
41                 // add global collections
42                 if (!is_dir($DIR_MEDIA)) return $collections;
43
44                 $dirhandle = opendir($DIR_MEDIA);
45                 while ($dirname = readdir($dirhandle)) {
46                         // only add non-numeric (numeric=private) dirs
47                         if (@is_dir($DIR_MEDIA . $dirname) && ($dirname != '.') && ($dirname != '..') && ($dirname != 'CVS') && (!is_numeric($dirname)))  {
48                                 $collections[$dirname] = $dirname;
49                         }
50                 }
51                 closedir($dirhandle);
52
53                 return $collections;
54
55         }
56
57         /**
58           * Returns an array of MEDIAOBJECT objects for a certain collection
59           *
60           * @param $collection
61           *             name of the collection
62           * @param $filter
63           *             filter on filename (defaults to none)
64           */
65         function getMediaListByCollection($collection, $filter = '') {
66                 global $DIR_MEDIA;
67
68                 $filelist = array();
69
70                 // 1. go through all objects and add them to the filelist
71
72                 $mediadir = $DIR_MEDIA . $collection . '/';
73
74                 // return if dir does not exist
75                 if (!is_dir($mediadir)) return $filelist;
76
77                 $dirhandle = opendir($mediadir);
78                 while ($filename = readdir($dirhandle)) {
79                         // only add files that match the filter
80                         if (!@is_dir($filename) && MEDIA::checkFilter($filename, $filter))
81                                 array_push($filelist, new MEDIAOBJECT($collection, $filename, filemtime($mediadir . $filename)));
82                 }
83                 closedir($dirhandle);
84
85                 // sort array so newer files are shown first
86                 usort($filelist, 'sort_media');
87
88                 return $filelist;
89         }
90
91         function checkFilter($strText, $strFilter) {
92                 if ($strFilter == '')
93                         return 1;
94                 else
95                         return is_integer(strpos(strtolower($strText), strtolower($strFilter)));
96         }
97
98         /**
99           * checks if a collection exists with the given name, and if it's
100           * allowed for the currently logged in member to upload files to it
101           */
102         function isValidCollection($collectionName) {\r
103                 global $member, $DIR_MEDIA;\r
104 \r
105                 // allow creating new private directory\r
106                 if (preg_match('#^[0-9]+[/\\\\]?$#',$collectionName))\r
107                         return ((int)$member->getID() == (int)$collectionName);\r
108 \r
109                 // avoid directory traversal\r
110                 // note that preg_replace() is requred to remove the last "/" or "\" if exists\r
111                 $media = realpath($DIR_MEDIA);\r
112                 $media = preg_replace('#[/\\\\]+$#','',$media);\r
113                 $collectionDir = realpath( $DIR_MEDIA . $collectionName );\r
114                 $collectionDir = preg_replace('#[/\\\\]+$#','',$collectionDir);\r
115                 if (strpos($collectionDir,$media)!==0 || $collectionDir == $media) return false;\r
116 \r
117                 // private collections only accept uploads from their owners\r
118                 // The "+1" of "strlen($media)+1" corresponds to "/" or "\".\r
119                 $collectionName=substr($collectionDir,strlen($media)+1);\r
120                 if (preg_match('/^[0-9]+$/',$collectionName))\r
121                         return ((int)$member->getID() == (int)$collectionName);\r
122 \r
123                 // other collections should exists and be writable\r
124                 return (@is_dir($collectionDir) && @is_writable($collectionDir));\r
125         }\r
126
127         /**
128           * Adds an uploaded file to the media archive
129           *
130           * @param collection
131           *             collection
132           * @param uploadfile
133           *             the postFileInfo(..) array
134           * @param filename
135           *             the filename that should be used to save the file as
136           *             (date prefix should be already added here)
137           */
138         function addMediaObject($collection, $uploadfile, $filename) {
139                 global $DIR_MEDIA, $manager;
140
141                 $manager->notify('PreMediaUpload',array('collection' => &$collection, 'uploadfile' => $uploadfile, 'filename' => &$filename));
142
143                 // don't allow uploads to unknown or forbidden collections
144                 if (!MEDIA::isValidCollection($collection))
145                         return _ERROR_DISALLOWED;
146
147                 // check dir permissions (try to create dir if it does not exist)
148                 $mediadir = $DIR_MEDIA . $collection;
149
150                 // try to create new private media directories if needed
151                 if (!@is_dir($mediadir) && is_numeric($collection)) {
152                         $oldumask = umask(0000);
153                         if (!@mkdir($mediadir, 0777))
154                                 return _ERROR_BADPERMISSIONS;
155                         umask($oldumask);
156                 }
157
158                 // if dir still not exists, the action is disallowed
159                 if (!@is_dir($mediadir))
160                         return _ERROR_DISALLOWED;
161
162                 if (!is_writeable($mediadir))
163                         return _ERROR_BADPERMISSIONS;
164
165                 // add trailing slash (don't add it earlier since it causes mkdir to fail on some systems)
166                 $mediadir .= '/';
167
168                 if (file_exists($mediadir . $filename))
169                         return _ERROR_UPLOADDUPLICATE;
170
171                 // move file to directory
172                 if (is_uploaded_file($uploadfile)) {
173                         if (!@move_uploaded_file($uploadfile, $mediadir . $filename))
174                                 return _ERROR_UPLOADMOVEP;
175                 } else {
176                         if (!copy($uploadfile, $mediadir . $filename))
177                                 return _ERROR_UPLOADCOPY ;
178                 }
179
180                 // chmod uploaded file
181                 $oldumask = umask(0000);
182                 @chmod($mediadir . $filename, 0644);
183                 umask($oldumask);
184
185                 $manager->notify('PostMediaUpload',array('collection' => $collection, 'mediadir' => $mediadir, 'filename' => $filename));
186
187                 return '';
188
189         }
190
191         /**
192          * Adds an uploaded file to the media dir.
193          *
194          * @param $collection
195          *              collection to use
196          * @param $filename
197          *              the filename that should be used to save the file as
198          *              (date prefix should be already added here)
199          * @param &$data
200          *              File data (binary)
201          *
202          * NOTE: does not check if $collection is valid.
203          */
204         function addMediaObjectRaw($collection, $filename, &$data) {
205                 global $DIR_MEDIA;
206
207                 // check dir permissions (try to create dir if it does not exist)
208                 $mediadir = $DIR_MEDIA . $collection;
209
210                 // try to create new private media directories if needed
211                 if (!@is_dir($mediadir) && is_numeric($collection)) {
212                         $oldumask = umask(0000);
213                         if (!@mkdir($mediadir, 0777))
214                                 return _ERROR_BADPERMISSIONS;
215                         umask($oldumask);
216                 }
217
218                 // if dir still not exists, the action is disallowed
219                 if (!@is_dir($mediadir))
220                         return _ERROR_DISALLOWED;
221
222                 if (!is_writeable($mediadir))
223                         return _ERROR_BADPERMISSIONS;
224
225                 // add trailing slash (don't add it earlier since it causes mkdir to fail on some systems)
226                 $mediadir .= '/';
227
228                 if (file_exists($mediadir . $filename))
229                         return _ERROR_UPLOADDUPLICATE;
230
231                 // create file
232                 $fh = @fopen($mediadir . $filename, 'wb');
233                 if (!$fh)
234                         return _ERROR_UPLOADFAILED;
235                 $ok = @fwrite($fh, $data);
236                 @fclose($fh);
237                 if (!$ok)
238                         return _ERROR_UPLOADFAILED;
239
240                 // chmod uploaded file
241                 $oldumask = umask(0000);
242                 @chmod($mediadir . $filename, 0644);
243                 umask($oldumask);
244
245                 return '';
246
247         }
248
249 }
250
251 /**
252   * Represents the characteristics of one single media-object
253   *
254   * Description of properties:
255   *  - filename: filename, without paths
256   *  - timestamp: last modification (unix timestamp)
257   *  - collection: collection to which the file belongs (can also be a owner ID, for private collections)
258   *  - private: true if the media belongs to a private member collection
259   */
260 class MEDIAOBJECT {
261
262         var $private;
263         var $collection;
264         var $filename;
265         var $timestamp;
266
267         function MEDIAOBJECT($collection, $filename, $timestamp) {
268                 $this->private = is_numeric($collection);
269                 $this->collection = $collection;
270                 $this->filename = $filename;
271                 $this->timestamp = $timestamp;
272         }
273
274 }
275
276 /**
277   * User-defined sort method to sort an array of MEDIAOBJECTS
278   */
279 function sort_media($a, $b) {
280         if ($a->timestamp == $b->timestamp) return 0;
281         return ($a->timestamp > $b->timestamp) ? -1 : 1;
282 }
283
284 ?>