Skip to content

Commit 6b8e3bf

Browse files
committed
Cacheable annotation working and simple test for it made (need more complex tests to test all the stack)
1 parent 93db1d3 commit 6b8e3bf

File tree

14 files changed

+536
-61
lines changed

14 files changed

+536
-61
lines changed

composer.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@
4242
"eventName": "Cacheable",
4343
"class": "ArthurH\\SphringCache\\CacheAnnotation\\SphringCacheableAnnotation"
4444
}
45+
],
46+
"annotationMethodCallAfter": [
47+
{
48+
"eventName": "Cacheable",
49+
"class": "ArthurH\\SphringCache\\CacheAnnotation\\SphringCacheableAnnotation"
50+
}
4551
]
4652
},
4753
"isPlugin": true

src/ArthurH/SphringCache/CacheAnnotation/Cacheable.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,38 @@
1414

1515
/**
1616
* @Annotation
17+
* @Target({"METHOD"})
1718
* Class Cacheable
1819
* @package ArthurH\SphringCache\CacheAnnotation
1920
*/
2021
class Cacheable
2122
{
22-
23+
/**
24+
* @var string
25+
*/
26+
public $value;
27+
/**
28+
* @var string
29+
*/
30+
public $cacheManager;
31+
/**
32+
* @var string
33+
*/
34+
public $condition;
35+
/**
36+
* @var string
37+
*/
38+
public $key;
39+
/**
40+
* @var string
41+
*/
42+
public $keyGenerator;
43+
/**
44+
* @var int
45+
*/
46+
public $lifetime = 0;
47+
/**
48+
* @var string
49+
*/
50+
public $unless;
2351
}

src/ArthurH/SphringCache/CacheAnnotation/SphringCacheableAnnotation.php

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@
1313
namespace ArthurH\SphringCache\CacheAnnotation;
1414

1515

16+
use Arthurh\Sphring\Exception\SphringAnnotationException;
1617
use Arthurh\Sphring\Utils\ClassName;
18+
use ArthurH\SphringCache\CacheManager\AbstractCacheManager;
1719
use ArthurH\SphringCache\Exception\SphringCacheException;
20+
use ArthurH\SphringCache\KeyGenerator\DefaultKeyGenerator;
21+
use ArthurH\SphringCache\KeyGenerator\KeyGenerator;
1822

1923
class SphringCacheableAnnotation extends AbstractSphringCacheAnnotation
2024
{
@@ -32,5 +36,106 @@ public static function getAnnotationName()
3236
public function run()
3337
{
3438
parent::run();
39+
$cacheableAnnot = $this->getData();
40+
if (!($cacheableAnnot instanceof Cacheable)) {
41+
throw new SphringAnnotationException("Error in bean '%s' in class annotation: Annotation '%s' required to have a '%s' class.",
42+
$this->getBean()->getId(), get_class($this), Cacheable::class);
43+
}
44+
if ($cacheableAnnot->value === null) {
45+
throw new SphringAnnotationException("Error in bean '%s' in class annotation: Annotation '%s' required to have a value property in annotation.",
46+
$this->getBean()->getId(), get_class($this));
47+
}
48+
$keyGenerator = $this->getKeyGenerator($cacheableAnnot->keyGenerator);
49+
$cacheManager = $this->getCacheManagerFromAnnotation($cacheableAnnot->cacheManager);
50+
$condition = $cacheableAnnot->condition;
51+
if ($condition !== null && !$this->evaluateExpressionBoolean($condition)) {
52+
return;
53+
}
54+
$key = $this->generateKey($cacheableAnnot->value, $cacheableAnnot->key, $keyGenerator);
55+
if ($cacheManager->contains($key)) {
56+
$this->event->setData($cacheManager->fetch($key));
57+
}
58+
if (!$this->isAfterCall()) {
59+
return;
60+
}
61+
$unless = $cacheableAnnot->unless;
62+
if ($unless !== null && !$this->evaluateExpressionBoolean($unless)) {
63+
return;
64+
}
65+
$args = $this->getEvent()->getMethodArgs();
66+
$cacheManager->save($key, $args['#result'], $cacheableAnnot->lifetime);
67+
}
68+
69+
private function isAfterCall()
70+
{
71+
$args = $this->getEvent()->getMethodArgs();
72+
return isset($args['#result']);
73+
}
74+
75+
/**
76+
* @param $value
77+
* @param $key
78+
* @param KeyGenerator $keyGenerator
79+
* @return string
80+
*/
81+
private function generateKey($value, $key, KeyGenerator $keyGenerator)
82+
{
83+
$finalKey = $value;
84+
$args = $this->getEvent()->getMethodArgs();
85+
if ($args === null) {
86+
return $finalKey;
87+
}
88+
$finalArgs = $args;
89+
if (isset($finalArgs['#result'])) {
90+
unset($finalArgs['#result']);
91+
}
92+
if ($key === null) {
93+
return $finalKey . '/' . $keyGenerator->generate($finalArgs);
94+
}
95+
return $finalKey . '/' . $keyGenerator->generate($this->evaluateExpression($key));
96+
}
97+
98+
/**
99+
* @param KeyGenerator $keyGenerator
100+
* @return KeyGenerator
101+
* @throws SphringAnnotationException
102+
*/
103+
private function getKeyGenerator($keyGenerator)
104+
{
105+
if ($keyGenerator === null) {
106+
return new DefaultKeyGenerator();
107+
}
108+
if (!class_exists($keyGenerator)) {
109+
throw new SphringAnnotationException("Error in bean '%s' in class annotation: Annotation '%s' not a valid KeyGenerator for '%s'.",
110+
$this->getBean()->getId(), get_class($this), $keyGenerator);
111+
}
112+
$keyGenerator = new $keyGenerator();
113+
if (!($keyGenerator instanceof KeyGenerator)) {
114+
throw new SphringAnnotationException("Error in bean '%s' in class annotation: Annotation '%s' not a valid KeyGenerator for '%s' it must implements '%s'.",
115+
$this->getBean()->getId(), get_class($this), $keyGenerator, KeyGenerator::class);
116+
}
117+
return $keyGenerator;
118+
}
119+
120+
/**
121+
* @param $cacheManager
122+
* @return AbstractCacheManager
123+
* @throws SphringAnnotationException
124+
*/
125+
private function getCacheManagerFromAnnotation($cacheManager)
126+
{
127+
if ($cacheManager === null) {
128+
return $this->getCacheManager();
129+
}
130+
if (!class_exists($cacheManager)) {
131+
throw new SphringAnnotationException("Error in bean '%s' in class annotation: Annotation '%s' not a valid CacheManager for '%s'.",
132+
$this->getBean()->getId(), get_class($this), $cacheManager);
133+
}
134+
$cacheManager = new $cacheManager();
135+
if (!($cacheManager instanceof AbstractCacheManager)) {
136+
throw new SphringAnnotationException("Error in bean '%s' in class annotation: Annotation '%s' not a valid CacheManager for '%s' it must implements '%s'.",
137+
$this->getBean()->getId(), get_class($this), $cacheManager, AbstractCacheManager::class);
138+
}
139+
return $cacheManager;
35140
}
36141
}

src/ArthurH/SphringCache/CacheManager/AbstractCacheManager.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414

1515

1616
use Arthurh\Sphring\Sphring;
17+
use Doctrine\Common\Cache\Cache;
1718

18-
abstract class AbstractCacheManager
19+
abstract class AbstractCacheManager implements Cache
1920
{
2021
/**
2122
* @var Sphring
@@ -138,5 +139,4 @@ public function setCacheSphringAnnotation($cacheSphringAnnotation)
138139
{
139140
$this->cacheSphringAnnotation = $cacheSphringAnnotation;
140141
}
141-
142142
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<?php
2+
/**
3+
* Copyright (C) 2014 Arthur Halet
4+
*
5+
* This software is distributed under the terms and conditions of the 'MIT'
6+
* license which can be found in the file 'LICENSE' in this package distribution
7+
* or at 'http://opensource.org/licenses/MIT'.
8+
*
9+
* Author: Arthur Halet
10+
* Date: 12/04/2015
11+
*/
12+
13+
namespace ArthurH\SphringCache\CacheManager;
14+
15+
16+
use Arthurh\Sphring\Annotations\AnnotationsSphring\Required;
17+
use Doctrine\Common\Cache\Cache;
18+
19+
class DoctrineCacheManager extends AbstractCacheManager
20+
{
21+
22+
/**
23+
* @var Cache
24+
*/
25+
private $doctrineCache;
26+
27+
/**
28+
* Fetches an entry from the cache.
29+
*
30+
* @param string $id The id of the cache entry to fetch.
31+
*
32+
* @return mixed The cached data or FALSE, if no cache entry exists for the given id.
33+
*/
34+
public function fetch($id)
35+
{
36+
return $this->doctrineCache->fetch($id);
37+
}
38+
39+
/**
40+
* Tests if an entry exists in the cache.
41+
*
42+
* @param string $id The cache id of the entry to check for.
43+
*
44+
* @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise.
45+
*/
46+
public function contains($id)
47+
{
48+
return $this->doctrineCache->contains($id);
49+
}
50+
51+
/**
52+
* Puts data into the cache.
53+
*
54+
* @param string $id The cache id.
55+
* @param mixed $data The cache entry/data.
56+
* @param int $lifeTime The cache lifetime.
57+
* If != 0, sets a specific lifetime for this cache entry (0 => infinite lifeTime).
58+
*
59+
* @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise.
60+
*/
61+
public function save($id, $data, $lifeTime = 0)
62+
{
63+
return $this->doctrineCache->save($id, $data, $lifeTime);
64+
}
65+
66+
/**
67+
* Deletes a cache entry.
68+
*
69+
* @param string $id The cache id.
70+
*
71+
* @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise.
72+
*/
73+
public function delete($id)
74+
{
75+
return $this->doctrineCache->delete($id);
76+
}
77+
78+
/**
79+
* Retrieves cached information from the data store.
80+
*
81+
* The server's statistics array has the following values:
82+
*
83+
* - <b>hits</b>
84+
* Number of keys that have been requested and found present.
85+
*
86+
* - <b>misses</b>
87+
* Number of items that have been requested and not found.
88+
*
89+
* - <b>uptime</b>
90+
* Time that the server is running.
91+
*
92+
* - <b>memory_usage</b>
93+
* Memory used by this server to store items.
94+
*
95+
* - <b>memory_available</b>
96+
* Memory allowed to use for storage.
97+
*
98+
* @since 2.2
99+
*
100+
* @return array|null An associative array with server's statistics if available, NULL otherwise.
101+
*/
102+
public function getStats()
103+
{
104+
return $this->doctrineCache->getStats();
105+
}
106+
107+
/**
108+
* @return Cache
109+
*/
110+
public function getDoctrineCache()
111+
{
112+
return $this->doctrineCache;
113+
}
114+
115+
/**
116+
* @param Cache $doctrineCache
117+
* @Required()
118+
*/
119+
public function setDoctrineCache($doctrineCache)
120+
{
121+
$this->doctrineCache = $doctrineCache;
122+
}
123+
124+
}

src/ArthurH/SphringCache/CacheManager/NullCacheManager.php

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,83 @@
1616
class NullCacheManager extends AbstractCacheManager
1717
{
1818

19+
/**
20+
* Fetches an entry from the cache.
21+
*
22+
* @param string $id The id of the cache entry to fetch.
23+
*
24+
* @return mixed The cached data or FALSE, if no cache entry exists for the given id.
25+
*/
26+
public function fetch($id)
27+
{
28+
return false;
29+
}
30+
31+
/**
32+
* Tests if an entry exists in the cache.
33+
*
34+
* @param string $id The cache id of the entry to check for.
35+
*
36+
* @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise.
37+
*/
38+
public function contains($id)
39+
{
40+
return false;
41+
}
42+
43+
/**
44+
* Puts data into the cache.
45+
*
46+
* @param string $id The cache id.
47+
* @param mixed $data The cache entry/data.
48+
* @param int $lifeTime The cache lifetime.
49+
* If != 0, sets a specific lifetime for this cache entry (0 => infinite lifeTime).
50+
*
51+
* @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise.
52+
*/
53+
public function save($id, $data, $lifeTime = 0)
54+
{
55+
return true;
56+
}
57+
58+
/**
59+
* Deletes a cache entry.
60+
*
61+
* @param string $id The cache id.
62+
*
63+
* @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise.
64+
*/
65+
public function delete($id)
66+
{
67+
return true;
68+
}
69+
70+
/**
71+
* Retrieves cached information from the data store.
72+
*
73+
* The server's statistics array has the following values:
74+
*
75+
* - <b>hits</b>
76+
* Number of keys that have been requested and found present.
77+
*
78+
* - <b>misses</b>
79+
* Number of items that have been requested and not found.
80+
*
81+
* - <b>uptime</b>
82+
* Time that the server is running.
83+
*
84+
* - <b>memory_usage</b>
85+
* Memory used by this server to store items.
86+
*
87+
* - <b>memory_available</b>
88+
* Memory allowed to use for storage.
89+
*
90+
* @since 2.2
91+
*
92+
* @return array|null An associative array with server's statistics if available, NULL otherwise.
93+
*/
94+
public function getStats()
95+
{
96+
return null;
97+
}
1998
}

0 commit comments

Comments
 (0)