Skip to content

Commit

Permalink
Support file output by ICS
Browse files Browse the repository at this point in the history
  • Loading branch information
alies-dev committed Jan 26, 2024
1 parent a74d683 commit f0e946b
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 21 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ tests/**/__snapshots__/IcsGeneratorTest* text eol=crlf

# PHPUnit
.phpunit.cache
.phpunit.cache/
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
"php": "^8.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.14",
"phpunit/phpunit": "^9.6 || ^10.0",
"spatie/phpunit-snapshot-assertions": "^4.2 || ^5.0",
"vimeo/psalm": "^5.6"
"friendsofphp/php-cs-fixer": "^3.48",
"phpunit/phpunit": "^10.1",
"spatie/phpunit-snapshot-assertions": "^5.1",
"vimeo/psalm": "^5.20"
},
"autoload": {
"psr-4": {
Expand Down
21 changes: 18 additions & 3 deletions src/Generators/Ics.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ class Ics implements Generator
/** @var array<non-empty-string, non-empty-string> */
protected $options = [];

/** @var array{format?: string} */
protected $presentationOptions = [];

/**
* @param array<non-empty-string, non-empty-string> $options
* @param array<non-empty-string, non-empty-string> $options Optional ICS properties and components
* @param array{format?: string} $presentationOptions
*/
public function __construct(array $options = [])
public function __construct(array $options = [], array $presentationOptions = [])
{
$this->options = $options;
$this->presentationOptions = $presentationOptions;
}

/** {@inheritDoc} */
Expand Down Expand Up @@ -64,14 +69,24 @@ public function generate(Link $link): string
$url[] = 'END:VEVENT';
$url[] = 'END:VCALENDAR';

return $this->buildLink($url);
$format = $this->presentationOptions['format'] ?? 'html';

return match ($format) {
'file' => $this->buildFile($url),
default => $this->buildLink($url),
};
}

protected function buildLink(array $propertiesAndComponents): string
{
return 'data:text/calendar;charset=utf8;base64,'.base64_encode(implode("\r\n", $propertiesAndComponents));
}

protected function buildFile(array $propertiesAndComponents): string
{
return implode("\r\n", $propertiesAndComponents);
}

/** @see https://tools.ietf.org/html/rfc5545.html#section-3.3.11 */
protected function escapeString(string $field): string
{
Expand Down
7 changes: 4 additions & 3 deletions src/Link.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,13 @@ public function google(): string
}

/**
* @param array<non-empty-string, non-empty-string> $options
* @param array<non-empty-string, non-empty-string> $options ICS specific properties and components
* @param array{format?: string} $presentationOptions
* @return string
*/
public function ics(array $options = []): string
public function ics(array $options = [], array $presentationOptions = []): string
{
return $this->formatWith(new Ics($options));
return $this->formatWith(new Ics($options, $presentationOptions));
}

public function yahoo(): string
Expand Down
25 changes: 14 additions & 11 deletions tests/Generators/IcsGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,10 @@ class IcsGeneratorTest extends TestCase
* @param array $options @see \Spatie\CalendarLinks\Generators\Ics::__construct
* @return \Spatie\CalendarLinks\Generator
*/
protected function generator(array $options = []): Generator
protected function generator(array $options = [], array $presentationOptions = []): Generator
{
// extend base class just to make output more readable and simplify reviewing of the snapshot diff
return new class($options) extends Ics {
protected function buildLink(array $propertiesAndComponents): string
{
return implode("\r\n", $propertiesAndComponents);
}
};
$presentationOptions['format'] ??= 'file';
return new Ics($options, $presentationOptions);
}

protected function linkMethodName(): string
Expand All @@ -34,23 +29,31 @@ protected function linkMethodName(): string
public function it_can_generate_an_ics_link_with_custom_uid(): void
{
$this->assertMatchesSnapshot(
$this->generator(['UID' => 'random-uid'])->generate($this->createShortEventLink())
$this->generator(['UID' => 'random-uid', ['format' => 'file']])->generate($this->createShortEventLink())
);
}

/** @test */
public function it_has_a_product_id(): void
{
$this->assertMatchesSnapshot(
$this->generator(['PRODID' => 'Spatie calendar-links'])->generate($this->createShortEventLink())
$this->generator(['PRODID' => 'Spatie calendar-links'], ['format' => 'file'])->generate($this->createShortEventLink())
);
}

/** @test */
public function it_has_a_product_dtstamp(): void
{
$this->assertMatchesSnapshot(
$this->generator(['DTSTAMP' => '20180201T090000Z'])->generate($this->createShortEventLink())
$this->generator(['DTSTAMP' => '20180201T090000Z'], ['format' => 'file'])->generate($this->createShortEventLink())
);
}

/** @test */
public function it_generates_base64_encoded_link_for_html(): void
{
$this->assertMatchesSnapshot(
$this->generator([], ['format' => 'html'])->generate($this->createShortEventLink())
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
data:text/calendar;charset=utf8;base64,QkVHSU46VkNBTEVOREFSDQpWRVJTSU9OOjIuMA0KUFJPRElEOlNwYXRpZSBjYWxlbmRhci1saW5rcw0KQkVHSU46VkVWRU5UDQpVSUQ6OTRhYjc1YWRkODRhNjdjMDE5ZWFlNTc1Mzk2NTgwMzYNClNVTU1BUlk6QmlydGhkYXkNCkRUU1RBTVA6MjAxODAyMDFUMDkwMDAwWg0KRFRTVEFSVDoyMDE4MDIwMVQwOTAwMDBaDQpEVEVORDoyMDE4MDIwMVQxODAwMDBaDQpERVNDUklQVElPTjpXaXRoIGJhbGxvb25zXCwgY2xvd25zIGFuZCBzdHVmZlxuQnJpbmcgYSBkb2dcLCBicmluZyBhIGZyb2cNCkxPQ0FUSU9OOlBhcnR5IExhbmUgMUFcLCAxMzM3IEZ1bnRvd24NCkVORDpWRVZFTlQNCkVORDpWQ0FMRU5EQVI=

0 comments on commit f0e946b

Please sign in to comment.