TYPO3 CMS  TYPO3_6-2
ApcBackend.php
Go to the documentation of this file.
1 <?php
3 
45 
51  protected $identifierPrefix;
52 
58  protected function setIdentifierPrefix($identifierPrefix) {
59  $this->identifierPrefix = $identifierPrefix;
60  }
61 
67  protected function getIdentifierPrefix() {
69  }
70 
78  public function __construct($context, array $options = array()) {
79  if (!extension_loaded('apc')) {
80  throw new \TYPO3\CMS\Core\Cache\Exception('The PHP extension "apc" or "apcu" must be installed and loaded in order to use the APC backend.', 1232985414);
81  }
82  if (PHP_SAPI === 'cli' && ini_get('apc.enable_cli') == 0) {
83  throw new \TYPO3\CMS\Core\Cache\Exception('The APC backend cannot be used because apc is disabled on CLI.', 1232985415);
84  }
85  parent::__construct($context, $options);
86  }
87 
94  public function setCache(\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $cache) {
95  parent::setCache($cache);
96  $processUser = $this->getCurrentUserData();
97  $pathHash = \TYPO3\CMS\Core\Utility\GeneralUtility::shortMD5($this->getPathSite() . $processUser['name'] . $this->context . $cache->getIdentifier(), 12);
98  $this->setIdentifierPrefix('TYPO3_' . $pathHash);
99  }
100 
107  protected function getCurrentUserData() {
108  return extension_loaded('posix') ? posix_getpwuid(posix_geteuid()) : array('name' => 'default');
109  }
110 
116  protected function getPathSite() {
117  return PATH_site;
118  }
119 
132  public function set($entryIdentifier, $data, array $tags = array(), $lifetime = NULL) {
133  if (!$this->cache instanceof \TYPO3\CMS\Core\Cache\Frontend\FrontendInterface) {
134  throw new \TYPO3\CMS\Core\Cache\Exception('No cache frontend has been set yet via setCache().', 1232986818);
135  }
136  if (!is_string($data)) {
137  throw new \TYPO3\CMS\Core\Cache\Exception\InvalidDataException('The specified data is of type "' . gettype($data) . '" but a string is expected.', 1232986825);
138  }
139  $tags[] = '%APCBE%' . $this->cacheIdentifier;
140  $expiration = $lifetime !== NULL ? $lifetime : $this->defaultLifetime;
141  $success = apc_store($this->getIdentifierPrefix() . $entryIdentifier, $data, $expiration);
142  if ($success === TRUE) {
143  $this->removeIdentifierFromAllTags($entryIdentifier);
144  $this->addIdentifierToTags($entryIdentifier, $tags);
145  } else {
146  throw new \TYPO3\CMS\Core\Cache\Exception('Could not set value.', 1232986877);
147  }
148  }
149 
157  public function get($entryIdentifier) {
158  $success = FALSE;
159  $value = apc_fetch($this->getIdentifierPrefix() . $entryIdentifier, $success);
160  return $success ? $value : $success;
161  }
162 
170  public function has($entryIdentifier) {
171  $success = FALSE;
172  apc_fetch($this->getIdentifierPrefix() . $entryIdentifier, $success);
173  return $success;
174  }
175 
185  public function remove($entryIdentifier) {
186  $this->removeIdentifierFromAllTags($entryIdentifier);
187  return apc_delete($this->getIdentifierPrefix() . $entryIdentifier);
188  }
189 
198  public function findIdentifiersByTag($tag) {
199  $success = FALSE;
200  $identifiers = apc_fetch($this->getIdentifierPrefix() . 'tag_' . $tag, $success);
201  if ($success === FALSE) {
202  return array();
203  } else {
204  return (array) $identifiers;
205  }
206  }
207 
215  protected function findTagsByIdentifier($identifier) {
216  $success = FALSE;
217  $tags = apc_fetch($this->getIdentifierPrefix() . 'ident_' . $identifier, $success);
218  return $success ? (array) $tags : array();
219  }
220 
228  public function flush() {
229  if (!$this->cache instanceof \TYPO3\CMS\Core\Cache\Frontend\FrontendInterface) {
230  throw new \TYPO3\CMS\Core\Cache\Exception('Yet no cache frontend has been set via setCache().', 1232986971);
231  }
232  $this->flushByTag('%APCBE%' . $this->cacheIdentifier);
233  }
234 
242  public function flushByTag($tag) {
243  $identifiers = $this->findIdentifiersByTag($tag);
244  foreach ($identifiers as $identifier) {
245  $this->remove($identifier);
246  }
247  }
248 
256  protected function addIdentifierToTags($entryIdentifier, array $tags) {
257  // Get identifier-to-tag index to look for updates
258  $existingTags = $this->findTagsByIdentifier($entryIdentifier);
259  $existingTagsUpdated = FALSE;
260 
261  foreach ($tags as $tag) {
262  // Update tag-to-identifier index
263  $identifiers = $this->findIdentifiersByTag($tag);
264  if (!in_array($entryIdentifier, $identifiers, TRUE)) {
265  $identifiers[] = $entryIdentifier;
266  apc_store($this->getIdentifierPrefix() . 'tag_' . $tag, $identifiers);
267  }
268  // Test if identifier-to-tag index needs update
269  if (!in_array($tag, $existingTags, TRUE)) {
270  $existingTags[] = $tag;
271  $existingTagsUpdated = TRUE;
272  }
273  }
274 
275  // Update identifier-to-tag index if needed
276  if ($existingTagsUpdated) {
277  apc_store($this->getIdentifierPrefix() . 'ident_' . $entryIdentifier, $existingTags);
278  }
279  }
280 
287  protected function removeIdentifierFromAllTags($entryIdentifier) {
288  // Get tags for this identifier
289  $tags = $this->findTagsByIdentifier($entryIdentifier);
290  // Deassociate tags with this identifier
291  foreach ($tags as $tag) {
292  $identifiers = $this->findIdentifiersByTag($tag);
293  // Formally array_search() below should never return FALSE due to
294  // the behavior of findTagsByIdentifier(). But if reverse index is
295  // corrupted, we still can get 'FALSE' from array_search(). This is
296  // not a problem because we are removing this identifier from
297  // anywhere.
298  if (($key = array_search($entryIdentifier, $identifiers)) !== FALSE) {
299  unset($identifiers[$key]);
300  if (count($identifiers)) {
301  apc_store($this->getIdentifierPrefix() . 'tag_' . $tag, $identifiers);
302  } else {
303  apc_delete($this->getIdentifierPrefix() . 'tag_' . $tag);
304  }
305  }
306  }
307  // Clear reverse tag index for this identifier
308  apc_delete($this->getIdentifierPrefix() . 'ident_' . $entryIdentifier);
309  }
310 
316  public function collectGarbage() {
317 
318  }
319 
320 }
__construct($context, array $options=array())
Definition: ApcBackend.php:78
setCache(\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $cache)
Definition: ApcBackend.php:94
addIdentifierToTags($entryIdentifier, array $tags)
Definition: ApcBackend.php:256
removeIdentifierFromAllTags($entryIdentifier)
Definition: ApcBackend.php:287