Passed
Push — new-api ( f151f9...5a646f )
by Sebastian
04:44
created

Label::render()   D

Complexity

Conditions 17
Paths 160

Size

Total Lines 44
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 32
CRAP Score 17

Importance

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