diff options
Diffstat (limited to 'engine/classes/ElggFile.php')
| -rw-r--r-- | engine/classes/ElggFile.php | 228 |
1 files changed, 175 insertions, 53 deletions
diff --git a/engine/classes/ElggFile.php b/engine/classes/ElggFile.php index 68ed2f2f2..23080834b 100644 --- a/engine/classes/ElggFile.php +++ b/engine/classes/ElggFile.php @@ -1,21 +1,24 @@ <?php /** - * @class ElggFile * This class represents a physical file. * - * Usage: - * Create a new ElggFile object and specify a filename, and optionally a FileStore (if one isn't specified - * then the default is assumed. + * Create a new ElggFile object and specify a filename, and optionally a + * FileStore (if one isn't specified then the default is assumed.) * - * Open the file using the appropriate mode, and you will be able to read and write to the file. + * Open the file using the appropriate mode, and you will be able to + * read and write to the file. * - * Optionally, you can also call the file's save() method, this will turn the file into an entity in the - * system and permit you to do things like attach tags to the file etc. This is not done automatically since - * there are many occasions where you may want access to file data on datastores using the ElggFile interface - * but do not want to create an Entity reference to it in the system (temporary files for example). + * Optionally, you can also call the file's save() method, this will + * turn the file into an entity in the system and permit you to do + * things like attach tags to the file etc. This is not done automatically + * since there are many occasions where you may want access to file data + * on datastores using the ElggFile interface but do not want to create + * an Entity reference to it in the system (temporary files for example). * - * @author Curverider Ltd + * @class ElggFile + * @package Elgg.Core + * @subpackage DataModel.File */ class ElggFile extends ElggObject { /** Filestore */ @@ -24,12 +27,22 @@ class ElggFile extends ElggObject { /** File handle used to identify this file in a filestore. Created by open. */ private $handle; - protected function initialise_attributes() { - parent::initialise_attributes(); + /** + * Set subtype to 'file'. + * + * @return void + */ + protected function initializeAttributes() { + parent::initializeAttributes(); $this->attributes['subtype'] = "file"; } + /** + * Loads an ElggFile entity. + * + * @param int $guid GUID of the ElggFile object + */ public function __construct($guid = null) { parent::__construct($guid); @@ -41,6 +54,8 @@ class ElggFile extends ElggObject { * Set the filename of this file. * * @param string $name The filename. + * + * @return void */ public function setFilename($name) { $this->filename = $name; @@ -48,33 +63,44 @@ class ElggFile extends ElggObject { /** * Return the filename. + * + * @return string */ public function getFilename() { return $this->filename; } /** - * Return the filename of this file as it is/will be stored on the filestore, which may be different - * to the filename. + * Return the filename of this file as it is/will be stored on the + * filestore, which may be different to the filename. + * + * @return string */ public function getFilenameOnFilestore() { return $this->filestore->getFilenameOnFilestore($this); } - /* + /** * Return the size of the filestore associated with this file * + * @param string $prefix Storage prefix + * @param int $container_guid The container GUID of the checked filestore + * + * @return int */ - public function getFilestoreSize($prefix='',$container_guid=0) { + public function getFilestoreSize($prefix = '', $container_guid = 0) { if (!$container_guid) { $container_guid = $this->container_guid; } $fs = $this->getFilestore(); - return $fs->getSize($prefix,$container_guid); + // @todo add getSize() to ElggFilestore + return $fs->getSize($prefix, $container_guid); } /** * Get the mime type of the file. + * + * @return string */ public function getMimeType() { if ($this->mimetype) { @@ -87,16 +113,63 @@ class ElggFile extends ElggObject { /** * Set the mime type of the file. * - * @param $mimetype The mimetype + * @param string $mimetype The mimetype + * + * @return bool */ public function setMimeType($mimetype) { return $this->mimetype = $mimetype; } /** + * Detects mime types based on filename or actual file. + * + * @param mixed $file The full path of the file to check. For uploaded files, use tmp_name. + * @param mixed $default A default. Useful to pass what the browser thinks it is. + * @since 1.7.12 + * + * @note If $file is provided, this may be called statically + * + * @return mixed Detected type on success, false on failure. + */ + public function detectMimeType($file = null, $default = null) { + if (!$file) { + if (isset($this) && $this->filename) { + $file = $this->filename; + } else { + return false; + } + } + + $mime = false; + + // for PHP5 folks. + if (function_exists('finfo_file') && defined('FILEINFO_MIME_TYPE')) { + $resource = finfo_open(FILEINFO_MIME_TYPE); + if ($resource) { + $mime = finfo_file($resource, $file); + } + } + + // for everyone else. + if (!$mime && function_exists('mime_content_type')) { + $mime = mime_content_type($file); + } + + // default + if (!$mime) { + return $default; + } + + return $mime; + } + + /** * Set the optional file description. * * @param string $description The description. + * + * @return bool */ public function setDescription($description) { $this->description = $description; @@ -106,6 +179,10 @@ class ElggFile extends ElggObject { * Open the file with the given mode * * @param string $mode Either read/write/append + * + * @return resource File handler + * + * @throws IOException|InvalidParameterException */ public function open($mode) { if (!$this->getFilename()) { @@ -117,11 +194,12 @@ class ElggFile extends ElggObject { // Sanity check if ( - ($mode!="read") && - ($mode!="write") && - ($mode!="append") + ($mode != "read") && + ($mode != "write") && + ($mode != "append") ) { - throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:UnrecognisedFileMode'), $mode)); + $msg = elgg_echo('InvalidParameterException:UnrecognisedFileMode', array($mode)); + throw new InvalidParameterException($msg); } // Get the filestore @@ -137,9 +215,11 @@ class ElggFile extends ElggObject { } /** - * Write some data. + * Write data. * * @param string $data The data + * + * @return bool */ public function write($data) { $fs = $this->getFilestore(); @@ -148,10 +228,12 @@ class ElggFile extends ElggObject { } /** - * Read some data. + * Read data. * * @param int $length Amount to read. * @param int $offset The offset to start from. + * + * @return mixed Data or false */ public function read($length, $offset = 0) { $fs = $this->getFilestore(); @@ -171,6 +253,8 @@ class ElggFile extends ElggObject { /** * Close the file and commit changes + * + * @return bool */ public function close() { $fs = $this->getFilestore(); @@ -186,22 +270,32 @@ class ElggFile extends ElggObject { /** * Delete this file. + * + * @return bool */ public function delete() { $fs = $this->getFilestore(); - if ($fs->delete($this)) { - return parent::delete(); + + $result = $fs->delete($this); + + if ($this->getGUID() && $result) { + $result = parent::delete(); } + + return $result; } /** * Seek a position in the file. * - * @param int $position + * @param int $position Position in bytes + * + * @return bool */ public function seek($position) { $fs = $this->getFilestore(); + // @todo add seek() to ElggFilestore return $fs->seek($this->handle, $position); } @@ -218,6 +312,8 @@ class ElggFile extends ElggObject { /** * Return the size of the file in bytes. + * + * @return int */ public function size() { return $this->filestore->getFileSize($this); @@ -225,6 +321,8 @@ class ElggFile extends ElggObject { /** * Return a boolean value whether the file handle is at the end of the file + * + * @return bool */ public function eof() { $fs = $this->getFilestore(); @@ -232,6 +330,11 @@ class ElggFile extends ElggObject { return $fs->eof($this->handle); } + /** + * Returns if the file exists + * + * @return bool + */ public function exists() { $fs = $this->getFilestore(); @@ -242,6 +345,8 @@ class ElggFile extends ElggObject { * Set a filestore. * * @param ElggFilestore $filestore The file store. + * + * @return void */ public function setFilestore(ElggFilestore $filestore) { $this->filestore = $filestore; @@ -249,8 +354,12 @@ class ElggFile extends ElggObject { /** * Return a filestore suitable for saving this file. - * This filestore is either a pre-registered filestore, a filestore loaded from metatags saved - * along side this file, or the system default. + * This filestore is either a pre-registered filestore, + * a filestore as recorded in metadata or the system default. + * + * @return ElggFilestore + * + * @throws ClassNotFoundException */ protected function getFilestore() { // Short circuit if already set. @@ -258,40 +367,43 @@ class ElggFile extends ElggObject { return $this->filestore; } - // If filestore meta set then retrieve filestore - // @todo Better way of doing this? - $metas = get_metadata_for_entity($this->guid); - $parameters = array(); - if (is_array($metas)) { - foreach ($metas as $meta) { - if (strpos($meta->name, "filestore::")!==false) { - // Filestore parameter tag - $comp = explode("::", $meta->name); - $name = $comp[1]; - - $parameters[$name] = $meta->value; + // ask for entity specific filestore + // saved as filestore::className in metadata. + // need to get all filestore::* metadata because the rest are "parameters" that + // get passed to filestore::setParameters() + if ($this->guid) { + $options = array( + 'guid' => $this->guid, + 'where' => array("n.string LIKE 'filestore::%'"), + ); + + $mds = elgg_get_metadata($options); + + $parameters = array(); + foreach ($mds as $md) { + list($foo, $name) = explode("::", $md->name); + if ($name == 'filestore') { + $filestore = $md->value; } + $parameters[$name] = $md->value; } } - if (isset($parameters['filestore'])) { - if (!class_exists($parameters['filestore'])) { - $msg = sprintf(elgg_echo('ClassNotFoundException:NotFoundNotSavedWithFile'), - $parameters['filestore'], - $this->guid); + // need to check if filestore is set because this entity is loaded in save() + // before the filestore metadata is saved. + if (isset($filestore)) { + if (!class_exists($filestore)) { + $msg = elgg_echo('ClassNotFoundException:NotFoundNotSavedWithFile', + array($filestore, $this->guid)); throw new ClassNotFoundException($msg); } - // Create new filestore object - $this->filestore = new $parameters['filestore'](); - + $this->filestore = new $filestore(); $this->filestore->setParameters($parameters); - } else { - // @todo - should we log error if filestore not set + // @todo explain why $parameters will always be set here (PhpStorm complains) } - - // if still nothing then set filestore to default + // this means the entity hasn't been saved so fallback to default if (!$this->filestore) { $this->filestore = get_default_filestore(); } @@ -299,6 +411,16 @@ class ElggFile extends ElggObject { return $this->filestore; } + /** + * Save the file + * + * Write the file's data to the filestore and save + * the corresponding entity. + * + * @see ElggObject::save() + * + * @return bool + */ public function save() { if (!parent::save()) { return false; |
