Passed
Push — new-api ( 34a0a9...30b18d )
by Sebastian
04:06
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 0
Metric Value
cc 10
eloc 21
c 0
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\Label;
11
12
use Seboettg\CiteProc\CiteProc;
13
use Seboettg\CiteProc\Locale\Locale;
14
use Seboettg\CiteProc\Locale\TermForm;
15
use Seboettg\CiteProc\Rendering\Rendering;
16
use Seboettg\CiteProc\Styles\FormattingTrait;
17
use Seboettg\CiteProc\Styles\StylesRenderer;
18
use SimpleXMLElement;
19
use stdClass;
20
21
/**
22
 * Class Label
23
 * @package Seboettg\CiteProc\Rendering
24
 *
25
 * @author Sebastian Böttger <[email protected]>
26
 */
27
class Label implements Rendering
28
{
29
    use FormattingTrait;
30
31
    private $variable;
32
33
    /** @var TermForm  */
34
    private $form;
35
36
    /** @var Plural */
37
    private $plural;
38
39
    /** @var Locale */
40
    private $locale;
41
42
    /** @var StylesRenderer */
43
    private $stylesRenderer;
44
45 60
    public static function factory(SimpleXMLElement $node)
46
    {
47 60
        $variable = $form = $plural = null;
48 60
        $context = CiteProc::getContext();
49
50 60
        foreach ($node->attributes() as $attribute) {
51 59
            switch ($attribute->getName()) {
52 59
                case "variable":
53 46
                    $variable = (string) $attribute;
54 46
                    break;
55 56
                case "form":
56 54
                    $form = new TermForm((string) $attribute);
57 54
                    break;
58 54
                case "plural":
59 4
                    $plural = new Plural((string) $attribute);
60 59
                    break;
61
            }
62
        }
63 60
        $locale = $context->getLocale();
64 60
        $stylesRenderer = StylesRenderer::factory($node);
65 60
        return new self($variable, $form, $plural, $stylesRenderer, $locale);
66
    }
67
68
69
    /**
70
     * Label constructor.
71
     * @param string|null $variable
72
     * @param TermForm|null $form
73
     * @param Plural|null $plural
74
     * @param StylesRenderer $stylesRenderer
75
     * @param Locale $locale
76
     */
77 60
    public function __construct(
78
        ?string $variable,
79
        ?TermForm $form,
80
        ?Plural $plural,
81
        StylesRenderer $stylesRenderer,
82
        Locale $locale
83
    ) {
84 60
        $this->variable = $variable;
85 60
        $this->form = $form;
86 60
        $this->plural = $plural;
87 60
        $this->stylesRenderer = $stylesRenderer;
88 60
        $this->locale = $locale;
89 60
    }
90
91
    /**
92
     * @param stdClass $data
93
     * @param int|null $citationNumber
94
     * @return string
95
     */
96 45
    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...
97
    {
98 45
        $lang = (isset($data->language) && $data->language != 'en') ? $data->language : 'en';
99 45
        $this->stylesRenderer->getTextCase()->setLanguage($lang);
100 45
        $text = '';
101 45
        $variables = explode(' ', $this->variable);
102 45
        $form = !empty($this->form) ? $this->form : 'long';
103 45
        $plural = $this->defaultPlural();
104
105 45
        if ($this->variable === "editortranslator") {
106 1
            if (isset($data->editor) && isset($data->translator)) {
107 1
                $plural = $this->getPlural($data, $plural, "editortranslator");
108 1
                $term = CiteProc::getContext()->getLocale()->filter('terms', "editortranslator", $form);
109 1
                $pluralForm = $term->{$plural};
110 1
                if (!empty($pluralForm)) {
111 1
                    $text = $pluralForm;
112
                }
113
            }
114 44
        } elseif ($this->variable === "locator") {
115 7
            $citationItem = CiteProc::getContext()->getCitationItemById($data->id);
116 7
            if (!empty($citationItem->label)) {
117 4
                $plural = $this->evaluateStringPluralism($citationItem->locator, $citationItem->label);
118 4
                $term = CiteProc::getContext()->getLocale()->filter('terms', $citationItem->label, $form);
119 4
                $pluralForm = $term->{$plural} ?? "";
120 4
                if (!empty($citationItem->locator) && !empty($pluralForm)) {
121 7
                    $text = $pluralForm;
122
                }
123
            }
124
        } else {
125 39
            foreach ($variables as $variable) {
126 39
                if (isset($data->{$variable})) {
127 36
                    $plural = $this->getPlural($data, $plural, $variable);
128 36
                    $term = $this->locale->filter('terms', $variable, $form);
129 36
                    $pluralForm = $term->{$plural} ?? "";
130 36
                    if (!empty($data->{$variable}) && !empty($pluralForm)) {
131 13
                        $text = $pluralForm;
132 39
                        break;
133
                    }
134
                }
135
            }
136
        }
137
138 45
        return $this->formatting($text);
139
    }
140
141
    /**
142
     * @param string $str
143
     * @param string $variable
144
     * @return string
145
     */
146 13
    private function evaluateStringPluralism(string $str, string $variable)
147
    {
148 13
        $plural = 'single';
149 13
        if (!empty($str)) {
150
            switch ($variable) {
151 12
                case 'page':
152 4
                case 'chapter':
153 2
                case 'folio':
154 11
                    $pageRegex = "/([a-zA-Z]*)([0-9]+)\s*(?:–|-)\s*([a-zA-Z]*)([0-9]+)/";
155 11
                    $err = preg_match($pageRegex, $str, $matches);
156 11
                    if ($err !== false && count($matches) == 0) {
157 3
                        $plural = 'single';
158 9
                    } elseif ($err !== false && count($matches)) {
159 9
                        $plural = 'multiple';
160
                    }
161 11
                    break;
162
                default:
163 1
                    if (is_numeric($str)) {
164
                        return $str > 1 ? 'multiple' : 'single';
165
                    }
166
            }
167
        }
168 13
        return $plural;
169
    }
170
171
    /**
172
     * @param string $variable
173
     */
174 32
    public function setVariable(string $variable)
175
    {
176 32
        $this->variable = $variable;
177 32
    }
178
179
    /**
180
     * @param $data
181
     * @param $plural
182
     * @param $variable
183
     * @return string
184
     */
185 37
    protected function getPlural($data, $plural, $variable)
186
    {
187
188 37
        if ($variable === "editortranslator" && isset($data->editor)) {
189 1
            $var = $data->editor;
190
        } else {
191 36
            $var = $data->{$variable};
192
        }
193 37
        if (((!isset($this->plural) || empty($plural))) && !empty($var)) {
194 36
            if (is_array($var)) {
195 32
                $count = count($var);
196 32
                if ($count == 1) {
197 24
                    $plural = 'single';
198 24
                    return $plural;
199 12
                } elseif ($count > 1) {
200 12
                    $plural = 'multiple';
201 12
                    return $plural;
202
                }
203
                return $plural;
204
            } else {
205 8
                return $this->evaluateStringPluralism($data->{$variable}, $variable);
206
            }
207
        } else {
208 1
            if ($this->plural != "always") {
0 ignored issues
show
introduced by
The condition $this->plural != 'always' is always true.
Loading history...
209 1
                $plural = $this->evaluateStringPluralism($data->{$variable}, $variable);
210 1
                return $plural;
211
            }
212
            return $plural;
213
        }
214
    }
215
216
    /**
217
     * @return string
218
     */
219 31
    public function getForm()
220
    {
221 31
        return $this->form;
222
    }
223
224
    /**
225
     * @param string $form
226
     */
227
    public function setForm(string $form)
228
    {
229
        $this->form = $form;
0 ignored issues
show
Documentation Bug introduced by
It seems like $form of type string is incompatible with the declared type Seboettg\CiteProc\Locale\TermForm of property $form.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
230
    }
231
232
    /**
233
     * @param $text
234
     * @param $lang
235
     * @return string
236
     */
237 45
    protected function formatting($text)
238
    {
239 45
        if (empty($text)) {
240 34
            return "";
241
        }
242 18
        if ($this->stripPeriods) {
243
            $text = str_replace('.', '', $text);
244
        }
245
246 18
        $text = preg_replace("/\s&\s/", " &#38; ", $text); //replace ampersands by html entity
247 18
        $text = $this->stylesRenderer->renderTextCase($text);
248 18
        $text = $this->stylesRenderer->renderFormatting($text);
249 18
        return $this->stylesRenderer->renderAffixes($text);
250
    }
251
252
    /**
253
     * @return string
254
     */
255 45
    protected function defaultPlural()
256
    {
257 45
        $plural = "";
258 45
        switch ($this->plural) {
259 45
            case 'never':
260
                $plural = 'single';
261
                break;
262 45
            case 'always':
263
                $plural = 'multiple';
264
                break;
265 45
            case 'contextual':
266
            default:
267
        }
268 45
        return $plural;
269
    }
270
}
271