Elgg  Version master
SimpleCache.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Cache;
4 
5 use Elgg\Config;
8 
15 class SimpleCache {
16 
22  protected array $simplecache_views = [];
23 
30  public function __construct(
31  protected Config $config,
32  protected ViewsService $views
33  ) {
34  }
35 
50  public function getUrl(string $view): string {
51  $this->registerCacheableView($view);
52 
53  return $this->getRoot() . $view;
54  }
55 
61  public function getRoot(): string {
62  $viewtype = $this->views->getViewtype();
63  if ($this->isEnabled()) {
64  $lastcache = (int) $this->config->lastcache;
65  } else {
66  $lastcache = 0;
67  }
68 
69  return elgg_normalize_url("/cache/{$lastcache}/{$viewtype}/");
70  }
71 
79  public function registerCacheableView(string $view): void {
80  $this->simplecache_views[$view] = true;
81  }
82 
90  public function isCacheableView(string $view): bool {
91  if (isset($this->simplecache_views[$view])) {
92  return true;
93  }
94 
95  // build list of viewtypes to check
96  $current_viewtype = $this->views->getViewtype();
97  $viewtypes = [$current_viewtype];
98 
99  if ($this->views->doesViewtypeFallback($current_viewtype) && $current_viewtype != 'default') {
100  $viewtypes[] = 'default';
101  }
102 
103  // If a static view file is found in any viewtype, it's considered cacheable
104  foreach ($viewtypes as $viewtype) {
105  $file = $this->views->findViewFile($view, $viewtype);
106 
107  if ($file && pathinfo($file, PATHINFO_EXTENSION) !== 'php') {
108  $this->simplecache_views[$view] = true;
109 
110  return true;
111  }
112  }
113 
114  // Assume not-cacheable by default
115  return false;
116  }
117 
123  public function getCacheableViews(): array {
125  }
126 
132  public function isEnabled(): bool {
133  return (bool) $this->config->simplecache_enabled;
134  }
135 
141  public function enable(): void {
142  $this->config->save('simplecache_enabled', 1);
143  }
144 
150  public function disable(): void {
151  if (!$this->isEnabled()) {
152  return;
153  }
154 
155  $this->config->save('simplecache_enabled', 0);
156  }
157 
163  protected function getPath(): string {
164  return (string) $this->config->assetroot;
165  }
166 
174  public function clear(): void {
175  elgg_delete_directory($this->getPath(), true);
176  }
177 
183  public function purge(): void {
184  $lastcache = (int) $this->config->lastcache;
185 
186  if (!is_dir($this->getPath())) {
187  return;
188  }
189 
190  $di = new \DirectoryIterator($this->getPath());
191 
192  /* @var $file_info \DirectoryIterator */
193  foreach ($di as $file_info) {
194  if (!$file_info->isDir() || $file_info->isDot()) {
195  continue;
196  }
197 
198  if ((int) $file_info->getBasename() === $lastcache) {
199  continue;
200  }
201 
202  elgg_delete_directory($file_info->getPathname());
203  }
204  }
205 
216  public function cachedAssetExists(int $cache_time, string $viewtype, string $view): bool {
217  $filename = $this->getCacheFilename($viewtype, $view, $cache_time);
218 
219  return file_exists($filename);
220  }
221 
232  public function getCachedAssetLocation(int $cache_time, string $viewtype, string $view): ?string {
233  if (!$this->cachedAssetExists($cache_time, $viewtype, $view)) {
234  return null;
235  }
236 
237  return $this->getCacheFilename($viewtype, $view, $cache_time);
238  }
239 
249  public function cacheAsset(string $viewtype, string $view, string $contents): int {
250  $filename = $this->getCacheFilename($viewtype, $view);
251  $dir = dirname($filename);
252 
253  if (!is_dir($dir)) {
254  // PHP and the server accessing the cache symlink may be a different user. And here
255  // it's safe to make everything readable anyway.
256  mkdir($dir, 0775, true);
257  }
258 
259  $result = file_put_contents($filename, $contents);
260  chmod($filename, 0664);
261 
262  return $result;
263  }
264 
274  protected function getCacheFilename(string $viewtype, string $view, int $cache_time = null): string {
275  if (!isset($cache_time)) {
276  $cache_time = $this->config->lastcache;
277  }
278 
279  $filename = $this->getPath() . "{$cache_time}/{$viewtype}/{$view}";
280  return Paths::sanitize($filename, false);
281  }
282 
289  public function isSymbolicLinked(): bool {
290  $simplecache_path = rtrim($this->getPath(), '/');
291  $symlink_path = elgg_get_root_path() . 'cache';
292 
293  return is_dir($symlink_path) && realpath($simplecache_path) === realpath($symlink_path);
294  }
295 
302  public function createSymbolicLink(): bool {
303  if ($this->isSymbolicLinked()) {
304  // symlink exists, no need to proceed
305  return true;
306  }
307 
308  $symlink_path = Paths::project() . 'cache';
309  if (is_dir($symlink_path)) {
310  // Cache directory already exists
311  // We can not proceed without overwriting files
312  return false;
313  }
314 
315  $simplecache_path = rtrim($this->getPath(), '/');
316  if (!is_dir($simplecache_path)) {
317  // Views simplecache directory has not yet been created
318  mkdir($simplecache_path, 0755, true);
319  }
320 
321  symlink($simplecache_path, $symlink_path);
322 
323  if ($this->isSymbolicLinked()) {
324  return true;
325  }
326 
327  if (is_dir($symlink_path)) {
328  unlink($symlink_path);
329  }
330 
331  return false;
332  }
333 }
isCacheableView(string $view)
Is the view cacheable.
Definition: SimpleCache.php:90
static project()
Get the project root (where composer is installed) path with "/".
Definition: Paths.php:25
getCacheFilename(string $viewtype, string $view, int $cache_time=null)
Get the cache file location.
if(parse_url(elgg_get_site_url(), PHP_URL_PATH)!== '/') if(file_exists(elgg_get_root_path(). 'robots.txt'))
Set robots.txt.
Definition: robots.php:10
getUrl(string $view)
Get the URL for the cached view.
Definition: SimpleCache.php:50
cachedAssetExists(int $cache_time, string $viewtype, string $view)
Check if a asset exists in the cache.
clear()
Deletes all cached views in the simplecache.
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it plus any associated interface definition plus the scripts used to control compilation and installation of the executable as a special the source code distributed need not include anything that is normally and so on of the operating system on which the executable unless that component itself accompanies the executable If distribution of executable or object code is made by offering access to copy from a designated then offering equivalent access to copy the source code from the same place counts as distribution of the source even though third parties are not compelled to copy the source along with the object code You may not or distribute the Program except as expressly provided under this License Any attempt otherwise to sublicense or distribute the Program is void
Definition: LICENSE.txt:215
purge()
Purge old/stale cache content.
__construct(protected Config $config, protected ViewsService $views)
Constructor.
Definition: SimpleCache.php:30
isEnabled()
Is simple cache enabled.
disable()
Disables the simple cache.
getRoot()
Get the base url for simple cache requests.
Definition: SimpleCache.php:61
$config
Advanced site settings, debugging section.
Definition: debugging.php:6
enable()
Enables the simple cache.
if(!empty($avatar)&&!$avatar->isValid()) elseif(empty($avatar)) if(!$owner->saveIconFromUploadedFile('avatar')) if(!elgg_trigger_event('profileiconupdate', $owner->type, $owner)) $view
Definition: upload.php:39
getCachedAssetLocation(int $cache_time, string $viewtype, string $view)
Get the cache location of an existing cached asset.
registerCacheableView(string $view)
Register a view as cacheable.
Definition: SimpleCache.php:79
cacheAsset(string $viewtype, string $view, string $contents)
Store an asset for caching.
elgg_get_root_path()
Get the project path (where composer is installed), ending with slash.
Views service.
$viewtype
Definition: default.php:11
elgg_delete_directory(string $directory, bool $leave_base_directory=false)
Delete a directory and all its contents.
Definition: filestore.php:51
getPath()
Returns the path to where views are simplecached.
Simple cache service.
Definition: SimpleCache.php:15
static sanitize($path, $append_slash=true)
Sanitize file paths ensuring that they begin and end with slashes etc.
Definition: Paths.php:76
elgg_normalize_url(string $url)
Definition: output.php:163
createSymbolicLink()
Symlinks /cache directory to views simplecache directory.
isSymbolicLinked()
Checks if /cache directory has been symlinked to views simplecache directory.
if(!empty($title)&&!empty($icon_name)) if(!empty($title)) if(!empty($menu)) if(!empty($header)) if(!empty($body)) $contents
Definition: message.php:73
getCacheableViews()
Returns the cacheable views.
$views
Definition: item.php:17