Passed
Pull Request — master (#64)
by
unknown
03:00
created

Date   F

Complexity

Total Complexity 109

Size/Duplication

Total Lines 511
Duplicated Lines 0 %

Test Coverage

Coverage 93.75%

Importance

Changes 0
Metric Value
eloc 249
dl 0
loc 511
ccs 225
cts 240
cp 0.9375
rs 2
c 0
b 0
f 0
wmc 109

13 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 29 7
A renderOneRangePart() 0 7 2
A prepareDatePartsChildren() 0 24 6
A getDatePartsFromLocales() 0 26 6
F render() 0 102 29
A getVariable() 0 3 1
A prepareDatePartsInVariable() 0 14 5
B createDateTime() 0 21 7
A cleanDate() 0 7 2
D renderDateRange() 0 143 41
A getForm() 0 3 1
A hasDatePartsFromLocales() 0 4 1
A renderNumeric() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like Date often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Date, and based on these observations, apply Extract Interface, too.

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
    /**
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 56
    public function __construct(\SimpleXMLElement $node)
77
    {
78 56
        $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 56
        foreach ($node->attributes() as $attribute) {
82 56
            switch ($attribute->getName()) {
83 56
                case 'form':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
84 27
                    $this->form = (string) $attribute;
85 27
                    break;
86 56
                case 'variable':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
87 56
                    $this->variable = (string) $attribute;
88 56
                    break;
89 34
                case 'date-parts':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
90 56
                    $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 56
        foreach ($node->children() as $child) {
95 43
            if ($child->getName() === "date-part") {
96 43
                $datePartName = (string) $child->attributes()["name"];
97 43
                $this->dateParts->set($this->form . "-" . $datePartName, Util\Factory::create($child));
98
            }
99
        }
100
101 56
        $this->initAffixesAttributes($node);
102 56
        $this->initDisplayAttributes($node);
103 56
        $this->initFormattingAttributes($node);
104 56
        $this->initTextCaseAttributes($node);
105 56
    }
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 49
    public function render($data)
114
    {
115 49
        $ret = "";
116 49
        $var = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $var is dead and can be removed.
Loading history...
117 49
        if (isset($data->{$this->variable})) {
118 48
            $var = $data->{$this->variable};
119
        } else {
120 7
            return "";
121
        }
122
123
        try {
124 48
            $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 48
        $form = $this->form;
132 48
        $dateParts = !empty($this->datePartsAttribute) ? explode("-", $this->datePartsAttribute) : [];
133 48
        $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 48
        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 36
            foreach ($this->dateParts as $part) {
140 36
                $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 48
        if ($this->dateParts->count() > 0) {
151
152
            /* if (isset($var->raw) && !preg_match("/(\p{L}+)\s?([\-\-\&,])\s?(\p{L}+)/u", $var->raw) && $this->dateParts->count() > 0) {
153
                //$var->{"date-parts"} = [];
154
            } else*/
155 47
            if (!isset($var->{'date-parts'})) { // ignore empty date-parts
156
                return "";
157
            }
158
159 47
            if (count($data->{$this->variable}->{'date-parts'}) === 1) {
160 46
                $data_ = $this->createDateTime($data->{$this->variable}->{'date-parts'});
161
                /** @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...
162 46
                foreach ($this->dateParts as $key => $datePart) {
163
                    /** @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...
164 46
                    list($f, $p) = explode("-", $key);
165 46
                    if (in_array($p, $dateParts)) {
166 46
                        $ret .= $datePart->render($data_[0], $this);
167
                    }
168
                }
169 2
            } else if (count($var->{'date-parts'}) === 2) { //date range
170 2
                $data_ = $this->createDateTime($var->{'date-parts'});
171 2
                $from = $data_[0];
172 2
                $to = $data_[1];
173 2
                $interval = $to->diff($from);
174 2
                $delim = "";
175 2
                $toRender = 0;
176 2
                if ($interval->y > 0 && in_array('year', $dateParts)) {
177 1
                    $toRender |= self::DATE_RANGE_STATE_YEAR;
178 1
                    $delim = $this->dateParts->get($this->form . "-year")->getRangeDelimiter();
179
                }
180 2
                if ($interval->m > 0 && $from->getMonth() - $to->getMonth() !== 0 && in_array('month', $dateParts)) {
181 1
                    $toRender |= self::DATE_RANGE_STATE_MONTH;
182 1
                    $delim = $this->dateParts->get($this->form . "-month")->getRangeDelimiter();
183
                }
184 2
                if ($interval->d > 0 && $from->getDay() - $to->getDay() !== 0 && in_array('day', $dateParts)) {
185 1
                    $toRender |= self::DATE_RANGE_STATE_DAY;
186 1
                    $delim = $this->dateParts->get($this->form . "-day")->getRangeDelimiter();
187
                }
188 2
                if ($toRender === self::DATE_RANGE_STATE_NONE) {
189 1
                  foreach ($this->dateParts as $key => $datePart) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 20 spaces, found 18
Loading history...
190
                    /** @noinspection PhpUnusedLocalVariableInspection */
3 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 24 spaces, found 20
Loading history...
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...
191 1
                    list($f, $p) = explode("-", $key);
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 24 spaces, found 20
Loading history...
192 1
                    if (in_array($p, $dateParts)) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 20
Loading history...
193 1
                      $ret .= $datePart->render($data_[0], $this);
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 28 spaces, found 22
Loading history...
194
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 20
Loading history...
195
                  }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 20 spaces, found 18
Loading history...
196
                }
197
                else {
0 ignored issues
show
Coding Style introduced by
Expected "} else \n"; found "\n else {\n"
Loading history...
198 1
                  $ret = $this->renderDateRange($toRender, $from, $to, $delim);
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 20 spaces, found 18
Loading history...
199
                }
200
            }
201
202 47
            if (isset($var->raw) && preg_match("/(\p{L}+)\s?([\-\-\&,])\s?(\p{L}+)/u", $var->raw, $matches)) {
203
                return $matches[1] . $matches[2] . $matches[3];
204
            }
205
        }
206
        // fallback:
207
        // When there are no dateParts children, but date-parts attribute in date
208
        // render numeric
209 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...
210 1
            $data = $this->createDateTime($var->{'date-parts'});
211 1
            $ret = $this->renderNumeric($data[0]);
212
        }
213
214 48
        return !empty($ret) ? $this->addAffixes($this->format($this->applyTextCase($ret))) : "";
215
    }
216
217
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
218
     * @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...
219
     * @return array
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
220
     * @throws \Exception
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
221
     */
222 48
    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...
223
    {
224 48
        $data = [];
225 48
        foreach ($dates as $date) {
226 48
            $date = $this->cleanDate($date);
227 48
            if ($date[0] < 1000) {
228 1
                $dateTime = new DateTime(0, 0, 0);
229 1
                $dateTime->setDay(0)->setMonth(0)->setYear(0);
230 1
                $data[] = $dateTime;
231
            }
232 48
            $dateTime = new DateTime($date[0], array_key_exists(1, $date) ? $date[1] : 1, array_key_exists(2, $date) ? $date[2] : 1);
233 48
            if (!array_key_exists(1, $date)) {
234 26
                $dateTime->setMonth(0);
235
            }
236 48
            if (!array_key_exists(2, $date)) {
237 31
                $dateTime->setDay(0);
238
            }
239 48
            $data[] = $dateTime;
240
        }
241
242 48
        return $data;
243
    }
244
245
    /**
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...
246
     * @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...
247
     * @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...
248
     * @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...
249
     * @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...
250
     * @return string
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
251
     */
252 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...
253
    {
254 1
        $ret = "";
255 1
        $dateParts_ = [];
256
        switch ($differentParts) {
257 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...
258 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...
259 1
                    if (strpos($key, "year") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
260 1
                        $ret .= $this->renderOneRangePart($datePart, $from, $to, $delim);
261
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
262 1
                    if (strpos($key, "month") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
263 1
                        $day = !empty($d = $from->getMonth()) ? $d : "";
264 1
                        $ret .= $day;
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) : "";
0 ignored issues
show
Unused Code introduced by
The assignment to $d is dead and can be removed.
Loading history...
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_MONTH:
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")) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
282 1
                        $ret .= $this->renderOneRangePart($datePart, $from, $to, $delim);
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") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
285 1
                        $day = !empty($d = $from->getDay()) ? $datePart->render($from, $this) : "";
286 1
                        $ret .= $day;
287
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
288
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
289 1
                break;
290 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...
291
                /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
292
                 * @var string $key
293
                 * @var DatePart $datePart
294
                 */
295 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...
296 1
                    if (strpos($key, "year") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
297 1
                        $ret .= $datePart->render($from, $this);
298
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
299 1
                    if (strpos($key, "month") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
300 1
                        $ret .= $datePart->render($from, $this);
301
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
302 1
                    if (strpos($key, "day")) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
303 1
                        $ret .= $this->renderOneRangePart($datePart, $from, $to, $delim);
304
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
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_YEARMONTHDAY:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
308 1
                $i = 0;
309 1
                foreach ($this->dateParts as $datePart) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
310 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...
311 1
                        $ret .= $datePart->renderPrefix();
312 1
                        $ret .= $datePart->renderWithoutAffixes($from, $this);
313
                    } else {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
314 1
                        $ret .= $datePart->render($from, $this);
315
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
316 1
                    ++$i;
317
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
318 1
                $ret .= $delim;
319 1
                $i = 0;
320 1
                foreach ($this->dateParts as $datePart) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
321 1
                    if ($i == 0) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
322 1
                        $ret .= $datePart->renderWithoutAffixes($to, $this);
323 1
                        $ret .= $datePart->renderSuffix();
324
                    } else {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
325 1
                        $ret .= $datePart->render($to, $this);
326
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
327 1
                    ++$i;
328
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
329 1
                break;
330 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...
331 1
                $dp = $this->dateParts->toArray();
332 1
                $i = 0;
333 1
                $dateParts_ = [];
334 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...
335 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...
336 1
                        $dateParts_["yearmonth"][] = $datePart;
337
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
338 1
                    if (strpos($key, "day") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
339 1
                        $dateParts_["day"] = $datePart;
340
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
341 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...
342 1
                break;
343 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...
344
                $dp = $this->dateParts->toArray();
345
                $i = 0;
346
                $dateParts_ = [];
347
                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...
348
                    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...
349
                        $dateParts_["yearday"][] = $datePart;
350
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
351
                    if (strpos($key, "month") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
352
                        $dateParts_["month"] = $datePart;
353
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
354
                });
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...
355
                break;
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
                $dp = $this->dateParts->toArray();
358 1
                $i = 0;
359 1
                $dateParts_ = [];
360 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...
361
                    //$bit = sprintf("%03d", decbin($differentParts));
362 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...
363 1
                        $dateParts_["monthday"][] = $datePart;
364
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
365 1
                    if (strpos($key, "year") !== false) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
366 1
                        $dateParts_["year"] = $datePart;
367
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
368 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...
369 1
                break;
370
        }
371
        switch ($differentParts) {
372 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...
373 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...
374 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...
375
                /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
376
                 * @var $key
377
                 * @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...
378 1
                foreach ($dateParts_ as $key => $datePart) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
379 1
                    if (is_array($datePart)) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
380
381 1
                        $f  = $datePart[0]->render($from, $this);
382 1
                        $f .= $datePart[1]->renderPrefix();
383 1
                        $f .= $datePart[1]->renderWithoutAffixes($from, $this);
384 1
                        $t  = $datePart[0]->renderWithoutAffixes($to, $this);
385 1
                        $t .= $datePart[0]->renderSuffix();
386 1
                        $t .= $datePart[1]->render($to, $this);
387 1
                        $ret .= $f . $delim . $t;
388
                    } else {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
389 1
                        $ret .= $datePart->render($from, $this);
390
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
391
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
392 1
                break;
393
        }
394 1
        return $ret;
395
    }
396
397
    /**
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...
398
     * @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...
399
     * @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...
400
     * @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...
401
     * @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...
402
     * @return string
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
403
     */
404 1
    protected function renderOneRangePart(DatePart $datePart, $from, $to, $delim)
405
    {
406 1
        $prefix = $datePart->renderPrefix();
407 1
        $from = $datePart->renderWithoutAffixes($from, $this);
408 1
        $to = $datePart->renderWithoutAffixes($to, $this);
409 1
        $suffix = !empty($to) ? $datePart->renderSuffix() : "";
410 1
        return $prefix . $from . $delim . $to . $suffix;
411
    }
412
413
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
414
     * @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...
415
     * @return bool
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
416
     */
417 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...
418
    {
419 15
        $dateXml = CiteProc::getContext()->getLocale()->getDateXml();
420 15
        return !empty($dateXml[$format]);
421
    }
422
423
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
424
     * @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...
425
     * @return array
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
426
     */
427 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...
428
    {
429 15
        $ret = [];
430
        // date parts from locales
431 15
        $dateFromLocale_ = CiteProc::getContext()->getLocale()->getDateXml();
432 15
        $dateFromLocale = $dateFromLocale_[$format];
433
434
        // no custom date parts within the date element (this)?
435 15
        if (!empty($dateFromLocale)) {
436
437 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...
438
                /** @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...
439 15
                $dateForm = (string) $element->attributes()["form"];
440 15
                return $dateForm === $format;
441 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...
442
443
            //has dateForm from locale children (date-part elements)?
444 15
            $localeDate = array_pop($dateForm);
445
446 15
            if ($localeDate instanceof \SimpleXMLElement && $localeDate->count() > 0) {
447 15
                foreach ($localeDate as $child) {
448 15
                    $ret[] = $child;
449
                }
450
            }
451
        }
452 15
        return $ret;
453
    }
454
455
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
456
     * @return string
457
     */
458 26
    public function getVariable()
459
    {
460 26
        return $this->variable;
461
    }
462
463
    /**
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...
464
     * @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...
465
     * @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...
466
     * @throws CiteProcException
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
467
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
468 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...
469
    {
470 48
        if (!isset($data->{$this->variable}->{'date-parts'}) || empty($data->{$this->variable}->{'date-parts'})) {
471 4
            if (isset($data->{$this->variable}->raw) && !empty($data->{$this->variable}->raw)) {
472
                //try {
473
                // try to parse date parts from "raw" attribute
474 4
                $var->{'date-parts'} = Util\DateHelper::parseDateParts($data->{$this->variable});
475
                //} catch (CiteProcException $e) {
476
                //    if (!preg_match("/(\p{L}+)\s?([\-\-\&,])\s?(\p{L}+)/u", $data->{$this->variable}->raw)) {
477
                //        return $this->addAffixes($this->format($this->applyTextCase($data->{$this->variable}->raw)));
478
                //    }
479
                //}
480
            } else {
481
                throw new CiteProcException("No valid date format");
482
                //return "";
483
            }
484
        }
485 48
    }
486
487
    /**
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...
488
     * @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...
489
     * @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...
490
     * @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...
491
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
492 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...
493
    {
494
        /* Localized date formats are selected with the optional form attribute, which must set to either “numeric”
495
        (for fully numeric formats, e.g. “12-15-2005”), or “text” (for formats with a non-numeric month, e.g.
496
        “December 15, 2005”). Localized date formats can be customized in two ways. First, the date-parts attribute may
497
        be used to show fewer date parts. The possible values are:
498
            - “year-month-day” - (default), renders the year, month and day
499
            - “year-month” - renders the year and month
500
            - “year” - renders the year */
501
502 48
        if ($this->dateParts->count() < 1 && in_array($form, self::$localizedDateFormats)) {
503 15
            if ($this->hasDatePartsFromLocales($form)) {
504 15
                $datePartsFromLocales = $this->getDatePartsFromLocales($form);
505 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...
506 15
                    return in_array($item["name"], $dateParts);
507 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...
508
509 15
                foreach ($datePartsFromLocales as $datePartNode) {
510 15
                    $datePart = $datePartNode["name"];
511 15
                    $this->dateParts->set("$form-$datePart", Util\Factory::create($datePartNode));
512
                }
513
            } else { //otherwise create default date parts
514
                foreach ($dateParts as $datePart) {
515
                    $this->dateParts->add("$form-$datePart", new DatePart(new \SimpleXMLElement('<date-part name="' . $datePart . '" form="' . $form . '" />')));
516
                }
517
            }
518
        }
519 48
    }
520
521
522 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...
523
    {
524 1
        return $date->renderNumeric();
525
    }
526
527 11
    public function getForm()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function getForm()
Loading history...
528
    {
529 11
        return $this->form;
530
    }
531
532 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...
533
    {
534 48
        $ret = [];
535 48
        foreach ($date as $key => $datePart) {
536 48
            $ret[$key] = Util\NumberHelper::extractNumber(Util\StringHelper::removeBrackets($datePart));
537
        }
538 48
        return $ret;
539
    }
540
}