Passed
Push — master ( dcb940...49cd7f )
by Sebastian
14:22 queued 12:58
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 63
    public function __construct(SimpleXMLElement $node)
63
    {
64
        /** @var SimpleXMLElement $attribute */
65 63
        foreach ($node->attributes() as $attribute) {
66 62
            switch ($attribute->getName()) {
67 62
                case "variable":
68 48
                    $this->variable = (string) $attribute;
69 48
                    break;
70 59
                case "form":
71 57
                    $this->form = (string) $attribute;
72 57
                    break;
73 57
                case "plural":
74 5
                    $this->plural = (string) $attribute;
75 5
                    break;
76
            }
77
        }
78
79 63
        $this->initFormattingAttributes($node);
80 63
        $this->initAffixesAttributes($node);
81 63
        $this->initTextCaseAttributes($node);
82 63
    }
83
84
    /**
85
     * @param stdClass $data
86
     * @param int|null $citationNumber
87
     * @return string
88
     */
89 47
    public function render($data, $citationNumber = null)
90
    {
91 47
        $lang = (isset($data->language) && $data->language != 'en') ? $data->language : 'en';
92
93 47
        $text = '';
94 47
        $variables = explode(' ', $this->variable);
95 47
        $form = !empty($this->form) ? $this->form : 'long';
96 47
        $plural = $this->defaultPlural();
97
98 47
        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 46
        } 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 41
            foreach ($variables as $variable) {
119 41
                if (isset($data->{$variable})) {
120 38
                    $plural = $this->getPlural($data, $plural, $variable);
121 38
                    $term = CiteProc::getContext()->getLocale()->filter('terms', $variable, $form);
122 38
                    $pluralForm = $term->{$plural} ?? "";
123 38
                    if (!empty($data->{$variable}) && !empty($pluralForm)) {
124 13
                        $text = $pluralForm;
125 13
                        break;
126
                    }
127
                }
128
            }
129
        }
130
131 47
        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 34
    public function setVariable($variable)
168
    {
169 34
        $this->variable = $variable;
170 34
    }
171
172
    /**
173
     * @param $data
174
     * @param $plural
175
     * @param $variable
176
     * @return string
177
     */
178 39
    protected function getPlural($data, $plural, $variable)
179
    {
180
181 39
        if ($variable === "editortranslator" && isset($data->editor)) {
182 1
            $var = $data->editor;
183
        } else {
184 38
            $var = $data->{$variable};
185
        }
186 39
        if (((!isset($this->plural) || empty($plural))) && !empty($var)) {
187 38
            if (is_array($var)) {
188 34
                $count = count($var);
189 34
                if ($count == 1) {
190 26
                    $plural = 'single';
191 26
                    return $plural;
192 13
                } elseif ($count > 1) {
193 13
                    $plural = 'multiple';
194 13
                    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 33
    public function getForm()
213
    {
214 33
        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 47
    protected function formatting($text, $lang)
231
    {
232 47
        if (empty($text)) {
233 36
            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 47
    protected function defaultPlural()
248
    {
249 47
        $plural = "";
250 47
        switch ($this->plural) {
251 47
            case 'never':
252
                $plural = 'single';
253
                break;
254 47
            case 'always':
255
                $plural = 'multiple';
256
                break;
257 47
            case 'contextual':
258
            default:
259
        }
260 47
        return $plural;
261
    }
262
}
263