作者 王智

'easywechat'

正在显示 56 个修改的文件 包含 4425 行增加138 行删除

要显示太多修改。

为保证性能只显示 56 of 56+ 个文件。

@@ -8,7 +8,8 @@ use app\common\model\Version; @@ -8,7 +8,8 @@ use app\common\model\Version;
8 use Qiniu\Auth; 8 use Qiniu\Auth;
9 use think\Config; 9 use think\Config;
10 use think\Hook; 10 use think\Hook;
11 -use EasyWeChat\Factory; 11 +//use EasyWeChat\Factory;
  12 +use EasyWeChat\Foundation\Application;
12 use think\Db; 13 use think\Db;
13 use app\common\model\Attachment; 14 use app\common\model\Attachment;
14 use think\process\exception\Timeout; 15 use think\process\exception\Timeout;
@@ -429,9 +430,10 @@ class Common extends Api @@ -429,9 +430,10 @@ class Common extends Api
429 'key_path' => '/home/wwwroot/fast/book/addons/epay/certs/apiclient_key.pem', // XXX: 绝对路径!!!! 430 'key_path' => '/home/wwwroot/fast/book/addons/epay/certs/apiclient_key.pem', // XXX: 绝对路径!!!!
430 ], 431 ],
431 ]; 432 ];
432 - $app = Factory::officialAccount($config); 433 + $app = new Application($config);
  434 + $payment = $app->payment;
433 try { 435 try {
434 - $result = $app->refund->byTransactionId($PayOrderInfo['WeChatOrder'], $PayOrderInfo['PayOrder'], $PayOrderInfo['money'] * 100, $TuiMoney * 100); // 总金额 100, 退款 80,操作员:商户号 436 + $result = $payment->refundByTransactionId($PayOrderInfo['WeChatOrder'], $PayOrderInfo['PayOrder'], $PayOrderInfo['money'] * 100, $TuiMoney * 100); // 总金额 100, 退款 80,操作员:商户号
435 //更改订单状态为已退款 437 //更改订单状态为已退款
436 Db::name('pay_order')->where('OrderSn', $OrderSn['OrderSn'])->where('PayOrder', $PayOrderInfo['PayOrder'])->update(['type' => 0]); 438 Db::name('pay_order')->where('OrderSn', $OrderSn['OrderSn'])->where('PayOrder', $PayOrderInfo['PayOrder'])->update(['type' => 0]);
437 } catch (Exception $e) { 439 } catch (Exception $e) {
@@ -512,9 +514,10 @@ class Common extends Api @@ -512,9 +514,10 @@ class Common extends Api
512 'key_path' => '/home/wwwroot/fast/book/addons/epay/certs/apiclient_key.pem', // XXX: 绝对路径!!!! 514 'key_path' => '/home/wwwroot/fast/book/addons/epay/certs/apiclient_key.pem', // XXX: 绝对路径!!!!
513 ], 515 ],
514 ]; 516 ];
515 - $app = Factory::officialAccount($config); 517 + $app = new Application($config);
  518 + $payment = $app->payment;
516 try { 519 try {
517 - $result = $app->refund->byTransactionId($PayOrderInfo['WeChatOrder'], $PayOrderInfo['PayOrder'], $PayOrderInfo['money'] * 100, $TuiMoney * 100); // 总金额 100, 退款 80,操作员:商户号 520 + $result = $payment->refundByTransactionId($PayOrderInfo['WeChatOrder'], $PayOrderInfo['PayOrder'], $PayOrderInfo['money'] * 100, $TuiMoney * 100); // 总金额 100, 退款 80,操作员:商户号
518 //更改订单状态为已退款 521 //更改订单状态为已退款
519 Db::name('pay_order')->where('OrderSn', $OrderSn)->where('PayOrder', $PayOrderInfo['PayOrder'])->update(['type' => 0]); 522 Db::name('pay_order')->where('OrderSn', $OrderSn)->where('PayOrder', $PayOrderInfo['PayOrder'])->update(['type' => 0]);
520 } catch (Exception $e) { 523 } catch (Exception $e) {
@@ -22,12 +22,12 @@ @@ -22,12 +22,12 @@
22 "karsonzhang/fastadmin-addons": "~1.2.4", 22 "karsonzhang/fastadmin-addons": "~1.2.4",
23 "overtrue/pinyin": "~3.0", 23 "overtrue/pinyin": "~3.0",
24 "phpoffice/phpspreadsheet": "^1.2", 24 "phpoffice/phpspreadsheet": "^1.2",
25 - "overtrue/wechat": "4.2.11",  
26 "nelexa/zip": "^3.3", 25 "nelexa/zip": "^3.3",
27 "symfony/var-exporter": "^4.4.13", 26 "symfony/var-exporter": "^4.4.13",
28 "ext-json": "*", 27 "ext-json": "*",
29 "ext-curl": "*", 28 "ext-curl": "*",
30 - "ext-pdo": "*" 29 + "ext-pdo": "*",
  30 + "overtrue/wechat": "~3.1"
31 }, 31 },
32 "config": { 32 "config": {
33 "preferred-install": "dist" 33 "preferred-install": "dist"
@@ -2,6 +2,6 @@ @@ -2,6 +2,6 @@
2 2
3 // autoload.php @generated by Composer 3 // autoload.php @generated by Composer
4 4
5 -require_once __DIR__ . '/composer' . '/autoload_real.php'; 5 +require_once __DIR__ . '/composer/autoload_real.php';
6 6
7 return ComposerAutoloaderInitf00349b72964a05454b796bb539364c1::getLoader(); 7 return ComposerAutoloaderInitf00349b72964a05454b796bb539364c1::getLoader();
@@ -55,6 +55,7 @@ class ClassLoader @@ -55,6 +55,7 @@ class ClassLoader
55 private $classMap = array(); 55 private $classMap = array();
56 private $classMapAuthoritative = false; 56 private $classMapAuthoritative = false;
57 private $missingClasses = array(); 57 private $missingClasses = array();
  58 + private $apcuPrefix;
58 59
59 public function getPrefixes() 60 public function getPrefixes()
60 { 61 {
@@ -272,6 +273,26 @@ class ClassLoader @@ -272,6 +273,26 @@ class ClassLoader
272 } 273 }
273 274
274 /** 275 /**
  276 + * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
  277 + *
  278 + * @param string|null $apcuPrefix
  279 + */
  280 + public function setApcuPrefix($apcuPrefix)
  281 + {
  282 + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
  283 + }
  284 +
  285 + /**
  286 + * The APCu prefix in use, or null if APCu caching is not enabled.
  287 + *
  288 + * @return string|null
  289 + */
  290 + public function getApcuPrefix()
  291 + {
  292 + return $this->apcuPrefix;
  293 + }
  294 +
  295 + /**
275 * Registers this instance as an autoloader. 296 * Registers this instance as an autoloader.
276 * 297 *
277 * @param bool $prepend Whether to prepend the autoloader or not 298 * @param bool $prepend Whether to prepend the autoloader or not
@@ -313,11 +334,6 @@ class ClassLoader @@ -313,11 +334,6 @@ class ClassLoader
313 */ 334 */
314 public function findFile($class) 335 public function findFile($class)
315 { 336 {
316 - // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731  
317 - if ('\\' == $class[0]) {  
318 - $class = substr($class, 1);  
319 - }  
320 -  
321 // class map lookup 337 // class map lookup
322 if (isset($this->classMap[$class])) { 338 if (isset($this->classMap[$class])) {
323 return $this->classMap[$class]; 339 return $this->classMap[$class];
@@ -325,6 +341,12 @@ class ClassLoader @@ -325,6 +341,12 @@ class ClassLoader
325 if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { 341 if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
326 return false; 342 return false;
327 } 343 }
  344 + if (null !== $this->apcuPrefix) {
  345 + $file = apcu_fetch($this->apcuPrefix.$class, $hit);
  346 + if ($hit) {
  347 + return $file;
  348 + }
  349 + }
328 350
329 $file = $this->findFileWithExtension($class, '.php'); 351 $file = $this->findFileWithExtension($class, '.php');
330 352
@@ -333,6 +355,10 @@ class ClassLoader @@ -333,6 +355,10 @@ class ClassLoader
333 $file = $this->findFileWithExtension($class, '.hh'); 355 $file = $this->findFileWithExtension($class, '.hh');
334 } 356 }
335 357
  358 + if (null !== $this->apcuPrefix) {
  359 + apcu_add($this->apcuPrefix.$class, $file);
  360 + }
  361 +
336 if (false === $file) { 362 if (false === $file) {
337 // Remember that this class does not exist. 363 // Remember that this class does not exist.
338 $this->missingClasses[$class] = true; 364 $this->missingClasses[$class] = true;
@@ -348,10 +374,14 @@ class ClassLoader @@ -348,10 +374,14 @@ class ClassLoader
348 374
349 $first = $class[0]; 375 $first = $class[0];
350 if (isset($this->prefixLengthsPsr4[$first])) { 376 if (isset($this->prefixLengthsPsr4[$first])) {
351 - foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {  
352 - if (0 === strpos($class, $prefix)) {  
353 - foreach ($this->prefixDirsPsr4[$prefix] as $dir) {  
354 - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { 377 + $subPath = $class;
  378 + while (false !== $lastPos = strrpos($subPath, '\\')) {
  379 + $subPath = substr($subPath, 0, $lastPos);
  380 + $search = $subPath . '\\';
  381 + if (isset($this->prefixDirsPsr4[$search])) {
  382 + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
  383 + foreach ($this->prefixDirsPsr4[$search] as $dir) {
  384 + if (file_exists($file = $dir . $pathEnd)) {
355 return $file; 385 return $file;
356 } 386 }
357 } 387 }
1 1
2 -Copyright (c) 2016 Nils Adermann, Jordi Boggiano 2 +Copyright (c) Nils Adermann, Jordi Boggiano
3 3
4 Permission is hereby granted, free of charge, to any person obtaining a copy 4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal 5 of this software and associated documentation files (the "Software"), to deal
@@ -6,12 +6,5 @@ $vendorDir = dirname(dirname(__FILE__)); @@ -6,12 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
6 $baseDir = dirname($vendorDir); 6 $baseDir = dirname($vendorDir);
7 7
8 return array( 8 return array(
9 - 'ArithmeticError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php',  
10 - 'AssertionError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php',  
11 - 'DivisionByZeroError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php',  
12 - 'Error' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/Error.php',  
13 'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', 9 'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
14 - 'ParseError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ParseError.php',  
15 - 'SessionUpdateTimestampHandlerInterface' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php',  
16 - 'TypeError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/TypeError.php',  
17 ); 10 );
@@ -6,31 +6,14 @@ $vendorDir = dirname(dirname(__FILE__)); @@ -6,31 +6,14 @@ $vendorDir = dirname(dirname(__FILE__));
6 $baseDir = dirname($vendorDir); 6 $baseDir = dirname($vendorDir);
7 7
8 return array( 8 return array(
9 - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',  
10 - '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',  
11 - '023d27dca8066ef29e6739335ea73bad' => $vendorDir . '/symfony/polyfill-php70/bootstrap.php',  
12 - 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',  
13 - 'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',  
14 '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', 9 '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
15 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php', 10 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
  11 + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
  12 + 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
  13 + '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
16 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', 14 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
  15 + 'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
17 '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', 16 '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
18 - '9d8e013a5160a09477beb8e44f8ae97b' => $vendorDir . '/markbaker/matrix/classes/src/functions/adjoint.php',  
19 - '6e78d1bdea6248d6aa117229efae50f2' => $vendorDir . '/markbaker/matrix/classes/src/functions/antidiagonal.php',  
20 - '4623d87924d94f5412fe5afbf1cef31d' => $vendorDir . '/markbaker/matrix/classes/src/functions/cofactors.php',  
21 - '901fd1f6950a637ca85f66b701a45e13' => $vendorDir . '/markbaker/matrix/classes/src/functions/determinant.php',  
22 - '83057abc0e4acc99ba80154ee5d02a49' => $vendorDir . '/markbaker/matrix/classes/src/functions/diagonal.php',  
23 - '07b7fd7a434451149b4fd477fca0ce06' => $vendorDir . '/markbaker/matrix/classes/src/functions/identity.php',  
24 - 'c8d43b340583e07ae89f2a3baef2cf89' => $vendorDir . '/markbaker/matrix/classes/src/functions/inverse.php',  
25 - '499bb10ed7a3aee2ba4c09a31a85e8d1' => $vendorDir . '/markbaker/matrix/classes/src/functions/minors.php',  
26 - '1cad2e6414d652e8b1c64e8967f6f37d' => $vendorDir . '/markbaker/matrix/classes/src/functions/trace.php',  
27 - '95a7f134ac17161d07def442b3b737e8' => $vendorDir . '/markbaker/matrix/classes/src/functions/transpose.php',  
28 - 'b3a6bc628377118d4b4b8ba08d1eb949' => $vendorDir . '/markbaker/matrix/classes/src/operations/add.php',  
29 - '5fef6d0e407f3f8887266dfa4a6c534c' => $vendorDir . '/markbaker/matrix/classes/src/operations/directsum.php',  
30 - '684ba247e1385946e3babdaa054119de' => $vendorDir . '/markbaker/matrix/classes/src/operations/subtract.php',  
31 - 'aa53dcba601214d17ad405b7c291b7e8' => $vendorDir . '/markbaker/matrix/classes/src/operations/multiply.php',  
32 - '75c79eb1b25749b05a47976f32b0d8a2' => $vendorDir . '/markbaker/matrix/classes/src/operations/divideby.php',  
33 - '6ab8ad87a734f276a6bcd5a0fe1289be' => $vendorDir . '/markbaker/matrix/classes/src/operations/divideinto.php',  
34 'abede361264e2ae69ec1eee813a101af' => $vendorDir . '/markbaker/complex/classes/src/functions/abs.php', 17 'abede361264e2ae69ec1eee813a101af' => $vendorDir . '/markbaker/complex/classes/src/functions/abs.php',
35 '21a5860fbef5be28db5ddfbc3cca67c4' => $vendorDir . '/markbaker/complex/classes/src/functions/acos.php', 18 '21a5860fbef5be28db5ddfbc3cca67c4' => $vendorDir . '/markbaker/complex/classes/src/functions/acos.php',
36 '1546e3f9d127f2a9bb2d1b6c31c26ef1' => $vendorDir . '/markbaker/complex/classes/src/functions/acosh.php', 19 '1546e3f9d127f2a9bb2d1b6c31c26ef1' => $vendorDir . '/markbaker/complex/classes/src/functions/acosh.php',
@@ -73,8 +56,23 @@ return array( @@ -73,8 +56,23 @@ return array(
73 '883af48563631547925fa4c3b48ead07' => $vendorDir . '/markbaker/complex/classes/src/operations/multiply.php', 56 '883af48563631547925fa4c3b48ead07' => $vendorDir . '/markbaker/complex/classes/src/operations/multiply.php',
74 'f190e3308e6ca23234a2875edc985c03' => $vendorDir . '/markbaker/complex/classes/src/operations/divideby.php', 57 'f190e3308e6ca23234a2875edc985c03' => $vendorDir . '/markbaker/complex/classes/src/operations/divideby.php',
75 'ac9e33ce6841aa5bf5d16d465a2f03a7' => $vendorDir . '/markbaker/complex/classes/src/operations/divideinto.php', 58 'ac9e33ce6841aa5bf5d16d465a2f03a7' => $vendorDir . '/markbaker/complex/classes/src/operations/divideinto.php',
76 - 'f0e7e63bbb278a92db02393536748c5f' => $vendorDir . '/overtrue/wechat/src/Kernel/Support/Helpers.php',  
77 - '6747f579ad6817f318cc3a7e7a0abb93' => $vendorDir . '/overtrue/wechat/src/Kernel/Helpers.php',  
78 - '1cfd2761b63b0a29ed23657ea394cb2d' => $vendorDir . '/topthink/think-captcha/src/helper.php', 59 + '9d8e013a5160a09477beb8e44f8ae97b' => $vendorDir . '/markbaker/matrix/classes/src/functions/adjoint.php',
  60 + '6e78d1bdea6248d6aa117229efae50f2' => $vendorDir . '/markbaker/matrix/classes/src/functions/antidiagonal.php',
  61 + '4623d87924d94f5412fe5afbf1cef31d' => $vendorDir . '/markbaker/matrix/classes/src/functions/cofactors.php',
  62 + '901fd1f6950a637ca85f66b701a45e13' => $vendorDir . '/markbaker/matrix/classes/src/functions/determinant.php',
  63 + '83057abc0e4acc99ba80154ee5d02a49' => $vendorDir . '/markbaker/matrix/classes/src/functions/diagonal.php',
  64 + '07b7fd7a434451149b4fd477fca0ce06' => $vendorDir . '/markbaker/matrix/classes/src/functions/identity.php',
  65 + 'c8d43b340583e07ae89f2a3baef2cf89' => $vendorDir . '/markbaker/matrix/classes/src/functions/inverse.php',
  66 + '499bb10ed7a3aee2ba4c09a31a85e8d1' => $vendorDir . '/markbaker/matrix/classes/src/functions/minors.php',
  67 + '1cad2e6414d652e8b1c64e8967f6f37d' => $vendorDir . '/markbaker/matrix/classes/src/functions/trace.php',
  68 + '95a7f134ac17161d07def442b3b737e8' => $vendorDir . '/markbaker/matrix/classes/src/functions/transpose.php',
  69 + 'b3a6bc628377118d4b4b8ba08d1eb949' => $vendorDir . '/markbaker/matrix/classes/src/operations/add.php',
  70 + '5fef6d0e407f3f8887266dfa4a6c534c' => $vendorDir . '/markbaker/matrix/classes/src/operations/directsum.php',
  71 + '684ba247e1385946e3babdaa054119de' => $vendorDir . '/markbaker/matrix/classes/src/operations/subtract.php',
  72 + 'aa53dcba601214d17ad405b7c291b7e8' => $vendorDir . '/markbaker/matrix/classes/src/operations/multiply.php',
  73 + '75c79eb1b25749b05a47976f32b0d8a2' => $vendorDir . '/markbaker/matrix/classes/src/operations/divideby.php',
  74 + '6ab8ad87a734f276a6bcd5a0fe1289be' => $vendorDir . '/markbaker/matrix/classes/src/operations/divideinto.php',
79 '488987c28e9b5e95a1ce6b6bcb94606c' => $vendorDir . '/karsonzhang/fastadmin-addons/src/common.php', 75 '488987c28e9b5e95a1ce6b6bcb94606c' => $vendorDir . '/karsonzhang/fastadmin-addons/src/common.php',
  76 + '9e090711773bfc38738f5dbaee5a7f14' => $vendorDir . '/overtrue/wechat/src/Payment/helpers.php',
  77 + '1cfd2761b63b0a29ed23657ea394cb2d' => $vendorDir . '/topthink/think-captcha/src/helper.php',
80 ); 78 );
@@ -7,4 +7,5 @@ $baseDir = dirname($vendorDir); @@ -7,4 +7,5 @@ $baseDir = dirname($vendorDir);
7 7
8 return array( 8 return array(
9 'Pimple' => array($vendorDir . '/pimple/pimple/src'), 9 'Pimple' => array($vendorDir . '/pimple/pimple/src'),
  10 + 'Doctrine\\Common\\Cache\\' => array($vendorDir . '/doctrine/cache/lib'),
10 ); 11 );
@@ -8,27 +8,19 @@ $baseDir = dirname($vendorDir); @@ -8,27 +8,19 @@ $baseDir = dirname($vendorDir);
8 return array( 8 return array(
9 'think\\composer\\' => array($vendorDir . '/topthink/think-installer/src'), 9 'think\\composer\\' => array($vendorDir . '/topthink/think-installer/src'),
10 'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'), 10 'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'),
11 - 'think\\' => array($baseDir . '/thinkphp/library/think', $vendorDir . '/karsonzhang/fastadmin-addons/src'), 11 + 'think\\' => array($vendorDir . '/karsonzhang/fastadmin-addons/src', $baseDir . '/thinkphp/library/think'),
12 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'), 12 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
13 - 'Symfony\\Polyfill\\Php70\\' => array($vendorDir . '/symfony/polyfill-php70'),  
14 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), 13 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
15 'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'), 14 'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'),
16 'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'), 15 'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'),
17 - 'Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'),  
18 - 'Symfony\\Contracts\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher-contracts'),  
19 - 'Symfony\\Contracts\\Cache\\' => array($vendorDir . '/symfony/cache-contracts'),  
20 'Symfony\\Component\\VarExporter\\' => array($vendorDir . '/symfony/var-exporter'), 16 'Symfony\\Component\\VarExporter\\' => array($vendorDir . '/symfony/var-exporter'),
21 - 'Symfony\\Component\\Mime\\' => array($vendorDir . '/symfony/mime'),  
22 'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'), 17 'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'),
23 'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'), 18 'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
24 - 'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),  
25 - 'Symfony\\Component\\Cache\\' => array($vendorDir . '/symfony/cache'),  
26 'Symfony\\Bridge\\PsrHttpMessage\\' => array($vendorDir . '/symfony/psr-http-message-bridge'), 19 'Symfony\\Bridge\\PsrHttpMessage\\' => array($vendorDir . '/symfony/psr-http-message-bridge'),
27 'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'), 20 'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
28 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), 21 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
29 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'), 22 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
30 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), 23 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
31 - 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),  
32 'PhpZip\\' => array($vendorDir . '/nelexa/zip/src'), 24 'PhpZip\\' => array($vendorDir . '/nelexa/zip/src'),
33 'PhpOffice\\PhpSpreadsheet\\' => array($vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet'), 25 'PhpOffice\\PhpSpreadsheet\\' => array($vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet'),
34 'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'), 26 'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'),
@@ -40,6 +32,5 @@ return array( @@ -40,6 +32,5 @@ return array(
40 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'), 32 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
41 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), 33 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
42 'EasyWeChat\\' => array($vendorDir . '/overtrue/wechat/src'), 34 'EasyWeChat\\' => array($vendorDir . '/overtrue/wechat/src'),
43 - 'EasyWeChatComposer\\' => array($vendorDir . '/easywechat-composer/easywechat-composer/src'),  
44 'Complex\\' => array($vendorDir . '/markbaker/complex/classes/src'), 35 'Complex\\' => array($vendorDir . '/markbaker/complex/classes/src'),
45 ); 36 );
@@ -13,6 +13,9 @@ class ComposerAutoloaderInitf00349b72964a05454b796bb539364c1 @@ -13,6 +13,9 @@ class ComposerAutoloaderInitf00349b72964a05454b796bb539364c1
13 } 13 }
14 } 14 }
15 15
  16 + /**
  17 + * @return \Composer\Autoload\ClassLoader
  18 + */
16 public static function getLoader() 19 public static function getLoader()
17 { 20 {
18 if (null !== self::$loader) { 21 if (null !== self::$loader) {
@@ -23,7 +26,7 @@ class ComposerAutoloaderInitf00349b72964a05454b796bb539364c1 @@ -23,7 +26,7 @@ class ComposerAutoloaderInitf00349b72964a05454b796bb539364c1
23 self::$loader = $loader = new \Composer\Autoload\ClassLoader(); 26 self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24 spl_autoload_unregister(array('ComposerAutoloaderInitf00349b72964a05454b796bb539364c1', 'loadClassLoader')); 27 spl_autoload_unregister(array('ComposerAutoloaderInitf00349b72964a05454b796bb539364c1', 'loadClassLoader'));
25 28
26 - $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION'); 29 + $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27 if ($useStaticLoader) { 30 if ($useStaticLoader) {
28 require_once __DIR__ . '/autoload_static.php'; 31 require_once __DIR__ . '/autoload_static.php';
29 32
@@ -7,31 +7,14 @@ namespace Composer\Autoload; @@ -7,31 +7,14 @@ namespace Composer\Autoload;
7 class ComposerStaticInitf00349b72964a05454b796bb539364c1 7 class ComposerStaticInitf00349b72964a05454b796bb539364c1
8 { 8 {
9 public static $files = array ( 9 public static $files = array (
10 - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',  
11 - '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',  
12 - '023d27dca8066ef29e6739335ea73bad' => __DIR__ . '/..' . '/symfony/polyfill-php70/bootstrap.php',  
13 - 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',  
14 - 'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',  
15 '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', 10 '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
16 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php', 11 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
  12 + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
  13 + 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',
  14 + '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
17 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', 15 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
  16 + 'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
18 '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', 17 '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
19 - '9d8e013a5160a09477beb8e44f8ae97b' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/adjoint.php',  
20 - '6e78d1bdea6248d6aa117229efae50f2' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/antidiagonal.php',  
21 - '4623d87924d94f5412fe5afbf1cef31d' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/cofactors.php',  
22 - '901fd1f6950a637ca85f66b701a45e13' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/determinant.php',  
23 - '83057abc0e4acc99ba80154ee5d02a49' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/diagonal.php',  
24 - '07b7fd7a434451149b4fd477fca0ce06' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/identity.php',  
25 - 'c8d43b340583e07ae89f2a3baef2cf89' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/inverse.php',  
26 - '499bb10ed7a3aee2ba4c09a31a85e8d1' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/minors.php',  
27 - '1cad2e6414d652e8b1c64e8967f6f37d' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/trace.php',  
28 - '95a7f134ac17161d07def442b3b737e8' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/transpose.php',  
29 - 'b3a6bc628377118d4b4b8ba08d1eb949' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/operations/add.php',  
30 - '5fef6d0e407f3f8887266dfa4a6c534c' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/operations/directsum.php',  
31 - '684ba247e1385946e3babdaa054119de' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/operations/subtract.php',  
32 - 'aa53dcba601214d17ad405b7c291b7e8' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/operations/multiply.php',  
33 - '75c79eb1b25749b05a47976f32b0d8a2' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/operations/divideby.php',  
34 - '6ab8ad87a734f276a6bcd5a0fe1289be' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/operations/divideinto.php',  
35 'abede361264e2ae69ec1eee813a101af' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/abs.php', 18 'abede361264e2ae69ec1eee813a101af' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/abs.php',
36 '21a5860fbef5be28db5ddfbc3cca67c4' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acos.php', 19 '21a5860fbef5be28db5ddfbc3cca67c4' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acos.php',
37 '1546e3f9d127f2a9bb2d1b6c31c26ef1' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acosh.php', 20 '1546e3f9d127f2a9bb2d1b6c31c26ef1' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acosh.php',
@@ -74,10 +57,25 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1 @@ -74,10 +57,25 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1
74 '883af48563631547925fa4c3b48ead07' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/multiply.php', 57 '883af48563631547925fa4c3b48ead07' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/multiply.php',
75 'f190e3308e6ca23234a2875edc985c03' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/divideby.php', 58 'f190e3308e6ca23234a2875edc985c03' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/divideby.php',
76 'ac9e33ce6841aa5bf5d16d465a2f03a7' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/divideinto.php', 59 'ac9e33ce6841aa5bf5d16d465a2f03a7' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/divideinto.php',
77 - 'f0e7e63bbb278a92db02393536748c5f' => __DIR__ . '/..' . '/overtrue/wechat/src/Kernel/Support/Helpers.php',  
78 - '6747f579ad6817f318cc3a7e7a0abb93' => __DIR__ . '/..' . '/overtrue/wechat/src/Kernel/Helpers.php',  
79 - '1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php', 60 + '9d8e013a5160a09477beb8e44f8ae97b' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/adjoint.php',
  61 + '6e78d1bdea6248d6aa117229efae50f2' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/antidiagonal.php',
  62 + '4623d87924d94f5412fe5afbf1cef31d' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/cofactors.php',
  63 + '901fd1f6950a637ca85f66b701a45e13' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/determinant.php',
  64 + '83057abc0e4acc99ba80154ee5d02a49' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/diagonal.php',
  65 + '07b7fd7a434451149b4fd477fca0ce06' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/identity.php',
  66 + 'c8d43b340583e07ae89f2a3baef2cf89' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/inverse.php',
  67 + '499bb10ed7a3aee2ba4c09a31a85e8d1' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/minors.php',
  68 + '1cad2e6414d652e8b1c64e8967f6f37d' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/trace.php',
  69 + '95a7f134ac17161d07def442b3b737e8' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/functions/transpose.php',
  70 + 'b3a6bc628377118d4b4b8ba08d1eb949' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/operations/add.php',
  71 + '5fef6d0e407f3f8887266dfa4a6c534c' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/operations/directsum.php',
  72 + '684ba247e1385946e3babdaa054119de' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/operations/subtract.php',
  73 + 'aa53dcba601214d17ad405b7c291b7e8' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/operations/multiply.php',
  74 + '75c79eb1b25749b05a47976f32b0d8a2' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/operations/divideby.php',
  75 + '6ab8ad87a734f276a6bcd5a0fe1289be' => __DIR__ . '/..' . '/markbaker/matrix/classes/src/operations/divideinto.php',
80 '488987c28e9b5e95a1ce6b6bcb94606c' => __DIR__ . '/..' . '/karsonzhang/fastadmin-addons/src/common.php', 76 '488987c28e9b5e95a1ce6b6bcb94606c' => __DIR__ . '/..' . '/karsonzhang/fastadmin-addons/src/common.php',
  77 + '9e090711773bfc38738f5dbaee5a7f14' => __DIR__ . '/..' . '/overtrue/wechat/src/Payment/helpers.php',
  78 + '1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php',
81 ); 79 );
82 80
83 public static $prefixLengthsPsr4 = array ( 81 public static $prefixLengthsPsr4 = array (
@@ -90,19 +88,12 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1 @@ -90,19 +88,12 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1
90 'S' => 88 'S' =>
91 array ( 89 array (
92 'Symfony\\Polyfill\\Php72\\' => 23, 90 'Symfony\\Polyfill\\Php72\\' => 23,
93 - 'Symfony\\Polyfill\\Php70\\' => 23,  
94 'Symfony\\Polyfill\\Mbstring\\' => 26, 91 'Symfony\\Polyfill\\Mbstring\\' => 26,
95 'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33, 92 'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33,
96 'Symfony\\Polyfill\\Intl\\Idn\\' => 26, 93 'Symfony\\Polyfill\\Intl\\Idn\\' => 26,
97 - 'Symfony\\Contracts\\Service\\' => 26,  
98 - 'Symfony\\Contracts\\EventDispatcher\\' => 34,  
99 - 'Symfony\\Contracts\\Cache\\' => 24,  
100 'Symfony\\Component\\VarExporter\\' => 30, 94 'Symfony\\Component\\VarExporter\\' => 30,
101 - 'Symfony\\Component\\Mime\\' => 23,  
102 'Symfony\\Component\\HttpFoundation\\' => 33, 95 'Symfony\\Component\\HttpFoundation\\' => 33,
103 'Symfony\\Component\\Finder\\' => 25, 96 'Symfony\\Component\\Finder\\' => 25,
104 - 'Symfony\\Component\\EventDispatcher\\' => 34,  
105 - 'Symfony\\Component\\Cache\\' => 24,  
106 'Symfony\\Bridge\\PsrHttpMessage\\' => 30, 97 'Symfony\\Bridge\\PsrHttpMessage\\' => 30,
107 ), 98 ),
108 'P' => 99 'P' =>
@@ -111,7 +102,6 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1 @@ -111,7 +102,6 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1
111 'Psr\\Log\\' => 8, 102 'Psr\\Log\\' => 8,
112 'Psr\\Http\\Message\\' => 17, 103 'Psr\\Http\\Message\\' => 17,
113 'Psr\\Container\\' => 14, 104 'Psr\\Container\\' => 14,
114 - 'Psr\\Cache\\' => 10,  
115 'PhpZip\\' => 7, 105 'PhpZip\\' => 7,
116 'PhpOffice\\PhpSpreadsheet\\' => 25, 106 'PhpOffice\\PhpSpreadsheet\\' => 25,
117 'PHPMailer\\PHPMailer\\' => 20, 107 'PHPMailer\\PHPMailer\\' => 20,
@@ -135,7 +125,6 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1 @@ -135,7 +125,6 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1
135 'E' => 125 'E' =>
136 array ( 126 array (
137 'EasyWeChat\\' => 11, 127 'EasyWeChat\\' => 11,
138 - 'EasyWeChatComposer\\' => 19,  
139 ), 128 ),
140 'C' => 129 'C' =>
141 array ( 130 array (
@@ -154,17 +143,13 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1 @@ -154,17 +143,13 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1
154 ), 143 ),
155 'think\\' => 144 'think\\' =>
156 array ( 145 array (
157 - 0 => __DIR__ . '/../..' . '/thinkphp/library/think',  
158 - 1 => __DIR__ . '/..' . '/karsonzhang/fastadmin-addons/src', 146 + 0 => __DIR__ . '/..' . '/karsonzhang/fastadmin-addons/src',
  147 + 1 => __DIR__ . '/../..' . '/thinkphp/library/think',
159 ), 148 ),
160 'Symfony\\Polyfill\\Php72\\' => 149 'Symfony\\Polyfill\\Php72\\' =>
161 array ( 150 array (
162 0 => __DIR__ . '/..' . '/symfony/polyfill-php72', 151 0 => __DIR__ . '/..' . '/symfony/polyfill-php72',
163 ), 152 ),
164 - 'Symfony\\Polyfill\\Php70\\' =>  
165 - array (  
166 - 0 => __DIR__ . '/..' . '/symfony/polyfill-php70',  
167 - ),  
168 'Symfony\\Polyfill\\Mbstring\\' => 153 'Symfony\\Polyfill\\Mbstring\\' =>
169 array ( 154 array (
170 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', 155 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
@@ -177,26 +162,10 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1 @@ -177,26 +162,10 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1
177 array ( 162 array (
178 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-idn', 163 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-idn',
179 ), 164 ),
180 - 'Symfony\\Contracts\\Service\\' =>  
181 - array (  
182 - 0 => __DIR__ . '/..' . '/symfony/service-contracts',  
183 - ),  
184 - 'Symfony\\Contracts\\EventDispatcher\\' =>  
185 - array (  
186 - 0 => __DIR__ . '/..' . '/symfony/event-dispatcher-contracts',  
187 - ),  
188 - 'Symfony\\Contracts\\Cache\\' =>  
189 - array (  
190 - 0 => __DIR__ . '/..' . '/symfony/cache-contracts',  
191 - ),  
192 'Symfony\\Component\\VarExporter\\' => 165 'Symfony\\Component\\VarExporter\\' =>
193 array ( 166 array (
194 0 => __DIR__ . '/..' . '/symfony/var-exporter', 167 0 => __DIR__ . '/..' . '/symfony/var-exporter',
195 ), 168 ),
196 - 'Symfony\\Component\\Mime\\' =>  
197 - array (  
198 - 0 => __DIR__ . '/..' . '/symfony/mime',  
199 - ),  
200 'Symfony\\Component\\HttpFoundation\\' => 169 'Symfony\\Component\\HttpFoundation\\' =>
201 array ( 170 array (
202 0 => __DIR__ . '/..' . '/symfony/http-foundation', 171 0 => __DIR__ . '/..' . '/symfony/http-foundation',
@@ -205,14 +174,6 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1 @@ -205,14 +174,6 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1
205 array ( 174 array (
206 0 => __DIR__ . '/..' . '/symfony/finder', 175 0 => __DIR__ . '/..' . '/symfony/finder',
207 ), 176 ),
208 - 'Symfony\\Component\\EventDispatcher\\' =>  
209 - array (  
210 - 0 => __DIR__ . '/..' . '/symfony/event-dispatcher',  
211 - ),  
212 - 'Symfony\\Component\\Cache\\' =>  
213 - array (  
214 - 0 => __DIR__ . '/..' . '/symfony/cache',  
215 - ),  
216 'Symfony\\Bridge\\PsrHttpMessage\\' => 177 'Symfony\\Bridge\\PsrHttpMessage\\' =>
217 array ( 178 array (
218 0 => __DIR__ . '/..' . '/symfony/psr-http-message-bridge', 179 0 => __DIR__ . '/..' . '/symfony/psr-http-message-bridge',
@@ -233,10 +194,6 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1 @@ -233,10 +194,6 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1
233 array ( 194 array (
234 0 => __DIR__ . '/..' . '/psr/container/src', 195 0 => __DIR__ . '/..' . '/psr/container/src',
235 ), 196 ),
236 - 'Psr\\Cache\\' =>  
237 - array (  
238 - 0 => __DIR__ . '/..' . '/psr/cache/src',  
239 - ),  
240 'PhpZip\\' => 197 'PhpZip\\' =>
241 array ( 198 array (
242 0 => __DIR__ . '/..' . '/nelexa/zip/src', 199 0 => __DIR__ . '/..' . '/nelexa/zip/src',
@@ -281,10 +238,6 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1 @@ -281,10 +238,6 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1
281 array ( 238 array (
282 0 => __DIR__ . '/..' . '/overtrue/wechat/src', 239 0 => __DIR__ . '/..' . '/overtrue/wechat/src',
283 ), 240 ),
284 - 'EasyWeChatComposer\\' =>  
285 - array (  
286 - 0 => __DIR__ . '/..' . '/easywechat-composer/easywechat-composer/src',  
287 - ),  
288 'Complex\\' => 241 'Complex\\' =>
289 array ( 242 array (
290 0 => __DIR__ . '/..' . '/markbaker/complex/classes/src', 243 0 => __DIR__ . '/..' . '/markbaker/complex/classes/src',
@@ -299,17 +252,17 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1 @@ -299,17 +252,17 @@ class ComposerStaticInitf00349b72964a05454b796bb539364c1
299 0 => __DIR__ . '/..' . '/pimple/pimple/src', 252 0 => __DIR__ . '/..' . '/pimple/pimple/src',
300 ), 253 ),
301 ), 254 ),
  255 + 'D' =>
  256 + array (
  257 + 'Doctrine\\Common\\Cache\\' =>
  258 + array (
  259 + 0 => __DIR__ . '/..' . '/doctrine/cache/lib',
  260 + ),
  261 + ),
302 ); 262 );
303 263
304 public static $classMap = array ( 264 public static $classMap = array (
305 - 'ArithmeticError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php',  
306 - 'AssertionError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php',  
307 - 'DivisionByZeroError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php',  
308 - 'Error' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/Error.php',  
309 'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', 265 'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
310 - 'ParseError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/ParseError.php',  
311 - 'SessionUpdateTimestampHandlerInterface' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php',  
312 - 'TypeError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/TypeError.php',  
313 ); 266 );
314 267
315 public static function getInitializer(ClassLoader $loader) 268 public static function getInitializer(ClassLoader $loader)
  1 +# for php-coveralls
  2 +service_name: travis-ci
  3 +src_dir: lib
  4 +coverage_clover: build/logs/clover.xml
  1 +vendor/
  2 +build/
  3 +phpunit.xml
  4 +composer.lock
  1 +language: php
  2 +
  3 +php:
  4 + - 5.3
  5 + - 5.4
  6 + - 5.5
  7 + - 5.6
  8 + - hhvm
  9 +
  10 +services:
  11 + - riak
  12 + - mongodb
  13 + - memcached
  14 + - redis-server
  15 +
  16 +before_install:
  17 + - sh -c "if [ $TRAVIS_PHP_VERSION != 'hhvm' ]; then pecl install riak-beta; fi"
  18 + - sh -c "if [[ $TRAVIS_PHP_VERSION != 'hhvm' && `php-config --vernum` -ge 50500 ]] ; then pecl config-set preferred_state beta; printf "yes\n" | pecl install apcu ; else echo 'extension="apc.so"' >> ./tests/travis/php.ini ;fi"
  19 + - composer self-update
  20 + - sh -c "if [ $TRAVIS_PHP_VERSION != 'hhvm' ]; then phpenv config-add ./tests/travis/php.ini; fi"
  21 +
  22 +install:
  23 + - composer --prefer-source --dev install
  24 +
  25 +script:
  26 + - ./vendor/bin/phpunit -c ./tests/travis/phpunit.travis.xml -v
  27 +
  28 +after_script:
  29 + - php vendor/bin/coveralls -v
  30 +
  31 +matrix:
  32 + allow_failures:
  33 + - php: hhvm
  1 +Copyright (c) 2006-2012 Doctrine Project
  2 +
  3 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  4 +this software and associated documentation files (the "Software"), to deal in
  5 +the Software without restriction, including without limitation the rights to
  6 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  7 +of the Software, and to permit persons to whom the Software is furnished to do
  8 +so, subject to the following conditions:
  9 +
  10 +The above copyright notice and this permission notice shall be included in all
  11 +copies or substantial portions of the Software.
  12 +
  13 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  19 +SOFTWARE.
  1 +# Doctrine Cache
  2 +
  3 +Master: [![Build Status](https://secure.travis-ci.org/doctrine/cache.png?branch=master)](http://travis-ci.org/doctrine/cache) [![Coverage Status](https://coveralls.io/repos/doctrine/cache/badge.png?branch=master)](https://coveralls.io/r/doctrine/cache?branch=master)
  4 +
  5 +[![Latest Stable Version](https://poser.pugx.org/doctrine/cache/v/stable.png)](https://packagist.org/packages/doctrine/cache) [![Total Downloads](https://poser.pugx.org/doctrine/cache/downloads.png)](https://packagist.org/packages/doctrine/cache)
  6 +
  7 +Cache component extracted from the Doctrine Common project.
  8 +
  9 +## Changelog
  10 +
  11 +### v1.2
  12 +
  13 +* Added support for MongoDB as Cache Provider
  14 +* Fix namespace version reset
  1 +# Upgrade to 1.4
  2 +
  3 +## Minor BC Break: `Doctrine\Common\Cache\FileCache#$extension` is now `private`.
  4 +
  5 +If you need to override the value of `Doctrine\Common\Cache\FileCache#$extension`, then use the
  6 +second parameter of `Doctrine\Common\Cache\FileCache#__construct()` instead of overriding
  7 +the property in your own implementation.
  8 +
  9 +## Minor BC Break: file based caches paths changed
  10 +
  11 +`Doctrine\Common\Cache\FileCache`, `Doctrine\Common\Cache\PhpFileCache` and
  12 +`Doctrine\Common\Cache\FilesystemCache` are using a different cache paths structure.
  13 +
  14 +If you rely on warmed up caches for deployments, consider that caches generated
  15 +with `doctrine/cache` `<1.4` are not compatible with the new directory structure,
  16 +and will be ignored.
  1 +# Version class and file
  2 +project.version_class = Doctrine\\Common\\Cache\\Version
  3 +project.version_file = lib/Doctrine/Common/Cache/Version.php
  1 +<?xml version="1.0"?>
  2 +<project name="DoctrineCommonCache" default="build" basedir=".">
  3 + <property file="build.properties" />
  4 +
  5 + <target name="php">
  6 + <exec executable="which" outputproperty="php_executable">
  7 + <arg value="php" />
  8 + </exec>
  9 + </target>
  10 +
  11 + <target name="prepare">
  12 + <mkdir dir="build" />
  13 + </target>
  14 +
  15 + <target name="build" depends="check-git-checkout-clean,prepare,php,composer">
  16 + <exec executable="${php_executable}">
  17 + <arg value="build/composer.phar" />
  18 + <arg value="archive" />
  19 + <arg value="--dir=build" />
  20 + </exec>
  21 + </target>
  22 +
  23 + <target name="composer" depends="php,composer-check,composer-download">
  24 + <exec executable="${php_executable}">
  25 + <arg value="build/composer.phar" />
  26 + <arg value="install" />
  27 + </exec>
  28 + </target>
  29 +
  30 + <target name="composer-check" depends="prepare">
  31 + <available file="build/composer.phar" property="composer.present"/>
  32 + </target>
  33 +
  34 + <target name="composer-download" unless="composer.present">
  35 + <exec executable="wget">
  36 + <arg value="-Obuild/composer.phar" />
  37 + <arg value="http://getcomposer.org/composer.phar" />
  38 + </exec>
  39 + </target>
  40 +
  41 + <target name="make-release" depends="check-git-checkout-clean,prepare,php">
  42 + <replace file="${project.version_file}" token="-DEV" value="" failOnNoReplacements="true" />
  43 + <exec executable="git" failonerror="true" outputproperty="current_git_branch">
  44 + <arg value="rev-parse" />
  45 + <arg value="--abbrev-ref" />
  46 + <arg value="HEAD" />
  47 + </exec>
  48 + <exec executable="${php_executable}" outputproperty="doctrine.current_version" failonerror="true">
  49 + <arg value="-r" />
  50 + <arg value="require_once '${project.version_file}';echo ${project.version_class}::VERSION;" />
  51 + </exec>
  52 + <exec executable="${php_executable}" outputproperty="doctrine.next_version" failonerror="true">
  53 + <arg value="-r" />
  54 + <arg value="$parts = explode('.', str_ireplace(array('-DEV', '-ALPHA', '-BETA'), '', '${doctrine.current_version}'));
  55 + if (count($parts) != 3) {
  56 + throw new \InvalidArgumentException('Version is assumed in format x.y.z, ${doctrine.current_version} given');
  57 + }
  58 + if ('${current_git_branch}' === 'master') {
  59 + $parts[1]++;
  60 + } else {
  61 + $parts[2]++;
  62 + }
  63 + echo implode('.', $parts);
  64 + " />
  65 + </exec>
  66 +
  67 + <git-commit file="${project.version_file}" message="Release ${doctrine.current_version}" />
  68 + <git-tag version="${doctrine.current_version}" />
  69 + <replace file="${project.version_file}" token="${doctrine.current_version}" value="${doctrine.next_version}-DEV" />
  70 + <git-commit file="${project.version_file}" message="Bump version to ${doctrine.next_version}" />
  71 + </target>
  72 +
  73 + <target name="check-git-checkout-clean">
  74 + <exec executable="git" failonerror="true">
  75 + <arg value="diff-index" />
  76 + <arg value="--quiet" />
  77 + <arg value="HEAD" />
  78 + </exec>
  79 + </target>
  80 +
  81 + <macrodef name="git-commit">
  82 + <attribute name="file" default="NOT SET"/>
  83 + <attribute name="message" default="NOT SET"/>
  84 +
  85 + <sequential>
  86 + <exec executable="git">
  87 + <arg value="add" />
  88 + <arg value="@{file}" />
  89 + </exec>
  90 + <exec executable="git">
  91 + <arg value="commit" />
  92 + <arg value="-m" />
  93 + <arg value="@{message}" />
  94 + </exec>
  95 + </sequential>
  96 + </macrodef>
  97 +
  98 + <macrodef name="git-tag">
  99 + <attribute name="version" default="NOT SET" />
  100 +
  101 + <sequential>
  102 + <exec executable="git">
  103 + <arg value="tag" />
  104 + <arg value="-m" />
  105 + <arg value="v@{version}" />
  106 + <arg value="v@{version}" />
  107 + </exec>
  108 + </sequential>
  109 + </macrodef>
  110 +</project>
  1 +{
  2 + "name": "doctrine/cache",
  3 + "type": "library",
  4 + "description": "Caching library offering an object-oriented API for many cache backends",
  5 + "keywords": ["cache", "caching"],
  6 + "homepage": "http://www.doctrine-project.org",
  7 + "license": "MIT",
  8 + "authors": [
  9 + {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
  10 + {"name": "Roman Borschel", "email": "roman@code-factory.org"},
  11 + {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
  12 + {"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
  13 + {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
  14 + ],
  15 + "require": {
  16 + "php": ">=5.3.2"
  17 + },
  18 + "require-dev": {
  19 + "phpunit/phpunit": ">=3.7",
  20 + "satooshi/php-coveralls": "~0.6",
  21 + "predis/predis": "~1.0"
  22 + },
  23 + "conflict": {
  24 + "doctrine/common": ">2.2,<2.4"
  25 + },
  26 + "autoload": {
  27 + "psr-0": { "Doctrine\\Common\\Cache\\": "lib/" }
  28 + },
  29 + "extra": {
  30 + "branch-alias": {
  31 + "dev-master": "1.5.x-dev"
  32 + }
  33 + }
  34 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +/**
  23 + * APC cache provider.
  24 + *
  25 + * @link www.doctrine-project.org
  26 + * @since 2.0
  27 + * @author Benjamin Eberlei <kontakt@beberlei.de>
  28 + * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
  29 + * @author Jonathan Wage <jonwage@gmail.com>
  30 + * @author Roman Borschel <roman@code-factory.org>
  31 + * @author David Abdemoulaie <dave@hobodave.com>
  32 + */
  33 +class ApcCache extends CacheProvider
  34 +{
  35 + /**
  36 + * {@inheritdoc}
  37 + */
  38 + protected function doFetch($id)
  39 + {
  40 + return apc_fetch($id);
  41 + }
  42 +
  43 + /**
  44 + * {@inheritdoc}
  45 + */
  46 + protected function doContains($id)
  47 + {
  48 + return apc_exists($id);
  49 + }
  50 +
  51 + /**
  52 + * {@inheritdoc}
  53 + */
  54 + protected function doSave($id, $data, $lifeTime = 0)
  55 + {
  56 + return (bool) apc_store($id, $data, (int) $lifeTime);
  57 + }
  58 +
  59 + /**
  60 + * {@inheritdoc}
  61 + */
  62 + protected function doDelete($id)
  63 + {
  64 + // apc_delete returns false if the id does not exist
  65 + return apc_delete($id) || ! apc_exists($id);
  66 + }
  67 +
  68 + /**
  69 + * {@inheritdoc}
  70 + */
  71 + protected function doFlush()
  72 + {
  73 + return apc_clear_cache() && apc_clear_cache('user');
  74 + }
  75 +
  76 + /**
  77 + * {@inheritdoc}
  78 + */
  79 + protected function doFetchMultiple(array $keys)
  80 + {
  81 + return apc_fetch($keys);
  82 + }
  83 +
  84 + /**
  85 + * {@inheritdoc}
  86 + */
  87 + protected function doGetStats()
  88 + {
  89 + $info = apc_cache_info('', true);
  90 + $sma = apc_sma_info();
  91 +
  92 + // @TODO - Temporary fix @see https://github.com/krakjoe/apcu/pull/42
  93 + if (PHP_VERSION_ID >= 50500) {
  94 + $info['num_hits'] = isset($info['num_hits']) ? $info['num_hits'] : $info['nhits'];
  95 + $info['num_misses'] = isset($info['num_misses']) ? $info['num_misses'] : $info['nmisses'];
  96 + $info['start_time'] = isset($info['start_time']) ? $info['start_time'] : $info['stime'];
  97 + }
  98 +
  99 + return array(
  100 + Cache::STATS_HITS => $info['num_hits'],
  101 + Cache::STATS_MISSES => $info['num_misses'],
  102 + Cache::STATS_UPTIME => $info['start_time'],
  103 + Cache::STATS_MEMORY_USAGE => $info['mem_size'],
  104 + Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'],
  105 + );
  106 + }
  107 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +/**
  23 + * Array cache driver.
  24 + *
  25 + * @link www.doctrine-project.org
  26 + * @since 2.0
  27 + * @author Benjamin Eberlei <kontakt@beberlei.de>
  28 + * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
  29 + * @author Jonathan Wage <jonwage@gmail.com>
  30 + * @author Roman Borschel <roman@code-factory.org>
  31 + * @author David Abdemoulaie <dave@hobodave.com>
  32 + */
  33 +class ArrayCache extends CacheProvider
  34 +{
  35 + /**
  36 + * @var array $data
  37 + */
  38 + private $data = array();
  39 +
  40 + /**
  41 + * {@inheritdoc}
  42 + */
  43 + protected function doFetch($id)
  44 + {
  45 + return $this->doContains($id) ? $this->data[$id] : false;
  46 + }
  47 +
  48 + /**
  49 + * {@inheritdoc}
  50 + */
  51 + protected function doContains($id)
  52 + {
  53 + // isset() is required for performance optimizations, to avoid unnecessary function calls to array_key_exists.
  54 + return isset($this->data[$id]) || array_key_exists($id, $this->data);
  55 + }
  56 +
  57 + /**
  58 + * {@inheritdoc}
  59 + */
  60 + protected function doSave($id, $data, $lifeTime = 0)
  61 + {
  62 + $this->data[$id] = $data;
  63 +
  64 + return true;
  65 + }
  66 +
  67 + /**
  68 + * {@inheritdoc}
  69 + */
  70 + protected function doDelete($id)
  71 + {
  72 + unset($this->data[$id]);
  73 +
  74 + return true;
  75 + }
  76 +
  77 + /**
  78 + * {@inheritdoc}
  79 + */
  80 + protected function doFlush()
  81 + {
  82 + $this->data = array();
  83 +
  84 + return true;
  85 + }
  86 +
  87 + /**
  88 + * {@inheritdoc}
  89 + */
  90 + protected function doGetStats()
  91 + {
  92 + return null;
  93 + }
  94 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +/**
  23 + * Interface for cache drivers.
  24 + *
  25 + * @link www.doctrine-project.org
  26 + * @since 2.0
  27 + * @author Benjamin Eberlei <kontakt@beberlei.de>
  28 + * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
  29 + * @author Jonathan Wage <jonwage@gmail.com>
  30 + * @author Roman Borschel <roman@code-factory.org>
  31 + * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
  32 + * @author Kévin Dunglas <dunglas@gmail.com>
  33 + */
  34 +interface Cache
  35 +{
  36 + const STATS_HITS = 'hits';
  37 + const STATS_MISSES = 'misses';
  38 + const STATS_UPTIME = 'uptime';
  39 + const STATS_MEMORY_USAGE = 'memory_usage';
  40 + const STATS_MEMORY_AVAILABLE = 'memory_available';
  41 + /**
  42 + * Only for backward compatibility (may be removed in next major release)
  43 + *
  44 + * @deprecated
  45 + */
  46 + const STATS_MEMORY_AVAILIABLE = 'memory_available';
  47 +
  48 + /**
  49 + * Fetches an entry from the cache.
  50 + *
  51 + * @param string $id The id of the cache entry to fetch.
  52 + *
  53 + * @return mixed The cached data or FALSE, if no cache entry exists for the given id.
  54 + */
  55 + public function fetch($id);
  56 +
  57 + /**
  58 + * Tests if an entry exists in the cache.
  59 + *
  60 + * @param string $id The cache id of the entry to check for.
  61 + *
  62 + * @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise.
  63 + */
  64 + public function contains($id);
  65 +
  66 + /**
  67 + * Puts data into the cache.
  68 + *
  69 + * If a cache entry with the given id already exists, its data will be replaced.
  70 + *
  71 + * @param string $id The cache id.
  72 + * @param mixed $data The cache entry/data.
  73 + * @param int $lifeTime The lifetime in number of seconds for this cache entry.
  74 + * If zero (the default), the entry never expires (although it may be deleted from the cache
  75 + * to make place for other entries).
  76 + *
  77 + * @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise.
  78 + */
  79 + public function save($id, $data, $lifeTime = 0);
  80 +
  81 + /**
  82 + * Deletes a cache entry.
  83 + *
  84 + * @param string $id The cache id.
  85 + *
  86 + * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise.
  87 + * Deleting a non-existing entry is considered successful.
  88 + */
  89 + public function delete($id);
  90 +
  91 + /**
  92 + * Retrieves cached information from the data store.
  93 + *
  94 + * The server's statistics array has the following values:
  95 + *
  96 + * - <b>hits</b>
  97 + * Number of keys that have been requested and found present.
  98 + *
  99 + * - <b>misses</b>
  100 + * Number of items that have been requested and not found.
  101 + *
  102 + * - <b>uptime</b>
  103 + * Time that the server is running.
  104 + *
  105 + * - <b>memory_usage</b>
  106 + * Memory used by this server to store items.
  107 + *
  108 + * - <b>memory_available</b>
  109 + * Memory allowed to use for storage.
  110 + *
  111 + * @since 2.2
  112 + *
  113 + * @return array|null An associative array with server's statistics if available, NULL otherwise.
  114 + */
  115 + public function getStats();
  116 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +/**
  23 + * Base class for cache provider implementations.
  24 + *
  25 + * @since 2.2
  26 + * @author Benjamin Eberlei <kontakt@beberlei.de>
  27 + * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
  28 + * @author Jonathan Wage <jonwage@gmail.com>
  29 + * @author Roman Borschel <roman@code-factory.org>
  30 + * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
  31 + */
  32 +abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiGetCache
  33 +{
  34 + const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]';
  35 +
  36 + /**
  37 + * The namespace to prefix all cache ids with.
  38 + *
  39 + * @var string
  40 + */
  41 + private $namespace = '';
  42 +
  43 + /**
  44 + * The namespace version.
  45 + *
  46 + * @var integer|null
  47 + */
  48 + private $namespaceVersion;
  49 +
  50 + /**
  51 + * Sets the namespace to prefix all cache ids with.
  52 + *
  53 + * @param string $namespace
  54 + *
  55 + * @return void
  56 + */
  57 + public function setNamespace($namespace)
  58 + {
  59 + $this->namespace = (string) $namespace;
  60 + $this->namespaceVersion = null;
  61 + }
  62 +
  63 + /**
  64 + * Retrieves the namespace that prefixes all cache ids.
  65 + *
  66 + * @return string
  67 + */
  68 + public function getNamespace()
  69 + {
  70 + return $this->namespace;
  71 + }
  72 +
  73 + /**
  74 + * {@inheritdoc}
  75 + */
  76 + public function fetch($id)
  77 + {
  78 + return $this->doFetch($this->getNamespacedId($id));
  79 + }
  80 +
  81 + /**
  82 + * {@inheritdoc}
  83 + */
  84 + public function fetchMultiple(array $keys)
  85 + {
  86 + if (empty($keys)) {
  87 + return array();
  88 + }
  89 +
  90 + // note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys
  91 + $namespacedKeys = array_combine($keys, array_map(array($this, 'getNamespacedId'), $keys));
  92 + $items = $this->doFetchMultiple($namespacedKeys);
  93 + $foundItems = array();
  94 +
  95 + // no internal array function supports this sort of mapping: needs to be iterative
  96 + // this filters and combines keys in one pass
  97 + foreach ($namespacedKeys as $requestedKey => $namespacedKey) {
  98 + if (isset($items[$namespacedKey]) || array_key_exists($namespacedKey, $items)) {
  99 + $foundItems[$requestedKey] = $items[$namespacedKey];
  100 + }
  101 + }
  102 +
  103 + return $foundItems;
  104 + }
  105 +
  106 + /**
  107 + * {@inheritdoc}
  108 + */
  109 + public function contains($id)
  110 + {
  111 + return $this->doContains($this->getNamespacedId($id));
  112 + }
  113 +
  114 + /**
  115 + * {@inheritdoc}
  116 + */
  117 + public function save($id, $data, $lifeTime = 0)
  118 + {
  119 + return $this->doSave($this->getNamespacedId($id), $data, $lifeTime);
  120 + }
  121 +
  122 + /**
  123 + * {@inheritdoc}
  124 + */
  125 + public function delete($id)
  126 + {
  127 + return $this->doDelete($this->getNamespacedId($id));
  128 + }
  129 +
  130 + /**
  131 + * {@inheritdoc}
  132 + */
  133 + public function getStats()
  134 + {
  135 + return $this->doGetStats();
  136 + }
  137 +
  138 + /**
  139 + * {@inheritDoc}
  140 + */
  141 + public function flushAll()
  142 + {
  143 + return $this->doFlush();
  144 + }
  145 +
  146 + /**
  147 + * {@inheritDoc}
  148 + */
  149 + public function deleteAll()
  150 + {
  151 + $namespaceCacheKey = $this->getNamespaceCacheKey();
  152 + $namespaceVersion = $this->getNamespaceVersion() + 1;
  153 +
  154 + if ($this->doSave($namespaceCacheKey, $namespaceVersion)) {
  155 + $this->namespaceVersion = $namespaceVersion;
  156 +
  157 + return true;
  158 + }
  159 +
  160 + return false;
  161 + }
  162 +
  163 + /**
  164 + * Prefixes the passed id with the configured namespace value.
  165 + *
  166 + * @param string $id The id to namespace.
  167 + *
  168 + * @return string The namespaced id.
  169 + */
  170 + private function getNamespacedId($id)
  171 + {
  172 + $namespaceVersion = $this->getNamespaceVersion();
  173 +
  174 + return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion);
  175 + }
  176 +
  177 + /**
  178 + * Returns the namespace cache key.
  179 + *
  180 + * @return string
  181 + */
  182 + private function getNamespaceCacheKey()
  183 + {
  184 + return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace);
  185 + }
  186 +
  187 + /**
  188 + * Returns the namespace version.
  189 + *
  190 + * @return integer
  191 + */
  192 + private function getNamespaceVersion()
  193 + {
  194 + if (null !== $this->namespaceVersion) {
  195 + return $this->namespaceVersion;
  196 + }
  197 +
  198 + $namespaceCacheKey = $this->getNamespaceCacheKey();
  199 + $this->namespaceVersion = $this->doFetch($namespaceCacheKey) ?: 1;
  200 +
  201 + return $this->namespaceVersion;
  202 + }
  203 +
  204 + /**
  205 + * Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it.
  206 + *
  207 + * @param array $keys Array of keys to retrieve from cache
  208 + * @return array Array of values retrieved for the given keys.
  209 + */
  210 + protected function doFetchMultiple(array $keys)
  211 + {
  212 + $returnValues = array();
  213 +
  214 + foreach ($keys as $index => $key) {
  215 + if (false !== ($item = $this->doFetch($key))) {
  216 + $returnValues[$key] = $item;
  217 + }
  218 + }
  219 +
  220 + return $returnValues;
  221 + }
  222 +
  223 + /**
  224 + * Fetches an entry from the cache.
  225 + *
  226 + * @param string $id The id of the cache entry to fetch.
  227 + *
  228 + * @return mixed|boolean The cached data or FALSE, if no cache entry exists for the given id.
  229 + */
  230 + abstract protected function doFetch($id);
  231 +
  232 + /**
  233 + * Tests if an entry exists in the cache.
  234 + *
  235 + * @param string $id The cache id of the entry to check for.
  236 + *
  237 + * @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise.
  238 + */
  239 + abstract protected function doContains($id);
  240 +
  241 + /**
  242 + * Puts data into the cache.
  243 + *
  244 + * @param string $id The cache id.
  245 + * @param string $data The cache entry/data.
  246 + * @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this
  247 + * cache entry (0 => infinite lifeTime).
  248 + *
  249 + * @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise.
  250 + */
  251 + abstract protected function doSave($id, $data, $lifeTime = 0);
  252 +
  253 + /**
  254 + * Deletes a cache entry.
  255 + *
  256 + * @param string $id The cache id.
  257 + *
  258 + * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise.
  259 + */
  260 + abstract protected function doDelete($id);
  261 +
  262 + /**
  263 + * Flushes all cache entries.
  264 + *
  265 + * @return boolean TRUE if the cache entries were successfully flushed, FALSE otherwise.
  266 + */
  267 + abstract protected function doFlush();
  268 +
  269 + /**
  270 + * Retrieves cached information from the data store.
  271 + *
  272 + * @since 2.2
  273 + *
  274 + * @return array|null An associative array with server's statistics if available, NULL otherwise.
  275 + */
  276 + abstract protected function doGetStats();
  277 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +/**
  23 + * Cache provider that allows to easily chain multiple cache providers
  24 + *
  25 + * @author Michaël Gallego <mic.gallego@gmail.com>
  26 + */
  27 +class ChainCache extends CacheProvider
  28 +{
  29 + /**
  30 + * @var CacheProvider[]
  31 + */
  32 + private $cacheProviders = array();
  33 +
  34 + /**
  35 + * Constructor
  36 + *
  37 + * @param CacheProvider[] $cacheProviders
  38 + */
  39 + public function __construct($cacheProviders = array())
  40 + {
  41 + $this->cacheProviders = $cacheProviders;
  42 + }
  43 +
  44 + /**
  45 + * {@inheritDoc}
  46 + */
  47 + public function setNamespace($namespace)
  48 + {
  49 + parent::setNamespace($namespace);
  50 +
  51 + foreach ($this->cacheProviders as $cacheProvider) {
  52 + $cacheProvider->setNamespace($namespace);
  53 + }
  54 + }
  55 +
  56 + /**
  57 + * {@inheritDoc}
  58 + */
  59 + protected function doFetch($id)
  60 + {
  61 + foreach ($this->cacheProviders as $key => $cacheProvider) {
  62 + if ($cacheProvider->doContains($id)) {
  63 + $value = $cacheProvider->doFetch($id);
  64 +
  65 + // We populate all the previous cache layers (that are assumed to be faster)
  66 + for ($subKey = $key - 1 ; $subKey >= 0 ; $subKey--) {
  67 + $this->cacheProviders[$subKey]->doSave($id, $value);
  68 + }
  69 +
  70 + return $value;
  71 + }
  72 + }
  73 +
  74 + return false;
  75 + }
  76 +
  77 + /**
  78 + * {@inheritDoc}
  79 + */
  80 + protected function doContains($id)
  81 + {
  82 + foreach ($this->cacheProviders as $cacheProvider) {
  83 + if ($cacheProvider->doContains($id)) {
  84 + return true;
  85 + }
  86 + }
  87 +
  88 + return false;
  89 + }
  90 +
  91 + /**
  92 + * {@inheritDoc}
  93 + */
  94 + protected function doSave($id, $data, $lifeTime = 0)
  95 + {
  96 + $stored = true;
  97 +
  98 + foreach ($this->cacheProviders as $cacheProvider) {
  99 + $stored = $cacheProvider->doSave($id, $data, $lifeTime) && $stored;
  100 + }
  101 +
  102 + return $stored;
  103 + }
  104 +
  105 + /**
  106 + * {@inheritDoc}
  107 + */
  108 + protected function doDelete($id)
  109 + {
  110 + $deleted = true;
  111 +
  112 + foreach ($this->cacheProviders as $cacheProvider) {
  113 + $deleted = $cacheProvider->doDelete($id) && $deleted;
  114 + }
  115 +
  116 + return $deleted;
  117 + }
  118 +
  119 + /**
  120 + * {@inheritDoc}
  121 + */
  122 + protected function doFlush()
  123 + {
  124 + $flushed = true;
  125 +
  126 + foreach ($this->cacheProviders as $cacheProvider) {
  127 + $flushed = $cacheProvider->doFlush() && $flushed;
  128 + }
  129 +
  130 + return $flushed;
  131 + }
  132 +
  133 + /**
  134 + * {@inheritDoc}
  135 + */
  136 + protected function doGetStats()
  137 + {
  138 + // We return all the stats from all adapters
  139 + $stats = array();
  140 +
  141 + foreach ($this->cacheProviders as $cacheProvider) {
  142 + $stats[] = $cacheProvider->doGetStats();
  143 + }
  144 +
  145 + return $stats;
  146 + }
  147 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +/**
  23 + * Interface for cache that can be flushed.
  24 + *
  25 + * Intended to be used for partial clearing of a cache namespace. For a more
  26 + * global "flushing", see {@see FlushableCache}.
  27 + *
  28 + * @link www.doctrine-project.org
  29 + * @since 1.4
  30 + * @author Adirelle <adirelle@gmail.com>
  31 + */
  32 +interface ClearableCache
  33 +{
  34 + /**
  35 + * Deletes all cache entries in the current cache namespace.
  36 + *
  37 + * @return boolean TRUE if the cache entries were successfully deleted, FALSE otherwise.
  38 + */
  39 + public function deleteAll();
  40 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +use \Couchbase;
  23 +
  24 +/**
  25 + * Couchbase cache provider.
  26 + *
  27 + * @link www.doctrine-project.org
  28 + * @since 2.4
  29 + * @author Michael Nitschinger <michael@nitschinger.at>
  30 + */
  31 +class CouchbaseCache extends CacheProvider
  32 +{
  33 + /**
  34 + * @var Couchbase|null
  35 + */
  36 + private $couchbase;
  37 +
  38 + /**
  39 + * Sets the Couchbase instance to use.
  40 + *
  41 + * @param Couchbase $couchbase
  42 + *
  43 + * @return void
  44 + */
  45 + public function setCouchbase(Couchbase $couchbase)
  46 + {
  47 + $this->couchbase = $couchbase;
  48 + }
  49 +
  50 + /**
  51 + * Gets the Couchbase instance used by the cache.
  52 + *
  53 + * @return Couchbase|null
  54 + */
  55 + public function getCouchbase()
  56 + {
  57 + return $this->couchbase;
  58 + }
  59 +
  60 + /**
  61 + * {@inheritdoc}
  62 + */
  63 + protected function doFetch($id)
  64 + {
  65 + return $this->couchbase->get($id) ?: false;
  66 + }
  67 +
  68 + /**
  69 + * {@inheritdoc}
  70 + */
  71 + protected function doContains($id)
  72 + {
  73 + return (null !== $this->couchbase->get($id));
  74 + }
  75 +
  76 + /**
  77 + * {@inheritdoc}
  78 + */
  79 + protected function doSave($id, $data, $lifeTime = 0)
  80 + {
  81 + if ($lifeTime > 30 * 24 * 3600) {
  82 + $lifeTime = time() + $lifeTime;
  83 + }
  84 + return $this->couchbase->set($id, $data, (int) $lifeTime);
  85 + }
  86 +
  87 + /**
  88 + * {@inheritdoc}
  89 + */
  90 + protected function doDelete($id)
  91 + {
  92 + return $this->couchbase->delete($id);
  93 + }
  94 +
  95 + /**
  96 + * {@inheritdoc}
  97 + */
  98 + protected function doFlush()
  99 + {
  100 + return $this->couchbase->flush();
  101 + }
  102 +
  103 + /**
  104 + * {@inheritdoc}
  105 + */
  106 + protected function doGetStats()
  107 + {
  108 + $stats = $this->couchbase->getStats();
  109 + $servers = $this->couchbase->getServers();
  110 + $server = explode(":", $servers[0]);
  111 + $key = $server[0] . ":" . "11210";
  112 + $stats = $stats[$key];
  113 + return array(
  114 + Cache::STATS_HITS => $stats['get_hits'],
  115 + Cache::STATS_MISSES => $stats['get_misses'],
  116 + Cache::STATS_UPTIME => $stats['uptime'],
  117 + Cache::STATS_MEMORY_USAGE => $stats['bytes'],
  118 + Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'],
  119 + );
  120 + }
  121 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +/**
  23 + * Base file cache driver.
  24 + *
  25 + * @since 2.3
  26 + * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
  27 + */
  28 +abstract class FileCache extends CacheProvider
  29 +{
  30 + /**
  31 + * The cache directory.
  32 + *
  33 + * @var string
  34 + */
  35 + protected $directory;
  36 +
  37 + /**
  38 + * The cache file extension.
  39 + *
  40 + * @var string
  41 + */
  42 + private $extension;
  43 +
  44 + /**
  45 + * @var string[] regular expressions for replacing disallowed characters in file name
  46 + */
  47 + private $disallowedCharacterPatterns = array(
  48 + '/\-/', // replaced to disambiguate original `-` and `-` derived from replacements
  49 + '/[^a-zA-Z0-9\-_\[\]]/' // also excludes non-ascii chars (not supported, depending on FS)
  50 + );
  51 +
  52 + /**
  53 + * @var string[] replacements for disallowed file characters
  54 + */
  55 + private $replacementCharacters = array('__', '-');
  56 +
  57 + /**
  58 + * @var int
  59 + */
  60 + private $umask;
  61 +
  62 + /**
  63 + * Constructor.
  64 + *
  65 + * @param string $directory The cache directory.
  66 + * @param string $extension The cache file extension.
  67 + *
  68 + * @throws \InvalidArgumentException
  69 + */
  70 + public function __construct($directory, $extension = '', $umask = 0002)
  71 + {
  72 + // YES, this needs to be *before* createPathIfNeeded()
  73 + if ( ! is_int($umask)) {
  74 + throw new \InvalidArgumentException(sprintf(
  75 + 'The umask parameter is required to be integer, was: %s',
  76 + gettype($umask)
  77 + ));
  78 + }
  79 + $this->umask = $umask;
  80 +
  81 + if ( ! $this->createPathIfNeeded($directory)) {
  82 + throw new \InvalidArgumentException(sprintf(
  83 + 'The directory "%s" does not exist and could not be created.',
  84 + $directory
  85 + ));
  86 + }
  87 +
  88 + if ( ! is_writable($directory)) {
  89 + throw new \InvalidArgumentException(sprintf(
  90 + 'The directory "%s" is not writable.',
  91 + $directory
  92 + ));
  93 + }
  94 +
  95 + // YES, this needs to be *after* createPathIfNeeded()
  96 + $this->directory = realpath($directory);
  97 + $this->extension = (string) $extension;
  98 + }
  99 +
  100 + /**
  101 + * Gets the cache directory.
  102 + *
  103 + * @return string
  104 + */
  105 + public function getDirectory()
  106 + {
  107 + return $this->directory;
  108 + }
  109 +
  110 + /**
  111 + * Gets the cache file extension.
  112 + *
  113 + * @return string|null
  114 + */
  115 + public function getExtension()
  116 + {
  117 + return $this->extension;
  118 + }
  119 +
  120 + /**
  121 + * @param string $id
  122 + *
  123 + * @return string
  124 + */
  125 + protected function getFilename($id)
  126 + {
  127 + return $this->directory
  128 + . DIRECTORY_SEPARATOR
  129 + . implode(str_split(hash('sha256', $id), 2), DIRECTORY_SEPARATOR)
  130 + . DIRECTORY_SEPARATOR
  131 + . preg_replace($this->disallowedCharacterPatterns, $this->replacementCharacters, $id)
  132 + . $this->extension;
  133 + }
  134 +
  135 + /**
  136 + * {@inheritdoc}
  137 + */
  138 + protected function doDelete($id)
  139 + {
  140 + $filename = $this->getFilename($id);
  141 +
  142 + return @unlink($filename) || ! file_exists($filename);
  143 + }
  144 +
  145 + /**
  146 + * {@inheritdoc}
  147 + */
  148 + protected function doFlush()
  149 + {
  150 + foreach ($this->getIterator() as $name => $file) {
  151 + if ($file->isDir()) {
  152 + // Remove the intermediate directories which have been created to balance the tree. It only takes effect
  153 + // if the directory is empty. If several caches share the same directory but with different file extensions,
  154 + // the other ones are not removed.
  155 + @rmdir($name);
  156 + } elseif ($this->isFilenameEndingWithExtension($name)) {
  157 + // If an extension is set, only remove files which end with the given extension.
  158 + // If no extension is set, we have no other choice than removing everything.
  159 + @unlink($name);
  160 + }
  161 + }
  162 +
  163 + return true;
  164 + }
  165 +
  166 + /**
  167 + * {@inheritdoc}
  168 + */
  169 + protected function doGetStats()
  170 + {
  171 + $usage = 0;
  172 + foreach ($this->getIterator() as $name => $file) {
  173 + if (! $file->isDir() && $this->isFilenameEndingWithExtension($name)) {
  174 + $usage += $file->getSize();
  175 + }
  176 + }
  177 +
  178 + $free = disk_free_space($this->directory);
  179 +
  180 + return array(
  181 + Cache::STATS_HITS => null,
  182 + Cache::STATS_MISSES => null,
  183 + Cache::STATS_UPTIME => null,
  184 + Cache::STATS_MEMORY_USAGE => $usage,
  185 + Cache::STATS_MEMORY_AVAILABLE => $free,
  186 + );
  187 + }
  188 +
  189 + /**
  190 + * Create path if needed.
  191 + *
  192 + * @param string $path
  193 + * @return bool TRUE on success or if path already exists, FALSE if path cannot be created.
  194 + */
  195 + private function createPathIfNeeded($path)
  196 + {
  197 + if ( ! is_dir($path)) {
  198 + if (false === @mkdir($path, 0777 & (~$this->umask), true) && !is_dir($path)) {
  199 + return false;
  200 + }
  201 + }
  202 +
  203 + return true;
  204 + }
  205 +
  206 + /**
  207 + * Writes a string content to file in an atomic way.
  208 + *
  209 + * @param string $filename Path to the file where to write the data.
  210 + * @param string $content The content to write
  211 + *
  212 + * @return bool TRUE on success, FALSE if path cannot be created, if path is not writable or an any other error.
  213 + */
  214 + protected function writeFile($filename, $content)
  215 + {
  216 + $filepath = pathinfo($filename, PATHINFO_DIRNAME);
  217 +
  218 + if ( ! $this->createPathIfNeeded($filepath)) {
  219 + return false;
  220 + }
  221 +
  222 + if ( ! is_writable($filepath)) {
  223 + return false;
  224 + }
  225 +
  226 + $tmpFile = tempnam($filepath, 'swap');
  227 + @chmod($tmpFile, 0666 & (~$this->umask));
  228 +
  229 + if (file_put_contents($tmpFile, $content) !== false) {
  230 + if (@rename($tmpFile, $filename)) {
  231 + return true;
  232 + }
  233 +
  234 + @unlink($tmpFile);
  235 + }
  236 +
  237 + return false;
  238 + }
  239 +
  240 + /**
  241 + * @return \Iterator
  242 + */
  243 + private function getIterator()
  244 + {
  245 + return new \RecursiveIteratorIterator(
  246 + new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS),
  247 + \RecursiveIteratorIterator::CHILD_FIRST
  248 + );
  249 + }
  250 +
  251 + /**
  252 + * @param string $name The filename
  253 + *
  254 + * @return bool
  255 + */
  256 + private function isFilenameEndingWithExtension($name)
  257 + {
  258 + return '' === $this->extension
  259 + || strrpos($name, $this->extension) === (strlen($name) - strlen($this->extension));
  260 + }
  261 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +/**
  23 + * Filesystem cache driver.
  24 + *
  25 + * @since 2.3
  26 + * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
  27 + */
  28 +class FilesystemCache extends FileCache
  29 +{
  30 + const EXTENSION = '.doctrinecache.data';
  31 +
  32 + /**
  33 + * {@inheritdoc}
  34 + */
  35 + public function __construct($directory, $extension = self::EXTENSION, $umask = 0002)
  36 + {
  37 + parent::__construct($directory, $extension, $umask);
  38 + }
  39 +
  40 + /**
  41 + * {@inheritdoc}
  42 + */
  43 + protected function doFetch($id)
  44 + {
  45 + $data = '';
  46 + $lifetime = -1;
  47 + $filename = $this->getFilename($id);
  48 +
  49 + if ( ! is_file($filename)) {
  50 + return false;
  51 + }
  52 +
  53 + $resource = fopen($filename, "r");
  54 +
  55 + if (false !== ($line = fgets($resource))) {
  56 + $lifetime = (int) $line;
  57 + }
  58 +
  59 + if ($lifetime !== 0 && $lifetime < time()) {
  60 + fclose($resource);
  61 +
  62 + return false;
  63 + }
  64 +
  65 + while (false !== ($line = fgets($resource))) {
  66 + $data .= $line;
  67 + }
  68 +
  69 + fclose($resource);
  70 +
  71 + return unserialize($data);
  72 + }
  73 +
  74 + /**
  75 + * {@inheritdoc}
  76 + */
  77 + protected function doContains($id)
  78 + {
  79 + $lifetime = -1;
  80 + $filename = $this->getFilename($id);
  81 +
  82 + if ( ! is_file($filename)) {
  83 + return false;
  84 + }
  85 +
  86 + $resource = fopen($filename, "r");
  87 +
  88 + if (false !== ($line = fgets($resource))) {
  89 + $lifetime = (int) $line;
  90 + }
  91 +
  92 + fclose($resource);
  93 +
  94 + return $lifetime === 0 || $lifetime > time();
  95 + }
  96 +
  97 + /**
  98 + * {@inheritdoc}
  99 + */
  100 + protected function doSave($id, $data, $lifeTime = 0)
  101 + {
  102 + if ($lifeTime > 0) {
  103 + $lifeTime = time() + $lifeTime;
  104 + }
  105 +
  106 + $data = serialize($data);
  107 + $filename = $this->getFilename($id);
  108 +
  109 + return $this->writeFile($filename, $lifeTime . PHP_EOL . $data);
  110 + }
  111 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +/**
  23 + * Interface for cache that can be flushed.
  24 + *
  25 + * @link www.doctrine-project.org
  26 + * @since 1.4
  27 + * @author Adirelle <adirelle@gmail.com>
  28 + */
  29 +interface FlushableCache
  30 +{
  31 + /**
  32 + * Flushes all cache entries, globally.
  33 + *
  34 + * @return boolean TRUE if the cache entries were successfully flushed, FALSE otherwise.
  35 + */
  36 + public function flushAll();
  37 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +use \Memcache;
  23 +
  24 +/**
  25 + * Memcache cache provider.
  26 + *
  27 + * @link www.doctrine-project.org
  28 + * @since 2.0
  29 + * @author Benjamin Eberlei <kontakt@beberlei.de>
  30 + * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
  31 + * @author Jonathan Wage <jonwage@gmail.com>
  32 + * @author Roman Borschel <roman@code-factory.org>
  33 + * @author David Abdemoulaie <dave@hobodave.com>
  34 + */
  35 +class MemcacheCache extends CacheProvider
  36 +{
  37 + /**
  38 + * @var Memcache|null
  39 + */
  40 + private $memcache;
  41 +
  42 + /**
  43 + * Sets the memcache instance to use.
  44 + *
  45 + * @param Memcache $memcache
  46 + *
  47 + * @return void
  48 + */
  49 + public function setMemcache(Memcache $memcache)
  50 + {
  51 + $this->memcache = $memcache;
  52 + }
  53 +
  54 + /**
  55 + * Gets the memcache instance used by the cache.
  56 + *
  57 + * @return Memcache|null
  58 + */
  59 + public function getMemcache()
  60 + {
  61 + return $this->memcache;
  62 + }
  63 +
  64 + /**
  65 + * {@inheritdoc}
  66 + */
  67 + protected function doFetch($id)
  68 + {
  69 + return $this->memcache->get($id);
  70 + }
  71 +
  72 + /**
  73 + * {@inheritdoc}
  74 + */
  75 + protected function doContains($id)
  76 + {
  77 + $flags = null;
  78 + $this->memcache->get($id, $flags);
  79 +
  80 + //if memcache has changed the value of "flags", it means the value exists
  81 + return ($flags !== null);
  82 + }
  83 +
  84 + /**
  85 + * {@inheritdoc}
  86 + */
  87 + protected function doSave($id, $data, $lifeTime = 0)
  88 + {
  89 + if ($lifeTime > 30 * 24 * 3600) {
  90 + $lifeTime = time() + $lifeTime;
  91 + }
  92 + return $this->memcache->set($id, $data, 0, (int) $lifeTime);
  93 + }
  94 +
  95 + /**
  96 + * {@inheritdoc}
  97 + */
  98 + protected function doDelete($id)
  99 + {
  100 + // Memcache::delete() returns false if entry does not exist
  101 + return $this->memcache->delete($id) || ! $this->doContains($id);
  102 + }
  103 +
  104 + /**
  105 + * {@inheritdoc}
  106 + */
  107 + protected function doFlush()
  108 + {
  109 + return $this->memcache->flush();
  110 + }
  111 +
  112 + /**
  113 + * {@inheritdoc}
  114 + */
  115 + protected function doGetStats()
  116 + {
  117 + $stats = $this->memcache->getStats();
  118 + return array(
  119 + Cache::STATS_HITS => $stats['get_hits'],
  120 + Cache::STATS_MISSES => $stats['get_misses'],
  121 + Cache::STATS_UPTIME => $stats['uptime'],
  122 + Cache::STATS_MEMORY_USAGE => $stats['bytes'],
  123 + Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'],
  124 + );
  125 + }
  126 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +use \Memcached;
  23 +
  24 +/**
  25 + * Memcached cache provider.
  26 + *
  27 + * @link www.doctrine-project.org
  28 + * @since 2.2
  29 + * @author Benjamin Eberlei <kontakt@beberlei.de>
  30 + * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
  31 + * @author Jonathan Wage <jonwage@gmail.com>
  32 + * @author Roman Borschel <roman@code-factory.org>
  33 + * @author David Abdemoulaie <dave@hobodave.com>
  34 + */
  35 +class MemcachedCache extends CacheProvider
  36 +{
  37 + /**
  38 + * @var Memcached|null
  39 + */
  40 + private $memcached;
  41 +
  42 + /**
  43 + * Sets the memcache instance to use.
  44 + *
  45 + * @param Memcached $memcached
  46 + *
  47 + * @return void
  48 + */
  49 + public function setMemcached(Memcached $memcached)
  50 + {
  51 + $this->memcached = $memcached;
  52 + }
  53 +
  54 + /**
  55 + * Gets the memcached instance used by the cache.
  56 + *
  57 + * @return Memcached|null
  58 + */
  59 + public function getMemcached()
  60 + {
  61 + return $this->memcached;
  62 + }
  63 +
  64 + /**
  65 + * {@inheritdoc}
  66 + */
  67 + protected function doFetch($id)
  68 + {
  69 + return $this->memcached->get($id);
  70 + }
  71 +
  72 + /**
  73 + * {@inheritdoc}
  74 + */
  75 + protected function doFetchMultiple(array $keys)
  76 + {
  77 + return $this->memcached->getMulti($keys);
  78 + }
  79 +
  80 + /**
  81 + * {@inheritdoc}
  82 + */
  83 + protected function doContains($id)
  84 + {
  85 + return false !== $this->memcached->get($id)
  86 + || $this->memcached->getResultCode() !== Memcached::RES_NOTFOUND;
  87 + }
  88 +
  89 + /**
  90 + * {@inheritdoc}
  91 + */
  92 + protected function doSave($id, $data, $lifeTime = 0)
  93 + {
  94 + if ($lifeTime > 30 * 24 * 3600) {
  95 + $lifeTime = time() + $lifeTime;
  96 + }
  97 + return $this->memcached->set($id, $data, (int) $lifeTime);
  98 + }
  99 +
  100 + /**
  101 + * {@inheritdoc}
  102 + */
  103 + protected function doDelete($id)
  104 + {
  105 + return $this->memcached->delete($id)
  106 + || $this->memcached->getResultCode() === Memcached::RES_NOTFOUND;
  107 + }
  108 +
  109 + /**
  110 + * {@inheritdoc}
  111 + */
  112 + protected function doFlush()
  113 + {
  114 + return $this->memcached->flush();
  115 + }
  116 +
  117 + /**
  118 + * {@inheritdoc}
  119 + */
  120 + protected function doGetStats()
  121 + {
  122 + $stats = $this->memcached->getStats();
  123 + $servers = $this->memcached->getServerList();
  124 + $key = $servers[0]['host'] . ':' . $servers[0]['port'];
  125 + $stats = $stats[$key];
  126 + return array(
  127 + Cache::STATS_HITS => $stats['get_hits'],
  128 + Cache::STATS_MISSES => $stats['get_misses'],
  129 + Cache::STATS_UPTIME => $stats['uptime'],
  130 + Cache::STATS_MEMORY_USAGE => $stats['bytes'],
  131 + Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'],
  132 + );
  133 + }
  134 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +use MongoBinData;
  23 +use MongoCollection;
  24 +use MongoDate;
  25 +
  26 +/**
  27 + * MongoDB cache provider.
  28 + *
  29 + * @since 1.1
  30 + * @author Jeremy Mikola <jmikola@gmail.com>
  31 + */
  32 +class MongoDBCache extends CacheProvider
  33 +{
  34 + /**
  35 + * The data field will store the serialized PHP value.
  36 + */
  37 + const DATA_FIELD = 'd';
  38 +
  39 + /**
  40 + * The expiration field will store a MongoDate value indicating when the
  41 + * cache entry should expire.
  42 + *
  43 + * With MongoDB 2.2+, entries can be automatically deleted by MongoDB by
  44 + * indexing this field with the "expireAfterSeconds" option equal to zero.
  45 + * This will direct MongoDB to regularly query for and delete any entries
  46 + * whose date is older than the current time. Entries without a date value
  47 + * in this field will be ignored.
  48 + *
  49 + * The cache provider will also check dates on its own, in case expired
  50 + * entries are fetched before MongoDB's TTLMonitor pass can expire them.
  51 + *
  52 + * @see http://docs.mongodb.org/manual/tutorial/expire-data/
  53 + */
  54 + const EXPIRATION_FIELD = 'e';
  55 +
  56 + /**
  57 + * @var MongoCollection
  58 + */
  59 + private $collection;
  60 +
  61 + /**
  62 + * Constructor.
  63 + *
  64 + * This provider will default to the write concern and read preference
  65 + * options set on the MongoCollection instance (or inherited from MongoDB or
  66 + * MongoClient). Using an unacknowledged write concern (< 1) may make the
  67 + * return values of delete() and save() unreliable. Reading from secondaries
  68 + * may make contain() and fetch() unreliable.
  69 + *
  70 + * @see http://www.php.net/manual/en/mongo.readpreferences.php
  71 + * @see http://www.php.net/manual/en/mongo.writeconcerns.php
  72 + * @param MongoCollection $collection
  73 + */
  74 + public function __construct(MongoCollection $collection)
  75 + {
  76 + $this->collection = $collection;
  77 + }
  78 +
  79 + /**
  80 + * {@inheritdoc}
  81 + */
  82 + protected function doFetch($id)
  83 + {
  84 + $document = $this->collection->findOne(array('_id' => $id), array(self::DATA_FIELD, self::EXPIRATION_FIELD));
  85 +
  86 + if ($document === null) {
  87 + return false;
  88 + }
  89 +
  90 + if ($this->isExpired($document)) {
  91 + $this->doDelete($id);
  92 + return false;
  93 + }
  94 +
  95 + return unserialize($document[self::DATA_FIELD]->bin);
  96 + }
  97 +
  98 + /**
  99 + * {@inheritdoc}
  100 + */
  101 + protected function doContains($id)
  102 + {
  103 + $document = $this->collection->findOne(array('_id' => $id), array(self::EXPIRATION_FIELD));
  104 +
  105 + if ($document === null) {
  106 + return false;
  107 + }
  108 +
  109 + if ($this->isExpired($document)) {
  110 + $this->doDelete($id);
  111 + return false;
  112 + }
  113 +
  114 + return true;
  115 + }
  116 +
  117 + /**
  118 + * {@inheritdoc}
  119 + */
  120 + protected function doSave($id, $data, $lifeTime = 0)
  121 + {
  122 + $result = $this->collection->update(
  123 + array('_id' => $id),
  124 + array('$set' => array(
  125 + self::EXPIRATION_FIELD => ($lifeTime > 0 ? new MongoDate(time() + $lifeTime) : null),
  126 + self::DATA_FIELD => new MongoBinData(serialize($data), MongoBinData::BYTE_ARRAY),
  127 + )),
  128 + array('upsert' => true, 'multiple' => false)
  129 + );
  130 +
  131 + return isset($result['ok']) ? $result['ok'] == 1 : true;
  132 + }
  133 +
  134 + /**
  135 + * {@inheritdoc}
  136 + */
  137 + protected function doDelete($id)
  138 + {
  139 + $result = $this->collection->remove(array('_id' => $id));
  140 +
  141 + return isset($result['ok']) ? $result['ok'] == 1 : true;
  142 + }
  143 +
  144 + /**
  145 + * {@inheritdoc}
  146 + */
  147 + protected function doFlush()
  148 + {
  149 + // Use remove() in lieu of drop() to maintain any collection indexes
  150 + $result = $this->collection->remove();
  151 +
  152 + return isset($result['ok']) ? $result['ok'] == 1 : true;
  153 + }
  154 +
  155 + /**
  156 + * {@inheritdoc}
  157 + */
  158 + protected function doGetStats()
  159 + {
  160 + $serverStatus = $this->collection->db->command(array(
  161 + 'serverStatus' => 1,
  162 + 'locks' => 0,
  163 + 'metrics' => 0,
  164 + 'recordStats' => 0,
  165 + 'repl' => 0,
  166 + ));
  167 +
  168 + $collStats = $this->collection->db->command(array('collStats' => 1));
  169 +
  170 + return array(
  171 + Cache::STATS_HITS => null,
  172 + Cache::STATS_MISSES => null,
  173 + Cache::STATS_UPTIME => (isset($serverStatus['uptime']) ? (int) $serverStatus['uptime'] : null),
  174 + Cache::STATS_MEMORY_USAGE => (isset($collStats['size']) ? (int) $collStats['size'] : null),
  175 + Cache::STATS_MEMORY_AVAILABLE => null,
  176 + );
  177 + }
  178 +
  179 + /**
  180 + * Check if the document is expired.
  181 + *
  182 + * @param array $document
  183 + * @return boolean
  184 + */
  185 + private function isExpired(array $document)
  186 + {
  187 + return isset($document[self::EXPIRATION_FIELD]) &&
  188 + $document[self::EXPIRATION_FIELD] instanceof MongoDate &&
  189 + $document[self::EXPIRATION_FIELD]->sec < time();
  190 + }
  191 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +/**
  23 + * Interface for cache drivers that allows to get many items at once.
  24 + *
  25 + * @link www.doctrine-project.org
  26 + * @since 1.4
  27 + * @author Asmir Mustafic <goetas@gmail.com>
  28 + */
  29 +interface MultiGetCache
  30 +{
  31 + /**
  32 + * Returns an associative array of values for keys is found in cache.
  33 + *
  34 + * @param string[] $keys Array of keys to retrieve from cache
  35 + * @return mixed[] Array of retrieved values, indexed by the specified keys.
  36 + * Values that couldn't be retrieved are not contained in this array.
  37 + */
  38 + function fetchMultiple(array $keys);
  39 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +/**
  23 + * Php file cache driver.
  24 + *
  25 + * @since 2.3
  26 + * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
  27 + */
  28 +class PhpFileCache extends FileCache
  29 +{
  30 + const EXTENSION = '.doctrinecache.php';
  31 +
  32 + /**
  33 + * {@inheritdoc}
  34 + */
  35 + public function __construct($directory, $extension = self::EXTENSION, $umask = 0002)
  36 + {
  37 + parent::__construct($directory, $extension, $umask);
  38 + }
  39 +
  40 + /**
  41 + * {@inheritdoc}
  42 + */
  43 + protected function doFetch($id)
  44 + {
  45 + $value = $this->includeFileForId($id);
  46 +
  47 + if (! $value) {
  48 + return false;
  49 + }
  50 +
  51 + if ($value['lifetime'] !== 0 && $value['lifetime'] < time()) {
  52 + return false;
  53 + }
  54 +
  55 + return $value['data'];
  56 + }
  57 +
  58 + /**
  59 + * {@inheritdoc}
  60 + */
  61 + protected function doContains($id)
  62 + {
  63 + $value = $this->includeFileForId($id);
  64 +
  65 + if (! $value) {
  66 + return false;
  67 + }
  68 +
  69 + return $value['lifetime'] === 0 || $value['lifetime'] > time();
  70 + }
  71 +
  72 + /**
  73 + * {@inheritdoc}
  74 + */
  75 + protected function doSave($id, $data, $lifeTime = 0)
  76 + {
  77 + if ($lifeTime > 0) {
  78 + $lifeTime = time() + $lifeTime;
  79 + }
  80 +
  81 + if (is_object($data) && ! method_exists($data, '__set_state')) {
  82 + throw new \InvalidArgumentException(
  83 + "Invalid argument given, PhpFileCache only allows objects that implement __set_state() " .
  84 + "and fully support var_export(). You can use the FilesystemCache to save arbitrary object " .
  85 + "graphs using serialize()/deserialize()."
  86 + );
  87 + }
  88 +
  89 + $filename = $this->getFilename($id);
  90 +
  91 + $value = array(
  92 + 'lifetime' => $lifeTime,
  93 + 'data' => $data
  94 + );
  95 +
  96 + $value = var_export($value, true);
  97 + $code = sprintf('<?php return %s;', $value);
  98 +
  99 + return $this->writeFile($filename, $code);
  100 + }
  101 +
  102 + /**
  103 + * @param string $id
  104 + *
  105 + * @return array|false
  106 + */
  107 + private function includeFileForId($id)
  108 + {
  109 + $fileName = $this->getFilename($id);
  110 +
  111 + // note: error suppression is still faster than `file_exists`, `is_file` and `is_readable`
  112 + $value = @include $fileName;
  113 +
  114 + if (! isset($value['lifetime'])) {
  115 + return false;
  116 + }
  117 +
  118 + return $value;
  119 + }
  120 +}
  1 +<?php
  2 +
  3 +namespace Doctrine\Common\Cache;
  4 +
  5 +use Predis\Client;
  6 +
  7 +/**
  8 + * Predis cache provider.
  9 + *
  10 + * @author othillo <othillo@othillo.nl>
  11 + */
  12 +class PredisCache extends CacheProvider
  13 +{
  14 + /**
  15 + * @var Client
  16 + */
  17 + private $client;
  18 +
  19 + /**
  20 + * @param Client $client
  21 + *
  22 + * @return void
  23 + */
  24 + public function __construct(Client $client)
  25 + {
  26 + $this->client = $client;
  27 + }
  28 +
  29 + /**
  30 + * {@inheritdoc}
  31 + */
  32 + protected function doFetch($id)
  33 + {
  34 + $result = $this->client->get($id);
  35 + if (null === $result) {
  36 + return false;
  37 + }
  38 +
  39 + return unserialize($result);
  40 + }
  41 +
  42 + /**
  43 + * {@inheritdoc}
  44 + */
  45 + protected function doFetchMultiple(array $keys)
  46 + {
  47 + $fetchedItems = call_user_func_array(array($this->client, 'mget'), $keys);
  48 +
  49 + return array_map('unserialize', array_filter(array_combine($keys, $fetchedItems)));
  50 + }
  51 +
  52 + /**
  53 + * {@inheritdoc}
  54 + */
  55 + protected function doContains($id)
  56 + {
  57 + return $this->client->exists($id);
  58 + }
  59 +
  60 + /**
  61 + * {@inheritdoc}
  62 + */
  63 + protected function doSave($id, $data, $lifeTime = 0)
  64 + {
  65 + $data = serialize($data);
  66 + if ($lifeTime > 0) {
  67 + $response = $this->client->setex($id, $lifeTime, $data);
  68 + } else {
  69 + $response = $this->client->set($id, $data);
  70 + }
  71 +
  72 + return $response === true || $response == 'OK';
  73 + }
  74 +
  75 + /**
  76 + * {@inheritdoc}
  77 + */
  78 + protected function doDelete($id)
  79 + {
  80 + return $this->client->del($id) >= 0;
  81 + }
  82 +
  83 + /**
  84 + * {@inheritdoc}
  85 + */
  86 + protected function doFlush()
  87 + {
  88 + $response = $this->client->flushdb();
  89 +
  90 + return $response === true || $response == 'OK';
  91 + }
  92 +
  93 + /**
  94 + * {@inheritdoc}
  95 + */
  96 + protected function doGetStats()
  97 + {
  98 + $info = $this->client->info();
  99 +
  100 + return array(
  101 + Cache::STATS_HITS => $info['Stats']['keyspace_hits'],
  102 + Cache::STATS_MISSES => $info['Stats']['keyspace_misses'],
  103 + Cache::STATS_UPTIME => $info['Server']['uptime_in_seconds'],
  104 + Cache::STATS_MEMORY_USAGE => $info['Memory']['used_memory'],
  105 + Cache::STATS_MEMORY_AVAILABLE => false
  106 + );
  107 + }
  108 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +use Redis;
  23 +
  24 +/**
  25 + * Redis cache provider.
  26 + *
  27 + * @link www.doctrine-project.org
  28 + * @since 2.2
  29 + * @author Osman Ungur <osmanungur@gmail.com>
  30 + */
  31 +class RedisCache extends CacheProvider
  32 +{
  33 + /**
  34 + * @var Redis|null
  35 + */
  36 + private $redis;
  37 +
  38 + /**
  39 + * Sets the redis instance to use.
  40 + *
  41 + * @param Redis $redis
  42 + *
  43 + * @return void
  44 + */
  45 + public function setRedis(Redis $redis)
  46 + {
  47 + $redis->setOption(Redis::OPT_SERIALIZER, $this->getSerializerValue());
  48 + $this->redis = $redis;
  49 + }
  50 +
  51 + /**
  52 + * Gets the redis instance used by the cache.
  53 + *
  54 + * @return Redis|null
  55 + */
  56 + public function getRedis()
  57 + {
  58 + return $this->redis;
  59 + }
  60 +
  61 + /**
  62 + * {@inheritdoc}
  63 + */
  64 + protected function doFetch($id)
  65 + {
  66 + return $this->redis->get($id);
  67 + }
  68 +
  69 + /**
  70 + * {@inheritdoc}
  71 + */
  72 + protected function doFetchMultiple(array $keys)
  73 + {
  74 + $fetchedItems = $this->redis->mget($keys);
  75 +
  76 + return array_filter(
  77 + array_combine($keys, $fetchedItems),
  78 + function ($value) {
  79 + return $value !== false;
  80 + }
  81 + );
  82 + }
  83 +
  84 + /**
  85 + * {@inheritdoc}
  86 + */
  87 + protected function doContains($id)
  88 + {
  89 + return $this->redis->exists($id);
  90 + }
  91 +
  92 + /**
  93 + * {@inheritdoc}
  94 + */
  95 + protected function doSave($id, $data, $lifeTime = 0)
  96 + {
  97 + if ($lifeTime > 0) {
  98 + return $this->redis->setex($id, $lifeTime, $data);
  99 + }
  100 +
  101 + return $this->redis->set($id, $data);
  102 + }
  103 +
  104 + /**
  105 + * {@inheritdoc}
  106 + */
  107 + protected function doDelete($id)
  108 + {
  109 + return $this->redis->delete($id) >= 0;
  110 + }
  111 +
  112 + /**
  113 + * {@inheritdoc}
  114 + */
  115 + protected function doFlush()
  116 + {
  117 + return $this->redis->flushDB();
  118 + }
  119 +
  120 + /**
  121 + * {@inheritdoc}
  122 + */
  123 + protected function doGetStats()
  124 + {
  125 + $info = $this->redis->info();
  126 + return array(
  127 + Cache::STATS_HITS => $info['keyspace_hits'],
  128 + Cache::STATS_MISSES => $info['keyspace_misses'],
  129 + Cache::STATS_UPTIME => $info['uptime_in_seconds'],
  130 + Cache::STATS_MEMORY_USAGE => $info['used_memory'],
  131 + Cache::STATS_MEMORY_AVAILABLE => false
  132 + );
  133 + }
  134 +
  135 + /**
  136 + * Returns the serializer constant to use. If Redis is compiled with
  137 + * igbinary support, that is used. Otherwise the default PHP serializer is
  138 + * used.
  139 + *
  140 + * @return integer One of the Redis::SERIALIZER_* constants
  141 + */
  142 + protected function getSerializerValue()
  143 + {
  144 + if (defined('HHVM_VERSION')) {
  145 + return Redis::SERIALIZER_PHP;
  146 + }
  147 + return defined('Redis::SERIALIZER_IGBINARY') ? Redis::SERIALIZER_IGBINARY : Redis::SERIALIZER_PHP;
  148 + }
  149 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +use Riak\Bucket;
  23 +use Riak\Connection;
  24 +use Riak\Input;
  25 +use Riak\Exception;
  26 +use Riak\Object;
  27 +
  28 +/**
  29 + * Riak cache provider.
  30 + *
  31 + * @link www.doctrine-project.org
  32 + * @since 1.1
  33 + * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
  34 + */
  35 +class RiakCache extends CacheProvider
  36 +{
  37 + const EXPIRES_HEADER = 'X-Riak-Meta-Expires';
  38 +
  39 + /**
  40 + * @var \Riak\Bucket
  41 + */
  42 + private $bucket;
  43 +
  44 + /**
  45 + * Sets the riak bucket instance to use.
  46 + *
  47 + * @param \Riak\Bucket $bucket
  48 + */
  49 + public function __construct(Bucket $bucket)
  50 + {
  51 + $this->bucket = $bucket;
  52 + }
  53 +
  54 + /**
  55 + * {@inheritdoc}
  56 + */
  57 + protected function doFetch($id)
  58 + {
  59 + try {
  60 + $response = $this->bucket->get($id);
  61 +
  62 + // No objects found
  63 + if ( ! $response->hasObject()) {
  64 + return false;
  65 + }
  66 +
  67 + // Check for attempted siblings
  68 + $object = ($response->hasSiblings())
  69 + ? $this->resolveConflict($id, $response->getVClock(), $response->getObjectList())
  70 + : $response->getFirstObject();
  71 +
  72 + // Check for expired object
  73 + if ($this->isExpired($object)) {
  74 + $this->bucket->delete($object);
  75 +
  76 + return false;
  77 + }
  78 +
  79 + return unserialize($object->getContent());
  80 + } catch (Exception\RiakException $e) {
  81 + // Covers:
  82 + // - Riak\ConnectionException
  83 + // - Riak\CommunicationException
  84 + // - Riak\UnexpectedResponseException
  85 + // - Riak\NotFoundException
  86 + }
  87 +
  88 + return false;
  89 + }
  90 +
  91 + /**
  92 + * {@inheritdoc}
  93 + */
  94 + protected function doContains($id)
  95 + {
  96 + try {
  97 + // We only need the HEAD, not the entire object
  98 + $input = new Input\GetInput();
  99 +
  100 + $input->setReturnHead(true);
  101 +
  102 + $response = $this->bucket->get($id, $input);
  103 +
  104 + // No objects found
  105 + if ( ! $response->hasObject()) {
  106 + return false;
  107 + }
  108 +
  109 + $object = $response->getFirstObject();
  110 +
  111 + // Check for expired object
  112 + if ($this->isExpired($object)) {
  113 + $this->bucket->delete($object);
  114 +
  115 + return false;
  116 + }
  117 +
  118 + return true;
  119 + } catch (Exception\RiakException $e) {
  120 + // Do nothing
  121 + }
  122 +
  123 + return false;
  124 + }
  125 +
  126 + /**
  127 + * {@inheritdoc}
  128 + */
  129 + protected function doSave($id, $data, $lifeTime = 0)
  130 + {
  131 + try {
  132 + $object = new Object($id);
  133 +
  134 + $object->setContent(serialize($data));
  135 +
  136 + if ($lifeTime > 0) {
  137 + $object->addMetadata(self::EXPIRES_HEADER, (string) (time() + $lifeTime));
  138 + }
  139 +
  140 + $this->bucket->put($object);
  141 +
  142 + return true;
  143 + } catch (Exception\RiakException $e) {
  144 + // Do nothing
  145 + }
  146 +
  147 + return false;
  148 + }
  149 +
  150 + /**
  151 + * {@inheritdoc}
  152 + */
  153 + protected function doDelete($id)
  154 + {
  155 + try {
  156 + $this->bucket->delete($id);
  157 +
  158 + return true;
  159 + } catch (Exception\BadArgumentsException $e) {
  160 + // Key did not exist on cluster already
  161 + } catch (Exception\RiakException $e) {
  162 + // Covers:
  163 + // - Riak\Exception\ConnectionException
  164 + // - Riak\Exception\CommunicationException
  165 + // - Riak\Exception\UnexpectedResponseException
  166 + }
  167 +
  168 + return false;
  169 + }
  170 +
  171 + /**
  172 + * {@inheritdoc}
  173 + */
  174 + protected function doFlush()
  175 + {
  176 + try {
  177 + $keyList = $this->bucket->getKeyList();
  178 +
  179 + foreach ($keyList as $key) {
  180 + $this->bucket->delete($key);
  181 + }
  182 +
  183 + return true;
  184 + } catch (Exception\RiakException $e) {
  185 + // Do nothing
  186 + }
  187 +
  188 + return false;
  189 + }
  190 +
  191 + /**
  192 + * {@inheritdoc}
  193 + */
  194 + protected function doGetStats()
  195 + {
  196 + // Only exposed through HTTP stats API, not Protocol Buffers API
  197 + return null;
  198 + }
  199 +
  200 + /**
  201 + * Check if a given Riak Object have expired.
  202 + *
  203 + * @param \Riak\Object $object
  204 + *
  205 + * @return boolean
  206 + */
  207 + private function isExpired(Object $object)
  208 + {
  209 + $metadataMap = $object->getMetadataMap();
  210 +
  211 + return isset($metadataMap[self::EXPIRES_HEADER])
  212 + && $metadataMap[self::EXPIRES_HEADER] < time();
  213 + }
  214 +
  215 + /**
  216 + * On-read conflict resolution. Applied approach here is last write wins.
  217 + * Specific needs may override this method to apply alternate conflict resolutions.
  218 + *
  219 + * {@internal Riak does not attempt to resolve a write conflict, and store
  220 + * it as sibling of conflicted one. By following this approach, it is up to
  221 + * the next read to resolve the conflict. When this happens, your fetched
  222 + * object will have a list of siblings (read as a list of objects).
  223 + * In our specific case, we do not care about the intermediate ones since
  224 + * they are all the same read from storage, and we do apply a last sibling
  225 + * (last write) wins logic.
  226 + * If by any means our resolution generates another conflict, it'll up to
  227 + * next read to properly solve it.}
  228 + *
  229 + * @param string $id
  230 + * @param string $vClock
  231 + * @param array $objectList
  232 + *
  233 + * @return \Riak\Object
  234 + */
  235 + protected function resolveConflict($id, $vClock, array $objectList)
  236 + {
  237 + // Our approach here is last-write wins
  238 + $winner = $objectList[count($objectList)];
  239 +
  240 + $putInput = new Input\PutInput();
  241 + $putInput->setVClock($vClock);
  242 +
  243 + $mergedObject = new Object($id);
  244 + $mergedObject->setContent($winner->getContent());
  245 +
  246 + $this->bucket->put($mergedObject, $putInput);
  247 +
  248 + return $mergedObject;
  249 + }
  250 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +use SQLite3;
  23 +use SQLite3Result;
  24 +
  25 +/**
  26 + * SQLite3 cache provider.
  27 + *
  28 + * @since 1.4
  29 + * @author Jake Bell <jake@theunraveler.com>
  30 + */
  31 +class SQLite3Cache extends CacheProvider
  32 +{
  33 + /**
  34 + * The ID field will store the cache key.
  35 + */
  36 + const ID_FIELD = 'k';
  37 +
  38 + /**
  39 + * The data field will store the serialized PHP value.
  40 + */
  41 + const DATA_FIELD = 'd';
  42 +
  43 + /**
  44 + * The expiration field will store a date value indicating when the
  45 + * cache entry should expire.
  46 + */
  47 + const EXPIRATION_FIELD = 'e';
  48 +
  49 + /**
  50 + * @var SQLite3
  51 + */
  52 + private $sqlite;
  53 +
  54 + /**
  55 + * @var string
  56 + */
  57 + private $table;
  58 +
  59 + /**
  60 + * Constructor.
  61 + *
  62 + * Calling the constructor will ensure that the database file and table
  63 + * exist and will create both if they don't.
  64 + *
  65 + * @param SQLite3 $sqlite
  66 + * @param string $table
  67 + */
  68 + public function __construct(SQLite3 $sqlite, $table)
  69 + {
  70 + $this->sqlite = $sqlite;
  71 + $this->table = (string) $table;
  72 +
  73 + list($id, $data, $exp) = $this->getFields();
  74 +
  75 + return $this->sqlite->exec(sprintf(
  76 + 'CREATE TABLE IF NOT EXISTS %s(%s TEXT PRIMARY KEY NOT NULL, %s BLOB, %s INTEGER)',
  77 + $table,
  78 + $id,
  79 + $data,
  80 + $exp
  81 + ));
  82 + }
  83 +
  84 + /**
  85 + * {@inheritdoc}
  86 + */
  87 + protected function doFetch($id)
  88 + {
  89 + if ($item = $this->findById($id)) {
  90 + return unserialize($item[self::DATA_FIELD]);
  91 + }
  92 +
  93 + return false;
  94 + }
  95 +
  96 + /**
  97 + * {@inheritdoc}
  98 + */
  99 + protected function doContains($id)
  100 + {
  101 + return (boolean) $this->findById($id, false);
  102 + }
  103 +
  104 + /**
  105 + * {@inheritdoc}
  106 + */
  107 + protected function doSave($id, $data, $lifeTime = 0)
  108 + {
  109 + $statement = $this->sqlite->prepare(sprintf(
  110 + 'INSERT OR REPLACE INTO %s (%s) VALUES (:id, :data, :expire)',
  111 + $this->table,
  112 + implode(',', $this->getFields())
  113 + ));
  114 +
  115 + $statement->bindValue(':id', $id);
  116 + $statement->bindValue(':data', serialize($data), SQLITE3_BLOB);
  117 + $statement->bindValue(':expire', $lifeTime > 0 ? time() + $lifeTime : null);
  118 +
  119 + return $statement->execute() instanceof SQLite3Result;
  120 + }
  121 +
  122 + /**
  123 + * {@inheritdoc}
  124 + */
  125 + protected function doDelete($id)
  126 + {
  127 + list($idField) = $this->getFields();
  128 +
  129 + $statement = $this->sqlite->prepare(sprintf(
  130 + 'DELETE FROM %s WHERE %s = :id',
  131 + $this->table,
  132 + $idField
  133 + ));
  134 +
  135 + $statement->bindValue(':id', $id);
  136 +
  137 + return $statement->execute() instanceof SQLite3Result;
  138 + }
  139 +
  140 + /**
  141 + * {@inheritdoc}
  142 + */
  143 + protected function doFlush()
  144 + {
  145 + return $this->sqlite->exec(sprintf('DELETE FROM %s', $this->table));
  146 + }
  147 +
  148 + /**
  149 + * {@inheritdoc}
  150 + */
  151 + protected function doGetStats()
  152 + {
  153 + // no-op.
  154 + }
  155 +
  156 + /**
  157 + * Find a single row by ID.
  158 + *
  159 + * @param mixed $id
  160 + * @param boolean $includeData
  161 + *
  162 + * @return array|null
  163 + */
  164 + private function findById($id, $includeData = true)
  165 + {
  166 + list($idField) = $fields = $this->getFields();
  167 +
  168 + if (!$includeData) {
  169 + $key = array_search(static::DATA_FIELD, $fields);
  170 + unset($fields[$key]);
  171 + }
  172 +
  173 + $statement = $this->sqlite->prepare(sprintf(
  174 + 'SELECT %s FROM %s WHERE %s = :id LIMIT 1',
  175 + implode(',', $fields),
  176 + $this->table,
  177 + $idField
  178 + ));
  179 +
  180 + $statement->bindValue(':id', $id, SQLITE3_TEXT);
  181 +
  182 + $item = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  183 +
  184 + if ($item === false) {
  185 + return null;
  186 + }
  187 +
  188 + if ($this->isExpired($item)) {
  189 + $this->doDelete($id);
  190 +
  191 + return null;
  192 + }
  193 +
  194 + return $item;
  195 + }
  196 +
  197 + /**
  198 + * Gets an array of the fields in our table.
  199 + *
  200 + * @return array
  201 + */
  202 + private function getFields()
  203 + {
  204 + return array(static::ID_FIELD, static::DATA_FIELD, static::EXPIRATION_FIELD);
  205 + }
  206 +
  207 + /**
  208 + * Check if the item is expired.
  209 + *
  210 + * @param array $item
  211 + * @return boolean
  212 + */
  213 + private function isExpired(array $item)
  214 + {
  215 + return isset($item[static::EXPIRATION_FIELD]) &&
  216 + $item[self::EXPIRATION_FIELD] !== null &&
  217 + $item[self::EXPIRATION_FIELD] < time();
  218 + }
  219 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +class Version
  23 +{
  24 + const VERSION = '1.4.4';
  25 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +/**
  23 + * Void cache driver. The cache could be of use in tests where you don`t need to cache anything.
  24 + *
  25 + * @link www.doctrine-project.org
  26 + * @since 1.5
  27 + * @author Kotlyar Maksim <kotlyar.maksim@gmail.com>
  28 + */
  29 +class VoidCache extends CacheProvider
  30 +{
  31 + /**
  32 + * {@inheritDoc}
  33 + */
  34 + protected function doFetch($id)
  35 + {
  36 + return false;
  37 + }
  38 +
  39 + /**
  40 + * {@inheritDoc}
  41 + */
  42 + protected function doContains($id)
  43 + {
  44 + return false;
  45 + }
  46 +
  47 + /**
  48 + * {@inheritDoc}
  49 + */
  50 + protected function doSave($id, $data, $lifeTime = 0)
  51 + {
  52 + return true;
  53 + }
  54 +
  55 + /**
  56 + * {@inheritDoc}
  57 + */
  58 + protected function doDelete($id)
  59 + {
  60 + return true;
  61 + }
  62 +
  63 + /**
  64 + * {@inheritDoc}
  65 + */
  66 + protected function doFlush()
  67 + {
  68 + return true;
  69 + }
  70 +
  71 + /**
  72 + * {@inheritDoc}
  73 + */
  74 + protected function doGetStats()
  75 + {
  76 + return;
  77 + }
  78 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +/**
  23 + * WinCache cache provider.
  24 + *
  25 + * @link www.doctrine-project.org
  26 + * @since 2.2
  27 + * @author Benjamin Eberlei <kontakt@beberlei.de>
  28 + * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
  29 + * @author Jonathan Wage <jonwage@gmail.com>
  30 + * @author Roman Borschel <roman@code-factory.org>
  31 + * @author David Abdemoulaie <dave@hobodave.com>
  32 + */
  33 +class WinCacheCache extends CacheProvider
  34 +{
  35 + /**
  36 + * {@inheritdoc}
  37 + */
  38 + protected function doFetch($id)
  39 + {
  40 + return wincache_ucache_get($id);
  41 + }
  42 +
  43 + /**
  44 + * {@inheritdoc}
  45 + */
  46 + protected function doContains($id)
  47 + {
  48 + return wincache_ucache_exists($id);
  49 + }
  50 +
  51 + /**
  52 + * {@inheritdoc}
  53 + */
  54 + protected function doSave($id, $data, $lifeTime = 0)
  55 + {
  56 + return (bool) wincache_ucache_set($id, $data, (int) $lifeTime);
  57 + }
  58 +
  59 + /**
  60 + * {@inheritdoc}
  61 + */
  62 + protected function doDelete($id)
  63 + {
  64 + return wincache_ucache_delete($id);
  65 + }
  66 +
  67 + /**
  68 + * {@inheritdoc}
  69 + */
  70 + protected function doFlush()
  71 + {
  72 + return wincache_ucache_clear();
  73 + }
  74 +
  75 + /**
  76 + * {@inheritdoc}
  77 + */
  78 + protected function doGetStats()
  79 + {
  80 + $info = wincache_ucache_info();
  81 + $meminfo = wincache_ucache_meminfo();
  82 +
  83 + return array(
  84 + Cache::STATS_HITS => $info['total_hit_count'],
  85 + Cache::STATS_MISSES => $info['total_miss_count'],
  86 + Cache::STATS_UPTIME => $info['total_cache_uptime'],
  87 + Cache::STATS_MEMORY_USAGE => $meminfo['memory_total'],
  88 + Cache::STATS_MEMORY_AVAILABLE => $meminfo['memory_free'],
  89 + );
  90 + }
  91 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +/**
  23 + * Xcache cache driver.
  24 + *
  25 + * @link www.doctrine-project.org
  26 + * @since 2.0
  27 + * @author Benjamin Eberlei <kontakt@beberlei.de>
  28 + * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
  29 + * @author Jonathan Wage <jonwage@gmail.com>
  30 + * @author Roman Borschel <roman@code-factory.org>
  31 + * @author David Abdemoulaie <dave@hobodave.com>
  32 + */
  33 +class XcacheCache extends CacheProvider
  34 +{
  35 + /**
  36 + * {@inheritdoc}
  37 + */
  38 + protected function doFetch($id)
  39 + {
  40 + return $this->doContains($id) ? unserialize(xcache_get($id)) : false;
  41 + }
  42 +
  43 + /**
  44 + * {@inheritdoc}
  45 + */
  46 + protected function doContains($id)
  47 + {
  48 + return xcache_isset($id);
  49 + }
  50 +
  51 + /**
  52 + * {@inheritdoc}
  53 + */
  54 + protected function doSave($id, $data, $lifeTime = 0)
  55 + {
  56 + return xcache_set($id, serialize($data), (int) $lifeTime);
  57 + }
  58 +
  59 + /**
  60 + * {@inheritdoc}
  61 + */
  62 + protected function doDelete($id)
  63 + {
  64 + return xcache_unset($id);
  65 + }
  66 +
  67 + /**
  68 + * {@inheritdoc}
  69 + */
  70 + protected function doFlush()
  71 + {
  72 + $this->checkAuthorization();
  73 +
  74 + xcache_clear_cache(XC_TYPE_VAR);
  75 +
  76 + return true;
  77 + }
  78 +
  79 + /**
  80 + * Checks that xcache.admin.enable_auth is Off.
  81 + *
  82 + * @return void
  83 + *
  84 + * @throws \BadMethodCallException When xcache.admin.enable_auth is On.
  85 + */
  86 + protected function checkAuthorization()
  87 + {
  88 + if (ini_get('xcache.admin.enable_auth')) {
  89 + throw new \BadMethodCallException(
  90 + 'To use all features of \Doctrine\Common\Cache\XcacheCache, '
  91 + . 'you must set "xcache.admin.enable_auth" to "Off" in your php.ini.'
  92 + );
  93 + }
  94 + }
  95 +
  96 + /**
  97 + * {@inheritdoc}
  98 + */
  99 + protected function doGetStats()
  100 + {
  101 + $this->checkAuthorization();
  102 +
  103 + $info = xcache_info(XC_TYPE_VAR, 0);
  104 + return array(
  105 + Cache::STATS_HITS => $info['hits'],
  106 + Cache::STATS_MISSES => $info['misses'],
  107 + Cache::STATS_UPTIME => null,
  108 + Cache::STATS_MEMORY_USAGE => $info['size'],
  109 + Cache::STATS_MEMORY_AVAILABLE => $info['avail'],
  110 + );
  111 + }
  112 +}
  1 +<?php
  2 +/*
  3 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14 + *
  15 + * This software consists of voluntary contributions made by many individuals
  16 + * and is licensed under the MIT license. For more information, see
  17 + * <http://www.doctrine-project.org>.
  18 + */
  19 +
  20 +namespace Doctrine\Common\Cache;
  21 +
  22 +/**
  23 + * Zend Data Cache cache driver.
  24 + *
  25 + * @link www.doctrine-project.org
  26 + * @since 2.0
  27 + * @author Ralph Schindler <ralph.schindler@zend.com>
  28 + * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
  29 + */
  30 +class ZendDataCache extends CacheProvider
  31 +{
  32 + /**
  33 + * {@inheritdoc}
  34 + */
  35 + protected function doFetch($id)
  36 + {
  37 + return zend_shm_cache_fetch($id);
  38 + }
  39 +
  40 + /**
  41 + * {@inheritdoc}
  42 + */
  43 + protected function doContains($id)
  44 + {
  45 + return (false !== zend_shm_cache_fetch($id));
  46 + }
  47 +
  48 + /**
  49 + * {@inheritdoc}
  50 + */
  51 + protected function doSave($id, $data, $lifeTime = 0)
  52 + {
  53 + return zend_shm_cache_store($id, $data, $lifeTime);
  54 + }
  55 +
  56 + /**
  57 + * {@inheritdoc}
  58 + */
  59 + protected function doDelete($id)
  60 + {
  61 + return zend_shm_cache_delete($id);
  62 + }
  63 +
  64 + /**
  65 + * {@inheritdoc}
  66 + */
  67 + protected function doFlush()
  68 + {
  69 + $namespace = $this->getNamespace();
  70 + if (empty($namespace)) {
  71 + return zend_shm_cache_clear();
  72 + }
  73 + return zend_shm_cache_clear($namespace);
  74 + }
  75 +
  76 + /**
  77 + * {@inheritdoc}
  78 + */
  79 + protected function doGetStats()
  80 + {
  81 + return null;
  82 + }
  83 +}
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +
  3 +<phpunit backupGlobals="false"
  4 + backupStaticAttributes="false"
  5 + colors="true"
  6 + convertErrorsToExceptions="true"
  7 + convertNoticesToExceptions="true"
  8 + convertWarningsToExceptions="true"
  9 + processIsolation="false"
  10 + stopOnFailure="false"
  11 + syntaxCheck="false"
  12 + bootstrap="./tests/Doctrine/Tests/TestInit.php"
  13 +>
  14 + <testsuites>
  15 + <testsuite name="Doctrine Cache Test Suite">
  16 + <directory>./tests/Doctrine/</directory>
  17 + </testsuite>
  18 + </testsuites>
  19 +
  20 + <filter>
  21 + <whitelist>
  22 + <directory>./lib/Doctrine/</directory>
  23 + </whitelist>
  24 + </filter>
  25 +</phpunit>
  1 +<?php
  2 +
  3 +namespace Doctrine\Tests\Common\Cache;
  4 +
  5 +use Doctrine\Common\Cache\ApcCache;
  6 +
  7 +class ApcCacheTest extends CacheTest
  8 +{
  9 + public function setUp()
  10 + {
  11 + if ( ! extension_loaded('apc') || false === @apc_cache_info()) {
  12 + $this->markTestSkipped('The ' . __CLASS__ .' requires the use of APC');
  13 + }
  14 + }
  15 +
  16 + protected function _getCacheDriver()
  17 + {
  18 + return new ApcCache();
  19 + }
  20 +}
  1 +<?php
  2 +
  3 +namespace Doctrine\Tests\Common\Cache;
  4 +
  5 +use Doctrine\Common\Cache\ArrayCache;
  6 +
  7 +class ArrayCacheTest extends CacheTest
  8 +{
  9 + protected function _getCacheDriver()
  10 + {
  11 + return new ArrayCache();
  12 + }
  13 +
  14 + public function testGetStats()
  15 + {
  16 + $cache = $this->_getCacheDriver();
  17 + $stats = $cache->getStats();
  18 +
  19 + $this->assertNull($stats);
  20 + }
  21 +
  22 + protected function isSharedStorage()
  23 + {
  24 + return false;
  25 + }
  26 +}
  1 +<?php
  2 +
  3 +namespace Doctrine\Tests\Common\Cache;
  4 +
  5 +use RecursiveDirectoryIterator;
  6 +use RecursiveIteratorIterator;
  7 +
  8 +abstract class BaseFileCacheTest extends CacheTest
  9 +{
  10 + protected $directory;
  11 +
  12 + public function testFlushAllRemovesBalancingDirectories()
  13 + {
  14 + $cache = $this->_getCacheDriver();
  15 +
  16 + $this->assertTrue($cache->save('key1', 1));
  17 + $this->assertTrue($cache->save('key2', 2));
  18 + $this->assertTrue($cache->flushAll());
  19 +
  20 + $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST);
  21 +
  22 + $this->assertCount(0, $iterator);
  23 + }
  24 +
  25 + protected function setUp()
  26 + {
  27 + do {
  28 + $this->directory = sys_get_temp_dir() . '/doctrine_cache_'. uniqid();
  29 + } while (file_exists($this->directory));
  30 + }
  31 +
  32 + protected function tearDown()
  33 + {
  34 + if ( ! is_dir($this->directory)) {
  35 + return;
  36 + }
  37 +
  38 + $iterator = new RecursiveDirectoryIterator($this->directory);
  39 +
  40 + foreach (new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST) as $file) {
  41 + if ($file->isFile()) {
  42 + @unlink($file->getRealPath());
  43 + } elseif ($file->isDir()) {
  44 + @rmdir($file->getRealPath());
  45 + }
  46 + }
  47 +
  48 + @rmdir($this->directory);
  49 + }
  50 +
  51 + protected function isSharedStorage()
  52 + {
  53 + return false;
  54 + }
  55 +}
  1 +<?php
  2 +
  3 +namespace Doctrine\Tests\Common\Cache;
  4 +
  5 +class CacheProviderTest extends \Doctrine\Tests\DoctrineTestCase
  6 +{
  7 + public function testFetchMultiWillFilterNonRequestedKeys()
  8 + {
  9 + /* @var $cache \Doctrine\Common\Cache\CacheProvider|\PHPUnit_Framework_MockObject_MockObject */
  10 + $cache = $this->getMockForAbstractClass(
  11 + 'Doctrine\Common\Cache\CacheProvider',
  12 + array(),
  13 + '',
  14 + true,
  15 + true,
  16 + true,
  17 + array('doFetchMultiple')
  18 + );
  19 +
  20 + $cache
  21 + ->expects($this->once())
  22 + ->method('doFetchMultiple')
  23 + ->will($this->returnValue(array(
  24 + '[foo][1]' => 'bar',
  25 + '[bar][1]' => 'baz',
  26 + '[baz][1]' => 'tab',
  27 + )));
  28 +
  29 + $this->assertEquals(
  30 + array('foo' => 'bar', 'bar' => 'baz'),
  31 + $cache->fetchMultiple(array('foo', 'bar'))
  32 + );
  33 + }
  34 +
  35 + public function testFailedDeleteAllDoesNotChangeNamespaceVersion()
  36 + {
  37 + /* @var $cache \Doctrine\Common\Cache\CacheProvider|\PHPUnit_Framework_MockObject_MockObject */
  38 + $cache = $this->getMockForAbstractClass(
  39 + 'Doctrine\Common\Cache\CacheProvider',
  40 + array(),
  41 + '',
  42 + true,
  43 + true,
  44 + true,
  45 + array('doFetch', 'doSave', 'doContains')
  46 + );
  47 +
  48 + $cache
  49 + ->expects($this->once())
  50 + ->method('doFetch')
  51 + ->with('DoctrineNamespaceCacheKey[]')
  52 + ->will($this->returnValue(false));
  53 +
  54 + // doSave is only called once from deleteAll as we do not need to persist the default version in getNamespaceVersion()
  55 + $cache
  56 + ->expects($this->once())
  57 + ->method('doSave')
  58 + ->with('DoctrineNamespaceCacheKey[]')
  59 + ->will($this->returnValue(false));
  60 +
  61 + // After a failed deleteAll() the local namespace version is not increased (still 1). Otherwise all data written afterwards
  62 + // would be lost outside the current instance.
  63 + $cache
  64 + ->expects($this->once())
  65 + ->method('doContains')
  66 + ->with('[key][1]')
  67 + ->will($this->returnValue(true));
  68 +
  69 + $this->assertFalse($cache->deleteAll(), 'deleteAll() returns false when saving the namespace version fails');
  70 + $cache->contains('key');
  71 + }
  72 +}
  1 +<?php
  2 +
  3 +namespace Doctrine\Tests\Common\Cache;
  4 +
  5 +use Doctrine\Common\Cache\Cache;
  6 +use ArrayObject;
  7 +
  8 +abstract class CacheTest extends \Doctrine\Tests\DoctrineTestCase
  9 +{
  10 + /**
  11 + * @dataProvider provideDataToCache
  12 + */
  13 + public function testSetContainsFetchDelete($value)
  14 + {
  15 + $cache = $this->_getCacheDriver();
  16 +
  17 + // Test saving a value, checking if it exists, and fetching it back
  18 + $this->assertTrue($cache->save('key', $value));
  19 + $this->assertTrue($cache->contains('key'));
  20 + if (is_object($value)) {
  21 + $this->assertEquals($value, $cache->fetch('key'), 'Objects retrieved from the cache must be equal but not necessarily the same reference');
  22 + } else {
  23 + $this->assertSame($value, $cache->fetch('key'), 'Scalar and array data retrieved from the cache must be the same as the original, e.g. same type');
  24 + }
  25 +
  26 + // Test deleting a value
  27 + $this->assertTrue($cache->delete('key'));
  28 + $this->assertFalse($cache->contains('key'));
  29 + $this->assertFalse($cache->fetch('key'));
  30 + }
  31 +
  32 + /**
  33 + * @dataProvider provideDataToCache
  34 + */
  35 + public function testUpdateExistingEntry($value)
  36 + {
  37 + $cache = $this->_getCacheDriver();
  38 +
  39 + $this->assertTrue($cache->save('key', 'old-value'));
  40 + $this->assertTrue($cache->contains('key'));
  41 +
  42 + $this->assertTrue($cache->save('key', $value));
  43 + $this->assertTrue($cache->contains('key'));
  44 + if (is_object($value)) {
  45 + $this->assertEquals($value, $cache->fetch('key'), 'Objects retrieved from the cache must be equal but not necessarily the same reference');
  46 + } else {
  47 + $this->assertSame($value, $cache->fetch('key'), 'Scalar and array data retrieved from the cache must be the same as the original, e.g. same type');
  48 + }
  49 + }
  50 +
  51 + public function testFetchMulti()
  52 + {
  53 + $cache = $this->_getCacheDriver();
  54 +
  55 + $cache->deleteAll();
  56 +
  57 + // Test saving some values, checking if it exists, and fetching it back with multiGet
  58 + $this->assertTrue($cache->save('key1', 'value1'));
  59 + $this->assertTrue($cache->save('key2', 'value2'));
  60 +
  61 + $this->assertEquals(
  62 + array('key1' => 'value1', 'key2' => 'value2'),
  63 + $cache->fetchMultiple(array('key1', 'key2'))
  64 + );
  65 + $this->assertEquals(
  66 + array('key1' => 'value1', 'key2' => 'value2'),
  67 + $cache->fetchMultiple(array('key1', 'key3', 'key2'))
  68 + );
  69 + $this->assertEquals(
  70 + array('key1' => 'value1', 'key2' => 'value2'),
  71 + $cache->fetchMultiple(array('key1', 'key2', 'key3'))
  72 + );
  73 + }
  74 +
  75 + public function testFetchMultiWithEmptyKeysArray()
  76 + {
  77 + $cache = $this->_getCacheDriver();
  78 +
  79 + $this->assertEmpty(
  80 + $cache->fetchMultiple(array())
  81 + );
  82 + }
  83 +
  84 + public function testFetchMultiWithFalsey()
  85 + {
  86 + $cache = $this->_getCacheDriver();
  87 +
  88 + $cache->deleteAll();
  89 +
  90 + $values = array(
  91 + 'string' => 'str',
  92 + 'integer' => 1,
  93 + 'boolean' => true,
  94 + 'null' => null,
  95 + 'array_empty' => array(),
  96 + 'integer_zero' => 0,
  97 + 'string_empty' => ''
  98 + );
  99 + foreach ($values AS $key => $value) {
  100 + $cache->save($key, $value);
  101 + }
  102 +
  103 + $this->assertEquals(
  104 + $values,
  105 + $cache->fetchMultiple(array_keys($values))
  106 + );
  107 + }
  108 +
  109 + public function provideDataToCache()
  110 + {
  111 + return array(
  112 + 'array' => array(array('one', 2, 3.01)),
  113 + 'string' => array('value'),
  114 + 'integer' => array(1),
  115 + 'float' => array(1.5),
  116 + 'object' => array(new ArrayObject()),
  117 + 'true' => array(true),
  118 + // the following are considered FALSE in boolean context, but caches should still recognize their existence
  119 + 'null' => array(null),
  120 + 'false' => array(false),
  121 + 'array_empty' => array(array()),
  122 + 'string_zero' => array('0'),
  123 + 'integer_zero' => array(0),
  124 + 'float_zero' => array(0.0),
  125 + 'string_empty' => array('')
  126 + );
  127 + }
  128 +
  129 + public function testDeleteIsSuccessfulWhenKeyDoesNotExist()
  130 + {
  131 + $cache = $this->_getCacheDriver();
  132 +
  133 + $this->assertFalse($cache->contains('key'));
  134 + $this->assertTrue($cache->delete('key'));
  135 + }
  136 +
  137 + public function testDeleteAll()
  138 + {
  139 + $cache = $this->_getCacheDriver();
  140 +
  141 + $this->assertTrue($cache->save('key1', 1));
  142 + $this->assertTrue($cache->save('key2', 2));
  143 + $this->assertTrue($cache->deleteAll());
  144 + $this->assertFalse($cache->contains('key1'));
  145 + $this->assertFalse($cache->contains('key2'));
  146 + }
  147 +
  148 + public function testDeleteAllAndNamespaceVersioningBetweenCaches()
  149 + {
  150 + if ( ! $this->isSharedStorage()) {
  151 + $this->markTestSkipped('The ' . __CLASS__ .' does not use shared storage');
  152 + }
  153 +
  154 + $cache1 = $this->_getCacheDriver();
  155 + $cache2 = $this->_getCacheDriver();
  156 +
  157 + $this->assertTrue($cache1->save('key1', 1));
  158 + $this->assertTrue($cache2->save('key2', 2));
  159 +
  160 + /* Both providers are initialized with the same namespace version, so
  161 + * they can see entries set by each other.
  162 + */
  163 + $this->assertTrue($cache1->contains('key1'));
  164 + $this->assertTrue($cache1->contains('key2'));
  165 + $this->assertTrue($cache2->contains('key1'));
  166 + $this->assertTrue($cache2->contains('key2'));
  167 +
  168 + /* Deleting all entries through one provider will only increment the
  169 + * namespace version on that object (and in the cache itself, which new
  170 + * instances will use to initialize). The second provider will retain
  171 + * its original version and still see stale data.
  172 + */
  173 + $this->assertTrue($cache1->deleteAll());
  174 + $this->assertFalse($cache1->contains('key1'));
  175 + $this->assertFalse($cache1->contains('key2'));
  176 + $this->assertTrue($cache2->contains('key1'));
  177 + $this->assertTrue($cache2->contains('key2'));
  178 +
  179 + /* A new cache provider should not see the deleted entries, since its
  180 + * namespace version will be initialized.
  181 + */
  182 + $cache3 = $this->_getCacheDriver();
  183 + $this->assertFalse($cache3->contains('key1'));
  184 + $this->assertFalse($cache3->contains('key2'));
  185 + }
  186 +
  187 + public function testFlushAll()
  188 + {
  189 + $cache = $this->_getCacheDriver();
  190 +
  191 + $this->assertTrue($cache->save('key1', 1));
  192 + $this->assertTrue($cache->save('key2', 2));
  193 + $this->assertTrue($cache->flushAll());
  194 + $this->assertFalse($cache->contains('key1'));
  195 + $this->assertFalse($cache->contains('key2'));
  196 + }
  197 +
  198 + public function testFlushAllAndNamespaceVersioningBetweenCaches()
  199 + {
  200 + if ( ! $this->isSharedStorage()) {
  201 + $this->markTestSkipped('The ' . __CLASS__ .' does not use shared storage');
  202 + }
  203 +
  204 + $cache1 = $this->_getCacheDriver();
  205 + $cache2 = $this->_getCacheDriver();
  206 +
  207 + /* Deleting all elements from the first provider should increment its
  208 + * namespace version before saving the first entry.
  209 + */
  210 + $cache1->deleteAll();
  211 + $this->assertTrue($cache1->save('key1', 1));
  212 +
  213 + /* The second provider will be initialized with the same namespace
  214 + * version upon its first save operation.
  215 + */
  216 + $this->assertTrue($cache2->save('key2', 2));
  217 +
  218 + /* Both providers have the same namespace version and can see entries
  219 + * set by each other.
  220 + */
  221 + $this->assertTrue($cache1->contains('key1'));
  222 + $this->assertTrue($cache1->contains('key2'));
  223 + $this->assertTrue($cache2->contains('key1'));
  224 + $this->assertTrue($cache2->contains('key2'));
  225 +
  226 + /* Flushing all entries through one cache will remove all entries from
  227 + * the cache but leave their namespace version as-is.
  228 + */
  229 + $this->assertTrue($cache1->flushAll());
  230 + $this->assertFalse($cache1->contains('key1'));
  231 + $this->assertFalse($cache1->contains('key2'));
  232 + $this->assertFalse($cache2->contains('key1'));
  233 + $this->assertFalse($cache2->contains('key2'));
  234 +
  235 + /* Inserting a new entry will use the same, incremented namespace
  236 + * version, and it will be visible to both providers.
  237 + */
  238 + $this->assertTrue($cache1->save('key1', 1));
  239 + $this->assertTrue($cache1->contains('key1'));
  240 + $this->assertTrue($cache2->contains('key1'));
  241 +
  242 + /* A new cache provider will be initialized with the original namespace
  243 + * version and not share any visibility with the first two providers.
  244 + */
  245 + $cache3 = $this->_getCacheDriver();
  246 + $this->assertFalse($cache3->contains('key1'));
  247 + $this->assertFalse($cache3->contains('key2'));
  248 + $this->assertTrue($cache3->save('key3', 3));
  249 + $this->assertTrue($cache3->contains('key3'));
  250 + }
  251 +
  252 + public function testNamespace()
  253 + {
  254 + $cache = $this->_getCacheDriver();
  255 +
  256 + $cache->setNamespace('ns1_');
  257 +
  258 + $this->assertTrue($cache->save('key1', 1));
  259 + $this->assertTrue($cache->contains('key1'));
  260 +
  261 + $cache->setNamespace('ns2_');
  262 +
  263 + $this->assertFalse($cache->contains('key1'));
  264 + }
  265 +
  266 + public function testDeleteAllNamespace()
  267 + {
  268 + $cache = $this->_getCacheDriver();
  269 +
  270 + $cache->setNamespace('ns1');
  271 + $this->assertFalse($cache->contains('key1'));
  272 + $cache->save('key1', 'test');
  273 + $this->assertTrue($cache->contains('key1'));
  274 +
  275 + $cache->setNamespace('ns2');
  276 + $this->assertFalse($cache->contains('key1'));
  277 + $cache->save('key1', 'test');
  278 + $this->assertTrue($cache->contains('key1'));
  279 +
  280 + $cache->setNamespace('ns1');
  281 + $this->assertTrue($cache->contains('key1'));
  282 + $cache->deleteAll();
  283 + $this->assertFalse($cache->contains('key1'));
  284 +
  285 + $cache->setNamespace('ns2');
  286 + $this->assertTrue($cache->contains('key1'));
  287 + $cache->deleteAll();
  288 + $this->assertFalse($cache->contains('key1'));
  289 + }
  290 +
  291 + /**
  292 + * @group DCOM-43
  293 + */
  294 + public function testGetStats()
  295 + {
  296 + $cache = $this->_getCacheDriver();
  297 + $stats = $cache->getStats();
  298 +
  299 + $this->assertArrayHasKey(Cache::STATS_HITS, $stats);
  300 + $this->assertArrayHasKey(Cache::STATS_MISSES, $stats);
  301 + $this->assertArrayHasKey(Cache::STATS_UPTIME, $stats);
  302 + $this->assertArrayHasKey(Cache::STATS_MEMORY_USAGE, $stats);
  303 + $this->assertArrayHasKey(Cache::STATS_MEMORY_AVAILABLE, $stats);
  304 + }
  305 +
  306 + public function testFetchMissShouldReturnFalse()
  307 + {
  308 + $cache = $this->_getCacheDriver();
  309 +
  310 + /* Ensure that caches return boolean false instead of null on a fetch
  311 + * miss to be compatible with ORM integration.
  312 + */
  313 + $result = $cache->fetch('nonexistent_key');
  314 +
  315 + $this->assertFalse($result);
  316 + $this->assertNotNull($result);
  317 + }
  318 +
  319 + /**
  320 + * Check to see that objects are correctly serialized and unserialized by the cache
  321 + * provider.
  322 + */
  323 + public function testCachedObject()
  324 + {
  325 + $cache = $this->_getCacheDriver();
  326 + $cache->deleteAll();
  327 + $obj = new \stdClass();
  328 + $obj->foo = "bar";
  329 + $obj2 = new \stdClass();
  330 + $obj2->bar = "foo";
  331 + $obj2->obj = $obj;
  332 + $obj->obj2 = $obj2;
  333 + $cache->save("obj", $obj);
  334 +
  335 + $fetched = $cache->fetch("obj");
  336 +
  337 + $this->assertInstanceOf("stdClass", $obj);
  338 + $this->assertInstanceOf("stdClass", $obj->obj2);
  339 + $this->assertInstanceOf("stdClass", $obj->obj2->obj);
  340 + $this->assertEquals("bar", $fetched->foo);
  341 + $this->assertEquals("foo", $fetched->obj2->bar);
  342 + }
  343 +
  344 + /**
  345 + * Check to see that objects fetched via fetchMultiple are properly unserialized
  346 + */
  347 + public function testFetchMultipleObjects()
  348 + {
  349 + $cache = $this->_getCacheDriver();
  350 + $cache->deleteAll();
  351 + $obj1 = new \stdClass();
  352 + $obj1->foo = "bar";
  353 + $cache->save("obj1", $obj1);
  354 + $obj2 = new \stdClass();
  355 + $obj2->bar = "baz";
  356 + $cache->save("obj2", $obj2);
  357 +
  358 + $fetched = $cache->fetchMultiple(array("obj1", "obj2"));
  359 + $this->assertInstanceOf("stdClass", $fetched["obj1"]);
  360 + $this->assertInstanceOf("stdClass", $fetched["obj2"]);
  361 + $this->assertEquals("bar", $fetched["obj1"]->foo);
  362 + $this->assertEquals("baz", $fetched["obj2"]->bar);
  363 + }
  364 +
  365 + /**
  366 + * Return whether multiple cache providers share the same storage.
  367 + *
  368 + * This is used for skipping certain tests for shared storage behavior.
  369 + *
  370 + * @return boolean
  371 + */
  372 + protected function isSharedStorage()
  373 + {
  374 + return true;
  375 + }
  376 +
  377 + /**
  378 + * @return \Doctrine\Common\Cache\CacheProvider
  379 + */
  380 + abstract protected function _getCacheDriver();
  381 +}
  1 +<?php
  2 +
  3 +namespace Doctrine\Tests\Common\Cache;
  4 +
  5 +use Doctrine\Common\Cache\ApcCache;
  6 +use Doctrine\Common\Cache\ArrayCache;
  7 +use Doctrine\Common\Cache\ChainCache;
  8 +
  9 +class ChainCacheTest extends CacheTest
  10 +{
  11 + protected function _getCacheDriver()
  12 + {
  13 + return new ChainCache(array(new ArrayCache()));
  14 + }
  15 +
  16 + public function testGetStats()
  17 + {
  18 + $cache = $this->_getCacheDriver();
  19 + $stats = $cache->getStats();
  20 +
  21 + $this->assertInternalType('array', $stats);
  22 + }
  23 +
  24 + public function testOnlyFetchFirstOne()
  25 + {
  26 + $cache1 = new ArrayCache();
  27 + $cache2 = $this->getMockForAbstractClass('Doctrine\Common\Cache\CacheProvider');
  28 +
  29 + $cache2->expects($this->never())->method('doFetch');
  30 +
  31 + $chainCache = new ChainCache(array($cache1, $cache2));
  32 + $chainCache->save('id', 'bar');
  33 +
  34 + $this->assertEquals('bar', $chainCache->fetch('id'));
  35 + }
  36 +
  37 + public function testFetchPropagateToFastestCache()
  38 + {
  39 + $cache1 = new ArrayCache();
  40 + $cache2 = new ArrayCache();
  41 +
  42 + $cache2->save('bar', 'value');
  43 +
  44 + $chainCache = new ChainCache(array($cache1, $cache2));
  45 +
  46 + $this->assertFalse($cache1->contains('bar'));
  47 +
  48 + $result = $chainCache->fetch('bar');
  49 +
  50 + $this->assertEquals('value', $result);
  51 + $this->assertTrue($cache2->contains('bar'));
  52 + }
  53 +
  54 + public function testNamespaceIsPropagatedToAllProviders()
  55 + {
  56 + $cache1 = new ArrayCache();
  57 + $cache2 = new ArrayCache();
  58 +
  59 + $chainCache = new ChainCache(array($cache1, $cache2));
  60 + $chainCache->setNamespace('bar');
  61 +
  62 + $this->assertEquals('bar', $cache1->getNamespace());
  63 + $this->assertEquals('bar', $cache2->getNamespace());
  64 + }
  65 +
  66 + public function testDeleteToAllProviders()
  67 + {
  68 + $cache1 = $this->getMockForAbstractClass('Doctrine\Common\Cache\CacheProvider');
  69 + $cache2 = $this->getMockForAbstractClass('Doctrine\Common\Cache\CacheProvider');
  70 +
  71 + $cache1->expects($this->once())->method('doDelete');
  72 + $cache2->expects($this->once())->method('doDelete');
  73 +
  74 + $chainCache = new ChainCache(array($cache1, $cache2));
  75 + $chainCache->delete('bar');
  76 + }
  77 +
  78 + public function testFlushToAllProviders()
  79 + {
  80 + $cache1 = $this->getMockForAbstractClass('Doctrine\Common\Cache\CacheProvider');
  81 + $cache2 = $this->getMockForAbstractClass('Doctrine\Common\Cache\CacheProvider');
  82 +
  83 + $cache1->expects($this->once())->method('doFlush');
  84 + $cache2->expects($this->once())->method('doFlush');
  85 +
  86 + $chainCache = new ChainCache(array($cache1, $cache2));
  87 + $chainCache->flushAll();
  88 + }
  89 +
  90 + protected function isSharedStorage()
  91 + {
  92 + return false;
  93 + }
  94 +}
  1 +<?php
  2 +
  3 +namespace Doctrine\Tests\Common\Cache;
  4 +
  5 +use Couchbase;
  6 +use Doctrine\Common\Cache\CouchbaseCache;
  7 +
  8 +class CouchbaseCacheTest extends CacheTest
  9 +{
  10 + private $couchbase;
  11 +
  12 + public function setUp()
  13 + {
  14 + if (extension_loaded('couchbase')) {
  15 + try {
  16 + $this->couchbase = new Couchbase('127.0.0.1', 'Administrator', 'password', 'default');
  17 + } catch(Exception $ex) {
  18 + $this->markTestSkipped('Could not instantiate the Couchbase cache because of: ' . $ex);
  19 + }
  20 + } else {
  21 + $this->markTestSkipped('The ' . __CLASS__ .' requires the use of the couchbase extension');
  22 + }
  23 + }
  24 +
  25 + public function testNoExpire()
  26 + {
  27 + $cache = $this->_getCacheDriver();
  28 + $cache->save('noexpire', 'value', 0);
  29 + sleep(1);
  30 + $this->assertTrue($cache->contains('noexpire'), 'Couchbase provider should support no-expire');
  31 + }
  32 +
  33 + public function testLongLifetime()
  34 + {
  35 + $cache = $this->_getCacheDriver();
  36 + $cache->save('key', 'value', 30 * 24 * 3600 + 1);
  37 +
  38 + $this->assertTrue($cache->contains('key'), 'Couchbase provider should support TTL > 30 days');
  39 + }
  40 +
  41 + protected function _getCacheDriver()
  42 + {
  43 + $driver = new CouchbaseCache();
  44 + $driver->setCouchbase($this->couchbase);
  45 + return $driver;
  46 + }
  47 +}
  1 +<?php
  2 +
  3 +namespace Doctrine\Tests\Common\Cache;
  4 +
  5 +use Doctrine\Common\Cache\Cache;
  6 +
  7 +/**
  8 + * @group DCOM-101
  9 + */
  10 +class FileCacheTest extends \Doctrine\Tests\DoctrineTestCase
  11 +{
  12 + /**
  13 + * @var \Doctrine\Common\Cache\FileCache
  14 + */
  15 + private $driver;
  16 +
  17 + protected function setUp()
  18 + {
  19 + $this->driver = $this->getMock(
  20 + 'Doctrine\Common\Cache\FileCache',
  21 + array('doFetch', 'doContains', 'doSave'),
  22 + array(), '', false
  23 + );
  24 + }
  25 +
  26 + public function getProviderFileName()
  27 + {
  28 + return array(
  29 + //The characters :\/<>"*?| are not valid in Windows filenames.
  30 + array('key:1', 'key-1'),
  31 + array('key\2', 'key-2'),
  32 + array('key/3', 'key-3'),
  33 + array('key<4', 'key-4'),
  34 + array('key>5', 'key-5'),
  35 + array('key"6', 'key-6'),
  36 + array('key*7', 'key-7'),
  37 + array('key?8', 'key-8'),
  38 + array('key|9', 'key-9'),
  39 + array('key[10]', 'key[10]'),
  40 + array('keyä11', 'key--11'),
  41 + array('../key12', '---key12'),
  42 + array('key-13', 'key__13'),
  43 + );
  44 + }
  45 +
  46 + /**
  47 + * @dataProvider getProviderFileName
  48 + */
  49 + public function testInvalidFilename($key, $expected)
  50 + {
  51 + $cache = $this->driver;
  52 + $method = new \ReflectionMethod($cache, 'getFilename');
  53 +
  54 + $method->setAccessible(true);
  55 +
  56 + $value = $method->invoke($cache, $key);
  57 + $actual = pathinfo($value, PATHINFO_FILENAME);
  58 +
  59 + $this->assertEquals($expected, $actual);
  60 + }
  61 +
  62 + public function testFilenameCollision()
  63 + {
  64 + $data = array(
  65 + 'key:0' => 'key-0',
  66 + 'key\0' => 'key-0',
  67 + 'key/0' => 'key-0',
  68 + 'key<0' => 'key-0',
  69 + 'key>0' => 'key-0',
  70 + 'key"0' => 'key-0',
  71 + 'key*0' => 'key-0',
  72 + 'key?0' => 'key-0',
  73 + 'key|0' => 'key-0',
  74 + 'key-0' => 'key__0',
  75 + 'keyä0' => 'key--0',
  76 + );
  77 +
  78 + $paths = array();
  79 + $cache = $this->driver;
  80 + $method = new \ReflectionMethod($cache, 'getFilename');
  81 +
  82 + $method->setAccessible(true);
  83 +
  84 + foreach ($data as $key => $expected) {
  85 + $path = $method->invoke($cache, $key);
  86 + $actual = pathinfo($path, PATHINFO_FILENAME);
  87 +
  88 + $this->assertNotContains($path, $paths);
  89 + $this->assertEquals($expected, $actual);
  90 +
  91 + $paths[] = $path;
  92 + }
  93 + }
  94 +
  95 + public function testFilenameShouldCreateThePathWithFourSubDirectories()
  96 + {
  97 + $cache = $this->driver;
  98 + $method = new \ReflectionMethod($cache, 'getFilename');
  99 + $key = 'item-key';
  100 + $expectedDir = array(
  101 + '84', 'e0', 'e2', 'e8', '93', 'fe', 'bb', '73', '7a', '0f', 'ee',
  102 + '0c', '89', 'd5', '3f', '4b', 'b7', 'fc', 'b4', '4c', '57', 'cd',
  103 + 'f3', 'd3', '2c', 'e7', '36', '3f', '5d', '59', '77', '60'
  104 + );
  105 + $expectedDir = implode(DIRECTORY_SEPARATOR, $expectedDir);
  106 +
  107 + $method->setAccessible(true);
  108 +
  109 + $path = $method->invoke($cache, $key);
  110 + $filename = pathinfo($path, PATHINFO_FILENAME);
  111 + $dirname = pathinfo($path, PATHINFO_DIRNAME);
  112 +
  113 + $this->assertEquals('item__key', $filename);
  114 + $this->assertEquals(DIRECTORY_SEPARATOR . $expectedDir, $dirname);
  115 + $this->assertEquals(DIRECTORY_SEPARATOR . $expectedDir . DIRECTORY_SEPARATOR . 'item__key', $path);
  116 + }
  117 +
  118 + public function testFileExtensionCorrectlyEscaped()
  119 + {
  120 + $driver1 = $this->getMock(
  121 + 'Doctrine\Common\Cache\FileCache',
  122 + array('doFetch', 'doContains', 'doSave'),
  123 + array(__DIR__, '.*')
  124 + );
  125 + $driver2 = $this->getMock(
  126 + 'Doctrine\Common\Cache\FileCache',
  127 + array('doFetch', 'doContains', 'doSave'),
  128 + array(__DIR__, '.php')
  129 + );
  130 +
  131 + $doGetStats = new \ReflectionMethod($driver1, 'doGetStats');
  132 +
  133 + $doGetStats->setAccessible(true);
  134 +
  135 + $stats1 = $doGetStats->invoke($driver1);
  136 + $stats2 = $doGetStats->invoke($driver2);
  137 +
  138 + $this->assertSame(0, $stats1[Cache::STATS_MEMORY_USAGE]);
  139 + $this->assertGreaterThan(0, $stats2[Cache::STATS_MEMORY_USAGE]);
  140 + }
  141 +
  142 + /**
  143 + * @group DCOM-266
  144 + */
  145 + public function testFileExtensionSlashCorrectlyEscaped()
  146 + {
  147 + $driver = $this->getMock(
  148 + 'Doctrine\Common\Cache\FileCache',
  149 + array('doFetch', 'doContains', 'doSave'),
  150 + array(__DIR__ . '/../', DIRECTORY_SEPARATOR . basename(__FILE__))
  151 + );
  152 +
  153 + $doGetStats = new \ReflectionMethod($driver, 'doGetStats');
  154 +
  155 + $doGetStats->setAccessible(true);
  156 +
  157 + $stats = $doGetStats->invoke($driver);
  158 +
  159 + $this->assertGreaterThan(0, $stats[Cache::STATS_MEMORY_USAGE]);
  160 + }
  161 +}
  1 +<?php
  2 +
  3 +namespace Doctrine\Tests\Common\Cache;
  4 +
  5 +use Doctrine\Common\Cache\Cache;
  6 +use Doctrine\Common\Cache\FilesystemCache;
  7 +
  8 +/**
  9 + * @group DCOM-101
  10 + */
  11 +class FilesystemCacheTest extends BaseFileCacheTest
  12 +{
  13 + public function testLifetime()
  14 + {
  15 + $cache = $this->_getCacheDriver();
  16 +
  17 + // Test save
  18 + $cache->save('test_key', 'testing this out', 10);
  19 +
  20 + // Test contains to test that save() worked
  21 + $this->assertTrue($cache->contains('test_key'));
  22 +
  23 + // Test fetch
  24 + $this->assertEquals('testing this out', $cache->fetch('test_key'));
  25 +
  26 + // access private methods
  27 + $getFilename = new \ReflectionMethod($cache, 'getFilename');
  28 + $getNamespacedId = new \ReflectionMethod($cache, 'getNamespacedId');
  29 +
  30 + $getFilename->setAccessible(true);
  31 + $getNamespacedId->setAccessible(true);
  32 +
  33 + $id = $getNamespacedId->invoke($cache, 'test_key');
  34 + $filename = $getFilename->invoke($cache, $id);
  35 +
  36 + $data = '';
  37 + $lifetime = 0;
  38 + $resource = fopen($filename, "r");
  39 +
  40 + if (false !== ($line = fgets($resource))) {
  41 + $lifetime = (integer) $line;
  42 + }
  43 +
  44 + while (false !== ($line = fgets($resource))) {
  45 + $data .= $line;
  46 + }
  47 +
  48 + $this->assertNotEquals(0, $lifetime, 'previous lifetime could not be loaded');
  49 +
  50 + // update lifetime
  51 + $lifetime = $lifetime - 20;
  52 + file_put_contents($filename, $lifetime . PHP_EOL . $data);
  53 +
  54 + // test expired data
  55 + $this->assertFalse($cache->contains('test_key'));
  56 + $this->assertFalse($cache->fetch('test_key'));
  57 + }
  58 +
  59 + public function testGetStats()
  60 + {
  61 + $cache = $this->_getCacheDriver();
  62 + $stats = $cache->getStats();
  63 +
  64 + $this->assertNull($stats[Cache::STATS_HITS]);
  65 + $this->assertNull($stats[Cache::STATS_MISSES]);
  66 + $this->assertNull($stats[Cache::STATS_UPTIME]);
  67 + $this->assertEquals(0, $stats[Cache::STATS_MEMORY_USAGE]);
  68 + $this->assertGreaterThan(0, $stats[Cache::STATS_MEMORY_AVAILABLE]);
  69 + }
  70 +
  71 + public function testCacheInSharedDirectoryIsPerExtension()
  72 + {
  73 + $cache1 = new FilesystemCache($this->directory, '.foo');
  74 + $cache2 = new FilesystemCache($this->directory, '.bar');
  75 +
  76 + $this->assertTrue($cache1->save('key1', 11));
  77 + $this->assertTrue($cache1->save('key2', 12));
  78 +
  79 + $this->assertTrue($cache2->save('key1', 21));
  80 + $this->assertTrue($cache2->save('key2', 22));
  81 +
  82 + $this->assertSame(11, $cache1->fetch('key1'), 'Cache value must not be influenced by a different cache in the same directory but different extension');
  83 + $this->assertSame(12, $cache1->fetch('key2'));
  84 + $this->assertTrue($cache1->flushAll());
  85 + $this->assertFalse($cache1->fetch('key1'), 'flushAll() must delete all items with the current extension');
  86 + $this->assertFalse($cache1->fetch('key2'));
  87 +
  88 + $this->assertSame(21, $cache2->fetch('key1'), 'flushAll() must not remove items with a different extension in a shared directory');
  89 + $this->assertSame(22, $cache2->fetch('key2'));
  90 + }
  91 +
  92 + public function testFlushAllWithNoExtension()
  93 + {
  94 + $cache = new FilesystemCache($this->directory, '');
  95 +
  96 + $this->assertTrue($cache->save('key1', 1));
  97 + $this->assertTrue($cache->save('key2', 2));
  98 + $this->assertTrue($cache->flushAll());
  99 + $this->assertFalse($cache->contains('key1'));
  100 + $this->assertFalse($cache->contains('key2'));
  101 + }
  102 +
  103 + protected function _getCacheDriver()
  104 + {
  105 + return new FilesystemCache($this->directory);
  106 + }
  107 +}
  1 +<?php
  2 +
  3 +namespace Doctrine\Tests\Common\Cache;
  4 +
  5 +use Doctrine\Common\Cache\MemcacheCache;
  6 +use Memcache;
  7 +
  8 +class MemcacheCacheTest extends CacheTest
  9 +{
  10 + private $memcache;
  11 +
  12 + public function setUp()
  13 + {
  14 + if ( ! extension_loaded('memcache')) {
  15 + $this->markTestSkipped('The ' . __CLASS__ .' requires the use of memcache');
  16 + }
  17 +
  18 + $this->memcache = new Memcache();
  19 +
  20 + if (@$this->memcache->connect('localhost', 11211) === false) {
  21 + unset($this->memcache);
  22 + $this->markTestSkipped('The ' . __CLASS__ .' cannot connect to memcache');
  23 + }
  24 + }
  25 +
  26 + public function tearDown()
  27 + {
  28 + if ($this->memcache instanceof Memcache) {
  29 + $this->memcache->flush();
  30 + }
  31 + }
  32 +
  33 + public function testNoExpire()
  34 + {
  35 + $cache = $this->_getCacheDriver();
  36 + $cache->save('noexpire', 'value', 0);
  37 + sleep(1);
  38 + $this->assertTrue($cache->contains('noexpire'), 'Memcache provider should support no-expire');
  39 + }
  40 +
  41 + public function testLongLifetime()
  42 + {
  43 + $cache = $this->_getCacheDriver();
  44 + $cache->save('key', 'value', 30 * 24 * 3600 + 1);
  45 + $this->assertTrue($cache->contains('key'), 'Memcache provider should support TTL > 30 days');
  46 + }
  47 +
  48 + protected function _getCacheDriver()
  49 + {
  50 + $driver = new MemcacheCache();
  51 + $driver->setMemcache($this->memcache);
  52 + return $driver;
  53 + }
  54 +}