1<?php 2 3/* 4 * This file is part of the Stash package. 5 * 6 * (c) Robert Hafner <tedivm@tedivm.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Stash\Driver; 13 14use Stash; 15 16/** 17 * The ephemeral class exists to assist with testing the main Stash class. Since this is a very minimal driver we can 18 * test Stash without having to worry about underlying problems interfering. 19 * 20 * @package Stash 21 * @author Robert Hafner <tedivm@tedivm.com> 22 */ 23class Ephemeral extends AbstractDriver 24{ 25 /** 26 * Contains the cached data. 27 * 28 * @var array 29 */ 30 protected $store = array(); 31 32 protected $maxItems = 0; 33 34 public function getDefaultOptions() 35 { 36 return ['maxItems' => 0]; 37 } 38 39 /** 40 * Allows setting maxItems. 41 * 42 * @param array $options 43 * If maxItems is 0, infinite items will be cached 44 */ 45 protected function setOptions(array $options = array()) 46 { 47 $options += $this->getDefaultOptions(); 48 49 if (array_key_exists('maxItems', $options)) { 50 $maxItems = $options['maxItems']; 51 if (!is_int($maxItems) || $maxItems < 0) { 52 throw new Stash\Exception\InvalidArgumentException( 53 'maxItems must be a positive integer.' 54 ); 55 } 56 $this->maxItems = $maxItems; 57 if ($this->maxItems > 0 && count($this->store) > $this->maxItems) { 58 $this->evict(count($this->store) - $this->maxItems); 59 } 60 } 61 } 62 63 /** 64 * Evicts the first $count items that were added to the store. 65 * 66 * Subclasses could implement more advanced eviction policies. 67 * 68 * @param int $count 69 */ 70 protected function evict($count) 71 { 72 while ( 73 $count-- > 0 74 && array_shift($this->store) !== null 75 ) { 76 } 77 } 78 79 /** 80 * {@inheritdoc} 81 */ 82 public function getData($key) 83 { 84 $key = $this->getKeyIndex($key); 85 86 return isset($this->store[$key]) ? $this->store[$key] : false; 87 } 88 89 /** 90 * Converts the key array into a passed function 91 * 92 * @param array $key 93 * @return string 94 */ 95 protected function getKeyIndex($key) 96 { 97 $index = ''; 98 foreach ($key as $value) { 99 $index .= str_replace('#', '#:', $value) . '#'; 100 } 101 102 return $index; 103 } 104 105 /** 106 * {@inheritdoc} 107 */ 108 public function storeData($key, $data, $expiration) 109 { 110 if ($this->maxItems > 0 && count($this->store) >= $this->maxItems) { 111 $this->evict((count($this->store) + 1) - $this->maxItems); 112 } 113 114 $this->store[$this->getKeyIndex($key)] = array('data' => $data, 'expiration' => $expiration); 115 116 return true; 117 } 118 119 /** 120 * {@inheritdoc} 121 */ 122 public function clear($key = null) 123 { 124 if (!isset($key)) { 125 $this->store = array(); 126 } else { 127 $clearIndex = $this->getKeyIndex($key); 128 foreach ($this->store as $index => $data) { 129 if (strpos($index, $clearIndex) === 0) { 130 unset($this->store[$index]); 131 } 132 } 133 } 134 135 return true; 136 } 137 138 /** 139 * {@inheritdoc} 140 */ 141 public function purge() 142 { 143 $now = time(); 144 foreach ($this->store as $index => $data) { 145 if ($data['expiration'] <= $now) { 146 unset($this->store[$index]); 147 } 148 } 149 150 return true; 151 } 152} 153