Passed
Push — master ( a9903c...537b56 )
by Sebastian
01:13
created

Date::iterateAndRenderDateParts()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 2
dl 0
loc 12
ccs 7
cts 7
cp 1
crap 3
rs 10
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
    // bitmask: 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
    /**
72
     * Date constructor.
73
     * @param \SimpleXMLElement $node
3 ignored issues
show
Coding Style introduced by
There must be exactly one blank line before the tags in a doc comment
Loading history...
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...
74
     * @throws \Seboettg\CiteProc\Exception\InvalidStylesheetException
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
75
     */
76 57
    public function __construct(\SimpleXMLElement $node)
77
    {
78 57
        $this->dateParts = new ArrayList();
79
80
        /** @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...
81 57
        foreach ($node->attributes() as $attribute) {
82 57
            switch ($attribute->getName()) {
83 57
                case 'form':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
84 28
                    $this->form = (string) $attribute;
85 28
                    break;
86 57
                case 'variable':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
87 57
                    $this->variable = (string) $attribute;
88 57
                    break;
89 35
                case 'date-parts':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
90 57
                    $this->datePartsAttribute = (string) $attribute;
91
            }
92
        }
93
        /** @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...
94 57
        foreach ($node->children() as $child) {
95 44
            if ($child->getName() === "date-part") {
96 44
                $datePartName = (string) $child->attributes()["name"];
97 44
                $this->dateParts->set($this->form . "-" . $datePartName, Util\Factory::create($child));
98
            }
99
        }
100
101 57
        $this->initAffixesAttributes($node);
102 57
        $this->initDisplayAttributes($node);
103 57
        $this->initFormattingAttributes($node);
104 57
        $this->initTextCaseAttributes($node);
105 57
    }
106
107
    /**
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...
108
     * @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...
109
     * @return string
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
110
     * @throws \Seboettg\CiteProc\Exception\InvalidStylesheetException
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
111
     * @throws \Exception
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
112
     */
113 50
    public function render($data)
114
    {
115 50
        $ret = "";
116 50
        $var = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $var is dead and can be removed.
Loading history...
117 50
        if (isset($data->{$this->variable})) {
118 49
            $var = $data->{$this->variable};
119
        } else {
120 7
            return "";
121
        }
122
123
        try {
124 49
            $this->prepareDatePartsInVariable($data, $var);
125 1
        } catch (CiteProcException $e) {
126 1
            if (!preg_match("/(\p{L}+)\s?([\-\-\&,])\s?(\p{L}+)/u", $data->{$this->variable}->raw)) {
127 1
                return $this->addAffixes($this->format($this->applyTextCase($data->{$this->variable}->raw)));
128
            }
129
        }
130
131 49
        $form = $this->form;
132 49
        $dateParts = !empty($this->datePartsAttribute) ? explode("-", $this->datePartsAttribute) : [];
133 49
        $this->prepareDatePartsChildren($dateParts, $form);
134
135
136
        // No date-parts in date-part attribute defined, take into account that the defined date-part children will be used.
137 49
        if (empty($this->datePartsAttribute) && $this->dateParts->count() > 0) {
138
            /** @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...
139 37
            foreach ($this->dateParts as $part) {
140 37
                $dateParts[] = $part->getName();
141
            }
142
        }
143
144
        /* cs:date may have one or more cs:date-part child elements (see Date-part). The attributes set on
145
        these elements override those specified for the localized date formats (e.g. to get abbreviated months for all
146
        locales, the form attribute on the month-cs:date-part element can be set to “short”). These cs:date-part
147
        elements do not affect which, or in what order, date parts are rendered. Affixes, which are very
148
        locale-specific, are not allowed on these cs:date-part elements. */
149
150 49
        if ($this->dateParts->count() > 0) {
151 48
            if (!isset($var->{'date-parts'})) { // ignore empty date-parts
152
                return "";
153
            }
154
155 48
            if (count($data->{$this->variable}->{'date-parts'}) === 1) {
156 46
                $data_ = $this->createDateTime($data->{$this->variable}->{'date-parts'});
157 46
                $ret .= $this->iterateAndRenderDateParts($dateParts, $data_);
158 2
            } else if (count($var->{'date-parts'}) === 2) { //date range
159 2
                $data_ = $this->createDateTime($var->{'date-parts'});
160 2
                $from = $data_[0];
161 2
                $to = $data_[1];
162 2
                $interval = $to->diff($from);
163 2
                $delim = "";
164 2
                $toRender = 0;
165 2
                if ($interval->y > 0 && in_array('year', $dateParts)) {
166 1
                    $toRender |= self::DATE_RANGE_STATE_YEAR;
167 1
                    $delim = $this->dateParts->get($this->form . "-year")->getRangeDelimiter();
168
                }
169 2
                if ($interval->m > 0 && $from->getMonth() - $to->getMonth() !== 0 && in_array('month', $dateParts)) {
170 1
                    $toRender |= self::DATE_RANGE_STATE_MONTH;
171 1
                    $delim = $this->dateParts->get($this->form . "-month")->getRangeDelimiter();
172
                }
173 2
                if ($interval->d > 0 && $from->getDay() - $to->getDay() !== 0 && in_array('day', $dateParts)) {
174 1
                    $toRender |= self::DATE_RANGE_STATE_DAY;
175 1
                    $delim = $this->dateParts->get($this->form . "-day")->getRangeDelimiter();
176
                }
177 2
                if ($toRender === self::DATE_RANGE_STATE_NONE) {
178 1
                    $ret .= $this->iterateAndRenderDateParts($dateParts, $data_);
179
                } else {
180 1
                    $ret .= $this->renderDateRange($toRender, $from, $to, $delim);
181
                }
182
            }
183
184 48
            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 49
        return !empty($ret) ? $this->addAffixes($this->format($this->applyTextCase($ret))) : "";
197
    }
198
199
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
200
     * @param array $dates
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...
201
     * @return array
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
202
     * @throws \Exception
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
203
     */
204 49
    private function createDateTime($dates)
1 ignored issue
show
Coding Style introduced by
Private method name "Date::createDateTime" must be prefixed with an underscore
Loading history...
205
    {
206 49
        $data = [];
207 49
        foreach ($dates as $date) {
208 49
            $date = $this->cleanDate($date);
209 49
            if ($date[0] < 1000) {
210 1
                $dateTime = new DateTime(0, 0, 0);
211 1
                $dateTime->setDay(0)->setMonth(0)->setYear(0);
212 1
                $data[] = $dateTime;
213
            }
214 49
            $dateTime = new DateTime($date[0], array_key_exists(1, $date) ? $date[1] : 1, array_key_exists(2, $date) ? $date[2] : 1);
215 49
            if (!array_key_exists(1, $date)) {
216 26
                $dateTime->setMonth(0);
217
            }
218 49
            if (!array_key_exists(2, $date)) {
219 31
                $dateTime->setDay(0);
220
            }
221 49
            $data[] = $dateTime;
222
        }
223
224 49
        return $data;
225
    }
226
227
    /**
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...
228
     * @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...
229
     * @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...
230
     * @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...
231
     * @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...
232
     * @return string
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
233
     */
234 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...
235
    {
236 1
        $ret = "";
237 1
        $dateParts_ = [];
238
        switch ($differentParts) {
239 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...
240 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...
241 1
                    if (strpos($key, "year") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
242 1
                        $ret .= $this->renderOneRangePart($datePart, $from, $to, $delim);
243
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
244 1
                    if (strpos($key, "month") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
245 1
                        $day = !empty($d = $from->getMonth()) ? $d : "";
246 1
                        $ret .= $day;
247
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
248 1
                    if (strpos($key, "day") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
249 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...
250 1
                        $ret .= $day;
251
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
252
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
253 1
                break;
254 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...
255
                /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
256
                 * @var string $key
257
                 * @var DatePart $datePart
258
                 */
259 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...
260 1
                    if (strpos($key, "year") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
261 1
                        $ret .= $datePart->render($from, $this);
262
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
263 1
                    if (strpos($key, "month")) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
264 1
                        $ret .= $this->renderOneRangePart($datePart, $from, $to, $delim);
265
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
266 1
                    if (strpos($key, "day") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
267 1
                        $day = !empty($d = $from->getDay()) ? $datePart->render($from, $this) : "";
268 1
                        $ret .= $day;
269
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
270
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
271 1
                break;
272 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...
273
                /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
274
                 * @var string $key
275
                 * @var DatePart $datePart
276
                 */
277 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...
278 1
                    if (strpos($key, "year") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
279 1
                        $ret .= $datePart->render($from, $this);
280
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
281 1
                    if (strpos($key, "month") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
282 1
                        $ret .= $datePart->render($from, $this);
283
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
284 1
                    if (strpos($key, "day")) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
285 1
                        $ret .= $this->renderOneRangePart($datePart, $from, $to, $delim);
286
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
287
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
288 1
                break;
289 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...
290 1
                $i = 0;
291 1
                foreach ($this->dateParts as $datePart) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
292 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...
293 1
                        $ret .= $datePart->renderPrefix();
294 1
                        $ret .= $datePart->renderWithoutAffixes($from, $this);
295
                    } else {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
296 1
                        $ret .= $datePart->render($from, $this);
297
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
298 1
                    ++$i;
299
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
300 1
                $ret .= $delim;
301 1
                $i = 0;
302 1
                foreach ($this->dateParts as $datePart) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
303 1
                    if ($i == 0) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
304 1
                        $ret .= $datePart->renderWithoutAffixes($to, $this);
305 1
                        $ret .= $datePart->renderSuffix();
306
                    } else {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
307 1
                        $ret .= $datePart->render($to, $this);
308
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
309 1
                    ++$i;
310
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
311 1
                break;
312 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...
313 1
                $dp = $this->dateParts->toArray();
314 1
                $i = 0;
315 1
                $dateParts_ = [];
316 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 $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...
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...
317 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...
318 1
                        $dateParts_["yearmonth"][] = $datePart;
319
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
320 1
                    if (strpos($key, "day") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
321 1
                        $dateParts_["day"] = $datePart;
322
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
323 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...
324 1
                break;
325 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...
326
                $dp = $this->dateParts->toArray();
327
                $i = 0;
328
                $dateParts_ = [];
329
                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 $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...
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...
330
                    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...
331
                        $dateParts_["yearday"][] = $datePart;
332
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
333
                    if (strpos($key, "month") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
334
                        $dateParts_["month"] = $datePart;
335
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
336
                });
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...
337
                break;
338 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...
339 1
                $dp = $this->dateParts->toArray();
340 1
                $i = 0;
341 1
                $dateParts_ = [];
342 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 $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...
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...
343
                    //$bit = sprintf("%03d", decbin($differentParts));
344 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...
345 1
                        $dateParts_["monthday"][] = $datePart;
346
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
347 1
                    if (strpos($key, "year") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
348 1
                        $dateParts_["year"] = $datePart;
349
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
350 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...
351 1
                break;
352
        }
353
        switch ($differentParts) {
354 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...
355 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...
356 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...
357
                /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
358
                 * @var $key
359
                 * @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...
360 1
                foreach ($dateParts_ as $key => $datePart) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
361 1
                    if (is_array($datePart)) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
362
363 1
                        $f  = $datePart[0]->render($from, $this);
364 1
                        $f .= $datePart[1]->renderPrefix();
365 1
                        $f .= $datePart[1]->renderWithoutAffixes($from, $this);
366 1
                        $t  = $datePart[0]->renderWithoutAffixes($to, $this);
367 1
                        $t .= $datePart[0]->renderSuffix();
368 1
                        $t .= $datePart[1]->render($to, $this);
369 1
                        $ret .= $f . $delim . $t;
370
                    } else {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
371 1
                        $ret .= $datePart->render($from, $this);
372
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
373
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
374 1
                break;
375
        }
376 1
        return $ret;
377
    }
378
379
    /**
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...
380
     * @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...
381
     * @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...
382
     * @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...
383
     * @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...
384
     * @return string
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
385
     */
386 1
    protected function renderOneRangePart(DatePart $datePart, $from, $to, $delim)
387
    {
388 1
        $prefix = $datePart->renderPrefix();
389 1
        $from = $datePart->renderWithoutAffixes($from, $this);
390 1
        $to = $datePart->renderWithoutAffixes($to, $this);
391 1
        $suffix = !empty($to) ? $datePart->renderSuffix() : "";
392 1
        return $prefix . $from . $delim . $to . $suffix;
393
    }
394
395
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
396
     * @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...
397
     * @return bool
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
398
     */
399 15
    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...
400
    {
401 15
        $dateXml = CiteProc::getContext()->getLocale()->getDateXml();
402 15
        return !empty($dateXml[$format]);
403
    }
404
405
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
406
     * @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...
407
     * @return array
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
408
     */
409 15
    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...
410
    {
411 15
        $ret = [];
412
        // date parts from locales
413 15
        $dateFromLocale_ = CiteProc::getContext()->getLocale()->getDateXml();
414 15
        $dateFromLocale = $dateFromLocale_[$format];
415
416
        // no custom date parts within the date element (this)?
417 15
        if (!empty($dateFromLocale)) {
418
419 15
            $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...
420
                /** @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...
421 15
                $dateForm = (string) $element->attributes()["form"];
422 15
                return $dateForm === $format;
423 15
            });
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...
424
425
            //has dateForm from locale children (date-part elements)?
426 15
            $localeDate = array_pop($dateForm);
427
428 15
            if ($localeDate instanceof \SimpleXMLElement && $localeDate->count() > 0) {
429 15
                foreach ($localeDate as $child) {
430 15
                    $ret[] = $child;
431
                }
432
            }
433
        }
434 15
        return $ret;
435
    }
436
437
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
438
     * @return string
439
     */
440 27
    public function getVariable()
441
    {
442 27
        return $this->variable;
443
    }
444
445
    /**
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...
446
     * @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...
447
     * @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...
448
     * @throws CiteProcException
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
449
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
450 49
    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...
451
    {
452 49
        if (!isset($data->{$this->variable}->{'date-parts'}) || empty($data->{$this->variable}->{'date-parts'})) {
453 4
            if (isset($data->{$this->variable}->raw) && !empty($data->{$this->variable}->raw)) {
454
                //try {
455
                // try to parse date parts from "raw" attribute
456 4
                $var->{'date-parts'} = Util\DateHelper::parseDateParts($data->{$this->variable});
457
                //} catch (CiteProcException $e) {
458
                //    if (!preg_match("/(\p{L}+)\s?([\-\-\&,])\s?(\p{L}+)/u", $data->{$this->variable}->raw)) {
459
                //        return $this->addAffixes($this->format($this->applyTextCase($data->{$this->variable}->raw)));
460
                //    }
461
                //}
462
            } else {
463
                throw new CiteProcException("No valid date format");
464
                //return "";
465
            }
466
        }
467 49
    }
468
469
    /**
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...
470
     * @param $dateParts
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...
471
     * @param string $form
3 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 4 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
472
     * @throws \Seboettg\CiteProc\Exception\InvalidStylesheetException
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
473
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
474 49
    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...
475
    {
476
        /* Localized date formats are selected with the optional form attribute, which must set to either “numeric”
477
        (for fully numeric formats, e.g. “12-15-2005”), or “text” (for formats with a non-numeric month, e.g.
478
        “December 15, 2005”). Localized date formats can be customized in two ways. First, the date-parts attribute may
479
        be used to show fewer date parts. The possible values are:
480
            - “year-month-day” - (default), renders the year, month and day
481
            - “year-month” - renders the year and month
482
            - “year” - renders the year */
483
484 49
        if ($this->dateParts->count() < 1 && in_array($form, self::$localizedDateFormats)) {
485 15
            if ($this->hasDatePartsFromLocales($form)) {
486 15
                $datePartsFromLocales = $this->getDatePartsFromLocales($form);
487 15
                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...
488 15
                    return in_array($item["name"], $dateParts);
489 15
                });
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...
490
491 15
                foreach ($datePartsFromLocales as $datePartNode) {
492 15
                    $datePart = $datePartNode["name"];
493 15
                    $this->dateParts->set("$form-$datePart", Util\Factory::create($datePartNode));
494
                }
495
            } else { //otherwise create default date parts
496
                foreach ($dateParts as $datePart) {
497
                    $this->dateParts->add("$form-$datePart", new DatePart(new \SimpleXMLElement('<date-part name="' . $datePart . '" form="' . $form . '" />')));
498
                }
499
            }
500
        }
501 49
    }
502
503
504 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...
505
    {
506 1
        return $date->renderNumeric();
507
    }
508
509 11
    public function getForm()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function getForm()
Loading history...
510
    {
511 11
        return $this->form;
512
    }
513
514 49
    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...
515
    {
516 49
        $ret = [];
517 49
        foreach ($date as $key => $datePart) {
518 49
            $ret[$key] = Util\NumberHelper::extractNumber(Util\StringHelper::removeBrackets($datePart));
519
        }
520 49
        return $ret;
521
    }
522
523
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
524
     * @param array $dateParts
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...
525
     * @param array $data_
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...
526
     * @return string
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
527
     */
528 47
    private function iterateAndRenderDateParts(array $dateParts, array $data_)
1 ignored issue
show
Coding Style introduced by
Private method name "Date::iterateAndRenderDateParts" must be prefixed with an underscore
Loading history...
529
    {
530 47
        $ret = "";
531
        /** @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...
532 47
        foreach ($this->dateParts as $key => $datePart) {
533
            /** @noinspection PhpUnusedLocalVariableInspection */
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...
534 47
            list($f, $p) = explode("-", $key);
535 47
            if (in_array($p, $dateParts)) {
536 47
                $ret .= $datePart->render($data_[0], $this);
537
            }
538
        }
539 47
        return $ret;
540
    }
541
}
542