Passed
Push — new-api ( 7cf340...18d26d )
by Sebastian
12:35 queued 08:17
created

Label::evaluateStringPluralism()   B

Complexity

Conditions 11
Paths 13

Size

Total Lines 23
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 11.0295

Importance

Changes 0
Metric Value
cc 11
eloc 17
c 0
b 0
f 0
nc 13
nop 2
dl 0
loc 23
ccs 15
cts 16
cp 0.9375
crap 11.0295
rs 7.3166

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
declare(strict_types=1);
3
/*
4
 * citeproc-php
5
 *
6
 * @link        http://github.com/seboettg/citeproc-php for the source repository
7
 * @copyright   Copyright (c) 2016 Sebastian Böttger.
8
 * @license     https://opensource.org/licenses/MIT
9
 */
10
11
namespace Seboettg\CiteProc\Rendering\Label;
12
13
use Seboettg\CiteProc\CiteProc;
14
use Seboettg\CiteProc\Locale\Locale;
15
use Seboettg\CiteProc\Locale\TermForm;
16
use Seboettg\CiteProc\Rendering\Observer\RenderingObserver;
17
use Seboettg\CiteProc\Rendering\Observer\RenderingObserverTrait;
18
use Seboettg\CiteProc\Rendering\Rendering;
19
use Seboettg\CiteProc\Styles\StylesRenderer;
20
use SimpleXMLElement;
21
22
/**
23
 * Class Label
24
 * @package Seboettg\CiteProc\Rendering
25
 *
26
 * @author Sebastian Böttger <[email protected]>
27
 */
28
class Label implements Rendering, RenderingObserver
29
{
30
    use RenderingObserverTrait;
31
32
    private $variable;
33
34
    private $stripPeriods;
35
36
    /** @var TermForm  */
37
    private $form;
38
39
    /** @var Plural */
40
    private $plural;
41
42
    /** @var Locale */
43
    private $locale;
44
45
    /** @var StylesRenderer */
46
    private $stylesRenderer;
47
48 63
    public static function factory(SimpleXMLElement $node): Label
49
    {
50 63
        $variable = $form = $plural = null;
51 63
        $stripPeriods = false;
52 63
        $context = CiteProc::getContext();
53
54 63
        foreach ($node->attributes() as $attribute) {
55 62
            switch ($attribute->getName()) {
56 62
                case "variable":
57 47
                    $variable = (string) $attribute;
58 47
                    break;
59 59
                case "form":
60 57
                    $form = new TermForm((string) $attribute);
61 57
                    break;
62 57
                case "plural":
63 5
                    $plural = new Plural((string) $attribute);
64 5
                    break;
65 57
                case "strip-periods":
66 62
                    $stripPeriods = (bool) $attribute;
67
            }
68
        }
69 63
        $locale = $context->getLocale();
70 63
        $stylesRenderer = StylesRenderer::factory($node);
71 63
        $label = new Label($variable, $form, $plural, $stylesRenderer, $locale, $stripPeriods);
72 63
        $context->addObserver($label);
73 63
        return $label;
74
    }
75
76
77
    /**
78
     * Label constructor.
79
     * @param string|null $variable
80
     * @param TermForm|null $form
81
     * @param Plural|null $plural
82
     * @param StylesRenderer $stylesRenderer
83
     * @param Locale $locale
84
     * @param bool $stripPeriods
85
     */
86 63
    public function __construct(
87
        ?string $variable,
88
        ?TermForm $form,
89
        ?Plural $plural,
90
        StylesRenderer $stylesRenderer,
91
        Locale $locale,
92
        bool $stripPeriods
93
    ) {
94 63
        $this->variable = $variable;
95 63
        $this->form = $form;
96 63
        $this->plural = $plural;
97 63
        $this->stylesRenderer = $stylesRenderer;
98 63
        $this->locale = $locale;
99 63
        $this->stripPeriods = $stripPeriods;
100 63
        $this->initObserver();
101 63
    }
102
103
    /**
104
     * @param $data
105
     * @param int|null $citationNumber
106
     * @return string
107
     */
108 46
    public function render($data, $citationNumber = null): string
109
    {
110 46
        $lang = (isset($data->language) && $data->language != 'en') ? $data->language : 'en';
111 46
        $this->stylesRenderer->getTextCase()->setLanguage($lang);
112 46
        $text = '';
113 46
        $variables = explode(' ', $this->variable);
114 46
        $form = !empty($this->form) ? $this->form : 'long';
115 46
        $plural = $this->defaultPlural();
116
117 46
        if ($this->variable === "editortranslator") {
118 1
            if (isset($data->editor) && isset($data->translator)) {
119 1
                $plural = $this->getPlural($data, $plural, "editortranslator");
120 1
                $term = $this->locale->filter('terms', "editortranslator", (string)$form);
121 1
                $pluralForm = $term->{$plural};
122 1
                if (!empty($pluralForm)) {
123 1
                    $text = $pluralForm;
124
                }
125
            }
126 45
        } elseif ($this->variable === "locator") {
127 7
            $id = $data->id;
128
            $citationItem = $this->citationItems->filter(function ($item) use ($id) {
129 6
                return $item->id === $id;
130 7
            })->current();
131 7
            if (!empty($citationItem->label)) {
132 4
                $plural = $this->evaluateStringPluralism($citationItem->locator, $citationItem->label);
133 4
                $term = $this->locale->filter('terms', $citationItem->label, (string)$form);
134 4
                $pluralForm = $term->{$plural} ?? "";
135 4
                if (!empty($citationItem->locator) && !empty($pluralForm)) {
136 7
                    $text = $pluralForm;
137
                }
138
            }
139
        } else {
140 40
            foreach ($variables as $variable) {
141 40
                if (isset($data->{$variable})) {
142 37
                    $plural = $this->getPlural($data, $plural, $variable);
143 37
                    $term = $this->locale->filter('terms', $variable, (string)$form);
144 37
                    $pluralForm = $term->{$plural} ?? "";
145 37
                    if (!empty($data->{$variable}) && !empty($pluralForm)) {
146 13
                        $text = $pluralForm;
147 40
                        break;
148
                    }
149
                }
150
            }
151
        }
152
153 46
        return $this->formatting($text);
154
    }
155
156
    /**
157
     * @param string $str
158
     * @param string $variable
159
     * @return string
160
     */
161 13
    private function evaluateStringPluralism(string $str, string $variable): string
162
    {
163 13
        $plural = 'single';
164 13
        if (!empty($str)) {
165
            switch ($variable) {
166 12
                case 'page':
167 4
                case 'chapter':
168 2
                case 'folio':
169 11
                    $pageRegex = "/([a-zA-Z]*)([0-9]+)\s*(?:–|-)\s*([a-zA-Z]*)([0-9]+)/";
170 11
                    $err = preg_match($pageRegex, $str, $matches);
171 11
                    if ($err !== false && count($matches) == 0) {
172 3
                        $plural = 'single';
173 9
                    } elseif ($err !== false && count($matches)) {
174 9
                        $plural = 'multiple';
175
                    }
176 11
                    break;
177
                default:
178 1
                    if (is_numeric($str)) {
179
                        return $str > 1 ? 'multiple' : 'single';
180
                    }
181
            }
182
        }
183 13
        return $plural;
184
    }
185
186
    /**
187
     * @param string $variable
188
     */
189 33
    public function setVariable(string $variable)
190
    {
191 33
        $this->variable = $variable;
192 33
    }
193
194
    /**
195
     * @param $data
196
     * @param $plural
197
     * @param $variable
198
     * @return string
199
     */
200 38
    protected function getPlural($data, $plural, $variable): string
201
    {
202
203 38
        if ($variable === "editortranslator" && isset($data->editor)) {
204 1
            $var = $data->editor;
205
        } else {
206 37
            $var = $data->{$variable};
207
        }
208 38
        if (((!isset($this->plural) || empty($plural))) && !empty($var)) {
209 37
            if (is_array($var)) {
210 33
                $count = count($var);
211 33
                if ($count == 1) {
212 25
                    $plural = 'single';
213 25
                    return $plural;
214 12
                } elseif ($count > 1) {
215 12
                    $plural = 'multiple';
216 12
                    return $plural;
217
                }
218
                return $plural;
219
            } else {
220 8
                return $this->evaluateStringPluralism($data->{$variable}, $variable);
221
            }
222
        } else {
223 1
            if ($this->plural != "always") {
0 ignored issues
show
introduced by
The condition $this->plural != 'always' is always true.
Loading history...
224 1
                $plural = $this->evaluateStringPluralism($data->{$variable}, $variable);
225 1
                return $plural;
226
            }
227
            return $plural;
228
        }
229
    }
230
231
    /**
232
     * @return string
233
     */
234 32
    public function getForm()
235
    {
236 32
        return $this->form;
237
    }
238
239
    /**
240
     * @param $text
241
     * @return string
242
     */
243 46
    protected function formatting(?string $text): string
244
    {
245 46
        if (empty($text)) {
246 35
            return "";
247
        }
248
        //if ($this->stripPeriods) {
249
        //    $text = str_replace('.', '', $text);
250
        //}
251
252 18
        $text = preg_replace("/\s&\s/", " &#38; ", $text); //replace ampersands by html entity
253 18
        $text = $this->stylesRenderer->renderTextCase($text);
254 18
        $text = $this->stylesRenderer->renderFormatting($text);
255 18
        return $this->stylesRenderer->renderAffixes($text);
256
    }
257
258
    /**
259
     * @return string
260
     */
261 46
    protected function defaultPlural(): string
262
    {
263 46
        $plural = "";
264 46
        switch ($this->plural) {
265 46
            case 'never':
266
                $plural = 'single';
267
                break;
268 46
            case 'always':
269
                $plural = 'multiple';
270
                break;
271 46
            case 'contextual':
272
            default:
273
        }
274 46
        return $plural;
275
    }
276
}
277