Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #122 from heiglandreas/addMultipleObservanceShifts
- Loading branch information
Showing
18 changed files
with
737 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<?php | ||
|
||
/** | ||
* Copyright Andreas Heigl <andreas@heigl.org> | ||
* | ||
* Licenses under the MIT-license. For details see the included file LICENSE.md | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Org_Heigl\Holidaychecker\Factory; | ||
|
||
use DOMElement; | ||
use Org_Heigl\Holidaychecker\CalendarDayFactory; | ||
use Org_Heigl\Holidaychecker\GregorianWeekday; | ||
use Org_Heigl\Holidaychecker\HolidayIteratorItemInterface; | ||
use Org_Heigl\Holidaychecker\IteratorItem\SwapDecorator; | ||
use Org_Heigl\Holidaychecker\SwapDirection; | ||
use Org_Heigl\Holidaychecker\SwapRule; | ||
use function array_map; | ||
use function explode; | ||
|
||
final class SwapDecoratorFactory implements DecorateFromDomElement | ||
{ | ||
public function decorate(HolidayIteratorItemInterface $element, DOMElement $domElement): HolidayIteratorItemInterface | ||
{ | ||
$rules = $this->getRulesFromDomElement($domElement); | ||
|
||
if ($rules === []) { | ||
return $element; | ||
} | ||
|
||
$day = CalendarDayFactory::createCalendarDay( | ||
(int) $domElement->getAttribute('day'), | ||
(int) $domElement->getAttribute('month'), | ||
($domElement->hasAttribute('calendar') ? $domElement->getAttribute('calendar') : 'gregorian') | ||
); | ||
|
||
if ($domElement->hasAttribute('year')) { | ||
$day->setYear((int) $domElement->getAttribute('year')); | ||
} | ||
|
||
return new SwapDecorator($element, $day, ...$rules); | ||
} | ||
|
||
private function createRuleFrom(string $to, string $when, SwapDirection $direction): SwapRule | ||
{ | ||
return new SwapRule( | ||
$direction, | ||
GregorianWeekday::fromString($to), | ||
...array_map(function ($item) { | ||
return GregorianWeekday::fromString($item); | ||
}, explode(' ', $when)) | ||
); | ||
} | ||
|
||
/** | ||
* @return SwapRule[] | ||
*/ | ||
private function getRulesFromDomElement(DOMElement $domElement): array | ||
{ | ||
$attributes = [ | ||
'forward' => SwapDirection::forward(), | ||
'alternateforward' => SwapDirection::forward(), | ||
'rewind' => SwapDirection::rewind(), | ||
'alternaterewind' => SwapDirection::rewind(), | ||
]; | ||
|
||
$rules = []; | ||
foreach ($attributes as $attribute => $direction) { | ||
if ($domElement->hasAttribute($attribute . 'to') && $domElement->hasAttribute($attribute . 'when')) { | ||
$rules[] = $this->createRuleFrom($domElement->getAttribute($attribute . 'to'), $domElement->getAttribute($attribute . 'when'), $direction); | ||
} | ||
} | ||
|
||
return $rules; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
<?php | ||
|
||
/** | ||
* Copyright Andreas Heigl <andreas@heigl.org> | ||
* | ||
* Licenses under the MIT-license. For details see the included file LICENSE.md | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Org_Heigl\Holidaychecker; | ||
|
||
use DateTimeInterface; | ||
use IntlCalendar; | ||
use RuntimeException; | ||
use UnexpectedValueException; | ||
use function method_exists; | ||
use function sprintf; | ||
use function strtolower; | ||
|
||
final class GregorianWeekday | ||
{ | ||
/** @var string */ | ||
private $value; | ||
|
||
/** @var array<string, GregorianWeekday> */ | ||
private static $instances = []; | ||
|
||
private const MONDAY = 'monday'; | ||
private const TUESDAY = 'tuesday'; | ||
private const WEDNESDAY = 'wednesday'; | ||
private const THURSDAY = 'thursday'; | ||
private const FRIDAY = 'friday'; | ||
private const SATURDAY = 'saturday'; | ||
private const SUNDAY = 'sunday'; | ||
|
||
private function __construct(string $value) | ||
{ | ||
$this->value = $value; | ||
} | ||
|
||
public function getValue(): string | ||
{ | ||
return $this->value; | ||
} | ||
|
||
public static function monday(): self | ||
{ | ||
if (! isset(self::$instances[self::MONDAY])) { | ||
self::$instances[self::MONDAY] = new self(self::MONDAY); | ||
} | ||
|
||
return self::$instances[self::MONDAY]; | ||
} | ||
|
||
public static function tuesday(): self | ||
{ | ||
if (! isset(self::$instances[self::TUESDAY])) { | ||
self::$instances[self::TUESDAY] = new self(self::TUESDAY); | ||
} | ||
|
||
return self::$instances[self::TUESDAY]; | ||
} | ||
|
||
public static function wednesday(): self | ||
{ | ||
if (! isset(self::$instances[self::WEDNESDAY])) { | ||
self::$instances[self::WEDNESDAY] = new self(self::WEDNESDAY); | ||
} | ||
|
||
return self::$instances[self::WEDNESDAY]; | ||
} | ||
|
||
public static function thursday(): self | ||
{ | ||
if (! isset(self::$instances[self::THURSDAY])) { | ||
self::$instances[self::THURSDAY] = new self(self::THURSDAY); | ||
} | ||
|
||
return self::$instances[self::THURSDAY]; | ||
} | ||
|
||
public static function friday(): self | ||
{ | ||
if (! isset(self::$instances[self::FRIDAY])) { | ||
self::$instances[self::FRIDAY] = new self(self::FRIDAY); | ||
} | ||
|
||
return self::$instances[self::FRIDAY]; | ||
} | ||
|
||
public static function saturday(): self | ||
{ | ||
if (! isset(self::$instances[self::SATURDAY])) { | ||
self::$instances[self::SATURDAY] = new self(self::SATURDAY); | ||
} | ||
|
||
return self::$instances[self::SATURDAY]; | ||
} | ||
|
||
public static function sunday(): self | ||
{ | ||
if (! isset(self::$instances[self::SUNDAY])) { | ||
self::$instances[self::SUNDAY] = new self(self::SUNDAY); | ||
} | ||
|
||
return self::$instances[self::SUNDAY]; | ||
} | ||
|
||
public static function fromString(string $weekday): self | ||
{ | ||
if (! method_exists(self::class, strtolower($weekday))) { | ||
throw new RuntimeException(sprintf( | ||
'Weekday "%s" is not known', | ||
$weekday | ||
)); | ||
} | ||
|
||
/** @var GregorianWeekday $gregorianWeekday */ | ||
$gregorianWeekday = [self::class, strtolower($weekday)](); | ||
|
||
return $gregorianWeekday; | ||
} | ||
|
||
public static function fromDateTimeInterface(DateTimeInterface $date): self | ||
{ | ||
return self::fromString($date->format('l')); | ||
} | ||
|
||
public static function fromIntlWeekday(int $weekday): self | ||
{ | ||
$mapper = [ | ||
IntlCalendar::DOW_SUNDAY => 'sunday', | ||
IntlCalendar::DOW_MONDAY => 'monday', | ||
IntlCalendar::DOW_TUESDAY => 'tuesday', | ||
IntlCalendar::DOW_WEDNESDAY => 'wednesday', | ||
IntlCalendar::DOW_THURSDAY => 'thursday', | ||
IntlCalendar::DOW_FRIDAY => 'friday', | ||
IntlCalendar::DOW_SATURDAY => 'saturday', | ||
]; | ||
if (! isset($mapper[$weekday])) { | ||
throw new UnexpectedValueException(sprintf( | ||
'IntlCalendar weekday %s could not be resolved', | ||
$weekday | ||
)); | ||
} | ||
|
||
return self::fromString($mapper[$weekday]); | ||
} | ||
|
||
public function __toString(): string | ||
{ | ||
return $this->getValue(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.