Completed
Push — develop ( 7e37ef...093d8d )
by Jaap
11:13
created

Queue::insert()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 4
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
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\Transformer\Router;
17
18
use phpDocumentor\Descriptor\Descriptor;
19
use phpDocumentor\Transformer\Transformation;
20
use phpDocumentor\Transformer\Writer\Pathfinder;
21
22
/**
23
 * Provides a queue of routers to determine the order in which they are executed.
24
 */
25
class Queue extends \SplPriorityQueue
26
{
27
    public function insert($value, $priority)
28
    {
29
        parent::insert($value, $priority); // TODO: Change the autogenerated stub
30
    }
31
32
33
    /**
34
     * Tries to match the given node with a rule defined in one of the routers.
35
     *
36
     * @param string|Descriptor $node
37
     *
38
     * @return Rule|null
39
     */
40 2
    public function match($node)
41
    {
42
        /** @var RouterAbstract $router */
43 2
        foreach (clone $this as $router) {
44 2
            $rule = $router->match($node);
45 2
            if ($rule) {
46 2
                return $rule;
47
            }
48
        }
49
50 1
        return null;
51
    }
52
53
    /**
54
     * Uses the currently selected node and transformation to assemble the destination path for the file.
55
     *
56
     * Writers accept the use of a Query to be able to generate output for multiple objects using the same
57
     * template.
58
     *
59
     * The given node is the result of such a query, or if no query given the selected element, and the transformation
60
     * contains the destination file.
61
     *
62
     * Since it is important to be able to generate a unique name per element can the user provide a template variable
63
     * in the name of the file.
64
     * Such a template variable always resides between double braces and tries to take the node value of a given
65
     * query string.
66
     *
67
     * Example:
68
     *
69
     *   An artifact stating `classes/{{name}}.html` will try to find the
70
     *   node 'name' as a child of the given $node and use that value instead.
71
     *
72
     * @throws \InvalidArgumentException if no artifact is provided and no routing rule matches.
73
     * @throws \UnexpectedValueException if the provided node does not contain anything.
74
     *
75
     * @return null|string returns the destination location or false if generation should be aborted.
76
     */
77
    public function destination(Descriptor $descriptor, Transformation $transformation): ?string
78
    {
79
        $path = $transformation->getTransformer()->getTarget() . DIRECTORY_SEPARATOR . $transformation->getArtifact();
80
        if (!$transformation->getArtifact()) {
81
            $rule = $this->match($descriptor);
82
            if (!$rule) {
83
                throw new \InvalidArgumentException(
84
                    'No matching routing rule could be found for the given node, please provide an artifact location, '
85
                    . 'encountered: ' . ($descriptor === null ? 'NULL' : get_class($descriptor))
86
                );
87
            }
88
89
            $rule = new ForFileProxy($rule);
90
            $url = $rule->generate($descriptor);
0 ignored issues
show
Documentation introduced by
$descriptor is of type object<phpDocumentor\Descriptor\Descriptor>, but the function expects a string|object<phpDocumen...tor\DescriptorAbstract>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
91
            if ($url === false || $url[0] !== DIRECTORY_SEPARATOR) {
92
                return null;
93
            }
94
95
            $path = $transformation->getTransformer()->getTarget()
96
                . str_replace('/', DIRECTORY_SEPARATOR, $url);
97
        }
98
99
        $finder = new Pathfinder();
100
        $destination = preg_replace_callback(
101
            '/{{([^}]+)}}/', // explicitly do not use the unicode modifier; this breaks windows
102
            function ($query) use ($descriptor, $finder) {
103
                // strip any surrounding \ or /
104
                $filepart = trim((string) current($finder->find($descriptor, $query[1])), '\\/');
105
106
                // make it windows proof
107
                if (extension_loaded('iconv')) {
108
                    $filepart = iconv('UTF-8', 'ASCII//TRANSLIT', $filepart);
109
                }
110
111
                return strpos($filepart, '/') !== false
112
                    ? implode('/', array_map('urlencode', explode('/', $filepart)))
113
                    : implode('\\', array_map('urlencode', explode('\\', $filepart)));
114
            },
115
            $path
116
        );
117
118
        // replace any \ with the directory separator to be compatible with the
119
        // current filesystem and allow the next file_exists to do its work
120
        $destination = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $destination);
121
122
        // create directory if it does not exist yet
123
        if (!file_exists(dirname($destination))) {
124
            mkdir(dirname($destination), 0777, true);
125
        }
126
127
        return $destination;
128
    }
129
}
130