Label   B
last analyzed

Complexity

Total Complexity 52

Size/Duplication

Total Lines 236
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 110
dl 0
loc 236
rs 7.44
c 1
b 0
f 0
wmc 52

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 20 5
A setVariable() 0 3 1
B evaluateStringPluralism() 0 23 11
B getPlural() 0 28 10
A formatting() 0 12 3
A setForm() 0 3 1
C render() 0 43 16
A getForm() 0 3 1
A defaultPlural() 0 14 4

How to fix   Complexity   

Complex Class

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.

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