Completed
Push — develop ( 0b8425...c51867 )
by Jaap
15s queued 11s
created

Descriptor/Cache/ProjectDescriptorMapper.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 InvalidArgumentException;
19
use phpDocumentor\Descriptor\FileDescriptor;
20
use phpDocumentor\Descriptor\ProjectDescriptor;
21
use phpDocumentor\Descriptor\ProjectDescriptor\Settings;
22
use Zend\Cache\Storage\IterableInterface;
23
use Zend\Cache\Storage\OptimizableInterface;
24
use Zend\Cache\Storage\StorageInterface;
25
26
/**
27
 * Maps a projectDescriptor to and from a cache instance.
28
 */
29
final class ProjectDescriptorMapper
30
{
31
    const FILE_PREFIX = 'file_';
32
33
    const KEY_SETTINGS = 'settings';
34
35
    /** @var StorageInterface|IterableInterface */
36
    private $cache;
37
38
    /**
39
     * Initializes this mapper with the given cache instance.
40
     */
41 3
    public function __construct(StorageInterface $cache)
42
    {
43 3
        if (!$cache instanceof IterableInterface) {
44 1
            throw new InvalidArgumentException('ProjectDescriptorMapper should also be an iterable Storage type');
45
        }
46
47 3
        $this->cache = $cache;
48 3
    }
49
50
    /**
51
     * Returns the Cache instance for this Mapper.
52
     */
53 1
    public function getCache(): StorageInterface
54
    {
55 1
        return $this->cache;
56
    }
57
58
    /**
59
     * Returns the Project Descriptor from the cache.
60
     */
61 1
    public function populate(ProjectDescriptor $projectDescriptor): void
62
    {
63 1
        $this->loadCacheItemAsSettings($projectDescriptor, self::KEY_SETTINGS);
64
65 1
        foreach ($this->getCache() as $key) {
66 1
            $this->loadCacheItemAsFile($projectDescriptor, $key);
67
        }
68 1
    }
69
70
    /**
71
     * Stores a Project Descriptor in the Cache.
72
     */
73 1
    public function save(ProjectDescriptor $projectDescriptor): void
74
    {
75 1
        $keys = [];
76 1
        $cache = $this->getCache();
77
78 1
        foreach ($cache as $key) {
79
            $keys[] = $key;
80
        }
81
82
        // store the settings for this Project Descriptor
83 1
        $cache->setItem(self::KEY_SETTINGS, $projectDescriptor->getSettings());
84
85
        // store cache items
86 1
        $usedKeys = [self::KEY_SETTINGS];
87 1
        foreach ($projectDescriptor->getFiles() as $file) {
88
            $key = self::FILE_PREFIX . md5($file->getPath());
89
            $usedKeys[] = $key;
90
            $cache->setItem($key, $file);
91
        }
92
93
        // remove any keys that are no longer used.
94 1
        $invalidatedKeys = array_diff($keys, $usedKeys);
95 1
        if ($invalidatedKeys) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $invalidatedKeys of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
96
            $cache->removeItems($invalidatedKeys);
97
        }
98
99 1
        if ($cache instanceof OptimizableInterface) {
100
            $cache->optimize();
101
        }
102 1
    }
103
104
    /**
105
     * Removes all files in cache that do not occur in the given FileSet Collection.
106
     *
107
     * @todo restore this?
108
     */
109
    public function garbageCollect($collection)
110
    {
111
//        $projectRoot = $collection->getProjectRoot();
112
//        $filenames = $collection->getFilenames();
113
//
114
//        foreach ($filenames as &$name) {
115
//            // the cache key contains a path relative to the project root; here we expect absolute paths.
116
//            $name = self::FILE_PREFIX . md5(substr($name, strlen($projectRoot)));
117
//        }
118
//
119
//        foreach ($this->getCache() as $item) {
120
//            if (substr($item, 0, strlen(self::FILE_PREFIX)) === self::FILE_PREFIX && !in_array($item, $filenames, true)) {
121
//                $this->getCache()->removeItem($item);
122
//            }
123
//        }
124
    }
125
126
    private function loadCacheItemAsFile(ProjectDescriptor $projectDescriptor, string $key): void
127
    {
128
        $item = $this->getCache()->getItem($key);
129
130
        if ($item instanceof FileDescriptor) {
131
            $projectDescriptor->getFiles()->set($item->getPath(), $item);
132
        }
133
    }
134
135
    private function loadCacheItemAsSettings(ProjectDescriptor $projectDescriptor, string $key): void
136
    {
137
        $item = $this->getCache()->getItem($key);
138
139
        if ($item instanceof Settings) {
140
            $projectDescriptor->setSettings($item);
141
        }
142
    }
143
}
144