Elgg  Version 2.2
 All Classes Namespaces Files Functions Variables Pages
File.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\FileService;
4 
6 
12 class File {
13 
14  const INLINE = 'inline';
15  const ATTACHMENT = 'attachment';
16 
20  private $file;
21 
25  private $expires;
26 
30  private $disposition;
31 
35  private $use_cookie = true;
36 
43  public function setFile(\ElggFile $file) {
44  $this->file = $file;
45  }
46 
51  public function getFile() {
52  return $this->file;
53  }
54 
61  public function setExpires($expires = '+2 hours') {
62  $this->expires = strtotime($expires);
63  }
64 
71  public function setDisposition($disposition = self::ATTACHMENT) {
72  if (!in_array($disposition, array(self::ATTACHMENT, self::INLINE))) {
73  throw new \InvalidArgumentException("Disposition $disposition is not supported in " . __CLASS__);
74  }
75  $this->disposition = $disposition;
76  }
77 
84  public function bindSession($use_cookie = true) {
85  $this->use_cookie = $use_cookie;
86  }
87 
92  public function getURL() {
93 
94  if (!$this->file instanceof \ElggFile || !$this->file->exists()) {
95  elgg_log("Unable to resolve resource URL for a file that does not exist on filestore");
96  return false;
97  }
98 
99  $relative_path = '';
100  $root_prefix = _elgg_services()->config->getDataPath();
101  $path = $this->file->getFilenameOnFilestore();
102  if (substr($path, 0, strlen($root_prefix)) == $root_prefix) {
103  $relative_path = substr($path, strlen($root_prefix));
104  }
105 
106  if (!$relative_path) {
107  elgg_log("Unable to resolve relative path of the file on the filestore");
108  return false;
109  }
110 
111  if (preg_match('~[^a-zA-Z0-9_\./ ]~', $relative_path)) {
112  // Filenames may contain special characters that result in malformatted URLs
113  // and/or HMAC mismatches. We want to avoid that by encoding the path.
114  $relative_path = ':' . Base64Url::encode($relative_path);
115  }
116 
117  $data = array(
118  'expires' => isset($this->expires) ? $this->expires : 0,
119  'last_updated' => filemtime($this->file->getFilenameOnFilestore()),
120  'disposition' => $this->disposition == self::INLINE ? 'i' : 'a',
121  'path' => $relative_path,
122  );
123 
124  if ($this->use_cookie) {
125  $data['cookie'] = _elgg_services()->session->getId();
126  if (empty($data['cookie'])) {
127  return false;
128  }
129  $data['use_cookie'] = 1;
130  } else {
131  $data['use_cookie'] = 0;
132  }
133 
134  ksort($data);
135  $mac = _elgg_services()->crypto->getHmac($data)->getToken();
136 
137  $url_segments = array(
138  'serve-file',
139  "e{$data['expires']}",
140  "l{$data['last_updated']}",
141  "d{$data['disposition']}",
142  "c{$data['use_cookie']}",
143  $mac,
144  $relative_path,
145  );
146 
147  return elgg_normalize_url(implode('/', $url_segments));
148  }
149 }
Encode and decode Base 64 URL.
Definition: Base64Url.php:9
bindSession($use_cookie=true)
Bind URL to current user session.
Definition: File.php:84
File service.
Definition: File.php:12
elgg_normalize_url($url)
Definition: output.php:290
$data
Definition: opendd.php:13
$path
Definition: details.php:88
exists()
Returns if the file exists.
Definition: ElggFile.php:396
$mac
Definition: contents.php:14
getFile()
Returns file object.
Definition: File.php:51
_elgg_services(\Elgg\Di\ServiceProvider $services=null)
Get the global service provider.
Definition: autoloader.php:17
setFile(\ElggFile $file)
Set file object.
Definition: File.php:43
elgg_log($message, $level= 'NOTICE')
Display or log a message.
Definition: elgglib.php:1000
setExpires($expires= '+2 hours')
Sets URL expiration.
Definition: File.php:61
setDisposition($disposition=self::ATTACHMENT)
Sets content disposition.
Definition: File.php:71
getURL()
Returns publicly accessible URL.
Definition: File.php:92
static encode($bytes)
Encode base 64 URL.
Definition: Base64Url.php:17