Skip to content

Commit e0c8c61

Browse files
committed
Splitted some code to increase quality and readability.
1 parent 56991e0 commit e0c8c61

File tree

4 files changed

+161
-107
lines changed

4 files changed

+161
-107
lines changed

lib/Phpfastcache/Cluster/Drivers/FullReplication/Driver.php

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ public function getItem(string $key): ExtendedCacheItemInterface
4545
$itemData = $item->get();
4646
$poolItemData = $poolItem->get();
4747

48-
if (
49-
\is_object($itemData)
50-
) {
48+
if (\is_object($itemData)) {
5149
if ($item->get() != $poolItemData) {
5250
$poolsToResync[] = $driverPool;
5351
}
@@ -61,18 +59,7 @@ public function getItem(string $key): ExtendedCacheItemInterface
6159
}
6260
}
6361

64-
if ($item && $item->isHit() && \count($poolsToResync) < \count($this->clusterPools)) {
65-
foreach ($poolsToResync as $poolToResync) {
66-
$poolItem = $poolToResync->getItem($key);
67-
$poolItem->setEventManager($this->getEventManager())
68-
->set($item->get())
69-
->setHit($item->isHit())
70-
->setTags($item->getTags())
71-
->expiresAt($item->getExpirationDate())
72-
->setDriver($poolToResync);
73-
$poolToResync->save($poolItem);
74-
}
75-
}
62+
$this->resynchronizePool($poolsToResync, $key, $item);
7663

7764
if ($item === null) {
7865
$item = new Item($this, $key, $this->getEventManager());
@@ -175,4 +162,27 @@ public function commit(): bool
175162
// Return true only if at least one backend confirmed the "commit" operation
176163
return $hasCommitOnce;
177164
}
165+
166+
/**
167+
* @param ExtendedCacheItemPoolInterface[] $poolsToResynchronize
168+
* @param string $key
169+
* @param ?ExtendedCacheItemInterface $item
170+
* @return void
171+
* @throws \Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException
172+
*/
173+
protected function resynchronizePool(array $poolsToResynchronize, string $key, ?ExtendedCacheItemInterface $item): void
174+
{
175+
if ($item && $item->isHit() && \count($poolsToResynchronize) < \count($this->clusterPools)) {
176+
foreach ($poolsToResynchronize as $poolToResynchronize) {
177+
$poolItem = $poolToResynchronize->getItem($key);
178+
$poolItem->setEventManager($this->getEventManager())
179+
->set($item->get())
180+
->setHit($item->isHit())
181+
->setTags($item->getTags())
182+
->expiresAt($item->getExpirationDate())
183+
->setDriver($poolToResynchronize);
184+
$poolToResynchronize->save($poolItem);
185+
}
186+
}
187+
}
178188
}

lib/Phpfastcache/Core/Pool/CacheItemPoolTrait.php

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -128,17 +128,15 @@ public function getItem(string $key): ExtendedCacheItemInterface
128128
* loop dispatching operations
129129
*/
130130
if (!isset($this->itemInstances[$key]) || !$this->getConfig()->isUseStaticItemCaching()) {
131-
if (\preg_match('~([' . \preg_quote(self::$unsupportedKeyChars, '~') . ']+)~', $key, $matches)) {
132-
throw new PhpfastcacheInvalidArgumentException(
133-
'Unsupported key character detected: "' . $matches[1] . '".
134-
Please check: https://github.com/PHPSocialNetwork/phpfastcache/wiki/%5BV6%5D-Unsupported-characters-in-key-identifiers'
135-
);
136-
}
131+
$this->validateCacheKey($key);
137132

138133
$cacheSlamsSpendSeconds = 0;
134+
139135
$itemClass = self::getItemClass();
140136
/** @var $item ExtendedCacheItemInterface */
141137
$item = new $itemClass($this, $key, $this->eventManager);
138+
// $item = new (self::getItemClass())($this, $key, $this->eventManager);
139+
// Uncomment above when this one will be fixed: https://github.com/phpmd/phpmd/issues/952
142140

143141
getItemDriverRead:
144142
{
@@ -190,35 +188,7 @@ public function getItem(string $key): ExtendedCacheItemInterface
190188
$item->setTags($this->driverUnwrapTags($driverArray));
191189

192190
getItemDriverExpired:
193-
if ($item->isExpired()) {
194-
/**
195-
* Using driverDelete() instead of delete()
196-
* to avoid infinite loop caused by
197-
* getItem() call in delete() method
198-
* As we MUST return an item in any
199-
* way, we do not de-register here
200-
*/
201-
$this->driverDelete($item);
202-
203-
/**
204-
* Reset the Item
205-
*/
206-
$item->set(null)
207-
->expiresAfter((int) abs($this->getConfig()->getDefaultTtl()))
208-
->setHit(false)
209-
->setTags([]);
210-
if ($this->getConfig()->isItemDetailedDate()) {
211-
/**
212-
* If the itemDetailedDate has been
213-
* set after caching, we MUST inject
214-
* a new DateTime object on the fly
215-
*/
216-
$item->setCreationDate(new DateTime());
217-
$item->setModificationDate(new DateTime());
218-
}
219-
} else {
220-
$item->setHit(true);
221-
}
191+
$this->handleExpiredCacheItem($item);
222192
} else {
223193
$item->expiresAfter((int) abs($this->getConfig()->getDefaultTtl()));
224194
}
@@ -227,12 +197,9 @@ public function getItem(string $key): ExtendedCacheItemInterface
227197
$item = $this->itemInstances[$key];
228198
}
229199

200+
$this->eventManager->dispatch(Event::CACHE_GET_ITEM, $this, $item);
230201

231-
if ($item !== null) {
232-
$this->eventManager->dispatch(Event::CACHE_GET_ITEM, $this, $item);
233-
234-
$item->isHit() ? $this->getIO()->incReadHit() : $this->getIO()->incReadMiss();
235-
}
202+
$item->isHit() ? $this->getIO()->incReadHit() : $this->getIO()->incReadMiss();
236203

237204
return $item;
238205
}
@@ -482,4 +449,48 @@ public function isAttached(CacheItemInterface $item): bool
482449
}
483450
return false;
484451
}
452+
453+
protected function validateCacheKey(string $key): void
454+
{
455+
if (\preg_match('~([' . \preg_quote(self::$unsupportedKeyChars, '~') . ']+)~', $key, $matches)) {
456+
throw new PhpfastcacheInvalidArgumentException(
457+
'Unsupported key character detected: "' . $matches[1] . '".
458+
Please check: https://github.com/PHPSocialNetwork/phpfastcache/wiki/%5BV6%5D-Unsupported-characters-in-key-identifiers'
459+
);
460+
}
461+
}
462+
463+
protected function handleExpiredCacheItem(ExtendedCacheItemInterface $item): void
464+
{
465+
if ($item->isExpired()) {
466+
/**
467+
* Using driverDelete() instead of delete()
468+
* to avoid infinite loop caused by
469+
* getItem() call in delete() method
470+
* As we MUST return an item in any
471+
* way, we do not de-register here
472+
*/
473+
$this->driverDelete($item);
474+
475+
/**
476+
* Reset the Item
477+
*/
478+
$item->set(null)
479+
->expiresAfter((int) abs($this->getConfig()->getDefaultTtl()))
480+
->setHit(false)
481+
->setTags([]);
482+
483+
if ($this->getConfig()->isItemDetailedDate()) {
484+
/**
485+
* If the itemDetailedDate has been
486+
* set after caching, we MUST inject
487+
* a new DateTime object on the fly
488+
*/
489+
$item->setCreationDate(new DateTime());
490+
$item->setModificationDate(new DateTime());
491+
}
492+
} else {
493+
$item->setHit(true);
494+
}
495+
}
485496
}

lib/Phpfastcache/Util/ClassNamespaceResolverTrait.php

Lines changed: 72 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
namespace Phpfastcache\Util;
1818

19-
use Iterator;
2019
use RecursiveDirectoryIterator;
2120
use RecursiveIteratorIterator;
2221

@@ -87,53 +86,12 @@ protected static function findClasses(string $path): array
8786
$class = '';
8887
switch ($token[0]) {
8988
case T_NAMESPACE:
90-
$namespace = '';
91-
// If there is a namespace, extract it (PHP 8 test)
92-
if (\defined('T_NAME_QUALIFIED')) {
93-
while (isset($tokens[++$i][1])) {
94-
if ($tokens[$i][0] === T_NAME_QUALIFIED) {
95-
$namespace = $tokens[$i][1];
96-
break;
97-
}
98-
}
99-
} else {
100-
while (isset($tokens[++$i][1])) {
101-
if (\in_array($tokens[$i][0], [T_STRING, T_NS_SEPARATOR], true)) {
102-
$namespace .= $tokens[$i][1];
103-
}
104-
}
105-
}
106-
$namespace .= '\\';
89+
$namespace = self::buildTokenNamespace($i, $tokens);
10790
break;
10891
case T_CLASS:
10992
case T_INTERFACE:
11093
case T_TRAIT:
111-
// Skip usage of ::class constant
112-
$isClassConstant = false;
113-
for ($j = $i - 1; $j > 0; --$j) {
114-
if (!isset($tokens[$j][1])) {
115-
break;
116-
}
117-
if (T_DOUBLE_COLON === $tokens[$j][0]) {
118-
$isClassConstant = true;
119-
break;
120-
} elseif (!\in_array($tokens[$j][0], [T_WHITESPACE, T_DOC_COMMENT, T_COMMENT], false)) {
121-
break;
122-
}
123-
}
124-
if ($isClassConstant) {
125-
break;
126-
}
127-
// Find the classname
128-
while (isset($tokens[++$i][1])) {
129-
$t = $tokens[$i];
130-
if (T_STRING === $t[0]) {
131-
$class .= $t[1];
132-
} elseif ('' !== $class && T_WHITESPACE === $t[0]) {
133-
break;
134-
}
135-
}
136-
$classes[] = ltrim($namespace . $class, '\\');
94+
$classes = self::buildTokenClasses($namespace, $class, $classes, $i, $tokens);
13795
break;
13896
default:
13997
break;
@@ -143,6 +101,76 @@ protected static function findClasses(string $path): array
143101
return $classes;
144102
}
145103

104+
/**
105+
* @param string $namespace
106+
* @param string $class
107+
* @param string[] $classes
108+
* @param int $index
109+
* @param array<array<mixed>|string> $tokens
110+
* @return string[]
111+
*/
112+
protected static function buildTokenClasses(string $namespace, string $class, array $classes, int $index, array $tokens): array
113+
{
114+
// Skip usage of ::class constant
115+
$isClassConstant = false;
116+
for ($j = $index - 1; $j > 0; --$j) {
117+
if (!isset($tokens[$j][1])) {
118+
break;
119+
}
120+
if (T_DOUBLE_COLON === $tokens[$j][0]) {
121+
$isClassConstant = true;
122+
break;
123+
}
124+
125+
if (!\in_array($tokens[$j][0], [T_WHITESPACE, T_DOC_COMMENT, T_COMMENT], false)) {
126+
break;
127+
}
128+
}
129+
if ($isClassConstant) {
130+
return $classes;
131+
}
132+
133+
// Find the classname
134+
while (isset($tokens[++$index][1])) {
135+
$t = $tokens[$index];
136+
if (T_STRING === $t[0]) {
137+
$class .= $t[1];
138+
} elseif ('' !== $class && T_WHITESPACE === $t[0]) {
139+
break;
140+
}
141+
}
142+
143+
return \array_merge($classes, [\ltrim($namespace . $class, '\\')]);
144+
}
145+
146+
/**
147+
* @param int $index
148+
* @param array<array<mixed>|string> $tokens
149+
* @return string
150+
*/
151+
protected static function buildTokenNamespace(int $index, array $tokens): string
152+
{
153+
$namespace = '';
154+
155+
// If there is a namespace, extract it (PHP 8 test)
156+
if (\defined('T_NAME_QUALIFIED')) {
157+
while (isset($tokens[++$index][1])) {
158+
if ($tokens[$index][0] === T_NAME_QUALIFIED) {
159+
$namespace = $tokens[$index][1];
160+
break;
161+
}
162+
}
163+
} else {
164+
while (isset($tokens[++$index][1])) {
165+
if (\in_array($tokens[$index][0], [T_STRING, T_NS_SEPARATOR], true)) {
166+
$namespace .= $tokens[$index][1];
167+
}
168+
}
169+
}
170+
171+
return $namespace . '\\';
172+
}
173+
146174
/**
147175
* @return string
148176
*/

tests/DriverListResolver.test.php

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,21 @@
2727

2828
$driverList = CacheManager::getDriverList();
2929

30-
31-
foreach ($driverList as $driver) {
32-
foreach ($subClasses as $subClass) {
33-
$className = "Phpfastcache\\Drivers\\{$driver}\\{$subClass}";
34-
if (class_exists($className)) {
35-
$testHelper->assertPass(sprintf('Found the %s %s class: "%s"', $driver, $subClass, $className));
36-
} else {
37-
$testHelper->assertFail(sprintf('Class "%s" not found', $className));
30+
if(count($driverList)){
31+
foreach ($driverList as $driver) {
32+
foreach ($subClasses as $subClass) {
33+
$className = "Phpfastcache\\Drivers\\{$driver}\\{$subClass}";
34+
if (class_exists($className)) {
35+
$testHelper->assertPass(sprintf('Found the %s %s class: "%s"', $driver, $subClass, $className));
36+
} else {
37+
$testHelper->assertFail(sprintf('Class "%s" not found', $className));
38+
}
3839
}
3940
}
41+
} else {
42+
$testHelper->assertFail('Driver list is empty');
4043
}
4144

45+
46+
4247
$testHelper->terminateTest();

0 commit comments

Comments
 (0)