Elgg  Version 2.2
 All Classes Namespaces Files Functions Variables Pages
EntityCache.php
Go to the documentation of this file.
1 <?php
2 namespace Elgg\Cache;
3 
4 use ElggEntity;
5 use ElggSession;
6 
12 class EntityCache {
13 
14  // @todo Pick a less arbitrary limit
15  const MAX_SIZE = 256;
16 
20  private $entities = [];
21 
25  private $disabled_guids = [];
26 
30  private $session;
31 
35  private $metadata_cache;
36 
43  public function __construct(ElggSession $session, MetadataCache $metadata_cache) {
44  $this->session = $session;
45  $this->metadata_cache = $metadata_cache;
46 
47  $GLOBALS['ENTITY_CACHE'] = $this->entities;
48  }
49 
57  public function get($guid) {
58  $this->checkGlobal();
59 
60  if (isset($this->entities[$guid]) && $this->entities[$guid]->isFullyLoaded()) {
61  return $this->entities[$guid];
62  }
63 
64  return false;
65  }
66 
73  public function set(ElggEntity $entity) {
74  $this->checkGlobal();
75 
76  $guid = $entity->guid;
77 
78  if (!$guid || isset($this->entities[$guid]) || isset($this->disabled_guids[$guid])) {
79  // have it or not saved
80  return;
81  }
82 
83  // Don't cache non-plugin entities while access control is off, otherwise they could be
84  // exposed to users who shouldn't see them when control is re-enabled.
85  if (!($entity instanceof \ElggPlugin) && $this->session->getIgnoreAccess()) {
86  return;
87  }
88 
89  // Don't store too many or we'll have memory problems
90  if (count($this->entities) > self::MAX_SIZE) {
91  $this->remove(array_rand($this->entities));
92  }
93 
94  $this->entities[$guid] = $entity;
95  $GLOBALS['ENTITY_CACHE'] = $this->entities;
96  }
97 
104  public function remove($guid) {
105  $this->checkGlobal();
106 
107  $guid = (int)$guid;
108 
109  if (!isset($this->entities[$guid])) {
110  return;
111  }
112 
113  unset($this->entities[$guid]);
114  $GLOBALS['ENTITY_CACHE'] = $this->entities;
115 
116  // Purge separate metadata cache. Original idea was to do in entity destructor, but that would
117  // have caused a bunch of unnecessary purges at every shutdown. Doing it this way we have no way
118  // to know that the expunged entity will be GCed (might be another reference living), but that's
119  // OK; the metadata will reload if necessary.
120  $this->metadata_cache->clear($guid);
121  }
122 
128  public function clear() {
129  $this->checkGlobal();
130  $this->entities = [];
131  $GLOBALS['ENTITY_CACHE'] = $this->entities;
132  }
133 
142  public function disableCachingForEntity($guid) {
143  $this->remove($guid);
144  $this->disabled_guids[$guid] = true;
145  }
146 
153  public function enableCachingForEntity($guid) {
154  unset($this->disabled_guids[$guid]);
155  }
156 
163  private function checkGlobal() {
164  if (!isset($GLOBALS['ENTITY_CACHE']) || ($GLOBALS['ENTITY_CACHE'] !== $this->entities)) {
165  $GLOBALS['ENTITY_CACHE'] = $this->entities;
166  elgg_deprecated_notice('Do not access or write to the global $ENTITY_CACHE.', '2.2');
167  }
168  }
169 }
set(ElggEntity $entity)
Cache an entity.
Definition: EntityCache.php:73
$guid
Removes an admin notice.
disableCachingForEntity($guid)
Remove this entity from the entity cache and make sure it is not re-added.
Volatile cache for entities.
Definition: EntityCache.php:12
elgg_deprecated_notice($msg, $dep_version, $backtrace_level=1)
Log a notice about deprecated use of a function, view, etc.
Definition: elgglib.php:1070
__construct(ElggSession $session, MetadataCache $metadata_cache)
Constructor.
Definition: EntityCache.php:43
clear()
Clear the entity cache.
In memory cache of known metadata values stored by entity.
$entity
Definition: delete.php:7
enableCachingForEntity($guid)
Allow this entity to be stored in the entity cache.