DatePart   A
last analyzed

Complexity

Total Complexity 40

Size/Duplication

Total Lines 202
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 87
c 1
b 0
f 0
dl 0
loc 202
rs 9.2
wmc 40

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getRangeDelimiter() 0 3 1
A getName() 0 3 1
A __construct() 0 21 6
A render() 0 5 2
A monthFromLocale() 0 8 2
A getForm() 0 3 1
A renderYear() 0 12 4
A renderWithoutAffixes() 0 18 6
B renderMonth() 0 22 8
B renderDay() 0 22 9

How to fix   Complexity   

Complex Class

Complex classes like DatePart 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 DatePart, and based on these observations, apply Extract Interface, too.

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\Rendering\Layout;
15
use Seboettg\CiteProc\Rendering\Number;
16
use Seboettg\CiteProc\Styles\AffixesTrait;
17
use Seboettg\CiteProc\Styles\FormattingTrait;
18
use Seboettg\CiteProc\Styles\RangeDelimiterTrait;
19
use Seboettg\CiteProc\Styles\TextCaseTrait;
20
use SimpleXMLElement;
21
22
class DatePart
23
{
24
25
    const DEFAULT_RANGE_DELIMITER = "–";
26
27
    use FormattingTrait,
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\DatePart.
Loading history...
28
        AffixesTrait,
29
        TextCaseTrait,
30
        RangeDelimiterTrait;
31
32
    /**
33
     * @var string
34
     */
35
    private $name;
36
37
    /**
38
     * @var string
39
     */
40
    private $form;
41
42
    /**
43
     * @var string
44
     */
45
    private $rangeDelimiter;
46
47
    /**
48
     * @var Date
49
     */
50
    private $parent;
51
52
    public function __construct(SimpleXMLElement $node)
53
    {
54
        foreach ($node->attributes() as $attribute) {
55
            if ("name" === $attribute->getName()) {
56
                $this->name = (string) $attribute;
57
            }
58
            if ("form" === $attribute->getName()) {
59
                $this->form = (string) $attribute;
60
            }
61
            if ("range-delimiter" === $attribute->getName()) {
62
                $this->rangeDelimiter = (string) $attribute;
63
            }
64
        }
65
66
        if (empty($this->rangeDelimiter)) {
67
            $this->rangeDelimiter = self::DEFAULT_RANGE_DELIMITER;
68
        }
69
70
        $this->initFormattingAttributes($node);
71
        $this->initAffixesAttributes($node);
72
        $this->initTextCaseAttributes($node);
73
    }
74
75
76
    /**
77
     * @param DateTime $date
78
     * @param Date $parent
79
     * @return string
80
     */
81
    public function render(DateTime $date, Date $parent)
82
    {
83
        $this->parent = $parent; //set parent
84
        $text = $this->renderWithoutAffixes($date);
85
        return !empty($text) ? $this->addAffixes($text) : "";
86
    }
87
88
    /**
89
     * @param DateTime $date
90
     * @param Date|null $parent
91
     * @return string
92
     */
93
    public function renderWithoutAffixes(DateTime $date, Date $parent = null)
94
    {
95
        if (!is_null($parent)) {
96
            $this->parent = $parent;
97
        }
98
        $text = "";
99
        switch ($this->name) {
100
            case 'year':
101
                $text = $this->renderYear($date);
102
                break;
103
            case 'month':
104
                $text = $this->renderMonth($date);
105
                break;
106
            case 'day':
107
                $text = $this->renderDay($date);
108
        }
109
110
        return !empty($text) ? $this->format($this->applyTextCase($text)) : "";
111
    }
112
113
    /**
114
     * @return string
115
     */
116
    public function getForm()
117
    {
118
        return $this->form;
119
    }
120
121
    /**
122
     * @return string
123
     */
124
    public function getName()
125
    {
126
        return $this->name;
127
    }
128
129
    /**
130
     * @return string
131
     */
132
    public function getRangeDelimiter()
133
    {
134
        return $this->rangeDelimiter;
135
    }
136
137
    /**
138
     * @param DateTime $date
139
     * @return string|int
140
     */
141
    protected function renderYear(DateTime $date)
142
    {
143
        $text = $date->getYear();
144
        if ($text > 0 && $text < 1000) {
145
            $text = $text . CiteProc::getContext()->getLocale()->filter("terms", "ad")->single;
146
            return $text;
147
        } elseif ($text < 0) {
148
            $text = $text * -1;
149
            $text = $text . CiteProc::getContext()->getLocale()->filter("terms", "bc")->single;
150
            return $text;
151
        }
152
        return $text;
153
    }
154
155
    /**
156
     * @param DateTime $date
157
     * @return string
158
     */
159
    protected function renderMonth(DateTime $date)
160
    {
161
        if ($date->getMonth() < 1 || $date->getMonth() > 12) {
162
            return "";
163
        }
164
165
        $text = $date->getMonth();
166
167
        $form = !empty($this->form) ? $this->form : "long";
168
        switch ($form) {
169
            case 'numeric':
170
                break;
171
            case 'numeric-leading-zeros':
172
                $text = sprintf("%02d", $text);
173
                break;
174
            case 'short':
175
            case 'long':
176
            default:
177
                $text = $this->monthFromLocale($text, $form);
178
                break;
179
        }
180
        return $text;
181
    }
182
183
    /**
184
     * @param DateTime $date
185
     * @return int|string
186
     */
187
    protected function renderDay(DateTime $date)
188
    {
189
        if ($date->getDay() < 1 || $date->getDay() > 31) {
190
            return "";
191
        }
192
193
        $text = $date->getDay();
194
        $form = !empty($this->form) ? $this->form : $this->parent->getForm();
195
        switch ($form) {
196
            case 'numeric':
197
                break;
198
            case 'numeric-leading-zeros':
199
                $text = sprintf("%02d", $text);
200
                break;
201
            case 'ordinal':
202
                $limitDayOrdinals =
203
                    CiteProc::getContext()->getLocale()->filter("options", "limit-day-ordinals-to-day-1");
204
                if (!$limitDayOrdinals || Layout::getNumberOfCitedItems() <= 1) {
205
                    $text = Number::ordinal($text);
206
                }
207
        }
208
        return $text;
209
    }
210
211
    /**
212
     * @param $text
213
     * @param $form
214
     * @return mixed
215
     */
216
    protected function monthFromLocale($text, $form)
217
    {
218
        if (empty($form)) {
219
            $form = "long";
220
        }
221
        $month = 'month-' . sprintf('%02d', $text);
222
        $text = CiteProc::getContext()->getLocale()->filter('terms', $month, $form)->single;
223
        return $text;
224
    }
225
}
226