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

UsesTag::process()   D

Complexity

Conditions 15
Paths 211

Size

Total Lines 127
Code Lines 71

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 15
eloc 71
nc 211
nop 1
dl 0
loc 127
rs 4.4065
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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