EGroupware /
egroupware
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * EGroupware API: Base class for all caching providers |
||
| 4 | * |
||
| 5 | * @link http://www.egroupware.org |
||
| 6 | * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License |
||
| 7 | * @package api |
||
| 8 | * @subpackage cache |
||
| 9 | * @author Ralf Becker <RalfBecker-AT-outdoor-training.de> |
||
| 10 | * @copyright (c) 2009-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de> |
||
| 11 | * @version $Id$ |
||
| 12 | */ |
||
| 13 | |||
| 14 | namespace EGroupware\Api\Cache; |
||
| 15 | |||
| 16 | /*if (isset($_SERVER['SCRIPT_FILENAME']) && realpath($_SERVER['SCRIPT_FILENAME']) == __FILE__) |
||
| 17 | { |
||
| 18 | require_once dirname(__DIR__).'/loader/common.php'; |
||
| 19 | }*/ |
||
| 20 | use EGroupware\Api; |
||
| 21 | |||
| 22 | /** |
||
| 23 | * Base class for all caching providers |
||
| 24 | * |
||
| 25 | * Implements some checks used for testing providers. |
||
| 26 | */ |
||
| 27 | abstract class Base implements Provider |
||
| 28 | { |
||
| 29 | /** |
||
| 30 | * Run several checks on a caching provider |
||
| 31 | * |
||
| 32 | * @param boolean $verbose =false true: echo failed checks |
||
| 33 | * @return int number of failed checks |
||
| 34 | */ |
||
| 35 | function check($verbose=false) |
||
| 36 | { |
||
| 37 | // set us up as provider for Api\Cache class |
||
| 38 | $GLOBALS['egw_info']['server']['install_id'] = md5(microtime(true)); |
||
| 39 | unset($GLOBALS['egw_info']['server']['cache_provider_instance']); |
||
| 40 | unset($GLOBALS['egw_info']['server']['cache_provider_tree']); |
||
| 41 | Api\Cache::$default_provider = get_class($this); |
||
|
0 ignored issues
–
show
|
|||
| 42 | |||
| 43 | $failed = 0; |
||
| 44 | foreach(array( |
||
| 45 | Api\Cache::TREE => 'tree', |
||
| 46 | Api\Cache::INSTANCE => 'instance', |
||
| 47 | ) as $level => $label) |
||
| 48 | { |
||
| 49 | $locations = array(); |
||
| 50 | foreach(array('string',123,true,false,null,array(),array(1,2,3)) as $data) |
||
| 51 | { |
||
| 52 | $location = md5(microtime(true).$label.serialize($data)); |
||
| 53 | $get_before_set = $this->get(array($level,__CLASS__,$location)); |
||
| 54 | if (!is_null($get_before_set)) |
||
| 55 | { |
||
| 56 | if ($verbose) echo "$label: get_before_set=".array2string($get_before_set)." != NULL\n"; |
||
| 57 | ++$failed; |
||
| 58 | } |
||
| 59 | if (($set = $this->set(array($level,__CLASS__,$location), $data, 10)) !== true) |
||
| 60 | { |
||
| 61 | if ($verbose) echo "$label: set returned ".array2string($set)." !== TRUE\n"; |
||
| 62 | ++$failed; |
||
| 63 | } |
||
| 64 | $get_after_set = $this->get(array($level,__CLASS__,$location)); |
||
| 65 | if ($get_after_set !== $data) |
||
| 66 | { |
||
| 67 | if ($verbose) echo "$label: get_after_set=".array2string($get_after_set)." !== ".array2string($data)."\n"; |
||
| 68 | ++$failed; |
||
| 69 | } |
||
| 70 | if (is_a($this, 'EGroupware\Api\Cache\ProviderMultiple')) |
||
| 71 | { |
||
| 72 | $mget_after_set = $this->mget(array($level,__CLASS__,array($location))); |
||
| 73 | if ($mget_after_set[$location] !== $data) |
||
| 74 | { |
||
| 75 | if ($verbose) echo "$label: mget_after_set['$location']=".array2string($mget_after_set[$location])." !== ".array2string($data)."\n"; |
||
| 76 | ++$failed; |
||
| 77 | } |
||
| 78 | } |
||
| 79 | $add_after_set = $this->add(array($level,__CLASS__,$location), 'other-data'); |
||
| 80 | if ($add_after_set !== false) |
||
| 81 | { |
||
| 82 | if ($verbose) echo "$label: add_after_set=".array2string($add_after_set)."\n"; |
||
| 83 | ++$failed; |
||
| 84 | } |
||
| 85 | if (($delete = $this->delete(array($level,__CLASS__,$location))) !== true) |
||
| 86 | { |
||
| 87 | if ($verbose) echo "$label: delete returned ".array2string($delete)." !== TRUE\n"; |
||
| 88 | ++$failed; |
||
| 89 | } |
||
| 90 | $get_after_delete = $this->get(array($level,__CLASS__,$location)); |
||
| 91 | if (!is_null($get_after_delete)) |
||
| 92 | { |
||
| 93 | if ($verbose) echo "$label: get_after_delete=".array2string($get_after_delete)." != NULL\n"; |
||
| 94 | ++$failed; |
||
| 95 | } |
||
| 96 | // prepare for mget of everything |
||
| 97 | if (is_a($this, 'EGroupware\Api\Cache\ProviderMultiple')) |
||
| 98 | { |
||
| 99 | $locations[$location] = $data; |
||
| 100 | $mget_after_delete = $this->mget(array($level,__CLASS__,array($location))); |
||
| 101 | if (isset($mget_after_delete[$location])) |
||
| 102 | { |
||
| 103 | if ($verbose) echo "$label: mget_after_delete['$location']=".array2string($mget_after_delete[$location])." != NULL\n"; |
||
| 104 | ++$failed; |
||
| 105 | } |
||
| 106 | } |
||
| 107 | elseif (!is_null($data)) // emulation can NOT distinquish between null and not set |
||
| 108 | { |
||
| 109 | $locations[$location] = $data; |
||
| 110 | } |
||
| 111 | $add_after_delete = $this->add(array($level,__CLASS__,$location), $data, 10); |
||
| 112 | if ($add_after_delete !== true) |
||
| 113 | { |
||
| 114 | if ($verbose) echo "$label: add_after_delete=".array2string($add_after_delete)."\n"; |
||
| 115 | ++$failed; |
||
| 116 | } |
||
| 117 | else |
||
| 118 | { |
||
| 119 | $get_after_add = $this->get(array($level,__CLASS__,$location)); |
||
| 120 | if ($get_after_add !== $data) |
||
| 121 | { |
||
| 122 | if ($verbose) echo "$label: get_after_add=".array2string($get_after_add)." !== ".array2string($data)."\n"; |
||
| 123 | ++$failed; |
||
| 124 | } |
||
| 125 | } |
||
| 126 | } |
||
| 127 | // get all above in one request |
||
| 128 | $keys = array_keys($locations); |
||
| 129 | $keys_bogus = array_merge(array('not-set'),array_keys($locations),array('not-set-too')); |
||
| 130 | if (is_a($this, 'EGroupware\Api\Cache\ProviderMultiple')) |
||
| 131 | { |
||
| 132 | $mget = $this->mget(array($level,__CLASS__,$keys)); |
||
| 133 | $mget_bogus = $this->mget(array($level,__CLASS__,$keys_bogus)); |
||
| 134 | /* Api\Cache::getCache() gives a different result, as it does NOT use $level direkt |
||
| 135 | } |
||
| 136 | else |
||
| 137 | { |
||
| 138 | $mget = Api\Cache::getCache($level, __CLASS__, $keys); |
||
| 139 | $mget_bogus = Api\Cache::getCache($level, __CLASS__, $keys_bogus); |
||
| 140 | }*/ |
||
| 141 | if ($mget !== $locations) |
||
| 142 | { |
||
| 143 | if ($verbose) echo "$label: mget=\n".array2string($mget)." !==\n".array2string($locations)."\n"; |
||
| 144 | ++$failed; |
||
| 145 | } |
||
| 146 | if ($mget_bogus !== $locations) |
||
| 147 | { |
||
| 148 | if ($verbose) echo "$label: mget(".array2string($keys_bogus).")=\n".array2string($mget_bogus)." !==\n".array2string($locations)."\n"; |
||
| 149 | ++$failed; |
||
| 150 | } |
||
| 151 | } |
||
| 152 | } |
||
| 153 | |||
| 154 | return $failed; |
||
| 155 | } |
||
| 156 | |||
| 157 | /** |
||
| 158 | * Delete all data under given keys |
||
| 159 | * |
||
| 160 | * Providers can return false, if they do not support flushing part of the cache (eg. memcache) |
||
| 161 | * |
||
| 162 | * @param array $keys eg. array($level,$app,$location) |
||
| 163 | * @return boolean true on success, false on error (eg. $key not set) |
||
| 164 | */ |
||
| 165 | function flush(array $keys) |
||
| 166 | { |
||
| 167 | unset($keys); // required by function signature |
||
| 168 | return false; |
||
| 169 | } |
||
| 170 | } |
||
| 171 | |||
| 172 | // some testcode, if this file is called via it's URL |
||
| 173 | // can be run on command-line: sudo php -d apc.enable_cli=1 -f api/src/Cache/Base.php |
||
| 174 | /*if (isset($_SERVER['SCRIPT_FILENAME']) && realpath($_SERVER['SCRIPT_FILENAME']) == __FILE__) |
||
| 175 | { |
||
| 176 | if (!isset($_SERVER['HTTP_HOST'])) |
||
| 177 | { |
||
| 178 | chdir(dirname(__FILE__)); // to enable our relative pathes to work |
||
| 179 | } |
||
| 180 | $GLOBALS['egw_info'] = array( |
||
| 181 | 'flags' => array( |
||
| 182 | 'noapi' => true, |
||
| 183 | ), |
||
| 184 | ); |
||
| 185 | include_once '../../../header.inc.php'; |
||
| 186 | |||
| 187 | if (isset($_SERVER['HTTP_HOST'])) echo "<pre style='whitespace: nowrap'>\n"; |
||
| 188 | |||
| 189 | foreach(array( |
||
| 190 | 'EGroupware\Api\Cache\Apcu' => array(), |
||
| 191 | 'EGroupware\Api\Cache\Apc' => array(), |
||
| 192 | 'EGroupware\Api\Cache\Memcached' => array('localhost'), |
||
| 193 | 'EGroupware\Api\Cache\Memcache' => array('localhost'), |
||
| 194 | 'EGroupware\Api\Cache\Files' => array('/tmp'), |
||
| 195 | ) as $class => $param) |
||
| 196 | { |
||
| 197 | echo "Checking $class:\n"; |
||
| 198 | try { |
||
| 199 | $start = microtime(true); |
||
| 200 | $provider = new $class($param); |
||
| 201 | $n = 100; |
||
| 202 | for($i=1; $i <= $n; ++$i) |
||
| 203 | { |
||
| 204 | $failed = $provider->check($i == 1); |
||
| 205 | } |
||
| 206 | printf("$failed checks failed, $n iterations took %5.3f sec\n\n", microtime(true)-$start); |
||
| 207 | } |
||
| 208 | catch (\Exception $e) { |
||
| 209 | printf($e->getMessage()."\n\n"); |
||
| 210 | } |
||
| 211 | } |
||
| 212 | }*/ |
||
| 213 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..