1
|
|
|
<?php |
2
|
|
|
declare(strict_types=1); |
3
|
|
|
|
4
|
|
|
/** |
5
|
|
|
* This file is part of phpDocumentor. |
6
|
|
|
* |
7
|
|
|
* For the full copyright and license information, please view the LICENSE |
8
|
|
|
* file that was distributed with this source code. |
9
|
|
|
* |
10
|
|
|
* @author Mike van Riel <[email protected]> |
11
|
|
|
* @copyright 2010-2018 Mike van Riel / Naenius (http://www.naenius.com) |
12
|
|
|
* @license http://www.opensource.org/licenses/mit-license.php MIT |
13
|
|
|
* @link http://phpdoc.org |
14
|
|
|
*/ |
15
|
|
|
|
16
|
|
|
namespace phpDocumentor\Descriptor\Cache; |
17
|
|
|
|
18
|
|
|
use phpDocumentor\Descriptor\FileDescriptor; |
19
|
|
|
use phpDocumentor\Descriptor\ProjectDescriptor; |
20
|
|
|
use phpDocumentor\Reflection\File; |
21
|
|
|
use Psr\Cache\CacheItemPoolInterface; |
22
|
|
|
use Stash\Item; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* Maps a projectDescriptor to and from a cache instance. |
26
|
|
|
*/ |
27
|
|
|
final class ProjectDescriptorMapper |
28
|
|
|
{ |
29
|
|
|
const FILE_PREFIX = 'phpDocumentor/projectDescriptor/files/'; |
30
|
|
|
|
31
|
|
|
const FILE_LIST = 'phpDocumentor/projectDescriptor/filelist'; |
32
|
|
|
|
33
|
|
|
const KEY_SETTINGS = 'phpDocumentor/projectDescriptor/settings'; |
34
|
|
|
|
35
|
|
|
/** @var CacheItemPoolInterface */ |
36
|
|
|
private $cache; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* Initializes this mapper with the given cache instance. |
40
|
|
|
*/ |
41
|
1 |
|
public function __construct(CacheItemPoolInterface $cache) |
42
|
|
|
{ |
43
|
1 |
|
$this->cache = $cache; |
44
|
1 |
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Returns the Project Descriptor from the cache. |
48
|
|
|
*/ |
49
|
1 |
|
public function populate(ProjectDescriptor $projectDescriptor): void |
50
|
|
|
{ |
51
|
1 |
|
$this->loadCacheItemAsSettings($projectDescriptor); |
52
|
|
|
|
53
|
1 |
|
$fileList = $this->cache->getItem(self::FILE_LIST)->get(); |
54
|
1 |
|
if ($fileList !== null) { |
55
|
|
|
/** @var Item $item */ |
56
|
1 |
|
foreach ($this->cache->getItems($fileList) as $item) { |
57
|
1 |
|
$file = $item->get(); |
58
|
|
|
|
59
|
1 |
|
if ($file instanceof FileDescriptor) { |
60
|
1 |
|
$projectDescriptor->getFiles()->set($file->getPath(), $file); |
61
|
|
|
} |
62
|
|
|
} |
63
|
|
|
} |
64
|
1 |
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* Stores a Project Descriptor in the Cache. |
68
|
|
|
*/ |
69
|
1 |
|
public function save(ProjectDescriptor $projectDescriptor): void |
70
|
|
|
{ |
71
|
1 |
|
$fileListItem = $this->cache->getItem(self::FILE_LIST); |
72
|
1 |
|
$currentFileList = $fileListItem->get(); |
73
|
|
|
|
74
|
|
|
// store the settings for this Project Descriptor |
75
|
1 |
|
$item = $this->cache->getItem(self::KEY_SETTINGS); |
76
|
1 |
|
$this->cache->saveDeferred($item->set($projectDescriptor->getSettings())); |
77
|
|
|
|
78
|
|
|
// store cache items |
79
|
1 |
|
$fileKeys = []; |
80
|
1 |
|
foreach ($projectDescriptor->getFiles() as $file) { |
81
|
1 |
|
$key = self::FILE_PREFIX . md5($file->getPath()); |
82
|
1 |
|
$fileKeys[] = $key; |
83
|
1 |
|
$item = $this->cache->getItem($key); |
84
|
1 |
|
$this->cache->saveDeferred($item->set($file)); |
85
|
|
|
} |
86
|
|
|
|
87
|
1 |
|
$this->cache->saveDeferred($fileListItem->set($fileKeys)); |
88
|
1 |
|
$this->cache->commit(); |
89
|
|
|
|
90
|
1 |
|
if ($currentFileList !== null) { |
91
|
|
|
// remove any keys that are no longer used. |
92
|
|
|
$invalidatedKeys = array_diff($currentFileList, $fileKeys); |
93
|
|
|
if ($invalidatedKeys) { |
|
|
|
|
94
|
|
|
$this->cache->deleteItems($invalidatedKeys); |
95
|
|
|
} |
96
|
|
|
} |
97
|
1 |
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Removes all files in cache that do not occur in the given FileSet Collection. |
101
|
|
|
* |
102
|
|
|
* @param File[] $files |
103
|
|
|
*/ |
104
|
|
|
public function garbageCollect(array $files) : void |
105
|
|
|
{ |
106
|
|
|
$fileListItem = $this->cache->getItem(self::FILE_LIST); |
107
|
|
|
$cachedFileList = $fileListItem->get(); |
108
|
|
|
|
109
|
|
|
if ($cachedFileList !== null) { |
110
|
|
|
$realFileKeys = array_map( |
111
|
|
|
static function (File $file) { |
112
|
|
|
return self::FILE_PREFIX . md5($file->path()); |
113
|
|
|
}, |
114
|
|
|
$files |
115
|
|
|
); |
116
|
|
|
|
117
|
|
|
$this->cache->deleteItems(array_diff($cachedFileList, $realFileKeys)); |
118
|
|
|
} |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
private function loadCacheItemAsSettings(ProjectDescriptor $projectDescriptor): void |
122
|
|
|
{ |
123
|
|
|
$item = $this->cache->getItem(self::KEY_SETTINGS); |
124
|
|
|
if ($item->isHit()) { |
125
|
|
|
$settings = $item->get(); |
126
|
|
|
$projectDescriptor->setSettings($settings); |
127
|
|
|
} |
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.