Completed
Push — master ( 69f162...acb4bc )
by Sebastian
02:58
created

Group::render()   F

Complexity

Conditions 27
Paths 1005

Size

Total Lines 123
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 123
rs 2
c 0
b 0
f 0
cc 27
eloc 42
nc 1005
nop 2

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
 * citeproc-php
4
 *
5
 * @link        http://github.com/seboettg/citeproc-php for the source repository
6
 * @copyright   Copyright (c) 2016 Sebastian Böttger.
7
 * @license     https://opensource.org/licenses/MIT
8
 */
9
10
namespace Seboettg\CiteProc\Rendering;
11
use Seboettg\CiteProc\Styles\AffixesTrait;
12
use Seboettg\CiteProc\Styles\ConsecutivePunctuationCharacterTrait;
13
use Seboettg\CiteProc\Styles\DelimiterTrait;
14
use Seboettg\CiteProc\Styles\DisplayTrait;
15
use Seboettg\CiteProc\Util\Factory;
16
use Seboettg\Collection\ArrayList;
17
18
19
/**
20
 * Class Group
21
 * @package Seboettg\CiteProc\Rendering
22
 *
23
 * @author Sebastian Böttger <[email protected]>
24
 */
25
class Group implements RenderingInterface, HasParent
26
{
27
    use DelimiterTrait,
28
        AffixesTrait,
29
        DisplayTrait,
30
        ConsecutivePunctuationCharacterTrait;
31
32
    const CLASS_PATH = 'Seboettg\CiteProc\Rendering';
33
34
    private static $suppressableElements = [
35
        self::CLASS_PATH . '\Number',
36
        self::CLASS_PATH . '\Group',
37
        self::CLASS_PATH . '\Date\Date'
38
    ]; 
39
40
    /**
41
     * @var ArrayList
42
     */
43
    private $children;
44
45
    /**
46
     * cs:group may carry the delimiter attribute to separate its child elements
47
     * @var
48
     */
49
    private $delimiter = "";
50
51
    private $parent;
52
53 View Code Duplication
    public function __construct(\SimpleXMLElement $node, $parent)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

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

Loading history...
54
    {
55
        $this->parent = $parent;
56
        $this->children = new ArrayList();
57
        foreach ($node->children() as $child) {
58
            $this->children->append(Factory::create($child, $this));
59
        }
60
        $this->initDisplayAttributes($node);
61
        $this->initAffixesAttributes($node);
62
        $this->initDelimiterAttributes($node);
63
    }
64
65
    /**
66
     * @param $data
67
     * @param int|null $citationNumber
68
     * @return string
69
     */
70
    public function render($data, $citationNumber = null)
71
    {
72
        //$text = '';
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
73
        $textParts = array();
74
        $terms = $variables = $haveVariables = $elementCount = 0;
75
        foreach ($this->children as $child) {
76
            $elementCount++;
77
            if (($child instanceof Text) &&
78
                ($child->getSource() == 'term' ||
79
                    $child->getSource() == 'value' )) {
80
                $terms++;
81
            }
82
            if (($child instanceof Label)) {
83
                ++$terms;
84
            }
85
            if (method_exists($child, "getSource") && $child->getSource() == 'variable' &&
86
                !empty($child->getVariable()) &&
87
                !empty($data->{$child->getVariable()})
88
            ) {
89
                ++$variables;
90
            }
91
            $text = $child->render($data, $citationNumber);
92
            $delimiter = $this->delimiter;
93
            if (!empty($text)) {
94
                if ($delimiter && ($elementCount < count($this->children))) {
95
                    //check to see if the delimiter is already the last character of the text string
96
                    //if so, remove it so we don't have two of them when we paste together the group
97
                    $stext = strip_tags(trim($text));
98
                    if ((strrpos($stext, $delimiter[0]) + 1) == strlen($stext) && strlen($stext) > 1) {
99
                        $text = str_replace($stext, '----REPLACE----', $text);
100
                        $stext = substr($stext, 0, -1);
101
                        $text = str_replace('----REPLACE----', $stext, $text);
102
                    }
103
                }
104
                //give the text parts a name
105
                if($child instanceof Text) {
106
                    $textParts[$child->getVariable()] = $text;
107
                } else {
108
                    $textParts[$elementCount] = $text;
109
                }
110
111
112
                if (method_exists($child, "getSource") && $child->getSource() == 'variable' || (method_exists($child, "getVariable") && !empty($child->getVariable()))) {
113
                    $haveVariables++;
114
                }
115
116
                if (method_exists($child, "getSource") && $child->getSource() == 'macro') {
117
                    $haveVariables++;
118
                }
119
            }
120
        }
121
        if (empty($textParts)) {
122
            return "";
123
        }
124
        if ($variables && !$haveVariables) {
125
            return ""; // there has to be at least one other none empty value before the term is output
126
        }
127
128
        if (count($textParts) == $terms) {
129
            return ""; // there has to be at least one other none empty value before the term is output
130
        }
131
132
        //$text = implode($delimiter, $textParts); // insert the delimiter if supplied.
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
133
        $text = implode($this->delimiter, $textParts);
134
        if (!empty($text)) {
135
            return $this->wrapDisplayBlock($this->addAffixes(($text)));
136
        }
137
138
        return "";
139
                /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
140
                $arr = new ArrayList();
141
                $i = 0;
142
143
                 cs:group implicitly acts as a conditional: cs:group and its child elements are suppressed if a) at least
144
                one rendering element in cs:group calls a variable (either directly or via a macro), and b) all variables
145
                that are called are empty. This accommodates descriptive cs:text elements.
146
147
                $suppressConditionA = false;
148
                /** @var RenderingInterface $child /
149
                foreach ($this->children as $child) {
150
151
                    $res = $child->render($data, $citationNumber);
152
                    $this->getChildsAffixesAndDelimiter($child);
153
154
                    if ($this->doesRenderingElementCallsVariable($child)) {
155
                        //$arr[] = $res;
156
                        $arr->add(get_class($child).$i, $res);
157
                        $suppressConditionA = true;
158
                    } else {
159
                        $arr[$i] = $res;
160
                    }
161
                    ++$i;
162
                }
163
164
                $suppressConditionB = null;
165
166
                if ($suppressConditionA) {
167
                    foreach ($arr as $key => $value) {
168
                        if (is_null($suppressConditionB)) {
169
                            $suppressConditionB = true;
170
                        }
171
                        if (!is_numeric($key)) {
172
                            $suppressConditionB = $suppressConditionB && empty($value);
173
                        }
174
                        if (!$suppressConditionB) {
175
                            break;
176
                        }
177
                    }
178
                }
179
180
                if ($suppressConditionA && !is_null($suppressConditionB) && $suppressConditionB === true) {
181
                    return "";
182
                }
183
184
185
                if (!empty($arr)) {
186
                    $res = $this->wrapDisplayBlock($this->addAffixes(implode($this->delimiter, $arr->toArray())));
187
                    $res = $this->removeConsecutiveChars($res);
188
                    return $res;
189
                }
190
                return "";
191
                */
192
    }
193
194
195
    private function doesRenderingElementCallsVariable($child)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
196
    {
197
        if ($child instanceof Text) {
198
            if ($child->rendersVariable()) {
199
                return true;
200
            }
201
            return false;
202
        }
203
        if (in_array(get_class($child), self::$suppressableElements)) {
204
205
            return true;
206
        }
207
        return false;
208
    }
209
210
    /**
211
     * @return mixed
212
     */
213
    public function getParent()
214
    {
215
        return $this->parent;
216
    }
217
}
0 ignored issues
show
Coding Style introduced by
As per coding style, files should not end with a newline character.

This check marks files that end in a newline character, i.e. an empy line.

Loading history...
218