PregNativeDateFragmented   A
last analyzed

Complexity

Total Complexity 24

Size/Duplication

Total Lines 144
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 144
rs 10
c 0
b 0
f 0
wmc 24

4 Methods

Rating   Name   Duplication   Size   Complexity  
A buildXNamesLexer() 0 10 2
A __construct() 0 3 2
A buildSuffixesLexer() 0 16 4
C parseSymbol() 0 75 16
1
<?php
2
3
namespace Popy\Calendar\Parser\SymbolParser;
4
5
use Popy\Calendar\Parser\FormatToken;
6
use Popy\Calendar\Parser\SymbolParserInterface;
7
use Popy\Calendar\Parser\FormatParserInterface;
8
use Popy\Calendar\Parser\DateLexer\PregSimple;
9
use Popy\Calendar\Parser\DateLexer\PregChoice;
10
use Popy\Calendar\Formatter\LocalisationInterface;
11
use Popy\Calendar\Formatter\Localisation\NativeHardcoded;
12
13
/**
14
 * Implementation of the native DateTime month/days formats using preg lexers.
15
 */
16
class PregNativeDateFragmented implements SymbolParserInterface
17
{
18
    /**
19
     * Localisation
20
     *
21
     * @var LocalisationInterface
22
     */
23
    protected $locale;
24
25
    /**
26
     * Class constructor.
27
     *
28
     * @param LocalisationInterface|null $locale
29
     */
30
    public function __construct(LocalisationInterface $locale = null)
31
    {
32
        $this->locale = $locale ?: new NativeHardcoded();
33
    }
34
35
    /**
36
     * @inheritDoc
37
     */
38
    public function parseSymbol(FormatToken $token, FormatParserInterface $parser)
39
    {
40
        if ($token->is('o')) {
41
            // o   ISO-8601 week-numbering year. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead.
42
            return new PregSimple($token, '\d\d\d\d');
43
        }
44
45
        if ($token->is('F')) {
46
            // F   A full textual representation of a month, such as January or March
47
            return $this->buildXNamesLexer('Month', $token);
48
        }
49
50
        if ($token->is('M')) {
51
            // M   A short textual representation of a month, three letters    Jan through Dec
52
            return $this->buildXNamesLexer('MonthShort', $token);
53
        }
54
55
        if ($token->is('m')) {
56
            // m   Numeric representation of a month, with leading zeros   01 through 12
57
            return new PregSimple($token, '\d\d');
58
        }
59
60
        if ($token->is('n')) {
61
            // n   Numeric representation of a month, without leading zeros
62
            return new PregSimple($token, '\d\d?');
63
        }
64
65
        if ($token->is('t')) {
66
            // t   Number of days in the given month
67
            return new PregSimple($token, '\d\d?');
68
        }
69
70
        if ($token->is('d')) {
71
            // d   Day of the month, 2 digits with leading zeros   01 to 31
72
            return new PregSimple($token, '\d\d');
73
        }
74
75
        if ($token->is('j')) {
76
            // j   Day of the month without leading zeros  1 to 31
77
            return new PregSimple($token, '\d\d?');
78
        }
79
80
        if ($token->is('l')) {
81
            // l (lowercase 'L')   A full textual representation of the day of the week
82
            return $this->buildXNamesLexer('Day', $token);
83
        }
84
85
        if ($token->is('D')) {
86
            // D   A textual representation of a day, three letters
87
            return $this->buildXNamesLexer('DayShort', $token);
88
        }
89
90
        if ($token->is('S')) {
91
            // S   English ordinal suffix for the day of the month, 2 characters
92
            return $this->buildSuffixesLexer($token);
93
        }
94
95
        if ($token->is('w')) {
96
            // w   Numeric representation of the day of the week   0 (for Sunday) through 6 (for Saturday)
97
            return new PregSimple($token, '\d');
98
        }
99
100
        if ($token->is('z')) {
101
            // z   The day of the year (starting from 0)
102
            return new PregSimple($token, '\d{1,3}');
103
        }
104
105
        if ($token->is('N')) {
106
            // N   ISO-8601 numeric representation of the day of the week (added in PHP 5.1.0) 1 (for Monday) through 7 (for Sunday)
107
            return new PregSimple($token, '\d');
108
        }
109
110
        if ($token->is('W')) {
111
            // W   ISO-8601 week number of year, weeks starting on Monday
112
            return new PregSimple($token, '\d\d?');
113
        }
114
    }
115
116
    /**
117
     * Builds a choice lexer based on a get*name localisation method.
118
     *
119
     * @param string      $x     Method name middle part.
120
     * @param FormatToken $token Token.
121
     *
122
     * @return PregChoice
123
     */
124
    protected function buildXNamesLexer($x, FormatToken $token)
125
    {
126
        $choices = [];
127
        $i = 0;
128
129
        while (null !== $label = $this->locale->{'get' . $x . 'Name'}($i++)) {
130
            $choices[] = $label;
131
        }
132
133
        return new PregChoice($token, $choices);
134
    }
135
136
    /**
137
     * Builds a choice lexer based on the getNumberOrdinalSuffix localisation
138
     * method.
139
     *
140
     * @param FormatToken $token Token.
141
     *
142
     * @return PregChoice
143
     */
144
    protected function buildSuffixesLexer(FormatToken $token)
145
    {
146
        $choices = [];
147
        $i = 0;
148
        $repetitions = 0;
149
150
        while ($label = $this->locale->getNumberOrdinalSuffix($i++)) {
151
            if (!in_array($label, $choices)) {
152
                $choices[] = $label;
153
                $repetitions = 0;
154
            } elseif (++$repetitions > 5) {
155
                break;
156
            }
157
        }
158
159
        return new PregChoice($token, $choices);
160
    }
161
}
162