OSDN Git Service

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