OSDN Git Service

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