Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
43.48% |
10 / 23 |
CRAP | |
85.80% |
145 / 169 |
ConfigurableFactory | |
0.00% |
0 / 1 |
|
43.48% |
10 / 23 |
52.06 | |
85.80% |
145 / 169 |
build | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
buildFormatter | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
buildParser | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
buildConverter | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
get | |
0.00% |
0 / 1 |
3.04 | |
83.33% |
5 / 6 |
|||
getLeap | |
0.00% |
0 / 1 |
3.00 | |
94.44% |
17 / 18 |
|||
getLocale | |
0.00% |
0 / 1 |
2.01 | |
87.50% |
7 / 8 |
|||
getConverter | |
100.00% |
1 / 1 |
1 | |
100.00% |
9 / 9 |
|||
getSolar | |
100.00% |
1 / 1 |
2 | |
100.00% |
5 / 5 |
|||
getMonthes | |
0.00% |
0 / 1 |
3.01 | |
90.00% |
9 / 10 |
|||
getTime | |
0.00% |
0 / 1 |
6.20 | |
63.64% |
7 / 11 |
|||
getWeek | |
0.00% |
0 / 1 |
3.00 | |
92.31% |
12 / 13 |
|||
getNumberConverter | |
0.00% |
0 / 1 |
3.00 | |
92.31% |
12 / 13 |
|||
getSymbolFormatter | |
100.00% |
1 / 1 |
1 | |
100.00% |
9 / 9 |
|||
getLexer | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getFormatter | |
100.00% |
1 / 1 |
1 | |
100.00% |
5 / 5 |
|||
getMapper | |
100.00% |
1 / 1 |
1 | |
100.00% |
7 / 7 |
|||
getAdditionalSymbolParser | |
0.00% |
0 / 1 |
3.01 | |
90.00% |
9 / 10 |
|||
getSymbolParser | |
100.00% |
1 / 1 |
2 | |
100.00% |
10 / 10 |
|||
getFormatParser | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
getParser | |
100.00% |
1 / 1 |
1 | |
100.00% |
5 / 5 |
|||
getOptionValue | |
0.00% |
0 / 1 |
3.71 | |
57.14% |
4 / 7 |
|||
getOptionValueChoice | |
0.00% |
0 / 1 |
5.32 | |
36.36% |
4 / 11 |
<?php | |
namespace Popy\Calendar\Factory; | |
use InvalidArgumentException; | |
use Popy\Calendar\Calendar\ComposedCalendar; | |
use Popy\Calendar\Converter\AgnosticConverter; | |
use Popy\Calendar\Converter\UnixTimeConverter; | |
use Popy\Calendar\Converter\LeapYearCalculator; | |
use Popy\Calendar\Converter\CompleteLeapYearCalculatorInterface; | |
use Popy\Calendar\Formatter\Localisation; | |
use Popy\Calendar\Formatter\SymbolFormatter; | |
use Popy\Calendar\Formatter\NumberConverter; | |
use Popy\Calendar\Formatter\AgnosticFormatter; | |
use Popy\Calendar\Parser\AgnosticParser; | |
use Popy\Calendar\Parser\ResultMapper; | |
use Popy\Calendar\Parser\FormatLexer; | |
use Popy\Calendar\Parser\FormatParser; | |
use Popy\Calendar\Parser\SymbolParser; | |
class ConfigurableFactory | |
{ | |
/** | |
* Available values for option "leap". | |
* | |
* @var array<string> | |
*/ | |
protected $leap = [ | |
'noleap' => LeapYearCalculator\NoLeap::class, | |
'none' => LeapYearCalculator\NoLeap::class, | |
'julian' => LeapYearCalculator\Caesar::class, | |
'caesar' => LeapYearCalculator\Caesar::class, | |
'modern' => LeapYearCalculator\Modern::class, | |
'gregorian' => LeapYearCalculator\Modern::class, | |
'futuristic' => LeapYearCalculator\Futuristic::class, | |
'persian' => LeapYearCalculator\Persian::class, | |
'hijri' => LeapYearCalculator\Persian::class, | |
'von_madler' => LeapYearCalculator\VonMadler::class, | |
'float' => LeapYearCalculator\FloatBased::class, | |
]; | |
/** | |
* Available values for option "locale". | |
* | |
* @var array<string> | |
*/ | |
protected $locale = [ | |
'native' => Localisation\NativeHardcoded::class, | |
]; | |
/** | |
* Available values for option "month" | |
* | |
* @var array<string> | |
*/ | |
protected $month = [ | |
'gregorian' => UnixTimeConverter\GregorianCalendarMonthes::class, | |
'equal_length' => UnixTimeConverter\EqualLengthMonthes::class, | |
]; | |
/** | |
* Available values for option "week" | |
* | |
* @var array<string> | |
*/ | |
protected $week = [ | |
'iso' => UnixTimeConverter\Iso8601Weeks::class, | |
'simple' => UnixTimeConverter\SimpleWeeks::class, | |
]; | |
/** | |
* Available values for option "number" | |
* | |
* @var array<string> | |
*/ | |
protected $number = [ | |
'two_digits' => NumberConverter\TwoDigitsYear::class, | |
'roman' => NumberConverter\Roman::class, | |
'rfc2550' => NumberConverter\RFC2550::class, | |
]; | |
/** | |
* Available values for option "additional_symbol_parser" | |
* | |
* @var array<string> | |
*/ | |
protected $additional_symbol_parser = [ | |
'none' => false, | |
'rfc2550' => SymbolParser\PregNativeRFC2550::class, | |
]; | |
/** | |
* Builds a gregorian calendar. | |
* | |
* @return ComposedCalendar | |
*/ | |
public function build(array $options = array()) | |
{ | |
return new ComposedCalendar( | |
$this->get('formatter', $options), | |
$this->get('parser', $options) | |
); | |
} | |
/** | |
* Builds a date formatter. | |
* | |
* @return AgnosticFormatter | |
*/ | |
public function buildFormatter(array $options = array()) | |
{ | |
return $this->get('formatter', $options); | |
} | |
/** | |
* Builds a date formatter. | |
* | |
* @return AgnosticParser | |
*/ | |
public function buildParser(array $options = array()) | |
{ | |
return $this->get('parser', $options); | |
} | |
/** | |
* Builds a date converter. | |
* | |
* @return AgnosticConverter | |
*/ | |
public function buildConverter(array $options = array()) | |
{ | |
return $this->get('converter', $options); | |
} | |
/** | |
* Generic service getter. | |
* | |
* @param string $service Service name. | |
* @param array &$options Option array | |
* | |
* @return mixed | |
*/ | |
protected function get($service, array &$options) | |
{ | |
if (isset($options[$service]) && is_object($options[$service])) { | |
return $options[$service]; | |
} | |
$service = explode('_', $service); | |
$service = array_map('ucfirst', $service); | |
$service = 'get' . implode('', $service); | |
return $options[$service] = $this->$service($options); | |
} | |
protected function getLeap(array &$options) | |
{ | |
$leap = $this->getOptionValueChoice( | |
$options, | |
'leap', | |
$this->leap, | |
'modern' | |
); | |
if (!is_object($leap)) { | |
$leap = new $leap( | |
$this->getOptionValue($options, 'year_length', 365), | |
$this->getOptionValue($options, 'era_start_year', 1970) | |
); | |
} | |
if ($leap instanceof CompleteLeapYearCalculatorInterface) { | |
return $leap; | |
} | |
return new LeapYearCalculator\AgnosticCompleteCalculator( | |
$leap, | |
(int)$this->getOptionValue($options, 'year_length', 365), | |
$this->getOptionValue($options, 'era_start_year', 1970) | |
); | |
} | |
protected function getLocale(array &$options) | |
{ | |
$locale = $this->getOptionValueChoice( | |
$options, | |
'locale', | |
$this->locale, | |
'native' | |
); | |
if (is_object($locale)) { | |
return $locale; | |
} | |
return new $locale(); | |
} | |
protected function getConverter(array &$options) | |
{ | |
return new AgnosticConverter(new UnixTimeConverter\Chain([ | |
new UnixTimeConverter\StandardDateFactory(), | |
new UnixTimeConverter\Date(), | |
new UnixTimeConverter\TimeOffset(), | |
$this->get('solar', $options), | |
$this->get('monthes', $options), | |
$this->get('week', $options), | |
$this->get('time', $options), | |
])); | |
} | |
protected function getSolar(array &$options) | |
{ | |
return new UnixTimeConverter\DateSolar( | |
$this->get('leap', $options), | |
$this->getOptionValue($options, 'era_start', 0), | |
$this->getOptionValue($options, 'day_length', false) ?: null | |
); | |
} | |
protected function getMonthes(array &$options) | |
{ | |
$month = $this->getOptionValueChoice( | |
$options, | |
'month', | |
$this->month, | |
'gregorian' | |
); | |
if (is_object($month)) { | |
return $month; | |
} | |
if ($month === UnixTimeConverter\EqualLengthMonthes::class) { | |
return new $month($this->get('leap', $options), $this->getOptionValue($options, 'month_length')); | |
} | |
return new UnixTimeConverter\GregorianCalendarMonthes($this->get('leap', $options)); | |
} | |
protected function getTime(array &$options) | |
{ | |
$ranges = $this->getOptionValue($options, 'time_ranges', false) ?: null; | |
if ($ranges === 'duodecimal') { | |
$ranges = null; | |
} | |
if ($ranges === 'decimal') { | |
$ranges = [10, 100, 100, 1000, 1000]; | |
} | |
return new UnixTimeConverter\Time( | |
$ranges, | |
$this->getOptionValue($options, 'day_length', false) ?: null | |
); | |
} | |
protected function getWeek(array &$options) | |
{ | |
$week = $this->getOptionValueChoice( | |
$options, | |
'week', | |
$this->week, | |
'iso' | |
); | |
if (is_object($week)) { | |
return $week; | |
} | |
if ($week === UnixTimeConverter\SimpleWeeks::class) { | |
return new $week($this->getOptionValue($options, 'week_length')); | |
} | |
return new UnixTimeConverter\Iso8601Weeks( | |
$this->get('leap', $options), | |
$this->getOptionValue($options, 'era_start_day_index', 3) | |
); | |
} | |
protected function getNumberConverter(array &$options) | |
{ | |
$number = $this->getOptionValueChoice( | |
$options, | |
'number', | |
$this->number, | |
'two_digits' | |
); | |
if (is_object($number)) { | |
return $number; | |
} | |
if ($number === NumberConverter\TwoDigitsYear::class) { | |
return new $number( | |
$this->getOptionValue($options, 'number_converter_year', 2000), | |
$this->getOptionValue($options, 'number_converter_late_fifty', true) | |
); | |
} | |
return new $number(); | |
} | |
protected function getSymbolFormatter(array &$options) | |
{ | |
return new SymbolFormatter\Chain([ | |
new SymbolFormatter\Litteral(), | |
new SymbolFormatter\StandardDate(), | |
new SymbolFormatter\StandardDateFragmented($this->get('locale', $options)), | |
new SymbolFormatter\StandardDateSolar($this->get('number_converter', $options)), | |
new SymbolFormatter\StandardDateTime(), | |
new SymbolFormatter\StandardRecursive(), | |
new SymbolFormatter\Litteral(true), | |
]); | |
} | |
protected function getLexer(array &$options) | |
{ | |
return new FormatLexer\MbString(); | |
} | |
protected function getFormatter(array &$options) | |
{ | |
return new AgnosticFormatter( | |
$this->get('lexer', $options), | |
$this->get('converter', $options), | |
$this->get('symbol_formatter', $options) | |
); | |
} | |
protected function getMapper(array &$options) | |
{ | |
return new ResultMapper\Chain([ | |
new ResultMapper\StandardDateFactory(), | |
new ResultMapper\StandardDate(), | |
new ResultMapper\StandardDateFragmented(), | |
new ResultMapper\StandardDateSolar(), | |
new ResultMapper\StandardDateTime(), | |
]); | |
} | |
protected function getAdditionalSymbolParser(array &$options) | |
{ | |
$parser = $this->getOptionValueChoice( | |
$options, | |
'additional_symbol_parser', | |
$this->additional_symbol_parser, | |
'none' | |
); | |
if (is_object($parser)) { | |
return $parser; | |
} | |
if ($parser === false) { | |
return null; | |
} | |
return new $parser($this->get('number_converter', $options)); | |
} | |
protected function getSymbolParser(array &$options) | |
{ | |
$chain = [ | |
new SymbolParser\PregNativeDate(), | |
new SymbolParser\PregNativeRecursive(), | |
new SymbolParser\PregNativeDateSolar($this->get('number_converter', $options)), | |
new SymbolParser\PregNativeDateFragmented($this->get('locale', $options)), | |
new SymbolParser\PregNativeDateTime(), | |
]; | |
if ($additional = $this->get('additional_symbol_parser', $options)) { | |
array_unshift($chain, $additional); | |
} | |
return new SymbolParser\Chain($chain); | |
} | |
protected function getFormatParser(array &$options) | |
{ | |
return new FormatParser\PregExtendedNative( | |
$this->get('lexer', $options), | |
$this->get('symbol_parser', $options) | |
); | |
} | |
protected function getParser(array &$options) | |
{ | |
return new AgnosticParser( | |
$this->get('format_parser', $options), | |
$this->get('mapper', $options), | |
$this->get('converter', $options) | |
); | |
} | |
protected function getOptionValue(array $options, $name, $default = null) | |
{ | |
if (isset($options[$name])) { | |
return $options[$name]; | |
} | |
if ($default !== null) { | |
return $default; | |
} | |
throw new InvalidArgumentException(sprintf( | |
'"%s" option is required.', | |
$name | |
)); | |
} | |
protected function getOptionValueChoice(array $options, $name, $list, $default = null) | |
{ | |
$value = $this->getOptionValue($options, $name, $default); | |
if (is_object($value)) { | |
return $value; | |
} | |
if (!isset($list[$value])) { | |
throw new InvalidArgumentException(sprintf( | |
'Invalid value "%s" for option "%s". possible values are : %s', | |
$value, | |
$name, | |
implode(', ', array_keys($list)) | |
)); | |
} | |
return $list[$value]; | |
} | |
} |