Passed
Push — develop ( e162a8...209be3 )
by Sebastian
14:13 queued 09:03
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 71
    public function __construct(SimpleXMLElement $node)
63
    {
64
        /** @var SimpleXMLElement $attribute */
65 71
        foreach ($node->attributes() as $attribute) {
66 70
            switch ($attribute->getName()) {
67 70
                case "variable":
68 52
                    $this->variable = (string) $attribute;
69 52
                    break;
70 67
                case "form":
71 65
                    $this->form = (string) $attribute;
72 65
                    break;
73 65
                case "plural":
74 5
                    $this->plural = (string) $attribute;
75 5
                    break;
76
            }
77
        }
78
79 71
        $this->initFormattingAttributes($node);
80 71
        $this->initAffixesAttributes($node);
81 71
        $this->initTextCaseAttributes($node);
82 71
    }
83
84
    /**
85
     * @param stdClass $data
86
     * @param int|null $citationNumber
87
     * @return string
88
     */
89 52
    public function render($data, $citationNumber = null)
90
    {
91 52
        $lang = (isset($data->language) && $data->language != 'en') ? $data->language : 'en';
92
93 52
        $text = '';
94 52
        $variables = explode(' ', $this->variable);
95 52
        $form = !empty($this->form) ? $this->form : 'long';
96 52
        $plural = $this->defaultPlural();
97
98 52
        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 51
        } 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 46
            foreach ($variables as $variable) {
119 46
                if (isset($data->{$variable})) {
120 42
                    $plural = $this->getPlural($data, $plural, $variable);
121 42
                    $term = CiteProc::getContext()->getLocale()->filter('terms', $variable, $form);
122 42
                    $pluralForm = $term->{$plural} ?? "";
123 42
                    if (!empty($data->{$variable}) && !empty($pluralForm)) {
124 16
                        $text = $pluralForm;
125 16
                        break;
126
                    }
127
                }
128
            }
129
        }
130
131 52
        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 38
    public function setVariable($variable)
168
    {
169 38
        $this->variable = $variable;
170 38
    }
171
172
    /**
173
     * @param $data
174
     * @param $plural
175
     * @param $variable
176
     * @return string
177
     */
178 43
    protected function getPlural($data, $plural, $variable)
179
    {
180
181 43
        if ($variable === "editortranslator" && isset($data->editor)) {
182 1
            $var = $data->editor;
183
        } else {
184 42
            $var = $data->{$variable};
185
        }
186 43
        if (((!isset($this->plural) || empty($plural))) && !empty($var)) {
187 42
            if (is_array($var)) {
188 38
                $count = count($var);
189 38
                if ($count == 1) {
190 28
                    $plural = 'single';
191 28
                    return $plural;
192 15
                } elseif ($count > 1) {
193 15
                    $plural = 'multiple';
194 15
                    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
    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 52
    protected function formatting($text, $lang)
231
    {
232 52
        if (empty($text)) {
233 38
            return "";
234
        }
235 21
        if ($this->stripPeriods) {
236
            $text = str_replace('.', '', $text);
237
        }
238
239 21
        $text = preg_replace("/\s&\s/", " &#38; ", $text); //replace ampersands by html entity
240 21
        $text = $this->format($this->applyTextCase($text, $lang));
241 21
        return $this->addAffixes($text);
242
    }
243
244
    /**
245
     * @return string
246
     */
247 52
    protected function defaultPlural()
248
    {
249 52
        $plural = "";
250 52
        switch ($this->plural) {
251 52
            case 'never':
252
                $plural = 'single';
253
                break;
254 52
            case 'always':
255
                $plural = 'multiple';
256
                break;
257 52
            case 'contextual':
258
            default:
259
        }
260 52
        return $plural;
261
    }
262
}
263