Completed
Push — master ( e09500...86ebd4 )
by Sebastian
02:59
created

Label::formatting()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 2
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
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
use Seboettg\CiteProc\CiteProc;
12
use Seboettg\CiteProc\Styles\AffixesTrait;
13
use Seboettg\CiteProc\Styles\FormattingTrait;
14
use Seboettg\CiteProc\Styles\TextCaseTrait;
15
16
17
/**
18
 * Class Label
19
 * @package Seboettg\CiteProc\Rendering
20
 *
21
 * @author Sebastian Böttger <[email protected]>
22
 */
23
class Label implements RenderingInterface
24
{
25
    use AffixesTrait,
26
        FormattingTrait,
27
        TextCaseTrait;
28
29
    private $variable;
30
31
    /**
32
     * Selects the form of the term, with allowed values:
33
     *
34
     *   - “long” - (default), e.g. “page”/”pages” for the “page” term
35
     *   - “short” - e.g. “p.”/”pp.” for the “page” term
36
     *   - “symbol” - e.g. “§”/”§§” for the “section” term
37
     *
38
     * @var string
39
     */
40
    private $form = "";
41
42
    /**
43
     * Sets pluralization of the term, with allowed values:
44
     *
45
     *   - “contextual” - (default), the term plurality matches that of the variable content. Content is considered
46
     *     plural when it contains multiple numbers (e.g. “page 1”, “pages 1-3”, “volume 2”, “volumes 2 & 4”), or, in
47
     *     the case of the “number-of-pages” and “number-of-volumes” variables, when the number is higher than 1
48
     *     (“1 volume” and “3 volumes”).
49
     *   - “always” - always use the plural form, e.g. “pages 1” and “pages 1-3”
50
     *   - “never” - always use the singular form, e.g. “page 1” and “page 1-3”
51
     *
52
     * @var string
53
     */
54
    private $plural = "contextual";
55
56
    /**
57
     * Label constructor.
58
     * @param \SimpleXMLElement $node
59
     */
60
    public function __construct(\SimpleXMLElement $node)
61
    {
62
        /** @var \SimpleXMLElement $attribute */
63 View Code Duplication
        foreach ($node->attributes() as $attribute) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
64
            switch ($attribute->getName()) {
65
                case "variable":
66
                    $this->variable = (string) $attribute;
67
                    break;
68
                case "form":
69
                    $this->form = (string) $attribute;
70
                    break;
71
                case "plural":
72
                    $this->plural = (string) $attribute;
73
                    break;
74
            }
75
        }
76
77
        $this->initFormattingAttributes($node);
78
        $this->initAffixesAttributes($node);
79
        $this->initTextCaseAttributes($node);
80
    }
81
82
    /**
83
     * @param \stdClass $data
84
     * @param int|null $citationNumber
85
     * @return string
86
     */
87
    public function render($data, $citationNumber = null)
88
    {
89
        $lang = (isset($data->language) && $data->language != 'en') ? $data->language : 'en';
90
91
        $text = '';
92
        $variables = explode(' ', $this->variable);
93
        $form = !empty($this->form) ? $this->form : 'long';
94
        $plural = $this->defaultPlural();
95
96
        if ($this->variable === "editortranslator") {
97
            if (isset($data->editor) && isset($data->translator)) {
98
                $plural = $this->getPlural($data, $plural, "editortranslator");
99
                $term = CiteProc::getContext()->getLocale()->filter('terms', "editortranslator", $form);
100
                $pluralForm = $term->{$plural};
101
                if (!empty($pluralForm)) {
102
                    $text = $pluralForm;
103
                }
104
            }
105
        } else {
106
            foreach ($variables as $variable) {
107
108
                if (isset($data->{$variable})) {
109
                    $plural = $this->getPlural($data, $plural, $variable);
110
                    $term = CiteProc::getContext()->getLocale()->filter('terms', $variable, $form);
111
                    $pluralForm = $term->{$plural};
112
                    if (!empty($data->{$variable}) && !empty($pluralForm)) {
113
                        $text = $pluralForm;
114
                        break;
115
                    }
116
                }
117
            }
118
        }
119
120
        return $this->formatting($text, $lang);
121
    }
122
123
    /**
124
     * @param $data
125
     * @param $variable
126
     * @return string
127
     */
128
    private function evaluateStringPluralism($data, $variable)
129
    {
130
        $str = $data->{$variable};
131
        $plural = 'single';
132
        if (!empty($str)) {
133
            switch ($variable) {
134
                case 'page':
135
                    $pageRegex = "/([a-zA-Z]*)([0-9]+)\s*(?:–|-)\s*([a-zA-Z]*)([0-9]+)/";
136
                    $err = preg_match($pageRegex, $str, $m);
137
                    if ($err !== false && count($m) == 0) {
138
                        $plural = 'single';
139
                    } elseif ($err !== false && count($m)) {
140
                        $plural = 'multiple';
141
                    }
142
                    break;
143
                default:
144
                    if (is_numeric($str)) {
145
                        return $str > 1 ? 'multiple' : 'single';
146
                    }
147
            }
148
        }
149
        return $plural;
150
    }
151
152
    /**
153
     * @param string $variable
154
     */
155
    public function setVariable($variable)
156
    {
157
        $this->variable = $variable;
158
    }
159
160
    /**
161
     * @param $data
162
     * @param $plural
163
     * @param $variable
164
     * @return string
165
     */
166
    protected function getPlural($data, $plural, $variable)
167
    {
168
169
        if ($variable === "editortranslator") {
170
            $var = $data->editor;
171
        } else {
172
            $var = $data->{$variable};
173
        }
174
        if (((!isset($this->plural) || empty($plural))) && !empty($var)) {
175
            if (is_array($var)) {
176
                $count = count($var);
177
                if ($count == 1) {
178
                    $plural = 'single';
179
                    return $plural;
180
                } elseif ($count > 1) {
181
                    $plural = 'multiple';
182
                    return $plural;
183
                }
184
                return $plural;
185
            } else {
186
                return $this->evaluateStringPluralism($data, $variable);
187
            }
188
189
        } else {
190
            if ($this->plural != "always") {
191
                $plural = $this->evaluateStringPluralism($data, $variable);
192
                return $plural;
193
            }
194
            return $plural;
195
        }
196
    }
197
198
    /**
199
     * @return string
200
     */
201
    public function getForm()
202
    {
203
        return $this->form;
204
    }
205
206
    /**
207
     * @param string $form
208
     */
209
    public function setForm($form)
210
    {
211
        $this->form = $form;
212
    }
213
214
    /**
215
     * @param $text
216
     * @param $lang
217
     * @return string
218
     */
219
    protected function formatting($text, $lang)
220
    {
221
        if (empty($text)) {
222
            return "";
223
        }
224
        if ($this->stripPeriods) {
225
            $text = str_replace('.', '', $text);
226
        }
227
228
        $text = preg_replace("/\s\&\s/", " &#38; ", $text); //replace ampersands by html entity
229
        $text = $this->format($this->applyTextCase($text, $lang));
230
        return $this->addAffixes($text);
231
    }
232
233
    /**
234
     * @return string
235
     */
236
    protected function defaultPlural()
237
    {
238
        $plural = "";
239
        switch ($this->plural) {
240
            case 'never':
241
                $plural = 'single';
242
                break;
243
            case 'always':
244
                $plural = 'multiple';
245
                break;
246
            case 'contextual':
247
            default:
248
        }
249
        return $plural;
250
    }
251
}