Elgg  Version 2.2
 All Classes Namespaces Files Functions Variables Pages
ElggFile.php
Go to the documentation of this file.
1 <?php
2 
25 class ElggFile extends \ElggObject {
26 
30  private $filestore;
31 
35  private $handle;
36 
42  protected function initializeAttributes() {
43  parent::initializeAttributes();
44 
45  $this->attributes['subtype'] = "file";
46  }
47 
51  public function getMetadata($name) {
52  if (0 === strpos($name, 'filestore::')) {
53  elgg_deprecated_notice("Do not access the ElggFile filestore metadata directly. Use setFilestore().", '2.0');
54  }
55  return parent::getMetadata($name);
56  }
57 
61  public function setMetadata($name, $value, $value_type = '', $multiple = false, $owner_guid = 0, $access_id = null) {
62  if (0 === strpos($name, 'filestore::')) {
63  elgg_deprecated_notice("Do not access the ElggFile filestore metadata directly. Use setFilestore().", '2.0');
64  }
65  return parent::setMetadata($name, $value, $value_type, $multiple, $owner_guid, $access_id);
66  }
67 
75  public function setFilename($name) {
76  $this->filename = $name;
77  }
78 
84  public function getFilename() {
85  return $this->filename;
86  }
87 
94  public function getFilenameOnFilestore() {
95  return $this->getFilestore()->getFilenameOnFilestore($this);
96  }
97 
106  public function getFilestoreSize($prefix = '', $container_guid = 0) {
107  if (!$container_guid) {
109  }
110  $fs = $this->getFilestore();
111  // @todo add getSize() to \ElggFilestore
112  return $fs->getSize($prefix, $container_guid);
113  }
114 
120  public function getMimeType() {
121  if ($this->mimetype) {
122  return $this->mimetype;
123  }
124  return $this->detectMimeType();
125  }
126 
133  public function setMimeType($mimetype) {
134  return $this->mimetype = $mimetype;
135  }
136 
149  public function detectMimeType($file = null, $default = null) {
150  $class = __CLASS__;
151  if (!$file && isset($this) && $this instanceof $class) {
152  $file = $this->getFilenameOnFilestore();
153  }
154 
155  if (!is_readable($file)) {
156  return false;
157  }
158 
159  $mime = $default;
160 
161  $detected = (new \Elgg\Filesystem\MimeTypeDetector())->tryStrategies($file);
162  if ($detected) {
163  $mime = $detected;
164  }
165 
166  $original_filename = isset($this) && $this instanceof $class ? $this->originalfilename : basename($file);
167  $params = array(
168  'filename' => $file,
169  'original_filename' => $original_filename, // @see file upload action
170  'default' => $default,
171  );
172  return _elgg_services()->hooks->trigger('mime_type', 'file', $params, $mime);
173  }
174 
182  public function getSimpleType() {
183  if (isset($this->simpletype)) {
184  return $this->simpletype;
185  }
186  $mime_type = $this->getMimeType();
187  return elgg_get_file_simple_type($mime_type);
188  }
189 
197  public function setDescription($description) {
198  $this->description = $description;
199  }
200 
210  public function open($mode) {
211  if (!$this->getFilename()) {
212  throw new \IOException("You must specify a name before opening a file.");
213  }
214 
215  // See if file has already been saved
216  // seek on datastore, parameters and name?
217 
218  // Sanity check
219  if (
220  ($mode != "read") &&
221  ($mode != "write") &&
222  ($mode != "append")
223  ) {
224  $msg = "Unrecognized file mode '" . $mode . "'";
225  throw new \InvalidParameterException($msg);
226  }
227 
228  // Get the filestore
229  $fs = $this->getFilestore();
230 
231  // Ensure that we save the file details to object store
232  //$this->save();
233 
234  // Open the file handle
235  $this->handle = $fs->open($this, $mode);
236 
237  return $this->handle;
238  }
239 
247  public function write($data) {
248  $fs = $this->getFilestore();
249 
250  return $fs->write($this->handle, $data);
251  }
252 
261  public function read($length, $offset = 0) {
262  $fs = $this->getFilestore();
263 
264  return $fs->read($this->handle, $length, $offset);
265  }
266 
272  public function grabFile() {
273  $fs = $this->getFilestore();
274  return $fs->grabFile($this);
275  }
276 
282  public function close() {
283  $fs = $this->getFilestore();
284 
285  if ($fs->close($this->handle)) {
286  $this->handle = null;
287 
288  return true;
289  }
290 
291  return false;
292  }
293 
300  public function delete($follow_symlinks = true) {
301  $fs = $this->getFilestore();
302 
303  $result = $fs->delete($this, $follow_symlinks);
304 
305  if ($this->getGUID() && $result) {
306  $result = parent::delete();
307  }
308 
309  return $result;
310  }
311 
319  public function seek($position) {
320  $fs = $this->getFilestore();
321 
322  return $fs->seek($this->handle, $position);
323  }
324 
330  public function tell() {
331  $fs = $this->getFilestore();
332 
333  return $fs->tell($this->handle);
334  }
335 
340  public function setModifiedTime() {
341  $filestorename = $this->getFilenameOnFilestore();
342  $modified = touch($filestorename);
343  if ($modified) {
344  clearstatcache(true, $filestorename);
345  } else {
346  elgg_log("Unable to update modified time for $filestorename", 'ERROR');
347  }
348  return $modified;
349  }
350 
355  public function getModifiedTime() {
356  return filemtime($this->getFilenameOnFilestore());
357  }
358 
365  public function getSize() {
366  return $this->getFilestore()->getFileSize($this);
367  }
368 
375  public function size() {
376  elgg_deprecated_notice("Use \ElggFile::getSize() instead of \ElggFile::size()", 1.9);
377  return $this->getSize();
378  }
379 
385  public function eof() {
386  $fs = $this->getFilestore();
387 
388  return $fs->eof($this->handle);
389  }
390 
396  public function exists() {
397  $fs = $this->getFilestore();
398 
399  return $fs->exists($this);
400  }
401 
410  public function setFilestore(\ElggFilestore $filestore) {
411  elgg_deprecated_notice(__METHOD__ . ' is deprecated.', '2.1');
412  $this->filestore = $filestore;
413  }
414 
424  protected function getFilestore() {
425  if ($this->filestore) {
426  // already set
427  return $this->filestore;
428  }
429 
430  // such a common case we just assume for now
431  $this->filestore = $GLOBALS['DEFAULT_FILE_STORE'];
432 
433  if (!$this->guid) {
434  return $this->filestore;
435  }
436 
437  // Note we use parent::getMetadata() below to avoid showing the warnings added in #9193
438 
439  $class = parent::getMetadata('filestore::filestore');
440  if (!$class) {
441  return $this->filestore;
442  }
443 
444  // common case
446  && parent::getMetadata('filestore::dir_root') === _elgg_services()->config->getDataPath()) {
447  return $this->filestore;
448  }
449 
450  if (!class_exists($class)) {
451  $this->filestore = null;
452  throw new \ClassNotFoundException("Unable to load filestore class $class for file {$this->guid}");
453  }
454 
455  // need to get all filestore::* metadata because the rest are "parameters" that
456  // get passed to filestore::setParameters()
457  $mds = elgg_get_metadata([
458  'guid' => $this->guid,
459  'where' => array("n.string LIKE 'filestore::%'"),
460  ]);
461  $parameters = [];
462  foreach ($mds as $md) {
463  list( , $name) = explode("::", $md->name);
464  if ($name !== 'filestore') {
465  $parameters[$name] = $md->value;
466  }
467  }
468 
469  $this->filestore = new $class();
470  $this->filestore->setParameters($parameters);
471  return $this->filestore;
472  }
473 
484  public function save() {
485  if (!parent::save()) {
486  return false;
487  }
488 
489  $filestore = $this->getFilestore();
490 
491  // Note we use parent::getMetadata() below to avoid showing the warnings added in #9193
492 
493  // Save datastore metadata
494  $params = $filestore->getParameters();
495  foreach ($params as $k => $v) {
496  parent::setMetadata("filestore::$k", $v);
497  }
498 
499  // Now make a note of the filestore class
500  parent::setMetadata("filestore::filestore", get_class($filestore));
501 
502  return true;
503  }
504 
516  public function transfer($owner_guid, $filename = null) {
517  if (!$owner_guid) {
518  return false;
519  }
520 
521  if (!$this->exists()) {
522  return false;
523  }
524 
525  if (!$filename) {
526  $filename = $this->getFilename();
527  }
528  $filestorename = $this->getFilenameOnFilestore();
529 
530  $this->owner_guid = $owner_guid;
531  $this->setFilename($filename);
532  $this->open('write');
533  $this->close();
534 
535  return rename($filestorename, $this->getFilenameOnFilestore());
536  }
537 
543  public function __sleep() {
544  return array_diff(array_keys(get_object_vars($this)), array(
545  // Don't persist filestore, which contains CONFIG
546  // https://github.com/Elgg/Elgg/issues/9081#issuecomment-152859856
547  'filestore',
548 
549  // a resource
550  'handle',
551  ));
552  }
553 }
setDescription($description)
Set the optional file description.
Definition: ElggFile.php:197
getSize()
Return the size of the file in bytes.
Definition: ElggFile.php:365
if(!array_key_exists($filename, $text_files)) $file
$mode
Configure site maintenance mode.
setMetadata($name, $value, $value_type= '', $multiple=false, $owner_guid=0, $access_id=null)
{}
Definition: ElggFile.php:61
write($data)
Write data.
Definition: ElggFile.php:247
if($guid==elgg_get_logged_in_user_guid()) $name
Definition: delete.php:21
setModifiedTime()
Updates modification time of the file and clears stats cache for the file.
Definition: ElggFile.php:340
getFilestoreSize($prefix= '', $container_guid=0)
Return the size of the filestore associated with this file.
Definition: ElggFile.php:106
close()
Close the file and commit changes.
Definition: ElggFile.php:282
seek($position)
Seek a position in the file.
Definition: ElggFile.php:319
$data
Definition: opendd.php:13
$value
Definition: longtext.php:26
eof()
Return a boolean value whether the file handle is at the end of the file.
Definition: ElggFile.php:385
exists()
Returns if the file exists.
Definition: ElggFile.php:396
if(!$count) $offset
Definition: pagination.php:26
getSimpleType()
Get the simple type of the file.
Definition: ElggFile.php:182
getGUID()
Returns the guid.
$default
Definition: checkbox.php:35
getMetadata($name)
{}
Definition: ElggFile.php:51
if(isset($vars['id'])) $class
Definition: ajax_loader.php:19
save()
Save the file.
Definition: ElggFile.php:484
getModifiedTime()
Returns file modification time.
Definition: ElggFile.php:355
$position
Definition: move.php:10
setFilestore(\ElggFilestore $filestore)
Set a filestore.
Definition: ElggFile.php:410
$params
Definition: login.php:72
getFilenameOnFilestore()
Return the filename of this file as it is/will be stored on the filestore, which may be different to ...
Definition: ElggFile.php:94
grabFile()
Gets the full contents of this file.
Definition: ElggFile.php:272
initializeAttributes()
Set subtype to 'file'.
Definition: ElggFile.php:42
$owner_guid
if(!$site) if(!($site instanceof ElggSite)) $site description
setMimeType($mimetype)
Set the mime type of the file.
Definition: ElggFile.php:133
elgg module widget elgg state draggable elgg widget handle
if($categories) $description
Definition: full.php:166
getFilename()
Return the filename.
Definition: ElggFile.php:84
detectMimeType($file=null, $default=null)
Detects mime types based on filename or actual file.
Definition: ElggFile.php:149
read($length, $offset=0)
Read data.
Definition: ElggFile.php:261
$comment owner_guid
Definition: save.php:58
tell()
Return the current position of the file.
Definition: ElggFile.php:330
getMimeType()
Get the mime type of the file.
Definition: ElggFile.php:120
elgg_deprecated_notice($msg, $dep_version, $backtrace_level=1)
Log a notice about deprecated use of a function, view, etc.
Definition: elgglib.php:1070
open($mode)
Open the file with the given mode.
Definition: ElggFile.php:210
_elgg_services(\Elgg\Di\ServiceProvider $services=null)
Get the global service provider.
Definition: autoloader.php:17
elgg_log($message, $level= 'NOTICE')
Display or log a message.
Definition: elgglib.php:1000
getFilestore()
Return a filestore suitable for saving this file.
Definition: ElggFile.php:424
elgg_get_metadata(array $options=array())
Returns metadata.
Definition: metadata.php:143
$filename
class
Definition: placeholder.php:21
setFilename($name)
Set the filename of this file.
Definition: ElggFile.php:75
size()
Return the size of the file in bytes.
Definition: ElggFile.php:375
$container_guid
transfer($owner_guid, $filename=null)
Transfer a file to a new owner and sets a new filename, copies file contents to a new location...
Definition: ElggFile.php:516
elgg_get_file_simple_type($mime_type)
Returns the category of a file from its MIME type.
Definition: filestore.php:462
__sleep()
Get property names to serialize.
Definition: ElggFile.php:543