Passed
Push — master ( d2184e...ee1eb5 )
by Sebastian
04:46
created

Date::prepareDatePartsChildren()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 24
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 6.1666

Importance

Changes 0
Metric Value
cc 6
eloc 11
nc 5
nop 2
dl 0
loc 24
ccs 10
cts 12
cp 0.8333
crap 6.1666
rs 9.2222
c 0
b 0
f 0
1
<?php
2
/*
1 ignored issue
show
Coding Style introduced by
You must use "/**" style comments for a file comment
Loading history...
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\Date;
11
12
use Seboettg\CiteProc\CiteProc;
13
use Seboettg\CiteProc\Exception\CiteProcException;
14
use Seboettg\CiteProc\Styles\AffixesTrait;
15
use Seboettg\CiteProc\Styles\DisplayTrait;
16
use Seboettg\CiteProc\Styles\FormattingTrait;
17
use Seboettg\CiteProc\Styles\TextCaseTrait;
18
use Seboettg\CiteProc\Util;
19
use Seboettg\Collection\ArrayList;
20
21
22
/**
23
 * Class Date
24
 * @package Seboettg\CiteProc\Rendering
1 ignored issue
show
Coding Style introduced by
There must be exactly one blank line before the tags in a doc comment
Loading history...
25
 *
26
 * @author Sebastian Böttger <[email protected]>
27
 */
3 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
28
class Date
29
{
30
31
    use AffixesTrait,
0 ignored issues
show
Bug introduced by
The trait Seboettg\CiteProc\Styles\AffixesTrait requires the property $single which is not provided by Seboettg\CiteProc\Rendering\Date\Date.
Loading history...
32
        DisplayTrait,
33
        FormattingTrait,
34
        TextCaseTrait;
35
36
    // ymd
37
    const DATE_RANGE_STATE_NONE         = 0; // 000
38
    const DATE_RANGE_STATE_DAY          = 1; // 001
39
    const DATE_RANGE_STATE_MONTH        = 2; // 010
40
    const DATE_RANGE_STATE_MONTHDAY     = 3; // 011
41
    const DATE_RANGE_STATE_YEAR         = 4; // 100
42
    const DATE_RANGE_STATE_YEARDAY      = 5; // 101
43
    const DATE_RANGE_STATE_YEARMONTH    = 6; // 110
44
    const DATE_RANGE_STATE_YEARMONTHDAY = 7; // 111
45
46
    private static $localizedDateFormats = [
0 ignored issues
show
Coding Style introduced by
Private member variable "localizedDateFormats" must be prefixed with an underscore
Loading history...
47
        'numeric',
48
        'text'
49
    ];
50
51
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
52
     * @var ArrayList
53
     */
54
    private $dateParts;
0 ignored issues
show
Coding Style introduced by
Private member variable "dateParts" must be prefixed with an underscore
Loading history...
55
56
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
57
     * @var string
58
     */
59
    private $form = "";
0 ignored issues
show
Coding Style introduced by
Private member variable "form" must be prefixed with an underscore
Loading history...
60
61
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
62
     * @var string
63
     */
64
    private $variable = "";
0 ignored issues
show
Coding Style introduced by
Private member variable "variable" must be prefixed with an underscore
Loading history...
65
66
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
67
     * @var string
68
     */
69
    private $datePartsAttribute = "";
0 ignored issues
show
Coding Style introduced by
Private member variable "datePartsAttribute" must be prefixed with an underscore
Loading history...
70
71 56
    public function __construct(\SimpleXMLElement $node)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __construct()
Loading history...
72
    {
73 56
        $this->dateParts = new ArrayList();
74
75
        /** @var \SimpleXMLElement $attribute */
3 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
76 56
        foreach ($node->attributes() as $attribute) {
77 56
            switch ($attribute->getName()) {
78 56
                case 'form':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
79 27
                    $this->form = (string) $attribute;
80 27
                    break;
81 56
                case 'variable':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
82 56
                    $this->variable = (string) $attribute;
83 56
                    break;
84 34
                case 'date-parts':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
85 56
                    $this->datePartsAttribute = (string) $attribute;
86
            }
87
        }
88
        /** @var \SimpleXMLElement $child */
3 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
89 56
        foreach ($node->children() as $child) {
90 43
            if ($child->getName() === "date-part") {
91 43
                $datePartName = (string) $child->attributes()["name"];
92 43
                $this->dateParts->set($this->form . "-" . $datePartName, Util\Factory::create($child));
93
            }
94
        }
95
96 56
        $this->initAffixesAttributes($node);
97 56
        $this->initDisplayAttributes($node);
98 56
        $this->initFormattingAttributes($node);
99 56
        $this->initTextCaseAttributes($node);
100 56
    }
101
102
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
Parameter $data should have a doc-comment as per coding-style.
Loading history...
103
     * @param $data
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter name
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
104
     * @return string
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
105
     */
106 49
    public function render($data)
107
    {
108 49
        $ret = "";
109 49
        $var = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $var is dead and can be removed.
Loading history...
110 49
        if (isset($data->{$this->variable})) {
111 48
            $var = $data->{$this->variable};
112
        } else {
113 7
            return "";
114
        }
115
116
        try {
117 48
            $this->prepareDatePartsInVariable($data, $var);
118 1
        } catch (CiteProcException $e) {
119 1
            if (!preg_match("/(\p{L}+)\s?([\-\-\&,])\s?(\p{L}+)/u", $data->{$this->variable}->raw)) {
120 1
                return $this->addAffixes($this->format($this->applyTextCase($data->{$this->variable}->raw)));
121
            }
122
        }
123
124 48
        $form = $this->form;
125 48
        $dateParts = !empty($this->datePartsAttribute) ? explode("-", $this->datePartsAttribute) : [];
126 48
        $this->prepareDatePartsChildren($dateParts, $form);
127
128
129
        // No date-parts in date-part attribute defined, take into account that the defined date-part children will be used.
130 48
        if (empty($this->datePartsAttribute) && $this->dateParts->count() > 0) {
131
            /** @var DatePart $part */
3 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
132 36
            foreach ($this->dateParts as $part) {
133 36
                $dateParts[] = $part->getName();
134
            }
135
        }
136
137
        /* cs:date may have one or more cs:date-part child elements (see Date-part). The attributes set on
138
        these elements override those specified for the localized date formats (e.g. to get abbreviated months for all
139
        locales, the form attribute on the month-cs:date-part element can be set to “short”). These cs:date-part
140
        elements do not affect which, or in what order, date parts are rendered. Affixes, which are very
141
        locale-specific, are not allowed on these cs:date-part elements. */
142
143 48
        if ($this->dateParts->count() > 0) {
144
145
            /* if (isset($var->raw) && !preg_match("/(\p{L}+)\s?([\-\-\&,])\s?(\p{L}+)/u", $var->raw) && $this->dateParts->count() > 0) {
146
                //$var->{"date-parts"} = [];
147
            } else*/
148 47
            if (!isset($var->{'date-parts'})) { // ignore empty date-parts
149
                return "";
150
            }
151
152 47
            if (count($data->{$this->variable}->{'date-parts'}) === 1) {
153 46
                $data_ = $this->createDateTime($data->{$this->variable}->{'date-parts'});
154
                /** @var DatePart $datePart */
3 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
155 46
                foreach ($this->dateParts as $key => $datePart) {
156 46
                    list($f, $p) = explode("-", $key);
157 46
                    if (in_array($p, $dateParts)) {
158 46
                        $ret .= $datePart->render($data_[0], $this);
159
                    }
160
                }
161 1
            } else if (count($var->{'date-parts'}) === 2) { //date range
162 1
                $data_ = $this->createDateTime($var->{'date-parts'});
163 1
                $from = $data_[0];
164 1
                $to = $data_[1];
165 1
                $interval = $to->diff($from);
166 1
                $delim = "";
167 1
                $toRender = 0;
168 1
                if ($interval->y > 0) {
169 1
                    $toRender |= self::DATE_RANGE_STATE_YEAR;
170 1
                    $delim = $this->dateParts->get($this->form . "-year")->getRangeDelimiter();
171
                }
172 1
                if ($interval->m > 0 && $from->getMonth() - $to->getMonth() !== 0) {
173 1
                    $toRender |= self::DATE_RANGE_STATE_MONTH;
174 1
                    $delim = $this->dateParts->get($this->form . "-month")->getRangeDelimiter();
175
                }
176 1
                if ($interval->d > 0 && $from->getDay() - $to->getDay() !== 0) {
177 1
                    $toRender |= self::DATE_RANGE_STATE_DAY;
178 1
                    $delim = $this->dateParts->get($this->form . "-day")->getRangeDelimiter();
179
                }
180
181 1
                $ret = $this->renderDateRange($toRender, $from, $to, $delim);
182
            }
183
184 47
            if (isset($var->raw) && preg_match("/(\p{L}+)\s?([\-\-\&,])\s?(\p{L}+)/u", $var->raw, $matches)) {
185
                return $matches[1] . $matches[2] . $matches[3];
186
            }
187
        }
188
        // fallback:
189
        // When there are no dateParts children, but date-parts attribute in date
190
        // render numeric
191 1
        else if (!empty($this->datePartsAttribute)) {
0 ignored issues
show
Coding Style introduced by
Expected "} else if (...) \n"; found "\n // fallback:\n // When there are no dateParts children, but date-parts attribute in date\n // render numeric\n else if (...) {\n"
Loading history...
192 1
            $data = $this->createDateTime($var->{'date-parts'});
193 1
            $ret = $this->renderNumeric($data[0]);
194
        }
195
196 48
        return !empty($ret) ? $this->addAffixes($this->format($this->applyTextCase($ret))) : "";
197
    }
198
199 48
    private function createDateTime($dates)
1 ignored issue
show
Coding Style introduced by
Missing doc comment for function createDateTime()
Loading history...
Coding Style introduced by
Private method name "Date::createDateTime" must be prefixed with an underscore
Loading history...
200
    {
201 48
        $data = [];
202 48
        foreach ($dates as $date) {
203 48
            $date = $this->cleanDate($date);
204 48
            if ($date[0] < 1000) {
205 1
                $dateTime = new DateTime(0, 0, 0);
0 ignored issues
show
Bug introduced by
0 of type integer is incompatible with the type DateTimeZone expected by parameter $month of Seboettg\CiteProc\Render...DateTime::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

205
                $dateTime = new DateTime(0, /** @scrutinizer ignore-type */ 0, 0);
Loading history...
206 1
                $dateTime->setDay(0)->setMonth(0)->setYear(0);
207 1
                $data[] = $dateTime;
208
            }
209 48
            $dateTime = new DateTime($date[0], array_key_exists(1, $date) ? $date[1] : 1, array_key_exists(2, $date) ? $date[2] : 1);
210 48
            if (!array_key_exists(1, $date)) {
211 26
                $dateTime->setMonth(0);
212
            }
213 48
            if (!array_key_exists(2, $date)) {
214 31
                $dateTime->setDay(0);
215
            }
216 48
            $data[] = $dateTime;
217
        }
218
219 48
        return $data;
220
    }
221
222
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
Parameter $delim should have a doc-comment as per coding-style.
Loading history...
223
     * @param integer $differentParts
3 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
224
     * @param DateTime $from
2 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
225
     * @param DateTime $to
2 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
226
     * @param $delim
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter name
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
227
     * @return string
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
228
     */
229 1
    private function renderDateRange($differentParts, DateTime $from, DateTime $to, $delim)
1 ignored issue
show
Coding Style introduced by
Private method name "Date::renderDateRange" must be prefixed with an underscore
Loading history...
230
    {
231 1
        $ret = "";
232 1
        $dateParts_ = [];
233
        switch ($differentParts) {
234 1
            case self::DATE_RANGE_STATE_YEAR:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
235 1
                foreach ($this->dateParts as $key => $datePart) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
236 1
                    if (strpos($key, "year") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
237 1
                        $ret .= $this->renderOneRangePart($datePart, $from, $to, $delim);
238
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
239 1
                    if (strpos($key, "month") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
240 1
                        $day = !empty($d = $from->getMonth()) ? $d : "";
241 1
                        $ret .= $day;
242
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
243 1
                    if (strpos($key, "day") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
244 1
                        $day = !empty($d = $from->getDay()) ? $datePart->render($from, $this) : "";
0 ignored issues
show
Unused Code introduced by
The assignment to $d is dead and can be removed.
Loading history...
245 1
                        $ret .= $day;
246
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
247
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
248 1
                break;
249 1
            case self::DATE_RANGE_STATE_MONTH:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
250
                /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
251
                 * @var string $key
252
                 * @var DatePart $datePart
253
                 */
254 1
                foreach ($this->dateParts as $key => $datePart) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
255 1
                    if (strpos($key, "year") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
256 1
                        $ret .= $datePart->render($from, $this);
257
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
258 1
                    if (strpos($key, "month")) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
259 1
                        $ret .= $this->renderOneRangePart($datePart, $from, $to, $delim);
260
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
261 1
                    if (strpos($key, "day") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
262 1
                        $day = !empty($d = $from->getDay()) ? $datePart->render($from, $this) : "";
263 1
                        $ret .= $day;
264
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
265
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
266 1
                break;
267 1
            case self::DATE_RANGE_STATE_DAY:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
268
                /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
269
                 * @var string $key
270
                 * @var DatePart $datePart
271
                 */
272 1
                foreach ($this->dateParts as $key => $datePart) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
273 1
                    if (strpos($key, "year") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
274 1
                        $ret .= $datePart->render($from, $this);
275
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
276 1
                    if (strpos($key, "month") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
277 1
                        $ret .= $datePart->render($from, $this);
278
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
279 1
                    if (strpos($key, "day")) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
280 1
                        $ret .= $this->renderOneRangePart($datePart, $from, $to, $delim);
281
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
282
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
283 1
                break;
284 1
            case self::DATE_RANGE_STATE_YEARMONTHDAY:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
285 1
                $i = 0;
286 1
                foreach ($this->dateParts as $datePart) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
287 1
                    if ($i === $this->dateParts->count() - 1) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
288 1
                        $ret .= $datePart->renderPrefix();
289 1
                        $ret .= $datePart->renderWithoutAffixes($from, $this);
290
                    } else {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
291 1
                        $ret .= $datePart->render($from, $this);
292
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
293 1
                    ++$i;
294
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
295 1
                $ret .= $delim;
296 1
                $i = 0;
297 1
                foreach ($this->dateParts as $datePart) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
298 1
                    if ($i == 0) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
299 1
                        $ret .= $datePart->renderWithoutAffixes($to, $this);
300 1
                        $ret .= $datePart->renderSuffix();
301
                    } else {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
302 1
                        $ret .= $datePart->render($to, $this);
303
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
304 1
                    ++$i;
305
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
306 1
                break;
307 1
            case self::DATE_RANGE_STATE_YEARMONTH:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
308 1
                $dp = $this->dateParts->toArray();
309 1
                $i = 0;
310 1
                $dateParts_ = [];
311 1
                array_walk($dp, function($datePart, $key) use (&$i, &$dateParts_, $differentParts) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
Unused Code introduced by
The import $i is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
Unused Code introduced by
The import $differentParts is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
312 1
                    if (strpos($key, "year") !== false || strpos($key, "month") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
313 1
                        $dateParts_["yearmonth"][] = $datePart;
314
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
315 1
                    if (strpos($key, "day") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
316 1
                        $dateParts_["day"] = $datePart;
317
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
318 1
                });
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
319 1
                break;
320 1
            case self::DATE_RANGE_STATE_YEARDAY:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
321
                $dp = $this->dateParts->toArray();
322
                $i = 0;
323
                $dateParts_ = [];
324
                array_walk($dp, function($datePart, $key) use (&$i, &$dateParts_, $differentParts) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
Unused Code introduced by
The import $i is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
Unused Code introduced by
The import $differentParts is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
325
                    if (strpos($key, "year") !== false || strpos($key, "day") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
326
                        $dateParts_["yearday"][] = $datePart;
327
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
328
                    if (strpos($key, "month") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
329
                        $dateParts_["month"] = $datePart;
330
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
331
                });
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
332
                break;
333 1
            case self::DATE_RANGE_STATE_MONTHDAY:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
334 1
                $dp = $this->dateParts->toArray();
335 1
                $i = 0;
336 1
                $dateParts_ = [];
337 1
                array_walk($dp, function($datePart, $key) use (&$i, &$dateParts_, $differentParts) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
Unused Code introduced by
The import $i is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
Unused Code introduced by
The import $differentParts is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
338
                    //$bit = sprintf("%03d", decbin($differentParts));
339 1
                    if (strpos($key, "month") !== false || strpos($key, "day") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
340 1
                        $dateParts_["monthday"][] = $datePart;
341
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
342 1
                    if (strpos($key, "year") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
343 1
                        $dateParts_["year"] = $datePart;
344
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
345 1
                });
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
346 1
                break;
347
        }
348
        switch ($differentParts) {
349 1
            case self::DATE_RANGE_STATE_YEARMONTH:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
350 1
            case self::DATE_RANGE_STATE_YEARDAY:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
351 1
            case self::DATE_RANGE_STATE_MONTHDAY:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
352
                /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
353
                 * @var $key
354
                 * @var DatePart $datePart */
1 ignored issue
show
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
355 1
                foreach ($dateParts_ as $key => $datePart) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
356 1
                    if (is_array($datePart)) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
357
358 1
                        $f  = $datePart[0]->render($from, $this);
359 1
                        $f .= $datePart[1]->renderPrefix();
360 1
                        $f .= $datePart[1]->renderWithoutAffixes($from, $this);
361 1
                        $t  = $datePart[0]->renderWithoutAffixes($to, $this);
362 1
                        $t .= $datePart[0]->renderSuffix();
363 1
                        $t .= $datePart[1]->render($to, $this);
364 1
                        $ret .= $f . $delim . $t;
365
                    } else {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
366 1
                        $ret .= $datePart->render($from, $this);
367
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
368
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
369 1
                break;
370
        }
371 1
        return $ret;
372
    }
373
374
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
Parameter $datePart should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $delim should have a doc-comment as per coding-style.
Loading history...
375
     * @param $datePart
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter name
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
376
     * @param DateTime $from
2 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
377
     * @param DateTime $to
2 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
378
     * @param $delim
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter name
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
379
     * @return string
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
380
     */
381 1
    protected function renderOneRangePart(DatePart $datePart, $from, $to, $delim)
382
    {
383 1
        $prefix = $datePart->renderPrefix();
384 1
        $from = $datePart->renderWithoutAffixes($from, $this);
385 1
        $to = $datePart->renderWithoutAffixes($to, $this);
386 1
        $suffix = !empty($to) ? $datePart->renderSuffix() : "";
387 1
        return $prefix . $from . $delim . $to . $suffix;
388
    }
389
390
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
391
     * @param string $format
2 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
392
     * @return bool
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
393
     */
394 14
    private function hasDatePartsFromLocales($format)
1 ignored issue
show
Coding Style introduced by
Private method name "Date::hasDatePartsFromLocales" must be prefixed with an underscore
Loading history...
395
    {
396 14
        $dateXml = CiteProc::getContext()->getLocale()->getDateXml();
397 14
        return !empty($dateXml[$format]);
398
    }
399
400
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
401
     * @param string $format
2 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
402
     * @return array
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
403
     */
404 14
    private function getDatePartsFromLocales($format)
1 ignored issue
show
Coding Style introduced by
Private method name "Date::getDatePartsFromLocales" must be prefixed with an underscore
Loading history...
405
    {
406 14
        $ret = [];
407
        // date parts from locales
408 14
        $dateFromLocale_ = CiteProc::getContext()->getLocale()->getDateXml();
409 14
        $dateFromLocale = $dateFromLocale_[$format];
410
411
        // no custom date parts within the date element (this)?
412 14
        if (!empty($dateFromLocale)) {
413
414 14
            $dateForm = array_filter(is_array($dateFromLocale) ? $dateFromLocale : [$dateFromLocale], function($element) use ($format) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
415
                /** @var \SimpleXMLElement $element */
3 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
416 14
                $dateForm = (string) $element->attributes()["form"];
417 14
                return $dateForm === $format;
418 14
            });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
419
420
            //has dateForm from locale children (date-part elements)?
421 14
            $localeDate = array_pop($dateForm);
422
423 14
            if ($localeDate instanceof \SimpleXMLElement && $localeDate->count() > 0) {
424 14
                foreach ($localeDate as $child) {
425 14
                    $ret[] = $child;
426
                }
427
            }
428
        }
429 14
        return $ret;
430
    }
431
432
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
433
     * @return string
434
     */
435 26
    public function getVariable()
436
    {
437 26
        return $this->variable;
438
    }
439
440
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
Parameter $data should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $var should have a doc-comment as per coding-style.
Loading history...
441
     * @param $data
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter name
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
442
     * @param $var
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter name
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
443
     * @throws CiteProcException
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
444
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
445 48
    private function prepareDatePartsInVariable($data, $var)
1 ignored issue
show
Coding Style introduced by
Private method name "Date::prepareDatePartsInVariable" must be prefixed with an underscore
Loading history...
446
    {
447 48
        if (!isset($data->{$this->variable}->{'date-parts'}) || empty($data->{$this->variable}->{'date-parts'})) {
448 4
            if (isset($data->{$this->variable}->raw) && !empty($data->{$this->variable}->raw)) {
449
                //try {
450
                // try to parse date parts from "raw" attribute
451 4
                $var->{'date-parts'} = Util\DateHelper::parseDateParts($data->{$this->variable});
452
                //} catch (CiteProcException $e) {
453
                //    if (!preg_match("/(\p{L}+)\s?([\-\-\&,])\s?(\p{L}+)/u", $data->{$this->variable}->raw)) {
454
                //        return $this->addAffixes($this->format($this->applyTextCase($data->{$this->variable}->raw)));
455
                //    }
456
                //}
457
            } else {
458
                throw new CiteProcException("No valid date format");
459
                //return "";
460
            }
461
        }
462 48
    }
463
464
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
Parameter $dateParts should have a doc-comment as per coding-style.
Loading history...
465
     * @param string $form
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $form does not match actual variable name $dateParts
Loading history...
466
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
467 48
    private function prepareDatePartsChildren($dateParts, $form)
1 ignored issue
show
Coding Style introduced by
Private method name "Date::prepareDatePartsChildren" must be prefixed with an underscore
Loading history...
468
    {
469
        /* Localized date formats are selected with the optional form attribute, which must set to either “numeric”
470
        (for fully numeric formats, e.g. “12-15-2005”), or “text” (for formats with a non-numeric month, e.g.
471
        “December 15, 2005”). Localized date formats can be customized in two ways. First, the date-parts attribute may
472
        be used to show fewer date parts. The possible values are:
473
            - “year-month-day” - (default), renders the year, month and day
474
            - “year-month” - renders the year and month
475
            - “year” - renders the year */
476
477 48
        if ($this->dateParts->count() < 1 && in_array($form, self::$localizedDateFormats)) {
478 14
            if ($this->hasDatePartsFromLocales($form)) {
479 14
                $datePartsFromLocales = $this->getDatePartsFromLocales($form);
480 14
                array_filter($datePartsFromLocales, function(\SimpleXMLElement $item) use ($dateParts) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
481 14
                    return in_array($item["name"], $dateParts);
482 14
                });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
483
484 14
                foreach ($datePartsFromLocales as $datePartNode) {
485 14
                    $datePart = $datePartNode["name"];
486 14
                    $this->dateParts->set("$form-$datePart", Util\Factory::create($datePartNode));
487
                }
488
            } else { //otherwise create default date parts
489
                foreach ($dateParts as $datePart) {
490
                    $this->dateParts->add("$form-$datePart", new DatePart(new \SimpleXMLElement('<date-part name="' . $datePart . '" form="' . $form . '" />')));
491
                }
492
            }
493
        }
494 48
    }
495
496
497 1
    private function renderNumeric(DateTime $date)
1 ignored issue
show
Coding Style introduced by
Missing doc comment for function renderNumeric()
Loading history...
Coding Style introduced by
Private method name "Date::renderNumeric" must be prefixed with an underscore
Loading history...
498
    {
499 1
        return $date->renderNumeric();
500
    }
501
502 11
    public function getForm()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function getForm()
Loading history...
503
    {
504 11
        return $this->form;
505
    }
506
507 48
    private function cleanDate($date)
1 ignored issue
show
Coding Style introduced by
Missing doc comment for function cleanDate()
Loading history...
Coding Style introduced by
Private method name "Date::cleanDate" must be prefixed with an underscore
Loading history...
508
    {
509 48
        $ret = [];
510 48
        foreach ($date as $key => $datePart) {
511 48
            $ret[$key] = Util\NumberHelper::extractNumber(Util\StringHelper::removeBrackets($datePart));
512
        }
513 48
        return $ret;
514
    }
515
}