Overview

Packages

  • ClipIt
    • clipit
      • api
    • urjc
      • backend
  • Elgg
    • Core
      • Access
      • Authentication
      • Cache
      • Caches
      • Core
      • DataMode
        • Site
      • DataModel
        • Annotations
        • Entities
        • Extender
        • File
        • Importable
        • Loggable
        • Notable
        • Object
        • User
      • DataStorage
      • Exception
      • Exceptions
        • Stub
      • FileStore
        • Disk
      • Groups
      • Helpers
      • HMAC
      • Memcache
      • Metadata
      • Navigation
      • ODD
      • Output
      • Plugins
        • Settings
      • Sessions
      • SocialModel
        • Friendable
        • Locatable
      • WebServicesAPI
      • Widgets
      • XML
      • XMLRPC
    • Exceptions
      • Stub
  • None
  • PHP

Classes

  • ElggDiskFilestore
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * A filestore that uses disk as storage.
  4:  *
  5:  * @warning This should be used by a wrapper class
  6:  * like {@link ElggFile}.
  7:  *
  8:  * @package    Elgg.Core
  9:  * @subpackage FileStore.Disk
 10:  * @link       http://docs.elgg.org/DataModel/FileStore/Disk
 11:  */
 12: class ElggDiskFilestore extends ElggFilestore {
 13:     /**
 14:      * Directory root.
 15:      */
 16:     private $dir_root;
 17: 
 18:     /**
 19:      * Default depth of file directory matrix
 20:      */
 21:     private $matrix_depth = 5;
 22: 
 23:     /**
 24:      * Construct a disk filestore using the given directory root.
 25:      *
 26:      * @param string $directory_root Root directory, must end in "/"
 27:      */
 28:     public function __construct($directory_root = "") {
 29:         global $CONFIG;
 30: 
 31:         if ($directory_root) {
 32:             $this->dir_root = $directory_root;
 33:         } else {
 34:             $this->dir_root = $CONFIG->dataroot;
 35:         }
 36:     }
 37: 
 38:     /**
 39:      * Open a file for reading, writing, or both.
 40:      *
 41:      * @note All files are opened binary safe.
 42:      * @warning This will try to create the a directory if it doesn't exist,
 43:      * even in read-only mode.
 44:      *
 45:      * @param ElggFile $file The file to open
 46:      * @param string   $mode read, write, or append.
 47:      *
 48:      * @throws InvalidParameterException
 49:      * @return resource File pointer resource
 50:      * @todo This really shouldn't try to create directories if not writing.
 51:      */
 52:     public function open(ElggFile $file, $mode) {
 53:         $fullname = $this->getFilenameOnFilestore($file);
 54: 
 55:         // Split into path and name
 56:         $ls = strrpos($fullname, "/");
 57:         if ($ls === false) {
 58:             $ls = 0;
 59:         }
 60: 
 61:         $path = substr($fullname, 0, $ls);
 62:         $name = substr($fullname, $ls);
 63:         // @todo $name is unused, remove it or do we need to fix something?
 64: 
 65:         // Try and create the directory
 66:         try {
 67:             $this->makeDirectoryRoot($path);
 68:         } catch (Exception $e) {
 69: 
 70:         }
 71: 
 72:         if (($mode != 'write') && (!file_exists($fullname))) {
 73:             return false;
 74:         }
 75: 
 76:         switch ($mode) {
 77:             case "read" :
 78:                 $mode = "rb";
 79:                 break;
 80:             case "write" :
 81:                 $mode = "w+b";
 82:                 break;
 83:             case "append" :
 84:                 $mode = "a+b";
 85:                 break;
 86:             default:
 87:                 $msg = elgg_echo('InvalidParameterException:UnrecognisedFileMode', array($mode));
 88:                 throw new InvalidParameterException($msg);
 89:         }
 90: 
 91:         return fopen($fullname, $mode);
 92: 
 93:     }
 94: 
 95:     /**
 96:      * Write data to a file.
 97:      *
 98:      * @param resource $f    File pointer resource
 99:      * @param mixed    $data The data to write.
100:      *
101:      * @return bool
102:      */
103:     public function write($f, $data) {
104:         return fwrite($f, $data);
105:     }
106: 
107:     /**
108:      * Read data from a file.
109:      *
110:      * @param resource $f      File pointer resource
111:      * @param int      $length The number of bytes to read
112:      * @param int      $offset The number of bytes to start after
113:      *
114:      * @return mixed Contents of file or false on fail.
115:      */
116:     public function read($f, $length, $offset = 0) {
117:         if ($offset) {
118:             $this->seek($f, $offset);
119:         }
120: 
121:         return fread($f, $length);
122:     }
123: 
124:     /**
125:      * Close a file pointer
126:      *
127:      * @param resource $f A file pointer resource
128:      *
129:      * @return bool
130:      */
131:     public function close($f) {
132:         return fclose($f);
133:     }
134: 
135:     /**
136:      * Delete an ElggFile file.
137:      *
138:      * @param ElggFile $file File to delete
139:      *
140:      * @return bool
141:      */
142:     public function delete(ElggFile $file) {
143:         $filename = $this->getFilenameOnFilestore($file);
144:         if (file_exists($filename)) {
145:             return unlink($filename);
146:         } else {
147:             return true;
148:         }
149:     }
150: 
151:     /**
152:      * Seek to the specified position.
153:      *
154:      * @param resource $f        File resource
155:      * @param int      $position Position in bytes
156:      *
157:      * @return bool
158:      */
159:     public function seek($f, $position) {
160:         return fseek($f, $position);
161:     }
162: 
163:     /**
164:      * Return the current location of the internal pointer
165:      *
166:      * @param resource $f File pointer resource
167:      *
168:      * @return int|false
169:      */
170:     public function tell($f) {
171:         return ftell($f);
172:     }
173: 
174:     /**
175:      * Tests for end of file on a file pointer
176:      *
177:      * @param resource $f File pointer resource
178:      *
179:      * @return bool
180:      */
181:     public function eof($f) {
182:         return feof($f);
183:     }
184: 
185:     /**
186:      * Returns the file size of an ElggFile file.
187:      *
188:      * @param ElggFile $file File object
189:      *
190:      * @return int The file size
191:      */
192:     public function getFileSize(ElggFile $file) {
193:         return filesize($this->getFilenameOnFilestore($file));
194:     }
195: 
196:     /**
197:      * Get the filename as saved on disk for an ElggFile object
198:      *
199:      * Returns an empty string if no filename set
200:      *
201:      * @param ElggFile $file File object
202:      *
203:      * @return string The full path of where the file is stored
204:      * @throws InvalidParameterException
205:      */
206:     public function getFilenameOnFilestore(ElggFile $file) {
207:         $owner_guid = $file->getOwnerGuid();
208:         if (!$owner_guid) {
209:             $owner_guid = elgg_get_logged_in_user_guid();
210:         }
211: 
212:         if (!$owner_guid) {
213:             $msg = elgg_echo('InvalidParameterException:MissingOwner',
214:                 array($file->getFilename(), $file->guid));
215:             throw new InvalidParameterException($msg);
216:         }
217: 
218:         $filename = $file->getFilename();
219:         if (!$filename) {
220:             return '';
221:         }
222: 
223:         return $this->dir_root . $this->makeFileMatrix($owner_guid) . $filename;
224:     }
225: 
226:     /**
227:      * Returns the contents of the ElggFile file.
228:      *
229:      * @param ElggFile $file File object
230:      *
231:      * @return string
232:      */
233:     public function grabFile(ElggFile $file) {
234:         return file_get_contents($file->getFilenameOnFilestore());
235:     }
236: 
237:     /**
238:      * Tests if an ElggFile file exists.
239:      *
240:      * @param ElggFile $file File object
241:      *
242:      * @return bool
243:      */
244:     public function exists(ElggFile $file) {
245:         if (!$file->getFilename()) {
246:             return false;
247:         }
248:         return file_exists($this->getFilenameOnFilestore($file));
249:     }
250: 
251:     /**
252:      * Returns the size of all data stored under a directory in the disk store.
253:      *
254:      * @param string $prefix         Optional/ The prefix to check under.
255:      * @param string $container_guid The guid of the entity whose data you want to check.
256:      *
257:      * @return int|false
258:      */
259:     public function getSize($prefix = '', $container_guid) {
260:         if ($container_guid) {
261:             return get_dir_size($this->dir_root . $this->makeFileMatrix($container_guid) . $prefix);
262:         } else {
263:             return false;
264:         }
265:     }
266: 
267:     // @codingStandardsIgnoreStart
268:     /**
269:      * Create a directory $dirroot
270:      *
271:      * @param string $dirroot The full path of the directory to create
272:      *
273:      * @throws IOException
274:      * @return true
275:      * @deprecated 1.8 Use ElggDiskFilestore::makeDirectoryRoot()
276:      */
277:     protected function make_directory_root($dirroot) {
278:         elgg_deprecated_notice('ElggDiskFilestore::make_directory_root() is deprecated by ::makeDirectoryRoot()', 1.8);
279: 
280:         return $this->makeDirectoryRoot($dirroot);
281:     }
282:     // @codingStandardsIgnoreEnd
283: 
284:     /**
285:      * Create a directory $dirroot
286:      *
287:      * @param string $dirroot The full path of the directory to create
288:      *
289:      * @throws IOException
290:      * @return true
291:      */
292:     protected function makeDirectoryRoot($dirroot) {
293:         if (!file_exists($dirroot)) {
294:             if (!@mkdir($dirroot, 0700, true)) {
295:                 throw new IOException(elgg_echo('IOException:CouldNotMake', array($dirroot)));
296:             }
297:         }
298: 
299:         return true;
300:     }
301: 
302:     // @codingStandardsIgnoreStart
303:     /**
304:      * Multibyte string tokeniser.
305:      *
306:      * Splits a string into an array. Will fail safely if mbstring is
307:      * not installed.
308:      *
309:      * @param string $string  String
310:      * @param string $charset The charset, defaults to UTF8
311:      *
312:      * @return array
313:      * @deprecated 1.8 Files are stored by date and guid; no need for this.
314:      */
315:     private function mb_str_split($string, $charset = 'UTF8') {
316:         elgg_deprecated_notice('ElggDiskFilestore::mb_str_split() is deprecated.', 1.8);
317: 
318:         if (is_callable('mb_substr')) {
319:             $length = mb_strlen($string);
320:             $array = array();
321: 
322:             while ($length) {
323:                 $array[] = mb_substr($string, 0, 1, $charset);
324:                 $string = mb_substr($string, 1, $length, $charset);
325: 
326:                 $length = mb_strlen($string);
327:             }
328: 
329:             return $array;
330:         } else {
331:             return str_split($string);
332:         }
333:     }
334:     // @codingStandardsIgnoreEnd
335: 
336:     // @codingStandardsIgnoreStart
337:     /**
338:      * Construct a file path matrix for an entity.
339:      *
340:      * @param int $identifier The guide of the entity to store the data under.
341:      *
342:      * @return string The path where the entity's data will be stored.
343:      * @deprecated 1.8 Use ElggDiskFilestore::makeFileMatrix()
344:      */
345:     protected function make_file_matrix($identifier) {
346:         elgg_deprecated_notice('ElggDiskFilestore::make_file_matrix() is deprecated by ::makeFileMatrix()', 1.8);
347: 
348:         return $this->makeFileMatrix($identifier);
349:     }
350:     // @codingStandardsIgnoreEnd
351: 
352:     /**
353:      * Construct a file path matrix for an entity.
354:      *
355:      * @param int $guid The guide of the entity to store the data under.
356:      *
357:      * @return string The path where the entity's data will be stored.
358:      */
359:     protected function makeFileMatrix($guid) {
360:         $entity = get_entity($guid);
361: 
362:         if (!($entity instanceof ElggEntity) || !$entity->time_created) {
363:             return false;
364:         }
365: 
366:         $time_created = date('Y/m/d', $entity->time_created);
367: 
368:         return "$time_created/$entity->guid/";
369:     }
370: 
371:     // @codingStandardsIgnoreStart
372:     /**
373:      * Construct a filename matrix.
374:      *
375:      * Generates a matrix using the entity's creation time and
376:      * unique guid.
377:      *
378:      * File path matrixes are:
379:      * YYYY/MM/DD/guid/
380:      *
381:      * @param int $guid The entity to contrust a matrix for
382:      *
383:      * @return string The
384:      */
385:     protected function user_file_matrix($guid) {
386:         elgg_deprecated_notice('ElggDiskFilestore::user_file_matrix() is deprecated by ::makeFileMatrix()', 1.8);
387: 
388:         return $this->makeFileMatrix($guid);
389:     }
390:     // @codingStandardsIgnoreEnd
391: 
392:     /**
393:      * Returns a list of attributes to save to the database when saving
394:      * the ElggFile object using this file store.
395:      *
396:      * @return array
397:      */
398:     public function getParameters() {
399:         return array("dir_root" => $this->dir_root);
400:     }
401: 
402:     /**
403:      * Sets parameters that should be saved to database.
404:      *
405:      * @param array $parameters Set parameters to save to DB for this filestore.
406:      *
407:      * @return bool
408:      */
409:     public function setParameters(array $parameters) {
410:         if (isset($parameters['dir_root'])) {
411:             $this->dir_root = $parameters['dir_root'];
412:             return true;
413:         }
414: 
415:         return false;
416:     }
417: }
418: 
API documentation generated by ApiGen 2.8.0