Completed
Push — develop ( 8eb671...133594 )
by Mike
19:30 queued 09:24
created

Descriptor/Cache/ProjectDescriptorMapper.php (1 issue)

Check for implicit conversion of array to boolean.

Best Practice Bug Minor

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(
45
                'ProjectDescriptorMapper should also be an iterable Storage type'
46
            );
47 3
        }
48 3
49
        $this->cache = $cache;
50
    }
51
52
    /**
53 1
     * Returns the Cache instance for this Mapper.
54
     */
55 1
    public function getCache(): StorageInterface
56
    {
57
        return $this->cache;
58
    }
59
60
    /**
61 1
     * Returns the Project Descriptor from the cache.
62
     */
63 1
    public function populate(ProjectDescriptor $projectDescriptor): void
64
    {
65 1
        $this->loadCacheItemAsSettings($projectDescriptor, self::KEY_SETTINGS);
66 1
67
        foreach ($this->getCache() as $key) {
68 1
            $this->loadCacheItemAsFile($projectDescriptor, $key);
69
        }
70
    }
71
72
    /**
73 1
     * Stores a Project Descriptor in the Cache.
74
     */
75 1
    public function save(ProjectDescriptor $projectDescriptor): void
76 1
    {
77
        $keys = [];
78 1
        $cache = $this->getCache();
79
80
        foreach ($cache as $key) {
81
            $keys[] = $key;
82
        }
83 1
84
        // store the settings for this Project Descriptor
85
        $cache->setItem(self::KEY_SETTINGS, $projectDescriptor->getSettings());
86 1
87 1
        // store cache items
88
        $usedKeys = [self::KEY_SETTINGS];
89
        foreach ($projectDescriptor->getFiles() as $file) {
90
            $key = self::FILE_PREFIX . md5($file->getPath());
91
            $usedKeys[] = $key;
92
            $cache->setItem($key, $file);
93
        }
94 1
95 1
        // remove any keys that are no longer used.
96
        $invalidatedKeys = array_diff($keys, $usedKeys);
97
        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...
98
            $cache->removeItems($invalidatedKeys);
99 1
        }
100
101
        if ($cache instanceof OptimizableInterface) {
102 1
            $cache->optimize();
103
        }
104
    }
105
106
    /**
107
     * Removes all files in cache that do not occur in the given FileSet Collection.
108
     *
109
     * @todo restore this?
110
     */
111
    public function garbageCollect($collection)
112
    {
113
//        $projectRoot = $collection->getProjectRoot();
114
//        $filenames = $collection->getFilenames();
115
//
116
//        foreach ($filenames as &$name) {
117
//            // the cache key contains a path relative to the project root; here we expect absolute paths.
118
//            $name = self::FILE_PREFIX . md5(substr($name, strlen($projectRoot)));
119
//        }
120
//
121
//        foreach ($this->getCache() as $item) {
122
//            if (substr($item, 0, strlen(self::FILE_PREFIX)) === self::FILE_PREFIX &&
123
//                  !in_array($item, $filenames, true)
124
//            ) {
125
//                $this->getCache()->removeItem($item);
126
//            }
127
//        }
128
    }
129
130
    private function loadCacheItemAsFile(ProjectDescriptor $projectDescriptor, string $key): void
131
    {
132
        $item = $this->getCache()->getItem($key);
133
134
        if ($item instanceof FileDescriptor) {
135
            $projectDescriptor->getFiles()->set($item->getPath(), $item);
136
        }
137
    }
138
139
    private function loadCacheItemAsSettings(ProjectDescriptor $projectDescriptor, string $key): void
140
    {
141
        $item = $this->getCache()->getItem($key);
142
143
        if ($item instanceof Settings) {
144
            $projectDescriptor->setSettings($item);
145
        }
146
    }
147
}
148