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

Parser/Middleware/CacheMiddleware.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\Parser\Middleware;
17
18
use phpDocumentor\Parser\Parser;
19
use phpDocumentor\Reflection\Middleware\Command;
20
use phpDocumentor\Reflection\Middleware\Middleware;
21
use phpDocumentor\Reflection\Php\Factory\File\CreateCommand;
22
use phpDocumentor\Reflection\Php\File;
23
use Stash\Interfaces\PoolInterface;
24
use Stash\Item;
25
use Stash\Pool;
26
27
final class CacheMiddleware implements Middleware
28
{
29
    /**
30
     * Cache namespace used for this repository.
31
     */
32
    const CACHE_NAMESPACE = 'Documentation\\Api\\Php';
33
34
    /**
35
     * Cache pool used to store files.
36
     *
37
     * @var Pool
38
     */
39
    private $dataStore;
40
41
    /**
42
     * @var Parser
43
     */
44
    private $parser;
45
46 2
    public function __construct(PoolInterface $dataStore, Parser $parser)
47
    {
48 2
        $this->dataStore = $dataStore;
0 ignored issues
show
Documentation Bug introduced by
$dataStore is of type object<Stash\Interfaces\PoolInterface>, but the property $dataStore was declared to be of type object<Stash\Pool>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
49 2
        $this->parser = $parser;
50 2
    }
51
52
    /**
53
     * Executes this middle ware class.
54
     * A middle ware class MUST return a File object or call the $next callable.
55
     *
56
     * @param CreateCommand $command
57
     * @param callable $next
58
     *
59
     * @return File
60
     */
61 2
    public function execute(Command $command, callable $next)
62
    {
63 2
        $itemName = $this->getItemName($command->getFile()->path());
64 2
        $item = $this->dataStore->getItem($itemName);
65 2
        if ($item->isMiss() || $this->parser->isForced()) {
66 1
            return $this->updateCache($command, $next, $item);
67
        }
68
69
        /** @var File $cachedFile */
70 1
        $cachedFile = $item->get();
71
72 1
        if ($cachedFile === null) {
73
            return $this->updateCache($command, $next, $item);
74
        }
75
76 1
        if ($cachedFile->getHash() !== $command->getFile()->md5()) {
77 1
            return $this->updateCache($command, $next, $item);
78
        }
79
80
        return $cachedFile;
81
    }
82
83
    /**
84
     * @param callable $next
85
     * @param Item $item
86
     * @return mixed
87
     */
88 2
    private function updateCache(CreateCommand $command, callable $next, $item)
89
    {
90 2
        $file = $next($command);
91 2
        $item->lock();
92 2
        $this->dataStore->save($item->set($file));
93 2
        return $file;
94
    }
95
96
    /**
97
     * Convert path to ItemName
98
     *
99
     * @param string $path
100
     * @return string
101
     */
102 2
    private function getItemName($path)
103
    {
104 2
        return static::CACHE_NAMESPACE . '\\' . md5($path);
105
    }
106
}
107