Passed
Push — feature/locators-issue-82 ( f7cde7...464c3c )
by Sebastian
04:57
created

Label::defaultPlural()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 5.1576

Importance

Changes 0
Metric Value
cc 4
eloc 11
nc 4
nop 0
dl 0
loc 14
ccs 7
cts 12
cp 0.5833
crap 5.1576
rs 9.9
c 0
b 0
f 0
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