Passed
Push — feature/locators-issue-82 ( f7cde7...464c3c )
by Sebastian
04:57
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 56
    public function __construct(SimpleXMLElement $node)
63
    {
64
        /** @var SimpleXMLElement $attribute */
65 56
        foreach ($node->attributes() as $attribute) {
66 55
            switch ($attribute->getName()) {
67 55
                case "variable":
68 43
                    $this->variable = (string) $attribute;
69 43
                    break;
70 52
                case "form":
71 51
                    $this->form = (string) $attribute;
72 51
                    break;
73 50
                case "plural":
74 4
                    $this->plural = (string) $attribute;
75 55
                    break;
76
            }
77
        }
78
79 56
        $this->initFormattingAttributes($node);
80 56
        $this->initAffixesAttributes($node);
81 56
        $this->initTextCaseAttributes($node);
82 56
    }
83
84
    /**
85
     * @param stdClass $data
86
     * @param int|null $citationNumber
87
     * @return string
88
     */
89 42
    public function render($data, $citationNumber = null)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$citationNumber" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$citationNumber"; expected 0 but found 1
Loading history...
90
    {
91 42
        $lang = (isset($data->language) && $data->language != 'en') ? $data->language : 'en';
92
93 42
        $text = '';
94 42
        $variables = explode(' ', $this->variable);
95 42
        $form = !empty($this->form) ? $this->form : 'long';
96 42
        $plural = $this->defaultPlural();
97
98 42
        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 41
        } elseif ($this->variable === "locator") {
108 5
            $citationItem = CiteProc::getContext()->getCitationItemById($data->id);
109 5
            if (!empty($citationItem->label)) {
110 3
                $plural = $this->evaluateStringPluralism($citationItem->locator, $citationItem->label);
111 3
                $term = CiteProc::getContext()->getLocale()->filter('terms', $citationItem->label, $form);
112 3
                $pluralForm = $term->{$plural};
113 3
                if (!empty($citationItem->locator) && !empty($pluralForm)) {
114 5
                    $text = $pluralForm;
115
                }
116
            }
117
        } else {
118 37
            foreach ($variables as $variable) {
119 37
                if (isset($data->{$variable})) {
120 34
                    $plural = $this->getPlural($data, $plural, $variable);
121 34
                    $term = CiteProc::getContext()->getLocale()->filter('terms', $variable, $form);
122 34
                    $pluralForm = $term->{$plural};
123 34
                    if (!empty($data->{$variable}) && !empty($pluralForm)) {
124 12
                        $text = $pluralForm;
125 37
                        break;
126
                    }
127
                }
128
            }
129
        }
130
131 42
        return $this->formatting($text, $lang);
132
    }
133
134
    /**
135
     * @param string $str
136
     * @param string $variable
137
     * @return string
138
     */
139 11
    private function evaluateStringPluralism($str, $variable)
140
    {
141 11
        $plural = 'single';
142 11
        if (!empty($str)) {
143
            switch ($variable) {
144 10
                case 'page':
145 3
                case 'chapter':
146 1
                case 'folio':
147 10
                    $pageRegex = "/([a-zA-Z]*)([0-9]+)\s*(?:–|-)\s*([a-zA-Z]*)([0-9]+)/";
148 10
                    $err = preg_match($pageRegex, $str, $m);
149 10
                    if ($err !== false && count($m) == 0) {
150 2
                        $plural = 'single';
151 8
                    } elseif ($err !== false && count($m)) {
152 8
                        $plural = 'multiple';
153
                    }
154 10
                    break;
155
                default:
156
                    if (is_numeric($str)) {
157
                        return $str > 1 ? 'multiple' : 'single';
158
                    }
159
            }
160
        }
161 11
        return $plural;
162
    }
163
164
    /**
165
     * @param string $variable
166
     */
167 30
    public function setVariable($variable)
168
    {
169 30
        $this->variable = $variable;
170 30
    }
171
172
    /**
173
     * @param $data
174
     * @param $plural
175
     * @param $variable
176
     * @return string
177
     */
178 35
    protected function getPlural($data, $plural, $variable)
179
    {
180
181 35
        if ($variable === "editortranslator" && isset($data->editor)) {
182 1
            $var = $data->editor;
183
        } else {
184 34
            $var = $data->{$variable};
185
        }
186 35
        if (((!isset($this->plural) || empty($plural))) && !empty($var)) {
187 34
            if (is_array($var)) {
188 30
                $count = count($var);
189 30
                if ($count == 1) {
190 22
                    $plural = 'single';
191 22
                    return $plural;
192 11
                } elseif ($count > 1) {
193 11
                    $plural = 'multiple';
194 11
                    return $plural;
195
                }
196
                return $plural;
197
            } else {
198 7
                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 29
    public function getForm()
213
    {
214 29
        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 42
    protected function formatting($text, $lang)
231
    {
232 42
        if (empty($text)) {
233 32
            return "";
234
        }
235 16
        if ($this->stripPeriods) {
236
            $text = str_replace('.', '', $text);
237
        }
238
239 16
        $text = preg_replace("/\s&\s/", " &#38; ", $text); //replace ampersands by html entity
240 16
        $text = $this->format($this->applyTextCase($text, $lang));
241 16
        return $this->addAffixes($text);
242
    }
243
244
    /**
245
     * @return string
246
     */
247 42
    protected function defaultPlural()
248
    {
249 42
        $plural = "";
250 42
        switch ($this->plural) {
251 42
            case 'never':
252
                $plural = 'single';
253
                break;
254 42
            case 'always':
255
                $plural = 'multiple';
256
                break;
257 42
            case 'contextual':
258
            default:
259
        }
260 42
        return $plural;
261
    }
262
}
263