Elgg  Version 2.2
 All Classes Namespaces Files Functions Variables Pages
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(
158  'table_alias' => 'n_table',
159  'guid_column' => 'entity_guid',
160  ))),
161  );
162  $data = _elgg_services()->metadataTable->getAll($options);
163 
164  // make sure we show all entities as loaded
165  foreach ($guids as $guid) {
166  $this->values[$access_key][$guid] = null;
167  }
168 
169  // build up metadata for each entity, save when GUID changes (or data ends)
170  $last_guid = null;
171  $metadata = array();
172  $last_row_idx = count($data) - 1;
173  foreach ($data as $i => $row) {
174  $name = $row->name;
175  $value = ($row->value_type === 'text') ? $row->value : (int) $row->value;
176  $guid = $row->entity_guid;
177  if ($guid !== $last_guid) {
178  if ($last_guid) {
179  $this->values[$access_key][$last_guid] = $metadata;
180  }
181  $metadata = array();
182  }
183  if (isset($metadata[$name])) {
184  $metadata[$name] = (array) $metadata[$name];
185  $metadata[$name][] = $value;
186  } else {
188  }
189  if (($i == $last_row_idx)) {
190  $this->values[$access_key][$guid] = $metadata;
191  }
192  $last_guid = $guid;
193  }
194  }
195 
205  public function filterMetadataHeavyEntities(array $guids, $limit = 1024000) {
206  $db_prefix = _elgg_services()->config->get('dbprefix');
207 
208  $options = array(
209  'guids' => $guids,
210  'limit' => 0,
211  'callback' => false,
212  'joins' => "JOIN {$db_prefix}metastrings v ON n_table.value_id = v.id",
213  'selects' => array('SUM(LENGTH(v.string)) AS bytes'),
214  'order_by' => 'n_table.entity_guid, n_table.time_created ASC',
215  'group_by' => 'n_table.entity_guid',
216  );
217  $data = _elgg_services()->metadataTable->getAll($options);
218  // don't cache if metadata for entity is over 10MB (or rolled INT)
219  foreach ($data as $row) {
220  if ($row->bytes > $limit || $row->bytes < 0) {
221  array_splice($guids, array_search($row->entity_guid, $guids), 1);
222  }
223  }
224  return $guids;
225  }
226 
232  protected function getAccessKey() {
233  if ($this->session->getIgnoreAccess()) {
234  return "ignored";
235  }
236  return (string)$this->session->getLoggedInUserGuid();
237  }
238 }
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.
$options
Elgg admin footer.
Definition: footer.php:6
$entity_guid
Definition: save.php:9
inject($entity_guid, array $values)
Set the visible metadata for an entity in the cache.
clearAll()
Clear entire cache.
$limit
Definition: userpicker.php:38
filterMetadataHeavyEntities(array $guids, $limit=1024000)
Filter out entities whose concatenated metadata values (INTs casted as string) exceed a threshold in ...
_elgg_services(\Elgg\Di\ServiceProvider $services=null)
Get the global service provider.
Definition: autoloader.php:17
$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:214
getAccessKey()
Get a key to represent the access ability of the system.
if(!$num_display) $db_prefix
Definition: content.php:12