Passed
Push — develop ( e162a8...209be3 )
by Sebastian
14:13 queued 09:03
created

Label::render()   C

Complexity

Conditions 16
Paths 80

Size

Total Lines 43
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 16

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 16
eloc 30
nc 80
nop 2
dl 0
loc 43
ccs 30
cts 30
cp 1
crap 16
rs 5.5666
c 1
b 0
f 0

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