Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide optional parameters to Countries #168

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,22 +106,30 @@ In case your country has specific rules for calculating holidays,
for example region specific holidays, you can pass this to the constructor of your country class.

```php
$holidays = Holidays::for(Austria::make(region: 'de-bw'))->get();
$holidays = Holidays::for(France::make(['region' => 'FR-57'])->get();
// or
$holidays = Holidays::for(country: 'fr?region=FR-57,other_params_if_required')->get();
```

The value, `de-bw`, will be passed to the region parameter of the constructor of a country.
or ethnical specific holidays

```php
$holidays = Holidays::for(NorthMacedonia::make(['type' => 'orthodox'])->get();
// or
$holidays = Holidays::for(country: 'mk?type=orhodox,other_params_if_required')->get();
```

The parameters entered are then provided in the Country class as params.

```php
class Austria extends Country
{
protected function __construct(
protected ?string $region = null,
) {
}

protected function allHolidays(int $year): array
{
// Here you can use $this->region (or other variables) to calculate holidays
$params = $this->params ?? [];
$ethnicType = $params['type'] ?? 'standard';
$region = $params['region'] ?? 'standard';
// You can use any param you want
}
```

Expand Down
22 changes: 20 additions & 2 deletions src/Countries/Country.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

abstract class Country
{
/** @param array<string, mixed> $params */
public function __construct(protected ?array $params = null) {}

abstract public function countryCode(): string;

/** @return array<string, string|CarbonImmutable> */
Expand Down Expand Up @@ -58,7 +61,22 @@ protected function orthodoxEaster(int $year): CarbonImmutable

public static function find(string $countryCode): ?Country
{
$countryCode = strtolower($countryCode);
// country codes can contain optional parameters like 'mk?type=orthodox'
$parts = explode('?', $countryCode);
$countryCode = $parts[0];

$params = null;
if (count($parts) > 1) {
$paramsPairs = explode(',', $parts[1]);
foreach ($paramsPairs as $pair) {
$paramParts = explode('=', $pair);
if (count($paramParts) === 1) {
$params[$paramParts[0]] = true;
} else {
$params[$paramParts[0]] = $paramParts[1];
}
}
}

foreach (glob(__DIR__.'/../Countries/*.php') as $filename) {
if (basename($filename) === 'Country.php') {
Expand All @@ -69,7 +87,7 @@ public static function find(string $countryCode): ?Country
$countryClass = '\\Spatie\\Holidays\\Countries\\'.basename($filename, '.php');

/** @var Country $country */
$country = new $countryClass;
$country = new $countryClass($params);

if (strtolower($country->countryCode()) === $countryCode) {
return $country;
Expand Down
9 changes: 2 additions & 7 deletions src/Countries/France.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@

class France extends Country
{
protected function __construct(
protected ?string $region = null,
) {
}

public function countryCode(): string
{
return 'fr';
Expand Down Expand Up @@ -43,7 +38,7 @@ protected function variableHolidays(int $year): array
'Lundi de Pentecôte' => $easter->addDays(50),
];

if (in_array($this->region, ['FR-57', 'FR-67', 'FR-68'])) {
if (in_array($this->params['region'] ?? '', ['FR-57', 'FR-67', 'FR-68'])) {
$holidays['Vendredi Saint'] = $easter->subDays(2);
}

Expand All @@ -53,7 +48,7 @@ protected function variableHolidays(int $year): array
/** @return array<string, string> */
protected function regionHolidays(): array
{
switch ($this->region) {
switch ($this->params['region'] ?? '') {
case 'FR-57':
case 'FR-67':
case 'FR-68':
Expand Down
31 changes: 19 additions & 12 deletions src/Countries/NorthMacedonia.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,28 @@ public function countryCode(): string

protected function allHolidays(int $year): array
{
return array_merge([
'Нова година' => '01-01',
'Божик, првиот ден на Божик според православниот календар' => '01-07',
'Ден на трудот' => '05-01',
'Св. Кирил и Методиј - Ден на сесловенските просветители' => '05-24',
'Ден на Републиката' => '08-02',
'Ден на независноста' => '09-08',
'Ден на народното востание' => '10-11',
'Ден на македонската револуционерна борба' => '10-23',
'Св. Климент Охридски' => '12-08',
], $this->variableHolidays($year));
$params = $this->params ?? [];
$ethnicType = $params['type'] ?? 'standard';

if ($ethnicType === 'standard') {
return array_merge([
'Нова година' => '01-01',
'Божик, првиот ден на Божик според православниот календар' => '01-07',
'Ден на трудот' => '05-01',
'Св. Кирил и Методиј - Ден на сесловенските просветители' => '05-24',
'Ден на Републиката' => '08-02',
'Ден на независноста' => '09-08',
'Ден на народното востание' => '10-11',
'Ден на македонската револуционерна борба' => '10-23',
'Св. Климент Охридски' => '12-08',
], $this->variableHolidays($year, $ethnicType));
} else {
return [];
}
}

/** @return array<string, CarbonImmutable> */
protected function variableHolidays(int $year): array
protected function variableHolidays(int $year, string $ethnicType = null): array
{
$easter = $this->orthodoxEaster($year);

Expand Down
4 changes: 2 additions & 2 deletions tests/Countries/FranceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
it('can calculate french easter based region holidays', function () {
CarbonImmutable::setTestNowAndTimezone('2024-01-01');

$holidays = Holidays::for(France::make('FR-57'))->get();
$holidays = Holidays::for(France::make(['region' => 'FR-57']))->get();

expect($holidays)
->toBeArray()
Expand All @@ -33,7 +33,7 @@
it('can calculate french date based regional holidays', function () {
CarbonImmutable::setTestNowAndTimezone('2024-01-01');

$holidays = Holidays::for(France::make('FR-BL'))->get();
$holidays = Holidays::for(France::make(['region' => 'FR-BL']))->get();

expect($holidays)
->toBeArray()
Expand Down
11 changes: 11 additions & 0 deletions tests/Countries/NorthMacedoniaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Carbon\CarbonImmutable;
use Spatie\Holidays\Holidays;
use Spatie\Holidays\Countries\NorthMacedonia;

it('can calculate macedonian holidays', function () {
CarbonImmutable::setTestNowAndTimezone('2024-01-01');
Expand All @@ -16,3 +17,13 @@

expect(formatDates($holidays))->toMatchSnapshot();
});

it('can retreive valid holiday for ethnical groups', function () {
//$holidays = Holidays::for(country: 'mk?type=orhodox')->get();
$holidays = Holidays::for(NorthMacedonia::make(['type' => 'orthodox']))->get();

expect($holidays)
->toBeArray();

// TODO: add more tests for ethnical groups
});