Passed
Push — new-api ( 34a0a9...30b18d )
by Sebastian
04:06
created

Label::render()   C

Complexity

Conditions 16
Paths 80

Size

Total Lines 43
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 16

Importance

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

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