Passed
Push — new-api ( f151f9...5a646f )
by Sebastian
04:44
created

DatePart::getForm()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
/*
4
 * citeproc-php
5
 *
6
 * @link        http://github.com/seboettg/citeproc-php for the source repository
7
 * @copyright   Copyright (c) 2016 Sebastian Böttger.
8
 * @license     https://opensource.org/licenses/MIT
9
 */
10
11
namespace Seboettg\CiteProc\Rendering\Date;
12
13
use Seboettg\CiteProc\CiteProc;
14
use Seboettg\CiteProc\Locale\Locale;
15
use Seboettg\CiteProc\Rendering\HasParent;
16
use Seboettg\CiteProc\Rendering\Layout;
17
use Seboettg\CiteProc\Rendering\Number\Number;
18
use Seboettg\CiteProc\Styles\AffixesRenderer;
19
use Seboettg\CiteProc\Styles\StylesRenderer;
20
use SimpleXMLElement;
21
22
/**
23
 * Class DatePart
24
 * @package Seboettg\CiteProc\Rendering\Date
25
 */
26
class DatePart implements HasParent
27
{
28
29
    const DEFAULT_RANGE_DELIMITER = "–";
30
31
    /** @var string|null */
32
    private $name;
33
34
    /** @var string|null */
35
    private $form;
36
37
    /** @var string|null */
38
    private $rangeDelimiter;
39
40
    /** @var Date */
41
    private $parent;
42
43
    /** @var StylesRenderer */
44
    private $stylesRenderer;
45
46
    /** @var Number */
47
    private $number;
48
49
    /** @var Locale */
50
    private $locale;
51
52 72
    public static function factory(SimpleXMLElement $node): DatePart
53
    {
54 72
        $name = (string) $node->attributes()['name'];
55 72
        $form = (string) $node->attributes()['form'];
56 72
        $rangeDelimiter = (string) $node->attributes()['range-delimiter'];
57 72
        $rangeDelimiter = empty($rangeDelimiter) ? self::DEFAULT_RANGE_DELIMITER : $rangeDelimiter;
58 72
        $stylesRenderer = StylesRenderer::factory($node);
59 72
        $locale = CiteProc::getContext()->getLocale();
60 72
        $number = new Number(null, null, $locale, $stylesRenderer);
61 72
        return new self($name, $form, $rangeDelimiter, $stylesRenderer, $number, $locale);
62
    }
63
64 72
    public function __construct(
65
        ?string $name,
66
        ?string $form,
67
        ?string $rangeDelimiter,
68
        StylesRenderer $stylesRenderer,
69
        Number $number,
70
        Locale $locale
71
    ) {
72 72
        $this->name = $name;
73 72
        $this->form = $form;
74 72
        $this->rangeDelimiter = $rangeDelimiter;
75 72
        $this->stylesRenderer = $stylesRenderer;
76 72
        $this->number = $number;
77 72
        $this->locale = $locale;
78 72
    }
79
80
    /**
81
     * @param DateTime $date
82
     * @param Date $parent
83
     * @return string
84
     */
85 62
    public function render(DateTime $date, Date $parent): string
86
    {
87 62
        $this->parent = $parent; //set parent
88 62
        $text = $this->renderWithoutAffixes($date);
89 62
        return !empty($text) ? $this->stylesRenderer->renderAffixes($text) : "";
90
    }
91
92
    /**
93
     * @param DateTime $date
94
     * @param Date|null $parent
95
     * @return string
96
     */
97 62
    public function renderWithoutAffixes(DateTime $date, Date $parent = null): string
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$parent" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$parent"; expected 0 but found 1
Loading history...
98
    {
99 62
        if (!is_null($parent)) {
100 1
            $this->parent = $parent;
101
        }
102 62
        $text = "";
103 62
        switch ($this->name) {
104 62
            case 'year':
105 61
                $text = $this->renderYear($date);
106 61
                break;
107 19
            case 'month':
108 19
                $text = $this->renderMonth($date);
109 19
                break;
110 15
            case 'day':
111 15
                $text = $this->renderDay($date);
112
        }
113
114 62
        return !empty($text) ? $this->stylesRenderer->renderFormatting(
115 61
            $this->stylesRenderer->renderTextCase($text)
116 62
        ) : "";
117
    }
118
119
    /**
120
     * @return string
121
     */
122 51
    public function getName(): ?string
123
    {
124 51
        return $this->name;
125
    }
126
127
    /**
128
     * @return string
129
     */
130 1
    public function getRangeDelimiter(): string
131
    {
132 1
        return $this->rangeDelimiter;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->rangeDelimiter could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
133
    }
134
135
    /**
136
     * @param DateTime $date
137
     * @return string
138
     */
139 61
    protected function renderYear(DateTime $date): string
140
    {
141 61
        $text = $date->getYear();
142 61
        if ($text > 0 && $text < 1000) {
143
            $text = $text . $this->locale->filter("terms", "ad")->single;
144
            return $text;
145 61
        } elseif ($text < 0) {
146
            $text = $text * -1;
147
            $text = $text . $this->locale->filter("terms", "bc")->single;
148
            return $text;
149
        }
150 61
        return (string) $text;
151
    }
152
153
    /**
154
     * @param DateTime $date
155
     * @return string
156
     */
157 19
    protected function renderMonth(DateTime $date): string
158
    {
159 19
        if ($date->getMonth() < 1 || $date->getMonth() > 12) {
160 2
            return "";
161
        }
162
163 17
        $text = $date->getMonth();
164
165 17
        $form = !empty($this->form) ? $this->form : "long";
166
        switch ($form) {
167 17
            case 'numeric':
168 1
                break;
169 17
            case 'numeric-leading-zeros':
170 3
                $text = sprintf("%02d", $text);
171 3
                break;
172 15
            case 'short':
173 11
            case 'long':
174
            default:
175 15
                $text = $this->monthFromLocale($text, $form);
176 15
                break;
177
        }
178 17
        return (string) $text;
179
    }
180
181
    /**
182
     * @param DateTime $date
183
     * @return string
184
     */
185 15
    protected function renderDay(DateTime $date): string
186
    {
187 15
        if ($date->getDay() < 1 || $date->getDay() > 31) {
188 2
            return "";
189
        }
190
191 15
        $text = $date->getDay();
192 15
        $form = !empty($this->form) ? $this->form : $this->parent->getForm();
193
        switch ($form) {
194 15
            case 'numeric':
195 1
                break;
196 15
            case 'numeric-leading-zeros':
197 3
                $text = sprintf("%02d", $text);
198 3
                break;
199 13
            case 'ordinal':
200
                $limitDayOrdinals =
201
                    CiteProc::getContext()->getLocale()->filter("options", "limit-day-ordinals-to-day-1");
202
                if (!$limitDayOrdinals || Layout::getNumberOfCitedItems() <= 1) {
203
                    $text = $this->number->ordinal($text);
204
                }
205
        }
206 15
        return (string) $text;
207
    }
208
209
    /**
210
     * @param $text
211
     * @param $form
212
     * @return mixed
213
     */
214 15
    protected function monthFromLocale($text, $form)
215
    {
216 15
        if (empty($form)) {
217
            $form = "long";
218
        }
219 15
        $month = 'month-' . sprintf('%02d', $text);
220 15
        $text = $this->locale->filter('terms', $month, $form)->single;
221 15
        return $text;
222
    }
223
224
    public function getParent(): Date
225
    {
226
        return $this->parent;
227
    }
228
229
    public function setParent($parent)
230
    {
231
        $this->parent = $parent;
232
    }
233
234 62
    public function getAffixes(): AffixesRenderer
235
    {
236 62
        return $this->stylesRenderer->getAffixes();
237
    }
238
}
239