Passed
Push — feature/issue-111-php80-compat... ( 179440 )
by Sebastian
05:37
created

Label::getPlural()   B

Complexity

Conditions 10
Paths 12

Size

Total Lines 28
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 10.1167

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 21
c 1
b 0
f 0
nc 12
nop 3
dl 0
loc 28
ccs 17
cts 19
cp 0.8947
crap 10.1167
rs 7.6666

How to fix   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
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 62
    public function __construct(SimpleXMLElement $node)
63
    {
64
        /** @var SimpleXMLElement $attribute */
65 62
        foreach ($node->attributes() as $attribute) {
66 61
            switch ($attribute->getName()) {
67 61
                case "variable":
68 47
                    $this->variable = (string) $attribute;
69 47
                    break;
70 58
                case "form":
71 56
                    $this->form = (string) $attribute;
72 56
                    break;
73 56
                case "plural":
74 5
                    $this->plural = (string) $attribute;
75 5
                    break;
76
            }
77
        }
78
79 62
        $this->initFormattingAttributes($node);
80 62
        $this->initAffixesAttributes($node);
81 62
        $this->initTextCaseAttributes($node);
82 62
    }
83
84
    /**
85
     * @param stdClass $data
86
     * @param int|null $citationNumber
87
     * @return string
88
     */
89 46
    public function render($data, $citationNumber = null)
90
    {
91 46
        $lang = (isset($data->language) && $data->language != 'en') ? $data->language : 'en';
92
93 46
        $text = '';
94 46
        $variables = explode(' ', $this->variable);
95 46
        $form = !empty($this->form) ? $this->form : 'long';
96 46
        $plural = $this->defaultPlural();
97
98 46
        if ($this->variable === "editortranslator") {
99 1
            if (isset($data->editor) && isset($data->translator)) {
100 1
                $plural = $this->getPlural($data, $plural, "editortranslator");
101 1
                $term = CiteProc::getContext()->getLocale()->filter('terms', "editortranslator", $form);
102 1
                $pluralForm = $term->{$plural};
103 1
                if (!empty($pluralForm)) {
104 1
                    $text = $pluralForm;
105
                }
106
            }
107 45
        } elseif ($this->variable === "locator") {
108 7
            $citationItem = CiteProc::getContext()->getCitationItemById($data->id);
109 7
            if (!empty($citationItem->label)) {
110 4
                $plural = $this->evaluateStringPluralism($citationItem->locator, $citationItem->label);
111 4
                $term = CiteProc::getContext()->getLocale()->filter('terms', $citationItem->label, $form);
112 4
                $pluralForm = $term->{$plural} ?? "";
113 4
                if (!empty($citationItem->locator) && !empty($pluralForm)) {
114 7
                    $text = $pluralForm;
115
                }
116
            }
117
        } else {
118 40
            foreach ($variables as $variable) {
119 40
                if (isset($data->{$variable})) {
120 37
                    $plural = $this->getPlural($data, $plural, $variable);
121 37
                    $term = CiteProc::getContext()->getLocale()->filter('terms', $variable, $form);
122 37
                    $pluralForm = $term->{$plural} ?? "";
123 37
                    if (!empty($data->{$variable}) && !empty($pluralForm)) {
124 13
                        $text = $pluralForm;
125 13
                        break;
126
                    }
127
                }
128
            }
129
        }
130
131 46
        return $this->formatting($text, $lang);
132
    }
133
134
    /**
135
     * @param string $str
136
     * @param string $variable
137
     * @return string
138
     */
139 13
    private function evaluateStringPluralism($str, $variable)
140
    {
141 13
        $plural = 'single';
142 13
        if (!empty($str)) {
143 12
            switch ($variable) {
144 12
                case 'page':
145 4
                case 'chapter':
146 2
                case 'folio':
147 11
                    $pageRegex = "/([a-zA-Z]*)([0-9]+)\s*(?:–|-)\s*([a-zA-Z]*)([0-9]+)/";
148 11
                    $err = preg_match($pageRegex, $str, $m);
149 11
                    if ($err !== false && count($m) == 0) {
150 3
                        $plural = 'single';
151 9
                    } elseif ($err !== false && count($m)) {
152 9
                        $plural = 'multiple';
153
                    }
154 11
                    break;
155
                default:
156 1
                    if (is_numeric($str)) {
157
                        return $str > 1 ? 'multiple' : 'single';
158
                    }
159
            }
160
        }
161 13
        return $plural;
162
    }
163
164
    /**
165
     * @param string $variable
166
     */
167 33
    public function setVariable($variable)
168
    {
169 33
        $this->variable = $variable;
170 33
    }
171
172
    /**
173
     * @param $data
174
     * @param $plural
175
     * @param $variable
176
     * @return string
177
     */
178 38
    protected function getPlural($data, $plural, $variable)
179
    {
180
181 38
        if ($variable === "editortranslator" && isset($data->editor)) {
182 1
            $var = $data->editor;
183
        } else {
184 37
            $var = $data->{$variable};
185
        }
186 38
        if (((!isset($this->plural) || empty($plural))) && !empty($var)) {
187 37
            if (is_array($var)) {
188 33
                $count = count($var);
189 33
                if ($count == 1) {
190 25
                    $plural = 'single';
191 25
                    return $plural;
192 12
                } elseif ($count > 1) {
193 12
                    $plural = 'multiple';
194 12
                    return $plural;
195
                }
196
                return $plural;
197
            } else {
198 8
                return $this->evaluateStringPluralism($data->{$variable}, $variable);
199
            }
200
        } else {
201 1
            if ($this->plural != "always") {
202 1
                $plural = $this->evaluateStringPluralism($data->{$variable}, $variable);
203 1
                return $plural;
204
            }
205
            return $plural;
206
        }
207
    }
208
209
    /**
210
     * @return string
211
     */
212 32
    public function getForm()
213
    {
214 32
        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 46
    protected function formatting($text, $lang)
231
    {
232 46
        if (empty($text)) {
233 35
            return "";
234
        }
235 18
        if ($this->stripPeriods) {
236
            $text = str_replace('.', '', $text);
237
        }
238
239 18
        $text = preg_replace("/\s&\s/", " &#38; ", $text); //replace ampersands by html entity
240 18
        $text = $this->format($this->applyTextCase($text, $lang));
241 18
        return $this->addAffixes($text);
242
    }
243
244
    /**
245
     * @return string
246
     */
247 46
    protected function defaultPlural()
248
    {
249 46
        $plural = "";
250 46
        switch ($this->plural) {
251 46
            case 'never':
252
                $plural = 'single';
253
                break;
254 46
            case 'always':
255
                $plural = 'multiple';
256
                break;
257 46
            case 'contextual':
258
            default:
259
        }
260 46
        return $plural;
261
    }
262
}
263