Elgg  Version 1.11
MetadataCache.php
Go to the documentation of this file.
1 <?php
2 namespace Elgg\Cache;
3 
9 class MetadataCache {
10 
16  protected $values = array();
17 
21  protected $session;
22 
28  public function __construct(\ElggSession $session) {
29  $this->session = $session;
30  }
31 
43  public function inject($entity_guid, array $values) {
44  $this->values[$this->getAccessKey()][$entity_guid] = $values;
45  }
46 
60  public function getSingle($entity_guid, $name) {
61  $access_key = $this->getAccessKey();
62 
63  if (isset($this->values[$access_key][$entity_guid])
64  && array_key_exists($name, $this->values[$access_key][$entity_guid])) {
65  return $this->values[$access_key][$entity_guid][$name];
66  } else {
67  return null;
68  }
69  }
70 
77  public function clear($entity_guid) {
78  foreach (array_keys($this->values) as $access_key) {
79  unset($this->values[$access_key][$entity_guid]);
80  }
81  }
82 
89  public function isLoaded($entity_guid) {
90  $access_key = $this->getAccessKey();
91 
92  if (empty($this->values[$access_key])) {
93  return false;
94  }
95  return array_key_exists($entity_guid, $this->values[$access_key]);
96  }
97 
103  public function clearAll() {
104  $this->values = array();
105  }
106 
114  public function invalidateByOptions(array $options) {
115  if (empty($options['guid'])) {
116  $this->clearAll();
117  } else {
118  $this->clear($options['guid']);
119  }
120  }
121 
128  public function populateFromEntities($guids) {
129  if (empty($guids)) {
130  return;
131  }
132 
133  $access_key = $this->getAccessKey();
134 
135  if (!is_array($guids)) {
136  $guids = array($guids);
137  }
138  $guids = array_unique($guids);
139 
140  // could be useful at some point in future
141  //$guids = $this->filterMetadataHeavyEntities($guids);
142 
143  $db_prefix = _elgg_services()->db->getTablePrefix();
144  $options = array(
145  'guids' => $guids,
146  'limit' => 0,
147  'callback' => false,
148  'distinct' => false,
149  'joins' => array(
150  "JOIN {$db_prefix}metastrings v ON n_table.value_id = v.id",
151  "JOIN {$db_prefix}metastrings n ON n_table.name_id = n.id",
152  ),
153  'selects' => array('n.string AS name', 'v.string AS value'),
154  'order_by' => 'n_table.entity_guid, n_table.time_created ASC, n_table.id ASC',
155 
156  // @todo don't know why this is necessary
157  'wheres' => array(_elgg_get_access_where_sql(array('table_alias' => 'n_table'))),
158  );
159  $data = _elgg_services()->metadataTable->getAll($options);
160 
161  // make sure we show all entities as loaded
162  foreach ($guids as $guid) {
163  $this->values[$access_key][$guid] = null;
164  }
165 
166  // build up metadata for each entity, save when GUID changes (or data ends)
167  $last_guid = null;
168  $metadata = array();
169  $last_row_idx = count($data) - 1;
170  foreach ($data as $i => $row) {
171  $name = $row->name;
172  $value = ($row->value_type === 'text') ? $row->value : (int) $row->value;
173  $guid = $row->entity_guid;
174  if ($guid !== $last_guid) {
175  if ($last_guid) {
176  $this->values[$access_key][$last_guid] = $metadata;
177  }
178  $metadata = array();
179  }
180  if (isset($metadata[$name])) {
181  $metadata[$name] = (array) $metadata[$name];
182  $metadata[$name][] = $value;
183  } else {
185  }
186  if (($i == $last_row_idx)) {
187  $this->values[$access_key][$guid] = $metadata;
188  }
189  $last_guid = $guid;
190  }
191  }
192 
202  public function filterMetadataHeavyEntities(array $guids, $limit = 1024000) {
203  $db_prefix = _elgg_services()->config->get('dbprefix');
204 
205  $options = array(
206  'guids' => $guids,
207  'limit' => 0,
208  'callback' => false,
209  'joins' => "JOIN {$db_prefix}metastrings v ON n_table.value_id = v.id",
210  'selects' => array('SUM(LENGTH(v.string)) AS bytes'),
211  'order_by' => 'n_table.entity_guid, n_table.time_created ASC',
212  'group_by' => 'n_table.entity_guid',
213  );
214  $data = _elgg_services()->metadataTable->getAll($options);
215  // don't cache if metadata for entity is over 10MB (or rolled INT)
216  foreach ($data as $row) {
217  if ($row->bytes > $limit || $row->bytes < 0) {
218  array_splice($guids, array_search($row->entity_guid, $guids), 1);
219  }
220  }
221  return $guids;
222  }
223 
229  protected function getAccessKey() {
230  if ($this->session->getIgnoreAccess()) {
231  return "ignored";
232  }
233  return (string)$this->session->getLoggedInUserGuid();
234  }
235 }
invalidateByOptions(array $options)
Invalidate based on options passed to the global *_metadata functions.
if($guid==elgg_get_logged_in_user_guid()) $name
Definition: delete.php:21
$metadata
Definition: entity.php:19
$data
Definition: opendd.php:13
$value
Definition: longtext.php:26
clear($entity_guid)
Forget about all metadata for an entity.
$guid
Removes an admin notice.
__construct(\ElggSession $session)
Constructor.
populateFromEntities($guids)
Populate the cache from a set of entities.
isLoaded($entity_guid)
If true, getSingle() will return an accurate values from the DB.
getSingle($entity_guid, $name)
Get the metadata for a particular name.
$entity_guid
Definition: save.php:9
$options
Definition: index.php:14
inject($entity_guid, array $values)
Set the visible metadata for an entity in the cache.
clearAll()
Clear entire cache.
$limit
Definition: userpicker.php:31
_elgg_services()
Definition: autoloader.php:14
filterMetadataHeavyEntities(array $guids, $limit=1024000)
Filter out entities whose concatenated metadata values (INTs casted as string) exceed a threshold in ...
$guids
In memory cache of known metadata values stored by entity.
$row
_elgg_get_access_where_sql(array $options=array())
Returns the SQL where clause for enforcing read access to data.
Definition: access.php:216
getAccessKey()
Get a key to represent the access ability of the system.
if(!$num_display) $db_prefix
Definition: content.php:12