Completed
Push — develop ( f937fe...60406c )
by Mike
14s
created

ProjectDescriptorMapper::loadCacheItemAsSettings()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 2
dl 0
loc 8
ccs 0
cts 5
cp 0
crap 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * phpDocumentor
4
 *
5
 * PHP Version 5.3
6
 *
7
 * @copyright 2010-2014 Mike van Riel / Naenius (http://www.naenius.com)
8
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
9
 * @link      http://phpdoc.org
10
 */
11
12
namespace phpDocumentor\Descriptor\Cache;
13
14
use Zend\Cache\Storage\IterableInterface;
15
use Zend\Cache\Storage\OptimizableInterface;
16
use Zend\Cache\Storage\StorageInterface;
17
use phpDocumentor\Descriptor\FileDescriptor;
18
use phpDocumentor\Descriptor\ProjectDescriptor;
19
use phpDocumentor\Descriptor\ProjectDescriptor\Settings;
20
use phpDocumentor\Fileset\Collection;
21
22
/**
23
 * Maps a projectDescriptor to and from a cache instance.
24
 */
25
final class ProjectDescriptorMapper
26
{
27
    const FILE_PREFIX = 'file_';
28
29
    const KEY_SETTINGS = 'settings';
30
31
    /** @var StorageInterface|IterableInterface */
32
    protected $cache;
33
34
    /**
35
     * Initializes this mapper with the given cache instance.
36
     */
37
    public function __construct(StorageInterface $cache)
38
    {
39
        if (!$cache instanceof IterableInterface) {
40
            throw new \InvalidArgumentException('ProjectDescriptorMapper should also be an iterable Storage type');
41
        }
42
43
        $this->cache = $cache;
44
    }
45
46
    /**
47
     * Returns the Cache instance for this Mapper.
48
     */
49
    public function getCache(): StorageInterface
50
    {
51
        return $this->cache;
52
    }
53
54
    /**
55
     * Returns the Project Descriptor from the cache.
56
     */
57
    public function populate(ProjectDescriptor $projectDescriptor)
58
    {
59
        $this->loadCacheItemAsSettings($projectDescriptor, self::KEY_SETTINGS);
60
61
        foreach ($this->getCache() as $key) {
0 ignored issues
show
Bug introduced by
The expression $this->getCache() of type object<Zend\Cache\Storage\StorageInterface> is not traversable.
Loading history...
62
            $this->loadCacheItemAsFile($projectDescriptor, $key);
63
        }
64
    }
65
66
    /**
67
     * Stores a Project Descriptor in the Cache.
68
     */
69
    public function save(ProjectDescriptor $projectDescriptor)
70
    {
71
        $keys  = array();
72
        $cache = $this->getCache();
73
74
        foreach ($cache as $key) {
0 ignored issues
show
Bug introduced by
The expression $cache of type object<Zend\Cache\Storage\StorageInterface> is not traversable.
Loading history...
75
            $keys[] = $key;
76
        }
77
78
        // store the settings for this Project Descriptor
79
        $cache->setItem(self::KEY_SETTINGS, $projectDescriptor->getSettings());
80
81
        // store cache items
82
        $usedKeys = array(self::KEY_SETTINGS);
83
        foreach ($projectDescriptor->getFiles() as $file) {
84
            $key        = self::FILE_PREFIX . md5($file->getPath());
85
            $usedKeys[] = $key;
86
            $cache->setItem($key, $file);
87
        }
88
89
        // remove any keys that are no longer used.
90
        $invalidatedKeys = array_diff($keys, $usedKeys);
91
        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...
92
            $cache->removeItems($invalidatedKeys);
93
        }
94
95
        if ($cache instanceof OptimizableInterface) {
96
            $cache->optimize();
97
        }
98
    }
99
100
    /**
101
     * Removes all files in cache that do not occur in the given FileSet Collection.
102
     */
103
    public function garbageCollect(Collection $collection)
104
    {
105
        $projectRoot = $collection->getProjectRoot();
106
        $filenames   = $collection->getFilenames();
107
108
        foreach ($filenames as &$name) {
109
            // the cache key contains a path relative to the project root; here we expect absolute paths.
110
            $name = self::FILE_PREFIX . md5(substr($name, strlen($projectRoot)));
111
        }
112
113
        foreach ($this->getCache() as $item) {
0 ignored issues
show
Bug introduced by
The expression $this->getCache() of type object<Zend\Cache\Storage\StorageInterface> is not traversable.
Loading history...
114
            if (substr($item, 0, strlen(self::FILE_PREFIX)) === self::FILE_PREFIX && !in_array($item, $filenames)) {
115
                $this->getCache()->removeItem($item);
116
            }
117
        }
118
    }
119
120
    private function loadCacheItemAsFile(ProjectDescriptor $projectDescriptor, string $key)
121
    {
122
        $item = $this->getCache()->getItem($key);
123
124
        if ($item instanceof FileDescriptor) {
125
            $projectDescriptor->getFiles()->set($item->getPath(), $item);
126
        }
127
    }
128
129
    private function loadCacheItemAsSettings(ProjectDescriptor $projectDescriptor, string $key)
130
    {
131
        $item = $this->getCache()->getItem($key);
132
133
        if ($item instanceof Settings) {
134
            $projectDescriptor->setSettings($item);
135
        }
136
    }
137
}
138