Completed
Push — develop ( 722f70...af048b )
by Jaap
15:12 queued 05:04
created

UsesTag   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 140
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 140
rs 10
c 0
b 0
f 0
wmc 15
lcom 0
cbo 0

1 Method

Rating   Name   Duplication   Size   Complexity  
D process() 0 127 15
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\Plugin\Core\Transformer\Behaviour\Tag;
13
14
/**
15
 * Behaviour that adds support for the uses tag
16
 */
17
class UsesTag
18
{
19
    /**
20
     * Find all return tags that contain 'self' or '$this' and replace those
21
     * terms for the name of the current class' type.
22
     *
23
     * @param \DOMDocument $xml Structure source to apply behaviour onto.
24
     *
25
     * @todo split method into submethods
26
     *
27
     * @return \DOMDocument
28
     */
29
    public function process(\DOMDocument $xml)
0 ignored issues
show
Complexity introduced by
This operation has 5617 execution paths which exceeds the configured maximum of 200.

A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.

You can also find more information in the “Code” section of your repository.

Loading history...
30
    {
31
        $xpath = new \DOMXPath($xml);
32
        $nodes = $xpath->query('//tag[@name=\'uses\']');
33
34
        /** @var \DOMElement $node */
35
        foreach ($nodes as $node) {
36
            $refers = $node->getAttribute('refers');
37
            $refers_array = explode('::', $refers);
38
39
            // determine the type so we know where to put the @usedby tag on
40
            $type = 'class';
41
            if (isset($refers_array[1])) {
42
                // starts with $ = property, ends with () = method,
43
                // otherwise constant
44
                $type = $refers_array[1][0] == '$' ? 'property' : 'constant';
45
                $type = substr($refers_array[1], -2) == '()' ? 'method' : $type;
46
            }
47
48
            switch ($type) {
49
                case 'class':
50
                    // escape single quotes in the class name
51
                    $xpath_refers = 'concat(\''.str_replace(
52
                        array("'", '"'),
53
                        array('\', "\'", \'', '\', \'"\' , \''),
54
                        $refers
55
                    ) . "', '')";
56
57
                    $qry = '/project/file/class[full_name=' . $xpath_refers . ']';
58
                    break;
59
                default:
60
                    $class_name = $refers_array[0];
61
62
                    // escape single quotes in the class name
63
                    $xpath_class_name = 'concat(\''.str_replace(
64
                        array("'", '"'),
65
                        array('\', "\'", \'', '\', \'"\' , \''),
66
                        $class_name
67
                    ) . "', '')";
68
69
                    // escape single quotes in the method name
70
                    $xpath_method_name = 'concat(\''.str_replace(
71
                        array("'", '"'),
72
                        array('\', "\'", \'', '\', \'"\' , \''),
73
                        rtrim($refers_array[1], '()')
74
                    ) . "', '')";
75
76
                    $qry = '/project/file/class[full_name=' . $xpath_class_name
77
                        . ']/'.$type.'[name=' . $xpath_method_name .']';
78
                    break;
79
            }
80
81
            /** @noinspection PhpUsageOfSilenceOperatorInspection as there is no pre-validation possible */
82
            $referral_nodes = @$xpath->query($qry);
83
84
            // if the query is wrong; output a Critical error and continue to
85
            // the next @uses
86
            if ($referral_nodes === false) {
87
                continue;
88
            }
89
90
            // check if the result is unique; if not we error and continue
91
            // to the next @uses
92
            if ($referral_nodes->length > 1) {
93
                continue;
94
            }
95
96
            // if there is one matching element; link them together
97
            if ($referral_nodes->length > 0) {
98
                /** @var \DOMElement $referral */
99
                $referral = $referral_nodes->item(0);
100
                $docblock = $referral->getElementsByTagName('docblock');
101
                if ($docblock->length < 1) {
102
                    $docblock = new \DOMElement('docblock');
103
                    $referral->appendChild($docblock);
104
                } else {
105
                    $docblock = $docblock->item(0);
106
                }
107
108
                $used_by = new \DOMElement('tag');
109
                $docblock->appendChild($used_by);
110
                $used_by->setAttribute('name', 'used_by');
111
                $used_by->setAttribute('line', '');
112
113
                // gather the name of the referring element and set that as refers
114
                // attribute
115
                if ($node->parentNode->parentNode->nodeName == 'class') {
116
                    // if the element where the @uses is in is a class; nothing
117
                    // more than the class name need to returned
118
                    $referral_name = $node->parentNode->parentNode
119
                        ->getElementsByTagName('full_name')->item(0)->nodeValue;
120
                } else {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
121
122
                    $referral_class_name = null;
123
                    if ($node->parentNode->parentNode->nodeName == 'method') {
124
                        // gather the name of the class where the @uses is in
125
                        $referral_class_name = $node->parentNode->parentNode
126
                            ->parentNode->getElementsByTagName('full_name')->item(0)
127
                            ->nodeValue;
128
                    }
129
130
                    // gather the name of the subelement of the class where
131
                    // the @uses is in
132
                    $referral_name = $node->parentNode->parentNode
133
                        ->getElementsByTagName('name')->item(0)->nodeValue;
134
135
                    // if it is a method; suffix with ()
136
                    if ($node->parentNode->parentNode->nodeName == 'method'
137
                        || $node->parentNode->parentNode->nodeName == 'function'
138
                    ) {
139
                        $referral_name .= '()';
140
                    }
141
142
                    // only prefix class name if this is a class member
143
                    if ($referral_class_name) {
144
                        $referral_name = $referral_class_name . '::'
145
                            . $referral_name;
146
                    }
147
                }
148
149
                $used_by->setAttribute('description', $referral_name);
150
                $used_by->setAttribute('refers', $referral_name);
151
            }
152
        }
153
154
        return $xml;
155
    }
156
}
157