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

CoversTag::process()   D

Complexity

Conditions 15
Paths 211

Size

Total Lines 131
Code Lines 71

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 15
eloc 71
nc 211
nop 1
dl 0
loc 131
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 @covers tag
16
 */
17
class CoversTag
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=\'covers\']');
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 @coveredby 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 @covers
86
            if ($referral_nodes === false) {
87
                // $this->log(
88
                //    'An XPath error occurs while processing @covers, the query used was: ' . $qry,
89
                //    LogLevel::CRITICAL
90
                // );
91
                continue;
92
            }
93
94
            // check if the result is unique; if not we error and continue
95
            // to the next @covers
96
            if ($referral_nodes->length > 1) {
97
                continue;
98
            }
99
100
            // if there is one matching element; link them together
101
            if ($referral_nodes->length > 0) {
102
                /** @var \DOMElement $referral  */
103
                $referral = $referral_nodes->item(0);
104
                $docblock = $referral->getElementsByTagName('docblock');
105
                if ($docblock->length < 1) {
106
                    $docblock = new \DOMElement('docblock');
107
                    $referral->appendChild($docblock);
108
                } else {
109
                    $docblock = $docblock->item(0);
110
                }
111
112
                $used_by = new \DOMElement('tag');
113
                $docblock->appendChild($used_by);
114
                $used_by->setAttribute('name', 'used_by');
115
                $used_by->setAttribute('line', '');
116
117
                // gather the name of the referring element and set that as refers
118
                // attribute
119
                if ($node->parentNode->parentNode->nodeName == 'class') {
120
                    // if the element where the @covers is in is a class; nothing
121
                    // more than the class name need to returned
122
                    $referral_name = $node->parentNode->parentNode
123
                        ->getElementsByTagName('full_name')->item(0)->nodeValue;
124
                } else {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
125
126
                    $referral_class_name = null;
127
                    if ($node->parentNode->parentNode->nodeName == 'method') {
128
                        // gather the name of the class where the @covers is in
129
                        $referral_class_name = $node->parentNode->parentNode
130
                            ->parentNode->getElementsByTagName('full_name')->item(0)
131
                            ->nodeValue;
132
                    }
133
134
                    // gather the name of the subelement of the class where
135
                    // the @covers is in
136
                    $referral_name = $node->parentNode->parentNode
137
                        ->getElementsByTagName('name')->item(0)->nodeValue;
138
139
                    // if it is a method; suffix with ()
140
                    if ($node->parentNode->parentNode->nodeName == 'method'
141
                        || $node->parentNode->parentNode->nodeName == 'function'
142
                    ) {
143
                        $referral_name .= '()';
144
                    }
145
146
                    // only prefix class name if this is a class member
147
                    if ($referral_class_name) {
148
                        $referral_name = $referral_class_name . '::'
149
                            . $referral_name;
150
                    }
151
                }
152
153
                $used_by->setAttribute('description', $referral_name);
154
                $used_by->setAttribute('refers', $referral_name);
155
            }
156
        }
157
158
        return $xml;
159
    }
160
}
161