TYPO3 CMS  TYPO3_6-2
XcacheBackend.php
Go to the documentation of this file.
1 <?php
3 
18 
42 
48  protected $identifierPrefix;
49 
57  public function __construct($context, array $options = array()) {
58  if (!extension_loaded('xcache')) {
59  throw new Exception(
60  'The PHP extension "xcache" must be installed and loaded in order to use the xcache backend.',
61  1363116592
62  );
63  }
64  parent::__construct($context, $options);
65  }
66 
78  public function set($entryIdentifier, $data, array $tags = array(), $lifetime = NULL) {
80  return;
81  }
82  if (!$this->cache instanceof \TYPO3\CMS\Core\Cache\Frontend\FrontendInterface) {
83  throw new Exception(
84  'No cache frontend has been set yet via setCache().',
85  1363117491
86  );
87  }
88  if (!is_string($data)) {
89  throw new Exception\InvalidDataException(
90  'The specified data is of type "' . gettype($data) . '" but a string is expected.',
91  1363117435
92  );
93  }
94  $tags[] = '%XCBE%' . $this->cache->getIdentifier();
95  $expiration = $lifetime !== NULL ? $lifetime : $this->defaultLifetime;
96  $success = xcache_set($this->identifierPrefix . $entryIdentifier, $data, $expiration);
97  if ($success === TRUE) {
98  $this->removeIdentifierFromAllTags($entryIdentifier);
99  $this->addIdentifierToTags($entryIdentifier, $tags);
100  } else {
101  throw new Exception(
102  'Could not set value.',
103  1363117507
104  );
105  }
106  }
107 
114  public function get($entryIdentifier) {
115  if ($this->runningFromCliOrWrongConfiguration()) {
116  return FALSE;
117  }
118  $value = xcache_get($this->identifierPrefix . $entryIdentifier);
119  return $value ?: FALSE;
120  }
121 
128  public function has($entryIdentifier) {
129  if ($this->runningFromCliOrWrongConfiguration()) {
130  return FALSE;
131  }
132  return xcache_isset($this->identifierPrefix . $entryIdentifier);
133  }
134 
143  public function remove($entryIdentifier) {
144  if ($this->runningFromCliOrWrongConfiguration()) {
145  return FALSE;
146  }
147  $this->removeIdentifierFromAllTags($entryIdentifier);
148  return xcache_unset($this->identifierPrefix . $entryIdentifier);
149  }
150 
158  public function findIdentifiersByTag($tag) {
159  if ($this->runningFromCliOrWrongConfiguration()) {
160  return array();
161  }
162  $identifiers = xcache_get($this->identifierPrefix . 'tag_' . $tag);
163  return $identifiers ?: array();
164  }
165 
173  protected function findTagsByIdentifier($identifier) {
174  if ($this->runningFromCliOrWrongConfiguration()) {
175  return array();
176  }
177  $tags = xcache_get($this->identifierPrefix . 'ident_' . $identifier);
178  return $tags ?: array();
179  }
180 
187  public function flush() {
188  if ($this->runningFromCliOrWrongConfiguration()) {
189  return;
190  }
191  if (!$this->cache instanceof \TYPO3\CMS\Core\Cache\Frontend\FrontendInterface) {
192  throw new Exception(
193  'Yet no cache frontend has been set via setCache().',
194  1363117531
195  );
196  }
197  $this->flushByTag('%XCBE%' . $this->cache->getIdentifier());
198  }
199 
207  public function flushByTag($tag) {
208  $identifiers = $this->findIdentifiersByTag($tag);
209  foreach ($identifiers as $identifier) {
210  $this->remove($identifier);
211  }
212  }
213 
221  protected function addIdentifierToTags($entryIdentifier, array $tags) {
222  if ($this->runningFromCliOrWrongConfiguration()) {
223  return;
224  }
225 
226  // Get identifier-to-tag index to look for updates
227  $existingTags = $this->findTagsByIdentifier($entryIdentifier);
228  $existingTagsUpdated = FALSE;
229 
230 
231  foreach ($tags as $tag) {
232  // Update tag-to-identifier index
233  $identifiers = $this->findIdentifiersByTag($tag);
234  if (!in_array($entryIdentifier, $identifiers, TRUE)) {
235  $identifiers[] = $entryIdentifier;
236  xcache_set($this->identifierPrefix . 'tag_' . $tag, $identifiers);
237  }
238  // Test if identifier-to-tag index needs update
239  if (!in_array($tag, $existingTags, TRUE)) {
240  $existingTags[] = $tag;
241  $existingTagsUpdated = TRUE;
242  }
243  }
244 
245  // Update identifier-to-tag index if needed
246  if ($existingTagsUpdated) {
247  xcache_set($this->identifierPrefix . 'ident_' . $entryIdentifier, $existingTags);
248  }
249  }
250 
257  protected function removeIdentifierFromAllTags($entryIdentifier) {
258  if ($this->runningFromCliOrWrongConfiguration()) {
259  return;
260  }
261  // Get tags for this identifier
262  $tags = $this->findTagsByIdentifier($entryIdentifier);
263  // Disassociate tags with this identifier
264  foreach ($tags as $tag) {
265  $identifiers = $this->findIdentifiersByTag($tag);
266  // Formally array_search() below should never return false due to
267  // the behavior of findTagsByIdentifier(). But if reverse index is
268  // corrupted, we still can get 'false' from array_search(). This is
269  // not a problem because we are removing this identifier from
270  // anywhere.
271  if (($key = array_search($entryIdentifier, $identifiers)) !== FALSE) {
272  unset($identifiers[$key]);
273  if (count($identifiers)) {
274  xcache_set($this->identifierPrefix . 'tag_' . $tag, $identifiers);
275  } else {
276  xcache_unset($this->identifierPrefix . 'tag_' . $tag);
277  }
278  }
279  }
280  // Clear reverse tag index for this identifier
281  xcache_unset($this->identifierPrefix . 'ident_' . $entryIdentifier);
282  }
283 
289  public function collectGarbage() {
290  }
291 
299  protected function runningFromCliOrWrongConfiguration() {
300  $varSize = ini_get('xcache.var_size');
301  return php_sapi_name() === 'cli' || empty($varSize);
302  }
303 }
__construct($context, array $options=array())
addIdentifierToTags($entryIdentifier, array $tags)