| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480 | 
							- <?php
 
- /**
 
-  * This class represents a physical file.
 
-  *
 
-  * 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.
 
-  *
 
-  * 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. If you do not save the file, no
 
-  * entity is created in the database. This is because there are occasions
 
-  * when you may want access to file data on datastores using the \ElggFile
 
-  * interface without a need to persist information such as temporary files.
 
-  *
 
-  * @package    Elgg.Core
 
-  * @subpackage DataModel.File
 
-  */
 
- class ElggFile extends \ElggObject {
 
- 	/** Filestore */
 
- 	private $filestore;
 
- 	/** File handle used to identify this file in a filestore. Created by open. */
 
- 	private $handle;
 
- 	/**
 
- 	 * Set subtype to 'file'.
 
- 	 *
 
- 	 * @return void
 
- 	 */
 
- 	protected function initializeAttributes() {
 
- 		parent::initializeAttributes();
 
- 		$this->attributes['subtype'] = "file";
 
- 	}
 
- 	/**
 
- 	 * Loads an \ElggFile entity.
 
- 	 *
 
- 	 * @param \stdClass $row Database result or null for new \ElggFile
 
- 	 */
 
- 	public function __construct($row = null) {
 
- 		parent::__construct($row);
 
- 		// Set default filestore
 
- 		$this->filestore = $this->getFilestore();
 
- 	}
 
- 	/**
 
- 	 * Set the filename of this file.
 
- 	 *
 
- 	 * @param string $name The filename.
 
- 	 *
 
- 	 * @return void
 
- 	 */
 
- 	public function setFilename($name) {
 
- 		$this->filename = $name;
 
- 	}
 
- 	/**
 
- 	 * 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 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) {
 
- 		if (!$container_guid) {
 
- 			$container_guid = $this->container_guid;
 
- 		}
 
- 		$fs = $this->getFilestore();
 
- 		// @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) {
 
- 			return $this->mimetype;
 
- 		}
 
- 		// @todo Guess mimetype if not here
 
- 	}
 
- 	/**
 
- 	 * Set the mime type of the file.
 
- 	 *
 
- 	 * @param string $mimetype The mimetype
 
- 	 *
 
- 	 * @return bool
 
- 	 */
 
- 	public function setMimeType($mimetype) {
 
- 		return $this->mimetype = $mimetype;
 
- 	}
 
- 	/**
 
- 	 * Detects mime types based on filename or actual file.
 
- 	 *
 
- 	 * @note This method can be called both dynamically and statically
 
- 	 *
 
- 	 * @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
 
- 	 *
 
- 	 * @return mixed Detected type on success, false on failure.
 
- 	 * @todo Move this out into a utility class
 
- 	 */
 
- 	public function detectMimeType($file = null, $default = null) {
 
- 		$class = __CLASS__;
 
- 		if (!$file && isset($this) && $this instanceof $class) {
 
- 			$file = $this->getFilenameOnFilestore();
 
- 		}
 
- 		if (!is_readable($file)) {
 
- 			return false;
 
- 		}
 
- 		$mime = $default;
 
- 		// 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);
 
- 		}
 
- 		$original_filename = isset($this) && $this instanceof $class ? $this->originalfilename : basename($file);
 
- 		$params = array(
 
- 			'filename' => $file,
 
- 			'original_filename' => $original_filename, // @see file upload action
 
- 			'default' => $default,
 
- 		);
 
- 		return _elgg_services()->hooks->trigger('mime_type', 'file', $params, $mime);
 
- 	}
 
- 	/**
 
- 	 * Set the optional file description.
 
- 	 *
 
- 	 * @param string $description The description.
 
- 	 *
 
- 	 * @return bool
 
- 	 */
 
- 	public function setDescription($description) {
 
- 		$this->description = $description;
 
- 	}
 
- 	/**
 
- 	 * 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()) {
 
- 			throw new \IOException("You must specify a name before opening a file.");
 
- 		}
 
- 		// See if file has already been saved
 
- 		// seek on datastore, parameters and name?
 
- 		// Sanity check
 
- 		if (
 
- 			($mode != "read") &&
 
- 			($mode != "write") &&
 
- 			($mode != "append")
 
- 		) {
 
- 			$msg = "Unrecognized file mode '" . $mode . "'";
 
- 			throw new \InvalidParameterException($msg);
 
- 		}
 
- 		// Get the filestore
 
- 		$fs = $this->getFilestore();
 
- 		// Ensure that we save the file details to object store
 
- 		//$this->save();
 
- 		// Open the file handle
 
- 		$this->handle = $fs->open($this, $mode);
 
- 		return $this->handle;
 
- 	}
 
- 	/**
 
- 	 * Write data.
 
- 	 *
 
- 	 * @param string $data The data
 
- 	 *
 
- 	 * @return bool
 
- 	 */
 
- 	public function write($data) {
 
- 		$fs = $this->getFilestore();
 
- 		return $fs->write($this->handle, $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();
 
- 		return $fs->read($this->handle, $length, $offset);
 
- 	}
 
- 	/**
 
- 	 * Gets the full contents of this file.
 
- 	 *
 
- 	 * @return mixed The file contents.
 
- 	 */
 
- 	public function grabFile() {
 
- 		$fs = $this->getFilestore();
 
- 		return $fs->grabFile($this);
 
- 	}
 
- 	/**
 
- 	 * Close the file and commit changes
 
- 	 *
 
- 	 * @return bool
 
- 	 */
 
- 	public function close() {
 
- 		$fs = $this->getFilestore();
 
- 		if ($fs->close($this->handle)) {
 
- 			$this->handle = null;
 
- 			return true;
 
- 		}
 
- 		return false;
 
- 	}
 
- 	/**
 
- 	 * Delete this file.
 
- 	 *
 
- 	 * @return bool
 
- 	 */
 
- 	public function delete() {
 
- 		$fs = $this->getFilestore();
 
- 		
 
- 		$result = $fs->delete($this);
 
- 		
 
- 		if ($this->getGUID() && $result) {
 
- 			$result = parent::delete();
 
- 		}
 
- 		
 
- 		return $result;
 
- 	}
 
- 	/**
 
- 	 * Seek a position in the file.
 
- 	 *
 
- 	 * @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);
 
- 	}
 
- 	/**
 
- 	 * Return the current position of the file.
 
- 	 *
 
- 	 * @return int The file position
 
- 	 */
 
- 	public function tell() {
 
- 		$fs = $this->getFilestore();
 
- 		return $fs->tell($this->handle);
 
- 	}
 
- 	/**
 
- 	 * Return the size of the file in bytes.
 
- 	 *
 
- 	 * @return int
 
- 	 * @since 1.9
 
- 	 */
 
- 	public function getSize() {
 
- 		return $this->filestore->getFileSize($this);
 
- 	}
 
- 	/**
 
- 	 * Return the size of the file in bytes.
 
- 	 *
 
- 	 * @return int
 
- 	 * @deprecated 1.8 Use getSize()
 
- 	 */
 
- 	public function size() {
 
- 		elgg_deprecated_notice("Use \ElggFile::getSize() instead of \ElggFile::size()", 1.9);
 
- 		return $this->getSize();
 
- 	}
 
- 	/**
 
- 	 * Return a boolean value whether the file handle is at the end of the file
 
- 	 *
 
- 	 * @return bool
 
- 	 */
 
- 	public function eof() {
 
- 		$fs = $this->getFilestore();
 
- 		return $fs->eof($this->handle);
 
- 	}
 
- 	/**
 
- 	 * Returns if the file exists
 
- 	 *
 
- 	 * @return bool
 
- 	 */
 
- 	public function exists() {
 
- 		$fs = $this->getFilestore();
 
- 		return $fs->exists($this);
 
- 	}
 
- 	/**
 
- 	 * Set a filestore.
 
- 	 *
 
- 	 * @param \ElggFilestore $filestore The file store.
 
- 	 *
 
- 	 * @return void
 
- 	 */
 
- 	public function setFilestore(\ElggFilestore $filestore) {
 
- 		$this->filestore = $filestore;
 
- 	}
 
- 	/**
 
- 	 * Return a filestore suitable for saving this file.
 
- 	 * 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.
 
- 		if ($this->filestore) {
 
- 			return $this->filestore;
 
- 		}
 
- 		// 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( , $name) = explode("::", $md->name);
 
- 				if ($name == 'filestore') {
 
- 					$filestore = $md->value;
 
- 				}
 
- 				$parameters[$name] = $md->value;
 
- 			}
 
- 		}
 
- 		// 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 = "Unable to load filestore class " . $filestore . " for file " . $this->guid;
 
- 				throw new \ClassNotFoundException($msg);
 
- 			}
 
- 			$this->filestore = new $filestore();
 
- 			$this->filestore->setParameters($parameters);
 
- 			// @todo explain why $parameters will always be set here (PhpStorm complains)
 
- 		}
 
- 		// this means the entity hasn't been saved so fallback to default
 
- 		if (!$this->filestore) {
 
- 			$this->filestore = get_default_filestore();
 
- 		}
 
- 		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;
 
- 		}
 
- 		// Save datastore metadata
 
- 		$params = $this->filestore->getParameters();
 
- 		foreach ($params as $k => $v) {
 
- 			$this->setMetadata("filestore::$k", $v);
 
- 		}
 
- 		// Now make a note of the filestore class
 
- 		$this->setMetadata("filestore::filestore", get_class($this->filestore));
 
- 		return true;
 
- 	}
 
- 	/**
 
- 	 * Get property names to serialize.
 
- 	 *
 
- 	 * @return string[]
 
- 	 */
 
- 	public function __sleep() {
 
- 		return array_diff(array_keys(get_object_vars($this)), array(
 
- 			// Don't persist filestore, which contains CONFIG
 
- 			// https://github.com/Elgg/Elgg/issues/9081#issuecomment-152859856
 
- 			'filestore',
 
- 			// a resource
 
- 			'handle',
 
- 		));
 
- 	}
 
- 	/**
 
- 	 * Reestablish filestore property
 
- 	 *
 
- 	 * @return void
 
- 	 * @throws ClassNotFoundException
 
- 	 */
 
- 	public function __wakeup() {
 
- 		$this->getFilestore();
 
- 	}
 
- }
 
 
  |