Completed
Push — master ( e09500...86ebd4 )
by Sebastian
02:59
created

Label   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 229
Duplicated Lines 5.68 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 2
Bugs 1 Features 0
Metric Value
dl 13
loc 229
rs 8.3673
c 2
b 1
f 0
wmc 45
lcom 1
cbo 6

9 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 13 21 5
C render() 0 35 12
C evaluateStringPluralism() 0 23 9
A setVariable() 0 4 1
D getPlural() 0 31 9
A getForm() 0 4 1
A setForm() 0 4 1
A formatting() 0 13 3
A defaultPlural() 0 15 4

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Label often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Label, and based on these observations, apply Extract Interface, too.

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\CiteProc;
12
use Seboettg\CiteProc\Styles\AffixesTrait;
13
use Seboettg\CiteProc\Styles\FormattingTrait;
14
use Seboettg\CiteProc\Styles\TextCaseTrait;
15
16
17
/**
18
 * Class Label
19
 * @package Seboettg\CiteProc\Rendering
20
 *
21
 * @author Sebastian Böttger <[email protected]>
22
 */
23
class Label implements RenderingInterface
24
{
25
    use AffixesTrait,
26
        FormattingTrait,
27
        TextCaseTrait;
28
29
    private $variable;
30
31
    /**
32
     * Selects the form of the term, with allowed values:
33
     *
34
     *   - “long” - (default), e.g. “page”/”pages” for the “page” term
35
     *   - “short” - e.g. “p.”/”pp.” for the “page” term
36
     *   - “symbol” - e.g. “§”/”§§” for the “section” term
37
     *
38
     * @var string
39
     */
40
    private $form = "";
41
42
    /**
43
     * Sets pluralization of the term, with allowed values:
44
     *
45
     *   - “contextual” - (default), the term plurality matches that of the variable content. Content is considered
46
     *     plural when it contains multiple numbers (e.g. “page 1”, “pages 1-3”, “volume 2”, “volumes 2 & 4”), or, in
47
     *     the case of the “number-of-pages” and “number-of-volumes” variables, when the number is higher than 1
48
     *     (“1 volume” and “3 volumes”).
49
     *   - “always” - always use the plural form, e.g. “pages 1” and “pages 1-3”
50
     *   - “never” - always use the singular form, e.g. “page 1” and “page 1-3”
51
     *
52
     * @var string
53
     */
54
    private $plural = "contextual";
55
56
    /**
57
     * Label constructor.
58
     * @param \SimpleXMLElement $node
59
     */
60
    public function __construct(\SimpleXMLElement $node)
61
    {
62
        /** @var \SimpleXMLElement $attribute */
63 View Code Duplication
        foreach ($node->attributes() as $attribute) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
64
            switch ($attribute->getName()) {
65
                case "variable":
66
                    $this->variable = (string) $attribute;
67
                    break;
68
                case "form":
69
                    $this->form = (string) $attribute;
70
                    break;
71
                case "plural":
72
                    $this->plural = (string) $attribute;
73
                    break;
74
            }
75
        }
76
77
        $this->initFormattingAttributes($node);
78
        $this->initAffixesAttributes($node);
79
        $this->initTextCaseAttributes($node);
80
    }
81
82
    /**
83
     * @param \stdClass $data
84
     * @param int|null $citationNumber
85
     * @return string
86
     */
87
    public function render($data, $citationNumber = null)
88
    {
89
        $lang = (isset($data->language) && $data->language != 'en') ? $data->language : 'en';
90
91
        $text = '';
92
        $variables = explode(' ', $this->variable);
93
        $form = !empty($this->form) ? $this->form : 'long';
94
        $plural = $this->defaultPlural();
95
96
        if ($this->variable === "editortranslator") {
97
            if (isset($data->editor) && isset($data->translator)) {
98
                $plural = $this->getPlural($data, $plural, "editortranslator");
99
                $term = CiteProc::getContext()->getLocale()->filter('terms', "editortranslator", $form);
100
                $pluralForm = $term->{$plural};
101
                if (!empty($pluralForm)) {
102
                    $text = $pluralForm;
103
                }
104
            }
105
        } else {
106
            foreach ($variables as $variable) {
107
108
                if (isset($data->{$variable})) {
109
                    $plural = $this->getPlural($data, $plural, $variable);
110
                    $term = CiteProc::getContext()->getLocale()->filter('terms', $variable, $form);
111
                    $pluralForm = $term->{$plural};
112
                    if (!empty($data->{$variable}) && !empty($pluralForm)) {
113
                        $text = $pluralForm;
114
                        break;
115
                    }
116
                }
117
            }
118
        }
119
120
        return $this->formatting($text, $lang);
121
    }
122
123
    /**
124
     * @param $data
125
     * @param $variable
126
     * @return string
127
     */
128
    private function evaluateStringPluralism($data, $variable)
129
    {
130
        $str = $data->{$variable};
131
        $plural = 'single';
132
        if (!empty($str)) {
133
            switch ($variable) {
134
                case 'page':
135
                    $pageRegex = "/([a-zA-Z]*)([0-9]+)\s*(?:–|-)\s*([a-zA-Z]*)([0-9]+)/";
136
                    $err = preg_match($pageRegex, $str, $m);
137
                    if ($err !== false && count($m) == 0) {
138
                        $plural = 'single';
139
                    } elseif ($err !== false && count($m)) {
140
                        $plural = 'multiple';
141
                    }
142
                    break;
143
                default:
144
                    if (is_numeric($str)) {
145
                        return $str > 1 ? 'multiple' : 'single';
146
                    }
147
            }
148
        }
149
        return $plural;
150
    }
151
152
    /**
153
     * @param string $variable
154
     */
155
    public function setVariable($variable)
156
    {
157
        $this->variable = $variable;
158
    }
159
160
    /**
161
     * @param $data
162
     * @param $plural
163
     * @param $variable
164
     * @return string
165
     */
166
    protected function getPlural($data, $plural, $variable)
167
    {
168
169
        if ($variable === "editortranslator") {
170
            $var = $data->editor;
171
        } else {
172
            $var = $data->{$variable};
173
        }
174
        if (((!isset($this->plural) || empty($plural))) && !empty($var)) {
175
            if (is_array($var)) {
176
                $count = count($var);
177
                if ($count == 1) {
178
                    $plural = 'single';
179
                    return $plural;
180
                } elseif ($count > 1) {
181
                    $plural = 'multiple';
182
                    return $plural;
183
                }
184
                return $plural;
185
            } else {
186
                return $this->evaluateStringPluralism($data, $variable);
187
            }
188
189
        } else {
190
            if ($this->plural != "always") {
191
                $plural = $this->evaluateStringPluralism($data, $variable);
192
                return $plural;
193
            }
194
            return $plural;
195
        }
196
    }
197
198
    /**
199
     * @return string
200
     */
201
    public function getForm()
202
    {
203
        return $this->form;
204
    }
205
206
    /**
207
     * @param string $form
208
     */
209
    public function setForm($form)
210
    {
211
        $this->form = $form;
212
    }
213
214
    /**
215
     * @param $text
216
     * @param $lang
217
     * @return string
218
     */
219
    protected function formatting($text, $lang)
220
    {
221
        if (empty($text)) {
222
            return "";
223
        }
224
        if ($this->stripPeriods) {
225
            $text = str_replace('.', '', $text);
226
        }
227
228
        $text = preg_replace("/\s\&\s/", " &#38; ", $text); //replace ampersands by html entity
229
        $text = $this->format($this->applyTextCase($text, $lang));
230
        return $this->addAffixes($text);
231
    }
232
233
    /**
234
     * @return string
235
     */
236
    protected function defaultPlural()
237
    {
238
        $plural = "";
239
        switch ($this->plural) {
240
            case 'never':
241
                $plural = 'single';
242
                break;
243
            case 'always':
244
                $plural = 'multiple';
245
                break;
246
            case 'contextual':
247
            default:
248
        }
249
        return $plural;
250
    }
251
}