From dc4b8a62ca9ba6edea49c4c3d27732a02658b672 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 9 Oct 2019 11:14:35 +0200 Subject: [PATCH 001/165] fix Bad file descriptor (7.4) (#469) --- tests/VObject/Parser/MimeDirTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/VObject/Parser/MimeDirTest.php b/tests/VObject/Parser/MimeDirTest.php index 671c23064..309068854 100644 --- a/tests/VObject/Parser/MimeDirTest.php +++ b/tests/VObject/Parser/MimeDirTest.php @@ -16,7 +16,7 @@ class MimeDirTest extends TestCase public function testParseError() { $mimeDir = new MimeDir(); - $mimeDir->parse(fopen(__FILE__, 'a')); + $mimeDir->parse(fopen(__FILE__, 'a+')); } public function testDecodeLatin1() From 26d8ecfb77d62de4ea38c99679012dc46563f077 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Wed, 9 Oct 2019 11:15:35 +0200 Subject: [PATCH 002/165] travis: allow failure for phpstan for now (#470) --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 686982b66..4bf5e44df 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,8 @@ matrix: fast_finish: true allow_failures: - php: 5.5 + - php: 7.2 + env: RUN_PHPSTAN="TRUE" install: - if [ $RUN_PHPSTAN == "TRUE" ]; then wget https://github.com/phpstan/phpstan/releases/download/0.11.8/phpstan.phar; fi From c2d75dbbc8dc0e15e0beb1f9a9c7baa5221aee44 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Wed, 9 Oct 2019 11:33:37 +0200 Subject: [PATCH 003/165] travis: add php 7.4snapshot build (#471) --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 4bf5e44df..4562f4440 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ php: - 7.1 - 7.2 - 7.3 + - 7.4snapshot env: global: From ebe974884ef45cd6b62472b5942f8839ae48b5c9 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Wed, 9 Oct 2019 11:53:23 +0200 Subject: [PATCH 004/165] reduce phpstan level back to 0, as level 1 is failing right now (#472) * reduce phpstan level back to 0, as level 1 is failing right now * travis: no longer allow failures for phpstan --- .travis.yml | 2 -- phpstan.neon | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4562f4440..64b055bf1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,8 +21,6 @@ matrix: fast_finish: true allow_failures: - php: 5.5 - - php: 7.2 - env: RUN_PHPSTAN="TRUE" install: - if [ $RUN_PHPSTAN == "TRUE" ]; then wget https://github.com/phpstan/phpstan/releases/download/0.11.8/phpstan.phar; fi diff --git a/phpstan.neon b/phpstan.neon index 241663a72..e50c5be6e 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,3 +1,3 @@ parameters: - level: 1 + level: 0 bootstrap: %currentWorkingDirectory%/vendor/autoload.php From 2de7a4c76a20c8cc8debd9046f434e7a95614fa2 Mon Sep 17 00:00:00 2001 From: Dominik Date: Wed, 13 Nov 2019 22:36:52 +0100 Subject: [PATCH 005/165] Fixed typo in vobject CLI help (#477) --- lib/Cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cli.php b/lib/Cli.php index 70b5e8d6e..8350719a4 100644 --- a/lib/Cli.php +++ b/lib/Cli.php @@ -289,7 +289,7 @@ protected function showHelp() $this->log($this->colorize('green', ' validate').' source_file Validates a file for correctness.'); $this->log($this->colorize('green', ' repair').' source_file [output_file] Repairs a file.'); $this->log($this->colorize('green', ' convert').' source_file [output_file] Converts a file.'); - $this->log($this->colorize('green', ' color').' source_file Colorize a file, useful for debbugging.'); + $this->log($this->colorize('green', ' color').' source_file Colorize a file, useful for debugging.'); $this->log( << Date: Wed, 18 Dec 2019 20:29:43 +0100 Subject: [PATCH 006/165] Release 4.2.1 (#479) * Release 4.2.1 * Update CHANGELOG.md --- CHANGELOG.md | 10 ++++++++++ lib/Version.php | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a2c935fb..3f70f37db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,16 @@ ChangeLog ========= +4.2.1 (2019-12-18) +------------------ + +* #469, #451: fix compat with php 7.4 +* #443: prevent running in indefinte loop +* #449: Preventing creating a component for a root document +* #450: Fix parse with option Forgiving with trailing equal +* #459: fixed typo in VCalendar which resulting in usage of the wrong TimeZone +* #462: Broker::parseEventForOrganizer copies DTSTAMP from $eventInfo that causes broken scheduling + 4.2.0 (2019-02-19) ------------------ diff --git a/lib/Version.php b/lib/Version.php index 257e66a79..b728f216d 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.2.0'; + const VERSION = '4.2.1'; } From 1356b64c885208f5386ce994f744d686d73b2faf Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Wed, 18 Dec 2019 20:40:38 +0100 Subject: [PATCH 007/165] Prepare next iteration (#480) --- CHANGELOG.md | 5 +++++ lib/Version.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f70f37db..9e4ec65dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ ChangeLog ========= +4.2.2-dev (XXXX-XX-XX) +------------------ + +* + 4.2.1 (2019-12-18) ------------------ diff --git a/lib/Version.php b/lib/Version.php index b728f216d..15d74ce1b 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.2.1'; + const VERSION = '4.2.2-dev'; } From 26673bbae7245e53e06b305473406331fdda063e Mon Sep 17 00:00:00 2001 From: Jeroen van Oort Date: Thu, 2 Jan 2020 14:53:39 +0100 Subject: [PATCH 008/165] Run phpstan on PHP >= 7.1 (#483) --- .travis.yml | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 64b055bf1..822a753e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ language: php -sudo: required php: - 5.5 - 5.6 @@ -7,31 +6,23 @@ php: - 7.1 - 7.2 - 7.3 - - 7.4snapshot - -env: - global: - - RUN_PHPSTAN="FALSE" + - 7.4 matrix: - include: - - name: 'PHPStan' - php: 7.2 - env: RUN_PHPSTAN="TRUE" fast_finish: true allow_failures: - php: 5.5 install: - - if [ $RUN_PHPSTAN == "TRUE" ]; then wget https://github.com/phpstan/phpstan/releases/download/0.11.8/phpstan.phar; fi + - if [[ $TRAVIS_PHP_VERSION =~ ^7\.1|7\.2|7\.3|7\.4$ ]]; then wget https://github.com/phpstan/phpstan/releases/download/0.12.3/phpstan.phar; fi before_script: - composer install script: - - if [ $RUN_PHPSTAN == "FALSE" ]; then ./bin/phpunit --configuration tests/phpunit.xml --coverage-clover=coverage.xml; fi - - if [ $RUN_PHPSTAN == "TRUE" ]; then php phpstan.phar analyse -c phpstan.neon lib; fi - + - if [[ $TRAVIS_PHP_VERSION =~ ^7\.1|7\.2|7\.3|7\.4$ ]]; then php phpstan.phar analyse -c phpstan.neon lib; fi + - ./bin/phpunit --configuration tests/phpunit.xml --coverage-clover=coverage.xml + after_success: - bash <(curl -s https://codecov.io/bash) From 7642fd7fdaac96e42fd85ff3b103a7555b84832b Mon Sep 17 00:00:00 2001 From: Renaud BOYER Date: Thu, 11 Jul 2019 12:34:52 +0200 Subject: [PATCH 009/165] Add TZ in iTip REPLY messages --- lib/ITip/Broker.php | 23 ++-- .../VObject/ITip/BrokerAttendeeReplyTest.php | 118 ++++++++++++++++++ tests/VObject/ITip/BrokerProcessReplyTest.php | 99 +++++++++++++++ tests/VObject/ITip/BrokerTester.php | 4 +- 4 files changed, 231 insertions(+), 13 deletions(-) diff --git a/lib/ITip/Broker.php b/lib/ITip/Broker.php index 4f37b75d0..ea27b3b3e 100644 --- a/lib/ITip/Broker.php +++ b/lib/ITip/Broker.php @@ -505,20 +505,21 @@ protected function parseEventForOrganizer(VCalendar $calendar, array $eventInfo, $message->recipient = $attendee['href']; $message->recipientName = $attendee['name']; + // Creating the new iCalendar body. + $icalMsg = new VCalendar(); + + foreach ($calendar->select('VTIMEZONE') as $timezone) { + $icalMsg->add(clone $timezone); + } + if (!$attendee['newInstances']) { // If there are no instances the attendee is a part of, it // means the attendee was removed and we need to send him a // CANCEL. $message->method = 'CANCEL'; - // Creating the new iCalendar body. - $icalMsg = new VCalendar(); $icalMsg->METHOD = $message->method; - foreach ($calendar->select('VTIMEZONE') as $timezone) { - $icalMsg->add(clone $timezone); - } - $event = $icalMsg->add('VEVENT', [ 'UID' => $message->uid, 'SEQUENCE' => $message->sequence, @@ -545,14 +546,8 @@ protected function parseEventForOrganizer(VCalendar $calendar, array $eventInfo, // The attendee gets the updated event body $message->method = 'REQUEST'; - // Creating the new iCalendar body. - $icalMsg = new VCalendar(); $icalMsg->METHOD = $message->method; - foreach ($calendar->select('VTIMEZONE') as $timezone) { - $icalMsg->add(clone $timezone); - } - // We need to find out that this change is significant. If it's // not, systems may opt to not send messages. // @@ -711,6 +706,10 @@ protected function parseEventForAttendee(VCalendar $calendar, array $eventInfo, $icalMsg = new VCalendar(); $icalMsg->METHOD = 'REPLY'; + foreach ($calendar->select('VTIMEZONE') as $timezone) { + $icalMsg->add(clone $timezone); + } + $hasReply = false; foreach ($instances as $instance) { diff --git a/tests/VObject/ITip/BrokerAttendeeReplyTest.php b/tests/VObject/ITip/BrokerAttendeeReplyTest.php index cd0c7bb66..71008c6ae 100644 --- a/tests/VObject/ITip/BrokerAttendeeReplyTest.php +++ b/tests/VObject/ITip/BrokerAttendeeReplyTest.php @@ -68,6 +68,124 @@ public function testAccepted() $this->parse($oldMessage, $newMessage, $expected); } + public function testAcceptedWithTz() + { + $oldMessage = << 'foobar', + 'method' => 'REPLY', + 'component' => 'VEVENT', + 'sender' => 'mailto:one@example.org', + 'senderName' => 'One', + 'recipient' => 'mailto:strunk@example.org', + 'recipientName' => 'Strunk', + 'message' => <<parse($oldMessage, $newMessage, $expected); + } + public function testRecurringReply() { $oldMessage = <<process($itip, $old, $expected); } + public function testReplyWithTz() + { + $itip = <<process($itip, $old, $expected); + } + public function testReplyRequestStatus() { $itip = <<getComponents() as $mainComponent) { - break; + if ('VEVENT' === $mainComponent->name) { + break; + } } $message = new Message(); From 82d2d6a582c41a767752c35041f044e2dc878b5c Mon Sep 17 00:00:00 2001 From: Jeroen van Oort Date: Sat, 4 Jan 2020 10:29:40 +0100 Subject: [PATCH 010/165] Added phpstan for tests folder (#485) --- .travis.yml | 2 +- composer.json | 5 ++ lib/PHPUnitAssertions.php | 3 +- tests/VObject/CliTest.php | 3 + tests/VObject/Component/VCardTest.php | 6 +- tests/VObject/FreeBusyGeneratorTest.php | 2 +- tests/VObject/JCalTest.php | 42 +++++----- tests/VObject/JCardTest.php | 36 ++++---- tests/VObject/Parser/JsonTest.php | 82 +++++++++---------- .../EventIterator/ByMonthInDailyTest.php | 2 +- .../Recur/EventIterator/BySetPosHangTest.php | 2 +- .../EventIterator/InfiniteLoopProblemTest.php | 3 + .../Recur/EventIterator/Issue48Test.php | 6 +- .../Recur/EventIterator/Issue50Test.php | 6 +- .../Recur/EventIterator/NoInstancesTest.php | 3 +- .../EventIterator/OverrideFirstEventTest.php | 2 +- .../SameDateForRecurringEventsTest.php | 3 +- tests/VObject/TimeZoneUtilTest.php | 2 +- tests/bootstrap.php | 2 - 19 files changed, 113 insertions(+), 99 deletions(-) diff --git a/.travis.yml b/.travis.yml index 822a753e0..e449565e3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ before_script: - composer install script: - - if [[ $TRAVIS_PHP_VERSION =~ ^7\.1|7\.2|7\.3|7\.4$ ]]; then php phpstan.phar analyse -c phpstan.neon lib; fi + - if [[ $TRAVIS_PHP_VERSION =~ ^7\.1|7\.2|7\.3|7\.4$ ]]; then php phpstan.phar analyse -c phpstan.neon lib tests; fi - ./bin/phpunit --configuration tests/phpunit.xml --coverage-clover=coverage.xml after_success: diff --git a/composer.json b/composer.json index ad026879e..bd7892464 100644 --- a/composer.json +++ b/composer.json @@ -71,6 +71,11 @@ "Sabre\\VObject\\" : "lib/" } }, + "autoload-dev" : { + "psr-4" : { + "Sabre\\VObject\\" : "tests/VObject" + } + }, "bin" : [ "bin/vobject", "bin/generate_vcards" diff --git a/lib/PHPUnitAssertions.php b/lib/PHPUnitAssertions.php index d77e4b1ed..635988387 100644 --- a/lib/PHPUnitAssertions.php +++ b/lib/PHPUnitAssertions.php @@ -34,8 +34,7 @@ trait PHPUnitAssertions */ public function assertVObjectEqualsVObject($expected, $actual, $message = '') { - $self = $this; - $getObj = function ($input) use ($self) { + $getObj = function ($input) { if (is_resource($input)) { $input = stream_get_contents($input); } diff --git a/tests/VObject/CliTest.php b/tests/VObject/CliTest.php index 11c969c9d..cae424d96 100644 --- a/tests/VObject/CliTest.php +++ b/tests/VObject/CliTest.php @@ -11,6 +11,9 @@ */ class CliTest extends TestCase { + /** @var CliMock */ + private $cli; + public function setUp() { $this->cli = new CliMock(); diff --git a/tests/VObject/Component/VCardTest.php b/tests/VObject/Component/VCardTest.php index 1895ce6c5..3124fec84 100644 --- a/tests/VObject/Component/VCardTest.php +++ b/tests/VObject/Component/VCardTest.php @@ -204,7 +204,7 @@ public function testNoUIDCardDAV() VCF; $this->assertValidate( $vcard, - VCARD::PROFILE_CARDDAV, + VCard::PROFILE_CARDDAV, 3, 'vCards on CardDAV servers MUST have a UID property.' ); @@ -236,7 +236,7 @@ public function testNoUIDNoCardDAVRepair() VCF; $this->assertValidate( $vcard, - VCARD::REPAIR, + VCard::REPAIR, 1, 'Adding a UID to a vCard property is recommended.' ); @@ -253,7 +253,7 @@ public function testVCard21CardDAV() VCF; $this->assertValidate( $vcard, - VCARD::PROFILE_CARDDAV, + VCard::PROFILE_CARDDAV, 3, 'CardDAV servers are not allowed to accept vCard 2.1.' ); diff --git a/tests/VObject/FreeBusyGeneratorTest.php b/tests/VObject/FreeBusyGeneratorTest.php index 323cf632b..e2dd59409 100644 --- a/tests/VObject/FreeBusyGeneratorTest.php +++ b/tests/VObject/FreeBusyGeneratorTest.php @@ -30,7 +30,7 @@ public function testInvalidArg() $gen = new FreeBusyGenerator( new \DateTime('2012-01-01'), new \DateTime('2012-12-31'), - new \StdClass() + new \stdClass() ); } diff --git a/tests/VObject/JCalTest.php b/tests/VObject/JCalTest.php index d2de80281..9332b6413 100644 --- a/tests/VObject/JCalTest.php +++ b/tests/VObject/JCalTest.php @@ -43,19 +43,19 @@ public function testToJCal() [ [ 'version', - new \StdClass(), + new \stdClass(), 'text', '2.0', ], [ 'prodid', - new \StdClass(), + new \stdClass(), 'text', '-//Sabre//Sabre VObject '.Version::VERSION.'//EN', ], [ 'calscale', - new \StdClass(), + new \stdClass(), 'text', 'GREGORIAN', ], @@ -64,22 +64,22 @@ public function testToJCal() ['vevent', [ [ - 'uid', new \StdClass(), 'text', 'foo', + 'uid', new \stdClass(), 'text', 'foo', ], [ - 'dtstart', new \StdClass(), 'date', '2013-05-26', + 'dtstart', new \stdClass(), 'date', '2013-05-26', ], [ - 'duration', new \StdClass(), 'duration', 'P1D', + 'duration', new \stdClass(), 'duration', 'P1D', ], [ - 'categories', new \StdClass(), 'text', 'home', 'testing', + 'categories', new \stdClass(), 'text', 'home', 'testing', ], [ - 'created', new \StdClass(), 'date-time', '2013-05-26T18:10:00Z', + 'created', new \stdClass(), 'date-time', '2013-05-26T18:10:00Z', ], [ - 'attendee', new \StdClass(), 'cal-address', 'mailto:armin@example.org', + 'attendee', new \stdClass(), 'cal-address', 'mailto:armin@example.org', ], [ 'attendee', @@ -91,50 +91,50 @@ public function testToJCal() 'mailto:dominik@example.org', ], [ - 'geo', new \StdClass(), 'float', [51.96668, 7.61876], + 'geo', new \stdClass(), 'float', [51.96668, 7.61876], ], [ - 'sequence', new \StdClass(), 'integer', 5, + 'sequence', new \stdClass(), 'integer', 5, ], [ - 'freebusy', new \StdClass(), 'period', ['2013-05-26T21:02:13', 'PT1H'], ['2013-06-26T12:00:00', '2013-06-26T13:00:00'], + 'freebusy', new \stdClass(), 'period', ['2013-05-26T21:02:13', 'PT1H'], ['2013-06-26T12:00:00', '2013-06-26T13:00:00'], ], [ - 'url', new \StdClass(), 'uri', 'http://example.org/', + 'url', new \stdClass(), 'uri', 'http://example.org/', ], [ - 'tzoffsetfrom', new \StdClass(), 'utc-offset', '+05:00', + 'tzoffsetfrom', new \stdClass(), 'utc-offset', '+05:00', ], [ - 'rrule', new \StdClass(), 'recur', [ + 'rrule', new \stdClass(), 'recur', [ 'freq' => 'WEEKLY', 'byday' => ['MO', 'TU'], ], ], [ - 'x-bool', new \StdClass(), 'boolean', true, + 'x-bool', new \stdClass(), 'boolean', true, ], [ - 'x-time', new \StdClass(), 'time', '08:00:00', + 'x-time', new \stdClass(), 'time', '08:00:00', ], [ - 'attach', new \StdClass(), 'binary', base64_encode('attachment'), + 'attach', new \stdClass(), 'binary', base64_encode('attachment'), ], [ 'request-status', - new \StdClass(), + new \stdClass(), 'text', ['2.0', 'Success'], ], [ 'request-status', - new \StdClass(), + new \stdClass(), 'text', ['3.7', 'Invalid Calendar User', 'ATTENDEE:mailto:jsmith@example.org'], ], [ 'dtend', - new \StdClass(), + new \stdClass(), 'date-time', '2015-01-08T13:30:00', ], diff --git a/tests/VObject/JCardTest.php b/tests/VObject/JCardTest.php index 2100a07a9..1864f666d 100644 --- a/tests/VObject/JCardTest.php +++ b/tests/VObject/JCardTest.php @@ -48,25 +48,25 @@ public function testToJCard() [ [ 'version', - new \StdClass(), + new \stdClass(), 'text', '4.0', ], [ 'prodid', - new \StdClass(), + new \stdClass(), 'text', '-//Sabre//Sabre VObject '.Version::VERSION.'//EN', ], [ 'uid', - new \StdClass(), + new \stdClass(), 'text', 'foo', ], [ 'bday', - new \StdClass(), + new \stdClass(), 'date-and-or-time', '1985-04-07', ], @@ -80,25 +80,25 @@ public function testToJCard() ], [ 'bday', - new \StdClass(), + new \stdClass(), 'date-time', '1979-12-25T02:00:00', ], [ 'rev', - new \StdClass(), + new \stdClass(), 'timestamp', '1995-10-31T22:27:10Z', ], [ 'lang', - new \StdClass(), + new \stdClass(), 'language-tag', 'nl', ], [ 'n', - new \StdClass(), + new \stdClass(), 'text', ['Last', 'First', 'Middle', '', ''], ], @@ -120,7 +120,7 @@ public function testToJCard() ], [ 'adr', - new \StdClass(), + new \stdClass(), 'text', [ '', @@ -134,55 +134,55 @@ public function testToJCard() ], [ 'x-truncated', - new \StdClass(), + new \stdClass(), 'date', '--12-25', ], [ 'x-time-local', - new \StdClass(), + new \stdClass(), 'time', '12:30:00', ], [ 'x-time-utc', - new \StdClass(), + new \stdClass(), 'time', '12:30:00Z', ], [ 'x-time-offset', - new \StdClass(), + new \stdClass(), 'time', '12:30:00-08:00', ], [ 'x-time-reduced', - new \StdClass(), + new \stdClass(), 'time', '23', ], [ 'x-time-truncated', - new \StdClass(), + new \stdClass(), 'time', '--30', ], [ 'x-karma-points', - new \StdClass(), + new \stdClass(), 'integer', 42, ], [ 'x-grade', - new \StdClass(), + new \stdClass(), 'float', 1.3, ], [ 'tz', - new \StdClass(), + new \stdClass(), 'utc-offset', '-05:00', ], diff --git a/tests/VObject/Parser/JsonTest.php b/tests/VObject/Parser/JsonTest.php index 587f55f70..2aa0d9dab 100644 --- a/tests/VObject/Parser/JsonTest.php +++ b/tests/VObject/Parser/JsonTest.php @@ -14,25 +14,25 @@ public function testRoundTripJCard() [ [ 'version', - new \StdClass(), + new \stdClass(), 'text', '4.0', ], [ 'prodid', - new \StdClass(), + new \stdClass(), 'text', '-//Sabre//Sabre VObject '.VObject\Version::VERSION.'//EN', ], [ 'uid', - new \StdClass(), + new \stdClass(), 'text', 'foo', ], [ 'bday', - new \StdClass(), + new \stdClass(), 'date-and-or-time', '1985-04-07', ], @@ -46,25 +46,25 @@ public function testRoundTripJCard() ], [ 'bday', - new \StdClass(), + new \stdClass(), 'date-time', '1979-12-25T02:00:00', ], [ 'rev', - new \StdClass(), + new \stdClass(), 'timestamp', '1995-10-31T22:27:10Z', ], [ 'lang', - new \StdClass(), + new \stdClass(), 'language-tag', 'nl', ], [ 'n', - new \StdClass(), + new \stdClass(), 'text', ['Last', 'First', 'Middle', '', ''], ], @@ -86,7 +86,7 @@ public function testRoundTripJCard() ], [ 'adr', - new \StdClass(), + new \stdClass(), 'text', [ '', @@ -101,55 +101,55 @@ public function testRoundTripJCard() [ 'x-truncated', - new \StdClass(), + new \stdClass(), 'date', '--12-25', ], [ 'x-time-local', - new \StdClass(), + new \stdClass(), 'time', '12:30:00', ], [ 'x-time-utc', - new \StdClass(), + new \stdClass(), 'time', '12:30:00Z', ], [ 'x-time-offset', - new \StdClass(), + new \stdClass(), 'time', '12:30:00-08:00', ], [ 'x-time-reduced', - new \StdClass(), + new \stdClass(), 'time', '23', ], [ 'x-time-truncated', - new \StdClass(), + new \stdClass(), 'time', '--30', ], [ 'x-karma-points', - new \StdClass(), + new \stdClass(), 'integer', 42, ], [ 'x-grade', - new \StdClass(), + new \stdClass(), 'float', 1.3, ], [ 'tz', - new \StdClass(), + new \stdClass(), 'utc-offset', '-05:00', ], @@ -203,19 +203,19 @@ public function testRoundTripJCal() [ [ 'version', - new \StdClass(), + new \stdClass(), 'text', '2.0', ], [ 'prodid', - new \StdClass(), + new \stdClass(), 'text', '-//Sabre//Sabre VObject '.VObject\Version::VERSION.'//EN', ], [ 'calscale', - new \StdClass(), + new \stdClass(), 'text', 'GREGORIAN', ], @@ -224,25 +224,25 @@ public function testRoundTripJCal() ['vevent', [ [ - 'uid', new \StdClass(), 'text', 'foo', + 'uid', new \stdClass(), 'text', 'foo', ], [ - 'dtstart', new \StdClass(), 'date', '2013-05-26', + 'dtstart', new \stdClass(), 'date', '2013-05-26', ], [ - 'duration', new \StdClass(), 'duration', 'P1D', + 'duration', new \stdClass(), 'duration', 'P1D', ], [ - 'categories', new \StdClass(), 'text', 'home', 'testing', + 'categories', new \stdClass(), 'text', 'home', 'testing', ], [ - 'created', new \StdClass(), 'date-time', '2013-05-26T18:10:00Z', + 'created', new \stdClass(), 'date-time', '2013-05-26T18:10:00Z', ], [ - 'attach', new \StdClass(), 'binary', base64_encode('attachment'), + 'attach', new \stdClass(), 'binary', base64_encode('attachment'), ], [ - 'attendee', new \StdClass(), 'cal-address', 'mailto:armin@example.org', + 'attendee', new \stdClass(), 'cal-address', 'mailto:armin@example.org', ], [ 'attendee', @@ -254,41 +254,41 @@ public function testRoundTripJCal() 'mailto:dominik@example.org', ], [ - 'geo', new \StdClass(), 'float', [51.96668, 7.61876], + 'geo', new \stdClass(), 'float', [51.96668, 7.61876], ], [ - 'sequence', new \StdClass(), 'integer', 5, + 'sequence', new \stdClass(), 'integer', 5, ], [ - 'freebusy', new \StdClass(), 'period', ['2013-05-26T21:02:13', 'PT1H'], ['2013-06-26T12:00:00', '2013-06-26T13:00:00'], + 'freebusy', new \stdClass(), 'period', ['2013-05-26T21:02:13', 'PT1H'], ['2013-06-26T12:00:00', '2013-06-26T13:00:00'], ], [ - 'url', new \StdClass(), 'uri', 'http://example.org/', + 'url', new \stdClass(), 'uri', 'http://example.org/', ], [ - 'tzoffsetfrom', new \StdClass(), 'utc-offset', '+05:00', + 'tzoffsetfrom', new \stdClass(), 'utc-offset', '+05:00', ], [ - 'rrule', new \StdClass(), 'recur', [ + 'rrule', new \stdClass(), 'recur', [ 'freq' => 'WEEKLY', 'byday' => ['MO', 'TU'], ], ], [ - 'x-bool', new \StdClass(), 'boolean', true, + 'x-bool', new \stdClass(), 'boolean', true, ], [ - 'x-time', new \StdClass(), 'time', '08:00:00', + 'x-time', new \stdClass(), 'time', '08:00:00', ], [ 'request-status', - new \StdClass(), + new \stdClass(), 'text', ['2.0', 'Success'], ], [ 'request-status', - new \StdClass(), + new \stdClass(), 'text', ['3.7', 'Invalid Calendar User', 'ATTENDEE:mailto:jsmith@example.org'], ], @@ -297,7 +297,7 @@ public function testRoundTripJCal() ['valarm', [ [ - 'action', new \StdClass(), 'text', 'DISPLAY', + 'action', new \stdClass(), 'text', 'DISPLAY', ], ], [], @@ -358,7 +358,7 @@ public function testParseStreamArg() 'vcard', [ [ - 'FN', new \StdClass(), 'text', 'foo', + 'FN', new \stdClass(), 'text', 'foo', ], ], ]; @@ -381,7 +381,7 @@ public function testParseInvalidData() 'vlist', [ [ - 'FN', new \StdClass(), 'text', 'foo', + 'FN', new \stdClass(), 'text', 'foo', ], ], ]; diff --git a/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php b/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php index 40f09364f..71858c36f 100644 --- a/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php +++ b/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php @@ -1,6 +1,6 @@ vcal = new VCalendar(); diff --git a/tests/VObject/Recur/EventIterator/Issue48Test.php b/tests/VObject/Recur/EventIterator/Issue48Test.php index fe4b06755..f08f0ccce 100644 --- a/tests/VObject/Recur/EventIterator/Issue48Test.php +++ b/tests/VObject/Recur/EventIterator/Issue48Test.php @@ -1,10 +1,12 @@ assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal); - $it = new Recur\EventIterator($vcal, 'foo'); + $it = new EventIterator($vcal, 'foo'); $result = iterator_to_array($it); diff --git a/tests/VObject/Recur/EventIterator/Issue50Test.php b/tests/VObject/Recur/EventIterator/Issue50Test.php index df9c15519..faa04e829 100644 --- a/tests/VObject/Recur/EventIterator/Issue50Test.php +++ b/tests/VObject/Recur/EventIterator/Issue50Test.php @@ -1,10 +1,12 @@ assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal); - $it = new Recur\EventIterator($vcal, '1aef0b27-3d92-4581-829a-11999dd36724'); + $it = new EventIterator($vcal, '1aef0b27-3d92-4581-829a-11999dd36724'); $result = []; foreach ($it as $instance) { diff --git a/tests/VObject/Recur/EventIterator/NoInstancesTest.php b/tests/VObject/Recur/EventIterator/NoInstancesTest.php index b3e5a11fa..24810db14 100644 --- a/tests/VObject/Recur/EventIterator/NoInstancesTest.php +++ b/tests/VObject/Recur/EventIterator/NoInstancesTest.php @@ -1,9 +1,10 @@ addPsr4('Sabre\\VObject\\', __DIR__.'/VObject'); - if (!defined('SABRE_TEMPDIR')) { define('SABRE_TEMPDIR', __DIR__.'/temp/'); } From 17e6eea2e3726fee370e64cecf638f250448bbe3 Mon Sep 17 00:00:00 2001 From: Christian Kraus Date: Mon, 6 Jan 2020 08:48:20 +0100 Subject: [PATCH 011/165] Add PHONE-NUMBER value type (used for TEL in vCard 3.0) (#486) Signed-off-by: Christian Kraus --- lib/Component/VCard.php | 1 + lib/Property/VCard/PhoneNumber.php | 30 +++++++++++++++++++ lib/VCardConverter.php | 3 ++ .../Property/VCard/PhoneNumberTest.php | 19 ++++++++++++ tests/VObject/VCardConverterTest.php | 30 +++++++++++++++++++ 5 files changed, 83 insertions(+) create mode 100644 lib/Property/VCard/PhoneNumber.php create mode 100644 tests/VObject/Property/VCard/PhoneNumberTest.php diff --git a/lib/Component/VCard.php b/lib/Component/VCard.php index 860e45ffa..4d7e861a2 100644 --- a/lib/Component/VCard.php +++ b/lib/Component/VCard.php @@ -57,6 +57,7 @@ class VCard extends VObject\Document 'FLOAT' => 'Sabre\\VObject\\Property\\FloatValue', 'INTEGER' => 'Sabre\\VObject\\Property\\IntegerValue', 'LANGUAGE-TAG' => 'Sabre\\VObject\\Property\\VCard\\LanguageTag', + 'PHONE-NUMBER' => 'Sabre\\VObject\\Property\\VCard\\PhoneNumber', // vCard 3.0 only 'TIMESTAMP' => 'Sabre\\VObject\\Property\\VCard\\TimeStamp', 'TEXT' => 'Sabre\\VObject\\Property\\Text', 'TIME' => 'Sabre\\VObject\\Property\\Time', diff --git a/lib/Property/VCard/PhoneNumber.php b/lib/Property/VCard/PhoneNumber.php new file mode 100644 index 000000000..b714ffd03 --- /dev/null +++ b/lib/Property/VCard/PhoneNumber.php @@ -0,0 +1,30 @@ + + */ +class PhoneNumber extends Property\Text +{ + protected $structuredValues = []; + + /** + * Returns the type of value. + * + * This corresponds to the VALUE= parameter. Every property also has a + * 'default' valueType. + * + * @return string + */ + public function getValueType() + { + return 'PHONE-NUMBER'; + } +} diff --git a/lib/VCardConverter.php b/lib/VCardConverter.php index 156b83b4e..bc80abee9 100644 --- a/lib/VCardConverter.php +++ b/lib/VCardConverter.php @@ -83,6 +83,9 @@ protected function convertProperty(Component\VCard $input, Component\VCard $outp if (!$valueType) { $valueType = $property->getValueType(); } + if (Document::VCARD30 !== $targetVersion && 'PHONE-NUMBER' === $valueType) { + $valueType = null; + } $newProperty = $output->createProperty( $property->name, $property->getParts(), diff --git a/tests/VObject/Property/VCard/PhoneNumberTest.php b/tests/VObject/Property/VCard/PhoneNumberTest.php new file mode 100644 index 000000000..4a54d3333 --- /dev/null +++ b/tests/VObject/Property/VCard/PhoneNumberTest.php @@ -0,0 +1,19 @@ +assertInstanceOf('Sabre\VObject\Property\VCard\PhoneNumber', $vCard->TEL); + $this->assertEquals('PHONE-NUMBER', $vCard->TEL->getValueType()); + $this->assertEquals($input, $vCard->serialize()); + } +} diff --git a/tests/VObject/VCardConverterTest.php b/tests/VObject/VCardConverterTest.php index a5be3cc8c..72c3ac64a 100644 --- a/tests/VObject/VCardConverterTest.php +++ b/tests/VObject/VCardConverterTest.php @@ -518,4 +518,34 @@ public function testNoLabel() $this->assertEquals($expected, str_replace("\r", '', $vcard)); } + + public function testPhoneNumberValueTypeGetsRemoved() + { + $input = <<convert(Document::VCARD40); + + $this->assertVObjectEqualsVObject( + $output, + $vcard + ); + } } From 346bd88bdc857b4d2b680e290921d8af23aa605a Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Tue, 14 Jan 2020 15:40:47 +0545 Subject: [PATCH 012/165] use latest phpstan 0.12.5 in CI --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e449565e3..a36b67c47 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ matrix: - php: 5.5 install: - - if [[ $TRAVIS_PHP_VERSION =~ ^7\.1|7\.2|7\.3|7\.4$ ]]; then wget https://github.com/phpstan/phpstan/releases/download/0.12.3/phpstan.phar; fi + - if [[ $TRAVIS_PHP_VERSION =~ ^7\.1|7\.2|7\.3|7\.4$ ]]; then wget https://github.com/phpstan/phpstan/releases/download/0.12.5/phpstan.phar; fi before_script: - composer install From c14af2a7fb87cb42abf11c43f84912344af5f8a7 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Tue, 14 Jan 2020 15:41:42 +0545 Subject: [PATCH 013/165] Add PHPstorm .idea to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f08b31359..f723749ef 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ bin/hoa # Development stuff testdata/ .php_cs.cache +.idea # OS X .DS_Store From 0fec2b0c475f9318353b4a9c50441470397f6da4 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Tue, 14 Jan 2020 15:42:20 +0545 Subject: [PATCH 014/165] Fix various typos --- lib/Cli.php | 4 ++-- lib/Component.php | 2 +- lib/Component/VEvent.php | 2 +- lib/PHPUnitAssertions.php | 2 +- lib/Parser/MimeDir.php | 4 ++-- lib/Parser/XML/Element/KeyValue.php | 2 +- lib/Property/Boolean.php | 2 +- lib/Property/IntegerValue.php | 2 +- lib/Property/Text.php | 2 +- lib/Property/Uri.php | 2 +- lib/Recur/NoInstancesException.php | 2 +- lib/Recur/RRuleIterator.php | 6 +++--- lib/Settings.php | 2 +- lib/TimeZoneUtil.php | 2 +- lib/VCardConverter.php | 2 +- 15 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/Cli.php b/lib/Cli.php index 8350719a4..be795e9e2 100644 --- a/lib/Cli.php +++ b/lib/Cli.php @@ -29,7 +29,7 @@ class Cli protected $showHelp = false; /** - * Wether to spit out 'mimedir' or 'json' format. + * Whether to spit out 'mimedir' or 'json' format. * * @var string */ @@ -516,7 +516,7 @@ protected function serializeComponent(Component $vObj) * * A higher score means the item will be lower in the list. * To avoid score collisions, each "score category" has a reasonable - * space to accomodate elements. The $key is added to the $score to + * space to accommodate elements. The $key is added to the $score to * preserve the original relative order of elements. * * @param int $key diff --git a/lib/Component.php b/lib/Component.php index a33b7d577..d4d8506d8 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -276,7 +276,7 @@ public function serialize() * * A higher score means the item will be lower in the list. * To avoid score collisions, each "score category" has a reasonable - * space to accomodate elements. The $key is added to the $score to + * space to accommodate elements. The $key is added to the $score to * preserve the original relative order of elements. * * @param int $key diff --git a/lib/Component/VEvent.php b/lib/Component/VEvent.php index 09f37033c..4a53a7561 100644 --- a/lib/Component/VEvent.php +++ b/lib/Component/VEvent.php @@ -36,7 +36,7 @@ public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) try { $it = new EventIterator($this, null, $start->getTimezone()); } catch (NoInstancesException $e) { - // If we've catched this exception, there are no instances + // If we've caught this exception, there are no instances // for the event that fall into the specified time-range. return false; } diff --git a/lib/PHPUnitAssertions.php b/lib/PHPUnitAssertions.php index 635988387..45c0a21c6 100644 --- a/lib/PHPUnitAssertions.php +++ b/lib/PHPUnitAssertions.php @@ -15,7 +15,7 @@ trait PHPUnitAssertions { /** - * This method tests wether two vcards or icalendar objects are + * This method tests whether two vcards or icalendar objects are * semantically identical. * * It supports objects being supplied as strings, streams or diff --git a/lib/Parser/MimeDir.php b/lib/Parser/MimeDir.php index 26a7101e5..ea5ac0326 100644 --- a/lib/Parser/MimeDir.php +++ b/lib/Parser/MimeDir.php @@ -124,7 +124,7 @@ public function setInput($input) $this->startLine = 0; if (is_string($input)) { - // Convering to a stream. + // Converting to a stream. $stream = fopen('php://temp', 'r+'); fwrite($stream, $input); rewind($stream); @@ -480,7 +480,7 @@ protected function readProperty($line) * vCard 3.0 says: * * (rfc2425) Backslashes, newlines (\n or \N) and comma's must be * escaped, all time time. - * * Comma's are used for delimeters in multiple values + * * Comma's are used for delimiters in multiple values * * (rfc2426) Adds to to this that the semi-colon MUST also be escaped, * as in some properties semi-colon is used for separators. * * Properties using semi-colons: N, ADR, GEO, ORG diff --git a/lib/Parser/XML/Element/KeyValue.php b/lib/Parser/XML/Element/KeyValue.php index e26540036..c0bbf0d9b 100644 --- a/lib/Parser/XML/Element/KeyValue.php +++ b/lib/Parser/XML/Element/KeyValue.php @@ -18,7 +18,7 @@ class KeyValue extends SabreXml\Element\KeyValue /** * The deserialize method is called during xml parsing. * - * This method is called staticly, this is because in theory this method + * This method is called statically, this is because in theory this method * may be used as a type of constructor, or factory method. * * Often you want to return an instance of the current class, but you are diff --git a/lib/Property/Boolean.php b/lib/Property/Boolean.php index 1b219bb8c..0e7bc666e 100644 --- a/lib/Property/Boolean.php +++ b/lib/Property/Boolean.php @@ -8,7 +8,7 @@ /** * Boolean property. * - * This object represents BOOLEAN values. These are always the case-insenstive + * This object represents BOOLEAN values. These are always the case-insensitive * string TRUE or FALSE. * * Automatic conversion to PHP's true and false are done. diff --git a/lib/Property/IntegerValue.php b/lib/Property/IntegerValue.php index ddd71d731..24a46fb07 100644 --- a/lib/Property/IntegerValue.php +++ b/lib/Property/IntegerValue.php @@ -9,7 +9,7 @@ * Integer property. * * This object represents INTEGER values. These are always a single integer. - * They may be preceeded by either + or -. + * They may be preceded by either + or -. * * @copyright Copyright (C) fruux GmbH (https://fruux.com/) * @author Evert Pot (http://evertpot.com/) diff --git a/lib/Property/Text.php b/lib/Property/Text.php index 23c945551..ac8aa066b 100644 --- a/lib/Property/Text.php +++ b/lib/Property/Text.php @@ -111,7 +111,7 @@ public function setQuotedPrintableValue($val) // that. // // We also don't have to unescape \\, so all we need to look for is a ; - // that's not preceeded with a \. + // that's not preceded with a \. $regex = '# (?setValue($matches); diff --git a/lib/Property/Uri.php b/lib/Property/Uri.php index 3449ba1f2..830cd3f18 100644 --- a/lib/Property/Uri.php +++ b/lib/Property/Uri.php @@ -72,7 +72,7 @@ public function setRawMimeDirValue($val) { // Normally we don't need to do any type of unescaping for these // properties, however.. we've noticed that Google Contacts - // specifically escapes the colon (:) with a blackslash. While I have + // specifically escapes the colon (:) with a backslash. While I have // no clue why they thought that was a good idea, I'm unescaping it // anyway. // diff --git a/lib/Recur/NoInstancesException.php b/lib/Recur/NoInstancesException.php index b55af567d..348c02306 100644 --- a/lib/Recur/NoInstancesException.php +++ b/lib/Recur/NoInstancesException.php @@ -7,7 +7,7 @@ /** * This exception gets thrown when a recurrence iterator produces 0 instances. * - * This may happen when every occurence in a rrule is also in EXDATE. + * This may happen when every occurrence in a rrule is also in EXDATE. * * @copyright Copyright (C) fruux GmbH (https://fruux.com/) * @author Evert Pot (http://evertpot.com/) diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index 75342a2a8..7bd4b086e 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -232,7 +232,7 @@ public function fastForward(DateTimeInterface $dt) * * This is an array of weekdays * - * This may also be preceeded by a positive or negative integer. If present, + * This may also be preceded by a positive or negative integer. If present, * this indicates the nth occurrence of a specific day within the monthly or * yearly rrule. For instance, -2TU indicates the second-last tuesday of * the month, or year. @@ -771,7 +771,7 @@ protected function parseRRule($rrule) $this->byMonth = (array) $value; foreach ($this->byMonth as $byMonth) { if (!is_numeric($byMonth) || (int) $byMonth < 1 || (int) $byMonth > 12) { - throw new InvalidDataException('BYMONTH in RRULE must have value(s) betweeen 1 and 12!'); + throw new InvalidDataException('BYMONTH in RRULE must have value(s) between 1 and 12!'); } } break; @@ -948,7 +948,7 @@ protected function getDays() { $recurrenceDays = []; foreach ($this->byDay as $byDay) { - // The day may be preceeded with a positive (+n) or + // The day may be preceded with a positive (+n) or // negative (-n) integer. However, this does not make // sense in 'weekly' so we ignore it here. $recurrenceDays[] = $this->dayMap[substr($byDay, -2)]; diff --git a/lib/Settings.php b/lib/Settings.php index afc586b0c..b0bb80a82 100644 --- a/lib/Settings.php +++ b/lib/Settings.php @@ -46,7 +46,7 @@ class Settings * specific events that recur many, many times, potentially DDOSing the * server. * - * The default (3500) allows creation of a dialy event that goes on for 10 + * The default (3500) allows creation of a daily event that goes on for 10 * years, which is hopefully long enough for most. * * Set this value to -1 to disable this control altogether. diff --git a/lib/TimeZoneUtil.php b/lib/TimeZoneUtil.php index 5b1a775c2..2c407fee6 100644 --- a/lib/TimeZoneUtil.php +++ b/lib/TimeZoneUtil.php @@ -139,7 +139,7 @@ public static function getTimeZone($tzid, Component $vcalendar = null, $failIfUn // PHP has a bug that logs PHP warnings even it shouldn't: // https://bugs.php.net/bug.php?id=67881 // - // That's why we're checking if we'll be able to successfull instantiate + // That's why we're checking if we'll be able to successfully instantiate // \DateTimeZone() before doing so. Otherwise we could simply instantiate // and catch the exception. $tzIdentifiers = \DateTimeZone::listIdentifiers(); diff --git a/lib/VCardConverter.php b/lib/VCardConverter.php index bc80abee9..5a814aa2e 100644 --- a/lib/VCardConverter.php +++ b/lib/VCardConverter.php @@ -230,7 +230,7 @@ protected function convertProperty(Component\VCard $input, Component\VCard $outp // Lastly, we need to see if there's a need for a VALUE parameter. // - // We can do that by instantating a empty property with that name, and + // We can do that by instantiating a empty property with that name, and // seeing if the default valueType is identical to the current one. $tempProperty = $output->createProperty($newProperty->name); if ($tempProperty->getValueType() !== $newProperty->getValueType()) { From 449616b2d45b95c8973975de23f34a3d14f63b4b Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Tue, 14 Jan 2020 11:18:45 +0100 Subject: [PATCH 015/165] Release 4.2.2 (#490) * Release 4.2.2 * Update CHANGELOG.md --- CHANGELOG.md | 5 +++-- lib/Version.php | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e4ec65dd..4ddee77f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,11 @@ ChangeLog ========= -4.2.2-dev (XXXX-XX-XX) +4.2.2 (2020-01-14) ------------------ -* +* #465: Add TZ in iTip REPLY iTip messages +* #486: Add PHONE-NUMBER value type (used for TEL in vCard 3.0) 4.2.1 (2019-12-18) ------------------ diff --git a/lib/Version.php b/lib/Version.php index 15d74ce1b..e040dd4d9 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.2.2-dev'; + const VERSION = '4.2.2'; } From 01ab95803b5dc129d926ffe5513718b5588b707f Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Tue, 14 Jan 2020 11:19:31 +0100 Subject: [PATCH 016/165] Prepare next iteration --- lib/Version.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Version.php b/lib/Version.php index e040dd4d9..e18fc00ea 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.2.2'; + const VERSION = '4.2.3-dev'; } From df805ce64a4192624758cf2694ff73f819b0be51 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sun, 26 Jan 2020 12:26:31 +0545 Subject: [PATCH 017/165] Update dependencies and code style tools --- .gitignore | 4 ++-- .php_cs.dist | 2 +- .travis.yml | 9 ++------- composer.json | 7 ++++--- tests/phpunit.xml | 9 +++++---- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index f723749ef..8b677a5ad 100644 --- a/.gitignore +++ b/.gitignore @@ -9,9 +9,9 @@ tests/temp #binaries bin/phpunit -bin/phpcs bin/php-cs-fixer -bin/sabre-cs-fixer +bin/phpstan +bin/phpstan.phar bin/hoa # Development stuff diff --git a/.php_cs.dist b/.php_cs.dist index 8d61ee259..c5c78a971 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -6,7 +6,7 @@ $config->getFinder() ->in(__DIR__); $config->setRules([ '@PSR1' => true, - '@Symfony' =>true + '@Symfony' => true ]); return $config; \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index a36b67c47..40c54aeb3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,5 @@ language: php php: - - 5.5 - - 5.6 - - 7.0 - 7.1 - 7.2 - 7.3 @@ -10,17 +7,15 @@ php: matrix: fast_finish: true - allow_failures: - - php: 5.5 install: - - if [[ $TRAVIS_PHP_VERSION =~ ^7\.1|7\.2|7\.3|7\.4$ ]]; then wget https://github.com/phpstan/phpstan/releases/download/0.12.5/phpstan.phar; fi + - composer require --dev phpstan/phpstan:^0.12 before_script: - composer install script: - - if [[ $TRAVIS_PHP_VERSION =~ ^7\.1|7\.2|7\.3|7\.4$ ]]; then php phpstan.phar analyse -c phpstan.neon lib tests; fi + - php ./bin/phpstan.phar analyse -c phpstan.neon lib tests - ./bin/phpunit --configuration tests/phpunit.xml --coverage-clover=coverage.xml after_success: diff --git a/composer.json b/composer.json index bd7892464..7e34b74b8 100644 --- a/composer.json +++ b/composer.json @@ -32,12 +32,13 @@ "homepage" : "http://sabre.io/vobject/", "license" : "BSD-3-Clause", "require" : { - "php" : ">=5.5", + "php" : "^7.1", "ext-mbstring" : "*", - "sabre/xml" : ">=1.5 <3.0" + "sabre/xml" : "^2.1" }, "require-dev" : { - "phpunit/phpunit" : "> 4.8.35, <6.0.0" + "friendsofphp/php-cs-fixer": "2.16.*", + "phpunit/phpunit" : "^7" }, "suggest" : { "hoa/bench" : "If you would like to run the benchmark scripts" diff --git a/tests/phpunit.xml b/tests/phpunit.xml index 46dad6a3d..c9abae412 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -6,11 +6,12 @@ convertWarningsToExceptions="true" beStrictAboutTestsThatDoNotTestAnything="true" beStrictAboutOutputDuringTests="true" - beStrictAboutTestSize="true" > - - VObject/ - + + + VObject/ + + From 4c55982419964c8aa6e8e8ffdd8c5080c2fa71a7 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sun, 26 Jan 2020 17:11:07 +0545 Subject: [PATCH 018/165] Remove unneeded 'bootstrap' line from phpstan.neon --- phpstan.neon | 1 - 1 file changed, 1 deletion(-) diff --git a/phpstan.neon b/phpstan.neon index e50c5be6e..5335bc651 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,3 +1,2 @@ parameters: level: 0 - bootstrap: %currentWorkingDirectory%/vendor/autoload.php From ce46be4189055aaf48c66dc240e1eae342a88d0e Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sun, 26 Jan 2020 12:32:22 +0545 Subject: [PATCH 019/165] Apply php-cs-fixer code style changes --- lib/Cli.php | 8 -------- lib/Component.php | 6 ++---- lib/Component/VAvailability.php | 3 --- lib/Component/VCalendar.php | 6 ++---- lib/Component/VEvent.php | 3 --- lib/Component/VFreeBusy.php | 3 --- lib/Component/VJournal.php | 3 --- lib/Component/VTodo.php | 3 --- lib/FreeBusyGenerator.php | 12 +----------- lib/ITip/Broker.php | 14 +------------- lib/Node.php | 2 -- lib/Parameter.php | 2 -- lib/Parser/Json.php | 4 ---- lib/Parser/XML.php | 18 +++++------------- lib/Property.php | 6 ------ lib/Property/Binary.php | 2 -- lib/Property/Boolean.php | 2 -- lib/Property/FloatValue.php | 2 -- lib/Property/ICalendar/DateTime.php | 5 ----- lib/Property/ICalendar/Period.php | 2 -- lib/Property/ICalendar/Recur.php | 2 -- lib/Property/IntegerValue.php | 2 -- lib/Property/Time.php | 4 ---- lib/Property/UtcOffset.php | 2 -- lib/Property/VCard/Date.php | 2 -- lib/Property/VCard/DateAndOrTime.php | 4 ---- lib/Recur/EventIterator.php | 2 -- lib/Recur/RDateIterator.php | 5 +---- lib/Recur/RRuleIterator.php | 5 +---- lib/VCardConverter.php | 20 ++++---------------- lib/Writer.php | 7 +------ 31 files changed, 18 insertions(+), 143 deletions(-) diff --git a/lib/Cli.php b/lib/Cli.php index be795e9e2..f3e419b15 100644 --- a/lib/Cli.php +++ b/lib/Cli.php @@ -312,8 +312,6 @@ protected function showHelp() /** * Validates a VObject file. * - * @param Component $vObj - * * @return int */ protected function validate(Component $vObj) @@ -354,8 +352,6 @@ protected function validate(Component $vObj) /** * Repairs a VObject file. * - * @param Component $vObj - * * @return int */ protected function repair(Component $vObj) @@ -582,8 +578,6 @@ function ($a, $b) use ($sortScore, $tmp) { /** * Colorizes a property. - * - * @param Property $property */ protected function serializeProperty(Property $property) { @@ -642,8 +636,6 @@ protected function serializeProperty(Property $property) /** * Parses the list of arguments. - * - * @param array $argv */ protected function parseArguments(array $argv) { diff --git a/lib/Component.php b/lib/Component.php index d4d8506d8..58594aec1 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -43,10 +43,8 @@ class Component extends Node * an iCalendar object, this may be something like CALSCALE:GREGORIAN. To * ensure that this does not happen, set $defaults to false. * - * @param Document $root - * @param string $name such as VCALENDAR, VEVENT - * @param array $children - * @param bool $defaults + * @param string $name such as VCALENDAR, VEVENT + * @param bool $defaults */ public function __construct(Document $root, $name, array $children = [], $defaults = true) { diff --git a/lib/Component/VAvailability.php b/lib/Component/VAvailability.php index 6f3e7f13c..04ec38dcb 100644 --- a/lib/Component/VAvailability.php +++ b/lib/Component/VAvailability.php @@ -26,9 +26,6 @@ class VAvailability extends VObject\Component * * https://tools.ietf.org/html/draft-daboo-calendar-availability-05#section-3.1 * - * @param DateTimeInterface $start - * @param DateTimeInterface $end - * * @return bool */ public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) diff --git a/lib/Component/VCalendar.php b/lib/Component/VCalendar.php index e21ae077a..54419c88a 100644 --- a/lib/Component/VCalendar.php +++ b/lib/Component/VCalendar.php @@ -276,10 +276,8 @@ public function getBaseComponent($componentName = null) * In addition, this method will cause timezone information to be stripped, * and normalized to UTC. * - * @param DateTimeInterface $start - * @param DateTimeInterface $end - * @param DateTimeZone $timeZone reference timezone for floating dates and - * times + * @param DateTimeZone $timeZone reference timezone for floating dates and + * times * * @return VCalendar */ diff --git a/lib/Component/VEvent.php b/lib/Component/VEvent.php index 4a53a7561..6ea93ed5e 100644 --- a/lib/Component/VEvent.php +++ b/lib/Component/VEvent.php @@ -25,9 +25,6 @@ class VEvent extends VObject\Component * The rules used to determine if an event falls within the specified * time-range is based on the CalDAV specification. * - * @param DateTimeInterface $start - * @param DateTimeInterface $end - * * @return bool */ public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) diff --git a/lib/Component/VFreeBusy.php b/lib/Component/VFreeBusy.php index 558a85233..fef418b53 100644 --- a/lib/Component/VFreeBusy.php +++ b/lib/Component/VFreeBusy.php @@ -21,9 +21,6 @@ class VFreeBusy extends VObject\Component * Checks based on the contained FREEBUSY information, if a timeslot is * available. * - * @param DateTimeInterface $start - * @param DateTimeInterface $end - * * @return bool */ public function isFree(DateTimeInterface $start, DatetimeInterface $end) diff --git a/lib/Component/VJournal.php b/lib/Component/VJournal.php index 9bd336776..9b7f1b873 100644 --- a/lib/Component/VJournal.php +++ b/lib/Component/VJournal.php @@ -23,9 +23,6 @@ class VJournal extends VObject\Component * The rules used to determine if an event falls within the specified * time-range is based on the CalDAV specification. * - * @param DateTimeInterface $start - * @param DateTimeInterface $end - * * @return bool */ public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) diff --git a/lib/Component/VTodo.php b/lib/Component/VTodo.php index 9de77e841..6f022ba6d 100644 --- a/lib/Component/VTodo.php +++ b/lib/Component/VTodo.php @@ -23,9 +23,6 @@ class VTodo extends VObject\Component * The rules used to determine if an event falls within the specified * time-range is based on the CalDAV specification. * - * @param DateTimeInterface $start - * @param DateTimeInterface $end - * * @return bool */ public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) diff --git a/lib/FreeBusyGenerator.php b/lib/FreeBusyGenerator.php index adb214c08..a1c24044c 100644 --- a/lib/FreeBusyGenerator.php +++ b/lib/FreeBusyGenerator.php @@ -109,8 +109,6 @@ public function __construct(DateTimeInterface $start = null, DateTimeInterface $ * for setting things like the METHOD, CALSCALE, VERSION, etc.. * * The VFREEBUSY object will be automatically added though. - * - * @param Document $vcalendar */ public function setBaseObject(Document $vcalendar) { @@ -119,8 +117,6 @@ public function setBaseObject(Document $vcalendar) /** * Sets a VAVAILABILITY document. - * - * @param Document $vcalendar */ public function setVAvailability(Document $vcalendar) { @@ -176,8 +172,6 @@ public function setTimeRange(DateTimeInterface $start = null, DateTimeInterface /** * Sets the reference timezone for floating times. - * - * @param DateTimeZone $timeZone */ public function setTimeZone(DateTimeZone $timeZone) { @@ -208,9 +202,6 @@ public function getResult() /** * This method takes a VAVAILABILITY component and figures out all the * available times. - * - * @param FreeBusyData $fbData - * @param VCalendar $vavailability */ protected function calculateAvailability(FreeBusyData $fbData, VCalendar $vavailability) { @@ -363,8 +354,7 @@ function ($a, $b) { * This method takes an array of iCalendar objects and applies its busy * times on fbData. * - * @param FreeBusyData $fbData - * @param VCalendar[] $objects + * @param VCalendar[] $objects */ protected function calculateBusy(FreeBusyData $fbData, array $objects) { diff --git a/lib/ITip/Broker.php b/lib/ITip/Broker.php index ea27b3b3e..c09cdf3be 100644 --- a/lib/ITip/Broker.php +++ b/lib/ITip/Broker.php @@ -104,7 +104,6 @@ class Broker * * If the iTip message was not supported, we will always return false. * - * @param Message $itipMessage * @param VCalendar $existingObject * * @return VCalendar|null @@ -263,8 +262,6 @@ public function parseEvent($calendar = null, $userHref, $oldCalendar = null) * This is message from an organizer, and is either a new event * invite, or an update to an existing one. * - * - * @param Message $itipMessage * @param VCalendar $existingObject * * @return VCalendar|null @@ -300,7 +297,6 @@ protected function processMessageRequest(Message $itipMessage, VCalendar $existi * attendee got removed from an event, or an event got cancelled * altogether. * - * @param Message $itipMessage * @param VCalendar $existingObject * * @return VCalendar|null @@ -326,7 +322,6 @@ protected function processMessageCancel(Message $itipMessage, VCalendar $existin * The message is a reply. This is for example an attendee telling * an organizer he accepted the invite, or declined it. * - * @param Message $itipMessage * @param VCalendar $existingObject * * @return VCalendar|null @@ -452,10 +447,6 @@ protected function processMessageReply(Message $itipMessage, VCalendar $existing * We will detect which attendees got added, which got removed and create * specific messages for these situations. * - * @param VCalendar $calendar - * @param array $eventInfo - * @param array $oldEventInfo - * * @return array */ protected function parseEventForOrganizer(VCalendar $calendar, array $eventInfo, array $oldEventInfo) @@ -620,10 +611,7 @@ protected function parseEventForOrganizer(VCalendar $calendar, array $eventInfo, * * This function figures out if we need to send a reply to an organizer. * - * @param VCalendar $calendar - * @param array $eventInfo - * @param array $oldEventInfo - * @param string $attendee + * @param string $attendee * * @return Message[] */ diff --git a/lib/Node.php b/lib/Node.php index 154a7fac5..4c0c04f72 100644 --- a/lib/Node.php +++ b/lib/Node.php @@ -115,8 +115,6 @@ public function getIterator() * Sets the overridden iterator. * * Note that this is not actually part of the iterator interface - * - * @param ElementList $iterator */ public function setIterator(ElementList $iterator) { diff --git a/lib/Parameter.php b/lib/Parameter.php index 2c9a8e7fd..e39d320a1 100644 --- a/lib/Parameter.php +++ b/lib/Parameter.php @@ -201,8 +201,6 @@ public function getValue() /** * Sets multiple values for this parameter. - * - * @param array $value */ public function setParts(array $value) { diff --git a/lib/Parser/Json.php b/lib/Parser/Json.php index 3fd307e97..e8138b197 100644 --- a/lib/Parser/Json.php +++ b/lib/Parser/Json.php @@ -87,8 +87,6 @@ public function parse($input = null, $options = 0) /** * Parses a component. * - * @param array $jComp - * * @return \Sabre\VObject\Component */ public function parseComponent(array $jComp) @@ -124,8 +122,6 @@ function ($jComp) use ($self) { /** * Parses properties. * - * @param array $jProp - * * @return \Sabre\VObject\Property */ public function parseProperty(array $jProp) diff --git a/lib/Parser/XML.php b/lib/Parser/XML.php index 90f262d9e..8b7693edd 100644 --- a/lib/Parser/XML.php +++ b/lib/Parser/XML.php @@ -112,8 +112,6 @@ public function parse($input = null, $options = 0) /** * Parse a xCalendar component. - * - * @param Component $parentComponent */ protected function parseVCalendarComponents(Component $parentComponent) { @@ -134,8 +132,6 @@ protected function parseVCalendarComponents(Component $parentComponent) /** * Parse a xCard component. - * - * @param Component $parentComponent */ protected function parseVCardComponents(Component $parentComponent) { @@ -146,8 +142,7 @@ protected function parseVCardComponents(Component $parentComponent) /** * Parse xCalendar and xCard properties. * - * @param Component $parentComponent - * @param string $propertyNamePrefix + * @param string $propertyNamePrefix */ protected function parseProperties(Component $parentComponent, $propertyNamePrefix = '') { @@ -302,8 +297,6 @@ protected function parseProperties(Component $parentComponent, $propertyNamePref /** * Parse a component. - * - * @param Component $parentComponent */ protected function parseComponent(Component $parentComponent) { @@ -327,11 +320,10 @@ protected function parseComponent(Component $parentComponent) /** * Create a property. * - * @param Component $parentComponent - * @param string $name - * @param array $parameters - * @param string $type - * @param mixed $value + * @param string $name + * @param array $parameters + * @param string $type + * @param mixed $value */ protected function createProperty(Component $parentComponent, $name, $parameters, $type, $value) { diff --git a/lib/Property.php b/lib/Property.php index 6105cb0f0..f9cf8e38e 100644 --- a/lib/Property.php +++ b/lib/Property.php @@ -123,8 +123,6 @@ public function getValue() /** * Sets a multi-valued property. - * - * @param array $parts */ public function setParts(array $parts) { @@ -262,8 +260,6 @@ public function getJsonValue() * Sets the JSON value, as it would appear in a jCard or jCal object. * * The value must always be an array. - * - * @param array $value */ public function setJsonValue(array $value) { @@ -309,8 +305,6 @@ public function jsonSerialize() /** * Hydrate data from a XML subtree, as it would appear in a xCard or xCal * object. - * - * @param array $value */ public function setXmlValue(array $value) { diff --git a/lib/Property/Binary.php b/lib/Property/Binary.php index 830dd9028..ec6713fdd 100644 --- a/lib/Property/Binary.php +++ b/lib/Property/Binary.php @@ -100,8 +100,6 @@ public function getJsonValue() * Sets the json value, as it would appear in a jCard or jCal object. * * The value must always be an array. - * - * @param array $value */ public function setJsonValue(array $value) { diff --git a/lib/Property/Boolean.php b/lib/Property/Boolean.php index 0e7bc666e..9fb2bce35 100644 --- a/lib/Property/Boolean.php +++ b/lib/Property/Boolean.php @@ -59,8 +59,6 @@ public function getValueType() /** * Hydrate data from a XML subtree, as it would appear in a xCard or xCal * object. - * - * @param array $value */ public function setXmlValue(array $value) { diff --git a/lib/Property/FloatValue.php b/lib/Property/FloatValue.php index 208d74516..0d0346968 100644 --- a/lib/Property/FloatValue.php +++ b/lib/Property/FloatValue.php @@ -93,8 +93,6 @@ public function getJsonValue() /** * Hydrate data from a XML subtree, as it would appear in a xCard or xCal * object. - * - * @param array $value */ public function setXmlValue(array $value) { diff --git a/lib/Property/ICalendar/DateTime.php b/lib/Property/ICalendar/DateTime.php index 7eb3e0bb7..a0d1b38d4 100644 --- a/lib/Property/ICalendar/DateTime.php +++ b/lib/Property/ICalendar/DateTime.php @@ -38,8 +38,6 @@ class DateTime extends Property * Sets a multi-valued property. * * You may also specify DateTime objects here. - * - * @param array $parts */ public function setParts(array $parts) { @@ -175,7 +173,6 @@ public function getDateTimes(DateTimeZone $timeZone = null) /** * Sets the property as a DateTime object. * - * @param DateTimeInterface $dt * @param bool isFloating If set to true, timezones will be ignored */ public function setDateTime(DateTimeInterface $dt, $isFloating = false) @@ -279,8 +276,6 @@ function (DateTimeInterface $dt) use ($hasTime, $isUtc) { * Sets the json value, as it would appear in a jCard or jCal object. * * The value must always be an array. - * - * @param array $value */ public function setJsonValue(array $value) { diff --git a/lib/Property/ICalendar/Period.php b/lib/Property/ICalendar/Period.php index 17bfa5c5c..eb3752770 100644 --- a/lib/Property/ICalendar/Period.php +++ b/lib/Property/ICalendar/Period.php @@ -67,8 +67,6 @@ public function getValueType() * Sets the json value, as it would appear in a jCard or jCal object. * * The value must always be an array. - * - * @param array $value */ public function setJsonValue(array $value) { diff --git a/lib/Property/ICalendar/Recur.php b/lib/Property/ICalendar/Recur.php index baeda781e..3d632fec1 100644 --- a/lib/Property/ICalendar/Recur.php +++ b/lib/Property/ICalendar/Recur.php @@ -88,8 +88,6 @@ public function getValue() /** * Sets a multi-valued property. - * - * @param array $parts */ public function setParts(array $parts) { diff --git a/lib/Property/IntegerValue.php b/lib/Property/IntegerValue.php index 24a46fb07..6f709bfff 100644 --- a/lib/Property/IntegerValue.php +++ b/lib/Property/IntegerValue.php @@ -68,8 +68,6 @@ public function getJsonValue() /** * Hydrate data from a XML subtree, as it would appear in a xCard or xCal * object. - * - * @param array $value */ public function setXmlValue(array $value) { diff --git a/lib/Property/Time.php b/lib/Property/Time.php index 7aeafc8d0..544b5ced3 100644 --- a/lib/Property/Time.php +++ b/lib/Property/Time.php @@ -40,8 +40,6 @@ public function getValueType() * Sets the JSON value, as it would appear in a jCard or jCal object. * * The value must always be an array. - * - * @param array $value */ public function setJsonValue(array $value) { @@ -119,8 +117,6 @@ public function getJsonValue() /** * Hydrate data from a XML subtree, as it would appear in a xCard or xCal * object. - * - * @param array $value */ public function setXmlValue(array $value) { diff --git a/lib/Property/UtcOffset.php b/lib/Property/UtcOffset.php index 732239e23..248ed40ea 100644 --- a/lib/Property/UtcOffset.php +++ b/lib/Property/UtcOffset.php @@ -38,8 +38,6 @@ public function getValueType() * Sets the JSON value, as it would appear in a jCard or jCal object. * * The value must always be an array. - * - * @param array $value */ public function setJsonValue(array $value) { diff --git a/lib/Property/VCard/Date.php b/lib/Property/VCard/Date.php index a018ccbb8..fc679d572 100644 --- a/lib/Property/VCard/Date.php +++ b/lib/Property/VCard/Date.php @@ -28,8 +28,6 @@ public function getValueType() /** * Sets the property as a DateTime object. - * - * @param \DateTimeInterface $dt */ public function setDateTime(\DateTimeInterface $dt) { diff --git a/lib/Property/VCard/DateAndOrTime.php b/lib/Property/VCard/DateAndOrTime.php index b7e17492a..09918b31a 100644 --- a/lib/Property/VCard/DateAndOrTime.php +++ b/lib/Property/VCard/DateAndOrTime.php @@ -45,8 +45,6 @@ public function getValueType() * Sets a multi-valued property. * * You may also specify DateTimeInterface objects here. - * - * @param array $parts */ public function setParts(array $parts) { @@ -80,8 +78,6 @@ public function setValue($value) /** * Sets the property as a DateTime object. - * - * @param DateTimeInterface $dt */ public function setDateTime(DateTimeInterface $dt) { diff --git a/lib/Recur/EventIterator.php b/lib/Recur/EventIterator.php index 135ecf00e..fd904b383 100644 --- a/lib/Recur/EventIterator.php +++ b/lib/Recur/EventIterator.php @@ -380,8 +380,6 @@ public function next() /** * Quickly jump to a date in the future. - * - * @param DateTimeInterface $dateTime */ public function fastForward(DateTimeInterface $dateTime) { diff --git a/lib/Recur/RDateIterator.php b/lib/Recur/RDateIterator.php index 013694b95..d117e152c 100644 --- a/lib/Recur/RDateIterator.php +++ b/lib/Recur/RDateIterator.php @@ -24,8 +24,7 @@ class RDateIterator implements Iterator /** * Creates the Iterator. * - * @param string|array $rrule - * @param DateTimeInterface $start + * @param string|array $rrule */ public function __construct($rrule, DateTimeInterface $start) { @@ -107,8 +106,6 @@ public function isInfinite() /** * This method allows you to quickly go to the next occurrence after the * specified date. - * - * @param DateTimeInterface $dt */ public function fastForward(DateTimeInterface $dt) { diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index 7bd4b086e..dd07310e5 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -27,8 +27,7 @@ class RRuleIterator implements Iterator /** * Creates the Iterator. * - * @param string|array $rrule - * @param DateTimeInterface $start + * @param string|array $rrule */ public function __construct($rrule, DateTimeInterface $start) { @@ -132,8 +131,6 @@ public function isInfinite() /** * This method allows you to quickly go to the next occurrence after the * specified date. - * - * @param DateTimeInterface $dt */ public function fastForward(DateTimeInterface $dt) { diff --git a/lib/VCardConverter.php b/lib/VCardConverter.php index 5a814aa2e..04932fe67 100644 --- a/lib/VCardConverter.php +++ b/lib/VCardConverter.php @@ -26,8 +26,7 @@ class VCardConverter * * If input and output version are identical, a clone is returned. * - * @param Component\VCard $input - * @param int $targetVersion + * @param int $targetVersion */ public function convert(Component\VCard $input, $targetVersion) { @@ -62,10 +61,7 @@ public function convert(Component\VCard $input, $targetVersion) /** * Handles conversion of a single property. * - * @param Component\VCard $input - * @param Component\VCard $output - * @param Property $property - * @param int $targetVersion + * @param int $targetVersion */ protected function convertProperty(Component\VCard $input, Component\VCard $output, Property $property, $targetVersion) { @@ -245,8 +241,7 @@ protected function convertProperty(Component\VCard $input, Component\VCard $outp * * vCard 4.0 no longer supports BINARY properties. * - * @param Component\VCard $output - * @param Property\Uri $property the input property + * @param Property\Uri $property the input property * @param $parameters list of parameters that will eventually be added to * the new property * @@ -299,8 +294,7 @@ protected function convertBinaryToUri(Component\VCard $output, Property\Binary $ * be valid in vCard 3.0 as well, we should convert those to BINARY if * possible, to improve compatibility. * - * @param Component\VCard $output - * @param Property\Uri $property the input property + * @param Property\Uri $property the input property * * @return Property\Binary|null */ @@ -347,9 +341,6 @@ protected function convertUriToBinary(Component\VCard $output, Property\Uri $new /** * Adds parameters to a new property for vCard 4.0. - * - * @param Property $newProperty - * @param array $parameters */ protected function convertParameters40(Property $newProperty, array $parameters) { @@ -386,9 +377,6 @@ protected function convertParameters40(Property $newProperty, array $parameters) /** * Adds parameters to a new property for vCard 3.0. - * - * @param Property $newProperty - * @param array $parameters */ protected function convertParameters30(Property $newProperty, array $parameters) { diff --git a/lib/Writer.php b/lib/Writer.php index c70a6ae4d..cbd22022e 100644 --- a/lib/Writer.php +++ b/lib/Writer.php @@ -19,8 +19,6 @@ class Writer /** * Serializes a vCard or iCalendar object. * - * @param Component $component - * * @return string */ public static function write(Component $component) @@ -31,8 +29,7 @@ public static function write(Component $component) /** * Serializes a jCal or jCard object. * - * @param Component $component - * @param int $options + * @param int $options * * @return string */ @@ -44,8 +41,6 @@ public static function writeJson(Component $component, $options = 0) /** * Serializes a xCal or xCard object. * - * @param Component $component - * * @return string */ public static function writeXml(Component $component) From f154971709d40b599820d6246e816396f384157a Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sun, 26 Jan 2020 12:34:31 +0545 Subject: [PATCH 020/165] run php-cs-fixer in CI --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 40c54aeb3..511119bbb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,7 @@ before_script: - composer install script: + - ./bin/php-cs-fixer fix lib/ --dry-run --diff - php ./bin/phpstan.phar analyse -c phpstan.neon lib tests - ./bin/phpunit --configuration tests/phpunit.xml --coverage-clover=coverage.xml From 5b828a9f87c30b00c51c796ad1d00191956c86ac Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sun, 26 Jan 2020 20:21:55 +0545 Subject: [PATCH 021/165] php-cs-fixer must be at least 2.16.1 for PHP 7.4 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 7e34b74b8..baf94db74 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ "sabre/xml" : "^2.1" }, "require-dev" : { - "friendsofphp/php-cs-fixer": "2.16.*", + "friendsofphp/php-cs-fixer": "~2.16.1", "phpunit/phpunit" : "^7" }, "suggest" : { From 458bf943067ca8c7b2c42194f85e12970149d1be Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Wed, 29 Jan 2020 20:40:20 +0545 Subject: [PATCH 022/165] Use phpunit8 where possible --- .gitignore | 1 + composer.json | 2 +- .../VObject/BirthdayCalendarGeneratorTest.php | 12 ++--- tests/VObject/CliTest.php | 2 +- tests/VObject/Component/VAlarmTest.php | 5 +-- tests/VObject/Component/VCalendarTest.php | 5 +-- tests/VObject/ComponentTest.php | 26 ++++------- tests/VObject/DateTimeParserTest.php | 20 +++------ tests/VObject/FreeBusyGeneratorTest.php | 4 +- tests/VObject/ITip/BrokerNewEventTest.php | 16 ++----- tests/VObject/IssueUndefinedIndexTest.php | 4 +- tests/VObject/Parser/JsonTest.php | 5 +-- tests/VObject/Parser/MimeDirTest.php | 13 ++---- tests/VObject/Property/BinaryTest.php | 4 +- .../Property/ICalendar/DateTimeTest.php | 7 ++- .../VObject/Property/ICalendar/RecurTest.php | 4 +- tests/VObject/Property/UriTest.php | 2 +- .../Property/VCard/DateAndOrTimeTest.php | 4 +- tests/VObject/PropertyTest.php | 8 ++-- tests/VObject/ReaderTest.php | 19 +++----- .../EventIterator/InfiniteLoopProblemTest.php | 6 +-- .../Recur/EventIterator/Issue26Test.php | 5 +-- .../VObject/Recur/EventIterator/MainTest.php | 13 +++--- .../Recur/EventIterator/MaxInstancesTest.php | 5 +-- .../Recur/EventIterator/NoInstancesTest.php | 5 +-- tests/VObject/Recur/RRuleIteratorTest.php | 44 +++++-------------- tests/VObject/Splitter/ICalendarTest.php | 11 ++--- tests/VObject/Splitter/VCardTest.php | 15 +++---- tests/VObject/TimeZoneUtilTest.php | 6 +-- tests/VObject/VCardConverterTest.php | 8 +--- 30 files changed, 91 insertions(+), 190 deletions(-) diff --git a/.gitignore b/.gitignore index 8b677a5ad..e9b0ed32f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ vendor/ composer.lock tests/cov/ tests/temp +tests/.phpunit.result.cache #vim .*.swp diff --git a/composer.json b/composer.json index baf94db74..9e522f8a4 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,7 @@ }, "require-dev" : { "friendsofphp/php-cs-fixer": "~2.16.1", - "phpunit/phpunit" : "^7" + "phpunit/phpunit" : "^7 || ^8" }, "suggest" : { "hoa/bench" : "If you would like to run the benchmark scripts" diff --git a/tests/VObject/BirthdayCalendarGeneratorTest.php b/tests/VObject/BirthdayCalendarGeneratorTest.php index 6e4f89a4c..d27362837 100644 --- a/tests/VObject/BirthdayCalendarGeneratorTest.php +++ b/tests/VObject/BirthdayCalendarGeneratorTest.php @@ -458,11 +458,9 @@ public function testVcardStringWithEmptyBirthdayProperty() ); } - /** - * @expectedException \Sabre\VObject\ParseException - */ public function testParseException() { + $this->expectException(ParseException::class); $generator = new BirthdayCalendarGenerator(); $input = <<setObjects($input); } - /** - * @expectedException \InvalidArgumentException - */ public function testInvalidArgumentException() { + $this->expectException(\InvalidArgumentException::class); $generator = new BirthdayCalendarGenerator(); $input = <<setObjects($input); } - /** - * @expectedException \InvalidArgumentException - */ public function testInvalidArgumentExceptionForPartiallyInvalidArray() { + $this->expectException(\InvalidArgumentException::class); $generator = new BirthdayCalendarGenerator(); $input = []; diff --git a/tests/VObject/CliTest.php b/tests/VObject/CliTest.php index cae424d96..2fa0162e4 100644 --- a/tests/VObject/CliTest.php +++ b/tests/VObject/CliTest.php @@ -14,7 +14,7 @@ class CliTest extends TestCase /** @var CliMock */ private $cli; - public function setUp() + public function setUp(): void { $this->cli = new CliMock(); $this->cli->stderr = fopen('php://memory', 'r+'); diff --git a/tests/VObject/Component/VAlarmTest.php b/tests/VObject/Component/VAlarmTest.php index 1e7a55ad7..2823d16da 100644 --- a/tests/VObject/Component/VAlarmTest.php +++ b/tests/VObject/Component/VAlarmTest.php @@ -4,6 +4,7 @@ use DateTime; use PHPUnit\Framework\TestCase; +use Sabre\VObject\InvalidDataException; use Sabre\VObject\Reader; class VAlarmTest extends TestCase @@ -126,11 +127,9 @@ public function timeRangeTestData() return $tests; } - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testInTimeRangeInvalidComponent() { + $this->expectException(InvalidDataException::class); $calendar = new VCalendar(); $valarm = $calendar->createComponent('VALARM'); $valarm->TRIGGER = '-P1D'; diff --git a/tests/VObject/Component/VCalendarTest.php b/tests/VObject/Component/VCalendarTest.php index dbf2fef0a..c2f0ce978 100644 --- a/tests/VObject/Component/VCalendarTest.php +++ b/tests/VObject/Component/VCalendarTest.php @@ -5,6 +5,7 @@ use DateTimeZone; use PHPUnit\Framework\TestCase; use Sabre\VObject; +use Sabre\VObject\InvalidDataException; class VCalendarTest extends TestCase { @@ -330,11 +331,9 @@ public function expandData() return $tests; } - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testBrokenEventExpand() { + $this->expectException(InvalidDataException::class); $input = 'BEGIN:VCALENDAR CALSCALE:GREGORIAN VERSION:2.0 diff --git a/tests/VObject/ComponentTest.php b/tests/VObject/ComponentTest.php index 8c0a0d7c6..b1e73c634 100644 --- a/tests/VObject/ComponentTest.php +++ b/tests/VObject/ComponentTest.php @@ -41,7 +41,7 @@ public function testMagicGet() $this->assertInstanceOf('Sabre\\VObject\\Component', $event); $this->assertEquals('VEVENT', $event->name); - $this->assertInternalType('null', $comp->vjournal); + $this->assertNull($comp->vjournal); } public function testMagicGetGroups() @@ -174,20 +174,16 @@ public function testArrayAccessExists() $this->assertTrue(isset($comp->vevent[1])); } - /** - * @expectedException \LogicException - */ public function testArrayAccessSet() { + $this->expectException(\LogicException::class); $comp = new VCalendar(); $comp['hey'] = 'hi there'; } - /** - * @expectedException \LogicException - */ public function testArrayAccessUnset() { + $this->expectException(\LogicException::class); $comp = new VCalendar(); unset($comp[0]); } @@ -250,20 +246,16 @@ public function testAddComponentTwice() $this->assertEquals('VEVENT', $comp->VEVENT->name); } - /** - * @expectedException \InvalidArgumentException - */ public function testAddArgFail() { + $this->expectException(\InvalidArgumentException::class); $comp = new VCalendar(); $comp->add($comp->createComponent('VEVENT'), 'hello'); } - /** - * @expectedException \InvalidArgumentException - */ public function testAddArgFail2() { + $this->expectException(\InvalidArgumentException::class); $comp = new VCalendar(); $comp->add([]); } @@ -293,7 +285,7 @@ public function testChildren() $comp->add($comp->createComponent('VTODO')); $r = $comp->children(); - $this->assertInternalType('array', $r); + $this->assertIsArray($r); $this->assertEquals(2, count($r)); } @@ -305,7 +297,7 @@ public function testGetComponents() $comp->add($comp->createComponent('VTODO')); $r = $comp->getComponents(); - $this->assertInternalType('array', $r); + $this->assertIsArray($r); $this->assertEquals(1, count($r)); $this->assertEquals('VTODO', $r[0]->name); } @@ -414,11 +406,9 @@ public function testRemoveByObj() $this->assertTrue(isset($comp->prop1)); } - /** - * @expectedException \InvalidArgumentException - */ public function testRemoveNotFound() { + $this->expectException(\InvalidArgumentException::class); $comp = new VCalendar([], false); $prop = $comp->createProperty('A', 'B'); $comp->remove($prop); diff --git a/tests/VObject/DateTimeParserTest.php b/tests/VObject/DateTimeParserTest.php index 44fba80c5..b20a43217 100644 --- a/tests/VObject/DateTimeParserTest.php +++ b/tests/VObject/DateTimeParserTest.php @@ -31,11 +31,9 @@ public function testParseICalendarDurationDateInterval() $this->assertEquals($expected, DateTimeParser::parseDuration('-PT3M')); } - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testParseICalendarDurationFail() { + $this->expectException(InvalidDataException::class); DateTimeParser::parseDuration('P1X', true); } @@ -50,19 +48,19 @@ public function testParseICalendarDateTime() /** * @depends testParseICalendarDateTime - * @expectedException \Sabre\VObject\InvalidDataException */ public function testParseICalendarDateTimeBadFormat() { + $this->expectException(InvalidDataException::class); $dateTime = DateTimeParser::parseDateTime('20100316T141405 '); } /** * @depends testParseICalendarDateTime - * @expectedException \Sabre\VObject\InvalidDataException */ public function testParseICalendarDateTimeInvalidTime() { + $this->expectException(InvalidDataException::class); $dateTime = DateTimeParser::parseDateTime('20100316T251405'); } @@ -143,19 +141,19 @@ public function testParseICalendarDateTimeGreaterThan4000() /** * @depends testParseICalendarDate - * @expectedException \Sabre\VObject\InvalidDataException */ public function testParseICalendarDateBadFormat() { + $this->expectException(InvalidDataException::class); $dateTime = DateTimeParser::parseDate('20100316T141405'); } /** * @depends testParseICalendarDate - * @expectedException \Sabre\VObject\InvalidDataException */ public function testParseICalendarDateInvalidDate() { + $this->expectException(InvalidDataException::class); $dateTime = DateTimeParser::parseDate('20101331'); } @@ -170,19 +168,15 @@ public function testVCardDate($input, $output) ); } - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testBadVCardDate() { + $this->expectException(InvalidDataException::class); DateTimeParser::parseVCardDateTime('1985---01'); } - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testBadVCardTime() { + $this->expectException(InvalidDataException::class); DateTimeParser::parseVCardTime('23:12:166'); } diff --git a/tests/VObject/FreeBusyGeneratorTest.php b/tests/VObject/FreeBusyGeneratorTest.php index e2dd59409..4700a2800 100644 --- a/tests/VObject/FreeBusyGeneratorTest.php +++ b/tests/VObject/FreeBusyGeneratorTest.php @@ -22,11 +22,9 @@ public function testGeneratorBaseObject() $this->assertEquals('PUBLISH', $result->METHOD->getValue()); } - /** - * @expectedException \InvalidArgumentException - */ public function testInvalidArg() { + $this->expectException(\InvalidArgumentException::class); $gen = new FreeBusyGenerator( new \DateTime('2012-01-01'), new \DateTime('2012-12-31'), diff --git a/tests/VObject/ITip/BrokerNewEventTest.php b/tests/VObject/ITip/BrokerNewEventTest.php index a727427af..f5b89b0e8 100644 --- a/tests/VObject/ITip/BrokerNewEventTest.php +++ b/tests/VObject/ITip/BrokerNewEventTest.php @@ -81,11 +81,9 @@ public function testSimpleInvite() $this->parse(null, $message, $expected, 'mailto:strunk@example.org'); } - /** - * @expectedException \Sabre\VObject\ITip\ITipException - */ public function testBrokenEventUIDMisMatch() { + $this->expectException(ITipException::class); $message = <<parse(null, $message, [], 'mailto:strunk@example.org'); } - /** - * @expectedException \Sabre\VObject\ITip\ITipException - */ public function testBrokenEventOrganizerMisMatch() { + $this->expectException(ITipException::class); $message = <<parse(null, $message, [], 'mailto:strunk@example.org'); } - /** - * @expectedException \Sabre\VObject\ITip\ITipException - */ public function testMultipleUID() { + $this->expectException(ITipException::class); $message = <<parse(null, $message, [], 'mailto:strunk@example.org'); } - /** - * @expectedException \Sabre\VObject\ITip\SameOrganizerForAllComponentsException - */ public function testChangingOrganizers() { + $this->expectException(SameOrganizerForAllComponentsException::class); $message = <<expectException(ParseException::class); $input = <<assertEquals('foo', $result->FN->getValue()); } - /** - * @expectedException \Sabre\VObject\ParseException - */ public function testParseInvalidData() { + $this->expectException(ParseException::class); $json = new Json(); $input = [ 'vlist', diff --git a/tests/VObject/Parser/MimeDirTest.php b/tests/VObject/Parser/MimeDirTest.php index 309068854..183c9ce4c 100644 --- a/tests/VObject/Parser/MimeDirTest.php +++ b/tests/VObject/Parser/MimeDirTest.php @@ -3,6 +3,7 @@ namespace Sabre\VObject\Parser; use PHPUnit\Framework\TestCase; +use Sabre\VObject\ParseException; /** * Note that most MimeDir related tests can actually be found in the ReaderTest @@ -10,11 +11,9 @@ */ class MimeDirTest extends TestCase { - /** - * @expectedException \Sabre\VObject\ParseException - */ public function testParseError() { + $this->expectException(ParseException::class); $mimeDir = new MimeDir(); $mimeDir->parse(fopen(__FILE__, 'a+')); } @@ -80,20 +79,16 @@ public function testDontDecodeLatin1() $this->assertEquals("umlaut u - \xFC", $vcard->FN->getValue()); } - /** - * @expectedException \InvalidArgumentException - */ public function testDecodeUnsupportedCharset() { + $this->expectException(\InvalidArgumentException::class); $mimeDir = new MimeDir(); $mimeDir->setCharset('foobar'); } - /** - * @expectedException \Sabre\VObject\ParseException - */ public function testDecodeUnsupportedInlineCharset() { + $this->expectException(ParseException::class); $vcard = <<expectException(\InvalidArgumentException::class); $vcard = new VObject\Component\VCard(['VERSION' => '3.0']); $vcard->add('PHOTO', ['a', 'b']); } diff --git a/tests/VObject/Property/ICalendar/DateTimeTest.php b/tests/VObject/Property/ICalendar/DateTimeTest.php index 33525ff33..40c6e2ef6 100644 --- a/tests/VObject/Property/ICalendar/DateTimeTest.php +++ b/tests/VObject/Property/ICalendar/DateTimeTest.php @@ -4,12 +4,13 @@ use PHPUnit\Framework\TestCase; use Sabre\VObject\Component\VCalendar; +use Sabre\VObject\InvalidDataException; class DateTimeTest extends TestCase { protected $vcal; - public function setUp() + public function setUp(): void { $this->vcal = new VCalendar(); } @@ -256,11 +257,9 @@ public function testGetDateTimeDateLOCALTZ() $this->assertEquals('Europe/Amsterdam', $dt->getTimeZone()->getName()); } - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testGetDateTimeDateInvalid() { + $this->expectException(InvalidDataException::class); $elem = $this->vcal->createProperty('DTSTART', 'bla'); $dt = $elem->getDateTime(); } diff --git a/tests/VObject/Property/ICalendar/RecurTest.php b/tests/VObject/Property/ICalendar/RecurTest.php index 818840605..3567ff1c0 100644 --- a/tests/VObject/Property/ICalendar/RecurTest.php +++ b/tests/VObject/Property/ICalendar/RecurTest.php @@ -24,11 +24,9 @@ public function testParts() $this->assertEquals(['FREQ' => 'MONTHLY'], $recur->getParts()); } - /** - * @expectedException \InvalidArgumentException - */ public function testSetValueBadVal() { + $this->expectException(\InvalidArgumentException::class); $vcal = new VCalendar(); $recur = $vcal->add('RRULE', 'FREQ=Daily'); $recur->setValue(new \Exception()); diff --git a/tests/VObject/Property/UriTest.php b/tests/VObject/Property/UriTest.php index 4ab32a736..d3d0e0f9c 100644 --- a/tests/VObject/Property/UriTest.php +++ b/tests/VObject/Property/UriTest.php @@ -21,6 +21,6 @@ public function testAlwaysEncodeUriVCalendar() END:VCALENDAR ICS; $output = Reader::read($input)->serialize(); - $this->assertContains('URL;VALUE=URI:http://example.org/', $output); + $this->assertStringContainsString('URL;VALUE=URI:http://example.org/', $output); } } diff --git a/tests/VObject/Property/VCard/DateAndOrTimeTest.php b/tests/VObject/Property/VCard/DateAndOrTimeTest.php index a59411e01..f21b408a1 100644 --- a/tests/VObject/Property/VCard/DateAndOrTimeTest.php +++ b/tests/VObject/Property/VCard/DateAndOrTimeTest.php @@ -105,11 +105,9 @@ public function testSetPartsDateTimeImmutable() $this->assertEquals('20140402T183700Z', $prop->getValue()); } - /** - * @expectedException \InvalidArgumentException - */ public function testSetPartsTooMany() { + $this->expectException(\InvalidArgumentException::class); $vcard = new VObject\Component\VCard(); $prop = $vcard->createProperty('BDAY'); diff --git a/tests/VObject/PropertyTest.php b/tests/VObject/PropertyTest.php index 1c2dc0830..adfb62e64 100644 --- a/tests/VObject/PropertyTest.php +++ b/tests/VObject/PropertyTest.php @@ -71,7 +71,7 @@ public function testParameterNotExists() $property = $cal->createProperty('propname', 'propvalue'); $property['paramname'] = 'paramvalue'; - $this->assertInternalType('null', $property['foo']); + $this->assertNull($property['foo']); } public function testParameterMultiple() @@ -308,11 +308,10 @@ public function testGetValue() /** * ElementList should reject this. - * - * @expectedException \LogicException */ public function testArrayAccessSetInt() { + $this->expectException(\LogicException::class); $calendar = new VCalendar(); $property = $calendar->createProperty('X-PROP', null); @@ -322,11 +321,10 @@ public function testArrayAccessSetInt() /** * ElementList should reject this. - * - * @expectedException \LogicException */ public function testArrayAccessUnsetInt() { + $this->expectException(\LogicException::class); $calendar = new VCalendar(); $property = $calendar->createProperty('X-PROP', null); diff --git a/tests/VObject/ReaderTest.php b/tests/VObject/ReaderTest.php index 06310e80a..f9d08c75a 100644 --- a/tests/VObject/ReaderTest.php +++ b/tests/VObject/ReaderTest.php @@ -54,21 +54,17 @@ public function testReadComponentLineFold() $this->assertEquals(0, count($result->children())); } - /** - * @expectedException \Sabre\VObject\ParseException - */ public function testReadCorruptComponent() { + $this->expectException(ParseException::class); $data = "BEGIN:VCALENDAR\r\nEND:FOO"; $result = Reader::read($data); } - /** - * @expectedException \Sabre\VObject\ParseException - */ public function testReadCorruptSubComponent() { + $this->expectException(ParseException::class); $data = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:FOO\r\nEND:VCALENDAR"; $result = Reader::read($data); @@ -118,11 +114,9 @@ public function testReadMappedPropertyGrouped() $this->assertEquals('20110529', $result->getValue()); } - /** - * @expectedException \Sabre\VObject\ParseException - */ public function testReadBrokenLine() { + $this->expectException(ParseException::class); $data = "BEGIN:VCALENDAR\r\nPROPNAME;propValue"; $result = Reader::read($data); } @@ -369,11 +363,10 @@ public function testReadWithInvalidLine() /** * Reported as Issue 32. - * - * @expectedException \Sabre\VObject\ParseException */ public function testReadIncompleteFile() { + $this->expectException(ParseException::class); $input = <<expectException(\InvalidArgumentException::class); Reader::read(false); } diff --git a/tests/VObject/Recur/EventIterator/InfiniteLoopProblemTest.php b/tests/VObject/Recur/EventIterator/InfiniteLoopProblemTest.php index ace78de2c..5546c508d 100644 --- a/tests/VObject/Recur/EventIterator/InfiniteLoopProblemTest.php +++ b/tests/VObject/Recur/EventIterator/InfiniteLoopProblemTest.php @@ -6,6 +6,7 @@ use DateTimeZone; use PHPUnit\Framework\TestCase; use Sabre\VObject\Component\VCalendar; +use Sabre\VObject\InvalidDataException; use Sabre\VObject\Recur; class InfiniteLoopProblemTest extends TestCase @@ -13,7 +14,7 @@ class InfiniteLoopProblemTest extends TestCase /** @var VCalendar */ private $vcal; - public function setUp() + public function setUp(): void { $this->vcal = new VCalendar(); } @@ -76,11 +77,10 @@ public function testYearlyByMonthLoop() * Something, somewhere produced an ics with an interval set to 0. Because * this means we increase the current day (or week, month) by 0, this also * results in an infinite loop. - * - * @expectedException \Sabre\VObject\InvalidDataException */ public function testZeroInterval() { + $this->expectException(InvalidDataException::class); $ev = $this->vcal->createComponent('VEVENT'); $ev->UID = 'uuid'; $ev->DTSTART = '20120824T145700Z'; diff --git a/tests/VObject/Recur/EventIterator/Issue26Test.php b/tests/VObject/Recur/EventIterator/Issue26Test.php index bb4df64df..60d3aa240 100644 --- a/tests/VObject/Recur/EventIterator/Issue26Test.php +++ b/tests/VObject/Recur/EventIterator/Issue26Test.php @@ -3,16 +3,15 @@ namespace Sabre\VObject\Recur\EventIterator; use PHPUnit\Framework\TestCase; +use Sabre\VObject\InvalidDataException; use Sabre\VObject\Reader; use Sabre\VObject\Recur\EventIterator; class Issue26Test extends TestCase { - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testExpand() { + $this->expectException(InvalidDataException::class); $input = <<expectException(InvalidDataException::class); $vcal = new VCalendar(); $ev = $vcal->createComponent('VEVENT'); $ev->RRULE = 'FREQ=SMONTHLY;INTERVAL=3;UNTIL=20111025T000000Z'; @@ -47,20 +48,16 @@ public function testInvalidFreq() $it = new EventIterator($vcal, (string) $ev->UID); } - /** - * @expectedException \InvalidArgumentException - */ public function testVCalendarNoUID() { + $this->expectException(\InvalidArgumentException::class); $vcal = new VCalendar(); $it = new EventIterator($vcal); } - /** - * @expectedException \InvalidArgumentException - */ public function testVCalendarInvalidUID() { + $this->expectException(\InvalidArgumentException::class); $vcal = new VCalendar(); $it = new EventIterator($vcal, 'foo'); } @@ -1386,10 +1383,10 @@ public function testRDATE() /** * @depends testValues - * @expectedException \InvalidArgumentException */ public function testNoMasterBadUID() { + $this->expectException(\InvalidArgumentException::class); $vcal = new VCalendar(); // ev2 overrides an event, and puts it on 2pm instead. $ev2 = $vcal->createComponent('VEVENT'); diff --git a/tests/VObject/Recur/EventIterator/MaxInstancesTest.php b/tests/VObject/Recur/EventIterator/MaxInstancesTest.php index d0571ee82..6314b3b5a 100644 --- a/tests/VObject/Recur/EventIterator/MaxInstancesTest.php +++ b/tests/VObject/Recur/EventIterator/MaxInstancesTest.php @@ -5,15 +5,14 @@ use DateTime; use PHPUnit\Framework\TestCase; use Sabre\VObject\Reader; +use Sabre\VObject\Recur\MaxInstancesExceededException; use Sabre\VObject\Settings; class MaxInstancesTest extends TestCase { - /** - * @expectedException \Sabre\VObject\Recur\MaxInstancesExceededException - */ public function testExceedMaxRecurrences() { + $this->expectException(MaxInstancesExceededException::class); $input = <<expectException(NoInstancesException::class); $input = <<expectException(InvalidDataException::class); $this->parse( 'FREQ=YEARLY;COUNT=6;BYMONTHDAY=24;BYMONTH=0', '2011-04-07 00:00:00', @@ -434,11 +433,9 @@ public function testYearlyByMonthInvalidValue1() ); } - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testYearlyByMonthInvalidValue2() { + $this->expectException(InvalidDataException::class); $this->parse( 'FREQ=YEARLY;COUNT=6;BYMONTHDAY=24;BYMONTH=bla', '2011-04-07 00:00:00', @@ -446,11 +443,9 @@ public function testYearlyByMonthInvalidValue2() ); } - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testYearlyByMonthManyInvalidValues() { + $this->expectException(InvalidDataException::class); $this->parse( 'FREQ=YEARLY;COUNT=6;BYMONTHDAY=24;BYMONTH=0,bla', '2011-04-07 00:00:00', @@ -458,11 +453,9 @@ public function testYearlyByMonthManyInvalidValues() ); } - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testYearlyByMonthEmptyValue() { + $this->expectException(InvalidDataException::class); $this->parse( 'FREQ=YEARLY;COUNT=6;BYMONTHDAY=24;BYMONTH=', '2011-04-07 00:00:00', @@ -576,11 +569,9 @@ public function testYearlyByYearDayNegative() ); } - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testYearlyByYearDayInvalid390() { + $this->expectException(InvalidDataException::class); $this->parse( 'FREQ=YEARLY;COUNT=8;INTERVAL=4;BYYEARDAY=390', '2011-04-07 00:00:00', @@ -589,11 +580,9 @@ public function testYearlyByYearDayInvalid390() ); } - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testYearlyByYearDayInvalid0() { + $this->expectException(InvalidDataException::class); $this->parse( 'FREQ=YEARLY;COUNT=8;INTERVAL=4;BYYEARDAY=0', '2011-04-07 00:00:00', @@ -770,11 +759,9 @@ public function testMultipleValidByWeekNo() ); } - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testInvalidByWeekNo() { + $this->expectException(InvalidDataException::class); $this->parse( 'FREQ=YEARLY;BYWEEKNO=54', '2011-05-16 00:00:00', @@ -802,11 +789,10 @@ public function testYearlyByMonthLoop() * Something, somewhere produced an ics with an interval set to 0. Because * this means we increase the current day (or week, month) by 0, this also * results in an infinite loop. - * - * @expectedException \Sabre\VObject\InvalidDataException */ public function testZeroInterval() { + $this->expectException(InvalidDataException::class); $this->parse( 'FREQ=YEARLY;INTERVAL=0', '2012-08-24 14:57:00', @@ -815,11 +801,9 @@ public function testZeroInterval() ); } - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testInvalidFreq() { + $this->expectException(InvalidDataException::class); $this->parse( 'FREQ=SMONTHLY;INTERVAL=3;UNTIL=20111025T000000Z', '2011-10-07', @@ -827,11 +811,9 @@ public function testInvalidFreq() ); } - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testByDayBadOffset() { + $this->expectException(InvalidDataException::class); $this->parse( 'FREQ=WEEKLY;INTERVAL=1;COUNT=4;BYDAY=0MO;WKST=SA', '2014-08-01 00:00:00', @@ -911,11 +893,9 @@ public function testNeverEnding() ); } - /** - * @expectedException \Sabre\VObject\InvalidDataException - */ public function testUnsupportedPart() { + $this->expectException(InvalidDataException::class); $this->parse( 'FREQ=DAILY;BYWODAN=1', '2014-08-02 00:15:00', diff --git a/tests/VObject/Splitter/ICalendarTest.php b/tests/VObject/Splitter/ICalendarTest.php index 5addf9f6d..2788b96d6 100644 --- a/tests/VObject/Splitter/ICalendarTest.php +++ b/tests/VObject/Splitter/ICalendarTest.php @@ -4,12 +4,13 @@ use PHPUnit\Framework\TestCase; use Sabre\VObject; +use Sabre\VObject\ParseException; class ICalendarTest extends TestCase { protected $version; - public function setUp() + public function setUp(): void { $this->version = VObject\Version::VERSION; } @@ -45,11 +46,9 @@ public function testICalendarImportValidEvent() $this->assertEquals([], VObject\Reader::read($return)->validate()); } - /** - * @expectedException \Sabre\VObject\ParseException - */ public function testICalendarImportWrongType() { + $this->expectException(ParseException::class); $data = <<assertNull($object = $objects->getNext()); } - /** - * @expectedException \Sabre\VObject\ParseException - */ public function testICalendarImportInvalidEvent() { + $this->expectException(ParseException::class); $data = <<createStream($data); diff --git a/tests/VObject/Splitter/VCardTest.php b/tests/VObject/Splitter/VCardTest.php index a7e4ea3d2..1402b5094 100644 --- a/tests/VObject/Splitter/VCardTest.php +++ b/tests/VObject/Splitter/VCardTest.php @@ -3,6 +3,7 @@ namespace Sabre\VObject\Splitter; use PHPUnit\Framework\TestCase; +use Sabre\VObject\ParseException; class VCardTest extends TestCase { @@ -33,11 +34,9 @@ public function testVCardImportValidVCard() $this->assertEquals(1, $count); } - /** - * @expectedException \Sabre\VObject\ParseException - */ public function testVCardImportWrongType() { + $this->expectException(ParseException::class); $event[] = <<assertEquals(4, $count); } - /** - * @expectedException \Sabre\VObject\ParseException - */ public function testVCardImportVCardNoComponent() { + $this->expectException(ParseException::class); $data = <<expectException(\Sabre\VObject\ParseException::class); + $this->expectException(ParseException::class); $this->expectExceptionMessage('Invalid MimeDir file. Unexpected component: "BEGIN:VCARD" in document type VCARD'); while ($object = $splitter->getNext()) { } @@ -161,11 +158,9 @@ public function testVCardImportEndOfData() $this->assertNull($objects->getNext()); } - /** - * @expectedException \Sabre\VObject\ParseException - */ public function testVCardImportCheckInvalidArgumentException() { + $this->expectException(ParseException::class); $data = <<assertEquals($ex->getName(), $tz->getName()); } - /** - * @expectedException \InvalidArgumentException - */ public function testTimezoneFail() { + $this->expectException(\InvalidArgumentException::class); $tz = TimeZoneUtil::getTimeZone('FooBar', null, true); } diff --git a/tests/VObject/VCardConverterTest.php b/tests/VObject/VCardConverterTest.php index 72c3ac64a..d7c48e045 100644 --- a/tests/VObject/VCardConverterTest.php +++ b/tests/VObject/VCardConverterTest.php @@ -294,11 +294,9 @@ public function testBDAYConversion() ); } - /** - * @expectedException \InvalidArgumentException - */ public function testUnknownSourceVCardVersion() { + $this->expectException(\InvalidArgumentException::class); $input = <<convert(Document::VCARD40); } - /** - * @expectedException \InvalidArgumentException - */ public function testUnknownTargetVCardVersion() { + $this->expectException(\InvalidArgumentException::class); $input = << Date: Tue, 7 Jan 2020 14:09:21 +0100 Subject: [PATCH 023/165] Fixed phpstan level 1 errors --- lib/Property/ICalendar/DateTime.php | 16 ++++++++-------- lib/Recur/RRuleIterator.php | 7 +++++++ phpstan.neon | 4 +++- tests/VObject/CliTest.php | 10 ++++++++-- tests/VObject/ComponentTest.php | 1 + tests/VObject/ElementListTest.php | 1 + tests/VObject/ITip/BrokerTester.php | 1 + .../Recur/EventIterator/ByMonthInDailyTest.php | 1 + .../Recur/EventIterator/BySetPosHangTest.php | 1 + tests/bootstrap.php | 8 -------- 10 files changed, 31 insertions(+), 19 deletions(-) diff --git a/lib/Property/ICalendar/DateTime.php b/lib/Property/ICalendar/DateTime.php index a0d1b38d4..66d7a122f 100644 --- a/lib/Property/ICalendar/DateTime.php +++ b/lib/Property/ICalendar/DateTime.php @@ -338,8 +338,8 @@ public function validate($options = 0) $messages = parent::validate($options); $valueType = $this->getValueType(); $values = $this->getParts(); - try { - foreach ($values as $value) { + foreach ($values as $value) { + try { switch ($valueType) { case 'DATE': DateTimeParser::parseDate($value); @@ -348,13 +348,13 @@ public function validate($options = 0) DateTimeParser::parseDateTime($value); break; } + } catch (InvalidDataException $e) { + $messages[] = [ + 'level' => 3, + 'message' => 'The supplied value ('.$value.') is not a correct '.$valueType, + 'node' => $this, + ]; } - } catch (InvalidDataException $e) { - $messages[] = [ - 'level' => 3, - 'message' => 'The supplied value ('.$value.') is not a correct '.$valueType, - 'node' => $this, - ]; } return $messages; diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index dd07310e5..55581e9ac 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -322,14 +322,17 @@ protected function nextDaily() return; } + $recurrenceHours = []; if (!empty($this->byHour)) { $recurrenceHours = $this->getHours(); } + $recurrenceDays = []; if (!empty($this->byDay)) { $recurrenceDays = $this->getDays(); } + $recurrenceMonths = []; if (!empty($this->byMonth)) { $recurrenceMonths = $this->getMonths(); } @@ -372,10 +375,12 @@ protected function nextWeekly() return; } + $recurrenceHours = []; if ($this->byHour) { $recurrenceHours = $this->getHours(); } + $recurrenceDays = []; if ($this->byDay) { $recurrenceDays = $this->getDays(); } @@ -436,6 +441,7 @@ protected function nextMonthly() return; } + $occurrence = -1; while (true) { $occurrences = $this->getMonthlyOccurrences(); @@ -605,6 +611,7 @@ protected function nextYearly() // If we got a byDay or getMonthDay filter, we must first expand // further. if ($this->byDay || $this->byMonthDay) { + $occurrence = -1; while (true) { $occurrences = $this->getMonthlyOccurrences(); diff --git a/phpstan.neon b/phpstan.neon index 5335bc651..c705178c9 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,2 +1,4 @@ parameters: - level: 0 + level: 1 + universalObjectCratesClasses: + - \Sabre\VObject\Component diff --git a/tests/VObject/CliTest.php b/tests/VObject/CliTest.php index 2fa0162e4..5736f9a01 100644 --- a/tests/VObject/CliTest.php +++ b/tests/VObject/CliTest.php @@ -14,8 +14,14 @@ class CliTest extends TestCase /** @var CliMock */ private $cli; + private $sabreTempDir = __DIR__.'/../temp/'; + public function setUp(): void { + if (!file_exists($this->sabreTempDir)) { + mkdir($this->sabreTempDir); + } + $this->cli = new CliMock(); $this->cli->stderr = fopen('php://memory', 'r+'); $this->cli->stdout = fopen('php://memory', 'r+'); @@ -269,7 +275,7 @@ public function testConvertMimeDir() public function testConvertDefaultFormats() { - $outputFile = SABRE_TEMPDIR.'bar.json'; + $outputFile = $this->sabreTempDir.'bar.json'; $this->assertEquals( 2, @@ -282,7 +288,7 @@ public function testConvertDefaultFormats() public function testConvertDefaultFormats2() { - $outputFile = SABRE_TEMPDIR.'bar.ics'; + $outputFile = $this->sabreTempDir.'bar.ics'; $this->assertEquals( 2, diff --git a/tests/VObject/ComponentTest.php b/tests/VObject/ComponentTest.php index b1e73c634..6026aaa54 100644 --- a/tests/VObject/ComponentTest.php +++ b/tests/VObject/ComponentTest.php @@ -19,6 +19,7 @@ public function testIterate() $comp->add($sub); $count = 0; + $key = null; foreach ($comp->children() as $key => $subcomponent) { ++$count; $this->assertInstanceOf('Sabre\\VObject\\Component', $subcomponent); diff --git a/tests/VObject/ElementListTest.php b/tests/VObject/ElementListTest.php index 1842ca963..2046ae4ca 100644 --- a/tests/VObject/ElementListTest.php +++ b/tests/VObject/ElementListTest.php @@ -20,6 +20,7 @@ public function testIterate() $elemList = new ElementList($elems); $count = 0; + $key = null; foreach ($elemList as $key => $subcomponent) { ++$count; $this->assertInstanceOf('Sabre\\VObject\\Component', $subcomponent); diff --git a/tests/VObject/ITip/BrokerTester.php b/tests/VObject/ITip/BrokerTester.php index 350e37e23..9e9956e03 100644 --- a/tests/VObject/ITip/BrokerTester.php +++ b/tests/VObject/ITip/BrokerTester.php @@ -45,6 +45,7 @@ public function process($input, $existingObject = null, $expected = false) $vcal = Reader::read($input); + $mainComponent = new \Sabre\VObject\Component\VEvent($vcal, 'VEVENT'); foreach ($vcal->getComponents() as $mainComponent) { if ('VEVENT' === $mainComponent->name) { break; diff --git a/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php b/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php index 71858c36f..3448032e8 100644 --- a/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php +++ b/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php @@ -40,6 +40,7 @@ public function testExpand() $vcal = $vcal->expand(new DateTime('2013-09-28'), new DateTime('2014-09-11')); + $dates = []; foreach ($vcal->VEVENT as $event) { $dates[] = $event->DTSTART->getValue(); } diff --git a/tests/VObject/Recur/EventIterator/BySetPosHangTest.php b/tests/VObject/Recur/EventIterator/BySetPosHangTest.php index bd00cb52a..caf6b0dc3 100644 --- a/tests/VObject/Recur/EventIterator/BySetPosHangTest.php +++ b/tests/VObject/Recur/EventIterator/BySetPosHangTest.php @@ -35,6 +35,7 @@ public function testExpand() $vcal = $vcal->expand(new DateTime('2015-01-01'), new DateTime('2016-01-01')); + $dates = []; foreach ($vcal->VEVENT as $event) { $dates[] = $event->DTSTART->getValue(); } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 590b25080..2496aa4ff 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -13,11 +13,3 @@ break; } } - -if (!defined('SABRE_TEMPDIR')) { - define('SABRE_TEMPDIR', __DIR__.'/temp/'); -} - -if (!file_exists(SABRE_TEMPDIR)) { - mkdir(SABRE_TEMPDIR); -} From c476d933e1ee16b1b859f1b6fe8aa2523880b3c1 Mon Sep 17 00:00:00 2001 From: Jeroen van Oort Date: Wed, 8 Jan 2020 09:06:05 +0100 Subject: [PATCH 024/165] Make sure there is no logic change --- lib/Property/ICalendar/DateTime.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Property/ICalendar/DateTime.php b/lib/Property/ICalendar/DateTime.php index 66d7a122f..f2dbdeba3 100644 --- a/lib/Property/ICalendar/DateTime.php +++ b/lib/Property/ICalendar/DateTime.php @@ -354,6 +354,7 @@ public function validate($options = 0) 'message' => 'The supplied value ('.$value.') is not a correct '.$valueType, 'node' => $this, ]; + break; } } From 36d00ee5642ecf97a8cbe2a890c183aeaf3dfbe6 Mon Sep 17 00:00:00 2001 From: Jeroen van Oort Date: Wed, 8 Jan 2020 09:19:35 +0100 Subject: [PATCH 025/165] Prevent setting foreach key beforehand --- tests/VObject/ComponentTest.php | 6 ++++-- tests/VObject/ElementListTest.php | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/VObject/ComponentTest.php b/tests/VObject/ComponentTest.php index 6026aaa54..4979592a0 100644 --- a/tests/VObject/ComponentTest.php +++ b/tests/VObject/ComponentTest.php @@ -19,13 +19,15 @@ public function testIterate() $comp->add($sub); $count = 0; - $key = null; foreach ($comp->children() as $key => $subcomponent) { ++$count; $this->assertInstanceOf('Sabre\\VObject\\Component', $subcomponent); + + if (2 === $count) { + $this->assertEquals(1, $key); + } } $this->assertEquals(2, $count); - $this->assertEquals(1, $key); } public function testMagicGet() diff --git a/tests/VObject/ElementListTest.php b/tests/VObject/ElementListTest.php index 2046ae4ca..4b1ce999f 100644 --- a/tests/VObject/ElementListTest.php +++ b/tests/VObject/ElementListTest.php @@ -20,12 +20,14 @@ public function testIterate() $elemList = new ElementList($elems); $count = 0; - $key = null; foreach ($elemList as $key => $subcomponent) { ++$count; $this->assertInstanceOf('Sabre\\VObject\\Component', $subcomponent); + + if (3 === $count) { + $this->assertEquals(2, $key); + } } $this->assertEquals(3, $count); - $this->assertEquals(2, $key); } } From 1af8f3f42b43e56c5ed84074e81c365e75111f66 Mon Sep 17 00:00:00 2001 From: Jeroen van Oort Date: Fri, 31 Jan 2020 13:18:17 +0100 Subject: [PATCH 026/165] Refactored fqcn strings to ::class to allow checking with phpstan (#495) --- lib/Component/VCalendar.php | 152 +++++++++--------- lib/Component/VCard.php | 136 ++++++++-------- lib/Document.php | 4 +- lib/Parser/Json.php | 6 +- lib/Parser/XML.php | 4 +- tests/VObject/Component/AvailableTest.php | 2 +- tests/VObject/Component/VAvailabilityTest.php | 4 +- tests/VObject/ComponentTest.php | 12 +- tests/VObject/DocumentTest.php | 12 +- tests/VObject/ElementListTest.php | 2 +- tests/VObject/EmptyParameterTest.php | 2 +- tests/VObject/ICalendar/AttachParseTest.php | 3 +- tests/VObject/Issue36WorkAroundTest.php | 2 +- tests/VObject/Issue64Test.php | 2 +- tests/VObject/Issue96Test.php | 2 +- tests/VObject/Parser/QuotedPrintableTest.php | 9 +- tests/VObject/Property/FloatTest.php | 2 +- .../VObject/Property/ICalendar/RecurTest.php | 2 +- .../Property/VCard/LanguageTagTest.php | 4 +- .../Property/VCard/PhoneNumberTest.php | 2 +- tests/VObject/PropertyTest.php | 6 +- tests/VObject/ReaderTest.php | 50 +++--- .../EventIterator/ByMonthInDailyTest.php | 3 +- .../Recur/EventIterator/BySetPosHangTest.php | 3 +- .../EventIterator/ExpandFloatingTimesTest.php | 5 +- .../EventIterator/HandleRDateExpandTest.php | 3 +- .../EventIterator/IncorrectExpandTest.php | 3 +- .../Recur/EventIterator/Issue26Test.php | 3 +- .../Recur/EventIterator/Issue48Test.php | 3 +- .../Recur/EventIterator/Issue50Test.php | 3 +- .../EventIterator/MissingOverriddenTest.php | 3 +- .../Recur/EventIterator/NoInstancesTest.php | 3 +- tests/VObject/VCardConverterTest.php | 2 +- 33 files changed, 234 insertions(+), 220 deletions(-) diff --git a/lib/Component/VCalendar.php b/lib/Component/VCalendar.php index 54419c88a..40e09a1c0 100644 --- a/lib/Component/VCalendar.php +++ b/lib/Component/VCalendar.php @@ -37,15 +37,15 @@ class VCalendar extends VObject\Document * @var array */ public static $componentMap = [ - 'VCALENDAR' => 'Sabre\\VObject\\Component\\VCalendar', - 'VALARM' => 'Sabre\\VObject\\Component\\VAlarm', - 'VEVENT' => 'Sabre\\VObject\\Component\\VEvent', - 'VFREEBUSY' => 'Sabre\\VObject\\Component\\VFreeBusy', - 'VAVAILABILITY' => 'Sabre\\VObject\\Component\\VAvailability', - 'AVAILABLE' => 'Sabre\\VObject\\Component\\Available', - 'VJOURNAL' => 'Sabre\\VObject\\Component\\VJournal', - 'VTIMEZONE' => 'Sabre\\VObject\\Component\\VTimeZone', - 'VTODO' => 'Sabre\\VObject\\Component\\VTodo', + 'VCALENDAR' => self::class, + 'VALARM' => VAlarm::class, + 'VEVENT' => VEvent::class, + 'VFREEBUSY' => VFreeBusy::class, + 'VAVAILABILITY' => VAvailability::class, + 'AVAILABLE' => Available::class, + 'VJOURNAL' => VJournal::class, + 'VTIMEZONE' => VTimeZone::class, + 'VTODO' => VTodo::class, ]; /** @@ -54,21 +54,21 @@ class VCalendar extends VObject\Document * @var array */ public static $valueMap = [ - 'BINARY' => 'Sabre\\VObject\\Property\\Binary', - 'BOOLEAN' => 'Sabre\\VObject\\Property\\Boolean', - 'CAL-ADDRESS' => 'Sabre\\VObject\\Property\\ICalendar\\CalAddress', - 'DATE' => 'Sabre\\VObject\\Property\\ICalendar\\Date', - 'DATE-TIME' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime', - 'DURATION' => 'Sabre\\VObject\\Property\\ICalendar\\Duration', - 'FLOAT' => 'Sabre\\VObject\\Property\\FloatValue', - 'INTEGER' => 'Sabre\\VObject\\Property\\IntegerValue', - 'PERIOD' => 'Sabre\\VObject\\Property\\ICalendar\\Period', - 'RECUR' => 'Sabre\\VObject\\Property\\ICalendar\\Recur', - 'TEXT' => 'Sabre\\VObject\\Property\\Text', - 'TIME' => 'Sabre\\VObject\\Property\\Time', - 'UNKNOWN' => 'Sabre\\VObject\\Property\\Unknown', // jCard / jCal-only. - 'URI' => 'Sabre\\VObject\\Property\\Uri', - 'UTC-OFFSET' => 'Sabre\\VObject\\Property\\UtcOffset', + 'BINARY' => VObject\Property\Binary::class, + 'BOOLEAN' => VObject\Property\Boolean::class, + 'CAL-ADDRESS' => VObject\Property\ICalendar\CalAddress::class, + 'DATE' => VObject\Property\ICalendar\Date::class, + 'DATE-TIME' => VObject\Property\ICalendar\DateTime::class, + 'DURATION' => VObject\Property\ICalendar\Duration::class, + 'FLOAT' => VObject\Property\FloatValue::class, + 'INTEGER' => VObject\Property\IntegerValue::class, + 'PERIOD' => VObject\Property\ICalendar\Period::class, + 'RECUR' => VObject\Property\ICalendar\Recur::class, + 'TEXT' => VObject\Property\Text::class, + 'TIME' => VObject\Property\Time::class, + 'UNKNOWN' => VObject\Property\Unknown::class, // jCard / jCal-only. + 'URI' => VObject\Property\Uri::class, + 'UTC-OFFSET' => VObject\Property\UtcOffset::class, ]; /** @@ -78,78 +78,78 @@ class VCalendar extends VObject\Document */ public static $propertyMap = [ // Calendar properties - 'CALSCALE' => 'Sabre\\VObject\\Property\\FlatText', - 'METHOD' => 'Sabre\\VObject\\Property\\FlatText', - 'PRODID' => 'Sabre\\VObject\\Property\\FlatText', - 'VERSION' => 'Sabre\\VObject\\Property\\FlatText', + 'CALSCALE' => VObject\Property\FlatText::class, + 'METHOD' => VObject\Property\FlatText::class, + 'PRODID' => VObject\Property\FlatText::class, + 'VERSION' => VObject\Property\FlatText::class, // Component properties - 'ATTACH' => 'Sabre\\VObject\\Property\\Uri', - 'CATEGORIES' => 'Sabre\\VObject\\Property\\Text', - 'CLASS' => 'Sabre\\VObject\\Property\\FlatText', - 'COMMENT' => 'Sabre\\VObject\\Property\\FlatText', - 'DESCRIPTION' => 'Sabre\\VObject\\Property\\FlatText', - 'GEO' => 'Sabre\\VObject\\Property\\FloatValue', - 'LOCATION' => 'Sabre\\VObject\\Property\\FlatText', - 'PERCENT-COMPLETE' => 'Sabre\\VObject\\Property\\IntegerValue', - 'PRIORITY' => 'Sabre\\VObject\\Property\\IntegerValue', - 'RESOURCES' => 'Sabre\\VObject\\Property\\Text', - 'STATUS' => 'Sabre\\VObject\\Property\\FlatText', - 'SUMMARY' => 'Sabre\\VObject\\Property\\FlatText', + 'ATTACH' => VObject\Property\Uri::class, + 'CATEGORIES' => VObject\Property\Text::class, + 'CLASS' => VObject\Property\FlatText::class, + 'COMMENT' => VObject\Property\FlatText::class, + 'DESCRIPTION' => VObject\Property\FlatText::class, + 'GEO' => VObject\Property\FloatValue::class, + 'LOCATION' => VObject\Property\FlatText::class, + 'PERCENT-COMPLETE' => VObject\Property\IntegerValue::class, + 'PRIORITY' => VObject\Property\IntegerValue::class, + 'RESOURCES' => VObject\Property\Text::class, + 'STATUS' => VObject\Property\FlatText::class, + 'SUMMARY' => VObject\Property\FlatText::class, // Date and Time Component Properties - 'COMPLETED' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime', - 'DTEND' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime', - 'DUE' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime', - 'DTSTART' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime', - 'DURATION' => 'Sabre\\VObject\\Property\\ICalendar\\Duration', - 'FREEBUSY' => 'Sabre\\VObject\\Property\\ICalendar\\Period', - 'TRANSP' => 'Sabre\\VObject\\Property\\FlatText', + 'COMPLETED' => VObject\Property\ICalendar\DateTime::class, + 'DTEND' => VObject\Property\ICalendar\DateTime::class, + 'DUE' => VObject\Property\ICalendar\DateTime::class, + 'DTSTART' => VObject\Property\ICalendar\DateTime::class, + 'DURATION' => VObject\Property\ICalendar\Duration::class, + 'FREEBUSY' => VObject\Property\ICalendar\Period::class, + 'TRANSP' => VObject\Property\FlatText::class, // Time Zone Component Properties - 'TZID' => 'Sabre\\VObject\\Property\\FlatText', - 'TZNAME' => 'Sabre\\VObject\\Property\\FlatText', - 'TZOFFSETFROM' => 'Sabre\\VObject\\Property\\UtcOffset', - 'TZOFFSETTO' => 'Sabre\\VObject\\Property\\UtcOffset', - 'TZURL' => 'Sabre\\VObject\\Property\\Uri', + 'TZID' => VObject\Property\FlatText::class, + 'TZNAME' => VObject\Property\FlatText::class, + 'TZOFFSETFROM' => VObject\Property\UtcOffset::class, + 'TZOFFSETTO' => VObject\Property\UtcOffset::class, + 'TZURL' => VObject\Property\Uri::class, // Relationship Component Properties - 'ATTENDEE' => 'Sabre\\VObject\\Property\\ICalendar\\CalAddress', - 'CONTACT' => 'Sabre\\VObject\\Property\\FlatText', - 'ORGANIZER' => 'Sabre\\VObject\\Property\\ICalendar\\CalAddress', - 'RECURRENCE-ID' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime', - 'RELATED-TO' => 'Sabre\\VObject\\Property\\FlatText', - 'URL' => 'Sabre\\VObject\\Property\\Uri', - 'UID' => 'Sabre\\VObject\\Property\\FlatText', + 'ATTENDEE' => VObject\Property\ICalendar\CalAddress::class, + 'CONTACT' => VObject\Property\FlatText::class, + 'ORGANIZER' => VObject\Property\ICalendar\CalAddress::class, + 'RECURRENCE-ID' => VObject\Property\ICalendar\DateTime::class, + 'RELATED-TO' => VObject\Property\FlatText::class, + 'URL' => VObject\Property\Uri::class, + 'UID' => VObject\Property\FlatText::class, // Recurrence Component Properties - 'EXDATE' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime', - 'RDATE' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime', - 'RRULE' => 'Sabre\\VObject\\Property\\ICalendar\\Recur', - 'EXRULE' => 'Sabre\\VObject\\Property\\ICalendar\\Recur', // Deprecated since rfc5545 + 'EXDATE' => VObject\Property\ICalendar\DateTime::class, + 'RDATE' => VObject\Property\ICalendar\DateTime::class, + 'RRULE' => VObject\Property\ICalendar\Recur::class, + 'EXRULE' => VObject\Property\ICalendar\Recur::class, // Deprecated since rfc5545 // Alarm Component Properties - 'ACTION' => 'Sabre\\VObject\\Property\\FlatText', - 'REPEAT' => 'Sabre\\VObject\\Property\\IntegerValue', - 'TRIGGER' => 'Sabre\\VObject\\Property\\ICalendar\\Duration', + 'ACTION' => VObject\Property\FlatText::class, + 'REPEAT' => VObject\Property\IntegerValue::class, + 'TRIGGER' => VObject\Property\ICalendar\Duration::class, // Change Management Component Properties - 'CREATED' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime', - 'DTSTAMP' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime', - 'LAST-MODIFIED' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime', - 'SEQUENCE' => 'Sabre\\VObject\\Property\\IntegerValue', + 'CREATED' => VObject\Property\ICalendar\DateTime::class, + 'DTSTAMP' => VObject\Property\ICalendar\DateTime::class, + 'LAST-MODIFIED' => VObject\Property\ICalendar\DateTime::class, + 'SEQUENCE' => VObject\Property\IntegerValue::class, // Request Status - 'REQUEST-STATUS' => 'Sabre\\VObject\\Property\\Text', + 'REQUEST-STATUS' => VObject\Property\Text::class, // Additions from draft-daboo-valarm-extensions-04 - 'ALARM-AGENT' => 'Sabre\\VObject\\Property\\Text', - 'ACKNOWLEDGED' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime', - 'PROXIMITY' => 'Sabre\\VObject\\Property\\Text', - 'DEFAULT-ALARM' => 'Sabre\\VObject\\Property\\Boolean', + 'ALARM-AGENT' => VObject\Property\Text::class, + 'ACKNOWLEDGED' => VObject\Property\ICalendar\DateTime::class, + 'PROXIMITY' => VObject\Property\Text::class, + 'DEFAULT-ALARM' => VObject\Property\Boolean::class, // Additions from draft-daboo-calendar-availability-05 - 'BUSYTYPE' => 'Sabre\\VObject\\Property\\Text', + 'BUSYTYPE' => VObject\Property\Text::class, ]; /** diff --git a/lib/Component/VCard.php b/lib/Component/VCard.php index 4d7e861a2..51321949f 100644 --- a/lib/Component/VCard.php +++ b/lib/Component/VCard.php @@ -39,7 +39,7 @@ class VCard extends VObject\Document * @var array */ public static $componentMap = [ - 'VCARD' => 'Sabre\\VObject\\Component\\VCard', + 'VCARD' => VCard::class, ]; /** @@ -48,23 +48,23 @@ class VCard extends VObject\Document * @var array */ public static $valueMap = [ - 'BINARY' => 'Sabre\\VObject\\Property\\Binary', - 'BOOLEAN' => 'Sabre\\VObject\\Property\\Boolean', - 'CONTENT-ID' => 'Sabre\\VObject\\Property\\FlatText', // vCard 2.1 only - 'DATE' => 'Sabre\\VObject\\Property\\VCard\\Date', - 'DATE-TIME' => 'Sabre\\VObject\\Property\\VCard\\DateTime', - 'DATE-AND-OR-TIME' => 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime', // vCard only - 'FLOAT' => 'Sabre\\VObject\\Property\\FloatValue', - 'INTEGER' => 'Sabre\\VObject\\Property\\IntegerValue', - 'LANGUAGE-TAG' => 'Sabre\\VObject\\Property\\VCard\\LanguageTag', - 'PHONE-NUMBER' => 'Sabre\\VObject\\Property\\VCard\\PhoneNumber', // vCard 3.0 only - 'TIMESTAMP' => 'Sabre\\VObject\\Property\\VCard\\TimeStamp', - 'TEXT' => 'Sabre\\VObject\\Property\\Text', - 'TIME' => 'Sabre\\VObject\\Property\\Time', - 'UNKNOWN' => 'Sabre\\VObject\\Property\\Unknown', // jCard / jCal-only. - 'URI' => 'Sabre\\VObject\\Property\\Uri', - 'URL' => 'Sabre\\VObject\\Property\\Uri', // vCard 2.1 only - 'UTC-OFFSET' => 'Sabre\\VObject\\Property\\UtcOffset', + 'BINARY' => VObject\Property\Binary::class, + 'BOOLEAN' => VObject\Property\Boolean::class, + 'CONTENT-ID' => VObject\Property\FlatText::class, // vCard 2.1 only + 'DATE' => VObject\Property\VCard\Date::class, + 'DATE-TIME' => VObject\Property\VCard\DateTime::class, + 'DATE-AND-OR-TIME' => VObject\Property\VCard\DateAndOrTime::class, // vCard only + 'FLOAT' => VObject\Property\FloatValue::class, + 'INTEGER' => VObject\Property\IntegerValue::class, + 'LANGUAGE-TAG' => VObject\Property\VCard\LanguageTag::class, + 'PHONE-NUMBER' => VObject\Property\VCard\PhoneNumber::class, // vCard 3.0 only + 'TIMESTAMP' => VObject\Property\VCard\TimeStamp::class, + 'TEXT' => VObject\Property\Text::class, + 'TIME' => VObject\Property\Time::class, + 'UNKNOWN' => VObject\Property\Unknown::class, // jCard / jCal-only. + 'URI' => VObject\Property\Uri::class, + 'URL' => VObject\Property\Uri::class, // vCard 2.1 only + 'UTC-OFFSET' => VObject\Property\UtcOffset::class, ]; /** @@ -74,68 +74,68 @@ class VCard extends VObject\Document */ public static $propertyMap = [ // vCard 2.1 properties and up - 'N' => 'Sabre\\VObject\\Property\\Text', - 'FN' => 'Sabre\\VObject\\Property\\FlatText', - 'PHOTO' => 'Sabre\\VObject\\Property\\Binary', - 'BDAY' => 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime', - 'ADR' => 'Sabre\\VObject\\Property\\Text', - 'LABEL' => 'Sabre\\VObject\\Property\\FlatText', // Removed in vCard 4.0 - 'TEL' => 'Sabre\\VObject\\Property\\FlatText', - 'EMAIL' => 'Sabre\\VObject\\Property\\FlatText', - 'MAILER' => 'Sabre\\VObject\\Property\\FlatText', // Removed in vCard 4.0 - 'GEO' => 'Sabre\\VObject\\Property\\FlatText', - 'TITLE' => 'Sabre\\VObject\\Property\\FlatText', - 'ROLE' => 'Sabre\\VObject\\Property\\FlatText', - 'LOGO' => 'Sabre\\VObject\\Property\\Binary', + 'N' => VObject\Property\Text::class, + 'FN' => VObject\Property\FlatText::class, + 'PHOTO' => VObject\Property\Binary::class, + 'BDAY' => VObject\Property\VCard\DateAndOrTime::class, + 'ADR' => VObject\Property\Text::class, + 'LABEL' => VObject\Property\FlatText::class, // Removed in vCard 4.0 + 'TEL' => VObject\Property\FlatText::class, + 'EMAIL' => VObject\Property\FlatText::class, + 'MAILER' => VObject\Property\FlatText::class, // Removed in vCard 4.0 + 'GEO' => VObject\Property\FlatText::class, + 'TITLE' => VObject\Property\FlatText::class, + 'ROLE' => VObject\Property\FlatText::class, + 'LOGO' => VObject\Property\Binary::class, // 'AGENT' => 'Sabre\\VObject\\Property\\', // Todo: is an embedded vCard. Probably rare, so // not supported at the moment - 'ORG' => 'Sabre\\VObject\\Property\\Text', - 'NOTE' => 'Sabre\\VObject\\Property\\FlatText', - 'REV' => 'Sabre\\VObject\\Property\\VCard\\TimeStamp', - 'SOUND' => 'Sabre\\VObject\\Property\\FlatText', - 'URL' => 'Sabre\\VObject\\Property\\Uri', - 'UID' => 'Sabre\\VObject\\Property\\FlatText', - 'VERSION' => 'Sabre\\VObject\\Property\\FlatText', - 'KEY' => 'Sabre\\VObject\\Property\\FlatText', - 'TZ' => 'Sabre\\VObject\\Property\\Text', + 'ORG' => VObject\Property\Text::class, + 'NOTE' => VObject\Property\FlatText::class, + 'REV' => VObject\Property\VCard\TimeStamp::class, + 'SOUND' => VObject\Property\FlatText::class, + 'URL' => VObject\Property\Uri::class, + 'UID' => VObject\Property\FlatText::class, + 'VERSION' => VObject\Property\FlatText::class, + 'KEY' => VObject\Property\FlatText::class, + 'TZ' => VObject\Property\Text::class, // vCard 3.0 properties - 'CATEGORIES' => 'Sabre\\VObject\\Property\\Text', - 'SORT-STRING' => 'Sabre\\VObject\\Property\\FlatText', - 'PRODID' => 'Sabre\\VObject\\Property\\FlatText', - 'NICKNAME' => 'Sabre\\VObject\\Property\\Text', - 'CLASS' => 'Sabre\\VObject\\Property\\FlatText', // Removed in vCard 4.0 + 'CATEGORIES' => VObject\Property\Text::class, + 'SORT-STRING' => VObject\Property\FlatText::class, + 'PRODID' => VObject\Property\FlatText::class, + 'NICKNAME' => VObject\Property\Text::class, + 'CLASS' => VObject\Property\FlatText::class, // Removed in vCard 4.0 // rfc2739 properties - 'FBURL' => 'Sabre\\VObject\\Property\\Uri', - 'CAPURI' => 'Sabre\\VObject\\Property\\Uri', - 'CALURI' => 'Sabre\\VObject\\Property\\Uri', - 'CALADRURI' => 'Sabre\\VObject\\Property\\Uri', + 'FBURL' => VObject\Property\Uri::class, + 'CAPURI' => VObject\Property\Uri::class, + 'CALURI' => VObject\Property\Uri::class, + 'CALADRURI' => VObject\Property\Uri::class, // rfc4770 properties - 'IMPP' => 'Sabre\\VObject\\Property\\Uri', + 'IMPP' => VObject\Property\Uri::class, // vCard 4.0 properties - 'SOURCE' => 'Sabre\\VObject\\Property\\Uri', - 'XML' => 'Sabre\\VObject\\Property\\FlatText', - 'ANNIVERSARY' => 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime', - 'CLIENTPIDMAP' => 'Sabre\\VObject\\Property\\Text', - 'LANG' => 'Sabre\\VObject\\Property\\VCard\\LanguageTag', - 'GENDER' => 'Sabre\\VObject\\Property\\Text', - 'KIND' => 'Sabre\\VObject\\Property\\FlatText', - 'MEMBER' => 'Sabre\\VObject\\Property\\Uri', - 'RELATED' => 'Sabre\\VObject\\Property\\Uri', + 'SOURCE' => VObject\Property\Uri::class, + 'XML' => VObject\Property\FlatText::class, + 'ANNIVERSARY' => VObject\Property\VCard\DateAndOrTime::class, + 'CLIENTPIDMAP' => VObject\Property\Text::class, + 'LANG' => VObject\Property\VCard\LanguageTag::class, + 'GENDER' => VObject\Property\Text::class, + 'KIND' => VObject\Property\FlatText::class, + 'MEMBER' => VObject\Property\Uri::class, + 'RELATED' => VObject\Property\Uri::class, // rfc6474 properties - 'BIRTHPLACE' => 'Sabre\\VObject\\Property\\FlatText', - 'DEATHPLACE' => 'Sabre\\VObject\\Property\\FlatText', - 'DEATHDATE' => 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime', + 'BIRTHPLACE' => VObject\Property\FlatText::class, + 'DEATHPLACE' => VObject\Property\FlatText::class, + 'DEATHDATE' => VObject\Property\VCard\DateAndOrTime::class, // rfc6715 properties - 'EXPERTISE' => 'Sabre\\VObject\\Property\\FlatText', - 'HOBBY' => 'Sabre\\VObject\\Property\\FlatText', - 'INTEREST' => 'Sabre\\VObject\\Property\\FlatText', - 'ORG-DIRECTORY' => 'Sabre\\VObject\\Property\\FlatText', + 'EXPERTISE' => VObject\Property\FlatText::class, + 'HOBBY' => VObject\Property\FlatText::class, + 'INTEREST' => VObject\Property\FlatText::class, + 'ORG-DIRECTORY' => VObject\Property\FlatText::class, ]; /** @@ -526,8 +526,8 @@ public function getClassNameForPropertyName($propertyName) $className = parent::getClassNameForPropertyName($propertyName); // In vCard 4, BINARY no longer exists, and we need URI instead. - if ('Sabre\\VObject\\Property\\Binary' == $className && self::VCARD40 === $this->getDocumentType()) { - return 'Sabre\\VObject\\Property\\Uri'; + if (VObject\Property\Binary::class == $className && self::VCARD40 === $this->getDocumentType()) { + return VObject\Property\Uri::class; } return $className; diff --git a/lib/Document.php b/lib/Document.php index 0cb2e0978..14a77c911 100644 --- a/lib/Document.php +++ b/lib/Document.php @@ -160,7 +160,7 @@ public function create($name) public function createComponent($name, array $children = null, $defaults = true) { $name = strtoupper($name); - $class = 'Sabre\\VObject\\Component'; + $class = Component::class; if (isset(static::$componentMap[$name])) { $class = static::$componentMap[$name]; @@ -258,7 +258,7 @@ public function getClassNameForPropertyName($propertyName) if (isset(static::$propertyMap[$propertyName])) { return static::$propertyMap[$propertyName]; } else { - return 'Sabre\\VObject\\Property\\Unknown'; + return Property\Unknown::class; } } } diff --git a/lib/Parser/Json.php b/lib/Parser/Json.php index e8138b197..f33603207 100644 --- a/lib/Parser/Json.php +++ b/lib/Parser/Json.php @@ -7,6 +7,8 @@ use Sabre\VObject\Document; use Sabre\VObject\EofException; use Sabre\VObject\ParseException; +use Sabre\VObject\Property\FlatText; +use Sabre\VObject\Property\Text; /** * Json Parser. @@ -156,8 +158,8 @@ public function parseProperty(array $jProp) // represents TEXT values. We have to normalize these here. In the // future we can get rid of FlatText once we're allowed to break BC // again. - if ('Sabre\VObject\Property\FlatText' === $defaultPropertyClass) { - $defaultPropertyClass = 'Sabre\VObject\Property\Text'; + if (FlatText::class === $defaultPropertyClass) { + $defaultPropertyClass = Text::class; } // If the value type we received (e.g.: TEXT) was not the default value diff --git a/lib/Parser/XML.php b/lib/Parser/XML.php index 8b7693edd..78773173d 100644 --- a/lib/Parser/XML.php +++ b/lib/Parser/XML.php @@ -351,9 +351,9 @@ public function setInput($input) if (is_string($input)) { $reader = new SabreXml\Reader(); $reader->elementMap['{'.self::XCAL_NAMESPACE.'}period'] - = 'Sabre\VObject\Parser\XML\Element\KeyValue'; + = XML\Element\KeyValue::class; $reader->elementMap['{'.self::XCAL_NAMESPACE.'}recur'] - = 'Sabre\VObject\Parser\XML\Element\KeyValue'; + = XML\Element\KeyValue::class; $reader->xml($input); $input = $reader->parse(); } diff --git a/tests/VObject/Component/AvailableTest.php b/tests/VObject/Component/AvailableTest.php index 55292424e..bf0a6716f 100644 --- a/tests/VObject/Component/AvailableTest.php +++ b/tests/VObject/Component/AvailableTest.php @@ -22,7 +22,7 @@ public function testAvailableComponent() END:VCALENDAR VCAL; $document = Reader::read($vcal); - $this->assertInstanceOf(__NAMESPACE__.'\Available', $document->AVAILABLE); + $this->assertInstanceOf(Available::class, $document->AVAILABLE); } public function testGetEffectiveStartEnd() diff --git a/tests/VObject/Component/VAvailabilityTest.php b/tests/VObject/Component/VAvailabilityTest.php index b6b9a2b80..2fd9c0dde 100644 --- a/tests/VObject/Component/VAvailabilityTest.php +++ b/tests/VObject/Component/VAvailabilityTest.php @@ -24,7 +24,7 @@ public function testVAvailabilityComponent() VCAL; $document = Reader::read($vcal); - $this->assertInstanceOf(__NAMESPACE__.'\VAvailability', $document->VAVAILABILITY); + $this->assertInstanceOf(VAvailability::class, $document->VAVAILABILITY); } public function testGetEffectiveStartEnd() @@ -236,7 +236,7 @@ public function testAvailableSubComponent() VCAL; $document = Reader::read($vcal); - $this->assertInstanceOf(__NAMESPACE__, $document->VAVAILABILITY->AVAILABLE); + $this->assertInstanceOf(Available::class, $document->VAVAILABILITY->AVAILABLE); } public function testRFCxxxSection3_1_availableprop_required() diff --git a/tests/VObject/ComponentTest.php b/tests/VObject/ComponentTest.php index 4979592a0..f56d55531 100644 --- a/tests/VObject/ComponentTest.php +++ b/tests/VObject/ComponentTest.php @@ -21,7 +21,7 @@ public function testIterate() $count = 0; foreach ($comp->children() as $key => $subcomponent) { ++$count; - $this->assertInstanceOf('Sabre\\VObject\\Component', $subcomponent); + $this->assertInstanceOf(Component::class, $subcomponent); if (2 === $count) { $this->assertEquals(1, $key); @@ -41,7 +41,7 @@ public function testMagicGet() $comp->add($sub); $event = $comp->vevent; - $this->assertInstanceOf('Sabre\\VObject\\Component', $event); + $this->assertInstanceOf(Component::class, $event); $this->assertEquals('VEVENT', $event->name); $this->assertNull($comp->vjournal); @@ -92,7 +92,7 @@ public function testMagicSetScalar() $comp = new VCalendar(); $comp->myProp = 'myValue'; - $this->assertInstanceOf('Sabre\\VObject\\Property', $comp->MYPROP); + $this->assertInstanceOf(Property::class, $comp->MYPROP); $this->assertEquals('myValue', (string) $comp->MYPROP); } @@ -103,7 +103,7 @@ public function testMagicSetScalarTwice() $comp->myProp = 'myValue'; $this->assertEquals(1, count($comp->children())); - $this->assertInstanceOf('Sabre\\VObject\\Property', $comp->MYPROP); + $this->assertInstanceOf(Property::class, $comp->MYPROP); $this->assertEquals('myValue', (string) $comp->MYPROP); } @@ -112,7 +112,7 @@ public function testMagicSetArray() $comp = new VCalendar(); $comp->ORG = ['Acme Inc', 'Section 9']; - $this->assertInstanceOf('Sabre\\VObject\\Property', $comp->ORG); + $this->assertInstanceOf(Property::class, $comp->ORG); $this->assertEquals(['Acme Inc', 'Section 9'], $comp->ORG->getParts()); } @@ -216,7 +216,7 @@ public function testAddScalarParams() $bla = $comp->children()[0]; - $this->assertInstanceOf('Sabre\\VObject\\Property', $bla); + $this->assertInstanceOf(Property::class, $bla); $this->assertEquals('MYPROP', $bla->name); $this->assertEquals('value', (string) $bla); diff --git a/tests/VObject/DocumentTest.php b/tests/VObject/DocumentTest.php index 2665406f6..f2698f65f 100644 --- a/tests/VObject/DocumentTest.php +++ b/tests/VObject/DocumentTest.php @@ -24,11 +24,11 @@ public function testCreateComponent() $event = $vcal->createComponent('VEVENT'); - $this->assertInstanceOf('Sabre\VObject\Component\VEvent', $event); + $this->assertInstanceOf(Component\VEvent::class, $event); $vcal->add($event); $prop = $vcal->createProperty('X-PROP', '1234256', ['X-PARAM' => '3']); - $this->assertInstanceOf('Sabre\VObject\Property', $prop); + $this->assertInstanceOf(Property::class, $prop); $event->add($prop); @@ -46,16 +46,16 @@ public function testCreate() $vcal = new Component\VCalendar([], false); $event = $vcal->create('VEVENT'); - $this->assertInstanceOf('Sabre\VObject\Component\VEvent', $event); + $this->assertInstanceOf(Component\VEvent::class, $event); $prop = $vcal->create('CALSCALE'); - $this->assertInstanceOf('Sabre\VObject\Property\Text', $prop); + $this->assertInstanceOf(Property\Text::class, $prop); } public function testGetClassNameForPropertyValue() { $vcal = new Component\VCalendar([], false); - $this->assertEquals('Sabre\\VObject\\Property\\Text', $vcal->getClassNameForPropertyValue('TEXT')); + $this->assertEquals(Property\Text::class, $vcal->getClassNameForPropertyValue('TEXT')); $this->assertNull($vcal->getClassNameForPropertyValue('FOO')); } @@ -64,7 +64,7 @@ public function testDestroy() $vcal = new Component\VCalendar([], false); $event = $vcal->createComponent('VEVENT'); - $this->assertInstanceOf('Sabre\VObject\Component\VEvent', $event); + $this->assertInstanceOf(Component\VEvent::class, $event); $vcal->add($event); $prop = $vcal->createProperty('X-PROP', '1234256', ['X-PARAM' => '3']); diff --git a/tests/VObject/ElementListTest.php b/tests/VObject/ElementListTest.php index 4b1ce999f..f3bb8f2bb 100644 --- a/tests/VObject/ElementListTest.php +++ b/tests/VObject/ElementListTest.php @@ -22,7 +22,7 @@ public function testIterate() $count = 0; foreach ($elemList as $key => $subcomponent) { ++$count; - $this->assertInstanceOf('Sabre\\VObject\\Component', $subcomponent); + $this->assertInstanceOf(Component::class, $subcomponent); if (3 === $count) { $this->assertEquals(2, $key); diff --git a/tests/VObject/EmptyParameterTest.php b/tests/VObject/EmptyParameterTest.php index 213e69ab8..52fe878e2 100644 --- a/tests/VObject/EmptyParameterTest.php +++ b/tests/VObject/EmptyParameterTest.php @@ -20,7 +20,7 @@ public function testRead() $vcard = Reader::read($input); - $this->assertInstanceOf('Sabre\\VObject\\Component\\VCard', $vcard); + $this->assertInstanceOf(Component\VCard::class, $vcard); $vcard = $vcard->convert(\Sabre\VObject\Document::VCARD30); $vcard = $vcard->serialize(); diff --git a/tests/VObject/ICalendar/AttachParseTest.php b/tests/VObject/ICalendar/AttachParseTest.php index a32a2462e..e6e3d8685 100644 --- a/tests/VObject/ICalendar/AttachParseTest.php +++ b/tests/VObject/ICalendar/AttachParseTest.php @@ -3,6 +3,7 @@ namespace Sabre\VObject\ICalendar; use PHPUnit\Framework\TestCase; +use Sabre\VObject\Property\Uri; use Sabre\VObject\Reader; class AttachParseTest extends TestCase @@ -23,7 +24,7 @@ public function testParseAttach() $vcal = Reader::read($vcal); $prop = $vcal->VEVENT->ATTACH; - $this->assertInstanceOf('Sabre\\VObject\\Property\\URI', $prop); + $this->assertInstanceOf(Uri::class, $prop); $this->assertEquals('ftp://example.com/pub/reports/r-960812.ps', $prop->getValue()); } } diff --git a/tests/VObject/Issue36WorkAroundTest.php b/tests/VObject/Issue36WorkAroundTest.php index 332aace39..1afd3d184 100644 --- a/tests/VObject/Issue36WorkAroundTest.php +++ b/tests/VObject/Issue36WorkAroundTest.php @@ -34,6 +34,6 @@ public function testWorkaround() // If this does not throw an exception, it's all good. $it = new Recur\EventIterator($obj, '1833bd44-188b-405c-9f85-1a12105318aa'); - $this->assertInstanceOf('Sabre\\VObject\\Recur\\EventIterator', $it); + $this->assertInstanceOf(Recur\EventIterator::class, $it); } } diff --git a/tests/VObject/Issue64Test.php b/tests/VObject/Issue64Test.php index 9dc2bb984..2e623baa8 100644 --- a/tests/VObject/Issue64Test.php +++ b/tests/VObject/Issue64Test.php @@ -14,6 +14,6 @@ public function testRead() $converted = Reader::read($vcard); - $this->assertInstanceOf('Sabre\\VObject\\Component\\VCard', $converted); + $this->assertInstanceOf(Component\VCard::class, $converted); } } diff --git a/tests/VObject/Issue96Test.php b/tests/VObject/Issue96Test.php index 22d1fed2f..88803a3e0 100644 --- a/tests/VObject/Issue96Test.php +++ b/tests/VObject/Issue96Test.php @@ -18,7 +18,7 @@ public function testRead() VCF; $vcard = Reader::read($input, Reader::OPTION_FORGIVING); - $this->assertInstanceOf('Sabre\\VObject\\Component\\VCard', $vcard); + $this->assertInstanceOf(Component\VCard::class, $vcard); $this->assertEquals('http://www.example.org', $vcard->URL->getValue()); } } diff --git a/tests/VObject/Parser/QuotedPrintableTest.php b/tests/VObject/Parser/QuotedPrintableTest.php index 7ec16a5a5..7cadb46eb 100644 --- a/tests/VObject/Parser/QuotedPrintableTest.php +++ b/tests/VObject/Parser/QuotedPrintableTest.php @@ -3,6 +3,7 @@ namespace Sabre\VObject\Parser; use PHPUnit\Framework\TestCase; +use Sabre\VObject\Component; use Sabre\VObject\Reader; class QuotedPrintableTest extends TestCase @@ -13,7 +14,7 @@ public function testReadQuotedPrintableSimple() $result = Reader::read($data); - $this->assertInstanceOf('Sabre\\VObject\\Component', $result); + $this->assertInstanceOf(Component::class, $result); $this->assertEquals('VCARD', $result->name); $this->assertEquals(1, count($result->children())); $this->assertEquals('Aachen', $this->getPropertyValue($result->LABEL)); @@ -24,7 +25,7 @@ public function testReadQuotedPrintableNewlineSoft() $data = "BEGIN:VCARD\r\nLABEL;ENCODING=QUOTED-PRINTABLE:Aa=\r\n ch=\r\n en\r\nEND:VCARD"; $result = Reader::read($data); - $this->assertInstanceOf('Sabre\\VObject\\Component', $result); + $this->assertInstanceOf(Component::class, $result); $this->assertEquals('VCARD', $result->name); $this->assertEquals(1, count($result->children())); $this->assertEquals('Aachen', $this->getPropertyValue($result->LABEL)); @@ -35,7 +36,7 @@ public function testReadQuotedPrintableNewlineHard() $data = "BEGIN:VCARD\r\nLABEL;ENCODING=QUOTED-PRINTABLE:Aachen=0D=0A=\r\n Germany\r\nEND:VCARD"; $result = Reader::read($data); - $this->assertInstanceOf('Sabre\\VObject\\Component', $result); + $this->assertInstanceOf(Component::class, $result); $this->assertEquals('VCARD', $result->name); $this->assertEquals(1, count($result->children())); $this->assertEquals("Aachen\r\nGermany", $this->getPropertyValue($result->LABEL)); @@ -46,7 +47,7 @@ public function testReadQuotedPrintableCompatibilityMS() $data = "BEGIN:VCARD\r\nLABEL;ENCODING=QUOTED-PRINTABLE:Aachen=0D=0A=\r\nDeutschland:okay\r\nEND:VCARD"; $result = Reader::read($data, Reader::OPTION_FORGIVING); - $this->assertInstanceOf('Sabre\\VObject\\Component', $result); + $this->assertInstanceOf(Component::class, $result); $this->assertEquals('VCARD', $result->name); $this->assertEquals(1, count($result->children())); $this->assertEquals("Aachen\r\nDeutschland:okay", $this->getPropertyValue($result->LABEL)); diff --git a/tests/VObject/Property/FloatTest.php b/tests/VObject/Property/FloatTest.php index c5237c47b..0ba02470e 100644 --- a/tests/VObject/Property/FloatTest.php +++ b/tests/VObject/Property/FloatTest.php @@ -14,7 +14,7 @@ public function testMimeDir() $result = $mimeDir->parse($input); - $this->assertInstanceOf('Sabre\VObject\Property\FloatValue', $result->{'X-FLOAT'}); + $this->assertInstanceOf(FloatValue::class, $result->{'X-FLOAT'}); $this->assertEquals([ 0.234, diff --git a/tests/VObject/Property/ICalendar/RecurTest.php b/tests/VObject/Property/ICalendar/RecurTest.php index 3567ff1c0..3902a6e13 100644 --- a/tests/VObject/Property/ICalendar/RecurTest.php +++ b/tests/VObject/Property/ICalendar/RecurTest.php @@ -16,7 +16,7 @@ public function testParts() $vcal = new VCalendar(); $recur = $vcal->add('RRULE', 'FREQ=Daily'); - $this->assertInstanceOf('Sabre\VObject\Property\ICalendar\Recur', $recur); + $this->assertInstanceOf(Recur::class, $recur); $this->assertEquals(['FREQ' => 'DAILY'], $recur->getParts()); $recur->setParts(['freq' => 'MONTHLY']); diff --git a/tests/VObject/Property/VCard/LanguageTagTest.php b/tests/VObject/Property/VCard/LanguageTagTest.php index ffb65f434..54106ffe8 100644 --- a/tests/VObject/Property/VCard/LanguageTagTest.php +++ b/tests/VObject/Property/VCard/LanguageTagTest.php @@ -14,7 +14,7 @@ public function testMimeDir() $result = $mimeDir->parse($input); - $this->assertInstanceOf('Sabre\VObject\Property\VCard\LanguageTag', $result->LANG); + $this->assertInstanceOf(LanguageTag::class, $result->LANG); $this->assertEquals('nl', $result->LANG->getValue()); @@ -31,7 +31,7 @@ public function testChangeAndSerialize() $result = $mimeDir->parse($input); - $this->assertInstanceOf('Sabre\VObject\Property\VCard\LanguageTag', $result->LANG); + $this->assertInstanceOf(LanguageTag::class, $result->LANG); // This replicates what the vcard converter does and triggered a bug in // the past. $result->LANG->setValue(['de']); diff --git a/tests/VObject/Property/VCard/PhoneNumberTest.php b/tests/VObject/Property/VCard/PhoneNumberTest.php index 4a54d3333..668bc7e4c 100644 --- a/tests/VObject/Property/VCard/PhoneNumberTest.php +++ b/tests/VObject/Property/VCard/PhoneNumberTest.php @@ -12,7 +12,7 @@ public function testParser() $input = "BEGIN:VCARD\r\nVERSION:3.0\r\nTEL;TYPE=HOME;VALUE=PHONE-NUMBER:+1234\r\nEND:VCARD\r\n"; $vCard = VObject\Reader::read($input); - $this->assertInstanceOf('Sabre\VObject\Property\VCard\PhoneNumber', $vCard->TEL); + $this->assertInstanceOf(PhoneNumber::class, $vCard->TEL); $this->assertEquals('PHONE-NUMBER', $vCard->TEL->getValueType()); $this->assertEquals($input, $vCard->serialize()); } diff --git a/tests/VObject/PropertyTest.php b/tests/VObject/PropertyTest.php index adfb62e64..1f6e07022 100644 --- a/tests/VObject/PropertyTest.php +++ b/tests/VObject/PropertyTest.php @@ -62,7 +62,7 @@ public function testParameterGet() $property = $cal->createProperty('propname', 'propvalue'); $property['paramname'] = 'paramvalue'; - $this->assertInstanceOf('Sabre\\VObject\\Parameter', $property['paramname']); + $this->assertInstanceOf(Parameter::class, $property['paramname']); } public function testParameterNotExists() @@ -81,7 +81,7 @@ public function testParameterMultiple() $property['paramname'] = 'paramvalue'; $property->add('paramname', 'paramvalue'); - $this->assertInstanceOf('Sabre\\VObject\\Parameter', $property['paramname']); + $this->assertInstanceOf(Parameter::class, $property['paramname']); $this->assertEquals(2, count($property['paramname']->getParts())); } @@ -92,7 +92,7 @@ public function testSetParameterAsString() $property['paramname'] = 'paramvalue'; $this->assertEquals(1, count($property->parameters())); - $this->assertInstanceOf('Sabre\\VObject\\Parameter', $property->parameters['PARAMNAME']); + $this->assertInstanceOf(Parameter::class, $property->parameters['PARAMNAME']); $this->assertEquals('PARAMNAME', $property->parameters['PARAMNAME']->name); $this->assertEquals('paramvalue', $property->parameters['PARAMNAME']->getValue()); } diff --git a/tests/VObject/ReaderTest.php b/tests/VObject/ReaderTest.php index f9d08c75a..0992806be 100644 --- a/tests/VObject/ReaderTest.php +++ b/tests/VObject/ReaderTest.php @@ -12,7 +12,7 @@ public function testReadComponent() $result = Reader::read($data); - $this->assertInstanceOf('Sabre\\VObject\\Component', $result); + $this->assertInstanceOf(Component::class, $result); $this->assertEquals('VCALENDAR', $result->name); $this->assertEquals(0, count($result->children())); } @@ -27,7 +27,7 @@ public function testReadStream() $result = Reader::read($stream); - $this->assertInstanceOf('Sabre\\VObject\\Component', $result); + $this->assertInstanceOf(Component::class, $result); $this->assertEquals('VCALENDAR', $result->name); $this->assertEquals(0, count($result->children())); } @@ -38,7 +38,7 @@ public function testReadComponentUnixNewLine() $result = Reader::read($data); - $this->assertInstanceOf('Sabre\\VObject\\Component', $result); + $this->assertInstanceOf(Component::class, $result); $this->assertEquals('VCALENDAR', $result->name); $this->assertEquals(0, count($result->children())); } @@ -49,7 +49,7 @@ public function testReadComponentLineFold() $result = Reader::read($data); - $this->assertInstanceOf('Sabre\\VObject\\Component', $result); + $this->assertInstanceOf(Component::class, $result); $this->assertEquals('VCALENDAR', $result->name); $this->assertEquals(0, count($result->children())); } @@ -76,7 +76,7 @@ public function testReadProperty() $result = Reader::read($data); $result = $result->SUMMARY; - $this->assertInstanceOf('Sabre\\VObject\\Property', $result); + $this->assertInstanceOf(Property::class, $result); $this->assertEquals('SUMMARY', $result->name); $this->assertEquals('propValue', $result->getValue()); } @@ -87,7 +87,7 @@ public function testReadPropertyWithNewLine() $result = Reader::read($data); $result = $result->SUMMARY; - $this->assertInstanceOf('Sabre\\VObject\\Property', $result); + $this->assertInstanceOf(Property::class, $result); $this->assertEquals('SUMMARY', $result->name); $this->assertEquals("Line1\nLine2\nLine3\\Not the 4th line!", $result->getValue()); } @@ -98,7 +98,7 @@ public function testReadMappedProperty() $result = Reader::read($data); $result = $result->DTSTART; - $this->assertInstanceOf('Sabre\\VObject\\Property\\ICalendar\\DateTime', $result); + $this->assertInstanceOf(Property\ICalendar\DateTime::class, $result); $this->assertEquals('DTSTART', $result->name); $this->assertEquals('20110529', $result->getValue()); } @@ -109,7 +109,7 @@ public function testReadMappedPropertyGrouped() $result = Reader::read($data); $result = $result->DTSTART; - $this->assertInstanceOf('Sabre\\VObject\\Property\\ICalendar\\DateTime', $result); + $this->assertInstanceOf(Property\ICalendar\DateTime::class, $result); $this->assertEquals('DTSTART', $result->name); $this->assertEquals('20110529', $result->getValue()); } @@ -131,10 +131,10 @@ public function testReadPropertyInComponent() $result = Reader::read(implode("\r\n", $data)); - $this->assertInstanceOf('Sabre\\VObject\\Component', $result); + $this->assertInstanceOf(Component::class, $result); $this->assertEquals('VCALENDAR', $result->name); $this->assertEquals(1, count($result->children())); - $this->assertInstanceOf('Sabre\\VObject\\Property', $result->children()[0]); + $this->assertInstanceOf(Property::class, $result->children()[0]); $this->assertEquals('PROPNAME', $result->children()[0]->name); $this->assertEquals('propValue', $result->children()[0]->getValue()); } @@ -152,13 +152,13 @@ public function testReadNestedComponent() $result = Reader::read(implode("\r\n", $data)); - $this->assertInstanceOf('Sabre\\VObject\\Component', $result); + $this->assertInstanceOf(Component::class, $result); $this->assertEquals('VCALENDAR', $result->name); $this->assertEquals(1, count($result->children())); - $this->assertInstanceOf('Sabre\\VObject\\Component', $result->children()[0]); + $this->assertInstanceOf(Component::class, $result->children()[0]); $this->assertEquals('VTIMEZONE', $result->children()[0]->name); $this->assertEquals(1, count($result->children()[0]->children())); - $this->assertInstanceOf('Sabre\\VObject\\Component', $result->children()[0]->children()[0]); + $this->assertInstanceOf(Component::class, $result->children()[0]->children()[0]); $this->assertEquals('DAYLIGHT', $result->children()[0]->children()[0]->name); } @@ -169,7 +169,7 @@ public function testReadPropertyParameter() $result = $result->PROPNAME; - $this->assertInstanceOf('Sabre\\VObject\\Property', $result); + $this->assertInstanceOf(Property::class, $result); $this->assertEquals('PROPNAME', $result->name); $this->assertEquals('propValue', $result->getValue()); $this->assertEquals(1, count($result->parameters())); @@ -184,7 +184,7 @@ public function testReadPropertyRepeatingParameter() $result = $result->PROPNAME; - $this->assertInstanceOf('Sabre\\VObject\\Property', $result); + $this->assertInstanceOf(Property::class, $result); $this->assertEquals('PROPNAME', $result->name); $this->assertEquals('propValue', $result->getValue()); $this->assertEquals(1, count($result->parameters())); @@ -200,7 +200,7 @@ public function testReadPropertyRepeatingNamelessGuessedParameter() $result = $result->PROPNAME; - $this->assertInstanceOf('Sabre\\VObject\\Property', $result); + $this->assertInstanceOf(Property::class, $result); $this->assertEquals('PROPNAME', $result->name); $this->assertEquals('propValue', $result->getValue()); $this->assertEquals(1, count($result->parameters())); @@ -216,7 +216,7 @@ public function testReadPropertyNoName() $result = $result->PROPNAME; - $this->assertInstanceOf('Sabre\\VObject\\Property', $result); + $this->assertInstanceOf(Property::class, $result); $this->assertEquals('PROPNAME', $result->name); $this->assertEquals('propValue', $result->getValue()); $this->assertEquals(1, count($result->parameters())); @@ -232,7 +232,7 @@ public function testReadPropertyParameterExtraColon() $result = $result->PROPNAME; - $this->assertInstanceOf('Sabre\\VObject\\Property', $result); + $this->assertInstanceOf(Property::class, $result); $this->assertEquals('PROPNAME', $result->name); $this->assertEquals('propValue:anotherrandomstring', $result->getValue()); $this->assertEquals(1, count($result->parameters())); @@ -247,7 +247,7 @@ public function testReadProperty2Parameters() $result = $result->PROPNAME; - $this->assertInstanceOf('Sabre\\VObject\\Property', $result); + $this->assertInstanceOf(Property::class, $result); $this->assertEquals('PROPNAME', $result->name); $this->assertEquals('propValue', $result->getValue()); $this->assertEquals(2, count($result->parameters())); @@ -264,7 +264,7 @@ public function testReadPropertyParameterQuoted() $result = $result->PROPNAME; - $this->assertInstanceOf('Sabre\\VObject\\Property', $result); + $this->assertInstanceOf(Property::class, $result); $this->assertEquals('PROPNAME', $result->name); $this->assertEquals('propValue', $result->getValue()); $this->assertEquals(1, count($result->parameters())); @@ -279,7 +279,7 @@ public function testReadPropertyParameterNewLines() $result = $result->PROPNAME; - $this->assertInstanceOf('Sabre\\VObject\\Property', $result); + $this->assertInstanceOf(Property::class, $result); $this->assertEquals('PROPNAME', $result->name); $this->assertEquals('propValue', $result->getValue()); @@ -294,7 +294,7 @@ public function testReadPropertyParameterQuotedColon() $result = Reader::read($data); $result = $result->PROPNAME; - $this->assertInstanceOf('Sabre\\VObject\\Property', $result); + $this->assertInstanceOf(Property::class, $result); $this->assertEquals('PROPNAME', $result->name); $this->assertEquals('propValue', $result->getValue()); $this->assertEquals(1, count($result->parameters())); @@ -408,7 +408,7 @@ public function testReadBOM() $data = chr(0xef).chr(0xbb).chr(0xbf)."BEGIN:VCALENDAR\r\nEND:VCALENDAR"; $result = Reader::read($data); - $this->assertInstanceOf('Sabre\\VObject\\Component', $result); + $this->assertInstanceOf(Component::class, $result); $this->assertEquals('VCALENDAR', $result->name); $this->assertEquals(0, count($result->children())); } @@ -425,7 +425,7 @@ public function testReadXMLComponent() $result = Reader::readXML($data); - $this->assertInstanceOf('Sabre\\VObject\\Component', $result); + $this->assertInstanceOf(Component::class, $result); $this->assertEquals('VCALENDAR', $result->name); $this->assertEquals(0, count($result->children())); } @@ -446,7 +446,7 @@ public function testReadXMLStream() $result = Reader::readXML($stream); - $this->assertInstanceOf('Sabre\\VObject\\Component', $result); + $this->assertInstanceOf(Component::class, $result); $this->assertEquals('VCALENDAR', $result->name); $this->assertEquals(0, count($result->children())); } diff --git a/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php b/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php index 3448032e8..bd1eeb9b6 100644 --- a/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php +++ b/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php @@ -4,6 +4,7 @@ use DateTime; use PHPUnit\Framework\TestCase; +use Sabre\VObject\Component\VCalendar; use Sabre\VObject\Reader; class ByMonthInDailyTest extends TestCase @@ -36,7 +37,7 @@ public function testExpand() ICS; $vcal = Reader::read($ics); - $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal); + $this->assertInstanceOf(VCalendar::class, $vcal); $vcal = $vcal->expand(new DateTime('2013-09-28'), new DateTime('2014-09-11')); diff --git a/tests/VObject/Recur/EventIterator/BySetPosHangTest.php b/tests/VObject/Recur/EventIterator/BySetPosHangTest.php index caf6b0dc3..555f2ffd4 100644 --- a/tests/VObject/Recur/EventIterator/BySetPosHangTest.php +++ b/tests/VObject/Recur/EventIterator/BySetPosHangTest.php @@ -4,6 +4,7 @@ use DateTime; use PHPUnit\Framework\TestCase; +use Sabre\VObject\Component\VCalendar; use Sabre\VObject\Reader; class BySetPosHangTest extends TestCase @@ -31,7 +32,7 @@ public function testExpand() ICS; $vcal = Reader::read($ics); - $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal); + $this->assertInstanceOf(VCalendar::class, $vcal); $vcal = $vcal->expand(new DateTime('2015-01-01'), new DateTime('2016-01-01')); diff --git a/tests/VObject/Recur/EventIterator/ExpandFloatingTimesTest.php b/tests/VObject/Recur/EventIterator/ExpandFloatingTimesTest.php index 635b0a8c5..605e10dde 100644 --- a/tests/VObject/Recur/EventIterator/ExpandFloatingTimesTest.php +++ b/tests/VObject/Recur/EventIterator/ExpandFloatingTimesTest.php @@ -5,6 +5,7 @@ use DateTime; use DateTimeZone; use PHPUnit\Framework\TestCase; +use Sabre\VObject\Component\VCalendar; use Sabre\VObject\Reader; class ExpandFloatingTimesTest extends TestCase @@ -26,7 +27,7 @@ public function testExpand() ICS; $vcal = Reader::read($input); - $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal); + $this->assertInstanceOf(VCalendar::class, $vcal); $vcal = $vcal->expand(new DateTime('2015-01-01'), new DateTime('2015-01-31')); $output = <<assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal); + $this->assertInstanceOf(VCalendar::class, $vcal); $vcal = $vcal->expand( new DateTime('2015-01-01'), diff --git a/tests/VObject/Recur/EventIterator/HandleRDateExpandTest.php b/tests/VObject/Recur/EventIterator/HandleRDateExpandTest.php index 698c5fe59..548820191 100644 --- a/tests/VObject/Recur/EventIterator/HandleRDateExpandTest.php +++ b/tests/VObject/Recur/EventIterator/HandleRDateExpandTest.php @@ -6,6 +6,7 @@ use DateTimeImmutable; use DateTimeZone; use PHPUnit\Framework\TestCase; +use Sabre\VObject\Component\VCalendar; use Sabre\VObject\Reader; /** @@ -36,7 +37,7 @@ public function testExpand() ICS; $vcal = Reader::read($input); - $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal); + $this->assertInstanceOf(VCalendar::class, $vcal); $vcal = $vcal->expand(new DateTime('2015-01-01'), new DateTime('2015-12-01')); diff --git a/tests/VObject/Recur/EventIterator/IncorrectExpandTest.php b/tests/VObject/Recur/EventIterator/IncorrectExpandTest.php index afc509972..f9fcda442 100644 --- a/tests/VObject/Recur/EventIterator/IncorrectExpandTest.php +++ b/tests/VObject/Recur/EventIterator/IncorrectExpandTest.php @@ -4,6 +4,7 @@ use DateTime; use PHPUnit\Framework\TestCase; +use Sabre\VObject\Component\VCalendar; use Sabre\VObject\Reader; /** @@ -34,7 +35,7 @@ public function testExpand() ICS; $vcal = Reader::read($input); - $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal); + $this->assertInstanceOf(VCalendar::class, $vcal); $vcal = $vcal->expand(new DateTime('2011-01-01'), new DateTime('2014-01-01')); diff --git a/tests/VObject/Recur/EventIterator/Issue26Test.php b/tests/VObject/Recur/EventIterator/Issue26Test.php index 60d3aa240..3313c3ec6 100644 --- a/tests/VObject/Recur/EventIterator/Issue26Test.php +++ b/tests/VObject/Recur/EventIterator/Issue26Test.php @@ -3,6 +3,7 @@ namespace Sabre\VObject\Recur\EventIterator; use PHPUnit\Framework\TestCase; +use Sabre\VObject\Component\VCalendar; use Sabre\VObject\InvalidDataException; use Sabre\VObject\Reader; use Sabre\VObject\Recur\EventIterator; @@ -25,7 +26,7 @@ public function testExpand() ICS; $vcal = Reader::read($input); - $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal); + $this->assertInstanceOf(VCalendar::class, $vcal); $it = new EventIterator($vcal, 'bae5d57a98'); } diff --git a/tests/VObject/Recur/EventIterator/Issue48Test.php b/tests/VObject/Recur/EventIterator/Issue48Test.php index f08f0ccce..aef592590 100644 --- a/tests/VObject/Recur/EventIterator/Issue48Test.php +++ b/tests/VObject/Recur/EventIterator/Issue48Test.php @@ -5,6 +5,7 @@ use DateTimeImmutable; use DateTimeZone; use PHPUnit\Framework\TestCase; +use Sabre\VObject\Component\VCalendar; use Sabre\VObject\Reader; use Sabre\VObject\Recur\EventIterator; @@ -30,7 +31,7 @@ public function testExpand() ICS; $vcal = Reader::read($input); - $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal); + $this->assertInstanceOf(VCalendar::class, $vcal); $it = new EventIterator($vcal, 'foo'); diff --git a/tests/VObject/Recur/EventIterator/Issue50Test.php b/tests/VObject/Recur/EventIterator/Issue50Test.php index faa04e829..5c476e6f2 100644 --- a/tests/VObject/Recur/EventIterator/Issue50Test.php +++ b/tests/VObject/Recur/EventIterator/Issue50Test.php @@ -5,6 +5,7 @@ use DateTimeImmutable; use DateTimeZone; use PHPUnit\Framework\TestCase; +use Sabre\VObject\Component\VCalendar; use Sabre\VObject\Reader; use Sabre\VObject\Recur\EventIterator; @@ -104,7 +105,7 @@ public function testExpand() ICS; $vcal = Reader::read($input); - $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal); + $this->assertInstanceOf(VCalendar::class, $vcal); $it = new EventIterator($vcal, '1aef0b27-3d92-4581-829a-11999dd36724'); diff --git a/tests/VObject/Recur/EventIterator/MissingOverriddenTest.php b/tests/VObject/Recur/EventIterator/MissingOverriddenTest.php index 5ed47238d..69af8a8a1 100644 --- a/tests/VObject/Recur/EventIterator/MissingOverriddenTest.php +++ b/tests/VObject/Recur/EventIterator/MissingOverriddenTest.php @@ -4,6 +4,7 @@ use DateTime; use PHPUnit\Framework\TestCase; +use Sabre\VObject\Component\VCalendar; use Sabre\VObject\Reader; class MissingOverriddenTest extends TestCase @@ -33,7 +34,7 @@ public function testExpand() ICS; $vcal = Reader::read($input); - $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal); + $this->assertInstanceOf(VCalendar::class, $vcal); $vcal = $vcal->expand(new DateTime('2011-01-01'), new DateTime('2015-01-01')); diff --git a/tests/VObject/Recur/EventIterator/NoInstancesTest.php b/tests/VObject/Recur/EventIterator/NoInstancesTest.php index 092a63c5f..d89afd197 100644 --- a/tests/VObject/Recur/EventIterator/NoInstancesTest.php +++ b/tests/VObject/Recur/EventIterator/NoInstancesTest.php @@ -3,6 +3,7 @@ namespace Sabre\VObject\Recur\EventIterator; use PHPUnit\Framework\TestCase; +use Sabre\VObject\Component\VCalendar; use Sabre\VObject\Reader; use Sabre\VObject\Recur\EventIterator; use Sabre\VObject\Recur\NoInstancesException; @@ -31,7 +32,7 @@ public function testRecurrence() ICS; $vcal = Reader::read($input); - $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal); + $this->assertInstanceOf(VCalendar::class, $vcal); $it = new EventIterator($vcal, 'foo'); } diff --git a/tests/VObject/VCardConverterTest.php b/tests/VObject/VCardConverterTest.php index d7c48e045..ae2b10bd5 100644 --- a/tests/VObject/VCardConverterTest.php +++ b/tests/VObject/VCardConverterTest.php @@ -491,7 +491,7 @@ public function testNoLabel() $vcard = Reader::read($input); - $this->assertInstanceOf('Sabre\\VObject\\Component\\VCard', $vcard); + $this->assertInstanceOf(Component\VCard::class, $vcard); $vcard = $vcard->convert(Document::VCARD40); $vcard = $vcard->serialize(); From 5b2248d965160f93053f3a24704794a13a22a1bb Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 31 Jan 2020 19:50:58 +0100 Subject: [PATCH 027/165] Release 4.3.0 (#497) * Update CHANGELOG.md * Update Version.php --- CHANGELOG.md | 7 +++++++ lib/Version.php | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ddee77f1..5126e04f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ ChangeLog ========= +4.3.0 (2020-01-31) +------------------ + +* Added support for PHP 7.4, dropped support for PHP 7.0 (@phil-davis) +* #487: Added phpstan coverage, updated testsuite for phpunit8 (@phil-davis, @JeroenVanOort) +* #495: refactored maps to use ::class notation (@JeroenVanOort) + 4.2.2 (2020-01-14) ------------------ diff --git a/lib/Version.php b/lib/Version.php index e18fc00ea..883d20289 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.2.3-dev'; + const VERSION = '4.3.0'; } From c0224ca9e2ee3d7326151fc3fb3095d1230708ac Mon Sep 17 00:00:00 2001 From: Jeroen van Oort Date: Fri, 31 Jan 2020 09:39:47 +0100 Subject: [PATCH 028/165] Added phpstan to dev dependencies --- .travis.yml | 3 --- composer.json | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 511119bbb..abe9185c6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,9 +8,6 @@ php: matrix: fast_finish: true -install: - - composer require --dev phpstan/phpstan:^0.12 - before_script: - composer install diff --git a/composer.json b/composer.json index 9e522f8a4..9f1195c26 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,8 @@ }, "require-dev" : { "friendsofphp/php-cs-fixer": "~2.16.1", - "phpunit/phpunit" : "^7 || ^8" + "phpunit/phpunit" : "^7 || ^8", + "phpstan/phpstan": "^0.12" }, "suggest" : { "hoa/bench" : "If you would like to run the benchmark scripts" From 6f6b093e54585c263bb21337078d45f5307aaca8 Mon Sep 17 00:00:00 2001 From: Jeroen van Oort Date: Fri, 31 Jan 2020 09:51:22 +0100 Subject: [PATCH 029/165] Reset bin-dir config --- .gitignore | 7 ------- .travis.yml | 8 ++++---- composer.json | 3 --- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index e9b0ed32f..f12ec08a8 100644 --- a/.gitignore +++ b/.gitignore @@ -8,13 +8,6 @@ tests/.phpunit.result.cache #vim .*.swp -#binaries -bin/phpunit -bin/php-cs-fixer -bin/phpstan -bin/phpstan.phar -bin/hoa - # Development stuff testdata/ .php_cs.cache diff --git a/.travis.yml b/.travis.yml index abe9185c6..8914a4791 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,10 +12,10 @@ before_script: - composer install script: - - ./bin/php-cs-fixer fix lib/ --dry-run --diff - - php ./bin/phpstan.phar analyse -c phpstan.neon lib tests - - ./bin/phpunit --configuration tests/phpunit.xml --coverage-clover=coverage.xml - + - php vendor/bin/php-cs-fixer fix lib/ --dry-run --diff + - php vendor/bin/phpstan analyse -c phpstan.neon lib tests + - php vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-clover=coverage.xml + after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/composer.json b/composer.json index 9f1195c26..d611cd77b 100644 --- a/composer.json +++ b/composer.json @@ -86,8 +86,5 @@ "branch-alias" : { "dev-master" : "4.0.x-dev" } - }, - "config" : { - "bin-dir" : "bin" } } From 874f389396bfbfefd7bd8ac9c3c74d0b5978fb95 Mon Sep 17 00:00:00 2001 From: Jeroen van Oort Date: Fri, 31 Jan 2020 09:55:18 +0100 Subject: [PATCH 030/165] Added convenient development commands --- composer.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/composer.json b/composer.json index d611cd77b..21542bb47 100644 --- a/composer.json +++ b/composer.json @@ -86,5 +86,21 @@ "branch-alias" : { "dev-master" : "4.0.x-dev" } + }, + "scripts": { + "phpstan": [ + "@php vendor/bin/phpstan analyse lib tests" + ], + "php-cs-fixer": [ + "@php vendor/bin/php-cs-fixer fix" + ], + "phpunit": [ + "@php vendor/bin/phpunit --configuration tests/phpunit.xml" + ], + "test": [ + "composer phpstan", + "composer php-cs-fixer", + "composer phpunit" + ] } } From 4b759b210f78cd001f6075d8344ccf86a3239357 Mon Sep 17 00:00:00 2001 From: Jeroen van Oort Date: Fri, 31 Jan 2020 09:57:59 +0100 Subject: [PATCH 031/165] Cleaned up .gitignore These entries should be in the developer's global .gitignore --- .gitignore | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.gitignore b/.gitignore index f12ec08a8..82b7dad3f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,13 +5,5 @@ tests/cov/ tests/temp tests/.phpunit.result.cache -#vim -.*.swp - # Development stuff -testdata/ .php_cs.cache -.idea - -# OS X -.DS_Store From 79bb4f007a3ee240a83623bab3ede34b4bf8f937 Mon Sep 17 00:00:00 2001 From: Jeroen van Oort Date: Sat, 1 Feb 2020 19:28:01 +0100 Subject: [PATCH 032/165] cs-fixer: don't check only the lib folder --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8914a4791..b435459c6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ before_script: - composer install script: - - php vendor/bin/php-cs-fixer fix lib/ --dry-run --diff + - php vendor/bin/php-cs-fixer fix --dry-run --diff - php vendor/bin/phpstan analyse -c phpstan.neon lib tests - php vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-clover=coverage.xml From 5bd174f688330c6868b2a356534e44a5dd024ad8 Mon Sep 17 00:00:00 2001 From: Jeroen van Oort Date: Sat, 1 Feb 2020 19:30:25 +0100 Subject: [PATCH 033/165] Decoupled cs-fixer command from chosen tool --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 21542bb47..555b90b91 100644 --- a/composer.json +++ b/composer.json @@ -91,7 +91,7 @@ "phpstan": [ "@php vendor/bin/phpstan analyse lib tests" ], - "php-cs-fixer": [ + "cs-fixer": [ "@php vendor/bin/php-cs-fixer fix" ], "phpunit": [ @@ -99,7 +99,7 @@ ], "test": [ "composer phpstan", - "composer php-cs-fixer", + "composer cs-fixer", "composer phpunit" ] } From 6b047514d57c468accd5779793efd8cefb5343fe Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Mon, 10 Feb 2020 09:17:43 +0545 Subject: [PATCH 034/165] Standardize CI --- .travis.yml | 20 ++++++++++++++++---- composer.json | 8 ++++---- tests/phpunit.xml | 5 +---- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index b435459c6..07c4824d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,16 +5,28 @@ php: - 7.3 - 7.4 +env: + global: + - MEMCACHED_SERVER=127.0.0.1 + - RUN_PHPSTAN="FALSE" + matrix: + - PREFER_LOWEST="" WITH_COVERAGE="--coverage-clover=coverage.xml" + - PREFER_LOWEST="--prefer-lowest" $WITH_COVERAGE="" + matrix: + include: + - name: 'PHPStan' + php: 7.4 + env: RUN_PHPSTAN="TRUE" fast_finish: true before_script: - - composer install + - composer update $PREFER_LOWEST script: - - php vendor/bin/php-cs-fixer fix --dry-run --diff - - php vendor/bin/phpstan analyse -c phpstan.neon lib tests - - php vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-clover=coverage.xml + - if [ $RUN_PHPSTAN == "FALSE" ]; then php vendor/bin/php-cs-fixer fix --dry-run --diff; fi + - if [ $RUN_PHPSTAN == "FALSE" ]; then php vendor/bin/phpunit --configuration tests/phpunit.xml $WITH_COVERAGE; fi + - if [ $RUN_PHPSTAN == "TRUE" ]; then composer phpstan; fi after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/composer.json b/composer.json index 555b90b91..4890de97b 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,7 @@ }, "require-dev" : { "friendsofphp/php-cs-fixer": "~2.16.1", - "phpunit/phpunit" : "^7 || ^8", + "phpunit/phpunit" : "^7.5 || ^8.5", "phpstan/phpstan": "^0.12" }, "suggest" : { @@ -89,13 +89,13 @@ }, "scripts": { "phpstan": [ - "@php vendor/bin/phpstan analyse lib tests" + "phpstan analyse lib tests" ], "cs-fixer": [ - "@php vendor/bin/php-cs-fixer fix" + "php-cs-fixer fix" ], "phpunit": [ - "@php vendor/bin/phpunit --configuration tests/phpunit.xml" + "phpunit --configuration tests/phpunit.xml" ], "test": [ "composer phpstan", diff --git a/tests/phpunit.xml b/tests/phpunit.xml index c9abae412..c0588d460 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -9,16 +9,13 @@ > - VObject/ + . ../lib/ - - ../lib/Sabre/VObject/includes.php - From 07db2ee3dc4e6d669f7bd8963b26af1cbe66530a Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Mon, 10 Feb 2020 09:35:43 +0545 Subject: [PATCH 035/165] Use phpunit 9 where possible --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4890de97b..d4fa56a31 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,7 @@ }, "require-dev" : { "friendsofphp/php-cs-fixer": "~2.16.1", - "phpunit/phpunit" : "^7.5 || ^8.5", + "phpunit/phpunit" : "^7.5 || ^8.5 || ^9.0", "phpstan/phpstan": "^0.12" }, "suggest" : { From 22067ece2cf924217cd13404ad13becd5f1e7c18 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Mon, 10 Feb 2020 09:46:39 +0545 Subject: [PATCH 036/165] Only upload coverage when it has been collected --- .travis.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 07c4824d0..d1feb60de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,14 +10,16 @@ env: - MEMCACHED_SERVER=127.0.0.1 - RUN_PHPSTAN="FALSE" matrix: - - PREFER_LOWEST="" WITH_COVERAGE="--coverage-clover=coverage.xml" - - PREFER_LOWEST="--prefer-lowest" $WITH_COVERAGE="" + - PREFER_LOWEST="" REPORT_COVERAGE="TRUE" WITH_COVERAGE="--coverage-clover=coverage.xml" + - PREFER_LOWEST="--prefer-lowest" REPORT_COVERAGE="FALSE" WITH_COVERAGE="" matrix: include: - name: 'PHPStan' php: 7.4 - env: RUN_PHPSTAN="TRUE" + env: + - RUN_PHPSTAN="TRUE" + - REPORT_COVERAGE="FALSE" fast_finish: true before_script: @@ -29,7 +31,7 @@ script: - if [ $RUN_PHPSTAN == "TRUE" ]; then composer phpstan; fi after_success: - - bash <(curl -s https://codecov.io/bash) + - if [ $REPORT_COVERAGE == "TRUE" ]; then bash <(curl -s https://codecov.io/bash); fi cache: directories: From d29010a67bc8a5604bf69fecb82f9eb8e48601a3 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sun, 21 Jun 2020 23:22:28 +0545 Subject: [PATCH 037/165] Replace assertRegExp with assertMatchesRegularExpression in unit test --- tests/VObject/CliTest.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/VObject/CliTest.php b/tests/VObject/CliTest.php index 5736f9a01..a4124b76b 100644 --- a/tests/VObject/CliTest.php +++ b/tests/VObject/CliTest.php @@ -483,7 +483,15 @@ public function testRepair() ); rewind($this->cli->stdout); - $this->assertRegExp("/^BEGIN:VCARD\r\nVERSION:2.1\r\nUID:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\r\nEND:VCARD\r\n$/", stream_get_contents($this->cli->stdout)); + $regularExpression = "/^BEGIN:VCARD\r\nVERSION:2.1\r\nUID:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\r\nEND:VCARD\r\n$/"; + $data = stream_get_contents($this->cli->stdout); + // ToDo: when we do not need to run phpunit 7 or 8, remove this 'if' block and just use + // the new assertMatchesRegularExpression that exists since phpunit 9. + if (method_exists($this, 'assertMatchesRegularExpression')) { + $this->assertMatchesRegularExpression($regularExpression, $data); + } else { + $this->assertRegExp($regularExpression, $data); + } } public function testRepairNothing() From 3f25520d13954514091418fc2080660bbc9b5b19 Mon Sep 17 00:00:00 2001 From: Michael Stilkerich Date: Mon, 6 Jul 2020 11:50:17 +0200 Subject: [PATCH 038/165] fix an incomplete phpdoc type annotation --- lib/Component.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Component.php b/lib/Component.php index 58594aec1..da45eb29f 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -431,7 +431,7 @@ protected function getDefaults() * * @param string $name * - * @return Property + * @return Property|null */ public function __get($name) { From b4c67374c54372b7939f6c551d65c2a1851064cf Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Mon, 13 Jul 2020 17:00:36 +0545 Subject: [PATCH 039/165] Release 4.3.1 --- CHANGELOG.md | 8 ++++++++ lib/Version.php | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5126e04f9..69e14154b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ ChangeLog ========= +4.3.1 (2020-07-13) +------------------ + +* #510: Fix an incomplete phpdoc type annotation (@mstilkerich) +* #505: Refactor unit test code for phpunit9 (@phil-davis) +* #500: Standardize CI (@phil-davis) +* #496: CI tooling changes (@JeroenVanOort) + 4.3.0 (2020-01-31) ------------------ diff --git a/lib/Version.php b/lib/Version.php index 883d20289..e5ab9af38 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.3.0'; + const VERSION = '4.3.1'; } From cfe4963f7df48f5422386da19f0d560bb6d45cdd Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sat, 3 Oct 2020 12:46:47 +0545 Subject: [PATCH 040/165] Adjust boolean vars in .travis.yml to prepare for PHP8.0 --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d1feb60de..3592c37af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,8 @@ php: env: global: - MEMCACHED_SERVER=127.0.0.1 + - RUN_PHPCSFIXER="TRUE" + - RUN_PHPUNIT="TRUE" - RUN_PHPSTAN="FALSE" matrix: - PREFER_LOWEST="" REPORT_COVERAGE="TRUE" WITH_COVERAGE="--coverage-clover=coverage.xml" @@ -18,16 +20,19 @@ matrix: - name: 'PHPStan' php: 7.4 env: + - RUN_PHPCSFIXER="FALSE" + - RUN_PHPUNIT="FALSE" - RUN_PHPSTAN="TRUE" - REPORT_COVERAGE="FALSE" fast_finish: true before_script: + - if [ $RUN_PHPCSFIXER == "FALSE" ]; then composer remove --dev friendsofphp/php-cs-fixer; fi - composer update $PREFER_LOWEST script: - - if [ $RUN_PHPSTAN == "FALSE" ]; then php vendor/bin/php-cs-fixer fix --dry-run --diff; fi - - if [ $RUN_PHPSTAN == "FALSE" ]; then php vendor/bin/phpunit --configuration tests/phpunit.xml $WITH_COVERAGE; fi + - if [ $RUN_PHPCSFIXER == "TRUE" ]; then php vendor/bin/php-cs-fixer fix --dry-run --diff; fi + - if [ $RUN_PHPUNIT == "TRUE" ]; then php vendor/bin/phpunit --configuration tests/phpunit.xml $WITH_COVERAGE; fi - if [ $RUN_PHPSTAN == "TRUE" ]; then composer phpstan; fi after_success: From a1a898a26b24a179b6ad2d543b1982cc3a6f2fb0 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sat, 3 Oct 2020 12:50:01 +0545 Subject: [PATCH 041/165] Run unit tests on PHP8 --- .travis.yml | 6 ++++++ composer.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3592c37af..0eff33ec4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,12 @@ env: matrix: include: + - name: 'PHP8' + dist: focal + php: nightly + env: + - RUN_PHPCSFIXER="FALSE" + - REPORT_COVERAGE="FALSE" - name: 'PHPStan' php: 7.4 env: diff --git a/composer.json b/composer.json index d4fa56a31..05524d254 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "homepage" : "http://sabre.io/vobject/", "license" : "BSD-3-Clause", "require" : { - "php" : "^7.1", + "php" : "^7.1 || ^8.0", "ext-mbstring" : "*", "sabre/xml" : "^2.1" }, From ad7ed41bda9516c61161be2fd1c48caeb41eafb1 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sat, 3 Oct 2020 12:59:52 +0545 Subject: [PATCH 042/165] Fixup calendar parameter to Broker parseEvent --- lib/ITip/Broker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ITip/Broker.php b/lib/ITip/Broker.php index c09cdf3be..4e0368e13 100644 --- a/lib/ITip/Broker.php +++ b/lib/ITip/Broker.php @@ -162,7 +162,7 @@ public function processMessage(Message $itipMessage, VCalendar $existingObject = * * @return array */ - public function parseEvent($calendar = null, $userHref, $oldCalendar = null) + public function parseEvent($calendar, $userHref, $oldCalendar = null) { if ($oldCalendar) { if (is_string($oldCalendar)) { From 433b88a238dc9c17d046f6c524f57baa97f66107 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sat, 3 Oct 2020 16:17:38 +0545 Subject: [PATCH 043/165] Release 4.3.2 --- CHANGELOG.md | 5 +++++ lib/Version.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69e14154b..69be5f924 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ ChangeLog ========= +4.3.2 (2020-10-03) +------------------ + +* #513: Added Support for PHP 8.0 (@phil-davis) + 4.3.1 (2020-07-13) ------------------ diff --git a/lib/Version.php b/lib/Version.php index e5ab9af38..cc1ff48b0 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.3.1'; + const VERSION = '4.3.2'; } From 15644b920a31848bd060d18d1ddb527cb64baa93 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sun, 8 Nov 2020 13:16:51 +0545 Subject: [PATCH 044/165] Remove Pacific-New obsolete timezone --- lib/timezonedata/php-bc.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/timezonedata/php-bc.php b/lib/timezonedata/php-bc.php index 83f38f507..3116c6868 100644 --- a/lib/timezonedata/php-bc.php +++ b/lib/timezonedata/php-bc.php @@ -147,7 +147,6 @@ 'US/Michigan', 'US/Mountain', 'US/Pacific', - 'US/Pacific-New', 'US/Samoa', 'WET', ]; From 0552fa28a469870f26278def7d8bde52a58f4240 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sun, 8 Nov 2020 13:47:54 +0545 Subject: [PATCH 045/165] Do composer remove --no-update in Travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0eff33ec4..4f50e97fd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ matrix: fast_finish: true before_script: - - if [ $RUN_PHPCSFIXER == "FALSE" ]; then composer remove --dev friendsofphp/php-cs-fixer; fi + - if [ $RUN_PHPCSFIXER == "FALSE" ]; then composer remove --no-update --dev friendsofphp/php-cs-fixer; fi - composer update $PREFER_LOWEST script: From 6dbc4a3d6f805734c72749ef1c46f6882c9a4d70 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sun, 8 Nov 2020 15:11:23 +0545 Subject: [PATCH 046/165] Use min php-cs-fixer 2.16.7 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 05524d254..f26c0b5ec 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ "sabre/xml" : "^2.1" }, "require-dev" : { - "friendsofphp/php-cs-fixer": "~2.16.1", + "friendsofphp/php-cs-fixer": "~2.16.7", "phpunit/phpunit" : "^7.5 || ^8.5 || ^9.0", "phpstan/phpstan": "^0.12" }, From 8e34e2e6a87932e01e40aa8c51b4af9d48028463 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Mon, 9 Nov 2020 10:07:23 +0545 Subject: [PATCH 047/165] Release 4.3.3 --- CHANGELOG.md | 5 +++++ lib/Version.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69be5f924..7d6b096fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ ChangeLog ========= +4.3.3 (2020-11-09) +------------------ + +* #519: Remove US/Pacific-New obsolete timezone (@phil-davis) + 4.3.2 (2020-10-03) ------------------ diff --git a/lib/Version.php b/lib/Version.php index cc1ff48b0..29ba84f88 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.3.2'; + const VERSION = '4.3.3'; } From 362a4483264606a4b02b9da1ff0c4b4c95533f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane?= Date: Fri, 27 Nov 2020 18:34:22 +0100 Subject: [PATCH 048/165] Add .gitattributes --- .gitattributes | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..f95a950f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +/tests export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.php_cs.dist export-ignore +/.travis.yml export-ignore +/CHANGELOG.md export-ignore +/phpstan.neon export-ignore From 4a92383d63430a46360468ab050c742ab5f9872c Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Thu, 10 Dec 2020 12:46:08 +0545 Subject: [PATCH 049/165] Explicitly select PHP 8.0 in CI --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4f50e97fd..a1a1f66b5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ matrix: include: - name: 'PHP8' dist: focal - php: nightly + php: 8.0 env: - RUN_PHPCSFIXER="FALSE" - REPORT_COVERAGE="FALSE" From 2fd911fec79f8d5c35fa149862bd710ea3a9a1a2 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sun, 13 Dec 2020 13:21:23 +0545 Subject: [PATCH 050/165] Use latest php-cs-fixer 2.17.1 --- bin/bench_freebusygenerator.php | 2 +- bin/bench_manipulatevcard.php | 2 +- bin/generateicalendardata.php | 4 +- bin/mergeduplicates.php | 4 +- bin/rrulebench.php | 2 +- composer.json | 2 +- lib/Cli.php | 7 +- lib/FreeBusyGenerator.php | 1 - lib/Parameter.php | 6 - lib/Parser/MimeDir.php | 2 +- lib/Property/Boolean.php | 3 +- lib/Property/ICalendar/CalAddress.php | 3 +- lib/Property/IntegerValue.php | 3 +- lib/Property/VCard/LanguageTag.php | 3 +- lib/Recur/RRuleIterator.php | 1 - lib/timezonedata/windowszones.php | 2 +- tests/VObject/Component/VAvailabilityTest.php | 14 +-- tests/VObject/DateTimeParserTest.php | 40 +++---- tests/VObject/Parser/XmlTest.php | 112 +++++++++--------- 19 files changed, 98 insertions(+), 115 deletions(-) diff --git a/bin/bench_freebusygenerator.php b/bin/bench_freebusygenerator.php index 1299c14fb..963623d18 100644 --- a/bin/bench_freebusygenerator.php +++ b/bin/bench_freebusygenerator.php @@ -11,7 +11,7 @@ echo "The process will be repeated 100 times to get accurate stats\n"; echo "\n"; echo 'Usage: '.$argv[0]." inputfile.ics\n"; - die(); + exit(); } list(, $inputFile) = $argv; diff --git a/bin/bench_manipulatevcard.php b/bin/bench_manipulatevcard.php index f229091db..df6d9f23d 100644 --- a/bin/bench_manipulatevcard.php +++ b/bin/bench_manipulatevcard.php @@ -10,7 +10,7 @@ echo 'system.'; echo "\n"; echo 'Usage: '.$argv[0]." inputfile.vcf\n"; - die(); + exit(); } list(, $inputFile) = $argv; diff --git a/bin/generateicalendardata.php b/bin/generateicalendardata.php index 62b6107c5..019ed9745 100755 --- a/bin/generateicalendardata.php +++ b/bin/generateicalendardata.php @@ -18,7 +18,7 @@ HI ); - die(); + exit(); } $events = 100; @@ -77,7 +77,7 @@ if ($result) { fwrite(STDERR, "Errors!\n"); fwrite(STDERR, print_r($result, true)); - die(-1); + exit(-1); } fwrite(STDERR, "Serializing this beast\n"); diff --git a/bin/mergeduplicates.php b/bin/mergeduplicates.php index e6cde73dd..31b2c14ab 100755 --- a/bin/mergeduplicates.php +++ b/bin/mergeduplicates.php @@ -19,7 +19,7 @@ if (!class_exists('Sabre\\VObject\\Version')) { fwrite(STDERR, "Composer autoloader could not be loaded.\n"); - die(1); + exit(1); } echo 'sabre/vobject ', Version::VERSION, " duplicate contact merge tool\n"; @@ -27,7 +27,7 @@ if ($argc < 3) { echo "\n"; echo 'Usage: ', $argv[0], " input.vcf output.vcf [debug.log]\n"; - die(1); + exit(1); } $input = fopen($argv[1], 'r'); diff --git a/bin/rrulebench.php b/bin/rrulebench.php index 583da574c..69008002e 100644 --- a/bin/rrulebench.php +++ b/bin/rrulebench.php @@ -9,7 +9,7 @@ echo 'system.'; echo "\n"; echo 'Usage: '.$argv[0]." inputfile.ics startdate enddate\n"; - die(); + exit(); } list(, $inputFile, $startDate, $endDate) = $argv; diff --git a/composer.json b/composer.json index f26c0b5ec..4de13d926 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ "sabre/xml" : "^2.1" }, "require-dev" : { - "friendsofphp/php-cs-fixer": "~2.16.7", + "friendsofphp/php-cs-fixer": "~2.17.1", "phpunit/phpunit" : "^7.5 || ^8.5 || ^9.0", "phpstan/phpstan": "^0.12" }, diff --git a/lib/Cli.php b/lib/Cli.php index f3e419b15..54b938764 100644 --- a/lib/Cli.php +++ b/lib/Cli.php @@ -2,8 +2,7 @@ namespace Sabre\VObject; -use - InvalidArgumentException; +use InvalidArgumentException; /** * This is the CLI interface for sabre-vobject. @@ -137,17 +136,14 @@ public function main(array $argv) // jcard/jcal documents case 'jcard': case 'jcal': - // specific document versions case 'vcard21': case 'vcard30': case 'vcard40': case 'icalendar20': - // specific formats case 'json': case 'mimedir': - // icalendar/vcad case 'icalendar': case 'vcard': @@ -183,7 +179,6 @@ public function main(array $argv) case 'vcard30': case 'vcard40': case 'icalendar20': - $this->inputFormat = 'mimedir'; break; diff --git a/lib/FreeBusyGenerator.php b/lib/FreeBusyGenerator.php index a1c24044c..63f05a151 100644 --- a/lib/FreeBusyGenerator.php +++ b/lib/FreeBusyGenerator.php @@ -362,7 +362,6 @@ protected function calculateBusy(FreeBusyData $fbData, array $objects) foreach ($object->getBaseComponents() as $component) { switch ($component->name) { case 'VEVENT': - $FBTYPE = 'BUSY'; if (isset($component->TRANSP) && ('TRANSPARENT' === strtoupper($component->TRANSP))) { break; diff --git a/lib/Parameter.php b/lib/Parameter.php index e39d320a1..de0c5bfdc 100644 --- a/lib/Parameter.php +++ b/lib/Parameter.php @@ -95,13 +95,11 @@ public static function guessParameterNameByValue($value) case 'WORK': case 'HOME': case 'PREF': - // Delivery Label Type case 'DOM': case 'INTL': case 'POSTAL': case 'PARCEL': - // Telephone types case 'VOICE': case 'FAX': @@ -113,7 +111,6 @@ public static function guessParameterNameByValue($value) case 'CAR': case 'ISDN': case 'VIDEO': - // EMAIL types (lol) case 'AOL': case 'APPLELINK': @@ -127,7 +124,6 @@ public static function guessParameterNameByValue($value) case 'PRODIGY': case 'TLX': case 'X400': - // Photo / Logo format types case 'GIF': case 'CGM': @@ -143,12 +139,10 @@ public static function guessParameterNameByValue($value) case 'MPEG2': case 'AVI': case 'QTIME': - // Sound Digital Audio Type case 'WAVE': case 'PCM': case 'AIFF': - // Key types case 'X509': case 'PGP': diff --git a/lib/Parser/MimeDir.php b/lib/Parser/MimeDir.php index ea5ac0326..385d340d7 100644 --- a/lib/Parser/MimeDir.php +++ b/lib/Parser/MimeDir.php @@ -343,7 +343,7 @@ protected function readProperty($line) ) (?=[;:,]) /xi"; - //echo $regex, "\n"; die(); + //echo $regex, "\n"; exit(); preg_match_all($regex, $line, $matches, PREG_SET_ORDER); $property = [ diff --git a/lib/Property/Boolean.php b/lib/Property/Boolean.php index 9fb2bce35..4bd6ffdfe 100644 --- a/lib/Property/Boolean.php +++ b/lib/Property/Boolean.php @@ -2,8 +2,7 @@ namespace Sabre\VObject\Property; -use - Sabre\VObject\Property; +use Sabre\VObject\Property; /** * Boolean property. diff --git a/lib/Property/ICalendar/CalAddress.php b/lib/Property/ICalendar/CalAddress.php index e89bb31f9..86be66c15 100644 --- a/lib/Property/ICalendar/CalAddress.php +++ b/lib/Property/ICalendar/CalAddress.php @@ -2,8 +2,7 @@ namespace Sabre\VObject\Property\ICalendar; -use - Sabre\VObject\Property\Text; +use Sabre\VObject\Property\Text; /** * CalAddress property. diff --git a/lib/Property/IntegerValue.php b/lib/Property/IntegerValue.php index 6f709bfff..3ae775214 100644 --- a/lib/Property/IntegerValue.php +++ b/lib/Property/IntegerValue.php @@ -2,8 +2,7 @@ namespace Sabre\VObject\Property; -use - Sabre\VObject\Property; +use Sabre\VObject\Property; /** * Integer property. diff --git a/lib/Property/VCard/LanguageTag.php b/lib/Property/VCard/LanguageTag.php index 697273989..318ea0231 100644 --- a/lib/Property/VCard/LanguageTag.php +++ b/lib/Property/VCard/LanguageTag.php @@ -2,8 +2,7 @@ namespace Sabre\VObject\Property\VCard; -use - Sabre\VObject\Property; +use Sabre\VObject\Property; /** * LanguageTag property. diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index 55581e9ac..1d774152a 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -717,7 +717,6 @@ protected function parseRRule($rrule) break; case 'INTERVAL': - case 'COUNT': $val = (int) $value; if ($val < 1) { diff --git a/lib/timezonedata/windowszones.php b/lib/timezonedata/windowszones.php index af3904b12..94455e66c 100644 --- a/lib/timezonedata/windowszones.php +++ b/lib/timezonedata/windowszones.php @@ -10,7 +10,7 @@ * @license http://sabre.io/license/ Modified BSD License */ -return [ +return [ 'AUS Central Standard Time' => 'Australia/Darwin', 'AUS Eastern Standard Time' => 'Australia/Sydney', 'Afghanistan Standard Time' => 'Asia/Kabul', diff --git a/tests/VObject/Component/VAvailabilityTest.php b/tests/VObject/Component/VAvailabilityTest.php index 2fd9c0dde..edd06b02b 100644 --- a/tests/VObject/Component/VAvailabilityTest.php +++ b/tests/VObject/Component/VAvailabilityTest.php @@ -122,7 +122,7 @@ public function testIsInTimeRangeOutside() ); } - public function testRFCxxxSection3_1_availabilityprop_required() + public function testRFCxxxSection3Part1AvailabilitypropRequired() { // UID and DTSTAMP are present. $this->assertIsValid(Reader::read( @@ -177,7 +177,7 @@ public function testRFCxxxSection3_1_availabilityprop_required() )); } - public function testRFCxxxSection3_1_availabilityprop_optional_once() + public function testRFCxxxSection3Part1AvailabilitypropOptionalOnce() { $properties = [ 'BUSYTYPE:BUSY', @@ -205,7 +205,7 @@ public function testRFCxxxSection3_1_availabilityprop_optional_once() } } - public function testRFCxxxSection3_1_availabilityprop_dtend_duration() + public function testRFCxxxSection3Part1AvailabilitypropDtendDuration() { // Only DTEND. $this->assertIsValid(Reader::read($this->template([ @@ -239,7 +239,7 @@ public function testAvailableSubComponent() $this->assertInstanceOf(Available::class, $document->VAVAILABILITY->AVAILABLE); } - public function testRFCxxxSection3_1_availableprop_required() + public function testRFCxxxSection3Part1AvailablepropRequired() { // UID, DTSTAMP and DTSTART are present. $this->assertIsValid(Reader::read( @@ -331,7 +331,7 @@ public function testRFCxxxSection3_1_availableprop_required() )); } - public function testRFCxxxSection3_1_available_dtend_duration() + public function testRFCxxxSection3Part1AvailableDtendDuration() { // Only DTEND. $this->assertIsValid(Reader::read($this->templateAvailable([ @@ -350,7 +350,7 @@ public function testRFCxxxSection3_1_available_dtend_duration() ]))); } - public function testRFCxxxSection3_1_available_optional_once() + public function testRFCxxxSection3Part1AvailableOptionalOnce() { $properties = [ 'CREATED:20111005T135125Z', @@ -373,7 +373,7 @@ public function testRFCxxxSection3_1_available_optional_once() } } - public function testRFCxxxSection3_2() + public function testRFCxxxSection3Part2() { $this->assertEquals( 'BUSY', diff --git a/tests/VObject/DateTimeParserTest.php b/tests/VObject/DateTimeParserTest.php index b20a43217..ede81e321 100644 --- a/tests/VObject/DateTimeParserTest.php +++ b/tests/VObject/DateTimeParserTest.php @@ -408,7 +408,7 @@ public function vcardDates() ]; } - public function testDateAndOrTime_DateWithYearMonthDay() + public function testDateAndOrTimeDateWithYearMonthDay() { $this->assertDateAndOrTimeEqualsTo( '20150128', @@ -420,7 +420,7 @@ public function testDateAndOrTime_DateWithYearMonthDay() ); } - public function testDateAndOrTime_DateWithYearMonth() + public function testDateAndOrTimeDateWithYearMonth() { $this->assertDateAndOrTimeEqualsTo( '2015-01', @@ -431,7 +431,7 @@ public function testDateAndOrTime_DateWithYearMonth() ); } - public function testDateAndOrTime_DateWithMonth() + public function testDateAndOrTimeDateWithMonth() { $this->assertDateAndOrTimeEqualsTo( '--01', @@ -441,7 +441,7 @@ public function testDateAndOrTime_DateWithMonth() ); } - public function testDateAndOrTime_DateWithMonthDay() + public function testDateAndOrTimeDateWithMonthDay() { $this->assertDateAndOrTimeEqualsTo( '--0128', @@ -452,7 +452,7 @@ public function testDateAndOrTime_DateWithMonthDay() ); } - public function testDateAndOrTime_DateWithDay() + public function testDateAndOrTimeDateWithDay() { $this->assertDateAndOrTimeEqualsTo( '---28', @@ -462,7 +462,7 @@ public function testDateAndOrTime_DateWithDay() ); } - public function testDateAndOrTime_TimeWithHour() + public function testDateAndOrTimeTimeWithHour() { $this->assertDateAndOrTimeEqualsTo( '13', @@ -472,7 +472,7 @@ public function testDateAndOrTime_TimeWithHour() ); } - public function testDateAndOrTime_TimeWithHourMinute() + public function testDateAndOrTimeTimeWithHourMinute() { $this->assertDateAndOrTimeEqualsTo( '1353', @@ -483,7 +483,7 @@ public function testDateAndOrTime_TimeWithHourMinute() ); } - public function testDateAndOrTime_TimeWithHourSecond() + public function testDateAndOrTimeTimeWithHourSecond() { $this->assertDateAndOrTimeEqualsTo( '135301', @@ -495,7 +495,7 @@ public function testDateAndOrTime_TimeWithHourSecond() ); } - public function testDateAndOrTime_TimeWithMinute() + public function testDateAndOrTimeTimeWithMinute() { $this->assertDateAndOrTimeEqualsTo( '-53', @@ -505,7 +505,7 @@ public function testDateAndOrTime_TimeWithMinute() ); } - public function testDateAndOrTime_TimeWithMinuteSecond() + public function testDateAndOrTimeTimeWithMinuteSecond() { $this->assertDateAndOrTimeEqualsTo( '-5301', @@ -516,7 +516,7 @@ public function testDateAndOrTime_TimeWithMinuteSecond() ); } - public function testDateAndOrTime_TimeWithSecond() + public function testDateAndOrTimeTimeWithSecond() { $this->assertTrue(true); @@ -526,7 +526,7 @@ public function testDateAndOrTime_TimeWithSecond() */ } - public function testDateAndOrTime_TimeWithSecondZ() + public function testDateAndOrTimeTimeWithSecondZ() { $this->assertDateAndOrTimeEqualsTo( '--01Z', @@ -537,7 +537,7 @@ public function testDateAndOrTime_TimeWithSecondZ() ); } - public function testDateAndOrTime_TimeWithSecondTZ() + public function testDateAndOrTimeTimeWithSecondTZ() { $this->assertDateAndOrTimeEqualsTo( '--01+1234', @@ -548,7 +548,7 @@ public function testDateAndOrTime_TimeWithSecondTZ() ); } - public function testDateAndOrTime_DateTimeWithYearMonthDayHour() + public function testDateAndOrTimeDateTimeWithYearMonthDayHour() { $this->assertDateAndOrTimeEqualsTo( '20150128T13', @@ -561,7 +561,7 @@ public function testDateAndOrTime_DateTimeWithYearMonthDayHour() ); } - public function testDateAndOrTime_DateTimeWithMonthDayHour() + public function testDateAndOrTimeDateTimeWithMonthDayHour() { $this->assertDateAndOrTimeEqualsTo( '--0128T13', @@ -573,7 +573,7 @@ public function testDateAndOrTime_DateTimeWithMonthDayHour() ); } - public function testDateAndOrTime_DateTimeWithDayHour() + public function testDateAndOrTimeDateTimeWithDayHour() { $this->assertDateAndOrTimeEqualsTo( '---28T13', @@ -584,7 +584,7 @@ public function testDateAndOrTime_DateTimeWithDayHour() ); } - public function testDateAndOrTime_DateTimeWithDayHourMinute() + public function testDateAndOrTimeDateTimeWithDayHourMinute() { $this->assertDateAndOrTimeEqualsTo( '---28T1353', @@ -596,7 +596,7 @@ public function testDateAndOrTime_DateTimeWithDayHourMinute() ); } - public function testDateAndOrTime_DateTimeWithDayHourMinuteSecond() + public function testDateAndOrTimeDateTimeWithDayHourMinuteSecond() { $this->assertDateAndOrTimeEqualsTo( '---28T135301', @@ -609,7 +609,7 @@ public function testDateAndOrTime_DateTimeWithDayHourMinuteSecond() ); } - public function testDateAndOrTime_DateTimeWithDayHourZ() + public function testDateAndOrTimeDateTimeWithDayHourZ() { $this->assertDateAndOrTimeEqualsTo( '---28T13Z', @@ -621,7 +621,7 @@ public function testDateAndOrTime_DateTimeWithDayHourZ() ); } - public function testDateAndOrTime_DateTimeWithDayHourTZ() + public function testDateAndOrTimeDateTimeWithDayHourTZ() { $this->assertDateAndOrTimeEqualsTo( '---28T13+1234', diff --git a/tests/VObject/Parser/XmlTest.php b/tests/VObject/Parser/XmlTest.php index e520185ba..46ee30ce2 100644 --- a/tests/VObject/Parser/XmlTest.php +++ b/tests/VObject/Parser/XmlTest.php @@ -262,7 +262,7 @@ public function testRFC6321Example2() /** * iCalendar Stream. */ - public function testRFC6321Section3_2() + public function testRFC6321Section3Part2() { $this->assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( @@ -466,7 +466,7 @@ public function testRFC6321Section3_4_1_3() /** * Values, Binary. */ - public function testRFC6321Section3_6_1() + public function testRFC6321Section3Part6Part1() { $this->assertXMLEqualsToMimeDir( <<assertXMLEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( << with a positive and a non-negative numbers. - $this->testRFC6321Section3_4_1_2(); + $this->testRFC6321Section3Part4Part1Part2(); } /** * Values, Integer. */ - public function testRFC6321Section3_6_8() + public function testRFC6321Section3Part6Part8() { $this->assertXMLEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( @@ -1259,7 +1259,7 @@ public function testRFC6351Section5Group() /** * Extensibility. */ - public function testRFC6351Section5_1_NoNamespace() + public function testRFC6351Section5Part1NoNamespace() { $this->assertXMLEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( <<assertXMLReflexivelyEqualsToMimeDir( << Date: Sun, 13 Dec 2020 17:43:53 +0545 Subject: [PATCH 051/165] Update windowszones timezone data to 2020-12-13 --- bin/fetch_windows_zones.php | 5 ++--- lib/timezonedata/windowszones.php | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/bin/fetch_windows_zones.php b/bin/fetch_windows_zones.php index 9c4e51abd..2361dc309 100755 --- a/bin/fetch_windows_zones.php +++ b/bin/fetch_windows_zones.php @@ -1,13 +1,12 @@ #!/usr/bin/env php 'Pacific/Kiritimati', 'Lord Howe Standard Time' => 'Australia/Lord_Howe', 'Magadan Standard Time' => 'Asia/Magadan', + 'Magallanes Standard Time' => 'America/Punta_Arenas', 'Marquesas Standard Time' => 'Pacific/Marquesas', 'Mauritius Standard Time' => 'Indian/Mauritius', 'Middle East Standard Time' => 'Asia/Beirut', @@ -91,11 +92,13 @@ 'North Asia East Standard Time' => 'Asia/Irkutsk', 'North Asia Standard Time' => 'Asia/Krasnoyarsk', 'North Korea Standard Time' => 'Asia/Pyongyang', + 'Omsk Standard Time' => 'Asia/Omsk', 'Pacific SA Standard Time' => 'America/Santiago', 'Pacific Standard Time' => 'America/Los_Angeles', 'Pacific Standard Time (Mexico)' => 'America/Tijuana', 'Pakistan Standard Time' => 'Asia/Karachi', 'Paraguay Standard Time' => 'America/Asuncion', + 'Qyzylorda Standard Time' => 'Asia/Qyzylorda', 'Romance Standard Time' => 'Europe/Paris', 'Russia Time Zone 10' => 'Asia/Srednekolymsk', 'Russia Time Zone 11' => 'Asia/Kamchatka', @@ -108,9 +111,12 @@ 'Saint Pierre Standard Time' => 'America/Miquelon', 'Sakhalin Standard Time' => 'Asia/Sakhalin', 'Samoa Standard Time' => 'Pacific/Apia', + 'Sao Tome Standard Time' => 'Africa/Sao_Tome', + 'Saratov Standard Time' => 'Europe/Saratov', 'Singapore Standard Time' => 'Asia/Singapore', 'South Africa Standard Time' => 'Africa/Johannesburg', 'Sri Lanka Standard Time' => 'Asia/Colombo', + 'Sudan Standard Time' => 'Africa/Khartoum', 'Syria Standard Time' => 'Asia/Damascus', 'Taipei Standard Time' => 'Asia/Taipei', 'Tasmania Standard Time' => 'Australia/Hobart', @@ -125,6 +131,7 @@ 'US Mountain Standard Time' => 'America/Phoenix', 'UTC' => 'Etc/GMT', 'UTC+12' => 'Etc/GMT-12', + 'UTC+13' => 'Etc/GMT-13', 'UTC-02' => 'Etc/GMT+2', 'UTC-08' => 'Etc/GMT+8', 'UTC-09' => 'Etc/GMT+9', @@ -132,6 +139,7 @@ 'Ulaanbaatar Standard Time' => 'Asia/Ulaanbaatar', 'Venezuela Standard Time' => 'America/Caracas', 'Vladivostok Standard Time' => 'Asia/Vladivostok', + 'Volgograd Standard Time' => 'Europe/Volgograd', 'W. Australia Standard Time' => 'Australia/Perth', 'W. Central Africa Standard Time' => 'Africa/Lagos', 'W. Europe Standard Time' => 'Europe/Berlin', @@ -140,4 +148,5 @@ 'West Bank Standard Time' => 'Asia/Hebron', 'West Pacific Standard Time' => 'Pacific/Port_Moresby', 'Yakutsk Standard Time' => 'Asia/Yakutsk', + 'Yukon Standard Time' => 'America/Whitehorse', ]; From 96d330d0c61c6221120271ee8d008b4292ef7105 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sun, 13 Dec 2020 18:11:33 +0545 Subject: [PATCH 052/165] Fix typos --- CHANGELOG.md | 10 +++++----- lib/Cli.php | 2 +- lib/Component/VCalendar.php | 2 +- lib/Component/VCard.php | 2 +- lib/FreeBusyData.php | 8 ++++---- lib/FreeBusyGenerator.php | 2 +- lib/Parameter.php | 2 +- lib/Property/ICalendar/DateTime.php | 2 +- lib/Recur/EventIterator.php | 2 +- tests/VObject/Component/VCardTest.php | 4 ++-- tests/VObject/EmptyValueIssueTest.php | 4 ++-- tests/VObject/ITip/BrokerAttendeeReplyTest.php | 2 +- tests/VObject/ITip/BrokerProcessReplyTest.php | 2 +- tests/VObject/ReaderTest.php | 2 +- tests/VObject/Recur/EventIterator/MainTest.php | 12 ++++++------ tests/VObject/Recur/RRuleIteratorTest.php | 4 ++-- tests/VObject/TimeZoneUtilTest.php | 4 ++-- 17 files changed, 33 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d6b096fd..28697b5b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,7 @@ ChangeLog ------------------ * #469, #451: fix compat with php 7.4 -* #443: prevent running in indefinte loop +* #443: prevent running in indefinite loop * #449: Preventing creating a component for a root document * #450: Fix parse with option Forgiving with trailing equal * #459: fixed typo in VCalendar which resulting in usage of the wrong TimeZone @@ -125,7 +125,7 @@ ChangeLog * #306: iTip REPLYs to the first instance of a recurring event was not handled correctly. * Slightly better error message during validation of `N` and `ADR` properties. -* #312: Correctly extracing timezone in the iTip broker, even when we don't +* #312: Correctly extracting timezone in the iTip broker, even when we don't have a master event. (@vkomrakov-sugar). * When validating a component's property that must appear once and which could automatically be repaired, make sure we report the change as 'repaired'. @@ -447,7 +447,7 @@ ChangeLog * #114: VTIMEZONE is retained when generating new REQUEST objects. * #114: Support for 'MAILTO:' style email addresses (in uppercase) in the iTip broker. This improves evolution support. -* #115: Using REQUEST-STATUS from REPLY messages and now propegating that into +* #115: Using REQUEST-STATUS from REPLY messages and now propagating that into SCHEDULE-STATUS. @@ -684,7 +684,7 @@ ChangeLog 3.0.0-alpha2 (2013-05-22) ------------------------- -* Fixed: vCard URL properties were referencing a non-existant class. +* Fixed: vCard URL properties were referencing a non-existent class. 3.0.0-alpha1 (2013-05-21) @@ -842,7 +842,7 @@ ChangeLog properties such as N, ADR, ORG and CATEGORIES. * Added: Splitter classes, that can split up large objects (such as exports) into individual objects (thanks @DominikTo and @armin-hackmann). -* Added: VFREEBUSY component, which allows easily checking wether timeslots are +* Added: VFREEBUSY component, which allows easily checking whether timeslots are available. * Added: The Reader class now has a 'FORGIVING' option, which allows it to parse properties with incorrect characters in the name (at this time, it just allows diff --git a/lib/Cli.php b/lib/Cli.php index 54b938764..4984ac9b2 100644 --- a/lib/Cli.php +++ b/lib/Cli.php @@ -206,7 +206,7 @@ public function main(array $argv) } if (!in_array($positional[0], ['validate', 'repair', 'convert', 'color'])) { - throw new InvalidArgumentException('Uknown command: '.$positional[0]); + throw new InvalidArgumentException('Unknown command: '.$positional[0]); } } catch (InvalidArgumentException $e) { $this->showHelp(); diff --git a/lib/Component/VCalendar.php b/lib/Component/VCalendar.php index 40e09a1c0..4db318135 100644 --- a/lib/Component/VCalendar.php +++ b/lib/Component/VCalendar.php @@ -309,7 +309,7 @@ public function expand(DateTimeInterface $start, DateTimeInterface $end, DateTim foreach ($this->children() as $child) { if ($child instanceof Property && 'PRODID' !== $child->name) { - // We explictly want to ignore PRODID, because we want to + // We explicitly want to ignore PRODID, because we want to // overwrite it with our own. $newChildren[] = clone $child; } elseif ($child instanceof Component && 'VTIMEZONE' !== $child->name) { diff --git a/lib/Component/VCard.php b/lib/Component/VCard.php index 51321949f..2430df621 100644 --- a/lib/Component/VCard.php +++ b/lib/Component/VCard.php @@ -373,7 +373,7 @@ public function getValidationRules() /** * Returns a preferred field. * - * VCards can indicate wether a field such as ADR, TEL or EMAIL is + * VCards can indicate whether a field such as ADR, TEL or EMAIL is * preferred by specifying TYPE=PREF (vcard 2.1, 3) or PREF=x (vcard 4, x * being a number between 1 and 100). * diff --git a/lib/FreeBusyData.php b/lib/FreeBusyData.php index d05dfc799..4d9f441ce 100644 --- a/lib/FreeBusyData.php +++ b/lib/FreeBusyData.php @@ -84,7 +84,7 @@ public function add($start, $end, $type) 'type' => $type, ]; - $preceedingItem = $this->data[$insertStartIndex - 1]; + $precedingItem = $this->data[$insertStartIndex - 1]; if ($this->data[$insertStartIndex - 1]['start'] === $start) { // The old item starts at the exact same point as the new item. --$insertStartIndex; @@ -122,11 +122,11 @@ public function add($start, $end, $type) // between. if (-1 === $itemsToDelete) { $itemsToDelete = 0; - if ($newItem['end'] < $preceedingItem['end']) { + if ($newItem['end'] < $precedingItem['end']) { $newItems[] = [ 'start' => $newItem['end'] + 1, - 'end' => $preceedingItem['end'], - 'type' => $preceedingItem['type'], + 'end' => $precedingItem['end'], + 'type' => $precedingItem['type'], ]; } } diff --git a/lib/FreeBusyGenerator.php b/lib/FreeBusyGenerator.php index 63f05a151..81b8126d5 100644 --- a/lib/FreeBusyGenerator.php +++ b/lib/FreeBusyGenerator.php @@ -126,7 +126,7 @@ public function setVAvailability(Document $vcalendar) /** * Sets the input objects. * - * You must either specify a valendar object as a string, or as the parse + * You must either specify a vcalendar object as a string, or as the parse * Component. * It's also possible to specify multiple objects as an array. * diff --git a/lib/Parameter.php b/lib/Parameter.php index de0c5bfdc..72f2ecbcb 100644 --- a/lib/Parameter.php +++ b/lib/Parameter.php @@ -293,7 +293,7 @@ function ($out, $item) { // https://tools.ietf.org/html/rfc6868 // // But we've found that iCal (7.0, shipped with OSX 10.9) - // severaly trips on + characters not being quoted, so we + // severely trips on + characters not being quoted, so we // added + as well. if (!preg_match('#(?: [\n":;\^,\+] )#x', $item)) { return $out.$item; diff --git a/lib/Property/ICalendar/DateTime.php b/lib/Property/ICalendar/DateTime.php index f2dbdeba3..d635e17ae 100644 --- a/lib/Property/ICalendar/DateTime.php +++ b/lib/Property/ICalendar/DateTime.php @@ -184,7 +184,7 @@ public function setDateTime(DateTimeInterface $dt, $isFloating = false) * Sets the property as multiple date-time objects. * * The first value will be used as a reference for the timezones, and all - * the otehr values will be adjusted for that timezone + * the other values will be adjusted for that timezone * * @param DateTimeInterface[] $dt * @param bool isFloating If set to true, timezones will be ignored diff --git a/lib/Recur/EventIterator.php b/lib/Recur/EventIterator.php index fd904b383..e42ca1360 100644 --- a/lib/Recur/EventIterator.php +++ b/lib/Recur/EventIterator.php @@ -83,7 +83,7 @@ class EventIterator implements \Iterator * 2. You can pass an array of VEVENTs (all UIDS should match). * 3. You can pass a single VEVENT component. * - * Only the second method is recomended. The other 1 and 3 will be removed + * Only the second method is recommended. The other 1 and 3 will be removed * at some point in the future. * * The $uid parameter is only required for the first method. diff --git a/tests/VObject/Component/VCardTest.php b/tests/VObject/Component/VCardTest.php index 3124fec84..d8e6110b6 100644 --- a/tests/VObject/Component/VCardTest.php +++ b/tests/VObject/Component/VCardTest.php @@ -135,8 +135,8 @@ public function testGetByType() $vcard = VObject\Reader::read($vcard); $this->assertEquals('1@example.org', $vcard->getByType('EMAIL', 'home')->getValue()); $this->assertEquals('2@example.org', $vcard->getByType('EMAIL', 'work')->getValue()); - $this->assertNull($vcard->getByType('EMAIL', 'non-existant')); - $this->assertNull($vcard->getByType('ADR', 'non-existant')); + $this->assertNull($vcard->getByType('EMAIL', 'non-existent')); + $this->assertNull($vcard->getByType('ADR', 'non-existent')); } public function testPreferredNoPref() diff --git a/tests/VObject/EmptyValueIssueTest.php b/tests/VObject/EmptyValueIssueTest.php index 91a4d84f6..0798d9c4a 100644 --- a/tests/VObject/EmptyValueIssueTest.php +++ b/tests/VObject/EmptyValueIssueTest.php @@ -17,7 +17,7 @@ public function testDecodeValue() BEGIN:VCALENDAR VERSION:2.0 BEGIN:VEVENT -DESCRIPTION:This is a descpription\\nwith a linebreak and a \\; \\, and : +DESCRIPTION:This is a description\\nwith a linebreak and a \\; \\, and : END:VEVENT END:VCALENDAR ICS; @@ -25,6 +25,6 @@ public function testDecodeValue() $vobj = Reader::read($input); // Before this bug was fixed, getValue() would return nothing. - $this->assertEquals("This is a descpription\nwith a linebreak and a ; , and :", $vobj->VEVENT->DESCRIPTION->getValue()); + $this->assertEquals("This is a description\nwith a linebreak and a ; , and :", $vobj->VEVENT->DESCRIPTION->getValue()); } } diff --git a/tests/VObject/ITip/BrokerAttendeeReplyTest.php b/tests/VObject/ITip/BrokerAttendeeReplyTest.php index 71008c6ae..284075adf 100644 --- a/tests/VObject/ITip/BrokerAttendeeReplyTest.php +++ b/tests/VObject/ITip/BrokerAttendeeReplyTest.php @@ -907,7 +907,7 @@ public function testDeclinedCancelledEvent() * Except in this case, there was already an overridden event, and the * overridden event was marked as cancelled by the attendee. * - * For any other attendence status, the new status would have been + * For any other attendance status, the new status would have been * declined, but for this, no message should we sent. */ public function testDontCreateReplyWhenEventWasDeclined() diff --git a/tests/VObject/ITip/BrokerProcessReplyTest.php b/tests/VObject/ITip/BrokerProcessReplyTest.php index 1cb685096..bbfd6c419 100644 --- a/tests/VObject/ITip/BrokerProcessReplyTest.php +++ b/tests/VObject/ITip/BrokerProcessReplyTest.php @@ -373,7 +373,7 @@ public function testReplyNewExceptionTz() $result = $this->process($itip, $old, $expected); } - public function testReplyPartyCrashCreateExcepton() + public function testReplyPartyCrashCreateException() { // IN this test there's a recurring event that has an exception. The // exception is missing the attendee. diff --git a/tests/VObject/ReaderTest.php b/tests/VObject/ReaderTest.php index 0992806be..6f2cbb77d 100644 --- a/tests/VObject/ReaderTest.php +++ b/tests/VObject/ReaderTest.php @@ -336,7 +336,7 @@ public function testReadWithInvalidLine() $data = [ 'BEGIN:VCALENDAR', 'DESCRIPTION:propValue', - "Yes, we've actually seen a file with non-idented property values on multiple lines", + "Yes, we've actually seen a file with non-indented property values on multiple lines", 'END:VCALENDAR', ]; diff --git a/tests/VObject/Recur/EventIterator/MainTest.php b/tests/VObject/Recur/EventIterator/MainTest.php index 1a019a57d..cf317f3ea 100644 --- a/tests/VObject/Recur/EventIterator/MainTest.php +++ b/tests/VObject/Recur/EventIterator/MainTest.php @@ -1172,7 +1172,7 @@ public function testComplexExclusions() /** * @depends testValues */ - public function testOverridenEvent() + public function testOverriddenEvent() { $vcal = new VCalendar(); @@ -1243,7 +1243,7 @@ public function testOverridenEvent() /** * @depends testValues */ - public function testOverridenEvent2() + public function testOverriddenEvent2() { $vcal = new VCalendar(); @@ -1291,7 +1291,7 @@ public function testOverridenEvent2() /** * @depends testValues */ - public function testOverridenEventNoValuesExpected() + public function testOverriddenEventNoValuesExpected() { $vcal = new VCalendar(); $ev1 = $vcal->createComponent('VEVENT'); @@ -1318,12 +1318,12 @@ public function testOverridenEventNoValuesExpected() $summaries = []; // The reported problem was specifically related to the VCALENDAR - // expansion. In this parcitular case, we had to forward to the 28th of + // expansion. In this particular case, we had to forward to the 28th of // january. $it->fastForward(new DateTimeImmutable('2012-01-28 23:00:00')); - // We stop the loop when it hits the 6th of februari. Normally this - // iterator would hit 24, 25 (overriden from 31) and 7 feb but because + // We stop the loop when it hits the 6th of February. Normally this + // iterator would hit 24, 25 (overridden from 31) and 7 feb but because // we 'filter' from the 28th till the 6th, we should get 0 results. while ($it->valid() && $it->getDTStart() < new DateTimeImmutable('2012-02-06 23:00:00')) { $dates[] = $it->getDTStart(); diff --git a/tests/VObject/Recur/RRuleIteratorTest.php b/tests/VObject/Recur/RRuleIteratorTest.php index 0b3e6b8de..8a38ad616 100644 --- a/tests/VObject/Recur/RRuleIteratorTest.php +++ b/tests/VObject/Recur/RRuleIteratorTest.php @@ -265,7 +265,7 @@ public function testMonthly() ); } - public function testMonlthyEndOfMonth() + public function testMonthlyEndOfMonth() { $this->parse( 'FREQ=MONTHLY;INTERVAL=2;COUNT=12', @@ -628,7 +628,7 @@ public function testFifthTuesdayProblem() * This bug came from a Fruux customer. This would result in a never-ending * request. */ - public function testFastFowardTooFar() + public function testFastForwardTooFar() { $this->parse( 'FREQ=WEEKLY;BYDAY=MO;UNTIL=20090704T205959Z;INTERVAL=1', diff --git a/tests/VObject/TimeZoneUtilTest.php b/tests/VObject/TimeZoneUtilTest.php index 619abc19a..580ac9fef 100644 --- a/tests/VObject/TimeZoneUtilTest.php +++ b/tests/VObject/TimeZoneUtilTest.php @@ -8,7 +8,7 @@ class TimeZoneUtilTest extends TestCase { public function setUp(): void { - // clearning the tz cache + // clearing the tz cache TimeZoneUtil::$map = null; } @@ -82,7 +82,7 @@ public function testExchangeMap() $this->assertEquals($ex->getName(), $tz->getName()); } - public function testWetherMicrosoftIsStillInsane() + public function testWhetherMicrosoftIsStillInsane() { $vobj = << Date: Tue, 2 Feb 2021 19:02:41 +0100 Subject: [PATCH 053/165] Reassign modified date in yearly rrule --- lib/Recur/RRuleIterator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index 1d774152a..981260606 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -536,7 +536,7 @@ protected function nextYearly() foreach ($this->byWeekNo as $byWeekNo) { foreach ($dayOffsets as $dayOffset) { $date = clone $this->currentDate; - $date->setISODate($currentYear, $byWeekNo, $dayOffset); + $date = $date->setISODate($currentYear, $byWeekNo, $dayOffset); if ($date > $this->currentDate) { $checkDates[] = $date; From ea97e1384d1e4ad0de0ff3320eb157cf0698e982 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Wed, 3 Feb 2021 08:55:25 +0100 Subject: [PATCH 054/165] Add test --- tests/VObject/Recur/RRuleIteratorTest.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/VObject/Recur/RRuleIteratorTest.php b/tests/VObject/Recur/RRuleIteratorTest.php index 8a38ad616..067991f73 100644 --- a/tests/VObject/Recur/RRuleIteratorTest.php +++ b/tests/VObject/Recur/RRuleIteratorTest.php @@ -591,6 +591,19 @@ public function testYearlyByYearDayInvalid0() ); } + public function testYearlyByDayByWeekNo() + { + $this->parse( + 'FREQ=YEARLY;COUNT=3;BYDAY=MO;BYWEEKNO=13,15,50', + '2021-01-01 00:00:00', + [ + '2021-01-01 00:00:00', + '2021-03-29 00:00:00', + '2021-04-12 00:00:00', + ] + ); + } + public function testFastForward() { // The idea is that we're fast-forwarding too far in the future, so From 67c6ee371abba8cd4222958200e7cb9057b07582 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Wed, 3 Feb 2021 08:59:18 +0100 Subject: [PATCH 055/165] Code style --- tests/VObject/Recur/RRuleIteratorTest.php | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/VObject/Recur/RRuleIteratorTest.php b/tests/VObject/Recur/RRuleIteratorTest.php index 067991f73..ddee980b5 100644 --- a/tests/VObject/Recur/RRuleIteratorTest.php +++ b/tests/VObject/Recur/RRuleIteratorTest.php @@ -591,18 +591,18 @@ public function testYearlyByYearDayInvalid0() ); } - public function testYearlyByDayByWeekNo() - { - $this->parse( - 'FREQ=YEARLY;COUNT=3;BYDAY=MO;BYWEEKNO=13,15,50', - '2021-01-01 00:00:00', - [ - '2021-01-01 00:00:00', - '2021-03-29 00:00:00', - '2021-04-12 00:00:00', - ] - ); - } + public function testYearlyByDayByWeekNo() + { + $this->parse( + 'FREQ=YEARLY;COUNT=3;BYDAY=MO;BYWEEKNO=13,15,50', + '2021-01-01 00:00:00', + [ + '2021-01-01 00:00:00', + '2021-03-29 00:00:00', + '2021-04-12 00:00:00', + ] + ); + } public function testFastForward() { From 7e48c3269ac938bdaaad9288a9174da2d6c3a270 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Wed, 3 Feb 2021 14:28:17 +0100 Subject: [PATCH 056/165] Add test for calendar expand --- tests/VObject/Component/VCalendarTest.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/VObject/Component/VCalendarTest.php b/tests/VObject/Component/VCalendarTest.php index c2f0ce978..ccc8a8eeb 100644 --- a/tests/VObject/Component/VCalendarTest.php +++ b/tests/VObject/Component/VCalendarTest.php @@ -350,6 +350,26 @@ public function testBrokenEventExpand() ); } + public function testEventExpandYearly() + { + $input = 'BEGIN:VCALENDAR +BEGIN:VEVENT +UID:1a093f1012086078fdd3d9df5ff4d7d0 +DTSTART;TZID=UTC:20210203T130000 +DTEND;TZID=UTC:20210203T140000 +RRULE:FREQ=YEARLY;COUNT=7;WKST=MO;BYDAY=MO;BYWEEKNO=13,15,50 +END:VEVENT +END:VCALENDAR +'; + $vcal = VObject\Reader::read($input); + $events = $vcal->expand( + new \DateTime('2021-01-01'), + new \DateTime('2023-01-01') + ); + + $this->assertCount(7, $events->VEVENT); + } + public function testGetDocumentType() { $vcard = new VCalendar(); From b571095958614b6bfbee9bd17a7b337204c031d0 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Wed, 3 Feb 2021 21:51:08 +0545 Subject: [PATCH 057/165] adjust unit test settings for time limits Some tests were testing a bug that caused an infinite loop. Annotate those tests with large, small annotations. Turn on enforceTimeLimit, failOnWarning and failOnRisky so that the annotations are enforced when unit tests are run. Add phpunit/php-invoker to the composer require-dev becaause this is required to make the enforceTimeLimit setting effective. --- composer.json | 1 + tests/VObject/Component/VCalendarTest.php | 7 +++++++ tests/VObject/Recur/RRuleIteratorTest.php | 7 +++++++ tests/phpunit.xml | 3 +++ 4 files changed, 18 insertions(+) diff --git a/composer.json b/composer.json index 4de13d926..b745b1fa6 100644 --- a/composer.json +++ b/composer.json @@ -39,6 +39,7 @@ "require-dev" : { "friendsofphp/php-cs-fixer": "~2.17.1", "phpunit/phpunit" : "^7.5 || ^8.5 || ^9.0", + "phpunit/php-invoker" : "^2.0 || ^3.1", "phpstan/phpstan": "^0.12" }, "suggest" : { diff --git a/tests/VObject/Component/VCalendarTest.php b/tests/VObject/Component/VCalendarTest.php index ccc8a8eeb..d34e12d2b 100644 --- a/tests/VObject/Component/VCalendarTest.php +++ b/tests/VObject/Component/VCalendarTest.php @@ -350,6 +350,13 @@ public function testBrokenEventExpand() ); } + /** + * This test used to induce an infinite loop. + * The "medium" annotation means that phpunit will fail the + * test if it takes longer than a default of 10 seconds. + * + * @medium + */ public function testEventExpandYearly() { $input = 'BEGIN:VCALENDAR diff --git a/tests/VObject/Recur/RRuleIteratorTest.php b/tests/VObject/Recur/RRuleIteratorTest.php index ddee980b5..f778afb4b 100644 --- a/tests/VObject/Recur/RRuleIteratorTest.php +++ b/tests/VObject/Recur/RRuleIteratorTest.php @@ -892,6 +892,13 @@ public function testMinusFifthThursday() ); } + /** + * This test can take some seconds to complete. + * The "large" annotation means phpunit will let it run for + * up to 60 seconds by default. + * + * @large + */ public function testNeverEnding() { $this->parse( diff --git a/tests/phpunit.xml b/tests/phpunit.xml index c0588d460..d40187d2a 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -6,6 +6,9 @@ convertWarningsToExceptions="true" beStrictAboutTestsThatDoNotTestAnything="true" beStrictAboutOutputDuringTests="true" + failOnRisky="true" + failOnWarning="true" + enforceTimeLimit="true" > From 3ee2401e107e46bb305d6e26604413dfb2872151 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Thu, 4 Feb 2021 14:30:56 +0545 Subject: [PATCH 058/165] Release 4.3.4 --- CHANGELOG.md | 6 ++++++ lib/Version.php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28697b5b2..607d07a2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ ChangeLog ========= +4.3.4 (2021-02-04) +------------------ + +* #529: Reassign modified date in yearly rrule (@laoneo) +* #525: Add .gitattributes to reduce package size (@fezfez) + 4.3.3 (2020-11-09) ------------------ diff --git a/lib/Version.php b/lib/Version.php index 29ba84f88..83c82a573 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.3.3'; + const VERSION = '4.3.4'; } From e8b5ea4b1492ff304cbef497c93e1b3ea0b7ee27 Mon Sep 17 00:00:00 2001 From: Jair Cueva Junior Date: Wed, 10 Feb 2021 16:12:39 -0300 Subject: [PATCH 059/165] Make use of until parameter in nextMonthly function --- lib/Recur/RRuleIterator.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index 981260606..2ba2d8369 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -466,7 +466,15 @@ protected function nextMonthly() // This goes to 0 because we need to start counting at the // beginning. - $currentDayOfMonth = 0; + $currentDayOfMonth = 0; + + // For some reason the "until" parameter was not being taken into + // account, that's why the workaround of the 10000 year bug was + // needed at all. + // Let's stop it before the "until" parameter date arrives. + if ($this->currentDate->getTimestamp() >= $this->until->getTimestamp()){ + return; + } // To prevent running this forever (better: until we hit the max date of DateTimeImmutable) we simply // stop at 9999-12-31. Looks like the year 10000 problem is not solved in php .... @@ -475,7 +483,7 @@ protected function nextMonthly() return; } - } + } $this->currentDate = $this->currentDate->setDate( (int) $this->currentDate->format('Y'), From 6c263cea300918245e12d6a2a420b893a0492c42 Mon Sep 17 00:00:00 2001 From: Jair Cueva Junior Date: Wed, 10 Feb 2021 16:27:06 -0300 Subject: [PATCH 060/165] CS FIX --- lib/Recur/RRuleIterator.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index 2ba2d8369..abc0e0a80 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -466,13 +466,12 @@ protected function nextMonthly() // This goes to 0 because we need to start counting at the // beginning. - $currentDayOfMonth = 0; + $currentDayOfMonth = 0; - // For some reason the "until" parameter was not being taken into - // account, that's why the workaround of the 10000 year bug was - // needed at all. - // Let's stop it before the "until" parameter date arrives. - if ($this->currentDate->getTimestamp() >= $this->until->getTimestamp()){ + // For some reason the "until" parameter was not being used here, + // that's why the workaround of the 10000 year bug was needed at all + // let's stop it before the "until" parameter date + if ($this->currentDate->getTimestamp() >= $this->until->getTimestamp()) { return; } @@ -483,7 +482,7 @@ protected function nextMonthly() return; } - } + } $this->currentDate = $this->currentDate->setDate( (int) $this->currentDate->format('Y'), @@ -884,7 +883,7 @@ protected function getMonthlyOccurrences() foreach ($this->byMonthDay as $monthDay) { // Removing values that are out of range for this month if ($monthDay > $startDate->format('t') || - $monthDay < 0 - $startDate->format('t')) { + $monthDay < 0 - $startDate->format('t')) { continue; } if ($monthDay > 0) { @@ -978,3 +977,4 @@ protected function getMonths() return $recurrenceMonths; } } + From 1f2e2e5495172149939ca2ce054c71673c07cbae Mon Sep 17 00:00:00 2001 From: Jair Cueva Junior Date: Wed, 10 Feb 2021 16:35:10 -0300 Subject: [PATCH 061/165] CS FIX --- lib/Recur/RRuleIterator.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index abc0e0a80..9c2aecabe 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -977,4 +977,3 @@ protected function getMonths() return $recurrenceMonths; } } - From 6d3f4ee783ac51f76019f622841e75d808639c01 Mon Sep 17 00:00:00 2001 From: Jair Cueva Junior Date: Wed, 10 Feb 2021 17:18:10 -0300 Subject: [PATCH 062/165] Fix breaking tests --- lib/Recur/RRuleIterator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index 9c2aecabe..0511f0ade 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -471,7 +471,7 @@ protected function nextMonthly() // For some reason the "until" parameter was not being used here, // that's why the workaround of the 10000 year bug was needed at all // let's stop it before the "until" parameter date - if ($this->currentDate->getTimestamp() >= $this->until->getTimestamp()) { + if ($this->until && $this->currentDate->getTimestamp() >= $this->until->getTimestamp()) { return; } From 1bed299d6ac62ac64175eefd8a5ff6b2a64098e9 Mon Sep 17 00:00:00 2001 From: Jair Cueva Junior Date: Thu, 11 Feb 2021 11:43:59 -0300 Subject: [PATCH 063/165] create testMonthlyByDayUntil --- tests/VObject/Recur/RRuleIteratorTest.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/VObject/Recur/RRuleIteratorTest.php b/tests/VObject/Recur/RRuleIteratorTest.php index f778afb4b..caf921833 100644 --- a/tests/VObject/Recur/RRuleIteratorTest.php +++ b/tests/VObject/Recur/RRuleIteratorTest.php @@ -332,6 +332,22 @@ public function testMonthlyByDay() ); } + public function testMonthlyByDayUntil() + { + $this->parse( + 'FREQ=MONTHLY;INTERVAL=1;BYDAY=WE;WKST=WE;UNTIL=20210317T000000Z', + '2021-02-10 00:00:00', + [ + '2021-02-10 00:00:00', + '2021-02-17 00:00:00', + '2021-02-24 00:00:00', + '2021-03-03 00:00:00', + '2021-03-10 00:00:00', + '2021-03-17 00:00:00', + ] + ); + } + public function testMonthlyByDayByMonthDay() { $this->parse( From 1bbae6556e9c10fc4bc916d5081f8cc1caba5a84 Mon Sep 17 00:00:00 2001 From: Jair Cueva Junior Date: Thu, 11 Feb 2021 11:49:17 -0300 Subject: [PATCH 064/165] create testMonthlyByDayUntilWithImpossibleNextOccurrence --- tests/VObject/Recur/RRuleIteratorTest.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/VObject/Recur/RRuleIteratorTest.php b/tests/VObject/Recur/RRuleIteratorTest.php index caf921833..cc40a6f6f 100644 --- a/tests/VObject/Recur/RRuleIteratorTest.php +++ b/tests/VObject/Recur/RRuleIteratorTest.php @@ -348,6 +348,17 @@ public function testMonthlyByDayUntil() ); } + public function testMonthlyByDayUntilWithImpossibleNextOccurrence() + { + $this->parse( + 'FREQ=MONTHLY;INTERVAL=1;BYDAY=2WE;BYMONTHDAY=2;WKST=WE;UNTIL=20210317T000000Z', + '2021-02-10 00:00:00', + [ + '2021-02-10 00:00:00', + ] + ); + } + public function testMonthlyByDayByMonthDay() { $this->parse( From 9708bd9a6ff12f1006fc8e1ce3a00b99cf6160fa Mon Sep 17 00:00:00 2001 From: Michael Stilkerich Date: Sat, 14 Nov 2020 10:00:28 +0100 Subject: [PATCH 065/165] Fix setting properties with group assignment --- lib/Component.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Component.php b/lib/Component.php index da45eb29f..07f6a627f 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -160,9 +160,9 @@ public function remove($item) return; } } - } - throw new \InvalidArgumentException('The item you passed to remove() was not a child of this component'); + throw new \InvalidArgumentException('The item you passed to remove() was not a child of this component'); + } } /** From 930b748faae459de0ce2fb05c2d54438d23cf981 Mon Sep 17 00:00:00 2001 From: Michael Stilkerich Date: Tue, 17 Nov 2020 13:23:14 +0100 Subject: [PATCH 066/165] Unit test for adding properties with group for a VCard --- tests/VObject/ComponentTest.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/VObject/ComponentTest.php b/tests/VObject/ComponentTest.php index f56d55531..ae7420dad 100644 --- a/tests/VObject/ComponentTest.php +++ b/tests/VObject/ComponentTest.php @@ -72,6 +72,23 @@ public function testMagicGetGroups() $this->assertEquals(null, $email3[0]->group); } + public function testAddGroupProperties() + { + $comp = new VCard([ + 'VERSION' => '3.0', + 'item2.X-ABLabel' => "item2-Foo", + ]); + + $comp->{'ITEM1.X-ABLabel'} = "ITEM1-Foo"; + + foreach (['item2', 'ITEM1'] as $group) { + $prop = $comp->{"$group.X-ABLabel"}; + $this->assertInstanceOf(Property::class, $prop); + $this->assertSame("$group-Foo", (string) $prop); + $this->assertSame($group, $prop->group); + } + } + public function testMagicIsset() { $comp = new VCalendar(); From 31c9187e466e67b413e3fbe03b55a9134d88ca79 Mon Sep 17 00:00:00 2001 From: Michael Stilkerich Date: Tue, 17 Nov 2020 13:26:02 +0100 Subject: [PATCH 067/165] Adapt style --- tests/VObject/ComponentTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/VObject/ComponentTest.php b/tests/VObject/ComponentTest.php index ae7420dad..cf3e196dc 100644 --- a/tests/VObject/ComponentTest.php +++ b/tests/VObject/ComponentTest.php @@ -76,10 +76,10 @@ public function testAddGroupProperties() { $comp = new VCard([ 'VERSION' => '3.0', - 'item2.X-ABLabel' => "item2-Foo", + 'item2.X-ABLabel' => 'item2-Foo', ]); - $comp->{'ITEM1.X-ABLabel'} = "ITEM1-Foo"; + $comp->{'ITEM1.X-ABLabel'} = 'ITEM1-Foo'; foreach (['item2', 'ITEM1'] as $group) { $prop = $comp->{"$group.X-ABLabel"}; From 6439b62db5862807c9ef618e19cb4209f109dcba Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Fri, 12 Feb 2021 11:12:49 +0545 Subject: [PATCH 068/165] Release 4.3.5 --- CHANGELOG.md | 6 ++++++ lib/Version.php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 607d07a2e..7605110f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ ChangeLog ========= +4.3.5 (2021-02-12) +------------------ + +* #523: Fix setting properties with group assignment (@mstilkerich) +* #532: Make use of until parameter in nextMonthly function (@jaircuevajunior) + 4.3.4 (2021-02-04) ------------------ diff --git a/lib/Version.php b/lib/Version.php index 83c82a573..63452400f 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.3.4'; + const VERSION = '4.3.5'; } From 502bc802854f411a230ad89d2cc85a7fa3705845 Mon Sep 17 00:00:00 2001 From: Parajuli Kiran Date: Fri, 8 Oct 2021 11:10:08 +0545 Subject: [PATCH 069/165] tests: migrate from Travis to gh-actions --- .github/ci.yml | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .github/ci.yml diff --git a/.github/ci.yml b/.github/ci.yml new file mode 100644 index 000000000..6195adc9d --- /dev/null +++ b/.github/ci.yml @@ -0,0 +1,65 @@ +name: continuous-integration + +on: + push: + branches: + - master + - release/* + pull_request: + +jobs: + unit-testing: + name: PHPUnit (PHP${{ matrix.php-versions }}) + runs-on: ubuntu-latest + + strategy: + fail-faset: false + matrix: + php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1'] + coverage: ['pcov'] + code-analysis: ['no'] + include: + - php-versions: '7.1' + coverage: 'none' + code-analysis: 'yes' + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP, with composer and extensions + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, dom, fileinfo, mysql, redis, opcache + coverage: ${{ matrix.coverage }} + tools: composer + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache composer dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install composer dependencies + run: composer install --no-progress --prefer-dist --optimize-autoloader + + - name: Code Analysis(PHP CS-Fixer) + if: matrix.code-analysis == 'yes' + run: composer cs-fixer + + - name: Code Analysis(PHPStan) + if: matrix.code-analysis == 'yes' + run: composer phpstan + + - name: Test with PHPUnit + run: composer phpunit --coverage-clover clover.xml + + - name: Code Coverage + uses: codecov/codecov-actions@v2 + if: matrix.coverage != 'none' \ No newline at end of file From 6a32c6cb398550e64a4ad38dad8f7eab4a53c683 Mon Sep 17 00:00:00 2001 From: Parajuli Kiran Date: Fri, 8 Oct 2021 11:24:20 +0545 Subject: [PATCH 070/165] Removed travis config --- .github/{ => workflows}/ci.yml | 50 ++++++++++++++++------------------ .travis.yml | 49 --------------------------------- lib/Cli.php | 2 -- 3 files changed, 24 insertions(+), 77 deletions(-) rename .github/{ => workflows}/ci.yml (62%) delete mode 100644 .travis.yml diff --git a/.github/ci.yml b/.github/workflows/ci.yml similarity index 62% rename from .github/ci.yml rename to .github/workflows/ci.yml index 6195adc9d..db8706bf9 100644 --- a/.github/ci.yml +++ b/.github/workflows/ci.yml @@ -1,19 +1,16 @@ name: continuous-integration - on: push: branches: - master - release/* - pull_request: - + pull_request: jobs: unit-testing: - name: PHPUnit (PHP${{ matrix.php-versions }}) + name: PHPUnit (PHP ${{ matrix.php-versions }}) runs-on: ubuntu-latest - strategy: - fail-faset: false + fail-fast: false matrix: php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1'] coverage: ['pcov'] @@ -22,44 +19,45 @@ jobs: - php-versions: '7.1' coverage: 'none' code-analysis: 'yes' - steps: - name: Checkout uses: actions/checkout@v2 - - - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@v2 + + - name: Setup PHP, with Composer and Extensions + uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php with: php-version: ${{ matrix.php-versions }} extensions: mbstring, dom, fileinfo, mysql, redis, opcache coverage: ${{ matrix.coverage }} tools: composer - - - name: Get composer cache directory + + - name: Get Composer Cache Directory id: composer-cache run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache composer dependencies + + - name: Cache Composer Dependencies uses: actions/cache@v2 with: path: ${{ steps.composer-cache.outputs.dir }} + # Use composer.json for key, if composer.lock is not committed. + # key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} restore-keys: ${{ runner.os }}-composer- - - - name: Install composer dependencies + + - name: Install Composer Dependencies run: composer install --no-progress --prefer-dist --optimize-autoloader - - - name: Code Analysis(PHP CS-Fixer) + + - name: Code Analysis (PHP CS-Fixer) if: matrix.code-analysis == 'yes' - run: composer cs-fixer - - - name: Code Analysis(PHPStan) + run: php vendor/bin/php-cs-fixer fix --dry-run --diff + + - name: Code Analysis (PHPStan) if: matrix.code-analysis == 'yes' run: composer phpstan - + - name: Test with PHPUnit - run: composer phpunit --coverage-clover clover.xml - + run: composer phpunit + - name: Code Coverage - uses: codecov/codecov-actions@v2 - if: matrix.coverage != 'none' \ No newline at end of file + uses: codecov/codecov-action@v2 + if: matrix.coverage != 'none' diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a1a1f66b5..000000000 --- a/.travis.yml +++ /dev/null @@ -1,49 +0,0 @@ -language: php -php: - - 7.1 - - 7.2 - - 7.3 - - 7.4 - -env: - global: - - MEMCACHED_SERVER=127.0.0.1 - - RUN_PHPCSFIXER="TRUE" - - RUN_PHPUNIT="TRUE" - - RUN_PHPSTAN="FALSE" - matrix: - - PREFER_LOWEST="" REPORT_COVERAGE="TRUE" WITH_COVERAGE="--coverage-clover=coverage.xml" - - PREFER_LOWEST="--prefer-lowest" REPORT_COVERAGE="FALSE" WITH_COVERAGE="" - -matrix: - include: - - name: 'PHP8' - dist: focal - php: 8.0 - env: - - RUN_PHPCSFIXER="FALSE" - - REPORT_COVERAGE="FALSE" - - name: 'PHPStan' - php: 7.4 - env: - - RUN_PHPCSFIXER="FALSE" - - RUN_PHPUNIT="FALSE" - - RUN_PHPSTAN="TRUE" - - REPORT_COVERAGE="FALSE" - fast_finish: true - -before_script: - - if [ $RUN_PHPCSFIXER == "FALSE" ]; then composer remove --no-update --dev friendsofphp/php-cs-fixer; fi - - composer update $PREFER_LOWEST - -script: - - if [ $RUN_PHPCSFIXER == "TRUE" ]; then php vendor/bin/php-cs-fixer fix --dry-run --diff; fi - - if [ $RUN_PHPUNIT == "TRUE" ]; then php vendor/bin/phpunit --configuration tests/phpunit.xml $WITH_COVERAGE; fi - - if [ $RUN_PHPSTAN == "TRUE" ]; then composer phpstan; fi - -after_success: - - if [ $REPORT_COVERAGE == "TRUE" ]; then bash <(curl -s https://codecov.io/bash); fi - -cache: - directories: - - $HOME/.composer/cache diff --git a/lib/Cli.php b/lib/Cli.php index 4984ac9b2..816e2cb31 100644 --- a/lib/Cli.php +++ b/lib/Cli.php @@ -453,8 +453,6 @@ protected function convert($vObj) * Colorizes a file. * * @param Component $vObj - * - * @return int */ protected function color($vObj) { From a7798a383c77304e33b3aaee82b44aeba5faefb1 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Fri, 8 Oct 2021 13:16:58 +0545 Subject: [PATCH 071/165] Minor edit to README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5030cf276..659e3fa83 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ sabre/vobject The VObject library allows you to easily parse and manipulate [iCalendar](https://tools.ietf.org/html/rfc5545) and [vCard](https://tools.ietf.org/html/rfc6350) objects using PHP. -The goal of the VObject library is to create a very complete library, with an easy to use API. +The goal of the VObject library is to create a very complete library, with an easy-to-use API. Installation From 94e63e75323d0730088554a3efaef3514c99fd75 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Fri, 8 Oct 2021 13:25:59 +0545 Subject: [PATCH 072/165] Run phpunit with coverage in CI --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db8706bf9..076b66694 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: run: composer phpstan - name: Test with PHPUnit - run: composer phpunit + run: vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-clover clover.xml - name: Code Coverage uses: codecov/codecov-action@v2 From bb3bfeb6b621bd08ea64993e04a0a267d15ecb14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Wed, 6 Oct 2021 15:25:01 +0200 Subject: [PATCH 073/165] Fix deprecated usages and return types on PHP 8.1 --- lib/Component.php | 1 + lib/Component/VCard.php | 1 + lib/ElementList.php | 2 ++ lib/Node.php | 7 +++++++ lib/Parameter.php | 2 ++ lib/Parser/MimeDir.php | 2 +- lib/Property.php | 5 +++++ lib/Property/ICalendar/DateTime.php | 1 + 8 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/Component.php b/lib/Component.php index 07f6a627f..f33b628a7 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -339,6 +339,7 @@ function ($a, $b) use ($sortScore, $tmp) { * * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { $components = []; diff --git a/lib/Component/VCard.php b/lib/Component/VCard.php index 2430df621..eac789842 100644 --- a/lib/Component/VCard.php +++ b/lib/Component/VCard.php @@ -445,6 +445,7 @@ protected function getDefaults() * * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { // A vcard does not have sub-components, so we're overriding this diff --git a/lib/ElementList.php b/lib/ElementList.php index 56058cbd5..860512649 100644 --- a/lib/ElementList.php +++ b/lib/ElementList.php @@ -25,6 +25,7 @@ class ElementList extends ArrayIterator * @param int $offset * @param mixed $value */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { throw new LogicException('You can not add new objects to an ElementList'); @@ -37,6 +38,7 @@ public function offsetSet($offset, $value) * * @param int $offset */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { throw new LogicException('You can not remove objects from an ElementList'); diff --git a/lib/Node.php b/lib/Node.php index 4c0c04f72..2041b2ac7 100644 --- a/lib/Node.php +++ b/lib/Node.php @@ -73,6 +73,7 @@ abstract public function serialize(); * * @return array */ + #[\ReturnTypeWillChange] abstract public function jsonSerialize(); /** @@ -102,6 +103,7 @@ public function destroy() * * @return ElementList */ + #[\ReturnTypeWillChange] public function getIterator() { if (!is_null($this->iterator)) { @@ -157,6 +159,7 @@ public function validate($options = 0) * * @return int */ + #[\ReturnTypeWillChange] public function count() { $it = $this->getIterator(); @@ -177,6 +180,7 @@ public function count() * * @return bool */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { $iterator = $this->getIterator(); @@ -193,6 +197,7 @@ public function offsetExists($offset) * * @return mixed */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { $iterator = $this->getIterator(); @@ -208,6 +213,7 @@ public function offsetGet($offset) * @param int $offset * @param mixed $value */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $iterator = $this->getIterator(); @@ -228,6 +234,7 @@ public function offsetSet($offset, $value) * * @param int $offset */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $iterator = $this->getIterator(); diff --git a/lib/Parameter.php b/lib/Parameter.php index 72f2ecbcb..7e4d55743 100644 --- a/lib/Parameter.php +++ b/lib/Parameter.php @@ -321,6 +321,7 @@ function ($out, $item) { * * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->value; @@ -354,6 +355,7 @@ public function __toString() * * @return ElementList */ + #[\ReturnTypeWillChange] public function getIterator() { if (!is_null($this->iterator)) { diff --git a/lib/Parser/MimeDir.php b/lib/Parser/MimeDir.php index 385d340d7..f6ffc37b6 100644 --- a/lib/Parser/MimeDir.php +++ b/lib/Parser/MimeDir.php @@ -439,7 +439,7 @@ protected function readProperty($line) $propObj->add(null, $namelessParameter); } - if ('QUOTED-PRINTABLE' === strtoupper($propObj['ENCODING'])) { + if (isset($propObj['ENCODING']) && 'QUOTED-PRINTABLE' === strtoupper($propObj['ENCODING'])) { $propObj->setQuotedPrintableValue($this->extractQuotedPrintableValue()); } else { $charset = $this->charset; diff --git a/lib/Property.php b/lib/Property.php index f9cf8e38e..6219c9b67 100644 --- a/lib/Property.php +++ b/lib/Property.php @@ -276,6 +276,7 @@ public function setJsonValue(array $value) * * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { $parameters = []; @@ -387,6 +388,7 @@ public function __toString() * * @return bool */ + #[\ReturnTypeWillChange] public function offsetExists($name) { if (is_int($name)) { @@ -413,6 +415,7 @@ public function offsetExists($name) * * @return Node */ + #[\ReturnTypeWillChange] public function offsetGet($name) { if (is_int($name)) { @@ -433,6 +436,7 @@ public function offsetGet($name) * @param string $name * @param mixed $value */ + #[\ReturnTypeWillChange] public function offsetSet($name, $value) { if (is_int($name)) { @@ -453,6 +457,7 @@ public function offsetSet($name, $value) * * @param string $name */ + #[\ReturnTypeWillChange] public function offsetUnset($name) { if (is_int($name)) { diff --git a/lib/Property/ICalendar/DateTime.php b/lib/Property/ICalendar/DateTime.php index d635e17ae..ca71633b9 100644 --- a/lib/Property/ICalendar/DateTime.php +++ b/lib/Property/ICalendar/DateTime.php @@ -300,6 +300,7 @@ function ($item) { * @param string $name * @param mixed $value */ + #[\ReturnTypeWillChange] public function offsetSet($name, $value) { parent::offsetSet($name, $value); From a9dc7a96f3cf5a5727e4263a6d312d27c0ebe790 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Wed, 3 Nov 2021 13:12:48 +0545 Subject: [PATCH 074/165] sync ci.yml to match other repos --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 076b66694..3a019fe77 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: - name: Checkout uses: actions/checkout@v2 - - name: Setup PHP, with Composer and Extensions + - name: Setup PHP, with composer and extensions uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php with: php-version: ${{ matrix.php-versions }} @@ -31,11 +31,11 @@ jobs: coverage: ${{ matrix.coverage }} tools: composer - - name: Get Composer Cache Directory + - name: Get composer cache directory id: composer-cache run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Cache Composer Dependencies + - name: Cache composer dependencies uses: actions/cache@v2 with: path: ${{ steps.composer-cache.outputs.dir }} @@ -44,7 +44,7 @@ jobs: key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} restore-keys: ${{ runner.os }}-composer- - - name: Install Composer Dependencies + - name: Install composer dependencies run: composer install --no-progress --prefer-dist --optimize-autoloader - name: Code Analysis (PHP CS-Fixer) @@ -55,7 +55,7 @@ jobs: if: matrix.code-analysis == 'yes' run: composer phpstan - - name: Test with PHPUnit + - name: Test with phpunit run: vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-clover clover.xml - name: Code Coverage From 8de260f324ff1b928e647160b15041f51ed8a7ea Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Thu, 4 Nov 2021 12:05:13 +0545 Subject: [PATCH 075/165] Changes that should have happened for 4.3.6 --- CHANGELOG.md | 5 +++++ lib/Version.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7605110f4..f6f087b4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ ChangeLog ========= +4.3.6 (2021-11-04) +------------------ + +* #544 Fix deprecated usages and return types on PHP 8.1 (@cedric-anne) + 4.3.5 (2021-02-12) ------------------ diff --git a/lib/Version.php b/lib/Version.php index 63452400f..d338adeaf 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.3.5'; + const VERSION = '4.3.6'; } From a3b1d590fd3629d6cf05d3fce83cbd4ee3d16db0 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Thu, 4 Nov 2021 12:51:40 +0545 Subject: [PATCH 076/165] changelog and VERSION bump for 4.3.7 --- CHANGELOG.md | 5 +++++ lib/Version.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6f087b4a..b7b735539 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ ChangeLog ========= +4.3.7 (2021-11-04) +------------------ + +* #551 version bump that was missed in 4.3.6 (@phil-davis) + 4.3.6 (2021-11-04) ------------------ diff --git a/lib/Version.php b/lib/Version.php index d338adeaf..3b9cc5e23 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.3.6'; + const VERSION = '4.3.7'; } From bfe37ff5bf2e754e57f43a8f10ab15c6703ac5ef Mon Sep 17 00:00:00 2001 From: Holger Floerke Date: Wed, 4 Aug 2021 12:05:53 +0200 Subject: [PATCH 077/165] EventIterator returns wrong endTime (#534) --- lib/Recur/EventIterator.php | 8 ++- .../EventIterator/OverrideDurationTest.php | 52 +++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 tests/VObject/Recur/EventIterator/OverrideDurationTest.php diff --git a/lib/Recur/EventIterator.php b/lib/Recur/EventIterator.php index e42ca1360..310bebe41 100644 --- a/lib/Recur/EventIterator.php +++ b/lib/Recur/EventIterator.php @@ -229,9 +229,13 @@ public function getDtEnd() if (!$this->valid()) { return; } - $end = clone $this->currentDate; + if ($this->currentOverriddenEvent && $this->currentOverriddenEvent->DTEND) { + return $this->currentOverriddenEvent->DTEND->getDateTime($this->timeZone); + } else { + $end = clone $this->currentDate; - return $end->modify('+'.$this->eventDuration.' seconds'); + return $end->modify('+'.$this->eventDuration.' seconds'); + } } /** diff --git a/tests/VObject/Recur/EventIterator/OverrideDurationTest.php b/tests/VObject/Recur/EventIterator/OverrideDurationTest.php new file mode 100644 index 000000000..f25ef13d9 --- /dev/null +++ b/tests/VObject/Recur/EventIterator/OverrideDurationTest.php @@ -0,0 +1,52 @@ +getComponents()); + + $this->assertEquals($eventIterator->current()->format('Y-m-d H:i:s'), '2021-05-17 09:00:00', 'recur event start time'); + $this->assertEquals($eventIterator->getDtEnd()->format('Y-m-d H:i:s'), '2021-05-17 10:00:00', 'recur event end time'); + + $eventIterator->next(); + $this->assertEquals($eventIterator->current()->format('Y-m-d H:i:s'), '2021-05-18 09:00:00', 'recur event start time'); + $this->assertEquals($eventIterator->getDtEnd()->format('Y-m-d H:i:s'), '2021-05-18 10:00:00', 'recur event end time'); + + $eventIterator->next(); + $this->assertEquals($eventIterator->current()->format('Y-m-d H:i:s'), '2021-05-19 09:00:00', 'overridden event start time'); + $this->assertEquals($eventIterator->getDtEnd()->format('Y-m-d H:i:s'), '2021-05-19 12:00:00', 'overridden event end time'); + + $eventIterator->next(); + $this->assertEquals($eventIterator->current()->format('Y-m-d H:i:s'), '2021-05-20 09:00:00', 'recur event start time'); + $this->assertEquals($eventIterator->getDtEnd()->format('Y-m-d H:i:s'), '2021-05-20 10:00:00', 'recur event end time'); + } +} From 5f81c0f189dd45639405d3c5d001e73a000258a5 Mon Sep 17 00:00:00 2001 From: Holger Floerke Date: Fri, 10 Sep 2021 08:02:20 +0200 Subject: [PATCH 078/165] Reordering of the attendees should not be a signitifcant change (sabre-io#540) --- lib/ITip/Broker.php | 6 ++- .../ITip/BrokerSignificantChangesTest.php | 42 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/lib/ITip/Broker.php b/lib/ITip/Broker.php index 4e0368e13..1c599b997 100644 --- a/lib/ITip/Broker.php +++ b/lib/ITip/Broker.php @@ -547,9 +547,13 @@ protected function parseEventForOrganizer(VCalendar $calendar, array $eventInfo, // properties changed in the event, or simply if there's a // difference in instances that the attendee is invited to. + $oldAttendeeInstances = array_keys($attendee['oldInstances']); + $newAttendeeInstances = array_keys($attendee['newInstances']); + $message->significantChange = 'REQUEST' === $attendee['forceSend'] || - array_keys($attendee['oldInstances']) != array_keys($attendee['newInstances']) || + count($oldAttendeeInstances) != count($newAttendeeInstances) || + count(array_diff($oldAttendeeInstances, $newAttendeeInstances)) > 0 || $oldEventInfo['significantChangeHash'] !== $eventInfo['significantChangeHash']; foreach ($attendee['newInstances'] as $instanceId => $instanceInfo) { diff --git a/tests/VObject/ITip/BrokerSignificantChangesTest.php b/tests/VObject/ITip/BrokerSignificantChangesTest.php index a225cb98c..ef4865127 100644 --- a/tests/VObject/ITip/BrokerSignificantChangesTest.php +++ b/tests/VObject/ITip/BrokerSignificantChangesTest.php @@ -105,4 +105,46 @@ public function testSignificantChangesRRuleOrderNoChange() $this->parse($old, $new, $expected, 'mailto:martin@fruux.com'); } + + /** + * Check significant changes detection (no change). + * Reordering of the attendees should not be a signitifcant change (#540) + * https://github.com/sabre-io/vobject/issues/540. + */ + public function testSignificantChangesAttendeesOrderNoChange() + { + $old = << false]; + $expected[] = ['significantChange' => false]; + + $this->parse($old, $new, $expected, 'mailto:martin@fruux.com'); + } } From 8ee715a520c573b7d9d4151eed0d4de5cfd2f69a Mon Sep 17 00:00:00 2001 From: Holger Floerke Date: Fri, 10 Sep 2021 13:33:24 +0200 Subject: [PATCH 079/165] Reordering of vevent should not be a significant change (#542) --- lib/ITip/Broker.php | 18 +++-- .../ITip/BrokerSignificantChangesTest.php | 68 ++++++++++++++++++- 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/lib/ITip/Broker.php b/lib/ITip/Broker.php index 1c599b997..b66a59f54 100644 --- a/lib/ITip/Broker.php +++ b/lib/ITip/Broker.php @@ -820,7 +820,10 @@ protected function parseEventInfo(VCalendar $calendar = null) $instances = []; $exdate = []; + $significantChangeEventProperties = []; + foreach ($calendar->VEVENT as $vevent) { + $eventSignificantChangeHash = ''; $rrule = []; if (is_null($uid)) { @@ -934,19 +937,26 @@ protected function parseEventInfo(VCalendar $calendar = null) if (isset($vevent->$prop)) { $propertyValues = $vevent->select($prop); - $significantChangeHash .= $prop.':'; + $eventSignificantChangeHash .= $prop.':'; if ('EXDATE' === $prop) { - $significantChangeHash .= implode(',', $exdate).';'; + $eventSignificantChangeHash .= implode(',', $exdate).';'; } elseif ('RRULE' === $prop) { - $significantChangeHash .= implode(',', $rrule).';'; + $eventSignificantChangeHash .= implode(',', $rrule).';'; } else { foreach ($propertyValues as $val) { - $significantChangeHash .= $val->getValue().';'; + $eventSignificantChangeHash .= $val->getValue().';'; } } } } + $significantChangeEventProperties[] = $eventSignificantChangeHash; + } + + asort($significantChangeEventProperties); + + foreach ($significantChangeEventProperties as $eventSignificantChangeHash) { + $significantChangeHash .= $eventSignificantChangeHash; } $significantChangeHash = md5($significantChangeHash); diff --git a/tests/VObject/ITip/BrokerSignificantChangesTest.php b/tests/VObject/ITip/BrokerSignificantChangesTest.php index ef4865127..a20d55025 100644 --- a/tests/VObject/ITip/BrokerSignificantChangesTest.php +++ b/tests/VObject/ITip/BrokerSignificantChangesTest.php @@ -108,7 +108,7 @@ public function testSignificantChangesRRuleOrderNoChange() /** * Check significant changes detection (no change). - * Reordering of the attendees should not be a signitifcant change (#540) + * Reordering of the attendees should not be a significant change (#540) * https://github.com/sabre-io/vobject/issues/540. */ public function testSignificantChangesAttendeesOrderNoChange() @@ -147,4 +147,70 @@ public function testSignificantChangesAttendeesOrderNoChange() $this->parse($old, $new, $expected, 'mailto:martin@fruux.com'); } + + /** + * Check significant changes detection (no change). + * Reordering of vevent in a recurring event with exceptions should + * not be a significant change + * https://github.com/sabre-io/vobject/issues/542. + */ + public function testSignificantChangesVeventOrderNoChange() + { + $vevent1 = << false]]; + + $this->parse($old, $new, $expected, 'mailto:martin@fruux.com'); + } } From 7cb4ddd934c815f0404ffcc5e7fddf8c4c20d34b Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sun, 14 Nov 2021 20:19:16 +0545 Subject: [PATCH 080/165] Prepare release 4.3.8 --- CHANGELOG.md | 7 +++++++ lib/Version.php | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7b735539..6621decbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ ChangeLog ========= +4.3.8 (2021-11-14) +------------------ + +* #538 fix EventIterator returns wrong end endTime (@floerke) +* #541 Reordering of the attendees is not a significant change (@floerke) +* #543 Reordering of vevent is not a significant change (@floerke) + 4.3.7 (2021-11-04) ------------------ diff --git a/lib/Version.php b/lib/Version.php index 3b9cc5e23..fce863ecb 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.3.7'; + const VERSION = '4.3.8'; } From 87c8def18d7f9a7d88ceff67e63a2ed006e082cc Mon Sep 17 00:00:00 2001 From: Andreas Heigl Date: Fri, 29 Oct 2021 11:50:30 +0200 Subject: [PATCH 081/165] Allow easier extension of the timezone guessing This will ease customization of timezone-guessing as it is now gets easier to extend that process with own implementations (as long as they implement the appropriate interface) This is espechially necessary when wanting to actually guess a timezone via the rules defined in the VTIMEZONE-entry (which is currently not done) --- lib/TimeZoneUtil.php | 261 +++++++++--------- lib/TimezoneGuesser/FindFromOffset.php | 31 +++ .../FindFromTimezoneIdentifier.php | 71 +++++ lib/TimezoneGuesser/FindFromTimezoneMap.php | 78 ++++++ lib/TimezoneGuesser/GuessFromLicEntry.php | 33 +++ lib/TimezoneGuesser/GuessFromMsTzId.php | 119 ++++++++ lib/TimezoneGuesser/TimezoneFinder.php | 10 + lib/TimezoneGuesser/TimezoneGuesser.php | 11 + tests/VObject/TimeZoneUtilTest.php | 14 +- 9 files changed, 496 insertions(+), 132 deletions(-) create mode 100644 lib/TimezoneGuesser/FindFromOffset.php create mode 100644 lib/TimezoneGuesser/FindFromTimezoneIdentifier.php create mode 100644 lib/TimezoneGuesser/FindFromTimezoneMap.php create mode 100644 lib/TimezoneGuesser/GuessFromLicEntry.php create mode 100644 lib/TimezoneGuesser/GuessFromMsTzId.php create mode 100644 lib/TimezoneGuesser/TimezoneFinder.php create mode 100644 lib/TimezoneGuesser/TimezoneGuesser.php diff --git a/lib/TimeZoneUtil.php b/lib/TimeZoneUtil.php index 2c407fee6..6422c0930 100644 --- a/lib/TimeZoneUtil.php +++ b/lib/TimeZoneUtil.php @@ -2,6 +2,16 @@ namespace Sabre\VObject; +use DateTimeZone; +use InvalidArgumentException; +use Sabre\VObject\TimezoneGuesser\FindFromOffset; +use Sabre\VObject\TimezoneGuesser\FindFromTimezoneIdentifier; +use Sabre\VObject\TimezoneGuesser\FindFromTimezoneMap; +use Sabre\VObject\TimezoneGuesser\GuessFromLicEntry; +use Sabre\VObject\TimezoneGuesser\GuessFromMsTzId; +use Sabre\VObject\TimezoneGuesser\TimezoneFinder; +use Sabre\VObject\TimezoneGuesser\TimezoneGuesser; + /** * Time zone name translation. * @@ -14,17 +24,136 @@ */ class TimeZoneUtil { + /** @var self */ + private static $instance = null; + + /** @var TimezoneGuesser[] */ + private $timezoneGuessers = []; + + /** @var TimezoneFinder[] */ + private $timezoneFinders = []; + + private function __construct() + { + $this->addGuesser('lic', new GuessFromLicEntry()); + $this->addGuesser('msTzId', new GuessFromMsTzId()); + $this->addFinder('tzid', new FindFromTimezoneIdentifier()); + $this->addFinder('tzmap', new FindFromTimezoneMap()); + $this->addFinder('offset', new FindFromOffset()); + } + + private static function getInstance(): self + { + if (null === self::$instance) { + self::$instance = new self(); + } + + return self::$instance; + } + + private function addGuesser(string $key, TimezoneGuesser $guesser): void + { + $this->timezoneGuessers[$key] = $guesser; + } + + private function addFinder(string $key, TimezoneFinder $finder): void + { + $this->timezoneFinders[$key] = $finder; + } + + /** + * This method will try to find out the correct timezone for an iCalendar + * date-time value. + * + * You must pass the contents of the TZID parameter, as well as the full + * calendar. + * + * If the lookup fails, this method will return the default PHP timezone + * (as configured using date_default_timezone_set, or the date.timezone ini + * setting). + * + * Alternatively, if $failIfUncertain is set to true, it will throw an + * exception if we cannot accurately determine the timezone. + */ + private function findTimeZone(string $tzid, Component $vcalendar = null, bool $failIfUncertain = false): DateTimeZone + { + foreach ($this->timezoneFinders as $timezoneFinder) { + $timezone = $timezoneFinder->find($tzid, $failIfUncertain); + if (!$timezone instanceof DateTimeZone) { + continue; + } + + return $timezone; + } + + if ($vcalendar) { + // If that didn't work, we will scan VTIMEZONE objects + foreach ($vcalendar->select('VTIMEZONE') as $vtimezone) { + if ((string) $vtimezone->TZID === $tzid) { + foreach ($this->timezoneGuessers as $timezoneGuesser) { + $timezone = $timezoneGuesser->guess($vtimezone, $failIfUncertain); + if (!$timezone instanceof DateTimeZone) { + continue; + } + + return $timezone; + } + } + } + } + + if ($failIfUncertain) { + throw new InvalidArgumentException('We were unable to determine the correct PHP timezone for tzid: '.$tzid); + } + + // If we got all the way here, we default to whatever has been set as the PHP default timezone. + return new DateTimeZone(date_default_timezone_get()); + } + + public static function addTimezoneGuesser(string $key, TimezoneGuesser $guesser): void + { + self::getInstance()->addGuesser($key, $guesser); + } + + public static function addTimezoneFinder(string $key, TimezoneFinder $finder): void + { + self::getInstance()->addFinder($key, $finder); + } + + /** + * @param string $tzid + * @param false $failIfUncertain + * + * @return DateTimeZone + */ + public static function getTimeZone($tzid, Component $vcalendar = null, $failIfUncertain = false) + { + return self::getInstance()->findTimeZone($tzid, $vcalendar, $failIfUncertain); + } + + public static function clean(): void + { + self::$instance = null; + } + + // Keeping things for backwards compatibility + /** + * @var array|null + * + * @deprecated + */ public static $map = null; /** * List of microsoft exchange timezone ids. * * Source: http://msdn.microsoft.com/en-us/library/aa563018(loband).aspx + * + * @deprecated */ public static $microsoftExchangeMap = [ 0 => 'UTC', 31 => 'Africa/Casablanca', - // Insanely, id #2 is used for both Europe/Lisbon, and Europe/Sarajevo. // I'm not even kidding.. We handle this special case in the // getTimeZone method. @@ -103,135 +232,11 @@ class TimeZoneUtil 39 => 'Pacific/Kwajalein', ]; - /** - * This method will try to find out the correct timezone for an iCalendar - * date-time value. - * - * You must pass the contents of the TZID parameter, as well as the full - * calendar. - * - * If the lookup fails, this method will return the default PHP timezone - * (as configured using date_default_timezone_set, or the date.timezone ini - * setting). - * - * Alternatively, if $failIfUncertain is set to true, it will throw an - * exception if we cannot accurately determine the timezone. - * - * @param string $tzid - * @param Sabre\VObject\Component $vcalendar - * - * @return \DateTimeZone - */ - public static function getTimeZone($tzid, Component $vcalendar = null, $failIfUncertain = false) - { - // First we will just see if the tzid is a support timezone identifier. - // - // The only exception is if the timezone starts with (. This is to - // handle cases where certain microsoft products generate timezone - // identifiers that for instance look like: - // - // (GMT+01.00) Sarajevo/Warsaw/Zagreb - // - // Since PHP 5.5.10, the first bit will be used as the timezone and - // this method will return just GMT+01:00. This is wrong, because it - // doesn't take DST into account. - if ('(' !== $tzid[0]) { - // PHP has a bug that logs PHP warnings even it shouldn't: - // https://bugs.php.net/bug.php?id=67881 - // - // That's why we're checking if we'll be able to successfully instantiate - // \DateTimeZone() before doing so. Otherwise we could simply instantiate - // and catch the exception. - $tzIdentifiers = \DateTimeZone::listIdentifiers(); - - try { - if ( - (in_array($tzid, $tzIdentifiers)) || - (preg_match('/^GMT(\+|-)([0-9]{4})$/', $tzid, $matches)) || - (in_array($tzid, self::getIdentifiersBC())) - ) { - return new \DateTimeZone($tzid); - } - } catch (\Exception $e) { - } - } - - self::loadTzMaps(); - - // Next, we check if the tzid is somewhere in our tzid map. - if (isset(self::$map[$tzid])) { - return new \DateTimeZone(self::$map[$tzid]); - } - - // Some Microsoft products prefix the offset first, so let's strip that off - // and see if it is our tzid map. We don't want to check for this first just - // in case there are overrides in our tzid map. - if (preg_match('/^\((UTC|GMT)(\+|\-)[\d]{2}\:[\d]{2}\) (.*)/', $tzid, $matches)) { - $tzidAlternate = $matches[3]; - if (isset(self::$map[$tzidAlternate])) { - return new \DateTimeZone(self::$map[$tzidAlternate]); - } - } - - // Maybe the author was hyper-lazy and just included an offset. We - // support it, but we aren't happy about it. - if (preg_match('/^GMT(\+|-)([0-9]{4})$/', $tzid, $matches)) { - // Note that the path in the source will never be taken from PHP 5.5.10 - // onwards. PHP 5.5.10 supports the "GMT+0100" style of format, so it - // already gets returned early in this function. Once we drop support - // for versions under PHP 5.5.10, this bit can be taken out of the - // source. - // @codeCoverageIgnoreStart - return new \DateTimeZone('Etc/GMT'.$matches[1].ltrim(substr($matches[2], 0, 2), '0')); - // @codeCoverageIgnoreEnd - } - - if ($vcalendar) { - // If that didn't work, we will scan VTIMEZONE objects - foreach ($vcalendar->select('VTIMEZONE') as $vtimezone) { - if ((string) $vtimezone->TZID === $tzid) { - // Some clients add 'X-LIC-LOCATION' with the olson name. - if (isset($vtimezone->{'X-LIC-LOCATION'})) { - $lic = (string) $vtimezone->{'X-LIC-LOCATION'}; - - // Libical generators may specify strings like - // "SystemV/EST5EDT". For those we must remove the - // SystemV part. - if ('SystemV/' === substr($lic, 0, 8)) { - $lic = substr($lic, 8); - } - - return self::getTimeZone($lic, null, $failIfUncertain); - } - // Microsoft may add a magic number, which we also have an - // answer for. - if (isset($vtimezone->{'X-MICROSOFT-CDO-TZID'})) { - $cdoId = (int) $vtimezone->{'X-MICROSOFT-CDO-TZID'}->getValue(); - - // 2 can mean both Europe/Lisbon and Europe/Sarajevo. - if (2 === $cdoId && false !== strpos((string) $vtimezone->TZID, 'Sarajevo')) { - return new \DateTimeZone('Europe/Sarajevo'); - } - - if (isset(self::$microsoftExchangeMap[$cdoId])) { - return new \DateTimeZone(self::$microsoftExchangeMap[$cdoId]); - } - } - } - } - } - - if ($failIfUncertain) { - throw new \InvalidArgumentException('We were unable to determine the correct PHP timezone for tzid: '.$tzid); - } - - // If we got all the way here, we default to UTC. - return new \DateTimeZone(date_default_timezone_get()); - } - /** * This method will load in all the tz mapping information, if it's not yet * done. + * + * @deprecated */ public static function loadTzMaps() { @@ -257,6 +262,8 @@ public static function loadTzMaps() * (See timezonedata/php-bc.php and timezonedata php-workaround.php) * * @return array + * + * @deprecated */ public static function getIdentifiersBC() { diff --git a/lib/TimezoneGuesser/FindFromOffset.php b/lib/TimezoneGuesser/FindFromOffset.php new file mode 100644 index 000000000..990ac9692 --- /dev/null +++ b/lib/TimezoneGuesser/FindFromOffset.php @@ -0,0 +1,31 @@ +getIdentifiersBC())) + ) { + return new DateTimeZone($tzid); + } + } catch (Exception $e) { + } + + return null; + } + + /** + * This method returns an array of timezone identifiers, that are supported + * by DateTimeZone(), but not returned by DateTimeZone::listIdentifiers(). + * + * We're not using DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC) because: + * - It's not supported by some PHP versions as well as HHVM. + * - It also returns identifiers, that are invalid values for new DateTimeZone() on some PHP versions. + * (See timezonedata/php-bc.php and timezonedata php-workaround.php) + * + * @return array + */ + private function getIdentifiersBC() + { + return include __DIR__.'/../timezonedata/php-bc.php'; + } +} diff --git a/lib/TimezoneGuesser/FindFromTimezoneMap.php b/lib/TimezoneGuesser/FindFromTimezoneMap.php new file mode 100644 index 000000000..b52ba6a19 --- /dev/null +++ b/lib/TimezoneGuesser/FindFromTimezoneMap.php @@ -0,0 +1,78 @@ +hasTzInMap($tzid)) { + return new DateTimeZone($this->getTzFromMap($tzid)); + } + + // Some Microsoft products prefix the offset first, so let's strip that off + // and see if it is our tzid map. We don't want to check for this first just + // in case there are overrides in our tzid map. + foreach ($this->patterns as $pattern) { + if (!preg_match($pattern, $tzid, $matches)) { + continue; + } + $tzidAlternate = $matches[3]; + if ($this->hasTzInMap($tzidAlternate)) { + return new DateTimeZone($this->getTzFromMap($tzidAlternate)); + } + } + + return null; + } + + /** + * This method returns an array of timezone identifiers, that are supported + * by DateTimeZone(), but not returned by DateTimeZone::listIdentifiers(). + * + * We're not using DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC) because: + * - It's not supported by some PHP versions as well as HHVM. + * - It also returns identifiers, that are invalid values for new DateTimeZone() on some PHP versions. + * (See timezonedata/php-bc.php and timezonedata php-workaround.php) + * + * @return array + */ + private function getTzMaps() + { + if ([] === $this->map) { + $this->map = array_merge( + include __DIR__.'/../timezonedata/windowszones.php', + include __DIR__.'/../timezonedata/lotuszones.php', + include __DIR__.'/../timezonedata/exchangezones.php', + include __DIR__.'/../timezonedata/php-workaround.php' + ); + } + + return $this->map; + } + + private function getTzFromMap(string $tzid): string + { + return $this->getTzMaps()[$tzid]; + } + + private function hasTzInMap(string $tzid): bool + { + return isset($this->getTzMaps()[$tzid]); + } +} diff --git a/lib/TimezoneGuesser/GuessFromLicEntry.php b/lib/TimezoneGuesser/GuessFromLicEntry.php new file mode 100644 index 000000000..f340a3962 --- /dev/null +++ b/lib/TimezoneGuesser/GuessFromLicEntry.php @@ -0,0 +1,33 @@ +{'X-LIC-LOCATION'})) { + return null; + } + + $lic = (string) $vtimezone->{'X-LIC-LOCATION'}; + + // Libical generators may specify strings like + // "SystemV/EST5EDT". For those we must remove the + // SystemV part. + if ('SystemV/' === substr($lic, 0, 8)) { + $lic = substr($lic, 8); + } + + return TimeZoneUtil::getTimeZone($lic, null, $failIfUncertain); + } +} diff --git a/lib/TimezoneGuesser/GuessFromMsTzId.php b/lib/TimezoneGuesser/GuessFromMsTzId.php new file mode 100644 index 000000000..b11ce1832 --- /dev/null +++ b/lib/TimezoneGuesser/GuessFromMsTzId.php @@ -0,0 +1,119 @@ + 'UTC', + 31 => 'Africa/Casablanca', + + // Insanely, id #2 is used for both Europe/Lisbon, and Europe/Sarajevo. + // I'm not even kidding.. We handle this special case in the + // getTimeZone method. + 2 => 'Europe/Lisbon', + 1 => 'Europe/London', + 4 => 'Europe/Berlin', + 6 => 'Europe/Prague', + 3 => 'Europe/Paris', + 69 => 'Africa/Luanda', // This was a best guess + 7 => 'Europe/Athens', + 5 => 'Europe/Bucharest', + 49 => 'Africa/Cairo', + 50 => 'Africa/Harare', + 59 => 'Europe/Helsinki', + 27 => 'Asia/Jerusalem', + 26 => 'Asia/Baghdad', + 74 => 'Asia/Kuwait', + 51 => 'Europe/Moscow', + 56 => 'Africa/Nairobi', + 25 => 'Asia/Tehran', + 24 => 'Asia/Muscat', // Best guess + 54 => 'Asia/Baku', + 48 => 'Asia/Kabul', + 58 => 'Asia/Yekaterinburg', + 47 => 'Asia/Karachi', + 23 => 'Asia/Calcutta', + 62 => 'Asia/Kathmandu', + 46 => 'Asia/Almaty', + 71 => 'Asia/Dhaka', + 66 => 'Asia/Colombo', + 61 => 'Asia/Rangoon', + 22 => 'Asia/Bangkok', + 64 => 'Asia/Krasnoyarsk', + 45 => 'Asia/Shanghai', + 63 => 'Asia/Irkutsk', + 21 => 'Asia/Singapore', + 73 => 'Australia/Perth', + 75 => 'Asia/Taipei', + 20 => 'Asia/Tokyo', + 72 => 'Asia/Seoul', + 70 => 'Asia/Yakutsk', + 19 => 'Australia/Adelaide', + 44 => 'Australia/Darwin', + 18 => 'Australia/Brisbane', + 76 => 'Australia/Sydney', + 43 => 'Pacific/Guam', + 42 => 'Australia/Hobart', + 68 => 'Asia/Vladivostok', + 41 => 'Asia/Magadan', + 17 => 'Pacific/Auckland', + 40 => 'Pacific/Fiji', + 67 => 'Pacific/Tongatapu', + 29 => 'Atlantic/Azores', + 53 => 'Atlantic/Cape_Verde', + 30 => 'America/Noronha', + 8 => 'America/Sao_Paulo', // Best guess + 32 => 'America/Argentina/Buenos_Aires', + 60 => 'America/Godthab', + 28 => 'America/St_Johns', + 9 => 'America/Halifax', + 33 => 'America/Caracas', + 65 => 'America/Santiago', + 35 => 'America/Bogota', + 10 => 'America/New_York', + 34 => 'America/Indiana/Indianapolis', + 55 => 'America/Guatemala', + 11 => 'America/Chicago', + 37 => 'America/Mexico_City', + 36 => 'America/Edmonton', + 38 => 'America/Phoenix', + 12 => 'America/Denver', // Best guess + 13 => 'America/Los_Angeles', // Best guess + 14 => 'America/Anchorage', + 15 => 'Pacific/Honolulu', + 16 => 'Pacific/Midway', + 39 => 'Pacific/Kwajalein', + ]; + + public function guess(VTimeZone $vtimezone, bool $throwIfUnsure = false): ?DateTimeZone + { + // Microsoft may add a magic number, which we also have an + // answer for. + if (!isset($vtimezone->{'X-MICROSOFT-CDO-TZID'})) { + return null; + } + $cdoId = (int) $vtimezone->{'X-MICROSOFT-CDO-TZID'}->getValue(); + + // 2 can mean both Europe/Lisbon and Europe/Sarajevo. + if (2 === $cdoId && false !== strpos((string) $vtimezone->TZID, 'Sarajevo')) { + return new DateTimeZone('Europe/Sarajevo'); + } + + if (isset(self::$microsoftExchangeMap[$cdoId])) { + return new DateTimeZone(self::$microsoftExchangeMap[$cdoId]); + } + + return null; + } +} diff --git a/lib/TimezoneGuesser/TimezoneFinder.php b/lib/TimezoneGuesser/TimezoneFinder.php new file mode 100644 index 000000000..5aa880a1c --- /dev/null +++ b/lib/TimezoneGuesser/TimezoneFinder.php @@ -0,0 +1,10 @@ + Date: Mon, 15 Nov 2021 16:16:23 +0545 Subject: [PATCH 082/165] testEmptyTimeZone --- tests/VObject/TimeZoneUtilTest.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/VObject/TimeZoneUtilTest.php b/tests/VObject/TimeZoneUtilTest.php index 494a2e1ae..4df91572c 100644 --- a/tests/VObject/TimeZoneUtilTest.php +++ b/tests/VObject/TimeZoneUtilTest.php @@ -151,6 +151,13 @@ public function testUnknownExchangeId() $this->assertEquals($ex->getName(), $tz->getName()); } + public function testEmptyTimeZone() + { + $tz = TimeZoneUtil::getTimeZone(''); + $ex = new \DateTimeZone('UTC'); + $this->assertEquals($ex->getName(), $tz->getName()); + } + public function testWindowsTimeZone() { $tz = TimeZoneUtil::getTimeZone('Eastern Standard Time'); From 962b5eea95dae8aab7f0af3c84de85443103e25f Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Mon, 15 Nov 2021 22:02:23 +0545 Subject: [PATCH 083/165] Changelog for 4.4.0 --- CHANGELOG.md | 15 ++++++++++----- lib/Version.php | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6621decbf..3461d0c65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,22 +1,27 @@ ChangeLog ========= +4.4.0 (2021-11-15) +------------------ + + #548: Allow easier extension of the timezone guessing (@heiglandreas) + 4.3.8 (2021-11-14) ------------------ -* #538 fix EventIterator returns wrong end endTime (@floerke) -* #541 Reordering of the attendees is not a significant change (@floerke) -* #543 Reordering of vevent is not a significant change (@floerke) +* #538: fix EventIterator returns wrong end endTime (@floerke) +* #541: Reordering of the attendees is not a significant change (@floerke) +* #543: Reordering of vevent is not a significant change (@floerke) 4.3.7 (2021-11-04) ------------------ -* #551 version bump that was missed in 4.3.6 (@phil-davis) +* #551: version bump that was missed in 4.3.6 (@phil-davis) 4.3.6 (2021-11-04) ------------------ -* #544 Fix deprecated usages and return types on PHP 8.1 (@cedric-anne) +* #544: Fix deprecated usages and return types on PHP 8.1 (@cedric-anne) 4.3.5 (2021-02-12) ------------------ diff --git a/lib/Version.php b/lib/Version.php index fce863ecb..e8e73360b 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.3.8'; + const VERSION = '4.4.0'; } From 68fe7d3b1e1927d55ad906162c53cd9d8853c070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Tue, 7 Dec 2021 09:28:22 +0100 Subject: [PATCH 084/165] Fix Iterator method signatures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids warnings under PHP>=8.1 Real return types should be added before PHP 9 Signed-off-by: Côme Chilliet --- lib/Recur/EventIterator.php | 9 +++++++++ lib/Recur/RDateIterator.php | 9 +++++++++ lib/Recur/RRuleIterator.php | 9 +++++++++ 3 files changed, 27 insertions(+) diff --git a/lib/Recur/EventIterator.php b/lib/Recur/EventIterator.php index 310bebe41..61f05d7de 100644 --- a/lib/Recur/EventIterator.php +++ b/lib/Recur/EventIterator.php @@ -198,6 +198,7 @@ public function __construct($input, $uid = null, DateTimeZone $timeZone = null) * * @return DateTimeImmutable */ + #[\ReturnTypeWillChange] public function current() { if ($this->currentDate) { @@ -285,6 +286,7 @@ public function getEventObject() * * @return int */ + #[\ReturnTypeWillChange] public function key() { // The counter is always 1 ahead. @@ -297,6 +299,7 @@ public function key() * * @return bool */ + #[\ReturnTypeWillChange] public function valid() { if ($this->counter > Settings::$maxRecurrences && -1 !== Settings::$maxRecurrences) { @@ -308,7 +311,10 @@ public function valid() /** * Sets the iterator back to the starting point. + * + * @return void */ + #[\ReturnTypeWillChange] public function rewind() { $this->recurIterator->rewind(); @@ -331,7 +337,10 @@ public function rewind() /** * Advances the iterator with one step. + * + * @return void */ + #[\ReturnTypeWillChange] public function next() { $this->currentOverriddenEvent = null; diff --git a/lib/Recur/RDateIterator.php b/lib/Recur/RDateIterator.php index d117e152c..5d56657fa 100644 --- a/lib/Recur/RDateIterator.php +++ b/lib/Recur/RDateIterator.php @@ -35,6 +35,7 @@ public function __construct($rrule, DateTimeInterface $start) /* Implementation of the Iterator interface {{{ */ + #[\ReturnTypeWillChange] public function current() { if (!$this->valid()) { @@ -49,6 +50,7 @@ public function current() * * @return int */ + #[\ReturnTypeWillChange] public function key() { return $this->counter; @@ -60,6 +62,7 @@ public function key() * * @return bool */ + #[\ReturnTypeWillChange] public function valid() { return $this->counter <= count($this->dates); @@ -67,7 +70,10 @@ public function valid() /** * Resets the iterator. + * + * @return void */ + #[\ReturnTypeWillChange] public function rewind() { $this->currentDate = clone $this->startDate; @@ -76,7 +82,10 @@ public function rewind() /** * Goes on to the next iteration. + * + * @return void */ + #[\ReturnTypeWillChange] public function next() { ++$this->counter; diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index 0511f0ade..d556aa6c3 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -38,6 +38,7 @@ public function __construct($rrule, DateTimeInterface $start) /* Implementation of the Iterator interface {{{ */ + #[\ReturnTypeWillChange] public function current() { if (!$this->valid()) { @@ -52,6 +53,7 @@ public function current() * * @return int */ + #[\ReturnTypeWillChange] public function key() { return $this->counter; @@ -64,6 +66,7 @@ public function key() * * @return bool */ + #[\ReturnTypeWillChange] public function valid() { if (null === $this->currentDate) { @@ -78,7 +81,10 @@ public function valid() /** * Resets the iterator. + * + * @return void */ + #[\ReturnTypeWillChange] public function rewind() { $this->currentDate = clone $this->startDate; @@ -87,7 +93,10 @@ public function rewind() /** * Goes on to the next iteration. + * + * @return void */ + #[\ReturnTypeWillChange] public function next() { // Otherwise, we find the next event in the normal RRULE From 07a329ed595d0ed99d963e3f8fbb63b811a36826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Tue, 7 Dec 2021 10:11:06 +0100 Subject: [PATCH 085/165] Avoid passing null as separator for implode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- lib/Parser/MimeDir.php | 2 +- lib/Property.php | 2 +- lib/Property/Binary.php | 4 ++-- lib/Property/FloatValue.php | 2 +- lib/Property/ICalendar/CalAddress.php | 4 ++-- lib/Property/ICalendar/Duration.php | 2 +- lib/Property/ICalendar/Period.php | 2 +- lib/Property/Time.php | 4 ++-- lib/Property/Uri.php | 4 ++-- lib/Property/UtcOffset.php | 4 ++-- lib/Property/VCard/DateAndOrTime.php | 4 ++-- lib/Property/VCard/TimeStamp.php | 4 ++-- 12 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/Parser/MimeDir.php b/lib/Parser/MimeDir.php index f6ffc37b6..db0f81531 100644 --- a/lib/Parser/MimeDir.php +++ b/lib/Parser/MimeDir.php @@ -518,7 +518,7 @@ protected function readProperty($line) * * Now for the parameters * - * If delimiter is not set (null) this method will just return a string. + * If delimiter is not set (empty string) this method will just return a string. * If it's a comma or a semi-colon the string will be split on those * characters, and always return an array. * diff --git a/lib/Property.php b/lib/Property.php index 6219c9b67..50cda9684 100644 --- a/lib/Property.php +++ b/lib/Property.php @@ -52,7 +52,7 @@ abstract class Property extends Node * In case this is a multi-value property. This string will be used as a * delimiter. * - * @var string|null + * @var string */ public $delimiter = ';'; diff --git a/lib/Property/Binary.php b/lib/Property/Binary.php index ec6713fdd..1262dd054 100644 --- a/lib/Property/Binary.php +++ b/lib/Property/Binary.php @@ -24,9 +24,9 @@ class Binary extends Property * In case this is a multi-value property. This string will be used as a * delimiter. * - * @var string|null + * @var string */ - public $delimiter = null; + public $delimiter = ''; /** * Updates the current value. diff --git a/lib/Property/FloatValue.php b/lib/Property/FloatValue.php index 0d0346968..e780ae6c1 100644 --- a/lib/Property/FloatValue.php +++ b/lib/Property/FloatValue.php @@ -21,7 +21,7 @@ class FloatValue extends Property * In case this is a multi-value property. This string will be used as a * delimiter. * - * @var string|null + * @var string */ public $delimiter = ';'; diff --git a/lib/Property/ICalendar/CalAddress.php b/lib/Property/ICalendar/CalAddress.php index 86be66c15..2dbbc6eaf 100644 --- a/lib/Property/ICalendar/CalAddress.php +++ b/lib/Property/ICalendar/CalAddress.php @@ -19,9 +19,9 @@ class CalAddress extends Text * In case this is a multi-value property. This string will be used as a * delimiter. * - * @var string|null + * @var string */ - public $delimiter = null; + public $delimiter = ''; /** * Returns the type of value. diff --git a/lib/Property/ICalendar/Duration.php b/lib/Property/ICalendar/Duration.php index 87f008160..e18fe191e 100644 --- a/lib/Property/ICalendar/Duration.php +++ b/lib/Property/ICalendar/Duration.php @@ -22,7 +22,7 @@ class Duration extends Property * In case this is a multi-value property. This string will be used as a * delimiter. * - * @var string|null + * @var string */ public $delimiter = ','; diff --git a/lib/Property/ICalendar/Period.php b/lib/Property/ICalendar/Period.php index eb3752770..ae8a78911 100644 --- a/lib/Property/ICalendar/Period.php +++ b/lib/Property/ICalendar/Period.php @@ -23,7 +23,7 @@ class Period extends Property * In case this is a multi-value property. This string will be used as a * delimiter. * - * @var string|null + * @var string */ public $delimiter = ','; diff --git a/lib/Property/Time.php b/lib/Property/Time.php index 544b5ced3..1b81609aa 100644 --- a/lib/Property/Time.php +++ b/lib/Property/Time.php @@ -19,9 +19,9 @@ class Time extends Text * In case this is a multi-value property. This string will be used as a * delimiter. * - * @var string|null + * @var string */ - public $delimiter = null; + public $delimiter = ''; /** * Returns the type of value. diff --git a/lib/Property/Uri.php b/lib/Property/Uri.php index 830cd3f18..1ad1fb199 100644 --- a/lib/Property/Uri.php +++ b/lib/Property/Uri.php @@ -20,9 +20,9 @@ class Uri extends Text * In case this is a multi-value property. This string will be used as a * delimiter. * - * @var string|null + * @var string */ - public $delimiter = null; + public $delimiter = ''; /** * Returns the type of value. diff --git a/lib/Property/UtcOffset.php b/lib/Property/UtcOffset.php index 248ed40ea..04b88447f 100644 --- a/lib/Property/UtcOffset.php +++ b/lib/Property/UtcOffset.php @@ -17,9 +17,9 @@ class UtcOffset extends Text * In case this is a multi-value property. This string will be used as a * delimiter. * - * @var string|null + * @var string */ - public $delimiter = null; + public $delimiter = ''; /** * Returns the type of value. diff --git a/lib/Property/VCard/DateAndOrTime.php b/lib/Property/VCard/DateAndOrTime.php index 09918b31a..7bf79c48c 100644 --- a/lib/Property/VCard/DateAndOrTime.php +++ b/lib/Property/VCard/DateAndOrTime.php @@ -24,9 +24,9 @@ class DateAndOrTime extends Property /** * Field separator. * - * @var string|null + * @var string */ - public $delimiter = null; + public $delimiter = ''; /** * Returns the type of value. diff --git a/lib/Property/VCard/TimeStamp.php b/lib/Property/VCard/TimeStamp.php index fccf2d600..da6ea3d44 100644 --- a/lib/Property/VCard/TimeStamp.php +++ b/lib/Property/VCard/TimeStamp.php @@ -21,9 +21,9 @@ class TimeStamp extends Text * In case this is a multi-value property. This string will be used as a * delimiter. * - * @var string|null + * @var string */ - public $delimiter = null; + public $delimiter = ''; /** * Returns the type of value. From 9c94b070431cd987c2962682f4eba154d7938a2a Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Tue, 7 Dec 2021 15:28:46 +0545 Subject: [PATCH 086/165] Prepare release 4.4.1 --- CHANGELOG.md | 5 +++++ lib/Version.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3461d0c65..972e8fb15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ ChangeLog ========= +4.4.1 (2021-12-07) +------------------ + + #557: Fix Iterator method signatures and avoid passing null as separator for implode (PHP 8.1 support) (@come-nc) + 4.4.0 (2021-11-15) ------------------ diff --git a/lib/Version.php b/lib/Version.php index e8e73360b..64938bf0b 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.4.0'; + const VERSION = '4.4.1'; } From 1c66700acd36dde4b6bb5cab1c0110a8954a0bee Mon Sep 17 00:00:00 2001 From: Ren Xie Liu Date: Mon, 14 Feb 2022 17:29:46 +0800 Subject: [PATCH 087/165] Fix infinite loop caused by yearly with bySetPos --- lib/Recur/RRuleIterator.php | 8 ++++++++ tests/VObject/Recur/RRuleIteratorTest.php | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index d556aa6c3..b003dcd60 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -658,6 +658,14 @@ protected function nextYearly() (int) $currentMonth, (int) $currentDayOfMonth ); + + // To prevent running this forever (better: until we hit the max date of DateTimeImmutable) we simply + // stop at 9999-12-31. Looks like the year 10000 problem is not solved in php .... + if ($this->currentDate->getTimestamp() > 253402300799) { + $this->currentDate = null; + + return; + } } // If we made it here, it means we got a valid occurrence diff --git a/tests/VObject/Recur/RRuleIteratorTest.php b/tests/VObject/Recur/RRuleIteratorTest.php index cc40a6f6f..23b1396b9 100644 --- a/tests/VObject/Recur/RRuleIteratorTest.php +++ b/tests/VObject/Recur/RRuleIteratorTest.php @@ -825,6 +825,17 @@ public function testYearlyByMonthLoop() ); } + public function testYearlyBySetPosLoop() + { + $this->parse( + 'FREQ=YEARLY;BYMONTH=5;BYSETPOS=3;BYMONTHDAY=3', + '2022-03-03 15:45:00', + [ + ], + '2022-05-01' + ); + } + /** * Something, somewhere produced an ics with an interval set to 0. Because * this means we increase the current day (or week, month) by 0, this also From c2a5ecd5f66a7528d8defab19ec83f47086d6d7e Mon Sep 17 00:00:00 2001 From: pk1234 Date: Sun, 20 Feb 2022 13:09:17 +0100 Subject: [PATCH 088/165] lowercase mailto:-addresses in getNormalizedValue() --- lib/Property/ICalendar/CalAddress.php | 6 +++++- tests/VObject/Property/ICalendar/CalAddressTest.php | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/Property/ICalendar/CalAddress.php b/lib/Property/ICalendar/CalAddress.php index 2dbbc6eaf..c190f4750 100644 --- a/lib/Property/ICalendar/CalAddress.php +++ b/lib/Property/ICalendar/CalAddress.php @@ -53,7 +53,11 @@ public function getNormalizedValue() return $input; } list($schema, $everythingElse) = explode(':', $input, 2); + $schema = strtolower($schema); + if($schema == "mailto") { + $everythingElse = strtolower($everythingElse); + } - return strtolower($schema).':'.$everythingElse; + return $schema.':'.$everythingElse; } } diff --git a/tests/VObject/Property/ICalendar/CalAddressTest.php b/tests/VObject/Property/ICalendar/CalAddressTest.php index a907daf5c..e7490869f 100644 --- a/tests/VObject/Property/ICalendar/CalAddressTest.php +++ b/tests/VObject/Property/ICalendar/CalAddressTest.php @@ -25,6 +25,8 @@ public function values() return [ ['mailto:a@b.com', 'mailto:a@b.com'], ['mailto:a@b.com', 'MAILTO:a@b.com'], + ['mailto:a@b.com', 'mailto:A@B.COM'], + ['mailto:a@b.com', 'MAILTO:A@B.COM'], ['/foo/bar', '/foo/bar'], ]; } From 8580257b0e9b2efcb00ddb4f61b1d05ce5afe700 Mon Sep 17 00:00:00 2001 From: Evengard Date: Sat, 2 Apr 2022 14:00:08 +0300 Subject: [PATCH 089/165] Add NICKNAME fallback for VCards without FNs This is a rare yet possible case (I stumbled upon such VCards in my own Google Account storage) where a NICKNAME is defined on a VCard but no FN. Importing such contacts into Nextcloud (using Sabre/VObject) is a bit of a pain, this attempts to solve it. --- lib/Component/VCard.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/Component/VCard.php b/lib/Component/VCard.php index eac789842..24c84b903 100644 --- a/lib/Component/VCard.php +++ b/lib/Component/VCard.php @@ -290,7 +290,12 @@ public function validate($options = 0) } elseif (isset($this->ORG)) { $this->FN = (string) $this->ORG; $repaired = true; - + + // Otherwise, the NICKNAME property may work + elseif (isset($this->NICKNAME)) { + $this->FN = (string) $this->NICKNAME; + $repaired = true; + // Otherwise, the EMAIL property may work } elseif (isset($this->EMAIL)) { $this->FN = (string) $this->EMAIL; From 2a624224c14eab9d53927a7965611559b811b10f Mon Sep 17 00:00:00 2001 From: Evengard Date: Sat, 2 Apr 2022 14:02:19 +0300 Subject: [PATCH 090/165] Fix up typo --- lib/Component/VCard.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Component/VCard.php b/lib/Component/VCard.php index 24c84b903..ba9645408 100644 --- a/lib/Component/VCard.php +++ b/lib/Component/VCard.php @@ -292,7 +292,7 @@ public function validate($options = 0) $repaired = true; // Otherwise, the NICKNAME property may work - elseif (isset($this->NICKNAME)) { + } elseif (isset($this->NICKNAME)) { $this->FN = (string) $this->NICKNAME; $repaired = true; From f732c65c2df0b51040894f72eec4cd484ed90fb9 Mon Sep 17 00:00:00 2001 From: Evengard Date: Sat, 2 Apr 2022 14:06:03 +0300 Subject: [PATCH 091/165] Adding test for NICKNAME fallback --- tests/VObject/Component/VCardTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/VObject/Component/VCardTest.php b/tests/VObject/Component/VCardTest.php index d8e6110b6..c23921682 100644 --- a/tests/VObject/Component/VCardTest.php +++ b/tests/VObject/Component/VCardTest.php @@ -92,6 +92,14 @@ public function validateData() ], "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nORG:Acme Co.\r\nFN:Acme Co.\r\nEND:VCARD\r\n", ]; + // No FN, NICKNAME fallback + $tests[] = [ + "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\NICKNAME:JohnDoe\r\nEND:VCARD\r\n", + [ + 'The FN property must appear in the VCARD component exactly 1 time', + ], + "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nNICKNAME:JohnDoe\r\nFN:JohnDoe\r\nEND:VCARD\r\n", + ]; // No FN, EMAIL fallback $tests[] = [ "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nEMAIL:1@example.org\r\nEND:VCARD\r\n", From e5941391feeb0bd141bc1e220eb5c55d8892ce08 Mon Sep 17 00:00:00 2001 From: pk1234 Date: Fri, 6 May 2022 19:25:03 +0200 Subject: [PATCH 092/165] Use === instead of == --- lib/Property/ICalendar/CalAddress.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Property/ICalendar/CalAddress.php b/lib/Property/ICalendar/CalAddress.php index c190f4750..00693d334 100644 --- a/lib/Property/ICalendar/CalAddress.php +++ b/lib/Property/ICalendar/CalAddress.php @@ -54,7 +54,7 @@ public function getNormalizedValue() } list($schema, $everythingElse) = explode(':', $input, 2); $schema = strtolower($schema); - if($schema == "mailto") { + if($schema === "mailto") { $everythingElse = strtolower($everythingElse); } From 7c50120f498ee9a73cc4c727a3e32d8bba1f0365 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 12 May 2022 02:06:11 +0200 Subject: [PATCH 093/165] Component/select: Before uppercasing $child->group, make sure it isn't null Signed-off-by: Gergely Nagy --- lib/Component.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Component.php b/lib/Component.php index f33b628a7..cb08c0061 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -249,7 +249,7 @@ function ($child) use ($group) { $result = []; foreach ($this->children as $childGroup) { foreach ($childGroup as $child) { - if ($child instanceof Property && strtoupper($child->group) === $group) { + if ($child instanceof Property && $child->group && strtoupper($child->group) === $group) { $result[] = $child; } } From 3f4b735fedbb700198291d313ca8b7c8686711d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= <91878298+come-nc@users.noreply.github.com> Date: Tue, 14 Jun 2022 09:10:47 +0200 Subject: [PATCH 094/165] Fix encoding detection on PHP 8.1 Also get rid of deprecated utf8_encode --- lib/StringUtil.php | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/lib/StringUtil.php b/lib/StringUtil.php index 2333d6ab9..b04539e4a 100644 --- a/lib/StringUtil.php +++ b/lib/StringUtil.php @@ -40,23 +40,11 @@ public static function isUTF8($str) */ public static function convertToUTF8($str) { - $encoding = mb_detect_encoding($str, ['UTF-8', 'ISO-8859-1', 'WINDOWS-1252'], true); - - switch ($encoding) { - case 'ISO-8859-1': - $newStr = utf8_encode($str); - break; - /* Unreachable code. Not sure yet how we can improve this - * situation. - case 'WINDOWS-1252' : - $newStr = iconv('cp1252', 'UTF-8', $str); - break; - */ - default: - $newStr = $str; + if (!mb_check_encoding($str, 'UTF-8') && mb_check_encoding($str, 'ISO-8859-1')) { + $str = mb_convert_encoding($str, 'UTF-8', 'ISO-8859-1'); } // Removing any control characters - return preg_replace('%(?:[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F])%', '', $newStr); + return preg_replace('%(?:[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F])%', '', $str); } } From 38b3a265583789bb13e236af6c05c321bddc4297 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Fri, 24 Jun 2022 17:04:26 +0545 Subject: [PATCH 095/165] Release 4.4.2 --- CHANGELOG.md | 8 ++++++++ lib/Version.php | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 972e8fb15..8476d7402 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ ChangeLog ========= +4.4.2 (2022-06-24) +------------------ + +* #565: lowercase mailto:-addresses in getNormalizedValue() (@pk1234) +* #568: Add NICKNAME fallback for VCards without FNs (@Evengard) +* #573: Component/select: Before uppercasing $child->group, make sure it isn't null (@algernon) +* #575: Fix encoding detection on PHP 8.1 (@come-nc) + 4.4.1 (2021-12-07) ------------------ diff --git a/lib/Version.php b/lib/Version.php index 64938bf0b..ff8cf49c2 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.4.1'; + const VERSION = '4.4.2'; } From 96517a3a48e3de5288e2dc59c0d9cfc2d7d46f00 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Fri, 24 Jun 2022 17:08:28 +0545 Subject: [PATCH 096/165] Fix test data for NICKNAME fallback test case --- tests/VObject/Component/VCardTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/VObject/Component/VCardTest.php b/tests/VObject/Component/VCardTest.php index c23921682..45743ff67 100644 --- a/tests/VObject/Component/VCardTest.php +++ b/tests/VObject/Component/VCardTest.php @@ -94,7 +94,7 @@ public function validateData() ]; // No FN, NICKNAME fallback $tests[] = [ - "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\NICKNAME:JohnDoe\r\nEND:VCARD\r\n", + "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nNICKNAME:JohnDoe\r\nEND:VCARD\r\n", [ 'The FN property must appear in the VCARD component exactly 1 time', ], From 025833e762c41dbfa93cefef540b5f017ec7729f Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Fri, 24 Jun 2022 17:19:43 +0545 Subject: [PATCH 097/165] Fix code-style --- lib/Component/VCard.php | 4 ++-- lib/Property/ICalendar/CalAddress.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Component/VCard.php b/lib/Component/VCard.php index ba9645408..90a6df72f 100644 --- a/lib/Component/VCard.php +++ b/lib/Component/VCard.php @@ -290,12 +290,12 @@ public function validate($options = 0) } elseif (isset($this->ORG)) { $this->FN = (string) $this->ORG; $repaired = true; - + // Otherwise, the NICKNAME property may work } elseif (isset($this->NICKNAME)) { $this->FN = (string) $this->NICKNAME; $repaired = true; - + // Otherwise, the EMAIL property may work } elseif (isset($this->EMAIL)) { $this->FN = (string) $this->EMAIL; diff --git a/lib/Property/ICalendar/CalAddress.php b/lib/Property/ICalendar/CalAddress.php index 00693d334..c90967d79 100644 --- a/lib/Property/ICalendar/CalAddress.php +++ b/lib/Property/ICalendar/CalAddress.php @@ -54,7 +54,7 @@ public function getNormalizedValue() } list($schema, $everythingElse) = explode(':', $input, 2); $schema = strtolower($schema); - if($schema === "mailto") { + if ('mailto' === $schema) { $everythingElse = strtolower($everythingElse); } From 85340b7c1f22f6dec5f295ec64fb1fcc0907f92f Mon Sep 17 00:00:00 2001 From: Andreas Heigl Date: Tue, 12 Jul 2022 17:08:55 +0200 Subject: [PATCH 098/165] Ignore multiple same parameter-values Sometimes it seems like parameters can be added multiple times with the same value. Besides not making any sense (and partially being not allowed in the first place) this will also possibly break the further process of parsing an icalendar file. This modification adds a shortcut when the last parameter-value and the current parameter value are exactly the same. In that case the new value is ignored and only the old value will be used. The use-case - as documented in the test - is that there seem to be icalendar files that contain the following content: DTSTART;VALUE=DATE;VALUE=DATE:20220612 While that seems to violate the RFC it is not seen as a violation in the icalendar validator at https://icalendar.org/validator.html and as it can also be imported by other calendaring systems it looks like this should at least not break the parser. --- lib/Parser/MimeDir.php | 3 +++ tests/VObject/Parser/MimeDirTest.php | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lib/Parser/MimeDir.php b/lib/Parser/MimeDir.php index db0f81531..e9cc75bdc 100644 --- a/lib/Parser/MimeDir.php +++ b/lib/Parser/MimeDir.php @@ -378,6 +378,9 @@ protected function readProperty($line) $property['parameters'][$lastParam] = $value; } elseif (is_array($property['parameters'][$lastParam])) { $property['parameters'][$lastParam][] = $value; + } elseif ($property['parameters'][$lastParam] === $value) { + // When the current value of the parameter is the same as the + // new one, then we can leave the current parameter as it is. } else { $property['parameters'][$lastParam] = [ $property['parameters'][$lastParam], diff --git a/tests/VObject/Parser/MimeDirTest.php b/tests/VObject/Parser/MimeDirTest.php index 183c9ce4c..3a0e71c75 100644 --- a/tests/VObject/Parser/MimeDirTest.php +++ b/tests/VObject/Parser/MimeDirTest.php @@ -145,4 +145,24 @@ public function testCaseInsensitiveInlineCharset() $this->assertEquals('Euro', $vcard->FN->getValue()); $this->assertEquals('Test2', $vcard->N->getValue()); } + + public function testParsingTwiceSameContent() + { + $card = <<parse($card); + // we can do a simple assertion here. As long as we don't get an exception, everything is thing + $this->assertEquals('20220612', $vcard->VEVENT->DTSTART->getValue()); + } } From 404e54826d93aba111aa7ef681f1021f3b6c1c47 Mon Sep 17 00:00:00 2001 From: Andreas Heigl Date: Thu, 14 Jul 2022 13:47:47 +0200 Subject: [PATCH 099/165] Fix a comment --- tests/VObject/Parser/MimeDirTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/VObject/Parser/MimeDirTest.php b/tests/VObject/Parser/MimeDirTest.php index 3a0e71c75..bd31b8159 100644 --- a/tests/VObject/Parser/MimeDirTest.php +++ b/tests/VObject/Parser/MimeDirTest.php @@ -162,7 +162,7 @@ public function testParsingTwiceSameContent() $mimeDir = new MimeDir(); $vcard = $mimeDir->parse($card); - // we can do a simple assertion here. As long as we don't get an exception, everything is thing + // we can do a simple assertion here. As long as we don't get an exception, everything is fine $this->assertEquals('20220612', $vcard->VEVENT->DTSTART->getValue()); } } From f80b3961afb8ed45f025c4664a894e591818e396 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Fri, 15 Jul 2022 21:03:48 +0545 Subject: [PATCH 100/165] Prepare release 4.4.3 --- CHANGELOG.md | 5 +++++ lib/Version.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8476d7402..aa9a6ced9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ ChangeLog ========= +4.4.3 (2022-07-15) +------------------ + +* #577: Ignore multiple same parameter-values (@heiglandreas) + 4.4.2 (2022-06-24) ------------------ diff --git a/lib/Version.php b/lib/Version.php index ff8cf49c2..4659730fd 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.4.2'; + const VERSION = '4.4.3'; } From cfb5ce689590b02303ccd4a3de5b21ad5f0f9e1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Wed, 27 Jul 2022 15:05:50 +0200 Subject: [PATCH 101/165] Update .gitattributes --- .gitattributes | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitattributes b/.gitattributes index f95a950f7..c717ebe6a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,7 +1,7 @@ -/tests export-ignore +/.github/ export-ignore +/tests/ export-ignore /.gitattributes export-ignore /.gitignore export-ignore /.php_cs.dist export-ignore -/.travis.yml export-ignore /CHANGELOG.md export-ignore /phpstan.neon export-ignore From e2d2770a9217022f2e4ebce9dd12627cd884df77 Mon Sep 17 00:00:00 2001 From: Michael Stilkerich Date: Fri, 14 Jan 2022 12:47:13 +0100 Subject: [PATCH 102/165] PHP 8.1 deprecated support for null values in its APIs Do not pass a null value to strtoupper. --- lib/Component.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Component.php b/lib/Component.php index cb08c0061..a1413bda3 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -238,7 +238,7 @@ public function select($name) return array_filter( $result, function ($child) use ($group) { - return $child instanceof Property && strtoupper($child->group) === $group; + return $child instanceof Property && strtoupper((string) $child->group) === $group; } ); } From 5bdd392b05a2c6e39683def44669b63b7f1be5bd Mon Sep 17 00:00:00 2001 From: Michael Stilkerich Date: Fri, 14 Jan 2022 16:42:31 +0100 Subject: [PATCH 103/165] Adapt style to preference of project owner --- lib/Component.php | 10 ++++++++-- lib/Property.php | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/Component.php b/lib/Component.php index a1413bda3..2c05c3d0d 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -28,7 +28,7 @@ class Component extends Node /** * A list of properties and/or sub-components. * - * @var array + * @var array */ protected $children = []; @@ -238,7 +238,13 @@ public function select($name) return array_filter( $result, function ($child) use ($group) { - return $child instanceof Property && strtoupper((string) $child->group) === $group; + if ($child instanceof Property) { + $cgroup = isset($child->group) ? strtoupper($child->group) : ''; + + return $cgroup === $group; + } + + return false; } ); } diff --git a/lib/Property.php b/lib/Property.php index 50cda9684..56096dafe 100644 --- a/lib/Property.php +++ b/lib/Property.php @@ -30,7 +30,7 @@ abstract class Property extends Node * * This is only used in vcards * - * @var string + * @var string|null */ public $group; From a11276d4ed115135c5c0952bb9d718b8188f975a Mon Sep 17 00:00:00 2001 From: Michael Stilkerich Date: Fri, 14 Jan 2022 17:32:20 +0100 Subject: [PATCH 104/165] Enable reporting of all PHP error levels in tests This will throw errors when deprecated PHP features are used. --- tests/phpunit.xml | 3 +++ tests/phpunit.xml.bak | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/phpunit.xml.bak diff --git a/tests/phpunit.xml b/tests/phpunit.xml index d40187d2a..16a75c3da 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -10,6 +10,9 @@ failOnWarning="true" enforceTimeLimit="true" > + + + . diff --git a/tests/phpunit.xml.bak b/tests/phpunit.xml.bak new file mode 100644 index 000000000..d40187d2a --- /dev/null +++ b/tests/phpunit.xml.bak @@ -0,0 +1,24 @@ + + + + . + + + + + + ../lib/ + + + From e70f3ede4d473c7a9bc61d94db3e29eb28dbbf82 Mon Sep 17 00:00:00 2001 From: Michael Stilkerich Date: Fri, 14 Jan 2022 17:33:00 +0100 Subject: [PATCH 105/165] Fix passing null values to PHP APIs where encountered by tests --- lib/Cli.php | 5 ++++- lib/Component.php | 6 +++--- lib/Parameter.php | 3 ++- lib/Property/Text.php | 22 ++++++++++++---------- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/lib/Cli.php b/lib/Cli.php index 816e2cb31..a8fc68af5 100644 --- a/lib/Cli.php +++ b/lib/Cli.php @@ -456,7 +456,10 @@ protected function convert($vObj) */ protected function color($vObj) { - fwrite($this->stdout, $this->serializeComponent($vObj)); + $text = $this->serializeComponent($vObj); + if (isset($text)) { + fwrite($this->stdout, $text); + } } /** diff --git a/lib/Component.php b/lib/Component.php index 2c05c3d0d..813ee8ac3 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -43,12 +43,12 @@ class Component extends Node * an iCalendar object, this may be something like CALSCALE:GREGORIAN. To * ensure that this does not happen, set $defaults to false. * - * @param string $name such as VCALENDAR, VEVENT - * @param bool $defaults + * @param string|null $name such as VCALENDAR, VEVENT + * @param bool $defaults */ public function __construct(Document $root, $name, array $children = [], $defaults = true) { - $this->name = strtoupper($name); + $this->name = isset($name) ? strtoupper($name) : ""; $this->root = $root; if ($defaults) { diff --git a/lib/Parameter.php b/lib/Parameter.php index 7e4d55743..c27b2aa47 100644 --- a/lib/Parameter.php +++ b/lib/Parameter.php @@ -52,11 +52,12 @@ class Parameter extends Node */ public function __construct(Document $root, $name, $value = null) { - $this->name = strtoupper($name); $this->root = $root; if (is_null($name)) { $this->noName = true; $this->name = static::guessParameterNameByValue($value); + } else { + $this->name = strtoupper($name); } // If guessParameterNameByValue() returns an empty string diff --git a/lib/Property/Text.php b/lib/Property/Text.php index ac8aa066b..20e477af3 100644 --- a/lib/Property/Text.php +++ b/lib/Property/Text.php @@ -136,16 +136,18 @@ public function getRawMimeDirValue() } foreach ($item as &$subItem) { - $subItem = strtr( - $subItem, - [ - '\\' => '\\\\', - ';' => '\;', - ',' => '\,', - "\n" => '\n', - "\r" => '', - ] - ); + if ($subItem != null) { + $subItem = strtr( + $subItem, + [ + '\\' => '\\\\', + ';' => '\;', + ',' => '\,', + "\n" => '\n', + "\r" => '', + ] + ); + } } $item = implode(',', $item); } From 64a0d6fcb3de4210510d68ffeef8f0407d4871b3 Mon Sep 17 00:00:00 2001 From: Michael Stilkerich Date: Fri, 14 Jan 2022 17:45:03 +0100 Subject: [PATCH 106/165] Run cs fixer --- lib/Component.php | 2 +- lib/Property/Text.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Component.php b/lib/Component.php index 813ee8ac3..a733d3798 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -48,7 +48,7 @@ class Component extends Node */ public function __construct(Document $root, $name, array $children = [], $defaults = true) { - $this->name = isset($name) ? strtoupper($name) : ""; + $this->name = isset($name) ? strtoupper($name) : ''; $this->root = $root; if ($defaults) { diff --git a/lib/Property/Text.php b/lib/Property/Text.php index 20e477af3..16d2c07f4 100644 --- a/lib/Property/Text.php +++ b/lib/Property/Text.php @@ -136,7 +136,7 @@ public function getRawMimeDirValue() } foreach ($item as &$subItem) { - if ($subItem != null) { + if (!is_null($subItem)) { $subItem = strtr( $subItem, [ From e4669aea813a17703440f0bb0d884b12c7ed4243 Mon Sep 17 00:00:00 2001 From: Michael Stilkerich Date: Fri, 14 Jan 2022 17:51:31 +0100 Subject: [PATCH 107/165] Remove file commit by accident --- tests/phpunit.xml.bak | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 tests/phpunit.xml.bak diff --git a/tests/phpunit.xml.bak b/tests/phpunit.xml.bak deleted file mode 100644 index d40187d2a..000000000 --- a/tests/phpunit.xml.bak +++ /dev/null @@ -1,24 +0,0 @@ - - - - . - - - - - - ../lib/ - - - From 13f3df9b3685a6df936ad2f422a452ce702ed1a9 Mon Sep 17 00:00:00 2001 From: Michael Stilkerich Date: Sun, 16 Jan 2022 08:53:39 +0100 Subject: [PATCH 108/165] Cli::serializeComponent does not return anything It (indirectly) writes to stdout by itself. --- lib/Cli.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/Cli.php b/lib/Cli.php index a8fc68af5..3bde16f9c 100644 --- a/lib/Cli.php +++ b/lib/Cli.php @@ -456,10 +456,7 @@ protected function convert($vObj) */ protected function color($vObj) { - $text = $this->serializeComponent($vObj); - if (isset($text)) { - fwrite($this->stdout, $text); - } + $this->serializeComponent($vObj); } /** From fe6189e5d4abdbcf0e812943c5c26869e4e24bc4 Mon Sep 17 00:00:00 2001 From: Michael Stilkerich Date: Wed, 17 Aug 2022 12:28:11 +0200 Subject: [PATCH 109/165] Fix filter for properties without group --- lib/Component.php | 10 ++-------- tests/VObject/ComponentTest.php | 8 ++++++++ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/Component.php b/lib/Component.php index a733d3798..1f513d2d7 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -238,13 +238,7 @@ public function select($name) return array_filter( $result, function ($child) use ($group) { - if ($child instanceof Property) { - $cgroup = isset($child->group) ? strtoupper($child->group) : ''; - - return $cgroup === $group; - } - - return false; + return $child instanceof Property && ($child->group ? strtoupper($child->group) : '') === $group; } ); } @@ -255,7 +249,7 @@ function ($child) use ($group) { $result = []; foreach ($this->children as $childGroup) { foreach ($childGroup as $child) { - if ($child instanceof Property && $child->group && strtoupper($child->group) === $group) { + if ($child instanceof Property && ($child->group ? strtoupper($child->group) : '') === $group) { $result[] = $child; } } diff --git a/tests/VObject/ComponentTest.php b/tests/VObject/ComponentTest.php index cf3e196dc..d28fa0fe6 100644 --- a/tests/VObject/ComponentTest.php +++ b/tests/VObject/ComponentTest.php @@ -67,9 +67,17 @@ public function testMagicGetGroups() $this->assertEquals('EMAIL', $email1[0]->name); $this->assertEquals('GROUP1', $email1[0]->group); + // this is supposed to return all EMAIL properties that do not have a group $email3 = $comp->{'.email'}; $this->assertEquals('EMAIL', $email3[0]->name); $this->assertEquals(null, $email3[0]->group); + + // this is supposed to return all properties that do not have a group + $nogroupProps = $comp->{'.'}; + $this->assertGreaterThan(0, count($email3)); + foreach ($nogroupProps as $prop) { + $this->assertEquals(null, $prop->group); + } } public function testAddGroupProperties() From 1aee5666ed8192fa667b9e8384a55c0eb75fc400 Mon Sep 17 00:00:00 2001 From: Michael Stilkerich Date: Wed, 17 Aug 2022 13:07:47 +0200 Subject: [PATCH 110/165] And also handle a group named 0 correctly --- lib/Component.php | 4 ++-- tests/VObject/ComponentTest.php | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/Component.php b/lib/Component.php index 1f513d2d7..79b43912d 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -238,7 +238,7 @@ public function select($name) return array_filter( $result, function ($child) use ($group) { - return $child instanceof Property && ($child->group ? strtoupper($child->group) : '') === $group; + return $child instanceof Property && ($child->group !== null ? strtoupper($child->group) : '') === $group; } ); } @@ -249,7 +249,7 @@ function ($child) use ($group) { $result = []; foreach ($this->children as $childGroup) { foreach ($childGroup as $child) { - if ($child instanceof Property && ($child->group ? strtoupper($child->group) : '') === $group) { + if ($child instanceof Property && ($child->group !== null ? strtoupper($child->group) : '') === $group) { $result[] = $child; } } diff --git a/tests/VObject/ComponentTest.php b/tests/VObject/ComponentTest.php index d28fa0fe6..9acedf925 100644 --- a/tests/VObject/ComponentTest.php +++ b/tests/VObject/ComponentTest.php @@ -60,13 +60,20 @@ public function testMagicGetGroups() $sub = $comp->createProperty('EMAIL', '3@3.com'); $comp->add($sub); + $sub = $comp->createProperty('0.EMAIL', '0@0.com'); + $comp->add($sub); + $emails = $comp->email; - $this->assertEquals(3, count($emails)); + $this->assertEquals(4, count($emails)); $email1 = $comp->{'group1.email'}; $this->assertEquals('EMAIL', $email1[0]->name); $this->assertEquals('GROUP1', $email1[0]->group); + $email0 = $comp->{'0.email'}; + $this->assertEquals('EMAIL', $email0[0]->name); + $this->assertEquals('0', $email0[0]->group); + // this is supposed to return all EMAIL properties that do not have a group $email3 = $comp->{'.email'}; $this->assertEquals('EMAIL', $email3[0]->name); From 63efe3815a71a555b04bdfe084e07851d2299aa7 Mon Sep 17 00:00:00 2001 From: Michael Stilkerich Date: Wed, 17 Aug 2022 13:10:43 +0200 Subject: [PATCH 111/165] Style appears to prefer yoda conditions --- lib/Component.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Component.php b/lib/Component.php index 79b43912d..a929387a3 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -238,7 +238,7 @@ public function select($name) return array_filter( $result, function ($child) use ($group) { - return $child instanceof Property && ($child->group !== null ? strtoupper($child->group) : '') === $group; + return $child instanceof Property && (null !== $child->group ? strtoupper($child->group) : '') === $group; } ); } @@ -249,7 +249,7 @@ function ($child) use ($group) { $result = []; foreach ($this->children as $childGroup) { foreach ($childGroup as $child) { - if ($child instanceof Property && ($child->group !== null ? strtoupper($child->group) : '') === $group) { + if ($child instanceof Property && (null !== $child->group ? strtoupper($child->group) : '') === $group) { $result[] = $child; } } From 69e49dffa1c63ee3b4ac1db9ab6489f7ef202cef Mon Sep 17 00:00:00 2001 From: Andreas Heigl Date: Fri, 29 Apr 2022 19:07:36 +0200 Subject: [PATCH 112/165] Fully ignore invalid lines Previously when OPTION_IGNORE_INVALID_LINES was set any invalid content of a property was ignored. With this change now also invalid properties themselves are ignored. This will help importing feeds that contain broken multi-line contents where newlines are not propperly escaped and therefore parts of the multiline content show up as property themselves. Without this addition the import will then break and not import anything at all. With this change added an import will now succeed when invalid lines shall be ignored. Without the option set everything will behave as before. --- lib/Parser/MimeDir.php | 7 +++ tests/VObject/Parser/MimeDirTest.php | 79 ++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/lib/Parser/MimeDir.php b/lib/Parser/MimeDir.php index e9cc75bdc..219c5f753 100644 --- a/lib/Parser/MimeDir.php +++ b/lib/Parser/MimeDir.php @@ -372,6 +372,13 @@ protected function readProperty($line) $value = $this->unescapeParam($value); if (is_null($lastParam)) { + if ($this->options & self::OPTION_IGNORE_INVALID_LINES) { + // When the property can't be matched and the configuration + // option is set to ignore invalid lines, we ignore this line + // This can happen when servers provide faulty data as iCloud + // frequently does with X-APPLE-STRUCTURED-LOCATION + continue; + } throw new ParseException('Invalid Mimedir file. Line starting at '.$this->startLine.' did not follow iCalendar/vCard conventions'); } if (is_null($property['parameters'][$lastParam])) { diff --git a/tests/VObject/Parser/MimeDirTest.php b/tests/VObject/Parser/MimeDirTest.php index bd31b8159..9fe7fc4ab 100644 --- a/tests/VObject/Parser/MimeDirTest.php +++ b/tests/VObject/Parser/MimeDirTest.php @@ -3,6 +3,7 @@ namespace Sabre\VObject\Parser; use PHPUnit\Framework\TestCase; +use Sabre\VObject\Component\VCalendar; use Sabre\VObject\ParseException; /** @@ -165,4 +166,82 @@ public function testParsingTwiceSameContent() // we can do a simple assertion here. As long as we don't get an exception, everything is fine $this->assertEquals('20220612', $vcard->VEVENT->DTSTART->getValue()); } + + /** + * @covers \Sabre\VObject\Parser\MimeDir::readProperty + * @dataProvider provideBrokenVCalendar + * + * @param string $vcalendar + * + * @return void + */ + public function testBrokenMultilineContentDoesNotBreakImportWhenSetToIgnoreBrokenLines($vcalendar) + { + $mimeDir = new MimeDir(null, MimeDir::OPTION_IGNORE_INVALID_LINES); + $vcalendar = $mimeDir->parse($vcalendar); + $this->assertInstanceOf(VCalendar::class, $vcalendar); + } + + /** + * @covers \Sabre\VObject\Parser\MimeDir::readProperty + * @dataProvider provideBrokenVCalendar + * + * @param string $vcalendar + * + * @return void + */ + public function testBrokenMultilineContentDoesBreakImport($vcalendar) + { + $mimeDir = new MimeDir(); + $this->expectException(ParseException::class); + $mimeDir->parse($vcalendar); + } + + public function provideBrokenVCalendar() + { + return [[<< Date: Tue, 15 Mar 2022 14:44:02 +0100 Subject: [PATCH 113/165] Test for issue-566 --- .../Recur/EventIterator/Issue566Test.php | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 tests/VObject/Recur/EventIterator/Issue566Test.php diff --git a/tests/VObject/Recur/EventIterator/Issue566Test.php b/tests/VObject/Recur/EventIterator/Issue566Test.php new file mode 100644 index 000000000..beb3b29a3 --- /dev/null +++ b/tests/VObject/Recur/EventIterator/Issue566Test.php @@ -0,0 +1,27 @@ +createComponent('VEVENT'); + $ev->UID = '1'; + $ev->RRULE = 'FREQ=DAILY;INTERVAL=7;BYDAY=MO'; + $dtStart = $vcal->createProperty('DTSTART'); + $dtStart->setDateTime(new DateTimeImmutable('2022-03-15')); + $ev->add($dtStart); + $vcal->add($ev); + $iterator = new EventIterator($vcal, $ev->UID); + $this->assertTrue(true); + } +} From bda30eb5f683f31797a1c462cbbcb991f3acee3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristoffer=20M=C3=B8llerh=C3=B8j?= Date: Tue, 15 Mar 2022 14:44:46 +0100 Subject: [PATCH 114/165] Solution for issue-566 --- lib/Recur/RRuleIterator.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index b003dcd60..23dd7fb3b 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -24,6 +24,13 @@ */ class RRuleIterator implements Iterator { + /** + * Constant denoting the upper limit on how long into the future + * we want to iterate. The value is a unix timestamp and currently + * corresponds to the datetime 9999-12-31 11:59:59 UTC. + */ + const dateUpperLimit = 253402300799; + /** * Creates the Iterator. * @@ -366,6 +373,12 @@ protected function nextDaily() // Current hour of the day $currentHour = $this->currentDate->format('G'); + + if ($this->currentDate->getTimestamp() > self::dateUpperLimit) { + $this->currentDate = null; + + return; + } } while ( ($this->byDay && !in_array($currentDay, $recurrenceDays)) || ($this->byHour && !in_array($currentHour, $recurrenceHours)) || @@ -486,7 +499,7 @@ protected function nextMonthly() // To prevent running this forever (better: until we hit the max date of DateTimeImmutable) we simply // stop at 9999-12-31. Looks like the year 10000 problem is not solved in php .... - if ($this->currentDate->getTimestamp() > 253402300799) { + if ($this->currentDate->getTimestamp() > self::dateUpperLimit) { $this->currentDate = null; return; From 5035657b2c1b2d754521f10b866ddfe488eddbf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristoffer=20M=C3=B8llerh=C3=B8j?= Date: Fri, 18 Mar 2022 10:24:43 +0100 Subject: [PATCH 115/165] Running php-cs-fixer on my to latest commits --- lib/Recur/RRuleIterator.php | 2 +- tests/VObject/Recur/EventIterator/Issue566Test.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index 23dd7fb3b..50a984c1c 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -29,7 +29,7 @@ class RRuleIterator implements Iterator * we want to iterate. The value is a unix timestamp and currently * corresponds to the datetime 9999-12-31 11:59:59 UTC. */ - const dateUpperLimit = 253402300799; + const dateUpperLimit = 253402300799; /** * Creates the Iterator. diff --git a/tests/VObject/Recur/EventIterator/Issue566Test.php b/tests/VObject/Recur/EventIterator/Issue566Test.php index beb3b29a3..f8d48d983 100644 --- a/tests/VObject/Recur/EventIterator/Issue566Test.php +++ b/tests/VObject/Recur/EventIterator/Issue566Test.php @@ -12,7 +12,8 @@ class Issue566Test extends TestCase /** * @medium */ - public function testDaily() { + public function testDaily() + { $vcal = new VCalendar(); $ev = $vcal->createComponent('VEVENT'); $ev->UID = '1'; From baed3e627d39ffa28b9834bdfcf5ebf56af87d3e Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Wed, 17 Aug 2022 19:21:42 +0545 Subject: [PATCH 116/165] Replace 253402300799 with dateUpperLimit --- lib/Recur/RRuleIterator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index 50a984c1c..da788a126 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -674,7 +674,7 @@ protected function nextYearly() // To prevent running this forever (better: until we hit the max date of DateTimeImmutable) we simply // stop at 9999-12-31. Looks like the year 10000 problem is not solved in php .... - if ($this->currentDate->getTimestamp() > 253402300799) { + if ($this->currentDate->getTimestamp() > self::dateUpperLimit) { $this->currentDate = null; return; From 8fedd6fbc951f659a046f834eaf1059576827bf3 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Wed, 17 Aug 2022 20:31:24 +0545 Subject: [PATCH 117/165] Add Issue566Test into the regular set of RRuleIteratorTest --- .../Recur/EventIterator/Issue566Test.php | 28 ------------------- tests/VObject/Recur/RRuleIteratorTest.php | 25 +++++++++++++++++ 2 files changed, 25 insertions(+), 28 deletions(-) delete mode 100644 tests/VObject/Recur/EventIterator/Issue566Test.php diff --git a/tests/VObject/Recur/EventIterator/Issue566Test.php b/tests/VObject/Recur/EventIterator/Issue566Test.php deleted file mode 100644 index f8d48d983..000000000 --- a/tests/VObject/Recur/EventIterator/Issue566Test.php +++ /dev/null @@ -1,28 +0,0 @@ -createComponent('VEVENT'); - $ev->UID = '1'; - $ev->RRULE = 'FREQ=DAILY;INTERVAL=7;BYDAY=MO'; - $dtStart = $vcal->createProperty('DTSTART'); - $dtStart->setDateTime(new DateTimeImmutable('2022-03-15')); - $ev->add($dtStart); - $vcal->add($ev); - $iterator = new EventIterator($vcal, $ev->UID); - $this->assertTrue(true); - } -} diff --git a/tests/VObject/Recur/RRuleIteratorTest.php b/tests/VObject/Recur/RRuleIteratorTest.php index 23b1396b9..4c9107ee5 100644 --- a/tests/VObject/Recur/RRuleIteratorTest.php +++ b/tests/VObject/Recur/RRuleIteratorTest.php @@ -147,6 +147,24 @@ public function testDailyByMonth() ); } + /** + * This test can take some seconds to complete. + * The "large" annotation means phpunit will let it run for + * up to 60 seconds by default. + * + * @large + */ + public function testDailyBySetPosLoop() + { + $this->parse( + 'FREQ=DAILY;INTERVAL=7;BYDAY=MO', + '2022-03-15', + [ + ], + '2022-05-01' + ); + } + public function testWeekly() { $this->parse( @@ -825,6 +843,13 @@ public function testYearlyByMonthLoop() ); } + /** + * This test can take some seconds to complete. + * The "large" annotation means phpunit will let it run for + * up to 60 seconds by default. + * + * @large + */ public function testYearlyBySetPosLoop() { $this->parse( From c828d732e8efa3e12862001daf9661d0e8e64f43 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 22 Jul 2019 14:57:03 +0300 Subject: [PATCH 118/165] Add support for MEMBER in a VCard --- lib/VCardConverter.php | 5 +++++ tests/VObject/VCardConverterTest.php | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/lib/VCardConverter.php b/lib/VCardConverter.php index 04932fe67..04129e355 100644 --- a/lib/VCardConverter.php +++ b/lib/VCardConverter.php @@ -140,6 +140,8 @@ protected function convertProperty(Component\VCard $input, Component\VCard $outp $newProperty = $output->createProperty('X-ADDRESSBOOKSERVER-KIND', 'GROUP'); break; } + } elseif ('MEMBER' === $property->name) { + $newProperty = $output->createProperty('X-ADDRESSBOOKSERVER-MEMBER', $property->getValue()); } } elseif (Document::VCARD40 === $targetVersion) { // These properties were removed in vCard 4.0 @@ -173,6 +175,9 @@ protected function convertProperty(Component\VCard $input, Component\VCard $outp $newProperty = $output->createProperty('KIND', 'GROUP'); } break; + case 'X-ADDRESSBOOKSERVER-MEMBER': + $newProperty = $output->createProperty('MEMBER', $property->getValue()); + break; case 'X-ANNIVERSARY': $newProperty->name = 'ANNIVERSARY'; // If we already have an anniversary property with the same diff --git a/tests/VObject/VCardConverterTest.php b/tests/VObject/VCardConverterTest.php index ae2b10bd5..7b31809a5 100644 --- a/tests/VObject/VCardConverterTest.php +++ b/tests/VObject/VCardConverterTest.php @@ -211,6 +211,8 @@ public function testConvertGroupCard() VERSION:3.0 PRODID:foo X-ADDRESSBOOKSERVER-KIND:GROUP +X-ADDRESSBOOKSERVER-MEMBER:mailto:someone@example.com +X-ADDRESSBOOKSERVER-MEMBER:mailto:sometwo@example.com END:VCARD IN; @@ -219,6 +221,8 @@ public function testConvertGroupCard() BEGIN:VCARD VERSION:4.0 KIND:GROUP +MEMBER:mailto:someone@example.com +MEMBER:mailto:sometwo@example.com END:VCARD OUT; @@ -236,6 +240,8 @@ public function testConvertGroupCard() BEGIN:VCARD VERSION:3.0 X-ADDRESSBOOKSERVER-KIND:GROUP +X-ADDRESSBOOKSERVER-MEMBER:mailto:someone@example.com +X-ADDRESSBOOKSERVER-MEMBER:mailto:sometwo@example.com END:VCARD OUT; From cd769888c0e4836172c3b71a1d53f01001505079 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 Dec 2021 09:31:43 +0300 Subject: [PATCH 119/165] Handle Vobjects without closing tag There are cases when objects do not have closing tags (for example, END: VCALENDAR), this fix solves this issue. --- lib/Parser/MimeDir.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/Parser/MimeDir.php b/lib/Parser/MimeDir.php index 219c5f753..92336feea 100644 --- a/lib/Parser/MimeDir.php +++ b/lib/Parser/MimeDir.php @@ -167,7 +167,11 @@ protected function parseDocument() while (true) { // Reading until we hit END: - $line = $this->readLine(); + try { + $line = $this->readLine(); + } catch (EofException $oEx) { + $line = 'END:'.$this->root->name; + } if ('END:' === strtoupper(substr($line, 0, 4))) { break; } From ccaec1c379042be77cfad69bfcd79f072041711c Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Wed, 17 Aug 2022 21:24:08 +0545 Subject: [PATCH 120/165] Adjust test for VCALENDAR with missing END --- tests/VObject/ReaderTest.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/VObject/ReaderTest.php b/tests/VObject/ReaderTest.php index 6f2cbb77d..cc2838a1a 100644 --- a/tests/VObject/ReaderTest.php +++ b/tests/VObject/ReaderTest.php @@ -114,11 +114,16 @@ public function testReadMappedPropertyGrouped() $this->assertEquals('20110529', $result->getValue()); } - public function testReadBrokenLine() + public function testReadMissingEnd() { - $this->expectException(ParseException::class); - $data = "BEGIN:VCALENDAR\r\nPROPNAME;propValue"; + $data = "BEGIN:VCALENDAR\r\nPROPNAME:propValue"; $result = Reader::read($data); + $this->assertInstanceOf(Component::class, $result); + $this->assertEquals('VCALENDAR', $result->name); + $this->assertEquals(1, count($result->children())); + $this->assertInstanceOf(Property::class, $result->children()[0]); + $this->assertEquals('PROPNAME', $result->children()[0]->name); + $this->assertEquals('propValue', $result->children()[0]->getValue()); } public function testReadPropertyInComponent() From 216e59590f90f5f07ada7002fcfd0127cc85124d Mon Sep 17 00:00:00 2001 From: Kay Lukas Date: Wed, 28 Nov 2018 15:28:32 +0100 Subject: [PATCH 121/165] Fix bug in by year day --- lib/Recur/RRuleIterator.php | 7 +-- tests/VObject/Recur/RRuleIteratorTest.php | 59 +++++++++++++++-------- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index da788a126..4f0e9070d 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -602,11 +602,12 @@ protected function nextYearly() // loop through all YearDay and Days to check all the combinations foreach ($this->byYearDay as $byYearDay) { $date = clone $this->currentDate; - $date = $date->setDate($currentYear, 1, 1); if ($byYearDay > 0) { - $date = $date->add(new \DateInterval('P'.$byYearDay.'D')); + $date = $date->setDate($currentYear, 1, 1); + $date = $date->add(new \DateInterval('P'.($byYearDay - 1).'D')); } else { - $date = $date->sub(new \DateInterval('P'.abs($byYearDay).'D')); + $date = $date->setDate($currentYear, 12, 31); + $date = $date->sub(new \DateInterval('P'.abs($byYearDay + 1).'D')); } if ($date > $this->currentDate && in_array($date->format('N'), $dayOffsets)) { diff --git a/tests/VObject/Recur/RRuleIteratorTest.php b/tests/VObject/Recur/RRuleIteratorTest.php index 4c9107ee5..0730489b0 100644 --- a/tests/VObject/Recur/RRuleIteratorTest.php +++ b/tests/VObject/Recur/RRuleIteratorTest.php @@ -526,19 +526,36 @@ public function testYearlyByMonthByDay() ); } + public function testYearlyNewYearsEve() + { + $this->parse( + 'FREQ=YEARLY;COUNT=7;INTERVAL=2;BYYEARDAY=1', + '2011-01-01 03:07:00', + [ + '2011-01-01 03:07:00', + '2013-01-01 03:07:00', + '2015-01-01 03:07:00', + '2017-01-01 03:07:00', + '2019-01-01 03:07:00', + '2021-01-01 03:07:00', + '2023-01-01 03:07:00', + ] + ); + } + public function testYearlyByYearDay() { $this->parse( 'FREQ=YEARLY;COUNT=7;INTERVAL=2;BYYEARDAY=190', - '2011-07-10 03:07:00', + '2011-07-09 03:07:00', [ - '2011-07-10 03:07:00', - '2013-07-10 03:07:00', - '2015-07-10 03:07:00', - '2017-07-10 03:07:00', - '2019-07-10 03:07:00', - '2021-07-10 03:07:00', - '2023-07-10 03:07:00', + '2011-07-09 03:07:00', + '2013-07-09 03:07:00', + '2015-07-09 03:07:00', + '2017-07-09 03:07:00', + '2019-07-09 03:07:00', + '2021-07-09 03:07:00', + '2023-07-09 03:07:00', ] ); } @@ -559,7 +576,7 @@ public function testYearlyByYearDayImmutable() $parser->next(); $item = $parser->current(); - $this->assertEquals($item->format('Y-m-d H:i:s'), '2013-07-10 03:07:00'); + $this->assertEquals($item->format('Y-m-d H:i:s'), '2013-07-09 03:07:00'); } public function testYearlyByYearDayMultiple() @@ -569,13 +586,13 @@ public function testYearlyByYearDayMultiple() '2011-07-10 14:53:11', [ '2011-07-10 14:53:11', - '2011-10-29 14:53:11', - '2014-07-10 14:53:11', - '2014-10-29 14:53:11', - '2017-07-10 14:53:11', - '2017-10-29 14:53:11', - '2020-07-09 14:53:11', - '2020-10-28 14:53:11', + '2011-10-28 14:53:11', + '2014-07-09 14:53:11', + '2014-10-28 14:53:11', + '2017-07-09 14:53:11', + '2017-10-28 14:53:11', + '2020-07-08 14:53:11', + '2020-10-27 14:53:11', ] ); } @@ -587,11 +604,11 @@ public function testYearlyByYearDayByDay() '2001-04-07 14:53:11', [ '2001-04-07 14:53:11', - '2006-04-08 14:53:11', - '2012-04-07 14:53:11', - '2017-04-08 14:53:11', - '2023-04-08 14:53:11', - '2034-04-08 14:53:11', + '2007-04-07 14:53:11', + '2018-04-07 14:53:11', + '2024-04-06 14:53:11', + '2029-04-07 14:53:11', + '2035-04-07 14:53:11', ] ); } From 21631cb1e92b57c0fc2aac8d90bdb544a357204e Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Wed, 17 Aug 2022 21:42:57 +0545 Subject: [PATCH 122/165] Adjust name of test case --- tests/VObject/Recur/RRuleIteratorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/VObject/Recur/RRuleIteratorTest.php b/tests/VObject/Recur/RRuleIteratorTest.php index 0730489b0..5c49964a1 100644 --- a/tests/VObject/Recur/RRuleIteratorTest.php +++ b/tests/VObject/Recur/RRuleIteratorTest.php @@ -526,7 +526,7 @@ public function testYearlyByMonthByDay() ); } - public function testYearlyNewYearsEve() + public function testYearlyNewYearsDay() { $this->parse( 'FREQ=YEARLY;COUNT=7;INTERVAL=2;BYYEARDAY=1', From 408b5913fdc63fab9095fcb77eba839a428bfdf1 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Wed, 17 Aug 2022 22:05:24 +0545 Subject: [PATCH 123/165] Add test cases for large negative BYYEARDAY values that cross 29 Feb --- tests/VObject/Recur/RRuleIteratorTest.php | 47 +++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/VObject/Recur/RRuleIteratorTest.php b/tests/VObject/Recur/RRuleIteratorTest.php index 5c49964a1..db5cee286 100644 --- a/tests/VObject/Recur/RRuleIteratorTest.php +++ b/tests/VObject/Recur/RRuleIteratorTest.php @@ -631,6 +631,53 @@ public function testYearlyByYearDayNegative() ); } + /* + * Verifies that -365 back in the year is usually 1 Jan, but + * in leap years it is 2 Jan. + */ + public function testYearlyByYearDayLargeNegative() + { + $this->parse( + 'FREQ=YEARLY;COUNT=8;BYYEARDAY=-365', + '2001-01-01 14:53:11', + [ + '2001-01-01 14:53:11', + '2002-01-01 14:53:11', + '2003-01-01 14:53:11', + '2004-01-02 14:53:11', + '2005-01-01 14:53:11', + '2006-01-01 14:53:11', + '2007-01-01 14:53:11', + '2008-01-02 14:53:11', + ] + ); + } + + /* + * Verifies that -366 back in the year is 1 Jan in a leap year + * Interestingly, it goes back to 31 Dec of the previous year + * when not a leap year. The spec says that -366 is valid, and + * makes no mention of it being valid only in a leap year, so + * the behavior seems reasonable. + */ + public function testYearlyByYearDayMaxNegative() + { + $this->parse( + 'FREQ=YEARLY;COUNT=8;BYYEARDAY=-366', + '2001-01-01 14:53:11', + [ + '2001-01-01 14:53:11', + '2001-12-31 14:53:11', + '2002-12-31 14:53:11', + '2004-01-01 14:53:11', + '2004-12-31 14:53:11', + '2005-12-31 14:53:11', + '2006-12-31 14:53:11', + '2008-01-01 14:53:11', + ] + ); + } + public function testYearlyByYearDayInvalid390() { $this->expectException(InvalidDataException::class); From 56f41cce81d39853f1512c0baac170288238d392 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Wed, 17 Aug 2022 22:21:44 +0545 Subject: [PATCH 124/165] Prepare 4.5.0 --- CHANGELOG.md | 12 ++++++++++++ lib/Version.php | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa9a6ced9..37bc00f02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,18 @@ ChangeLog ========= +4.5.0 (2022-08-17) +------------------ + +* #579: Update .gitattributes (@cedric-anne) +* #561: PHP 8.1 deprecated support for null values in its APIs (@mstilkerich) +* #571: Fully ignore invalid lines (@heiglandreas) +* #564: Fix infinite loop caused by yearly with bySetPos (@liurxliu) +* #567: Endless loop problem in RRuleIterator::nextDaily (@KristofferFM) +* #466: Add support for MEMBER in a VCard (@sash04ek) +* #559: Handle Vobjects without closing tag (@sash04ek) +* #582: Fix bug in by year day (@KAYLukas) + 4.4.3 (2022-07-15) ------------------ diff --git a/lib/Version.php b/lib/Version.php index 4659730fd..167ac28de 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.4.3'; + const VERSION = '4.5.0'; } From 87037b2ba489d6a5178e23475414c5f3280272da Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Fri, 21 Jan 2022 10:42:42 +0100 Subject: [PATCH 125/165] Modernize code * Require PHP 7.4 * Add typing everywhere possible * Small internal improvements Signed-off-by: Thomas Citharel --- .gitignore | 2 +- .php_cs.dist => .php-cs-fixer.dist.php | 2 +- composer.json | 9 +- lib/BirthdayCalendarGenerator.php | 22 +-- lib/Cli.php | 114 +++++------- lib/Component.php | 127 ++++++------- lib/Component/Available.php | 18 +- lib/Component/VAlarm.php | 32 ++-- lib/Component/VAvailability.php | 22 +-- lib/Component/VCalendar.php | 66 +++---- lib/Component/VCard.php | 80 +++----- lib/Component/VEvent.php | 25 ++- lib/Component/VFreeBusy.php | 13 +- lib/Component/VJournal.php | 14 +- lib/Component/VTimeZone.php | 11 +- lib/Component/VTodo.php | 31 ++-- lib/DateTimeParser.php | 144 +++++++-------- lib/Document.php | 83 +++------ lib/FreeBusyData.php | 10 +- lib/FreeBusyGenerator.php | 42 +++-- lib/ITip/Broker.php | 86 ++++----- lib/ITip/Message.php | 46 ++--- lib/Node.php | 46 ++--- lib/PHPUnitAssertions.php | 3 +- lib/Parameter.php | 60 ++---- lib/Parser/Json.php | 30 +-- lib/Parser/MimeDir.php | 95 +++++----- lib/Parser/Parser.php | 21 +-- lib/Parser/XML.php | 69 +++---- lib/Parser/XML/Element/KeyValue.php | 6 +- lib/Property.php | 171 ++++++++---------- lib/Property/Binary.php | 27 +-- lib/Property/Boolean.php | 16 +- lib/Property/FlatText.php | 10 +- lib/Property/FloatValue.php | 26 +-- lib/Property/ICalendar/CalAddress.php | 12 +- lib/Property/ICalendar/DateTime.php | 82 +++++---- lib/Property/ICalendar/Duration.php | 22 +-- lib/Property/ICalendar/Period.php | 27 +-- lib/Property/ICalendar/Recur.php | 54 +++--- lib/Property/IntegerValue.php | 18 +- lib/Property/Text.php | 92 +++++----- lib/Property/Time.php | 17 +- lib/Property/Unknown.php | 8 +- lib/Property/Uri.php | 20 +- lib/Property/UtcOffset.php | 18 +- lib/Property/VCard/Date.php | 6 +- lib/Property/VCard/DateAndOrTime.php | 45 ++--- lib/Property/VCard/DateTime.php | 4 +- lib/Property/VCard/LanguageTag.php | 12 +- lib/Property/VCard/PhoneNumber.php | 6 +- lib/Property/VCard/TimeStamp.php | 17 +- lib/Reader.php | 35 ++-- lib/Recur/EventIterator.php | 108 ++++++----- lib/Recur/RDateIterator.php | 39 ++-- lib/Recur/RRuleIterator.php | 104 ++++------- lib/Splitter/ICalendar.php | 21 +-- lib/Splitter/SplitterInterface.php | 6 +- lib/Splitter/VCard.php | 13 +- lib/StringUtil.php | 12 +- lib/TimeZoneUtil.php | 142 +-------------- .../FindFromTimezoneIdentifier.php | 4 +- lib/TimezoneGuesser/FindFromTimezoneMap.php | 8 +- lib/TimezoneGuesser/GuessFromMsTzId.php | 4 +- lib/UUIDUtil.php | 20 +- lib/VCardConverter.php | 41 +++-- lib/Version.php | 2 +- lib/Writer.php | 14 +- tests/VObject/ComponentTest.php | 63 ++++--- tests/VObject/DateTimeParserTest.php | 20 +- tests/VObject/DocumentTest.php | 5 +- tests/VObject/ITip/BrokerNewEventTest.php | 14 +- tests/VObject/ITip/BrokerTester.php | 19 +- tests/VObject/Property/BooleanTest.php | 3 + tests/VObject/PropertyTest.php | 10 +- tests/VObject/ReaderTest.php | 2 +- .../VObject/Recur/EventIterator/MainTest.php | 72 +++++++- tests/VObject/StringUtilTest.php | 6 +- tests/VObject/VCardConverterTest.php | 94 ++++++++-- tests/phpunit.xml | 11 +- 80 files changed, 1295 insertions(+), 1636 deletions(-) rename .php_cs.dist => .php-cs-fixer.dist.php (79%) diff --git a/.gitignore b/.gitignore index 82b7dad3f..d0e5169ac 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,4 @@ tests/temp tests/.phpunit.result.cache # Development stuff -.php_cs.cache +.php-cs-fixer.cache \ No newline at end of file diff --git a/.php_cs.dist b/.php-cs-fixer.dist.php similarity index 79% rename from .php_cs.dist rename to .php-cs-fixer.dist.php index c5c78a971..eb32278a0 100644 --- a/.php_cs.dist +++ b/.php-cs-fixer.dist.php @@ -1,6 +1,6 @@ getFinder() ->exclude('vendor') ->in(__DIR__); diff --git a/composer.json b/composer.json index b745b1fa6..fcbadf31e 100644 --- a/composer.json +++ b/composer.json @@ -32,15 +32,16 @@ "homepage" : "http://sabre.io/vobject/", "license" : "BSD-3-Clause", "require" : { - "php" : "^7.1 || ^8.0", + "php" : "^7.4 || ^8.0", "ext-mbstring" : "*", + "ext-json" : "*", "sabre/xml" : "^2.1" }, "require-dev" : { - "friendsofphp/php-cs-fixer": "~2.17.1", + "friendsofphp/php-cs-fixer": "^3.5.0", "phpunit/phpunit" : "^7.5 || ^8.5 || ^9.0", "phpunit/php-invoker" : "^2.0 || ^3.1", - "phpstan/phpstan": "^0.12" + "phpstan/phpstan": "^1.4.2" }, "suggest" : { "hoa/bench" : "If you would like to run the benchmark scripts" @@ -90,7 +91,7 @@ }, "scripts": { "phpstan": [ - "phpstan analyse lib tests" + "phpstan analyse lib tests --memory-limit 1G" ], "cs-fixer": [ "php-cs-fixer fix" diff --git a/lib/BirthdayCalendarGenerator.php b/lib/BirthdayCalendarGenerator.php index fade50e16..1d17353b5 100644 --- a/lib/BirthdayCalendarGenerator.php +++ b/lib/BirthdayCalendarGenerator.php @@ -2,7 +2,10 @@ namespace Sabre\VObject; +use DateTime; +use InvalidArgumentException; use Sabre\VObject\Component\VCalendar; +use Sabre\VObject\Component\VEvent; /** * This class generates birthday calendars. @@ -24,7 +27,7 @@ class BirthdayCalendarGenerator * Default year. * Used for dates without a year. */ - const DEFAULT_YEAR = 2000; + public const DEFAULT_YEAR = 2000; /** * Output format for the SUMMARY. @@ -56,7 +59,7 @@ public function __construct($objects = null) * * @param mixed $objects */ - public function setObjects($objects) + public function setObjects($objects): void { if (!is_array($objects)) { $objects = [$objects]; @@ -67,34 +70,30 @@ public function setObjects($objects) if (is_string($object)) { $vObj = Reader::read($object); if (!$vObj instanceof Component\VCard) { - throw new \InvalidArgumentException('String could not be parsed as \\Sabre\\VObject\\Component\\VCard by setObjects'); + throw new InvalidArgumentException('String could not be parsed as \\Sabre\\VObject\\Component\\VCard by setObjects'); } $this->objects[] = $vObj; } elseif ($object instanceof Component\VCard) { $this->objects[] = $object; } else { - throw new \InvalidArgumentException('You can only pass strings or \\Sabre\\VObject\\Component\\VCard arguments to setObjects'); + throw new InvalidArgumentException('You can only pass strings or \\Sabre\\VObject\\Component\\VCard arguments to setObjects'); } } } /** * Sets the output format for the SUMMARY. - * - * @param string $format */ - public function setFormat($format) + public function setFormat(string $format): void { $this->format = $format; } /** * Parses the input data and returns a VCALENDAR. - * - * @return Component/VCalendar */ - public function getResult() + public function getResult(): VCalendar { $calendar = new VCalendar(); @@ -142,9 +141,10 @@ public function getResult() } // Create event. + /** @var VEvent $event */ $event = $calendar->add('VEVENT', [ 'SUMMARY' => sprintf($this->format, $object->FN->getValue()), - 'DTSTART' => new \DateTime($object->BDAY->getValue()), + 'DTSTART' => new DateTime($object->BDAY->getValue()), 'RRULE' => 'FREQ=YEARLY', 'TRANSP' => 'TRANSPARENT', ]); diff --git a/lib/Cli.php b/lib/Cli.php index 3bde16f9c..987665afa 100644 --- a/lib/Cli.php +++ b/lib/Cli.php @@ -2,7 +2,12 @@ namespace Sabre\VObject; +use Exception; use InvalidArgumentException; +use Sabre\VObject\Component\VCard; +use Sabre\VObject\Parser\Json; +use Sabre\VObject\Parser\MimeDir; +use Sabre\VObject\Parser\Parser; /** * This is the CLI interface for sabre-vobject. @@ -20,13 +25,6 @@ class Cli */ protected $quiet = false; - /** - * Help display. - * - * @var bool - */ - protected $showHelp = false; - /** * Whether to spit out 'mimedir' or 'json' format. * @@ -92,10 +90,8 @@ class Cli /** * Main function. - * - * @return int */ - public function main(array $argv) + public function main(array $argv): int { // @codeCoverageIgnoreStart // We cannot easily test this, so we'll skip it. Pretty basic anyway. @@ -130,7 +126,6 @@ public function main(array $argv) $this->showHelp(); return 0; - break; case 'format': switch ($value) { // jcard/jcal documents @@ -218,7 +213,7 @@ public function main(array $argv) $command = $positional[0]; $this->inputPath = $positional[1]; - $this->outputPath = isset($positional[2]) ? $positional[2] : '-'; + $this->outputPath = $positional[2] ?? '-'; if ('-' !== $this->outputPath) { $this->stdout = fopen($this->outputPath, 'w'); @@ -250,7 +245,7 @@ public function main(array $argv) } } catch (EofException $e) { // end of file - } catch (\Exception $e) { + } catch (Exception $e) { $this->log('Error: '.$e->getMessage(), 'red'); return 2; @@ -262,7 +257,7 @@ public function main(array $argv) /** * Shows the help message. */ - protected function showHelp() + protected function showHelp(): void { $this->log('Usage:', 'yellow'); $this->log(' vobject [options] command [arguments]'); @@ -306,10 +301,8 @@ protected function showHelp() /** * Validates a VObject file. - * - * @return int */ - protected function validate(Component $vObj) + protected function validate(Component $vObj): int { $returnCode = 0; @@ -346,10 +339,8 @@ protected function validate(Component $vObj) /** * Repairs a VObject file. - * - * @return int */ - protected function repair(Component $vObj) + protected function repair(Component $vObj): int { $returnCode = 0; @@ -387,12 +378,8 @@ protected function repair(Component $vObj) /** * Converts a vObject file to a new format. - * - * @param Component $vObj - * - * @return int */ - protected function convert($vObj) + protected function convert(Component $vObj): int { $json = false; $convertVersion = null; @@ -431,9 +418,10 @@ protected function convert($vObj) } if ($forceInput && $vObj->name !== $forceInput) { - throw new \Exception('You cannot convert a '.strtolower($vObj->name).' to '.$this->format); + throw new Exception('You cannot convert a '.strtolower($vObj->name).' to '.$this->format); } if ($convertVersion) { + /** @var VCard $vObj */ $vObj = $vObj->convert($convertVersion); } if ($json) { @@ -451,22 +439,18 @@ protected function convert($vObj) /** * Colorizes a file. - * - * @param Component $vObj */ - protected function color($vObj) + protected function color(Component $vObj): int { $this->serializeComponent($vObj); + + return 0; } /** * Returns an ansi color string for a color name. - * - * @param string $color - * - * @return string */ - protected function colorize($color, $str, $resetTo = 'default') + protected function colorize(string $color, string $str, string $resetTo = 'default'): string { $colors = [ 'cyan' => '1;36', @@ -483,16 +467,13 @@ protected function colorize($color, $str, $resetTo = 'default') /** * Writes out a string in specific color. - * - * @param string $color - * @param string $str */ - protected function cWrite($color, $str) + protected function cWrite(string $color, string $str): void { fwrite($this->stdout, $this->colorize($color, $str)); } - protected function serializeComponent(Component $vObj) + protected function serializeComponent(Component $vObj): void { $this->cWrite('cyan', 'BEGIN'); $this->cWrite('red', ':'); @@ -513,42 +494,39 @@ protected function serializeComponent(Component $vObj) * * @return int */ - $sortScore = function ($key, $array) { + $sortScore = function (int $key, array $array): ?int { if ($array[$key] instanceof Component) { // We want to encode VTIMEZONE first, this is a personal // preference. if ('VTIMEZONE' === $array[$key]->name) { $score = 300000000; - - return $score + $key; } else { $score = 400000000; - - return $score + $key; } - } else { - // Properties get encoded first - // VCARD version 4.0 wants the VERSION property to appear first - if ($array[$key] instanceof Property) { - if ('VERSION' === $array[$key]->name) { - $score = 100000000; - - return $score + $key; - } else { - // All other properties - $score = 200000000; - return $score + $key; - } + return $score + $key; + } + // Properties get encoded first + // VCARD version 4.0 wants the VERSION property to appear first + if ($array[$key] instanceof Property) { + if ('VERSION' === $array[$key]->name) { + $score = 100000000; + } else { + // All other properties + $score = 200000000; } + + return $score + $key; } + + return 0; }; $children = $vObj->children(); $tmp = $children; uksort( $children, - function ($a, $b) use ($sortScore, $tmp) { + function ($a, $b) use ($sortScore, $tmp): int { $sA = $sortScore($a, $tmp); $sB = $sortScore($b, $tmp); @@ -572,7 +550,7 @@ function ($a, $b) use ($sortScore, $tmp) { /** * Colorizes a property. */ - protected function serializeProperty(Property $property) + protected function serializeProperty(Property $property): void { if ($property->group) { $this->cWrite('default', $property->group); @@ -630,7 +608,7 @@ protected function serializeProperty(Property $property) /** * Parses the list of arguments. */ - protected function parseArguments(array $argv) + protected function parseArguments(array $argv): array { $positional = []; $options = []; @@ -664,14 +642,16 @@ protected function parseArguments(array $argv) return [$options, $positional]; } - protected $parser; + protected ?Parser $parser = null; /** * Reads the input file. * - * @return Component + * @throws EofException + * @throws ParseException + * @throws InvalidDataException */ - protected function readInput() + protected function readInput(): ?Document { if (!$this->parser) { if ('-' !== $this->inputPath) { @@ -679,9 +659,9 @@ protected function readInput() } if ('mimedir' === $this->inputFormat) { - $this->parser = new Parser\MimeDir($this->stdin, ($this->forgiving ? Reader::OPTION_FORGIVING : 0)); + $this->parser = new MimeDir($this->stdin, ($this->forgiving ? Reader::OPTION_FORGIVING : 0)); } else { - $this->parser = new Parser\Json($this->stdin, ($this->forgiving ? Reader::OPTION_FORGIVING : 0)); + $this->parser = new Json($this->stdin, ($this->forgiving ? Reader::OPTION_FORGIVING : 0)); } } @@ -690,10 +670,8 @@ protected function readInput() /** * Sends a message to STDERR. - * - * @param string $msg */ - protected function log($msg, $color = 'default') + protected function log(string $msg, string $color = 'default'): void { if (!$this->quiet) { if ('default' !== $color) { diff --git a/lib/Component.php b/lib/Component.php index a929387a3..9a54d4ea8 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -2,6 +2,10 @@ namespace Sabre\VObject; +use InvalidArgumentException; +use ReturnTypeWillChange; +use RuntimeException; +use Sabre\VObject; use Sabre\Xml; /** @@ -13,6 +17,8 @@ * @copyright Copyright (C) fruux GmbH (https://fruux.com/) * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License + * + * @property VObject\Property\FlatText UID */ class Component extends Node { @@ -46,7 +52,7 @@ class Component extends Node * @param string|null $name such as VCALENDAR, VEVENT * @param bool $defaults */ - public function __construct(Document $root, $name, array $children = [], $defaults = true) + public function __construct(Document $root, ?string $name, array $children = [], bool $defaults = true) { $this->name = isset($name) ? strtoupper($name) : ''; $this->root = $root; @@ -97,25 +103,24 @@ public function __construct(Document $root, $name, array $children = [], $defaul * add($name, $value, array $parameters = []) // Adds a new property * add($name, array $children = []) // Adds a new component * by name. - * - * @return Node */ - public function add() + public function add(): Node { $arguments = func_get_args(); if ($arguments[0] instanceof Node) { if (isset($arguments[1])) { - throw new \InvalidArgumentException('The second argument must not be specified, when passing a VObject Node'); + throw new InvalidArgumentException('The second argument must not be specified, when passing a VObject Node'); } $arguments[0]->parent = $this; $newNode = $arguments[0]; } elseif (is_string($arguments[0])) { $newNode = call_user_func_array([$this->root, 'create'], $arguments); } else { - throw new \InvalidArgumentException('The first argument must either be a \\Sabre\\VObject\\Node or a string'); + throw new InvalidArgumentException('The first argument must either be a \\Sabre\\VObject\\Node or a string'); } + /** @var Component|Property|Parameter $newNode */ $name = $newNode->name; if (isset($this->children[$name])) { $this->children[$name][] = $newNode; @@ -135,6 +140,8 @@ public function add() * exact item will be removed. * * @param string|Property|Component $item + * + * @return void */ public function remove($item) { @@ -161,17 +168,15 @@ public function remove($item) } } - throw new \InvalidArgumentException('The item you passed to remove() was not a child of this component'); + throw new InvalidArgumentException('The item you passed to remove() was not a child of this component'); } } /** * Returns a flat list of all the properties and components in this * component. - * - * @return array */ - public function children() + public function children(): array { $result = []; foreach ($this->children as $childGroup) { @@ -184,10 +189,8 @@ public function children() /** * This method only returns a list of sub-components. Properties are * ignored. - * - * @return array */ - public function getComponents() + public function getComponents(): array { $result = []; @@ -211,12 +214,8 @@ public function getComponents() * search for a property in a specific group, you can select on the entire * string ("HOME.EMAIL"). If you want to search on a specific property that * has not been assigned a group, specify ".EMAIL". - * - * @param string $name - * - * @return array */ - public function select($name) + public function select(string $name): array { $group = null; $name = strtoupper($name); @@ -228,7 +227,7 @@ public function select($name) } if (!is_null($name)) { - $result = isset($this->children[$name]) ? $this->children[$name] : []; + $result = $this->children[$name] ?? []; if (is_null($group)) { return $result; @@ -260,10 +259,8 @@ function ($child) use ($group) { /** * Turns the object back into a serialized blob. - * - * @return string */ - public function serialize() + public function serialize(): string { $str = 'BEGIN:'.$this->name."\r\n"; @@ -282,42 +279,39 @@ public function serialize() * * @return int */ - $sortScore = function ($key, $array) { + $sortScore = function (int $key, array $array): ?int { if ($array[$key] instanceof Component) { // We want to encode VTIMEZONE first, this is a personal // preference. if ('VTIMEZONE' === $array[$key]->name) { $score = 300000000; - - return $score + $key; } else { $score = 400000000; - - return $score + $key; } - } else { - // Properties get encoded first - // VCARD version 4.0 wants the VERSION property to appear first - if ($array[$key] instanceof Property) { - if ('VERSION' === $array[$key]->name) { - $score = 100000000; - - return $score + $key; - } else { - // All other properties - $score = 200000000; - - return $score + $key; - } + + return $score + $key; + } + // Properties get encoded first + // VCARD version 4.0 wants the VERSION property to appear first + if ($array[$key] instanceof Property) { + if ('VERSION' === $array[$key]->name) { + $score = 100000000; + } else { + // All other properties + $score = 200000000; } + + return $score + $key; } + + return 0; }; $children = $this->children(); $tmp = $children; uksort( $children, - function ($a, $b) use ($sortScore, $tmp) { + function ($a, $b) use ($sortScore, $tmp): int { $sA = $sortScore($a, $tmp); $sB = $sortScore($b, $tmp); @@ -336,11 +330,9 @@ function ($a, $b) use ($sortScore, $tmp) { /** * This method returns an array, with the representation as it should be * encoded in JSON. This is used to create jCard or jCal documents. - * - * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + #[ReturnTypeWillChange] + public function jsonSerialize(): array { $components = []; $properties = []; @@ -368,7 +360,7 @@ public function jsonSerialize() * * @param Xml\Writer $writer XML writer */ - public function xmlSerialize(Xml\Writer $writer) + public function xmlSerialize(Xml\Writer $writer): void { $components = []; $properties = []; @@ -410,10 +402,8 @@ public function xmlSerialize(Xml\Writer $writer) /** * This method should return a list of default property values. - * - * @return array */ - protected function getDefaults() + protected function getDefaults(): array { return []; } @@ -430,19 +420,17 @@ protected function getDefaults() * * $event = $calendar->VEVENT; * - * @param string $name - * - * @return Property|null + * @return Property|Component */ - public function __get($name) + public function __get(string $name): ?Node { if ('children' === $name) { - throw new \RuntimeException('Starting sabre/vobject 4.0 the children property is now protected. You should use the children() method instead'); + throw new RuntimeException('Starting sabre/vobject 4.0 the children property is now protected. You should use the children() method instead'); } $matches = $this->select($name); if (0 === count($matches)) { - return; + return null; } else { $firstMatch = current($matches); /* @var $firstMatch Property */ @@ -454,12 +442,8 @@ public function __get($name) /** * This method checks if a sub-element with the specified name exists. - * - * @param string $name - * - * @return bool */ - public function __isset($name) + public function __isset(string $name): bool { $matches = $this->select($name); @@ -475,10 +459,9 @@ public function __isset($name) * If the item already exists, it will be removed. If you want to add * a new item with the same name, always use the add() method. * - * @param string $name - * @param mixed $value + * @param mixed $value */ - public function __set($name, $value) + public function __set(string $name, $value): void { $name = strtoupper($name); $this->remove($name); @@ -492,10 +475,8 @@ public function __set($name, $value) /** * Removes all properties and components within this component with the * specified name. - * - * @param string $name */ - public function __unset($name) + public function __unset(string $name): void { $this->remove($name); } @@ -536,10 +517,8 @@ public function __clone() * * See the VEVENT implementation for getValidationRules for a more complex * example. - * - * @var array */ - public function getValidationRules() + public function getValidationRules(): array { return []; } @@ -563,12 +542,8 @@ public function getValidationRules() * 1 - The issue was repaired (only happens if REPAIR was turned on). * 2 - A warning. * 3 - An error. - * - * @param int $options - * - * @return array */ - public function validate($options = 0) + public function validate(int $options = 0): array { $rules = $this->getValidationRules(); $defaults = $this->getDefaults(); @@ -659,7 +634,7 @@ public function validate($options = 0) * It's intended to remove all circular references, so PHP can easily clean * it up. */ - public function destroy() + public function destroy(): void { parent::destroy(); foreach ($this->children as $childGroup) { diff --git a/lib/Component/Available.php b/lib/Component/Available.php index 5510b9e0a..b3ba40b07 100644 --- a/lib/Component/Available.php +++ b/lib/Component/Available.php @@ -13,6 +13,10 @@ * @copyright Copyright (C) fruux GmbH (https://fruux.com/) * @author Ivan Enderlin * @license http://sabre.io/license/ Modified BSD License + * + * @property VObject\Property\ICalendar\DateTime DTSTART + * @property VObject\Property\ICalendar\DateTime DTEND + * @property VObject\Property\ICalendar\Duration DURATION */ class Available extends VObject\Component { @@ -26,9 +30,9 @@ class Available extends VObject\Component * If either the start or end is 'unbounded' its value will be null * instead. * - * @return array + * @throws VObject\InvalidDataException */ - public function getEffectiveStartEnd() + public function getEffectiveStartEnd(): array { $effectiveStart = $this->DTSTART->getDateTime(); if (isset($this->DTEND)) { @@ -52,10 +56,8 @@ public function getEffectiveStartEnd() * * + - Must appear at least once. * * * - Can appear any number of times. * * ? - May appear, but not more than once. - * - * @var array */ - public function getValidationRules() + public function getValidationRules(): array { return [ 'UID' => 1, @@ -101,12 +103,8 @@ public function getValidationRules() * 1 - The issue was repaired (only happens if REPAIR was turned on). * 2 - A warning. * 3 - An error. - * - * @param int $options - * - * @return array */ - public function validate($options = 0) + public function validate(int $options = 0): array { $result = parent::validate($options); diff --git a/lib/Component/VAlarm.php b/lib/Component/VAlarm.php index bd00eb600..a865f2a41 100644 --- a/lib/Component/VAlarm.php +++ b/lib/Component/VAlarm.php @@ -2,6 +2,7 @@ namespace Sabre\VObject\Component; +use DatePeriod; use DateTimeImmutable; use DateTimeInterface; use Sabre\VObject; @@ -15,6 +16,12 @@ * @copyright Copyright (C) fruux GmbH (https://fruux.com/) * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License + * + * @property VObject\Property\ICalendar\DateTime DTSTART + * @property VObject\Property\ICalendar\DateTime DTEND + * @property VObject\Property\ICalendar\Duration DURATION + * @property VObject\Property\ICalendar\Duration|VObject\Property\ICalendar\DateTime TRIGGER + * @property VObject\Property\IntegerValue REPEAT */ class VAlarm extends VObject\Component { @@ -23,15 +30,16 @@ class VAlarm extends VObject\Component * * This ignores repeated alarm, only the first trigger is returned. * - * @return DateTimeImmutable + * @throws InvalidDataException */ - public function getEffectiveTriggerTime() + public function getEffectiveTriggerTime(): DateTimeImmutable { $trigger = $this->TRIGGER; - if (!isset($trigger['VALUE']) || 'DURATION' === strtoupper($trigger['VALUE'])) { + if (!isset($trigger['VALUE']) || ($trigger['VALUE'] && 'DURATION' === strtoupper($trigger['VALUE']))) { $triggerDuration = VObject\DateTimeParser::parseDuration($this->TRIGGER); $related = (isset($trigger['RELATED']) && 'END' == strtoupper($trigger['RELATED'])) ? 'END' : 'START'; + /** @var VEvent|VTodo $parentComponent */ $parentComponent = $this->parent; if ('START' === $related) { if ('VTODO' === $parentComponent->name) { @@ -41,7 +49,6 @@ public function getEffectiveTriggerTime() } $effectiveTrigger = $parentComponent->$propName->getDateTime(); - $effectiveTrigger = $effectiveTrigger->add($triggerDuration); } else { if ('VTODO' === $parentComponent->name) { $endProp = 'DUE'; @@ -53,17 +60,15 @@ public function getEffectiveTriggerTime() if (isset($parentComponent->$endProp)) { $effectiveTrigger = $parentComponent->$endProp->getDateTime(); - $effectiveTrigger = $effectiveTrigger->add($triggerDuration); } elseif (isset($parentComponent->DURATION)) { $effectiveTrigger = $parentComponent->DTSTART->getDateTime(); $duration = VObject\DateTimeParser::parseDuration($parentComponent->DURATION); $effectiveTrigger = $effectiveTrigger->add($duration); - $effectiveTrigger = $effectiveTrigger->add($triggerDuration); } else { $effectiveTrigger = $parentComponent->DTSTART->getDateTime(); - $effectiveTrigger = $effectiveTrigger->add($triggerDuration); } } + $effectiveTrigger = $effectiveTrigger->add($triggerDuration); } else { $effectiveTrigger = $trigger->getDateTime(); } @@ -78,12 +83,9 @@ public function getEffectiveTriggerTime() * The rules used to determine if an event falls within the specified * time-range is based on the CalDAV specification. * - * @param DateTime $start - * @param DateTime $end - * - * @return bool + * @throws InvalidDataException */ - public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) + public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end): bool { $effectiveTrigger = $this->getEffectiveTriggerTime(); @@ -94,7 +96,7 @@ public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) $repeat = 1; } - $period = new \DatePeriod($effectiveTrigger, $duration, (int) $repeat); + $period = new DatePeriod($effectiveTrigger, $duration, (int) $repeat); foreach ($period as $occurrence) { if ($start <= $occurrence && $end > $occurrence) { @@ -120,10 +122,8 @@ public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) * * + - Must appear at least once. * * * - Can appear any number of times. * * ? - May appear, but not more than once. - * - * @var array */ - public function getValidationRules() + public function getValidationRules(): array { return [ 'ACTION' => 1, diff --git a/lib/Component/VAvailability.php b/lib/Component/VAvailability.php index 04ec38dcb..b3cd6d96d 100644 --- a/lib/Component/VAvailability.php +++ b/lib/Component/VAvailability.php @@ -14,6 +14,10 @@ * @copyright Copyright (C) fruux GmbH (https://fruux.com/) * @author Ivan Enderlin * @license http://sabre.io/license/ Modified BSD License + * + * @property VObject\Property\ICalendar\DateTime DTSTART + * @property VObject\Property\ICalendar\DateTime DTEND + * @property VObject\Property\ICalendar\Duration DURATION */ class VAvailability extends VObject\Component { @@ -26,9 +30,9 @@ class VAvailability extends VObject\Component * * https://tools.ietf.org/html/draft-daboo-calendar-availability-05#section-3.1 * - * @return bool + * @throws VObject\InvalidDataException */ - public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) + public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end): bool { list($effectiveStart, $effectiveEnd) = $this->getEffectiveStartEnd(); @@ -48,9 +52,9 @@ public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) * If either the start or end is 'unbounded' its value will be null * instead. * - * @return array + * @throws VObject\InvalidDataException */ - public function getEffectiveStartEnd() + public function getEffectiveStartEnd(): array { $effectiveStart = null; $effectiveEnd = null; @@ -79,10 +83,8 @@ public function getEffectiveStartEnd() * * + - Must appear at least once. * * * - Can appear any number of times. * * ? - May appear, but not more than once. - * - * @var array */ - public function getValidationRules() + public function getValidationRules(): array { return [ 'UID' => 1, @@ -127,12 +129,8 @@ public function getValidationRules() * 1 - The issue was repaired (only happens if REPAIR was turned on). * 2 - A warning. * 3 - An error. - * - * @param int $options - * - * @return array */ - public function validate($options = 0) + public function validate(int $options = 0): array { $result = parent::validate($options); diff --git a/lib/Component/VCalendar.php b/lib/Component/VCalendar.php index 4db318135..da7a211f9 100644 --- a/lib/Component/VCalendar.php +++ b/lib/Component/VCalendar.php @@ -19,6 +19,11 @@ * @copyright Copyright (C) fruux GmbH (https://fruux.com/) * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License + * + * @property VEvent VEVENT + * @property VJournal VJOURNAL + * @property VObject\Property\Text ORG + * @property VObject\Property\FlatText METHOD */ class VCalendar extends VObject\Document { @@ -26,17 +31,13 @@ class VCalendar extends VObject\Document * The default name for this component. * * This should be 'VCALENDAR' or 'VCARD'. - * - * @var string */ - public static $defaultName = 'VCALENDAR'; + public static ?string $defaultName = 'VCALENDAR'; /** * This is a list of components, and which classes they should map to. - * - * @var array */ - public static $componentMap = [ + public static array $componentMap = [ 'VCALENDAR' => self::class, 'VALARM' => VAlarm::class, 'VEVENT' => VEvent::class, @@ -50,10 +51,8 @@ class VCalendar extends VObject\Document /** * List of value-types, and which classes they map to. - * - * @var array */ - public static $valueMap = [ + public static array $valueMap = [ 'BINARY' => VObject\Property\Binary::class, 'BOOLEAN' => VObject\Property\Boolean::class, 'CAL-ADDRESS' => VObject\Property\ICalendar\CalAddress::class, @@ -73,10 +72,8 @@ class VCalendar extends VObject\Document /** * List of properties, and which classes they map to. - * - * @var array */ - public static $propertyMap = [ + public static array $propertyMap = [ // Calendar properties 'CALSCALE' => VObject\Property\FlatText::class, 'METHOD' => VObject\Property\FlatText::class, @@ -154,10 +151,8 @@ class VCalendar extends VObject\Document /** * Returns the current document type. - * - * @return int */ - public function getDocumentType() + public function getDocumentType(): int { return self::ICALENDAR20; } @@ -169,13 +164,13 @@ public function getDocumentType() * * VTIMEZONE components will always be excluded. * - * @param string $componentName filter by component name + * @param string|null $componentName filter by component name * * @return VObject\Component[] */ - public function getBaseComponents($componentName = null) + public function getBaseComponents(string $componentName = null): array { - $isBaseComponent = function ($component) { + $isBaseComponent = function ($component): bool { if (!$component instanceof VObject\Component) { return false; } @@ -220,13 +215,13 @@ public function getBaseComponents($componentName = null) * * If there is no such component, null will be returned. * - * @param string $componentName filter by component name + * @param string|null $componentName filter by component name * * @return VObject\Component|null */ - public function getBaseComponent($componentName = null) + public function getBaseComponent(string $componentName = null): ?Component { - $isBaseComponent = function ($component) { + $isBaseComponent = function ($component): bool { if (!$component instanceof VObject\Component) { return false; } @@ -276,12 +271,13 @@ public function getBaseComponent($componentName = null) * In addition, this method will cause timezone information to be stripped, * and normalized to UTC. * - * @param DateTimeZone $timeZone reference timezone for floating dates and - * times + * @param DateTimeZone|null $timeZone reference timezone for floating dates and + * times * - * @return VCalendar + * @throws InvalidDataException + * @throws VObject\Recur\MaxInstancesExceededException */ - public function expand(DateTimeInterface $start, DateTimeInterface $end, DateTimeZone $timeZone = null) + public function expand(DateTimeInterface $start, DateTimeInterface $end, DateTimeZone $timeZone = null): VCalendar { $newChildren = []; $recurringEvents = []; @@ -290,7 +286,7 @@ public function expand(DateTimeInterface $start, DateTimeInterface $end, DateTim $timeZone = new DateTimeZone('UTC'); } - $stripTimezones = function (Component $component) use ($timeZone, &$stripTimezones) { + $stripTimezones = function (Component $component) use ($timeZone, &$stripTimezones): Component { foreach ($component->children() as $componentChild) { if ($componentChild instanceof Property\ICalendar\DateTime && $componentChild->hasTime()) { $dt = $componentChild->getDateTimes($timeZone); @@ -356,10 +352,8 @@ public function expand(DateTimeInterface $start, DateTimeInterface $end, DateTim /** * This method should return a list of default property values. - * - * @return array */ - protected function getDefaults() + protected function getDefaults(): array { return [ 'VERSION' => '2.0', @@ -380,10 +374,8 @@ protected function getDefaults() * * + - Must appear at least once. * * * - Can appear any number of times. * * ? - May appear, but not more than once. - * - * @var array */ - public function getValidationRules() + public function getValidationRules(): array { return [ 'PRODID' => 1, @@ -413,12 +405,8 @@ public function getValidationRules() * 1 - The issue was repaired (only happens if REPAIR was turned on). * 2 - A warning. * 3 - An error. - * - * @param int $options - * - * @return array */ - public function validate($options = 0) + public function validate(int $options = 0): array { $warnings = parent::validate($options); @@ -511,10 +499,8 @@ public function validate($options = 0) /** * Returns all components with a specific UID value. - * - * @return array */ - public function getByUID($uid) + public function getByUID($uid): array { return array_filter($this->getComponents(), function ($item) use ($uid) { if (!$itemUid = $item->select('UID')) { diff --git a/lib/Component/VCard.php b/lib/Component/VCard.php index 90a6df72f..335cb6bec 100644 --- a/lib/Component/VCard.php +++ b/lib/Component/VCard.php @@ -2,6 +2,7 @@ namespace Sabre\VObject\Component; +use ArrayAccess; use Sabre\VObject; use Sabre\Xml; @@ -14,6 +15,10 @@ * @copyright Copyright (C) fruux GmbH (https://fruux.com/) * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License + * + * @property VObject\Property\FlatText FN + * @property VObject\Property\Text ORG + * @property VObject\Property\FlatText EMAIL */ class VCard extends VObject\Document { @@ -21,33 +26,25 @@ class VCard extends VObject\Document * The default name for this component. * * This should be 'VCALENDAR' or 'VCARD'. - * - * @var string */ - public static $defaultName = 'VCARD'; + public static ?string $defaultName = 'VCARD'; /** * Caching the version number. - * - * @var int */ - private $version = null; + private ?int $version = null; /** * This is a list of components, and which classes they should map to. - * - * @var array */ - public static $componentMap = [ + public static array $componentMap = [ 'VCARD' => VCard::class, ]; /** * List of value-types, and which classes they map to. - * - * @var array */ - public static $valueMap = [ + public static array $valueMap = [ 'BINARY' => VObject\Property\Binary::class, 'BOOLEAN' => VObject\Property\Boolean::class, 'CONTENT-ID' => VObject\Property\FlatText::class, // vCard 2.1 only @@ -69,10 +66,8 @@ class VCard extends VObject\Document /** * List of properties, and which classes they map to. - * - * @var array */ - public static $propertyMap = [ + public static array $propertyMap = [ // vCard 2.1 properties and up 'N' => VObject\Property\Text::class, 'FN' => VObject\Property\FlatText::class, @@ -140,10 +135,8 @@ class VCard extends VObject\Document /** * Returns the current document type. - * - * @return int */ - public function getDocumentType() + public function getDocumentType(): int { if (!$this->version) { $version = (string) $this->VERSION; @@ -178,11 +171,9 @@ public function getDocumentType() * * If input and output version are identical, a clone is returned. * - * @param int $target - * - * @return VCard + * @throws VObject\InvalidDataException */ - public function convert($target) + public function convert(int $target): VCard { $converter = new VObject\VCardConverter(); @@ -194,7 +185,7 @@ public function convert($target) * * If the VCARD doesn't know its version, 2.1 is assumed. */ - const DEFAULT_VERSION = self::VCARD21; + public const DEFAULT_VERSION = self::VCARD21; /** * Validates the node for correctness. @@ -213,12 +204,8 @@ public function convert($target) * 1 - The issue was repaired (only happens if REPAIR was turned on) * 2 - An inconsequential issue * 3 - A severe issue. - * - * @param int $options - * - * @return array */ - public function validate($options = 0) + public function validate(int $options = 0): array { $warnings = []; @@ -327,10 +314,8 @@ public function validate($options = 0) * * + - Must appear at least once. * * * - Can appear any number of times. * * ? - May appear, but not more than once. - * - * @var array */ - public function getValidationRules() + public function getValidationRules(): array { return [ 'ADR' => '*', @@ -384,12 +369,8 @@ public function getValidationRules() * * If neither of those parameters are specified, the first is returned, if * a field with that name does not exist, null is returned. - * - * @param string $fieldName - * - * @return VObject\Property|null */ - public function preferred($propertyName) + public function preferred(string $propertyName): ?VObject\Property { $preferred = null; $lastPref = 101; @@ -416,26 +397,23 @@ public function preferred($propertyName) * This function will return null if the property does not exist. If there are * multiple properties with the same TYPE value, only one will be returned. * - * @param string $propertyName - * @param string $type - * - * @return VObject\Property|null + * @return ArrayAccess|array|null */ - public function getByType($propertyName, $type) + public function getByType(string $propertyName, string $type) { foreach ($this->select($propertyName) as $field) { if (isset($field['TYPE']) && $field['TYPE']->has($type)) { return $field; } } + + return null; } /** * This method should return a list of default property values. - * - * @return array */ - protected function getDefaults() + protected function getDefaults(): array { return [ 'VERSION' => '4.0', @@ -447,11 +425,9 @@ protected function getDefaults() /** * This method returns an array, with the representation as it should be * encoded in json. This is used to create jCard or jCal documents. - * - * @return array */ #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { // A vcard does not have sub-components, so we're overriding this // method to remove that array element. @@ -470,10 +446,8 @@ public function jsonSerialize() /** * This method serializes the data into XML. This is used to create xCard or * xCal documents. - * - * @param Xml\Writer $writer XML writer */ - public function xmlSerialize(Xml\Writer $writer) + public function xmlSerialize(Xml\Writer $writer): void { $propertiesByGroup = []; @@ -522,12 +496,8 @@ public function xmlSerialize(Xml\Writer $writer) /** * Returns the default class for a property name. - * - * @param string $propertyName - * - * @return string */ - public function getClassNameForPropertyName($propertyName) + public function getClassNameForPropertyName(string $propertyName): string { $className = parent::getClassNameForPropertyName($propertyName); diff --git a/lib/Component/VEvent.php b/lib/Component/VEvent.php index 6ea93ed5e..e6dfc7a3b 100644 --- a/lib/Component/VEvent.php +++ b/lib/Component/VEvent.php @@ -15,6 +15,18 @@ * @copyright Copyright (C) fruux GmbH (https://fruux.com/) * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License + * + * @property VObject\Property\ICalendar\DateTime DTSTART + * @property VObject\Property\ICalendar\DateTime DTEND + * @property VObject\Property\ICalendar\DateTime DTSTAMP + * @property VObject\Property\ICalendar\Duration DURATION + * @property VObject\Property\ICalendar\Recur RRULE + * @property VObject\Property\ICalendar\DateTime[] EXDATE + * @property VObject\Property\ICalendar\DateTime RDATE + * @property VObject\Property\ICalendar\Recur EXRULE + * @property VObject\Property\ICalendar\DateTime RECURRENCE-ID + * @property VObject\Property\FlatText TRANSP + * @property VObject\Property\FlatText STATUS */ class VEvent extends VObject\Component { @@ -25,9 +37,10 @@ class VEvent extends VObject\Component * The rules used to determine if an event falls within the specified * time-range is based on the CalDAV specification. * - * @return bool + * @throws VObject\InvalidDataException + * @throws VObject\Recur\MaxInstancesExceededException */ - public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) + public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end): bool { if ($this->RRULE) { try { @@ -73,10 +86,8 @@ public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) /** * This method should return a list of default property values. - * - * @return array */ - protected function getDefaults() + protected function getDefaults(): array { return [ 'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(), @@ -96,10 +107,8 @@ protected function getDefaults() * * + - Must appear at least once. * * * - Can appear any number of times. * * ? - May appear, but not more than once. - * - * @var array */ - public function getValidationRules() + public function getValidationRules(): array { $hasMethod = isset($this->parent->METHOD); diff --git a/lib/Component/VFreeBusy.php b/lib/Component/VFreeBusy.php index fef418b53..68bc999ed 100644 --- a/lib/Component/VFreeBusy.php +++ b/lib/Component/VFreeBusy.php @@ -2,6 +2,7 @@ namespace Sabre\VObject\Component; +use DateInterval; use DateTimeInterface; use Sabre\VObject; @@ -14,6 +15,8 @@ * @copyright Copyright (C) fruux GmbH (https://fruux.com/) * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License + * + * @property VObject\Property\ICalendar\Period FREEBUSY */ class VFreeBusy extends VObject\Component { @@ -21,9 +24,9 @@ class VFreeBusy extends VObject\Component * Checks based on the contained FREEBUSY information, if a timeslot is * available. * - * @return bool + * @throws VObject\InvalidDataException */ - public function isFree(DateTimeInterface $start, DatetimeInterface $end) + public function isFree(DateTimeInterface $start, DatetimeInterface $end): bool { foreach ($this->select('FREEBUSY') as $freebusy) { // We are only interested in FBTYPE=BUSY (the default), @@ -44,7 +47,7 @@ public function isFree(DateTimeInterface $start, DatetimeInterface $end) $busyStart = VObject\DateTimeParser::parse($busyStart); $busyEnd = VObject\DateTimeParser::parse($busyEnd); - if ($busyEnd instanceof \DateInterval) { + if ($busyEnd instanceof DateInterval) { $busyEnd = $busyStart->add($busyEnd); } @@ -69,10 +72,8 @@ public function isFree(DateTimeInterface $start, DatetimeInterface $end) * * + - Must appear at least once. * * * - Can appear any number of times. * * ? - May appear, but not more than once. - * - * @var array */ - public function getValidationRules() + public function getValidationRules(): array { return [ 'UID' => 1, diff --git a/lib/Component/VJournal.php b/lib/Component/VJournal.php index 9b7f1b873..730b776ab 100644 --- a/lib/Component/VJournal.php +++ b/lib/Component/VJournal.php @@ -13,6 +13,8 @@ * @copyright Copyright (C) fruux GmbH (https://fruux.com/) * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License + * + * @property VObject\Property\ICalendar\DateTime DTSTART */ class VJournal extends VObject\Component { @@ -23,9 +25,9 @@ class VJournal extends VObject\Component * The rules used to determine if an event falls within the specified * time-range is based on the CalDAV specification. * - * @return bool + * @throws VObject\InvalidDataException */ - public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) + public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end): bool { $dtstart = isset($this->DTSTART) ? $this->DTSTART->getDateTime() : null; if ($dtstart) { @@ -52,10 +54,8 @@ public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) * * + - Must appear at least once. * * * - Can appear any number of times. * * ? - May appear, but not more than once. - * - * @var array */ - public function getValidationRules() + public function getValidationRules(): array { return [ 'UID' => 1, @@ -88,10 +88,8 @@ public function getValidationRules() /** * This method should return a list of default property values. - * - * @return array */ - protected function getDefaults() + protected function getDefaults(): array { return [ 'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(), diff --git a/lib/Component/VTimeZone.php b/lib/Component/VTimeZone.php index 21c062377..12332b6db 100644 --- a/lib/Component/VTimeZone.php +++ b/lib/Component/VTimeZone.php @@ -2,6 +2,7 @@ namespace Sabre\VObject\Component; +use DateTimeZone; use Sabre\VObject; /** @@ -13,6 +14,8 @@ * @copyright Copyright (C) fruux GmbH (https://fruux.com/) * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License + * + * @property VObject\Property\FlatText TZID */ class VTimeZone extends VObject\Component { @@ -21,10 +24,8 @@ class VTimeZone extends VObject\Component * * If we can't accurately determine the timezone, this method will return * UTC. - * - * @return \DateTimeZone */ - public function getTimeZone() + public function getTimeZone(): DateTimeZone { return VObject\TimeZoneUtil::getTimeZone((string) $this->TZID, $this->root); } @@ -41,10 +42,8 @@ public function getTimeZone() * * + - Must appear at least once. * * * - Can appear any number of times. * * ? - May appear, but not more than once. - * - * @var array */ - public function getValidationRules() + public function getValidationRules(): array { return [ 'TZID' => 1, diff --git a/lib/Component/VTodo.php b/lib/Component/VTodo.php index 6f022ba6d..a22686cb0 100644 --- a/lib/Component/VTodo.php +++ b/lib/Component/VTodo.php @@ -13,6 +13,19 @@ * @copyright Copyright (C) fruux GmbH (https://fruux.com/) * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License + * + * @property VObject\Property\ICalendar\DateTime DTSTART + * @property VObject\Property\ICalendar\DateTime DTEND + * @property VObject\Property\ICalendar\DateTime DTSTAMP + * @property VObject\Property\ICalendar\Duration DURATION + * @property VObject\Property\ICalendar\Recur RRULE + * @property VObject\Property\ICalendar\DateTime EXDATE + * @property VObject\Property\ICalendar\DateTime RDATE + * @property VObject\Property\ICalendar\Recur EXRULE + * @property VObject\Property\ICalendar\DateTime {'RECURRENCE-ID'} + * @property VObject\Property\ICalendar\DateTime DUE + * @property VObject\Property\ICalendar\DateTime COMPLETED + * @property VObject\Property\ICalendar\DateTime CREATED */ class VTodo extends VObject\Component { @@ -23,9 +36,9 @@ class VTodo extends VObject\Component * The rules used to determine if an event falls within the specified * time-range is based on the CalDAV specification. * - * @return bool + * @throws VObject\InvalidDataException */ - public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) + public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end): bool { $dtstart = isset($this->DTSTART) ? $this->DTSTART->getDateTime() : null; $duration = isset($this->DURATION) ? VObject\DateTimeParser::parseDuration($this->DURATION) : null; @@ -76,10 +89,8 @@ public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) * * + - Must appear at least once. * * * - Can appear any number of times. * * ? - May appear, but not more than once. - * - * @var array */ - public function getValidationRules() + public function getValidationRules(): array { return [ 'UID' => 1, @@ -137,11 +148,9 @@ public function getValidationRules() * 2 - An inconsequential issue * 3 - A severe issue. * - * @param int $options - * - * @return array + * @throws VObject\InvalidDataException */ - public function validate($options = 0) + public function validate(int $options = 0): array { $result = parent::validate($options); if (isset($this->DUE) && isset($this->DTSTART)) { @@ -168,10 +177,8 @@ public function validate($options = 0) /** * This method should return a list of default property values. - * - * @return array */ - protected function getDefaults() + protected function getDefaults(): array { return [ 'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(), diff --git a/lib/DateTimeParser.php b/lib/DateTimeParser.php index 1c253437a..bcd9a828a 100644 --- a/lib/DateTimeParser.php +++ b/lib/DateTimeParser.php @@ -5,6 +5,7 @@ use DateInterval; use DateTimeImmutable; use DateTimeZone; +use Exception; /** * DateTimeParser. @@ -26,12 +27,9 @@ class DateTimeParser * if the non-UTC format is used. The argument is used as a reference, the * returned DateTimeImmutable object will still be in the UTC timezone. * - * @param string $dt - * @param DateTimeZone $tz - * - * @return DateTimeImmutable + * @throws InvalidDataException */ - public static function parseDateTime($dt, DateTimeZone $tz = null) + public static function parseDateTime(string $dt, DateTimeZone $tz = null): DateTimeImmutable { // Format is YYYYMMDD + "T" + hhmmss $result = preg_match('/^([0-9]{4})([0-1][0-9])([0-3][0-9])T([0-2][0-9])([0-5][0-9])([0-5][0-9])([Z]?)$/', $dt, $matches); @@ -46,7 +44,7 @@ public static function parseDateTime($dt, DateTimeZone $tz = null) try { $date = new DateTimeImmutable($matches[1].'-'.$matches[2].'-'.$matches[3].' '.$matches[4].':'.$matches[5].':'.$matches[6], $tz); - } catch (\Exception $e) { + } catch (Exception $e) { throw new InvalidDataException('The supplied iCalendar datetime value is incorrect: '.$dt); } @@ -56,12 +54,9 @@ public static function parseDateTime($dt, DateTimeZone $tz = null) /** * Parses an iCalendar (rfc5545) formatted date and returns a DateTimeImmutable object. * - * @param string $date - * @param DateTimeZone $tz - * - * @return DateTimeImmutable + * @throws InvalidDataException */ - public static function parseDate($date, DateTimeZone $tz = null) + public static function parseDate(string $date, DateTimeZone $tz = null): DateTimeImmutable { // Format is YYYYMMDD $result = preg_match('/^([0-9]{4})([0-1][0-9])([0-3][0-9])$/', $date, $matches); @@ -76,7 +71,7 @@ public static function parseDate($date, DateTimeZone $tz = null) try { $date = new DateTimeImmutable($matches[1].'-'.$matches[2].'-'.$matches[3], $tz); - } catch (\Exception $e) { + } catch (Exception $e) { throw new InvalidDataException('The supplied iCalendar date value is incorrect: '.$date); } @@ -86,29 +81,25 @@ public static function parseDate($date, DateTimeZone $tz = null) /** * Parses an iCalendar (RFC5545) formatted duration value. * - * This method will either return a DateTimeInterval object, or a string - * suitable for strtotime or DateTime::modify. - * - * @param string $duration - * @param bool $asString + * This method will return a DateTimeInterval object * - * @return DateInterval|string + * @throws InvalidDataException + * @throws Exception */ - public static function parseDuration($duration, $asString = false) + public static function parseDuration(string $duration): DateInterval { $result = preg_match('/^(?\+|-)?P((?\d+)W)?((?\d+)D)?(T((?\d+)H)?((?\d+)M)?((?\d+)S)?)?$/', $duration, $matches); if (!$result) { throw new InvalidDataException('The supplied iCalendar duration value is incorrect: '.$duration); } - if (!$asString) { - $invert = false; + $invert = false; - if ('-' === $matches['plusminus']) { - $invert = true; - } + if ('-' === $matches['plusminus']) { + $invert = true; + } - $parts = [ + $parts = [ 'week', 'day', 'hour', @@ -116,50 +107,64 @@ public static function parseDuration($duration, $asString = false) 'second', ]; - foreach ($parts as $part) { - $matches[$part] = isset($matches[$part]) && $matches[$part] ? (int) $matches[$part] : 0; - } - - // We need to re-construct the $duration string, because weeks and - // days are not supported by DateInterval in the same string. - $duration = 'P'; - $days = $matches['day']; + foreach ($parts as $part) { + $matches[$part] = isset($matches[$part]) && $matches[$part] ? (int) $matches[$part] : 0; + } - if ($matches['week']) { - $days += $matches['week'] * 7; - } + // We need to re-construct the $duration string, because weeks and + // days are not supported by DateInterval in the same string. + $duration = 'P'; + $days = $matches['day']; - if ($days) { - $duration .= $days.'D'; - } + if ($matches['week']) { + $days += $matches['week'] * 7; + } - if ($matches['minute'] || $matches['second'] || $matches['hour']) { - $duration .= 'T'; + if ($days) { + $duration .= $days.'D'; + } - if ($matches['hour']) { - $duration .= $matches['hour'].'H'; - } + if ($matches['minute'] || $matches['second'] || $matches['hour']) { + $duration .= 'T'; - if ($matches['minute']) { - $duration .= $matches['minute'].'M'; - } + if ($matches['hour']) { + $duration .= $matches['hour'].'H'; + } - if ($matches['second']) { - $duration .= $matches['second'].'S'; - } + if ($matches['minute']) { + $duration .= $matches['minute'].'M'; } - if ('P' === $duration) { - $duration = 'PT0S'; + if ($matches['second']) { + $duration .= $matches['second'].'S'; } + } - $iv = new DateInterval($duration); + if ('P' === $duration) { + $duration = 'PT0S'; + } - if ($invert) { - $iv->invert = true; - } + $iv = new DateInterval($duration); - return $iv; + if ($invert) { + $iv->invert = true; + } + + return $iv; + } + + /** + * Parses an iCalendar (RFC5545) formatted duration value. + * + * This method will return a string suitable for strtotime or DateTime::modify. + * + * @throws InvalidDataException + */ + public static function parseDurationAsString(string $duration): string + { + $result = preg_match('/^(?\+|-)?P((?\d+)W)?((?\d+)D)?(T((?\d+)H)?((?\d+)M)?((?\d+)S)?)?$/', $duration, $matches); + if (!$result) { + throw new InvalidDataException('The supplied iCalendar duration value is incorrect: '.$duration); } $parts = [ @@ -190,12 +195,13 @@ public static function parseDuration($duration, $asString = false) /** * Parses either a Date or DateTime, or Duration value. * - * @param string $date * @param DateTimeZone|string $referenceTz * - * @return DateTimeImmutable|DateInterval + * @return DateInterval|DateTimeImmutable + * + * @throws InvalidDataException */ - public static function parse($date, $referenceTz = null) + public static function parse(string $date, $referenceTz = null) { if ('P' === $date[0] || ('-' === $date[0] && 'P' === $date[1])) { return self::parseDuration($date); @@ -258,11 +264,9 @@ public static function parse($date, $referenceTz = null) * Times may be postfixed by a timezone offset. This can be either 'Z' for * UTC, or a string like -0500 or +1100. * - * @param string $date - * - * @return array + * @throws InvalidDataException */ - public static function parseVCardDateTime($date) + public static function parseVCardDateTime(string $date): array { $regex = '/^ (?: # date part @@ -377,11 +381,9 @@ public static function parseVCardDateTime($date) * Times may be postfixed by a timezone offset. This can be either 'Z' for * UTC, or a string like -0500 or +11:00. * - * @param string $date - * - * @return array + * @throws InvalidDataException */ - public static function parseVCardTime($date) + public static function parseVCardTime(string $date): array { $regex = '/^ (? [0-9]{2} | -) @@ -483,11 +485,9 @@ public static function parseVCardTime($date) * Times may be postfixed by a timezone offset. This can be either 'Z' for * UTC, or a string like -0500 or +1100. * - * @param string $date - * - * @return array + * @throws InvalidDataException */ - public static function parseVCardDateAndOrTime($date) + public static function parseVCardDateAndOrTime(string $date): array { // \d{8}|\d{4}-\d\d|--\d\d(\d\d)?|---\d\d $valueDate = '/^(?J)(?:'. diff --git a/lib/Document.php b/lib/Document.php index 14a77c911..e59938075 100644 --- a/lib/Document.php +++ b/lib/Document.php @@ -2,6 +2,8 @@ namespace Sabre\VObject; +use Sabre\VObject; + /** * Document. * @@ -15,68 +17,62 @@ * @copyright Copyright (C) fruux GmbH (https://fruux.com/) * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License + * + * @property VObject\Property\FlatText VERSION */ abstract class Document extends Component { /** * Unknown document type. */ - const UNKNOWN = 1; + public const UNKNOWN = 1; /** * vCalendar 1.0. */ - const VCALENDAR10 = 2; + public const VCALENDAR10 = 2; /** * iCalendar 2.0. */ - const ICALENDAR20 = 3; + public const ICALENDAR20 = 3; /** * vCard 2.1. */ - const VCARD21 = 4; + public const VCARD21 = 4; /** * vCard 3.0. */ - const VCARD30 = 5; + public const VCARD30 = 5; /** * vCard 4.0. */ - const VCARD40 = 6; + public const VCARD40 = 6; /** * The default name for this component. * * This should be 'VCALENDAR' or 'VCARD'. - * - * @var string */ - public static $defaultName; + public static ?string $defaultName = null; /** * List of properties, and which classes they map to. - * - * @var array */ - public static $propertyMap = []; + public static array $propertyMap = []; /** * List of components, along with which classes they map to. - * - * @var array */ - public static $componentMap = []; + public static array $componentMap = []; /** * List of value-types, and which classes they map to. - * - * @var array */ - public static $valueMap = []; + public static array $valueMap = []; /** * Creates a new document. @@ -97,22 +93,20 @@ public function __construct() $args = func_get_args(); $name = static::$defaultName; if (0 === count($args) || is_array($args[0])) { - $children = isset($args[0]) ? $args[0] : []; - $defaults = isset($args[1]) ? $args[1] : true; + $children = $args[0] ?? []; + $defaults = $args[1] ?? true; } else { $name = $args[0]; - $children = isset($args[1]) ? $args[1] : []; - $defaults = isset($args[2]) ? $args[2] : true; + $children = $args[1] ?? []; + $defaults = $args[2] ?? true; } parent::__construct($this, $name, $children, $defaults); } /** * Returns the current document type. - * - * @return int */ - public function getDocumentType() + public function getDocumentType(): int { return self::UNKNOWN; } @@ -123,12 +117,11 @@ public function getDocumentType() * If it's a known component, we will automatically call createComponent. * otherwise, we'll assume it's a property and call createProperty instead. * - * @param string $name * @param string $arg1,... Unlimited number of args * * @return mixed */ - public function create($name) + public function create(string $name) { if (isset(static::$componentMap[strtoupper($name)])) { return call_user_func_array([$this, 'createComponent'], func_get_args()); @@ -150,14 +143,8 @@ public function create($name) * By default, a set of sensible values will be added to the component. For * an iCalendar object, this may be something like CALSCALE:GREGORIAN. To * ensure that this does not happen, set $defaults to false. - * - * @param string $name - * @param array $children - * @param bool $defaults - * - * @return Component */ - public function createComponent($name, array $children = null, $defaults = true) + public function createComponent(string $name, array $children = null, bool $defaults = true): Component { $name = strtoupper($name); $class = Component::class; @@ -182,14 +169,12 @@ public function createComponent($name, array $children = null, $defaults = true) * parameters will automatically be created, or you can just pass a list of * Parameter objects. * - * @param string $name - * @param mixed $value - * @param array $parameters - * @param string $valueType Force a specific valuetype, such as URI or TEXT + * @param mixed $value + * @param string|null $valueType Force a specific valuetype, such as URI or TEXT * - * @return Property + * @throws InvalidDataException */ - public function createProperty($name, $value = null, array $parameters = null, $valueType = null) + public function createProperty(string $name, $value = null, array $parameters = null, string $valueType = null): Property { // If there's a . in the name, it means it's prefixed by a groupname. if (false !== ($i = strpos($name, '.'))) { @@ -234,11 +219,9 @@ public function createProperty($name, $value = null, array $parameters = null, $ * * This method returns null if we don't have a specialized class. * - * @param string $valueParam - * - * @return string|null + * @return string|void|null */ - public function getClassNameForPropertyValue($valueParam) + public function getClassNameForPropertyValue(string $valueParam) { $valueParam = strtoupper($valueParam); if (isset(static::$valueMap[$valueParam])) { @@ -248,17 +231,9 @@ public function getClassNameForPropertyValue($valueParam) /** * Returns the default class for a property name. - * - * @param string $propertyName - * - * @return string */ - public function getClassNameForPropertyName($propertyName) + public function getClassNameForPropertyName(string $propertyName): string { - if (isset(static::$propertyMap[$propertyName])) { - return static::$propertyMap[$propertyName]; - } else { - return Property\Unknown::class; - } + return static::$propertyMap[$propertyName] ?? Property\Unknown::class; } } diff --git a/lib/FreeBusyData.php b/lib/FreeBusyData.php index 4d9f441ce..9ea7958a3 100644 --- a/lib/FreeBusyData.php +++ b/lib/FreeBusyData.php @@ -48,11 +48,11 @@ public function __construct($start, $end) /** * Adds free or busytime to the data. * - * @param int $start - * @param int $end - * @param string $type FREE, BUSY, BUSY-UNAVAILABLE or BUSY-TENTATIVE + * @param string $type FREE, BUSY, BUSY-UNAVAILABLE or BUSY-TENTATIVE + * + * @return void */ - public function add($start, $end, $type) + public function add(int $start, int $end, string $type) { if ($start > $this->end || $end < $this->start) { // This new data is outside our timerange. @@ -178,7 +178,7 @@ public function add($start, $end, $type) } } - public function getData() + public function getData(): array { return $this->data; } diff --git a/lib/FreeBusyGenerator.php b/lib/FreeBusyGenerator.php index 81b8126d5..48927d317 100644 --- a/lib/FreeBusyGenerator.php +++ b/lib/FreeBusyGenerator.php @@ -5,7 +5,11 @@ use DateTimeImmutable; use DateTimeInterface; use DateTimeZone; +use Exception; use Sabre\VObject\Component\VCalendar; +use Sabre\VObject\Component\VEvent; +use Sabre\VObject\Component\VFreeBusy; +use Sabre\VObject\Property\ICalendar\DateTime; use Sabre\VObject\Recur\EventIterator; use Sabre\VObject\Recur\NoInstancesException; @@ -84,10 +88,7 @@ class FreeBusyGenerator * Check the setTimeRange and setObjects methods for details about the * arguments. * - * @param DateTimeInterface $start - * @param DateTimeInterface $end - * @param mixed $objects - * @param DateTimeZone $timeZone + * @param mixed $objects */ public function __construct(DateTimeInterface $start = null, DateTimeInterface $end = null, $objects = null, DateTimeZone $timeZone = null) { @@ -110,7 +111,7 @@ public function __construct(DateTimeInterface $start = null, DateTimeInterface $ * * The VFREEBUSY object will be automatically added though. */ - public function setBaseObject(Document $vcalendar) + public function setBaseObject(Document $vcalendar): void { $this->baseObject = $vcalendar; } @@ -118,7 +119,7 @@ public function setBaseObject(Document $vcalendar) /** * Sets a VAVAILABILITY document. */ - public function setVAvailability(Document $vcalendar) + public function setVAvailability(Document $vcalendar): void { $this->vavailability = $vcalendar; } @@ -132,7 +133,7 @@ public function setVAvailability(Document $vcalendar) * * @param mixed $objects */ - public function setObjects($objects) + public function setObjects($objects): void { if (!is_array($objects)) { $objects = [$objects]; @@ -155,10 +156,9 @@ public function setObjects($objects) * * Any freebusy object falling outside of this time range will be ignored. * - * @param DateTimeInterface $start - * @param DateTimeInterface $end + * @throws Exception */ - public function setTimeRange(DateTimeInterface $start = null, DateTimeInterface $end = null) + public function setTimeRange(DateTimeInterface $start = null, DateTimeInterface $end = null): void { if (!$start) { $start = new DateTimeImmutable(Settings::$minDate); @@ -173,7 +173,7 @@ public function setTimeRange(DateTimeInterface $start = null, DateTimeInterface /** * Sets the reference timezone for floating times. */ - public function setTimeZone(DateTimeZone $timeZone) + public function setTimeZone(DateTimeZone $timeZone): void { $this->timeZone = $timeZone; } @@ -203,7 +203,7 @@ public function getResult() * This method takes a VAVAILABILITY component and figures out all the * available times. */ - protected function calculateAvailability(FreeBusyData $fbData, VCalendar $vavailability) + protected function calculateAvailability(FreeBusyData $fbData, VCalendar $vavailability): void { $vavailComps = iterator_to_array($vavailability->VAVAILABILITY); usort( @@ -355,13 +355,16 @@ function ($a, $b) { * times on fbData. * * @param VCalendar[] $objects + * + * @throws InvalidDataException|Recur\MaxInstancesExceededException */ - protected function calculateBusy(FreeBusyData $fbData, array $objects) + protected function calculateBusy(FreeBusyData $fbData, array $objects): void { foreach ($objects as $key => $object) { foreach ($object->getBaseComponents() as $component) { switch ($component->name) { case 'VEVENT': + /** @var VEvent $component */ $FBTYPE = 'BUSY'; if (isset($component->TRANSP) && ('TRANSPARENT' === strtoupper($component->TRANSP))) { break; @@ -447,6 +450,7 @@ protected function calculateBusy(FreeBusyData $fbData, array $objects) break; case 'VFREEBUSY': + /** @var VFreeBusy $component */ foreach ($component->FREEBUSY as $freebusy) { $fbType = isset($freebusy['FBTYPE']) ? strtoupper($freebusy['FBTYPE']) : 'BUSY'; @@ -491,9 +495,10 @@ protected function calculateBusy(FreeBusyData $fbData, array $objects) * This method takes a FreeBusyData object and generates the VCALENDAR * object associated with it. * - * @return VCalendar + * @throws InvalidDataException + * @throws Exception */ - protected function generateFreeBusyCalendar(FreeBusyData $fbData) + protected function generateFreeBusyCalendar(FreeBusyData $fbData): VCalendar { if ($this->baseObject) { $calendar = $this->baseObject; @@ -505,17 +510,20 @@ protected function generateFreeBusyCalendar(FreeBusyData $fbData) $calendar->add($vfreebusy); if ($this->start) { + /** @var DateTime $dtstart */ $dtstart = $calendar->createProperty('DTSTART'); $dtstart->setDateTime($this->start); $vfreebusy->add($dtstart); } if ($this->end) { + /** @var DateTime $dtend */ $dtend = $calendar->createProperty('DTEND'); $dtend->setDateTime($this->end); $vfreebusy->add($dtend); } $tz = new \DateTimeZone('UTC'); + /** @var DateTime $dtstamp */ $dtstamp = $calendar->createProperty('DTSTAMP'); $dtstamp->setDateTime(new DateTimeImmutable('now', $tz)); $vfreebusy->add($dtstamp); @@ -528,8 +536,8 @@ protected function generateFreeBusyCalendar(FreeBusyData $fbData) continue; } - $busyTime[0] = new \DateTimeImmutable('@'.$busyTime['start'], $tz); - $busyTime[1] = new \DateTimeImmutable('@'.$busyTime['end'], $tz); + $busyTime[0] = new DateTimeImmutable('@'.$busyTime['start'], $tz); + $busyTime[1] = new DateTimeImmutable('@'.$busyTime['end'], $tz); $prop = $calendar->createProperty( 'FREEBUSY', diff --git a/lib/ITip/Broker.php b/lib/ITip/Broker.php index b66a59f54..c740453b0 100644 --- a/lib/ITip/Broker.php +++ b/lib/ITip/Broker.php @@ -3,9 +3,14 @@ namespace Sabre\VObject\ITip; use Sabre\VObject\Component\VCalendar; +use Sabre\VObject\Component\VEvent; use Sabre\VObject\DateTimeParser; +use Sabre\VObject\InvalidDataException; +use Sabre\VObject\ParseException; use Sabre\VObject\Reader; use Sabre\VObject\Recur\EventIterator; +use Sabre\VObject\Recur\MaxInstancesExceededException; +use Sabre\VObject\Recur\NoInstancesException; /** * The ITip\Broker class is a utility class that helps with processing @@ -49,10 +54,8 @@ class Broker * CLIENT will be ignored. This is the desired behavior for a CalDAV * server, but if you're writing an iTip application that doesn't deal with * CalDAV, you may want to ignore this parameter. - * - * @var bool */ - public $scheduleAgentServerRules = true; + public bool $scheduleAgentServerRules = true; /** * The broker will try during 'parseEvent' figure out whether the change @@ -66,7 +69,7 @@ class Broker * * @var string[] */ - public $significantChangeProperties = [ + public array $significantChangeProperties = [ 'DTSTART', 'DTEND', 'DURATION', @@ -104,9 +107,11 @@ class Broker * * If the iTip message was not supported, we will always return false. * - * @param VCalendar $existingObject + * @return VCalendar|false|void|null * - * @return VCalendar|null + * @throws InvalidDataException + * @throws MaxInstancesExceededException + * @throws NoInstancesException */ public function processMessage(Message $itipMessage, VCalendar $existingObject = null) { @@ -129,8 +134,6 @@ public function processMessage(Message $itipMessage, VCalendar $existingObject = // Unsupported iTip message return; } - - return $existingObject; } /** @@ -156,13 +159,16 @@ public function processMessage(Message $itipMessage, VCalendar $existingObject = * people. If the user was an attendee, we need to make sure that the * organizer gets the 'declined' message. * - * @param VCalendar|string $calendar - * @param string|array $userHref - * @param VCalendar|string $oldCalendar + * @param VCalendar|string $calendar + * @param string|array $userHref + * @param VCalendar|string|null $oldCalendar * - * @return array + * @throws ITipException + * @throws InvalidDataException + * @throws ParseException + * @throws SameOrganizerForAllComponentsException */ - public function parseEvent($calendar, $userHref, $oldCalendar = null) + public function parseEvent($calendar, $userHref, $oldCalendar = null): array { if ($oldCalendar) { if (is_string($oldCalendar)) { @@ -261,20 +267,13 @@ public function parseEvent($calendar, $userHref, $oldCalendar = null) * * This is message from an organizer, and is either a new event * invite, or an update to an existing one. - * - * @param VCalendar $existingObject - * - * @return VCalendar|null */ - protected function processMessageRequest(Message $itipMessage, VCalendar $existingObject = null) + protected function processMessageRequest(Message $itipMessage, VCalendar $existingObject = null): ?VCalendar { if (!$existingObject) { // This is a new invite, and we're just going to copy over // all the components from the invite. $existingObject = new VCalendar(); - foreach ($itipMessage->message->getComponents() as $component) { - $existingObject->add(clone $component); - } } else { // We need to update an existing object with all the new // information. We can just remove all existing components @@ -282,9 +281,9 @@ protected function processMessageRequest(Message $itipMessage, VCalendar $existi foreach ($existingObject->getComponents() as $component) { $existingObject->remove($component); } - foreach ($itipMessage->message->getComponents() as $component) { - $existingObject->add(clone $component); - } + } + foreach ($itipMessage->message->getComponents() as $component) { + $existingObject->add(clone $component); } return $existingObject; @@ -296,12 +295,8 @@ protected function processMessageRequest(Message $itipMessage, VCalendar $existi * This is a message from an organizer, and means that either an * attendee got removed from an event, or an event got cancelled * altogether. - * - * @param VCalendar $existingObject - * - * @return VCalendar|null */ - protected function processMessageCancel(Message $itipMessage, VCalendar $existingObject = null) + protected function processMessageCancel(Message $itipMessage, VCalendar $existingObject = null): ?VCalendar { if (!$existingObject) { // The event didn't exist in the first place, so we're just @@ -322,9 +317,11 @@ protected function processMessageCancel(Message $itipMessage, VCalendar $existin * The message is a reply. This is for example an attendee telling * an organizer he accepted the invite, or declined it. * - * @param VCalendar $existingObject + * @return VCalendar|void * - * @return VCalendar|null + * @throws InvalidDataException + * @throws MaxInstancesExceededException + * @throws NoInstancesException */ protected function processMessageReply(Message $itipMessage, VCalendar $existingObject = null) { @@ -446,10 +443,8 @@ protected function processMessageReply(Message $itipMessage, VCalendar $existing * * We will detect which attendees got added, which got removed and create * specific messages for these situations. - * - * @return array */ - protected function parseEventForOrganizer(VCalendar $calendar, array $eventInfo, array $oldEventInfo) + protected function parseEventForOrganizer(VCalendar $calendar, array $eventInfo, array $oldEventInfo): array { // Merging attendee lists. $attendees = []; @@ -511,6 +506,7 @@ protected function parseEventForOrganizer(VCalendar $calendar, array $eventInfo, $icalMsg->METHOD = $message->method; + /** @var VEvent $event */ $event = $icalMsg->add('VEVENT', [ 'UID' => $message->uid, 'SEQUENCE' => $message->sequence, @@ -615,11 +611,11 @@ protected function parseEventForOrganizer(VCalendar $calendar, array $eventInfo, * * This function figures out if we need to send a reply to an organizer. * - * @param string $attendee - * * @return Message[] + * + * @throws InvalidDataException */ - protected function parseEventForAttendee(VCalendar $calendar, array $eventInfo, array $oldEventInfo, $attendee) + protected function parseEventForAttendee(VCalendar $calendar, array $eventInfo, array $oldEventInfo, string $attendee): array { if ($this->scheduleAgentServerRules && 'CLIENT' === $eventInfo['organizerScheduleAgent']) { return []; @@ -710,6 +706,7 @@ protected function parseEventForAttendee(VCalendar $calendar, array $eventInfo, continue; } + /** @var VEvent $event */ $event = $icalMsg->add('VEVENT', [ 'UID' => $message->uid, 'SEQUENCE' => $message->sequence, @@ -796,11 +793,10 @@ protected function parseEventForAttendee(VCalendar $calendar, array $eventInfo, * 11. significantChangeHash * 12. status * - * @param VCalendar $calendar - * - * @return array + * @throws ITipException + * @throws SameOrganizerForAllComponentsException */ - protected function parseEventInfo(VCalendar $calendar = null) + protected function parseEventInfo(VCalendar $calendar = null): array { $uid = null; $organizer = null; @@ -811,8 +807,6 @@ protected function parseEventInfo(VCalendar $calendar = null) $status = null; $organizerScheduleAgent = 'SERVER'; - $significantChangeHash = ''; - // Now we need to collect a list of attendees, and which instances they // are a part of. $attendees = []; @@ -841,7 +835,7 @@ protected function parseEventInfo(VCalendar $calendar = null) if (isset($vevent->ORGANIZER)) { if (is_null($organizer)) { $organizer = $vevent->ORGANIZER->getNormalizedValue(); - $organizerName = isset($vevent->ORGANIZER['CN']) ? $vevent->ORGANIZER['CN'] : null; + $organizerName = $vevent->ORGANIZER['CN'] ?? null; } else { if (strtoupper($organizer) !== strtoupper($vevent->ORGANIZER->getNormalizedValue())) { throw new SameOrganizerForAllComponentsException('Every instance of the event must have the same organizer.'); @@ -955,9 +949,7 @@ protected function parseEventInfo(VCalendar $calendar = null) asort($significantChangeEventProperties); - foreach ($significantChangeEventProperties as $eventSignificantChangeHash) { - $significantChangeHash .= $eventSignificantChangeHash; - } + $significantChangeHash = implode('', $significantChangeEventProperties); $significantChangeHash = md5($significantChangeHash); return compact( diff --git a/lib/ITip/Message.php b/lib/ITip/Message.php index 43536f172..9aa93996a 100644 --- a/lib/ITip/Message.php +++ b/lib/ITip/Message.php @@ -2,6 +2,8 @@ namespace Sabre\VObject\ITip; +use Sabre\VObject\Component\VCalendar; + /** * This class represents an iTip message. * @@ -18,32 +20,24 @@ class Message { /** * The object's UID. - * - * @var string */ - public $uid; + public string $uid; /** * The component type, such as VEVENT. - * - * @var string */ - public $component; + public string $component; /** * Contains the ITip method, which is something like REQUEST, REPLY or * CANCEL. - * - * @var string */ - public $method; + public ?string $method; /** * The current sequence number for the event. - * - * @var int */ - public $sequence; + public ?int $sequence; /** * The senders' email address. @@ -51,33 +45,25 @@ class Message * Note that this does not imply that this has to be used in a From: field * if the message is sent by email. It may also be populated in Reply-To: * or not at all. - * - * @var string */ - public $sender; + public string $sender; /** * The name of the sender. This is often populated from a CN parameter from * either the ORGANIZER or ATTENDEE, depending on the message. - * - * @var string|null */ - public $senderName; + public ?string $senderName; /** * The recipient's email address. - * - * @var string */ - public $recipient; + public string $recipient; /** * The name of the recipient. This is usually populated with the CN * parameter from the ATTENDEE or ORGANIZER property, if it's available. - * - * @var string|null */ - public $recipientName; + public ?string $recipientName; /** * After the message has been delivered, this should contain a string such @@ -87,17 +73,13 @@ class Message * * See: * http://tools.ietf.org/html/rfc6638#section-7.3 - * - * @var string */ - public $scheduleStatus; + public ?string $scheduleStatus = null; /** * The iCalendar / iTip body. - * - * @var \Sabre\VObject\Component\VCalendar */ - public $message; + public VCalendar $message; /** * This will be set to true, if the iTip broker considers the change @@ -110,10 +92,8 @@ class Message * * To see the list of properties that are considered 'significant', check * out Sabre\VObject\ITip\Broker::$significantChangeProperties. - * - * @var bool */ - public $significantChange = true; + public bool $significantChange = true; /** * Returns the schedule status as a string. diff --git a/lib/Node.php b/lib/Node.php index 2041b2ac7..efb18347f 100644 --- a/lib/Node.php +++ b/lib/Node.php @@ -19,7 +19,7 @@ abstract class Node implements \IteratorAggregate, \ArrayAccess, \Countable, \Js * If REPAIR is set, the validator will attempt to repair any broken data * (if possible). */ - const REPAIR = 1; + public const REPAIR = 1; /** * If this option is set, the validator will operate on the vcards on the @@ -28,7 +28,7 @@ abstract class Node implements \IteratorAggregate, \ArrayAccess, \Countable, \Js * This means for example that the UID is required, whereas it is not for * regular vcards. */ - const PROFILE_CARDDAV = 2; + public const PROFILE_CARDDAV = 2; /** * If this option is set, the validator will operate on iCalendar objects @@ -37,41 +37,33 @@ abstract class Node implements \IteratorAggregate, \ArrayAccess, \Countable, \Js * This means for example that calendars can only contain objects with * identical component types and UIDs. */ - const PROFILE_CALDAV = 4; + public const PROFILE_CALDAV = 4; /** * Reference to the parent object, if this is not the top object. - * - * @var Node */ - public $parent; + public ?Node $parent; /** * Iterator override. - * - * @var ElementList */ - protected $iterator = null; + protected ?ElementList $iterator = null; /** * The root document. - * - * @var Component */ - protected $root; + protected ?Component $root; /** * Serializes the node into a mimedir format. - * - * @return string */ - abstract public function serialize(); + abstract public function serialize(): string; /** * This method returns an array, with the representation as it should be * encoded in JSON. This is used to create jCard or jCal documents. * - * @return array + * @return array|string */ #[\ReturnTypeWillChange] abstract public function jsonSerialize(); @@ -82,13 +74,15 @@ abstract public function jsonSerialize(); * * @param Xml\Writer $writer XML writer */ - abstract public function xmlSerialize(Xml\Writer $writer); + abstract public function xmlSerialize(Xml\Writer $writer): void; /** * Call this method on a document if you're done using it. * * It's intended to remove all circular references, so PHP can easily clean * it up. + * + * @return void */ public function destroy() { @@ -104,7 +98,7 @@ public function destroy() * @return ElementList */ #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): ?ElementList { if (!is_null($this->iterator)) { return $this->iterator; @@ -118,7 +112,7 @@ public function getIterator() * * Note that this is not actually part of the iterator interface */ - public function setIterator(ElementList $iterator) + public function setIterator(ElementList $iterator): void { $this->iterator = $iterator; } @@ -140,12 +134,8 @@ public function setIterator(ElementList $iterator) * 1 - The issue was repaired (only happens if REPAIR was turned on) * 2 - An inconsequential issue * 3 - A severe issue. - * - * @param int $options - * - * @return array */ - public function validate($options = 0) + public function validate(int $options = 0): array { return []; } @@ -156,11 +146,9 @@ public function validate($options = 0) /** * Returns the number of elements. - * - * @return int */ #[\ReturnTypeWillChange] - public function count() + public function count(): int { $it = $this->getIterator(); @@ -177,11 +165,9 @@ public function count() * This method just forwards the request to the inner iterator * * @param int $offset - * - * @return bool */ #[\ReturnTypeWillChange] - public function offsetExists($offset) + public function offsetExists($offset): bool { $iterator = $this->getIterator(); diff --git a/lib/PHPUnitAssertions.php b/lib/PHPUnitAssertions.php index 45c0a21c6..fcaaafd5a 100644 --- a/lib/PHPUnitAssertions.php +++ b/lib/PHPUnitAssertions.php @@ -30,9 +30,8 @@ trait PHPUnitAssertions * * @param resource|string|Component $expected * @param resource|string|Component $actual - * @param string $message */ - public function assertVObjectEqualsVObject($expected, $actual, $message = '') + public function assertVObjectEqualsVObject($expected, $actual, string $message = '') { $getObj = function ($input) { if (is_resource($input)) { diff --git a/lib/Parameter.php b/lib/Parameter.php index c27b2aa47..ef3461b85 100644 --- a/lib/Parameter.php +++ b/lib/Parameter.php @@ -2,7 +2,6 @@ namespace Sabre\VObject; -use ArrayIterator; use Sabre\Xml; /** @@ -21,24 +20,20 @@ class Parameter extends Node { /** * Parameter name. - * - * @var string */ - public $name; + public string $name; /** * vCard 2.1 allows parameters to be encoded without a name. * * We can deduce the parameter name based on its value. - * - * @var bool */ - public $noName = false; + public bool $noName = false; /** * Parameter value. * - * @var string + * @var string|array|null */ protected $value; @@ -47,10 +42,9 @@ class Parameter extends Node * * It's recommended to use the create:: factory method instead. * - * @param string $name - * @param string $value + * @param string|array|null $value */ - public function __construct(Document $root, $name, $value = null) + public function __construct(Document $root, ?string $name, $value = null) { $this->root = $root; if (is_null($name)) { @@ -77,12 +71,8 @@ public function __construct(Document $root, $name, $value = null) * Figuring out what the name should have been. Note that a ton of * these are rather silly in 2014 and would probably rarely be * used, but we like to be complete. - * - * @param string $value - * - * @return string */ - public static function guessParameterNameByValue($value) + public static function guessParameterNameByValue(string $value): string { switch (strtoupper($value)) { // Encodings @@ -172,7 +162,7 @@ public static function guessParameterNameByValue($value) * * @param string|array $value */ - public function setValue($value) + public function setValue($value): void { $this->value = $value; } @@ -182,10 +172,8 @@ public function setValue($value) * * This method will always return a string, or null. If there were multiple * values, it will automatically concatenate them (separated by comma). - * - * @return string|null */ - public function getValue() + public function getValue(): ?string { if (is_array($this->value)) { return implode(',', $this->value); @@ -197,7 +185,7 @@ public function getValue() /** * Sets multiple values for this parameter. */ - public function setParts(array $value) + public function setParts(array $value): void { $this->value = $value; } @@ -206,10 +194,8 @@ public function setParts(array $value) * Returns all values for this parameter. * * If there were no values, an empty array will be returned. - * - * @return array */ - public function getParts() + public function getParts(): array { if (is_array($this->value)) { return $this->value; @@ -228,7 +214,7 @@ public function getParts() * * @param string|array $part */ - public function addValue($part) + public function addValue($part): void { if (is_null($this->value)) { $this->value = $part; @@ -243,12 +229,8 @@ public function addValue($part) * This is a case-insensitive match. It makes sense to call this for for * instance the TYPE parameter, to see if it contains a keyword such as * 'WORK' or 'FAX'. - * - * @param string $value - * - * @return bool */ - public function has($value) + public function has(string $value): bool { return in_array( strtolower($value), @@ -258,10 +240,8 @@ public function has($value) /** * Turns the object back into a serialized blob. - * - * @return string */ - public function serialize() + public function serialize(): string { $value = $this->getParts(); @@ -320,7 +300,7 @@ function ($out, $item) { * This method returns an array, with the representation as it should be * encoded in JSON. This is used to create jCard or jCal documents. * - * @return array + * @return array|string|null */ #[\ReturnTypeWillChange] public function jsonSerialize() @@ -334,7 +314,7 @@ public function jsonSerialize() * * @param Xml\Writer $writer XML writer */ - public function xmlSerialize(Xml\Writer $writer) + public function xmlSerialize(Xml\Writer $writer): void { foreach (explode(',', $this->value) as $value) { $writer->writeElement('text', $value); @@ -343,26 +323,22 @@ public function xmlSerialize(Xml\Writer $writer) /** * Called when this object is being cast to a string. - * - * @return string */ - public function __toString() + public function __toString(): string { return (string) $this->getValue(); } /** * Returns the iterator for this object. - * - * @return ElementList */ #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): ElementList { if (!is_null($this->iterator)) { return $this->iterator; } - return $this->iterator = new ArrayIterator((array) $this->value); + return $this->iterator = new ElementList((array) $this->value); } } diff --git a/lib/Parser/Json.php b/lib/Parser/Json.php index f33603207..77572c1a0 100644 --- a/lib/Parser/Json.php +++ b/lib/Parser/Json.php @@ -2,11 +2,14 @@ namespace Sabre\VObject\Parser; +use Sabre\VObject\Component; use Sabre\VObject\Component\VCalendar; use Sabre\VObject\Component\VCard; use Sabre\VObject\Document; use Sabre\VObject\EofException; +use Sabre\VObject\InvalidDataException; use Sabre\VObject\ParseException; +use Sabre\VObject\Property; use Sabre\VObject\Property\FlatText; use Sabre\VObject\Property\Text; @@ -23,17 +26,13 @@ class Json extends Parser { /** * The input data. - * - * @var array */ - protected $input; + protected ?array $input; /** * Root component. - * - * @var Document */ - protected $root; + protected ?Document $root; /** * This method starts the parsing process. @@ -44,11 +43,12 @@ class Json extends Parser * If either input or options are not supplied, the defaults will be used. * * @param resource|string|array|null $input - * @param int $options * - * @return \Sabre\VObject\Document + * @throws EofException + * @throws ParseException + * @throws InvalidDataException */ - public function parse($input = null, $options = 0) + public function parse($input = null, int $options = 0): ?Document { if (!is_null($input)) { $this->setInput($input); @@ -89,9 +89,9 @@ public function parse($input = null, $options = 0) /** * Parses a component. * - * @return \Sabre\VObject\Component + * @throws InvalidDataException */ - public function parseComponent(array $jComp) + public function parseComponent(array $jComp): Component { // We can remove $self from PHP 5.4 onward. $self = $this; @@ -117,16 +117,16 @@ function ($jComp) use ($self) { return $this->root->createComponent( $jComp[0], array_merge($properties, $components), - $defaults = false + false ); } /** * Parses properties. * - * @return \Sabre\VObject\Property + * @throws InvalidDataException */ - public function parseProperty(array $jProp) + public function parseProperty(array $jProp): Property { list( $propertyName, @@ -177,7 +177,7 @@ public function parseProperty(array $jProp) * * @param resource|string|array $input */ - public function setInput($input) + public function setInput($input): void { if (is_resource($input)) { $input = stream_get_contents($input); diff --git a/lib/Parser/MimeDir.php b/lib/Parser/MimeDir.php index 92336feea..b06a16d33 100644 --- a/lib/Parser/MimeDir.php +++ b/lib/Parser/MimeDir.php @@ -2,13 +2,22 @@ namespace Sabre\VObject\Parser; +use function feof; +use function fgets; +use InvalidArgumentException; +use function is_null; +use LogicException; +use function rtrim; use Sabre\VObject\Component; use Sabre\VObject\Component\VCalendar; use Sabre\VObject\Component\VCard; use Sabre\VObject\Document; use Sabre\VObject\EofException; +use Sabre\VObject\InvalidDataException; use Sabre\VObject\Node; use Sabre\VObject\ParseException; +use Sabre\VObject\Property; +use function substr; /** * MimeDir parser. @@ -34,10 +43,8 @@ class MimeDir extends Parser /** * Root component. - * - * @var Component */ - protected $root; + protected ?Document $root; /** * By default all input will be assumed to be UTF-8. @@ -48,17 +55,15 @@ class MimeDir extends Parser * If this is the case, use setEncoding to specify that a different * encoding will be used. If this is set, the parser will automatically * convert all incoming data to UTF-8. - * - * @var string */ - protected $charset = 'UTF-8'; + protected string $charset = 'UTF-8'; /** * The list of character sets we support when decoding. * * This would be a const expression but for now we need to support PHP 5.5 */ - protected static $SUPPORTED_CHARSETS = [ + protected static array $SUPPORTED_CHARSETS = [ 'UTF-8', 'ISO-8859-1', 'Windows-1252', @@ -71,11 +76,10 @@ class MimeDir extends Parser * used. * * @param string|resource|null $input - * @param int $options * - * @return \Sabre\VObject\Document + * @throws ParseException */ - public function parse($input = null, $options = 0) + public function parse($input = null, int $options = 0): ?Document { $this->root = null; @@ -101,13 +105,11 @@ public function parse($input = null, $options = 0) * If this is the case, use setEncoding to specify that a different * encoding will be used. If this is set, the parser will automatically * convert all incoming data to UTF-8. - * - * @param string $charset */ - public function setCharset($charset) + public function setCharset(string $charset): void { if (!in_array($charset, self::$SUPPORTED_CHARSETS)) { - throw new \InvalidArgumentException('Unsupported encoding. (Supported encodings: '.implode(', ', self::$SUPPORTED_CHARSETS).')'); + throw new InvalidArgumentException('Unsupported encoding. (Supported encodings: '.implode(', ', self::$SUPPORTED_CHARSETS).')'); } $this->charset = $charset; } @@ -116,6 +118,8 @@ public function setCharset($charset) * Sets the input buffer. Must be a string or stream. * * @param resource|string $input + * + * @return void */ public function setInput($input) { @@ -132,23 +136,26 @@ public function setInput($input) } elseif (is_resource($input)) { $this->input = $input; } else { - throw new \InvalidArgumentException('This parser can only read from strings or streams.'); + throw new InvalidArgumentException('This parser can only read from strings or streams.'); } } /** * Parses an entire document. + * + * @throws EofException + * @throws ParseException */ - protected function parseDocument() + protected function parseDocument(): void { $line = $this->readLine(); // BOM is ZERO WIDTH NO-BREAK SPACE (U+FEFF). // It's 0xEF 0xBB 0xBF in UTF-8 hex. if (3 <= strlen($line) - && 0xef === ord($line[0]) - && 0xbb === ord($line[1]) - && 0xbf === ord($line[2])) { + && 0xEF === ord($line[0]) + && 0xBB === ord($line[1]) + && 0xBF === ord($line[2])) { $line = substr($line, 3); } @@ -193,9 +200,12 @@ protected function parseDocument() * * @param string $line Unfolded line * - * @return Node + * @return Node|Property|false + * + * @throws EofException + * @throws ParseException */ - protected function parseLine($line) + protected function parseLine(string $line) { // Start of a new component if ('BEGIN:' === strtoupper(substr($line, 0, 6))) { @@ -269,28 +279,28 @@ protected function parseLine($line) * * This method strips any newlines and also takes care of unfolding. * - * @throws \Sabre\VObject\EofException - * * @return string + * + *@throws EofException|ParseException */ - protected function readLine() + protected function readLine(): ?string { - if (!\is_null($this->lineBuffer)) { + if (!is_null($this->lineBuffer)) { $rawLine = $this->lineBuffer; $this->lineBuffer = null; } else { do { - $eof = \feof($this->input); + $eof = feof($this->input); - $rawLine = \fgets($this->input); + $rawLine = fgets($this->input); - if ($eof || (\feof($this->input) && false === $rawLine)) { + if ($eof || (feof($this->input) && false === $rawLine)) { throw new EofException('End of document reached prematurely'); } if (false === $rawLine) { throw new ParseException('Error reading from input stream'); } - $rawLine = \rtrim($rawLine, "\r\n"); + $rawLine = rtrim($rawLine, "\r\n"); } while ('' === $rawLine); // Skipping empty lines ++$this->lineIndex; } @@ -300,13 +310,13 @@ protected function readLine() // Looking ahead for folded lines. while (true) { - $nextLine = \rtrim(\fgets($this->input), "\r\n"); + $nextLine = rtrim(fgets($this->input), "\r\n"); ++$this->lineIndex; if (!$nextLine) { break; } if ("\t" === $nextLine[0] || ' ' === $nextLine[0]) { - $curLine = \substr($nextLine, 1); + $curLine = substr($nextLine, 1); $line .= $curLine; $rawLine .= "\n ".$curLine; } else { @@ -321,8 +331,12 @@ protected function readLine() /** * Reads a property or component from a line. + * + * @return Property|false + * + * @throws ParseException|InvalidDataException */ - protected function readProperty($line) + protected function readProperty(string $line) { if ($this->options & self::OPTION_FORGIVING) { $propNameToken = 'A-Z0-9\-\._\\/'; @@ -417,7 +431,7 @@ protected function readProperty($line) } // @codeCoverageIgnoreStart - throw new \LogicException('This code should not be reachable'); + throw new LogicException('This code should not be reachable'); // @codeCoverageIgnoreEnd } @@ -454,6 +468,7 @@ protected function readProperty($line) } if (isset($propObj['ENCODING']) && 'QUOTED-PRINTABLE' === strtoupper($propObj['ENCODING'])) { + /* @var Property\Text|Property\FlatText $propObj */ $propObj->setQuotedPrintableValue($this->extractQuotedPrintableValue()); } else { $charset = $this->charset; @@ -536,12 +551,9 @@ protected function readProperty($line) * If it's a comma or a semi-colon the string will be split on those * characters, and always return an array. * - * @param string $input - * @param string $delimiter - * * @return string|string[] */ - public static function unescapeValue($input, $delimiter = ';') + public static function unescapeValue(string $input, string $delimiter = ';') { $regex = '# (?: (\\\\ (?: \\\\ | N | n | ; | , ) )'; if ($delimiter) { @@ -613,10 +625,8 @@ public static function unescapeValue($input, $delimiter = ';') * * New-line is encoded as ^n * * ^ is encoded as ^^. * * " is encoded as ^' - * - * @param string $input */ - private function unescapeParam($input) + private function unescapeParam(string $input): ?string { return preg_replace_callback( @@ -646,9 +656,10 @@ function ($matches) { * * This method does not do any decoding. * - * @return string + * @throws EofException + * @throws ParseException */ - private function extractQuotedPrintableValue() + private function extractQuotedPrintableValue(): string { // We need to parse the raw line again to get the start of the value. // diff --git a/lib/Parser/Parser.php b/lib/Parser/Parser.php index b7b611430..d0bca8e41 100644 --- a/lib/Parser/Parser.php +++ b/lib/Parser/Parser.php @@ -2,6 +2,8 @@ namespace Sabre\VObject\Parser; +use Sabre\VObject\Document; + /** * Abstract parser. * @@ -20,20 +22,18 @@ abstract class Parser * accept slashes and underscores in property names, and it will also * attempt to fix Microsoft vCard 2.1's broken line folding. */ - const OPTION_FORGIVING = 1; + public const OPTION_FORGIVING = 1; /** * If this option is turned on, any lines we cannot parse will be ignored * by the reader. */ - const OPTION_IGNORE_INVALID_LINES = 2; + public const OPTION_IGNORE_INVALID_LINES = 2; /** * Bitmask of parser options. - * - * @var int */ - protected $options; + protected int $options; /** * Creates the parser. @@ -43,7 +43,7 @@ abstract class Parser * @param mixed $input * @param int $options any parser options (OPTION constants) */ - public function __construct($input = null, $options = 0) + public function __construct($input = null, int $options = 0) { if (!is_null($input)) { $this->setInput($input); @@ -59,17 +59,14 @@ public function __construct($input = null, $options = 0) * * If either input or options are not supplied, the defaults will be used. * - * @param mixed $input - * @param int $options - * - * @return array + * @param resource|string|array|null $input */ - abstract public function parse($input = null, $options = 0); + abstract public function parse($input = null, int $options = 0): ?Document; /** * Sets the input data. * - * @param mixed $input + * @param resource|string|array $input */ abstract public function setInput($input); } diff --git a/lib/Parser/XML.php b/lib/Parser/XML.php index 78773173d..a64f5c50f 100644 --- a/lib/Parser/XML.php +++ b/lib/Parser/XML.php @@ -5,7 +5,9 @@ use Sabre\VObject\Component; use Sabre\VObject\Component\VCalendar; use Sabre\VObject\Component\VCard; +use Sabre\VObject\Document; use Sabre\VObject\EofException; +use Sabre\VObject\InvalidDataException; use Sabre\VObject\ParseException; use Sabre\Xml as SabreXml; @@ -20,29 +22,23 @@ */ class XML extends Parser { - const XCAL_NAMESPACE = 'urn:ietf:params:xml:ns:icalendar-2.0'; - const XCARD_NAMESPACE = 'urn:ietf:params:xml:ns:vcard-4.0'; + public const XCAL_NAMESPACE = 'urn:ietf:params:xml:ns:icalendar-2.0'; + public const XCARD_NAMESPACE = 'urn:ietf:params:xml:ns:vcard-4.0'; /** * The input data. - * - * @var array */ - protected $input; + protected ?array $input; /** * A pointer/reference to the input. - * - * @var array */ - private $pointer; + private ?array $pointer; /** * Document, root component. - * - * @var \Sabre\VObject\Document */ - protected $root; + protected ?Document $root; /** * Creates the parser. @@ -52,7 +48,7 @@ class XML extends Parser * @param mixed $input * @param int $options any parser options (OPTION constants) */ - public function __construct($input = null, $options = 0) + public function __construct($input = null, int $options = 0) { if (0 === $options) { $options = parent::OPTION_FORGIVING; @@ -64,14 +60,14 @@ public function __construct($input = null, $options = 0) /** * Parse xCal or xCard. * - * @param resource|string $input - * @param int $options + * @param resource|string|null $input * - * @throws \Exception - * - * @return \Sabre\VObject\Document + * @throws EofException + * @throws InvalidDataException + * @throws ParseException + * @throws SabreXml\LibXMLException */ - public function parse($input = null, $options = 0) + public function parse($input = null, int $options = 0): ?Document { if (!is_null($input)) { $this->setInput($input); @@ -112,8 +108,10 @@ public function parse($input = null, $options = 0) /** * Parse a xCalendar component. + * + * @throws InvalidDataException */ - protected function parseVCalendarComponents(Component $parentComponent) + protected function parseVCalendarComponents(Component $parentComponent): void { foreach ($this->pointer['value'] ?: [] as $children) { switch (static::getTagName($children['name'])) { @@ -132,8 +130,10 @@ protected function parseVCalendarComponents(Component $parentComponent) /** * Parse a xCard component. + * + * @throws InvalidDataException */ - protected function parseVCardComponents(Component $parentComponent) + protected function parseVCardComponents(Component $parentComponent): void { $this->pointer = &$this->pointer['value']; $this->parseProperties($parentComponent); @@ -142,9 +142,9 @@ protected function parseVCardComponents(Component $parentComponent) /** * Parse xCalendar and xCard properties. * - * @param string $propertyNamePrefix + * @throws InvalidDataException */ - protected function parseProperties(Component $parentComponent, $propertyNamePrefix = '') + protected function parseProperties(Component $parentComponent, string $propertyNamePrefix = ''): void { foreach ($this->pointer ?: [] as $xmlProperty) { list($namespace, $tagName) = SabreXml\Service::parseClarkNotation($xmlProperty['name']); @@ -297,8 +297,10 @@ protected function parseProperties(Component $parentComponent, $propertyNamePref /** * Parse a component. + * + * @throws InvalidDataException */ - protected function parseComponent(Component $parentComponent) + protected function parseComponent(Component $parentComponent): void { $components = $this->pointer['value'] ?: []; @@ -320,12 +322,11 @@ protected function parseComponent(Component $parentComponent) /** * Create a property. * - * @param string $name - * @param array $parameters - * @param string $type - * @param mixed $value + * @param mixed $value + * + * @throws InvalidDataException */ - protected function createProperty(Component $parentComponent, $name, $parameters, $type, $value) + protected function createProperty(Component $parentComponent, string $name, array $parameters, string $type, $value): void { $property = $this->root->createProperty( $name, @@ -340,7 +341,11 @@ protected function createProperty(Component $parentComponent, $name, $parameters /** * Sets the input data. * - * @param resource|string $input + * @param resource|string|array $input + * + * @throws SabreXml\LibXMLException + * + * @return void */ public function setInput($input) { @@ -363,12 +368,8 @@ public function setInput($input) /** * Get tag name from a Clark notation. - * - * @param string $clarkedTagName - * - * @return string */ - protected static function getTagName($clarkedTagName) + protected static function getTagName(string $clarkedTagName): string { list(, $tagName) = SabreXml\Service::parseClarkNotation($clarkedTagName); diff --git a/lib/Parser/XML/Element/KeyValue.php b/lib/Parser/XML/Element/KeyValue.php index c0bbf0d9b..207f150b2 100644 --- a/lib/Parser/XML/Element/KeyValue.php +++ b/lib/Parser/XML/Element/KeyValue.php @@ -32,12 +32,8 @@ class KeyValue extends SabreXml\Element\KeyValue * * $reader->parseInnerTree() will parse the entire sub-tree, and advance to * the next element. - * - * @param XML\Reader $reader - * - * @return mixed */ - public static function xmlDeserialize(SabreXml\Reader $reader) + public static function xmlDeserialize(SabreXml\Reader $reader): array { // If there's no children, we don't do anything. if ($reader->isEmptyElement) { diff --git a/lib/Property.php b/lib/Property.php index 56096dafe..310e66e59 100644 --- a/lib/Property.php +++ b/lib/Property.php @@ -2,7 +2,10 @@ namespace Sabre\VObject; +use Exception; +use function preg_replace; use Sabre\Xml; +use function substr; /** * Property. @@ -16,30 +19,29 @@ */ abstract class Property extends Node { + /** + * The root document. + */ + public ?Component $root; + /** * Property name. * * This will contain a string such as DTSTART, SUMMARY, FN. - * - * @var string */ - public $name; + public ?string $name; /** * Property group. * * This is only used in vcards - * - * @var string|null */ - public $group; + public ?string $group; /** * List of parameters. - * - * @var array */ - public $parameters = []; + public array $parameters = []; /** * Current value. @@ -51,10 +53,8 @@ abstract class Property extends Node /** * In case this is a multi-value property. This string will be used as a * delimiter. - * - * @var string */ - public $delimiter = ';'; + public string $delimiter = ';'; /** * Creates the generic property. @@ -62,12 +62,13 @@ abstract class Property extends Node * Parameters must be specified in key=>value syntax. * * @param Component $root The root document - * @param string $name * @param string|array|null $value * @param array $parameters List of parameters - * @param string $group The vcard property group + * @param string|null $group The vcard property group + * + * @throws InvalidDataException */ - public function __construct(Component $root, $name, $value = null, array $parameters = [], $group = null) + public function __construct(Component $root, ?string $name, $value = null, array $parameters = [], string $group = null) { $this->name = $name; $this->group = $group; @@ -90,7 +91,7 @@ public function __construct(Component $root, $name, $value = null, array $parame * * @param string|array $value */ - public function setValue($value) + public function setValue($value): void { $this->value = $value; } @@ -103,28 +104,26 @@ public function setValue($value) * it as a string. * * To get the correct multi-value version, use getParts. - * - * @return string */ public function getValue() { if (is_array($this->value)) { if (0 == count($this->value)) { - return; + return null; } elseif (1 === count($this->value)) { return $this->value[0]; - } else { - return $this->getRawMimeDirValue(); } - } else { - return $this->value; + + return $this->getRawMimeDirValue(); } + + return $this->value; } /** * Sets a multi-valued property. */ - public function setParts(array $parts) + public function setParts(array $parts): void { $this->value = $parts; } @@ -134,10 +133,8 @@ public function setParts(array $parts) * * This method always returns an array, if there was only a single value, * it will still be wrapped in an array. - * - * @return array */ - public function getParts() + public function getParts(): array { if (is_null($this->value)) { return []; @@ -155,10 +152,9 @@ public function getParts() * combined. * If nameless parameter is added, we try to guess its name. * - * @param string $name * @param string|array|null $value */ - public function add($name, $value = null) + public function add(?string $name, $value = null): void { $noName = false; if (null === $name) { @@ -177,10 +173,8 @@ public function add($name, $value = null) /** * Returns an iterable list of children. - * - * @return array */ - public function parameters() + public function parameters(): array { return $this->parameters; } @@ -190,34 +184,26 @@ public function parameters() * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - abstract public function getValueType(); + abstract public function getValueType(): string; /** * Sets a raw value coming from a mimedir (iCalendar/vCard) file. * * This has been 'unfolded', so only 1 line will be passed. Unescaping is * not yet done, but parameters are not included. - * - * @param string $val */ - abstract public function setRawMimeDirValue($val); + abstract public function setRawMimeDirValue(string $val): void; /** * Returns a raw mime-dir representation of the value. - * - * @return string */ - abstract public function getRawMimeDirValue(); + abstract public function getRawMimeDirValue(): string; /** * Turns the object back into a serialized blob. - * - * @return string */ - public function serialize() + public function serialize(): string { $str = $this->name; if ($this->group) { @@ -230,7 +216,7 @@ public function serialize() $str .= ':'.$this->getRawMimeDirValue(); - $str = \preg_replace( + $str = preg_replace( '/( (?:^.)? # 1 additional byte in first line because of missing single space (see next line) .{1,74} # max 75 bytes per line (1 byte is used for a single space added after every CRLF) @@ -241,17 +227,15 @@ public function serialize() ); // remove single space after last CRLF - return \substr($str, 0, -1); + return substr($str, 0, -1); } /** * Returns the value, in the format it should be encoded for JSON. * * This method must always return an array. - * - * @return array */ - public function getJsonValue() + public function getJsonValue(): array { return $this->getParts(); } @@ -260,8 +244,10 @@ public function getJsonValue() * Sets the JSON value, as it would appear in a jCard or jCal object. * * The value must always be an array. + * + * @throws InvalidDataException */ - public function setJsonValue(array $value) + public function setJsonValue(array $value): void { if (1 === count($value)) { $this->setValue(reset($value)); @@ -273,11 +259,9 @@ public function setJsonValue(array $value) /** * This method returns an array, with the representation as it should be * encoded in JSON. This is used to create jCard or jCal documents. - * - * @return array */ #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { $parameters = []; @@ -306,8 +290,10 @@ public function jsonSerialize() /** * Hydrate data from a XML subtree, as it would appear in a xCard or xCal * object. + * + * @throws InvalidDataException */ - public function setXmlValue(array $value) + public function setXmlValue(array $value): void { $this->setJsonValue($value); } @@ -318,7 +304,7 @@ public function setXmlValue(array $value) * * @param Xml\Writer $writer XML writer */ - public function xmlSerialize(Xml\Writer $writer) + public function xmlSerialize(Xml\Writer $writer): void { $parameters = []; @@ -354,7 +340,7 @@ public function xmlSerialize(Xml\Writer $writer) * * @param Xml\Writer $writer XML writer */ - protected function xmlSerializeValue(Xml\Writer $writer) + protected function xmlSerializeValue(Xml\Writer $writer): void { $valueType = strtolower($this->getValueType()); @@ -371,10 +357,8 @@ protected function xmlSerializeValue(Xml\Writer $writer) * If the property only had a single value, you will get just that. In the * case the property had multiple values, the contents will be escaped and * combined with ,. - * - * @return string */ - public function __toString() + public function __toString(): string { return (string) $this->getValue(); } @@ -384,21 +368,19 @@ public function __toString() /** * Checks if an array element exists. * - * @param mixed $name - * - * @return bool + * @param mixed $offset */ #[\ReturnTypeWillChange] - public function offsetExists($name) + public function offsetExists($offset): bool { - if (is_int($name)) { - return parent::offsetExists($name); + if (is_int($offset)) { + return parent::offsetExists($offset); } - $name = strtoupper($name); + $offset = strtoupper($offset); foreach ($this->parameters as $parameter) { - if ($parameter->name == $name) { + if ($parameter->name == $offset) { return true; } } @@ -411,36 +393,34 @@ public function offsetExists($name) * * If the parameter does not exist, null is returned. * - * @param string $name - * - * @return Node + * @param string|int $offset */ #[\ReturnTypeWillChange] - public function offsetGet($name) + public function offsetGet($offset): ?Node { - if (is_int($name)) { - return parent::offsetGet($name); + if (is_int($offset)) { + return parent::offsetGet($offset); } - $name = strtoupper($name); + $offset = strtoupper($offset); - if (!isset($this->parameters[$name])) { - return; + if (!isset($this->parameters[$offset])) { + return null; } - return $this->parameters[$name]; + return $this->parameters[$offset]; } /** * Creates a new parameter. * - * @param string $name - * @param mixed $value + * @param string|int $offset + * @param mixed $value */ #[\ReturnTypeWillChange] - public function offsetSet($name, $value) + public function offsetSet($offset, $value): void { - if (is_int($name)) { - parent::offsetSet($name, $value); + if (is_int($offset)) { + parent::offsetSet($offset, $value); // @codeCoverageIgnoreStart // This will never be reached, because an exception is always // thrown. @@ -448,20 +428,20 @@ public function offsetSet($name, $value) // @codeCoverageIgnoreEnd } - $param = new Parameter($this->root, $name, $value); + $param = new Parameter($this->root, $offset, $value); $this->parameters[$param->name] = $param; } /** * Removes one or more parameters with the specified name. * - * @param string $name + * @param string|int $offset */ #[\ReturnTypeWillChange] - public function offsetUnset($name) + public function offsetUnset($offset): void { - if (is_int($name)) { - parent::offsetUnset($name); + if (is_int($offset)) { + parent::offsetUnset($offset); // @codeCoverageIgnoreStart // This will never be reached, because an exception is always // thrown. @@ -469,7 +449,7 @@ public function offsetUnset($name) // @codeCoverageIgnoreEnd } - unset($this->parameters[strtoupper($name)]); + unset($this->parameters[strtoupper($offset)]); } /* }}} */ @@ -499,12 +479,8 @@ public function __clone() * * level - (number between 1 and 3 with severity information) * * message - (human readable message) * * node - (reference to the offending node) - * - * @param int $options - * - * @return array */ - public function validate($options = 0) + public function validate(int $options = 0): array { $warnings = []; @@ -514,10 +490,8 @@ public function validate($options = 0) $level = 3; if ($options & self::REPAIR) { $newValue = StringUtil::convertToUTF8($oldValue); - if (true || StringUtil::isUTF8($newValue)) { - $this->setRawMimeDirValue($newValue); - $level = 1; - } + $this->setRawMimeDirValue($newValue); + $level = 1; } if (preg_match('%([\x00-\x08\x0B-\x0C\x0E-\x1F\x7F])%', $oldValue, $matches)) { @@ -558,6 +532,7 @@ public function validate($options = 0) 'node' => $this, ]; } else { + /** @var Property $encoding */ $encoding = (string) $encoding; $allowedEncoding = []; @@ -609,7 +584,7 @@ public function validate($options = 0) * It's intended to remove all circular references, so PHP can easily clean * it up. */ - public function destroy() + public function destroy(): void { parent::destroy(); foreach ($this->parameters as $param) { diff --git a/lib/Property/Binary.php b/lib/Property/Binary.php index 1262dd054..8e2115c2e 100644 --- a/lib/Property/Binary.php +++ b/lib/Property/Binary.php @@ -2,6 +2,7 @@ namespace Sabre\VObject\Property; +use InvalidArgumentException; use Sabre\VObject\Property; /** @@ -23,10 +24,8 @@ class Binary extends Property /** * In case this is a multi-value property. This string will be used as a * delimiter. - * - * @var string */ - public $delimiter = ''; + public string $delimiter = ''; /** * Updates the current value. @@ -35,13 +34,13 @@ class Binary extends Property * * @param string|array $value */ - public function setValue($value) + public function setValue($value): void { if (is_array($value)) { if (1 === count($value)) { $this->value = $value[0]; } else { - throw new \InvalidArgumentException('The argument must either be a string or an array with only one child'); + throw new InvalidArgumentException('The argument must either be a string or an array with only one child'); } } else { $this->value = $value; @@ -53,20 +52,16 @@ public function setValue($value) * * This has been 'unfolded', so only 1 line will be passed. Unescaping is * not yet done, but parameters are not included. - * - * @param string $val */ - public function setRawMimeDirValue($val) + public function setRawMimeDirValue(string $val): void { $this->value = base64_decode($val); } /** * Returns a raw mime-dir representation of the value. - * - * @return string */ - public function getRawMimeDirValue() + public function getRawMimeDirValue(): string { return base64_encode($this->value); } @@ -76,10 +71,8 @@ public function getRawMimeDirValue() * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'BINARY'; } @@ -88,10 +81,8 @@ public function getValueType() * Returns the value, in the format it should be encoded for json. * * This method must always return an array. - * - * @return array */ - public function getJsonValue() + public function getJsonValue(): array { return [base64_encode($this->getValue())]; } @@ -101,7 +92,7 @@ public function getJsonValue() * * The value must always be an array. */ - public function setJsonValue(array $value) + public function setJsonValue(array $value): void { $value = array_map('base64_decode', $value); parent::setJsonValue($value); diff --git a/lib/Property/Boolean.php b/lib/Property/Boolean.php index 4bd6ffdfe..b7f06012c 100644 --- a/lib/Property/Boolean.php +++ b/lib/Property/Boolean.php @@ -23,21 +23,17 @@ class Boolean extends Property * * This has been 'unfolded', so only 1 line will be passed. Unescaping is * not yet done, but parameters are not included. - * - * @param string $val */ - public function setRawMimeDirValue($val) + public function setRawMimeDirValue(string $val): void { - $val = 'TRUE' === strtoupper($val) ? true : false; + $val = 'TRUE' === strtoupper($val); $this->setValue($val); } /** * Returns a raw mime-dir representation of the value. - * - * @return string */ - public function getRawMimeDirValue() + public function getRawMimeDirValue(): string { return $this->value ? 'TRUE' : 'FALSE'; } @@ -47,10 +43,8 @@ public function getRawMimeDirValue() * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'BOOLEAN'; } @@ -59,7 +53,7 @@ public function getValueType() * Hydrate data from a XML subtree, as it would appear in a xCard or xCal * object. */ - public function setXmlValue(array $value) + public function setXmlValue(array $value): void { $value = array_map( function ($value) { diff --git a/lib/Property/FlatText.php b/lib/Property/FlatText.php index d15cfe051..f1c529b65 100644 --- a/lib/Property/FlatText.php +++ b/lib/Property/FlatText.php @@ -2,6 +2,8 @@ namespace Sabre\VObject\Property; +use Sabre\VObject\InvalidDataException; + /** * FlatText property. * @@ -26,19 +28,17 @@ class FlatText extends Text { /** * Field separator. - * - * @var string */ - public $delimiter = ','; + public string $delimiter = ','; /** * Sets the value as a quoted-printable encoded string. * * Overriding this so we're not splitting on a ; delimiter. * - * @param string $val + * @throws InvalidDataException */ - public function setQuotedPrintableValue($val) + public function setQuotedPrintableValue(string $val): void { $val = quoted_printable_decode($val); $this->setValue($val); diff --git a/lib/Property/FloatValue.php b/lib/Property/FloatValue.php index e780ae6c1..b2e9f93e8 100644 --- a/lib/Property/FloatValue.php +++ b/lib/Property/FloatValue.php @@ -20,20 +20,16 @@ class FloatValue extends Property /** * In case this is a multi-value property. This string will be used as a * delimiter. - * - * @var string */ - public $delimiter = ';'; + public string $delimiter = ';'; /** * Sets a raw value coming from a mimedir (iCalendar/vCard) file. * * This has been 'unfolded', so only 1 line will be passed. Unescaping is * not yet done, but parameters are not included. - * - * @param string $val */ - public function setRawMimeDirValue($val) + public function setRawMimeDirValue(string $val): void { $val = explode($this->delimiter, $val); foreach ($val as &$item) { @@ -44,10 +40,8 @@ public function setRawMimeDirValue($val) /** * Returns a raw mime-dir representation of the value. - * - * @return string */ - public function getRawMimeDirValue() + public function getRawMimeDirValue(): string { return implode( $this->delimiter, @@ -60,10 +54,8 @@ public function getRawMimeDirValue() * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'FLOAT'; } @@ -72,10 +64,8 @@ public function getValueType() * Returns the value, in the format it should be encoded for JSON. * * This method must always return an array. - * - * @return array */ - public function getJsonValue() + public function getJsonValue(): array { $val = array_map('floatval', $this->getParts()); @@ -94,7 +84,7 @@ public function getJsonValue() * Hydrate data from a XML subtree, as it would appear in a xCard or xCal * object. */ - public function setXmlValue(array $value) + public function setXmlValue(array $value): void { $value = array_map('floatval', $value); parent::setXmlValue($value); @@ -103,10 +93,8 @@ public function setXmlValue(array $value) /** * This method serializes only the value of a property. This is used to * create xCard or xCal documents. - * - * @param Xml\Writer $writer XML writer */ - protected function xmlSerializeValue(Xml\Writer $writer) + protected function xmlSerializeValue(Xml\Writer $writer): void { // Special-casing the GEO property. // diff --git a/lib/Property/ICalendar/CalAddress.php b/lib/Property/ICalendar/CalAddress.php index c90967d79..01969e87d 100644 --- a/lib/Property/ICalendar/CalAddress.php +++ b/lib/Property/ICalendar/CalAddress.php @@ -18,20 +18,16 @@ class CalAddress extends Text /** * In case this is a multi-value property. This string will be used as a * delimiter. - * - * @var string */ - public $delimiter = ''; + public string $delimiter = ''; /** * Returns the type of value. * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'CAL-ADDRESS'; } @@ -43,10 +39,8 @@ public function getValueType() * uris to lower-case. * * Evolution in particular tends to encode mailto: as MAILTO:. - * - * @return string */ - public function getNormalizedValue() + public function getNormalizedValue(): string { $input = $this->getValue(); if (!strpos($input, ':')) { diff --git a/lib/Property/ICalendar/DateTime.php b/lib/Property/ICalendar/DateTime.php index ca71633b9..774ab7180 100644 --- a/lib/Property/ICalendar/DateTime.php +++ b/lib/Property/ICalendar/DateTime.php @@ -2,6 +2,8 @@ namespace Sabre\VObject\Property\ICalendar; +use DateInterval; +use DateTimeImmutable; use DateTimeInterface; use DateTimeZone; use Sabre\VObject\DateTimeParser; @@ -32,14 +34,16 @@ class DateTime extends Property * * @var string|null */ - public $delimiter = ','; + public string $delimiter = ','; /** * Sets a multi-valued property. * * You may also specify DateTime objects here. + * + * @throws InvalidDataException */ - public function setParts(array $parts) + public function setParts(array $parts): void { if (isset($parts[0]) && $parts[0] instanceof DateTimeInterface) { $this->setDateTimes($parts); @@ -56,8 +60,10 @@ public function setParts(array $parts) * Instead of strings, you may also use DateTime here. * * @param string|array|DateTimeInterface $value + * + * @throws InvalidDataException */ - public function setValue($value) + public function setValue($value): void { if (is_array($value) && isset($value[0]) && $value[0] instanceof DateTimeInterface) { $this->setDateTimes($value); @@ -74,29 +80,25 @@ public function setValue($value) * This has been 'unfolded', so only 1 line will be passed. Unescaping is * not yet done, but parameters are not included. * - * @param string $val + * @throws InvalidDataException */ - public function setRawMimeDirValue($val) + public function setRawMimeDirValue(string $val): void { $this->setValue(explode($this->delimiter, $val)); } /** * Returns a raw mime-dir representation of the value. - * - * @return string */ - public function getRawMimeDirValue() + public function getRawMimeDirValue(): string { return implode($this->delimiter, $this->getParts()); } /** * Returns true if this is a DATE-TIME value, false if it's a DATE. - * - * @return bool */ - public function hasTime() + public function hasTime(): bool { return 'DATE' !== strtoupper((string) $this['VALUE']); } @@ -106,7 +108,7 @@ public function hasTime() * * Note that DATE is always floating. */ - public function isFloating() + public function isFloating(): bool { return !$this->hasTime() || @@ -127,15 +129,13 @@ public function isFloating() * property or floating time, we will use the DateTimeZone argument to * figure out the exact date. * - * @param DateTimeZone $timeZone - * - * @return \DateTimeImmutable + * @throws InvalidDataException */ - public function getDateTime(DateTimeZone $timeZone = null) + public function getDateTime(DateTimeZone $timeZone = null): ?DateTimeImmutable { $dt = $this->getDateTimes($timeZone); if (!$dt) { - return; + return null; } return $dt[0]; @@ -148,14 +148,14 @@ public function getDateTime(DateTimeZone $timeZone = null) * property or floating time, we will use the DateTimeZone argument to * figure out the exact date. * - * @param DateTimeZone $timeZone + * @throws InvalidDataException * - * @return \DateTimeImmutable[] - * @return \DateTime[] + * @return DateInterval[]|DateTimeImmutable[] */ - public function getDateTimes(DateTimeZone $timeZone = null) + public function getDateTimes(DateTimeZone $timeZone = null): array { // Does the property have a TZID? + /** @var Property\FlatText $tzid */ $tzid = $this['TZID']; if ($tzid) { @@ -174,8 +174,10 @@ public function getDateTimes(DateTimeZone $timeZone = null) * Sets the property as a DateTime object. * * @param bool isFloating If set to true, timezones will be ignored + * + * @throws InvalidDataException */ - public function setDateTime(DateTimeInterface $dt, $isFloating = false) + public function setDateTime(DateTimeInterface $dt, $isFloating = false): void { $this->setDateTimes([$dt], $isFloating); } @@ -188,8 +190,10 @@ public function setDateTime(DateTimeInterface $dt, $isFloating = false) * * @param DateTimeInterface[] $dt * @param bool isFloating If set to true, timezones will be ignored + * + * @throws InvalidDataException */ - public function setDateTimes(array $dt, $isFloating = false) + public function setDateTimes(array $dt, $isFloating = false): void { $values = []; @@ -236,10 +240,8 @@ public function setDateTimes(array $dt, $isFloating = false) * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return $this->hasTime() ? 'DATE-TIME' : 'DATE'; } @@ -249,16 +251,16 @@ public function getValueType() * * This method must always return an array. * - * @return array + * @throws InvalidDataException */ - public function getJsonValue() + public function getJsonValue(): array { $dts = $this->getDateTimes(); $hasTime = $this->hasTime(); $isFloating = $this->isFloating(); $tz = $dts[0]->getTimeZone(); - $isUtc = $isFloating ? false : in_array($tz->getName(), ['UTC', 'GMT', 'Z']); + $isUtc = !$isFloating && in_array($tz->getName(), ['UTC', 'GMT', 'Z']); return array_map( function (DateTimeInterface $dt) use ($hasTime, $isUtc) { @@ -276,8 +278,10 @@ function (DateTimeInterface $dt) use ($hasTime, $isUtc) { * Sets the json value, as it would appear in a jCard or jCal object. * * The value must always be an array. + * + * @throws InvalidDataException */ - public function setJsonValue(array $value) + public function setJsonValue(array $value): void { // dates and times in jCal have one difference to dates and times in // iCalendar. In jCal date-parts are separated by dashes, and @@ -297,14 +301,16 @@ function ($item) { * We need to intercept offsetSet, because it may be used to alter the * VALUE from DATE-TIME to DATE or vice-versa. * - * @param string $name - * @param mixed $value + * @param string|int $offset + * @param mixed $value + * + * @throws InvalidDataException */ #[\ReturnTypeWillChange] - public function offsetSet($name, $value) + public function offsetSet($offset, $value): void { - parent::offsetSet($name, $value); - if ('VALUE' !== strtoupper($name)) { + parent::offsetSet($offset, $value); + if ('VALUE' !== strtoupper($offset)) { return; } @@ -329,12 +335,8 @@ public function offsetSet($name, $value) * 1 - The issue was repaired (only happens if REPAIR was turned on) * 2 - An inconsequential issue * 3 - A severe issue. - * - * @param int $options - * - * @return array */ - public function validate($options = 0) + public function validate(int $options = 0): array { $messages = parent::validate($options); $valueType = $this->getValueType(); diff --git a/lib/Property/ICalendar/Duration.php b/lib/Property/ICalendar/Duration.php index e18fe191e..0a189b14e 100644 --- a/lib/Property/ICalendar/Duration.php +++ b/lib/Property/ICalendar/Duration.php @@ -2,7 +2,9 @@ namespace Sabre\VObject\Property\ICalendar; +use DateInterval; use Sabre\VObject\DateTimeParser; +use Sabre\VObject\InvalidDataException; use Sabre\VObject\Property; /** @@ -21,30 +23,24 @@ class Duration extends Property /** * In case this is a multi-value property. This string will be used as a * delimiter. - * - * @var string */ - public $delimiter = ','; + public string $delimiter = ','; /** * Sets a raw value coming from a mimedir (iCalendar/vCard) file. * * This has been 'unfolded', so only 1 line will be passed. Unescaping is * not yet done, but parameters are not included. - * - * @param string $val */ - public function setRawMimeDirValue($val) + public function setRawMimeDirValue(string $val): void { $this->setValue(explode($this->delimiter, $val)); } /** * Returns a raw mime-dir representation of the value. - * - * @return string */ - public function getRawMimeDirValue() + public function getRawMimeDirValue(): string { return implode($this->delimiter, $this->getParts()); } @@ -54,10 +50,8 @@ public function getRawMimeDirValue() * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'DURATION'; } @@ -67,7 +61,9 @@ public function getValueType() * * If the property has more than one value, only the first is returned. * - * @return \DateInterval + * @throws InvalidDataException + * + * @return DateInterval|string */ public function getDateInterval() { diff --git a/lib/Property/ICalendar/Period.php b/lib/Property/ICalendar/Period.php index ae8a78911..7632cb4d1 100644 --- a/lib/Property/ICalendar/Period.php +++ b/lib/Property/ICalendar/Period.php @@ -3,6 +3,7 @@ namespace Sabre\VObject\Property\ICalendar; use Sabre\VObject\DateTimeParser; +use Sabre\VObject\InvalidDataException; use Sabre\VObject\Property; use Sabre\Xml; @@ -22,30 +23,24 @@ class Period extends Property /** * In case this is a multi-value property. This string will be used as a * delimiter. - * - * @var string */ - public $delimiter = ','; + public string $delimiter = ','; /** * Sets a raw value coming from a mimedir (iCalendar/vCard) file. * * This has been 'unfolded', so only 1 line will be passed. Unescaping is * not yet done, but parameters are not included. - * - * @param string $val */ - public function setRawMimeDirValue($val) + public function setRawMimeDirValue(string $val): void { $this->setValue(explode($this->delimiter, $val)); } /** * Returns a raw mime-dir representation of the value. - * - * @return string */ - public function getRawMimeDirValue() + public function getRawMimeDirValue(): string { return implode($this->delimiter, $this->getParts()); } @@ -55,10 +50,8 @@ public function getRawMimeDirValue() * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'PERIOD'; } @@ -68,7 +61,7 @@ public function getValueType() * * The value must always be an array. */ - public function setJsonValue(array $value) + public function setJsonValue(array $value): void { $value = array_map( function ($item) { @@ -84,9 +77,9 @@ function ($item) { * * This method must always return an array. * - * @return array + * @throws InvalidDataException */ - public function getJsonValue() + public function getJsonValue(): array { $return = []; foreach ($this->getParts() as $item) { @@ -116,9 +109,9 @@ public function getJsonValue() * This method serializes only the value of a property. This is used to * create xCard or xCal documents. * - * @param Xml\Writer $writer XML writer + * @throws InvalidDataException */ - protected function xmlSerializeValue(Xml\Writer $writer) + protected function xmlSerializeValue(Xml\Writer $writer): void { $writer->startElement(strtolower($this->getValueType())); $value = $this->getJsonValue(); diff --git a/lib/Property/ICalendar/Recur.php b/lib/Property/ICalendar/Recur.php index 3d632fec1..36e4e8f6b 100644 --- a/lib/Property/ICalendar/Recur.php +++ b/lib/Property/ICalendar/Recur.php @@ -2,6 +2,9 @@ namespace Sabre\VObject\Property\ICalendar; +use InvalidArgumentException; +use Sabre\VObject\InvalidDataException; +use Sabre\VObject\Node; use Sabre\VObject\Property; use Sabre\Xml; @@ -24,6 +27,11 @@ */ class Recur extends Property { + /** + * Reference to the parent object, if this is not the top object. + */ + public ?Node $parent; + /** * Updates the current value. * @@ -31,7 +39,7 @@ class Recur extends Property * * @param string|array $value */ - public function setValue($value) + public function setValue($value): void { // If we're getting the data from json, we'll be receiving an object if ($value instanceof \StdClass) { @@ -61,7 +69,7 @@ public function setValue($value) } elseif (is_string($value)) { $this->value = self::stringToArray($value); } else { - throw new \InvalidArgumentException('You must either pass a string, or a key=>value array'); + throw new InvalidArgumentException('You must either pass a string, or a key=>value array'); } } @@ -73,10 +81,8 @@ public function setValue($value) * it as a string. * * To get the correct multi-value version, use getParts. - * - * @return string */ - public function getValue() + public function getValue(): string { $out = []; foreach ($this->value as $key => $value) { @@ -89,7 +95,7 @@ public function getValue() /** * Sets a multi-valued property. */ - public function setParts(array $parts) + public function setParts(array $parts): void { $this->setValue($parts); } @@ -99,10 +105,8 @@ public function setParts(array $parts) * * This method always returns an array, if there was only a single value, * it will still be wrapped in an array. - * - * @return array */ - public function getParts() + public function getParts(): array { return $this->value; } @@ -112,20 +116,16 @@ public function getParts() * * This has been 'unfolded', so only 1 line will be passed. Unescaping is * not yet done, but parameters are not included. - * - * @param string $val */ - public function setRawMimeDirValue($val) + public function setRawMimeDirValue(string $val): void { $this->setValue($val); } /** * Returns a raw mime-dir representation of the value. - * - * @return string */ - public function getRawMimeDirValue() + public function getRawMimeDirValue(): string { return $this->getValue(); } @@ -135,10 +135,8 @@ public function getRawMimeDirValue() * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'RECUR'; } @@ -148,9 +146,9 @@ public function getValueType() * * This method must always return an array. * - * @return array + * @throws InvalidDataException */ - public function getJsonValue() + public function getJsonValue(): array { $values = []; foreach ($this->getParts() as $k => $v) { @@ -170,10 +168,8 @@ public function getJsonValue() /** * This method serializes only the value of a property. This is used to * create xCard or xCal documents. - * - * @param Xml\Writer $writer XML writer */ - protected function xmlSerializeValue(Xml\Writer $writer) + protected function xmlSerializeValue(Xml\Writer $writer): void { $valueType = strtolower($this->getValueType()); @@ -184,12 +180,8 @@ protected function xmlSerializeValue(Xml\Writer $writer) /** * Parses an RRULE value string, and turns it into a struct-ish array. - * - * @param string $value - * - * @return array */ - public static function stringToArray($value) + public static function stringToArray(string $value): array { $value = strtoupper($value); $newValue = []; @@ -227,12 +219,8 @@ public static function stringToArray($value) * 1 - The issue was repaired (only happens if REPAIR was turned on) * 2 - An inconsequential issue * 3 - A severe issue. - * - * @param int $options - * - * @return array */ - public function validate($options = 0) + public function validate(int $options = 0): array { $repair = ($options & self::REPAIR); diff --git a/lib/Property/IntegerValue.php b/lib/Property/IntegerValue.php index 3ae775214..cb9f3569b 100644 --- a/lib/Property/IntegerValue.php +++ b/lib/Property/IntegerValue.php @@ -21,20 +21,16 @@ class IntegerValue extends Property * * This has been 'unfolded', so only 1 line will be passed. Unescaping is * not yet done, but parameters are not included. - * - * @param string $val */ - public function setRawMimeDirValue($val) + public function setRawMimeDirValue(string $val): void { $this->setValue((int) $val); } /** * Returns a raw mime-dir representation of the value. - * - * @return string */ - public function getRawMimeDirValue() + public function getRawMimeDirValue(): string { return $this->value; } @@ -44,10 +40,8 @@ public function getRawMimeDirValue() * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'INTEGER'; } @@ -56,10 +50,8 @@ public function getValueType() * Returns the value, in the format it should be encoded for json. * * This method must always return an array. - * - * @return array */ - public function getJsonValue() + public function getJsonValue(): array { return [(int) $this->getValue()]; } @@ -68,7 +60,7 @@ public function getJsonValue() * Hydrate data from a XML subtree, as it would appear in a xCard or xCal * object. */ - public function setXmlValue(array $value) + public function setXmlValue(array $value): void { $value = array_map('intval', $value); parent::setXmlValue($value); diff --git a/lib/Property/Text.php b/lib/Property/Text.php index 16d2c07f4..281e65e8a 100644 --- a/lib/Property/Text.php +++ b/lib/Property/Text.php @@ -2,11 +2,24 @@ namespace Sabre\VObject\Property; +use function array_pad; +use function bin2hex; +use function count; +use function implode; +use function is_null; +use function ord; +use function preg_replace; use Sabre\VObject\Component; use Sabre\VObject\Document; +use Sabre\VObject\InvalidDataException; use Sabre\VObject\Parser\MimeDir; use Sabre\VObject\Property; use Sabre\Xml; +use function str_replace; +use function strlen; +use function strpos; +use function strtoupper; +use function substr; /** * Text property. @@ -22,17 +35,13 @@ class Text extends Property /** * In case this is a multi-value property. This string will be used as a * delimiter. - * - * @var string */ - public $delimiter = ','; + public string $delimiter = ','; /** * List of properties that are considered 'structured'. - * - * @var array */ - protected $structuredValues = [ + protected array $structuredValues = [ // vCard 'N', 'ADR', @@ -49,10 +58,8 @@ class Text extends Property * * N must for instance be represented as 5 components, separated by ;, even * if the last few components are unused. - * - * @var array */ - protected $minimumPropertyValues = [ + protected array $minimumPropertyValues = [ 'N' => 5, 'ADR' => 7, ]; @@ -65,12 +72,11 @@ class Text extends Property * Parameter objects. * * @param Component $root The root document - * @param string $name * @param string|array|null $value * @param array $parameters List of parameters - * @param string $group The vcard property group + * @param string|null $group The vcard property group */ - public function __construct(Component $root, $name, $value = null, array $parameters = [], $group = null) + public function __construct(Component $root, string $name, $value = null, array $parameters = [], string $group = null) { // There's two types of multi-valued text properties: // 1. multivalue properties. @@ -90,19 +96,17 @@ public function __construct(Component $root, $name, $value = null, array $parame * This has been 'unfolded', so only 1 line will be passed. Unescaping is * not yet done, but parameters are not included. * - * @param string $val + * @throws InvalidDataException */ - public function setRawMimeDirValue($val) + public function setRawMimeDirValue(string $val): void { $this->setValue(MimeDir::unescapeValue($val, $this->delimiter)); } /** * Sets the value as a quoted-printable encoded string. - * - * @param string $val */ - public function setQuotedPrintableValue($val) + public function setQuotedPrintableValue(string $val): void { $val = quoted_printable_decode($val); @@ -119,10 +123,8 @@ public function setQuotedPrintableValue($val) /** * Returns a raw mime-dir representation of the value. - * - * @return string */ - public function getRawMimeDirValue() + public function getRawMimeDirValue(): string { $val = $this->getParts(); @@ -159,10 +161,8 @@ public function getRawMimeDirValue() * Returns the value, in the format it should be encoded for json. * * This method must always return an array. - * - * @return array */ - public function getJsonValue() + public function getJsonValue(): array { // Structured text values should always be returned as a single // array-item. Multi-value text should be returned as multiple items in @@ -179,20 +179,16 @@ public function getJsonValue() * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'TEXT'; } /** * Turns the object back into a serialized blob. - * - * @return string */ - public function serialize() + public function serialize(): string { // We need to kick in a special type of encoding, if it's a 2.1 vcard. if (Document::VCARD21 !== $this->root->getDocumentType()) { @@ -202,16 +198,16 @@ public function serialize() $val = $this->getParts(); if (isset($this->minimumPropertyValues[$this->name])) { - $val = \array_pad($val, $this->minimumPropertyValues[$this->name], ''); + $val = array_pad($val, $this->minimumPropertyValues[$this->name], ''); } // Imploding multiple parts into a single value, and splitting the // values with ;. - if (\count($val) > 1) { + if (count($val) > 1) { foreach ($val as $k => $v) { - $val[$k] = \str_replace(';', '\;', $v); + $val[$k] = str_replace(';', '\;', $v); } - $val = \implode(';', $val); + $val = implode(';', $val); } else { $val = $val[0]; } @@ -229,30 +225,30 @@ public function serialize() // If the resulting value contains a \n, we must encode it as // quoted-printable. - if (false !== \strpos($val, "\n")) { + if (false !== strpos($val, "\n")) { $str .= ';ENCODING=QUOTED-PRINTABLE:'; $lastLine = $str; - $out = null; + $out = ''; // The PHP built-in quoted-printable-encode does not correctly // encode newlines for us. Specifically, the \r\n sequence must in // vcards be encoded as =0D=OA and we must insert soft-newlines // every 75 bytes. - for ($ii = 0; $ii < \strlen($val); ++$ii) { - $ord = \ord($val[$ii]); + for ($ii = 0; $ii < strlen($val); ++$ii) { + $ord = ord($val[$ii]); // These characters are encoded as themselves. if ($ord >= 32 && $ord <= 126) { $lastLine .= $val[$ii]; } else { - $lastLine .= '='.\strtoupper(\bin2hex($val[$ii])); + $lastLine .= '='.strtoupper(bin2hex($val[$ii])); } - if (\strlen($lastLine) >= 75) { + if (strlen($lastLine) >= 75) { // Soft line break $out .= $lastLine."=\r\n "; $lastLine = null; } } - if (!\is_null($lastLine)) { + if (!is_null($lastLine)) { $out .= $lastLine."\r\n"; } @@ -260,7 +256,7 @@ public function serialize() } else { $str .= ':'.$val; - $str = \preg_replace( + $str = preg_replace( '/( (?:^.)? # 1 additional byte in first line because of missing single space (see next line) .{1,74} # max 75 bytes per line (1 byte is used for a single space added after every CRLF) @@ -271,21 +267,19 @@ public function serialize() ); // remove single space after last CRLF - return \substr($str, 0, -1); + return substr($str, 0, -1); } } /** * This method serializes only the value of a property. This is used to * create xCard or xCal documents. - * - * @param Xml\Writer $writer XML writer */ - protected function xmlSerializeValue(Xml\Writer $writer) + protected function xmlSerializeValue(Xml\Writer $writer): void { $values = $this->getParts(); - $map = function ($items) use ($values, $writer) { + $map = function (array $items) use ($values, $writer): void { foreach ($items as $i => $item) { $writer->writeElement( $item, @@ -362,12 +356,8 @@ protected function xmlSerializeValue(Xml\Writer $writer) * * level - (number between 1 and 3 with severity information) * * message - (human readable message) * * node - (reference to the offending node) - * - * @param int $options - * - * @return array */ - public function validate($options = 0) + public function validate(int $options = 0): array { $warnings = parent::validate($options); diff --git a/lib/Property/Time.php b/lib/Property/Time.php index 1b81609aa..67a41a243 100644 --- a/lib/Property/Time.php +++ b/lib/Property/Time.php @@ -3,6 +3,7 @@ namespace Sabre\VObject\Property; use Sabre\VObject\DateTimeParser; +use Sabre\VObject\InvalidDataException; /** * Time property. @@ -18,20 +19,16 @@ class Time extends Text /** * In case this is a multi-value property. This string will be used as a * delimiter. - * - * @var string */ - public $delimiter = ''; + public string $delimiter = ''; /** * Returns the type of value. * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'TIME'; } @@ -41,7 +38,7 @@ public function getValueType() * * The value must always be an array. */ - public function setJsonValue(array $value) + public function setJsonValue(array $value): void { // Removing colons from value. $value = str_replace( @@ -62,9 +59,9 @@ public function setJsonValue(array $value) * * This method must always return an array. * - * @return array + * @throws InvalidDataException */ - public function getJsonValue() + public function getJsonValue(): array { $parts = DateTimeParser::parseVCardTime($this->getValue()); $timeStr = ''; @@ -118,7 +115,7 @@ public function getJsonValue() * Hydrate data from a XML subtree, as it would appear in a xCard or xCal * object. */ - public function setXmlValue(array $value) + public function setXmlValue(array $value): void { $value = array_map( function ($value) { diff --git a/lib/Property/Unknown.php b/lib/Property/Unknown.php index 6f404c286..3bcf61351 100644 --- a/lib/Property/Unknown.php +++ b/lib/Property/Unknown.php @@ -18,10 +18,8 @@ class Unknown extends Text * Returns the value, in the format it should be encoded for json. * * This method must always return an array. - * - * @return array */ - public function getJsonValue() + public function getJsonValue(): array { return [$this->getRawMimeDirValue()]; } @@ -31,10 +29,8 @@ public function getJsonValue() * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'UNKNOWN'; } diff --git a/lib/Property/Uri.php b/lib/Property/Uri.php index 1ad1fb199..48a831877 100644 --- a/lib/Property/Uri.php +++ b/lib/Property/Uri.php @@ -19,30 +19,24 @@ class Uri extends Text /** * In case this is a multi-value property. This string will be used as a * delimiter. - * - * @var string */ - public $delimiter = ''; + public string $delimiter = ''; /** * Returns the type of value. * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'URI'; } /** * Returns an iterable list of children. - * - * @return array */ - public function parameters() + public function parameters(): array { $parameters = parent::parameters(); if (!isset($parameters['VALUE']) && in_array($this->name, ['URL', 'PHOTO'])) { @@ -65,10 +59,8 @@ public function parameters() * * This has been 'unfolded', so only 1 line will be passed. Unescaping is * not yet done, but parameters are not included. - * - * @param string $val */ - public function setRawMimeDirValue($val) + public function setRawMimeDirValue(string $val): void { // Normally we don't need to do any type of unescaping for these // properties, however.. we've noticed that Google Contacts @@ -100,10 +92,8 @@ public function setRawMimeDirValue($val) /** * Returns a raw mime-dir representation of the value. - * - * @return string */ - public function getRawMimeDirValue() + public function getRawMimeDirValue(): string { if (is_array($this->value)) { $value = $this->value[0]; diff --git a/lib/Property/UtcOffset.php b/lib/Property/UtcOffset.php index 04b88447f..09aab0151 100644 --- a/lib/Property/UtcOffset.php +++ b/lib/Property/UtcOffset.php @@ -2,6 +2,8 @@ namespace Sabre\VObject\Property; +use Sabre\VObject\InvalidDataException; + /** * UtcOffset property. * @@ -16,20 +18,16 @@ class UtcOffset extends Text /** * In case this is a multi-value property. This string will be used as a * delimiter. - * - * @var string */ - public $delimiter = ''; + public string $delimiter = ''; /** * Returns the type of value. * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'UTC-OFFSET'; } @@ -38,8 +36,10 @@ public function getValueType() * Sets the JSON value, as it would appear in a jCard or jCal object. * * The value must always be an array. + * + * @throws InvalidDataException */ - public function setJsonValue(array $value) + public function setJsonValue(array $value): void { $value = array_map( function ($value) { @@ -54,10 +54,8 @@ function ($value) { * Returns the value, in the format it should be encoded for JSON. * * This method must always return an array. - * - * @return array */ - public function getJsonValue() + public function getJsonValue(): array { return array_map( function ($value) { diff --git a/lib/Property/VCard/Date.php b/lib/Property/VCard/Date.php index fc679d572..1ad9fedc2 100644 --- a/lib/Property/VCard/Date.php +++ b/lib/Property/VCard/Date.php @@ -18,10 +18,8 @@ class Date extends DateAndOrTime * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'DATE'; } @@ -29,7 +27,7 @@ public function getValueType() /** * Sets the property as a DateTime object. */ - public function setDateTime(\DateTimeInterface $dt) + public function setDateTime(\DateTimeInterface $dt): void { $this->value = $dt->format('Ymd'); } diff --git a/lib/Property/VCard/DateAndOrTime.php b/lib/Property/VCard/DateAndOrTime.php index 7bf79c48c..470725c89 100644 --- a/lib/Property/VCard/DateAndOrTime.php +++ b/lib/Property/VCard/DateAndOrTime.php @@ -5,6 +5,7 @@ use DateTime; use DateTimeImmutable; use DateTimeInterface; +use InvalidArgumentException; use Sabre\VObject\DateTimeParser; use Sabre\VObject\InvalidDataException; use Sabre\VObject\Property; @@ -23,20 +24,16 @@ class DateAndOrTime extends Property { /** * Field separator. - * - * @var string */ - public $delimiter = ''; + public string $delimiter = ''; /** * Returns the type of value. * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'DATE-AND-OR-TIME'; } @@ -46,10 +43,10 @@ public function getValueType() * * You may also specify DateTimeInterface objects here. */ - public function setParts(array $parts) + public function setParts(array $parts): void { if (count($parts) > 1) { - throw new \InvalidArgumentException('Only one value allowed'); + throw new InvalidArgumentException('Only one value allowed'); } if (isset($parts[0]) && $parts[0] instanceof DateTimeInterface) { $this->setDateTime($parts[0]); @@ -67,7 +64,7 @@ public function setParts(array $parts) * * @param string|array|DateTimeInterface $value */ - public function setValue($value) + public function setValue($value): void { if ($value instanceof DateTimeInterface) { $this->setDateTime($value); @@ -79,7 +76,7 @@ public function setValue($value) /** * Sets the property as a DateTime object. */ - public function setDateTime(DateTimeInterface $dt) + public function setDateTime(DateTimeInterface $dt): void { $tz = $dt->getTimeZone(); $isUtc = in_array($tz->getName(), ['UTC', 'GMT', 'Z']); @@ -108,9 +105,9 @@ public function setDateTime(DateTimeInterface $dt) * current values for those. So at the time of writing, if the year was * omitted, we would have filled in 2014. * - * @return DateTimeImmutable + * @throws InvalidDataException */ - public function getDateTime() + public function getDateTime(): DateTimeImmutable { $now = new DateTime(); @@ -136,9 +133,9 @@ public function getDateTime() * * This method must always return an array. * - * @return array + * @throws InvalidDataException */ - public function getJsonValue() + public function getJsonValue(): array { $parts = DateTimeParser::parseVCardDateTime($this->getValue()); @@ -228,16 +225,16 @@ public function getJsonValue() * This method serializes only the value of a property. This is used to * create xCard or xCal documents. * - * @param Xml\Writer $writer XML writer + * @throws InvalidDataException */ - protected function xmlSerializeValue(Xml\Writer $writer) + protected function xmlSerializeValue(Xml\Writer $writer): void { $valueType = strtolower($this->getValueType()); $parts = DateTimeParser::parseVCardDateAndOrTime($this->getValue()); $value = ''; // $d = defined - $d = function ($part) use ($parts) { + $d = function ($part) use ($parts): bool { return !is_null($parts[$part]); }; @@ -307,20 +304,16 @@ protected function xmlSerializeValue(Xml\Writer $writer) * * This has been 'unfolded', so only 1 line will be passed. Unescaping is * not yet done, but parameters are not included. - * - * @param string $val */ - public function setRawMimeDirValue($val) + public function setRawMimeDirValue(string $val): void { $this->setValue($val); } /** * Returns a raw mime-dir representation of the value. - * - * @return string */ - public function getRawMimeDirValue() + public function getRawMimeDirValue(): string { return implode($this->delimiter, $this->getParts()); } @@ -342,12 +335,8 @@ public function getRawMimeDirValue() * 1 - The issue was repaired (only happens if REPAIR was turned on) * 2 - An inconsequential issue * 3 - A severe issue. - * - * @param int $options - * - * @return array */ - public function validate($options = 0) + public function validate(int $options = 0): array { $messages = parent::validate($options); $value = $this->getValue(); diff --git a/lib/Property/VCard/DateTime.php b/lib/Property/VCard/DateTime.php index 49c1f3555..c71071f1a 100644 --- a/lib/Property/VCard/DateTime.php +++ b/lib/Property/VCard/DateTime.php @@ -18,10 +18,8 @@ class DateTime extends DateAndOrTime * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'DATE-TIME'; } diff --git a/lib/Property/VCard/LanguageTag.php b/lib/Property/VCard/LanguageTag.php index 318ea0231..c3b996f52 100644 --- a/lib/Property/VCard/LanguageTag.php +++ b/lib/Property/VCard/LanguageTag.php @@ -20,20 +20,16 @@ class LanguageTag extends Property * * This has been 'unfolded', so only 1 line will be passed. Unescaping is * not yet done, but parameters are not included. - * - * @param string $val */ - public function setRawMimeDirValue($val) + public function setRawMimeDirValue(string $val): void { $this->setValue($val); } /** * Returns a raw mime-dir representation of the value. - * - * @return string */ - public function getRawMimeDirValue() + public function getRawMimeDirValue(): string { return $this->getValue(); } @@ -43,10 +39,8 @@ public function getRawMimeDirValue() * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'LANGUAGE-TAG'; } diff --git a/lib/Property/VCard/PhoneNumber.php b/lib/Property/VCard/PhoneNumber.php index b714ffd03..f007be3df 100644 --- a/lib/Property/VCard/PhoneNumber.php +++ b/lib/Property/VCard/PhoneNumber.php @@ -13,17 +13,15 @@ */ class PhoneNumber extends Property\Text { - protected $structuredValues = []; + protected array $structuredValues = []; /** * Returns the type of value. * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'PHONE-NUMBER'; } diff --git a/lib/Property/VCard/TimeStamp.php b/lib/Property/VCard/TimeStamp.php index da6ea3d44..80739237e 100644 --- a/lib/Property/VCard/TimeStamp.php +++ b/lib/Property/VCard/TimeStamp.php @@ -3,6 +3,7 @@ namespace Sabre\VObject\Property\VCard; use Sabre\VObject\DateTimeParser; +use Sabre\VObject\InvalidDataException; use Sabre\VObject\Property\Text; use Sabre\Xml; @@ -20,20 +21,16 @@ class TimeStamp extends Text /** * In case this is a multi-value property. This string will be used as a * delimiter. - * - * @var string */ - public $delimiter = ''; + public string $delimiter = ''; /** * Returns the type of value. * * This corresponds to the VALUE= parameter. Every property also has a * 'default' valueType. - * - * @return string */ - public function getValueType() + public function getValueType(): string { return 'TIMESTAMP'; } @@ -43,9 +40,9 @@ public function getValueType() * * This method must always return an array. * - * @return array + * @throws InvalidDataException */ - public function getJsonValue() + public function getJsonValue(): array { $parts = DateTimeParser::parseVCardDateTime($this->getValue()); @@ -68,10 +65,8 @@ public function getJsonValue() /** * This method serializes only the value of a property. This is used to * create xCard or xCal documents. - * - * @param Xml\Writer $writer XML writer */ - protected function xmlSerializeValue(Xml\Writer $writer) + protected function xmlSerializeValue(Xml\Writer $writer): void { // xCard is the only XML and JSON format that has the same date and time // format than vCard. diff --git a/lib/Reader.php b/lib/Reader.php index 055d546a5..353186920 100644 --- a/lib/Reader.php +++ b/lib/Reader.php @@ -2,6 +2,8 @@ namespace Sabre\VObject; +use Sabre\Xml\LibXMLException; + /** * iCalendar/vCard/jCal/jCard/xCal/xCard reader object. * @@ -18,13 +20,13 @@ class Reader * If this option is passed to the reader, it will be less strict about the * validity of the lines. */ - const OPTION_FORGIVING = 1; + public const OPTION_FORGIVING = 1; /** * If this option is turned on, any lines we cannot parse will be ignored * by the reader. */ - const OPTION_IGNORE_INVALID_LINES = 2; + public const OPTION_IGNORE_INVALID_LINES = 2; /** * Parses a vCard or iCalendar object, and returns the top component. @@ -35,18 +37,15 @@ class Reader * You can either supply a string, or a readable stream for input. * * @param string|resource $data - * @param int $options - * @param string $charset * - * @return Document + * @throws ParseException */ - public static function read($data, $options = 0, $charset = 'UTF-8') + public static function read($data, int $options = 0, string $charset = 'UTF-8'): ?Document { $parser = new Parser\MimeDir(); $parser->setCharset($charset); - $result = $parser->parse($data, $options); - return $result; + return $parser->parse($data, $options); } /** @@ -60,16 +59,15 @@ public static function read($data, $options = 0, $charset = 'UTF-8') * input. * * @param string|resource|array $data - * @param int $options * - * @return Document + * @throws EofException + * @throws ParseException|InvalidDataException */ - public static function readJson($data, $options = 0) + public static function readJson($data, int $options = 0): ?Document { $parser = new Parser\Json(); - $result = $parser->parse($data, $options); - return $result; + return $parser->parse($data, $options); } /** @@ -81,15 +79,16 @@ public static function readJson($data, $options = 0) * You can either supply a string, or a readable stream for input. * * @param string|resource $data - * @param int $options * - * @return Document + * @throws EofException + * @throws InvalidDataException + * @throws ParseException + * @throws LibXMLException */ - public static function readXML($data, $options = 0) + public static function readXML($data, int $options = 0): ?Document { $parser = new Parser\XML(); - $result = $parser->parse($data, $options); - return $result; + return $parser->parse($data, $options); } } diff --git a/lib/Recur/EventIterator.php b/lib/Recur/EventIterator.php index 61f05d7de..9362ba47f 100644 --- a/lib/Recur/EventIterator.php +++ b/lib/Recur/EventIterator.php @@ -6,8 +6,10 @@ use DateTimeInterface; use DateTimeZone; use InvalidArgumentException; +use Iterator; use Sabre\VObject\Component; use Sabre\VObject\Component\VEvent; +use Sabre\VObject\InvalidDataException; use Sabre\VObject\Settings; /** @@ -58,21 +60,17 @@ * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License */ -class EventIterator implements \Iterator +class EventIterator implements Iterator { /** * Reference timeZone for floating dates and times. - * - * @var DateTimeZone */ - protected $timeZone; + protected DateTimeZone $timeZone; /** * True if we're iterating an all-day event. - * - * @var bool */ - protected $allDay = false; + protected bool $allDay = false; /** * Creates the iterator. @@ -88,12 +86,15 @@ class EventIterator implements \Iterator * * The $uid parameter is only required for the first method. * - * @param Component|array $input - * @param string|null $uid - * @param DateTimeZone $timeZone reference timezone for floating dates and - * times + * @param Component|Component\VCalendar|array $input + * @param DateTimeZone|null $timeZone reference timezone for floating dates and + * times + * + * @throws MaxInstancesExceededException + * @throws NoInstancesException + * @throws InvalidDataException */ - public function __construct($input, $uid = null, DateTimeZone $timeZone = null) + public function __construct($input, string $uid = null, DateTimeZone $timeZone = null) { if (is_null($timeZone)) { $timeZone = new DateTimeZone('UTC'); @@ -107,7 +108,6 @@ public function __construct($input, $uid = null, DateTimeZone $timeZone = null) $events = [$input]; } else { // Calendar + UID mode. - $uid = (string) $uid; if (!$uid) { throw new InvalidArgumentException('The UID argument is required when a VCALENDAR is passed to this constructor'); } @@ -117,6 +117,7 @@ public function __construct($input, $uid = null, DateTimeZone $timeZone = null) $events = $input->getByUID($uid); } + /** @var VEvent[] $events */ foreach ($events as $vevent) { if (!isset($vevent->{'RECURRENCE-ID'})) { $this->masterEvent = $vevent; @@ -199,11 +200,13 @@ public function __construct($input, $uid = null, DateTimeZone $timeZone = null) * @return DateTimeImmutable */ #[\ReturnTypeWillChange] - public function current() + public function current(): ?DateTimeImmutable { if ($this->currentDate) { return clone $this->currentDate; } + + return null; } /** @@ -212,11 +215,13 @@ public function current() * * @return DateTimeImmutable */ - public function getDtStart() + public function getDtStart(): ?DateTimeImmutable { if ($this->currentDate) { return clone $this->currentDate; } + + return null; } /** @@ -224,11 +229,13 @@ public function getDtStart() * event. * * @return DateTimeImmutable + * + * @throws MaxInstancesExceededException|InvalidDataException */ - public function getDtEnd() + public function getDtEnd(): ?DateTimeImmutable { if (!$this->valid()) { - return; + return null; } if ($this->currentOverriddenEvent && $this->currentOverriddenEvent->DTEND) { return $this->currentOverriddenEvent->DTEND->getDateTime($this->timeZone); @@ -245,14 +252,16 @@ public function getDtEnd() * This VEVENT will have a recurrence id, and its DTSTART and DTEND * altered. * - * @return VEvent + * @throws MaxInstancesExceededException + * @throws InvalidDataException */ - public function getEventObject() + public function getEventObject(): VEvent { if ($this->currentOverriddenEvent) { return $this->currentOverriddenEvent; } + /** @var VEvent $event */ $event = clone $this->masterEvent; // Ignoring the following block, because PHPUnit's code coverage @@ -283,11 +292,9 @@ public function getEventObject() * Returns the current position of the iterator. * * This is for us simply a 0-based index. - * - * @return int */ #[\ReturnTypeWillChange] - public function key() + public function key(): int { // The counter is always 1 ahead. return $this->counter - 1; @@ -297,10 +304,10 @@ public function key() * This is called after next, to see if the iterator is still at a valid * position, or if it's at the end. * - * @return bool + * @throws MaxInstancesExceededException */ #[\ReturnTypeWillChange] - public function valid() + public function valid(): bool { if ($this->counter > Settings::$maxRecurrences && -1 !== Settings::$maxRecurrences) { throw new MaxInstancesExceededException('Recurring events are only allowed to generate '.Settings::$maxRecurrences); @@ -313,6 +320,8 @@ public function valid() * Sets the iterator back to the starting point. * * @return void + * + * @throws InvalidDataException */ #[\ReturnTypeWillChange] public function rewind() @@ -321,6 +330,7 @@ public function rewind() // re-creating overridden event index. $index = []; foreach ($this->overriddenEvents as $key => $event) { + /** @var VEvent $event */ $stamp = $event->DTSTART->getDateTime($this->timeZone)->getTimeStamp(); $index[$stamp][] = $key; } @@ -339,6 +349,8 @@ public function rewind() * Advances the iterator with one step. * * @return void + * + * @throws InvalidDataException */ #[\ReturnTypeWillChange] public function next() @@ -393,8 +405,10 @@ public function next() /** * Quickly jump to a date in the future. + * + * @throws MaxInstancesExceededException|InvalidDataException */ - public function fastForward(DateTimeInterface $dateTime) + public function fastForward(DateTimeInterface $dateTime): void { while ($this->valid() && $this->getDtEnd() <= $dateTime) { $this->next(); @@ -403,10 +417,8 @@ public function fastForward(DateTimeInterface $dateTime) /** * Returns true if this recurring event never ends. - * - * @return bool */ - public function isInfinite() + public function isInfinite(): bool { return $this->recurIterator->isInfinite(); } @@ -414,9 +426,9 @@ public function isInfinite() /** * RRULE parser. * - * @var RRuleIterator + * @var RRuleIterator|RDateIterator */ - protected $recurIterator; + protected Iterator $recurIterator; /** * The duration, in seconds, of the master event. @@ -427,71 +439,53 @@ public function isInfinite() /** * A reference to the main (master) event. - * - * @var VEVENT */ - protected $masterEvent; + protected ?VEvent $masterEvent = null; /** * List of overridden events. - * - * @var array */ - protected $overriddenEvents = []; + protected array $overriddenEvents = []; /** * Overridden event index. * * Key is timestamp, value is the list of indexes of the item in the $overriddenEvent * property. - * - * @var array */ - protected $overriddenEventsIndex; + protected array $overriddenEventsIndex; /** * A list of recurrence-id's that are either part of EXDATE, or are * overridden. - * - * @var array */ - protected $exceptions = []; + protected array $exceptions = []; /** * Internal event counter. - * - * @var int */ - protected $counter; + protected int $counter = 0; /** * The very start of the iteration process. - * - * @var DateTimeImmutable */ - protected $startDate; + protected ?DateTimeImmutable $startDate; /** * Where we are currently in the iteration process. - * - * @var DateTimeImmutable */ - protected $currentDate; + protected ?DateTimeImmutable $currentDate = null; /** * The next date from the rrule parser. * * Sometimes we need to temporary store the next date, because an * overridden event came before. - * - * @var DateTimeImmutable */ - protected $nextDate; + protected ?DateTimeImmutable $nextDate = null; /** * The event that overwrites the current iteration. - * - * @var VEVENT */ - protected $currentOverriddenEvent; + protected ?VEvent $currentOverriddenEvent = null; } diff --git a/lib/Recur/RDateIterator.php b/lib/Recur/RDateIterator.php index 5d56657fa..b5337fb15 100644 --- a/lib/Recur/RDateIterator.php +++ b/lib/Recur/RDateIterator.php @@ -5,6 +5,7 @@ use DateTimeInterface; use Iterator; use Sabre\VObject\DateTimeParser; +use Sabre\VObject\InvalidDataException; /** * RRuleParser. @@ -47,11 +48,9 @@ public function current() /** * Returns the current item number. - * - * @return int */ #[\ReturnTypeWillChange] - public function key() + public function key(): int { return $this->counter; } @@ -59,11 +58,9 @@ public function key() /** * Returns whether the current item is a valid item for the recurrence * iterator. - * - * @return bool */ #[\ReturnTypeWillChange] - public function valid() + public function valid(): bool { return $this->counter <= count($this->dates); } @@ -84,6 +81,8 @@ public function rewind() * Goes on to the next iteration. * * @return void + * + * @throws InvalidDataException */ #[\ReturnTypeWillChange] public function next() @@ -104,10 +103,8 @@ public function next() /** * Returns true if this recurring event never ends. - * - * @return bool */ - public function isInfinite() + public function isInfinite(): bool { return false; } @@ -115,8 +112,10 @@ public function isInfinite() /** * This method allows you to quickly go to the next occurrence after the * specified date. + * + * @throws InvalidDataException */ - public function fastForward(DateTimeInterface $dt) + public function fastForward(DateTimeInterface $dt): void { while ($this->valid() && $this->currentDate < $dt) { $this->next(); @@ -127,27 +126,21 @@ public function fastForward(DateTimeInterface $dt) * The reference start date/time for the rrule. * * All calculations are based on this initial date. - * - * @var DateTimeInterface */ - protected $startDate; + protected DateTimeInterface $startDate; /** * The date of the current iteration. You can get this by calling * ->current(). - * - * @var DateTimeInterface */ - protected $currentDate; + protected DateTimeInterface $currentDate; /** * The current item in the list. * * You can get this number with the key() method. - * - * @var int */ - protected $counter = 0; + protected int $counter = 0; /* }}} */ @@ -155,9 +148,9 @@ public function fastForward(DateTimeInterface $dt) * This method receives a string from an RRULE property, and populates this * class with all the values. * - * @param string|array $rrule + * @param string|array $rdate */ - protected function parseRDate($rdate) + protected function parseRDate($rdate): void { if (is_string($rdate)) { $rdate = explode(',', $rdate); @@ -168,8 +161,6 @@ protected function parseRDate($rdate) /** * Array with the RRULE dates. - * - * @var array */ - protected $dates = []; + protected array $dates = []; } diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index 4f0e9070d..0cb9e57bc 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -2,8 +2,10 @@ namespace Sabre\VObject\Recur; +use DateTime; use DateTimeImmutable; use DateTimeInterface; +use Exception; use Iterator; use Sabre\VObject\DateTimeParser; use Sabre\VObject\InvalidDataException; @@ -35,6 +37,8 @@ class RRuleIterator implements Iterator * Creates the Iterator. * * @param string|array $rrule + * + * @throws InvalidDataException */ public function __construct($rrule, DateTimeInterface $start) { @@ -136,10 +140,8 @@ public function next() /** * Returns true if this recurring event never ends. - * - * @return bool */ - public function isInfinite() + public function isInfinite(): bool { return !$this->count && !$this->until; } @@ -148,7 +150,7 @@ public function isInfinite() * This method allows you to quickly go to the next occurrence after the * specified date. */ - public function fastForward(DateTimeInterface $dt) + public function fastForward(DateTimeInterface $dt): void { while ($this->valid() && $this->currentDate < $dt) { $this->next(); @@ -159,86 +161,66 @@ public function fastForward(DateTimeInterface $dt) * The reference start date/time for the rrule. * * All calculations are based on this initial date. - * - * @var DateTimeInterface */ - protected $startDate; + protected DateTimeInterface $startDate; /** * The date of the current iteration. You can get this by calling * ->current(). - * - * @var DateTimeInterface */ - protected $currentDate; + protected ?DateTimeInterface $currentDate; /** * Frequency is one of: secondly, minutely, hourly, daily, weekly, monthly, * yearly. - * - * @var string */ - protected $frequency; + protected string $frequency; /** * The number of recurrences, or 'null' if infinitely recurring. - * - * @var int */ - protected $count; + protected ?int $count = null; /** * The interval. * * If for example frequency is set to daily, interval = 2 would mean every * 2 days. - * - * @var int */ - protected $interval = 1; + protected int $interval = 1; /** * The last instance of this recurrence, inclusively. - * - * @var DateTimeInterface|null */ - protected $until; + protected ?DateTimeInterface $until = null; /** * Which seconds to recur. * * This is an array of integers (between 0 and 60) - * - * @var array */ - protected $bySecond; + protected ?array $bySecond = null; /** * Which minutes to recur. * * This is an array of integers (between 0 and 59) - * - * @var array */ - protected $byMinute; + protected ?array $byMinute = null; /** * Which hours to recur. * * This is an array of integers (between 0 and 23) - * - * @var array */ - protected $byHour; + protected ?array $byHour = null; /** * The current item in the list. * * You can get this number with the key() method. - * - * @var int */ - protected $counter = 0; + protected int $counter = 0; /** * Which weekdays to recur. @@ -249,20 +231,16 @@ public function fastForward(DateTimeInterface $dt) * this indicates the nth occurrence of a specific day within the monthly or * yearly rrule. For instance, -2TU indicates the second-last tuesday of * the month, or year. - * - * @var array */ - protected $byDay; + protected ?array $byDay = null; /** * Which days of the month to recur. * * This is an array of days of the months (1-31). The value can also be * negative. -5 for instance means the 5th last day of the month. - * - * @var array */ - protected $byMonthDay; + protected ?array $byMonthDay = null; /** * Which days of the year to recur. @@ -270,29 +248,23 @@ public function fastForward(DateTimeInterface $dt) * This is an array with days of the year (1 to 366). The values can also * be negative. For instance, -1 will always represent the last day of the * year. (December 31st). - * - * @var array */ - protected $byYearDay; + protected ?array $byYearDay = null; /** * Which week numbers to recur. * * This is an array of integers from 1 to 53. The values can also be * negative. -1 will always refer to the last week of the year. - * - * @var array */ - protected $byWeekNo; + protected ?array $byWeekNo = null; /** * Which months to recur. * * This is an array of integers from 1 to 12. - * - * @var array */ - protected $byMonth; + protected ?array $byMonth = null; /** * Which items in an existing st to recur. @@ -305,24 +277,20 @@ public function fastForward(DateTimeInterface $dt) * * This would be done by setting frequency to 'monthly', byDay to * 'MO,TU,WE,TH,FR' and bySetPos to -1. - * - * @var array */ - protected $bySetPos; + protected ?array $bySetPos = null; /** * When the week starts. - * - * @var string */ - protected $weekStart = 'MO'; + protected string $weekStart = 'MO'; /* Functions that advance the iterator {{{ */ /** * Does the processing for advancing the iterator for hourly frequency. */ - protected function nextHourly() + protected function nextHourly(): void { $this->currentDate = $this->currentDate->modify('+'.$this->interval.' hours'); } @@ -330,7 +298,7 @@ protected function nextHourly() /** * Does the processing for advancing the iterator for daily frequency. */ - protected function nextDaily() + protected function nextDaily(): void { if (!$this->byHour && !$this->byDay) { $this->currentDate = $this->currentDate->modify('+'.$this->interval.' days'); @@ -389,7 +357,7 @@ protected function nextDaily() /** * Does the processing for advancing the iterator for weekly frequency. */ - protected function nextWeekly() + protected function nextWeekly(): void { if (!$this->byHour && !$this->byDay) { $this->currentDate = $this->currentDate->modify('+'.$this->interval.' weeks'); @@ -440,8 +408,10 @@ protected function nextWeekly() /** * Does the processing for advancing the iterator for monthly frequency. + * + * @throws Exception */ - protected function nextMonthly() + protected function nextMonthly(): void { $currentDayOfMonth = $this->currentDate->format('j'); if (!$this->byMonthDay && !$this->byDay) { @@ -516,7 +486,7 @@ protected function nextMonthly() /** * Does the processing for advancing the iterator for yearly frequency. */ - protected function nextYearly() + protected function nextYearly(): void { $currentMonth = $this->currentDate->format('n'); $currentYear = $this->currentDate->format('Y'); @@ -717,8 +687,10 @@ protected function nextYearly() * class with all the values. * * @param string|array $rrule + * + * @throws InvalidDataException */ - protected function parseRRule($rrule) + protected function parseRRule($rrule): void { if (is_string($rrule)) { $rrule = Property\ICalendar\Recur::stringToArray($rrule); @@ -853,6 +825,8 @@ protected function parseRRule($rrule) * The returned list is an array of integers with the day of month (1-31). * * @return array + * + * @throws Exception */ protected function getMonthlyOccurrences() { @@ -871,7 +845,7 @@ protected function getMonthlyOccurrences() $dayHits = []; // workaround for missing 'first day of the month' support in hhvm - $checkDate = new \DateTime($startDate->format('Y-m-1')); + $checkDate = new DateTime($startDate->format('Y-m-1')); // workaround modify always advancing the date even if the current day is a $dayName in hhvm if ($checkDate->format('l') !== $dayName) { $checkDate = $checkDate->modify($dayName); @@ -975,7 +949,7 @@ protected function getMonthlyOccurrences() 'SA' => 6, ]; - protected function getHours() + protected function getHours(): array { $recurrenceHours = []; foreach ($this->byHour as $byHour) { @@ -985,7 +959,7 @@ protected function getHours() return $recurrenceHours; } - protected function getDays() + protected function getDays(): array { $recurrenceDays = []; foreach ($this->byDay as $byDay) { @@ -998,7 +972,7 @@ protected function getDays() return $recurrenceDays; } - protected function getMonths() + protected function getMonths(): array { $recurrenceMonths = []; foreach ($this->byMonth as $byMonth) { diff --git a/lib/Splitter/ICalendar.php b/lib/Splitter/ICalendar.php index d42566194..79dd351bc 100644 --- a/lib/Splitter/ICalendar.php +++ b/lib/Splitter/ICalendar.php @@ -3,6 +3,7 @@ namespace Sabre\VObject\Splitter; use Sabre\VObject; +use Sabre\VObject\Component; use Sabre\VObject\Component\VCalendar; /** @@ -23,17 +24,13 @@ class ICalendar implements SplitterInterface { /** * Timezones. - * - * @var array */ - protected $vtimezones = []; + protected array $vtimezones = []; /** * iCalendar objects. - * - * @var array */ - protected $objects = []; + protected array $objects = []; /** * Constructor. @@ -42,8 +39,10 @@ class ICalendar implements SplitterInterface * * @param resource $input * @param int $options parser options, see the OPTIONS constants + * + * @throws VObject\ParseException */ - public function __construct($input, $options = 0) + public function __construct($input, int $options = 0) { $data = VObject\Reader::read($input, $options); @@ -52,7 +51,7 @@ public function __construct($input, $options = 0) } foreach ($data->children() as $component) { - if (!$component instanceof VObject\Component) { + if (!$component instanceof Component) { continue; } @@ -82,10 +81,8 @@ public function __construct($input, $options = 0) * hit the end of the stream. * * When the end is reached, null will be returned. - * - * @return \Sabre\VObject\Component|null */ - public function getNext() + public function getNext(): ?Component { if ($object = array_shift($this->objects)) { // create our baseobject @@ -100,7 +97,7 @@ public function getNext() return $object; } else { - return; + return null; } } } diff --git a/lib/Splitter/SplitterInterface.php b/lib/Splitter/SplitterInterface.php index c845ac5fc..6827e1422 100644 --- a/lib/Splitter/SplitterInterface.php +++ b/lib/Splitter/SplitterInterface.php @@ -2,6 +2,8 @@ namespace Sabre\VObject\Splitter; +use Sabre\VObject\Component; + /** * VObject splitter. * @@ -31,8 +33,6 @@ public function __construct($input); * hit the end of the stream. * * When the end is reached, null will be returned. - * - * @return \Sabre\VObject\Component|null */ - public function getNext(); + public function getNext(): ?Component; } diff --git a/lib/Splitter/VCard.php b/lib/Splitter/VCard.php index a20f5c2c1..dfe596d5f 100644 --- a/lib/Splitter/VCard.php +++ b/lib/Splitter/VCard.php @@ -3,6 +3,7 @@ namespace Sabre\VObject\Splitter; use Sabre\VObject; +use Sabre\VObject\Component; use Sabre\VObject\Parser\MimeDir; /** @@ -30,10 +31,8 @@ class VCard implements SplitterInterface /** * Persistent parser. - * - * @var MimeDir */ - protected $parser; + protected MimeDir $parser; /** * Constructor. @@ -43,7 +42,7 @@ class VCard implements SplitterInterface * @param resource $input * @param int $options parser options, see the OPTIONS constants */ - public function __construct($input, $options = 0) + public function __construct($input, int $options = 0) { $this->input = $input; $this->parser = new MimeDir($input, $options); @@ -55,9 +54,9 @@ public function __construct($input, $options = 0) * * When the end is reached, null will be returned. * - * @return \Sabre\VObject\Component|null + * @throws VObject\ParseException */ - public function getNext() + public function getNext(): ?Component { try { $object = $this->parser->parse(); @@ -66,7 +65,7 @@ public function getNext() throw new VObject\ParseException('The supplied input contained non-VCARD data.'); } } catch (VObject\EofException $e) { - return; + return null; } return $object; diff --git a/lib/StringUtil.php b/lib/StringUtil.php index b04539e4a..8fe5f9f0a 100644 --- a/lib/StringUtil.php +++ b/lib/StringUtil.php @@ -13,12 +13,8 @@ class StringUtil { /** * Returns true or false depending on if a string is valid UTF-8. - * - * @param string $str - * - * @return bool */ - public static function isUTF8($str) + public static function isUTF8(string $str): bool { // Control characters if (preg_match('%[\x00-\x08\x0B-\x0C\x0E\x0F]%', $str)) { @@ -33,12 +29,8 @@ public static function isUTF8($str) * * Currently only ISO-5991-1 input and UTF-8 input is supported, but this * may be expanded upon if we receive other examples. - * - * @param string $str - * - * @return string */ - public static function convertToUTF8($str) + public static function convertToUTF8(string $str): string { if (!mb_check_encoding($str, 'UTF-8') && mb_check_encoding($str, 'ISO-8859-1')) { $str = mb_convert_encoding($str, 'UTF-8', 'ISO-8859-1'); diff --git a/lib/TimeZoneUtil.php b/lib/TimeZoneUtil.php index 6422c0930..dac2a87d2 100644 --- a/lib/TimeZoneUtil.php +++ b/lib/TimeZoneUtil.php @@ -120,13 +120,7 @@ public static function addTimezoneFinder(string $key, TimezoneFinder $finder): v self::getInstance()->addFinder($key, $finder); } - /** - * @param string $tzid - * @param false $failIfUncertain - * - * @return DateTimeZone - */ - public static function getTimeZone($tzid, Component $vcalendar = null, $failIfUncertain = false) + public static function getTimeZone(string $tzid, Component $vcalendar = null, bool $failIfUncertain = false): DateTimeZone { return self::getInstance()->findTimeZone($tzid, $vcalendar, $failIfUncertain); } @@ -135,138 +129,4 @@ public static function clean(): void { self::$instance = null; } - - // Keeping things for backwards compatibility - /** - * @var array|null - * - * @deprecated - */ - public static $map = null; - - /** - * List of microsoft exchange timezone ids. - * - * Source: http://msdn.microsoft.com/en-us/library/aa563018(loband).aspx - * - * @deprecated - */ - public static $microsoftExchangeMap = [ - 0 => 'UTC', - 31 => 'Africa/Casablanca', - // Insanely, id #2 is used for both Europe/Lisbon, and Europe/Sarajevo. - // I'm not even kidding.. We handle this special case in the - // getTimeZone method. - 2 => 'Europe/Lisbon', - 1 => 'Europe/London', - 4 => 'Europe/Berlin', - 6 => 'Europe/Prague', - 3 => 'Europe/Paris', - 69 => 'Africa/Luanda', // This was a best guess - 7 => 'Europe/Athens', - 5 => 'Europe/Bucharest', - 49 => 'Africa/Cairo', - 50 => 'Africa/Harare', - 59 => 'Europe/Helsinki', - 27 => 'Asia/Jerusalem', - 26 => 'Asia/Baghdad', - 74 => 'Asia/Kuwait', - 51 => 'Europe/Moscow', - 56 => 'Africa/Nairobi', - 25 => 'Asia/Tehran', - 24 => 'Asia/Muscat', // Best guess - 54 => 'Asia/Baku', - 48 => 'Asia/Kabul', - 58 => 'Asia/Yekaterinburg', - 47 => 'Asia/Karachi', - 23 => 'Asia/Calcutta', - 62 => 'Asia/Kathmandu', - 46 => 'Asia/Almaty', - 71 => 'Asia/Dhaka', - 66 => 'Asia/Colombo', - 61 => 'Asia/Rangoon', - 22 => 'Asia/Bangkok', - 64 => 'Asia/Krasnoyarsk', - 45 => 'Asia/Shanghai', - 63 => 'Asia/Irkutsk', - 21 => 'Asia/Singapore', - 73 => 'Australia/Perth', - 75 => 'Asia/Taipei', - 20 => 'Asia/Tokyo', - 72 => 'Asia/Seoul', - 70 => 'Asia/Yakutsk', - 19 => 'Australia/Adelaide', - 44 => 'Australia/Darwin', - 18 => 'Australia/Brisbane', - 76 => 'Australia/Sydney', - 43 => 'Pacific/Guam', - 42 => 'Australia/Hobart', - 68 => 'Asia/Vladivostok', - 41 => 'Asia/Magadan', - 17 => 'Pacific/Auckland', - 40 => 'Pacific/Fiji', - 67 => 'Pacific/Tongatapu', - 29 => 'Atlantic/Azores', - 53 => 'Atlantic/Cape_Verde', - 30 => 'America/Noronha', - 8 => 'America/Sao_Paulo', // Best guess - 32 => 'America/Argentina/Buenos_Aires', - 60 => 'America/Godthab', - 28 => 'America/St_Johns', - 9 => 'America/Halifax', - 33 => 'America/Caracas', - 65 => 'America/Santiago', - 35 => 'America/Bogota', - 10 => 'America/New_York', - 34 => 'America/Indiana/Indianapolis', - 55 => 'America/Guatemala', - 11 => 'America/Chicago', - 37 => 'America/Mexico_City', - 36 => 'America/Edmonton', - 38 => 'America/Phoenix', - 12 => 'America/Denver', // Best guess - 13 => 'America/Los_Angeles', // Best guess - 14 => 'America/Anchorage', - 15 => 'Pacific/Honolulu', - 16 => 'Pacific/Midway', - 39 => 'Pacific/Kwajalein', - ]; - - /** - * This method will load in all the tz mapping information, if it's not yet - * done. - * - * @deprecated - */ - public static function loadTzMaps() - { - if (!is_null(self::$map)) { - return; - } - - self::$map = array_merge( - include __DIR__.'/timezonedata/windowszones.php', - include __DIR__.'/timezonedata/lotuszones.php', - include __DIR__.'/timezonedata/exchangezones.php', - include __DIR__.'/timezonedata/php-workaround.php' - ); - } - - /** - * This method returns an array of timezone identifiers, that are supported - * by DateTimeZone(), but not returned by DateTimeZone::listIdentifiers(). - * - * We're not using DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC) because: - * - It's not supported by some PHP versions as well as HHVM. - * - It also returns identifiers, that are invalid values for new DateTimeZone() on some PHP versions. - * (See timezonedata/php-bc.php and timezonedata php-workaround.php) - * - * @return array - * - * @deprecated - */ - public static function getIdentifiersBC() - { - return include __DIR__.'/timezonedata/php-bc.php'; - } } diff --git a/lib/TimezoneGuesser/FindFromTimezoneIdentifier.php b/lib/TimezoneGuesser/FindFromTimezoneIdentifier.php index d8c6d5d3b..8424e14a4 100644 --- a/lib/TimezoneGuesser/FindFromTimezoneIdentifier.php +++ b/lib/TimezoneGuesser/FindFromTimezoneIdentifier.php @@ -61,10 +61,8 @@ public function find(string $tzid, bool $failIfUncertain = false): ?DateTimeZone * - It's not supported by some PHP versions as well as HHVM. * - It also returns identifiers, that are invalid values for new DateTimeZone() on some PHP versions. * (See timezonedata/php-bc.php and timezonedata php-workaround.php) - * - * @return array */ - private function getIdentifiersBC() + private function getIdentifiersBC(): array { return include __DIR__.'/../timezonedata/php-bc.php'; } diff --git a/lib/TimezoneGuesser/FindFromTimezoneMap.php b/lib/TimezoneGuesser/FindFromTimezoneMap.php index b52ba6a19..89263f69e 100644 --- a/lib/TimezoneGuesser/FindFromTimezoneMap.php +++ b/lib/TimezoneGuesser/FindFromTimezoneMap.php @@ -11,9 +11,9 @@ */ class FindFromTimezoneMap implements TimezoneFinder { - private $map = []; + private array $map = []; - private $patterns = [ + private array $patterns = [ '/^\((UTC|GMT)(\+|\-)[\d]{2}\:[\d]{2}\) (.*)/', '/^\((UTC|GMT)(\+|\-)[\d]{2}\.[\d]{2}\) (.*)/', ]; @@ -49,10 +49,8 @@ public function find(string $tzid, bool $failIfUncertain = false): ?DateTimeZone * - It's not supported by some PHP versions as well as HHVM. * - It also returns identifiers, that are invalid values for new DateTimeZone() on some PHP versions. * (See timezonedata/php-bc.php and timezonedata php-workaround.php) - * - * @return array */ - private function getTzMaps() + private function getTzMaps(): array { if ([] === $this->map) { $this->map = array_merge( diff --git a/lib/TimezoneGuesser/GuessFromMsTzId.php b/lib/TimezoneGuesser/GuessFromMsTzId.php index b11ce1832..0e4847f9d 100644 --- a/lib/TimezoneGuesser/GuessFromMsTzId.php +++ b/lib/TimezoneGuesser/GuessFromMsTzId.php @@ -14,7 +14,7 @@ class GuessFromMsTzId implements TimezoneGuesser * * Source: http://msdn.microsoft.com/en-us/library/aa563018(loband).aspx */ - public static $microsoftExchangeMap = [ + public static array $microsoftExchangeMap = [ 0 => 'UTC', 31 => 'Africa/Casablanca', @@ -96,7 +96,7 @@ class GuessFromMsTzId implements TimezoneGuesser 39 => 'Pacific/Kwajalein', ]; - public function guess(VTimeZone $vtimezone, bool $throwIfUnsure = false): ?DateTimeZone + public function guess(VTimeZone $vtimezone, bool $failIfUncertain = false): ?DateTimeZone { // Microsoft may add a magic number, which we also have an // answer for. diff --git a/lib/UUIDUtil.php b/lib/UUIDUtil.php index 066af624c..e8208630c 100644 --- a/lib/UUIDUtil.php +++ b/lib/UUIDUtil.php @@ -21,42 +21,36 @@ class UUIDUtil * This function is based on a comment by Andrew Moore on php.net * * @see http://www.php.net/manual/en/function.uniqid.php#94959 - * - * @return string */ - public static function getUUID() + public static function getUUID(): string { return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', // 32 bits for "time_low" - mt_rand(0, 0xffff), mt_rand(0, 0xffff), + mt_rand(0, 0xFFFF), mt_rand(0, 0xFFFF), // 16 bits for "time_mid" - mt_rand(0, 0xffff), + mt_rand(0, 0xFFFF), // 16 bits for "time_hi_and_version", // four most significant bits holds version number 4 - mt_rand(0, 0x0fff) | 0x4000, + mt_rand(0, 0x0FFF) | 0x4000, // 16 bits, 8 bits for "clk_seq_hi_res", // 8 bits for "clk_seq_low", // two most significant bits holds zero and one for variant DCE1.1 - mt_rand(0, 0x3fff) | 0x8000, + mt_rand(0, 0x3FFF) | 0x8000, // 48 bits for "node" - mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) + mt_rand(0, 0xFFFF), mt_rand(0, 0xFFFF), mt_rand(0, 0xFFFF) ); } /** * Checks if a string is a valid UUID. - * - * @param string $uuid - * - * @return bool */ - public static function validateUUID($uuid) + public static function validateUUID(string $uuid): bool { return 0 !== preg_match( '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i', diff --git a/lib/VCardConverter.php b/lib/VCardConverter.php index 04129e355..8480421d9 100644 --- a/lib/VCardConverter.php +++ b/lib/VCardConverter.php @@ -2,6 +2,10 @@ namespace Sabre\VObject; +use InvalidArgumentException; +use Sabre\VObject\Property\Binary; +use Sabre\VObject\Property\Uri; + /** * This utility converts vcards from one version to another. * @@ -26,9 +30,9 @@ class VCardConverter * * If input and output version are identical, a clone is returned. * - * @param int $targetVersion + * @throws InvalidDataException */ - public function convert(Component\VCard $input, $targetVersion) + public function convert(Component\VCard $input, int $targetVersion): Component\VCard { $inputVersion = $input->getDocumentType(); if ($inputVersion === $targetVersion) { @@ -36,10 +40,10 @@ public function convert(Component\VCard $input, $targetVersion) } if (!in_array($inputVersion, [Document::VCARD21, Document::VCARD30, Document::VCARD40])) { - throw new \InvalidArgumentException('Only vCard 2.1, 3.0 and 4.0 are supported for the input data'); + throw new InvalidArgumentException('Only vCard 2.1, 3.0 and 4.0 are supported for the input data'); } if (!in_array($targetVersion, [Document::VCARD30, Document::VCARD40])) { - throw new \InvalidArgumentException('You can only use vCard 3.0 or 4.0 for the target version'); + throw new InvalidArgumentException('You can only use vCard 3.0 or 4.0 for the target version'); } $newVersion = Document::VCARD40 === $targetVersion ? '4.0' : '3.0'; @@ -61,9 +65,11 @@ public function convert(Component\VCard $input, $targetVersion) /** * Handles conversion of a single property. * - * @param int $targetVersion + * @return void + * + * @throws InvalidDataException */ - protected function convertProperty(Component\VCard $input, Component\VCard $output, Property $property, $targetVersion) + protected function convertProperty(Component\VCard $input, Component\VCard $output, Property $property, int $targetVersion) { // Skipping these, those are automatically added. if (in_array($property->name, ['VERSION', 'PRODID'])) { @@ -91,6 +97,7 @@ protected function convertProperty(Component\VCard $input, Component\VCard $outp if (Document::VCARD30 === $targetVersion) { if ($property instanceof Property\Uri && in_array($property->name, ['PHOTO', 'LOGO', 'SOUND'])) { + /** @var Property\Uri $newProperty */ $newProperty = $this->convertUriToBinary($output, $newProperty); } elseif ($property instanceof Property\VCard\DateAndOrTime) { // In vCard 4, the birth year may be optional. This is not the @@ -150,6 +157,7 @@ protected function convertProperty(Component\VCard $input, Component\VCard $outp } if ($property instanceof Property\Binary) { + /** @var Property\Binary $newProperty */ $newProperty = $this->convertBinaryToUri($output, $newProperty, $parameters); } elseif ($property instanceof Property\VCard\DateAndOrTime && isset($parameters['X-APPLE-OMIT-YEAR'])) { // If a property such as BDAY contained 'X-APPLE-OMIT-YEAR', @@ -246,15 +254,15 @@ protected function convertProperty(Component\VCard $input, Component\VCard $outp * * vCard 4.0 no longer supports BINARY properties. * - * @param Property\Uri $property the input property - * @param $parameters list of parameters that will eventually be added to - * the new property + * @param array $parameters list of parameters that will eventually be added to + * the new property * - * @return Property\Uri + * @throws InvalidDataException */ - protected function convertBinaryToUri(Component\VCard $output, Property\Binary $newProperty, array &$parameters) + protected function convertBinaryToUri(Component\VCard $output, Property\Binary $newProperty, array &$parameters): Uri { $value = $newProperty->getValue(); + /** @var Uri $newProperty */ $newProperty = $output->createProperty( $newProperty->name, null, // no value @@ -299,11 +307,11 @@ protected function convertBinaryToUri(Component\VCard $output, Property\Binary $ * be valid in vCard 3.0 as well, we should convert those to BINARY if * possible, to improve compatibility. * - * @param Property\Uri $property the input property + * @return Property\Binary|Property\Uri|null * - * @return Property\Binary|null + * @throws InvalidDataException */ - protected function convertUriToBinary(Component\VCard $output, Property\Uri $newProperty) + protected function convertUriToBinary(Component\VCard $output, Property\Uri $newProperty): Property { $value = $newProperty->getValue(); @@ -312,6 +320,7 @@ protected function convertUriToBinary(Component\VCard $output, Property\Uri $new return $newProperty; } + /** @var Binary $newProperty */ $newProperty = $output->createProperty( $newProperty->name, null, // no value @@ -347,7 +356,7 @@ protected function convertUriToBinary(Component\VCard $output, Property\Uri $new /** * Adds parameters to a new property for vCard 4.0. */ - protected function convertParameters40(Property $newProperty, array $parameters) + protected function convertParameters40(Property $newProperty, array $parameters): void { // Adding all parameters. foreach ($parameters as $param) { @@ -383,7 +392,7 @@ protected function convertParameters40(Property $newProperty, array $parameters) /** * Adds parameters to a new property for vCard 3.0. */ - protected function convertParameters30(Property $newProperty, array $parameters) + protected function convertParameters30(Property $newProperty, array $parameters): void { // Adding all parameters. foreach ($parameters as $param) { diff --git a/lib/Version.php b/lib/Version.php index 167ac28de..fc8a605f4 100644 --- a/lib/Version.php +++ b/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.5.0'; + public const VERSION = '4.5.0'; } diff --git a/lib/Writer.php b/lib/Writer.php index cbd22022e..504e38a7d 100644 --- a/lib/Writer.php +++ b/lib/Writer.php @@ -18,32 +18,24 @@ class Writer { /** * Serializes a vCard or iCalendar object. - * - * @return string */ - public static function write(Component $component) + public static function write(Component $component): string { return $component->serialize(); } /** * Serializes a jCal or jCard object. - * - * @param int $options - * - * @return string */ - public static function writeJson(Component $component, $options = 0) + public static function writeJson(Component $component, int $options = 0): string { return json_encode($component, $options); } /** * Serializes a xCal or xCard object. - * - * @return string */ - public static function writeXml(Component $component) + public static function writeXml(Component $component): string { $writer = new Xml\Writer(); $writer->openMemory(); diff --git a/tests/VObject/ComponentTest.php b/tests/VObject/ComponentTest.php index 9acedf925..aa4f3e4b1 100644 --- a/tests/VObject/ComponentTest.php +++ b/tests/VObject/ComponentTest.php @@ -40,13 +40,16 @@ public function testMagicGet() $sub = $comp->createComponent('VTODO'); $comp->add($sub); - $event = $comp->vevent; + $event = $comp->VEVENT; $this->assertInstanceOf(Component::class, $event); $this->assertEquals('VEVENT', $event->name); - $this->assertNull($comp->vjournal); + $this->assertNull($comp->VJOURNAL); } + /** + * @throws InvalidDataException + */ public function testMagicGetGroups() { $comp = new VCard(); @@ -63,8 +66,8 @@ public function testMagicGetGroups() $sub = $comp->createProperty('0.EMAIL', '0@0.com'); $comp->add($sub); - $emails = $comp->email; - $this->assertEquals(4, count($emails)); + $emails = $comp->EMAIL; + $this->assertCount(4, $emails); $email1 = $comp->{'group1.email'}; $this->assertEquals('EMAIL', $email1[0]->name); @@ -134,7 +137,7 @@ public function testMagicSetScalarTwice() $comp->myProp = 'myValue'; $comp->myProp = 'myValue'; - $this->assertEquals(1, count($comp->children())); + $this->assertCount(1, $comp->children()); $this->assertInstanceOf(Property::class, $comp->MYPROP); $this->assertEquals('myValue', (string) $comp->MYPROP); } @@ -155,7 +158,7 @@ public function testMagicSetComponent() // Note that 'myProp' is ignored here. $comp->myProp = $comp->createComponent('VEVENT'); - $this->assertEquals(1, count($comp)); + $this->assertCount(1, $comp); $this->assertEquals('VEVENT', $comp->VEVENT->name); } @@ -167,7 +170,7 @@ public function testMagicSetTwice() $comp->VEVENT = $comp->createComponent('VEVENT'); $comp->VEVENT = $comp->createComponent('VEVENT'); - $this->assertEquals(1, count($comp->children())); + $this->assertCount(1, $comp->children()); $this->assertEquals('VEVENT', $comp->VEVENT->name); } @@ -229,7 +232,7 @@ public function testAddScalar() $comp->add('myprop', 'value'); - $this->assertEquals(1, count($comp->children())); + $this->assertCount(1, $comp->children()); $bla = $comp->children()[0]; @@ -244,7 +247,7 @@ public function testAddScalarParams() $comp->add('myprop', 'value', ['param1' => 'value1']); - $this->assertEquals(1, count($comp->children())); + $this->assertCount(1, $comp->children()); $bla = $comp->children()[0]; @@ -252,7 +255,7 @@ public function testAddScalarParams() $this->assertEquals('MYPROP', $bla->name); $this->assertEquals('value', (string) $bla); - $this->assertEquals(1, count($bla->parameters())); + $this->assertCount(1, $bla->parameters()); $this->assertEquals('PARAM1', $bla->parameters['PARAM1']->name); $this->assertEquals('value1', $bla->parameters['PARAM1']->getValue()); @@ -264,7 +267,7 @@ public function testAddComponent() $comp->add($comp->createComponent('VEVENT')); - $this->assertEquals(1, count($comp->children())); + $this->assertCount(1, $comp->children()); $this->assertEquals('VEVENT', $comp->VEVENT->name); } @@ -276,7 +279,7 @@ public function testAddComponentTwice() $comp->add($comp->createComponent('VEVENT')); $comp->add($comp->createComponent('VEVENT')); - $this->assertEquals(2, count($comp->children())); + $this->assertCount(2, $comp->children()); $this->assertEquals('VEVENT', $comp->VEVENT->name); } @@ -302,7 +305,7 @@ public function testMagicUnset() unset($comp->vevent); - $this->assertEquals(0, count($comp->children())); + $this->assertCount(0, $comp->children()); } public function testCount() @@ -321,9 +324,12 @@ public function testChildren() $r = $comp->children(); $this->assertIsArray($r); - $this->assertEquals(2, count($r)); + $this->assertCount(2, $r); } + /** + * @throws InvalidDataException + */ public function testGetComponents() { $comp = new VCalendar(); @@ -333,7 +339,7 @@ public function testGetComponents() $r = $comp->getComponents(); $this->assertIsArray($r); - $this->assertEquals(1, count($r)); + $this->assertCount(1, $r); $this->assertEquals('VTODO', $r[0]->name); } @@ -441,6 +447,9 @@ public function testRemoveByObj() $this->assertTrue(isset($comp->prop1)); } + /** + * @throws InvalidDataException + */ public function testRemoveNotFound() { $this->expectException(\InvalidArgumentException::class); @@ -461,7 +470,7 @@ public function testValidateRules($componentList, $errorCount) $component->add($v, 'Hello.'); } - $this->assertEquals($errorCount, count($component->validate())); + $this->assertCount($errorCount, $component->validate()); } public function testValidateRepair() @@ -484,9 +493,9 @@ public function testValidateRepairShouldNotDeduplicatePropertiesWhenValuesDiffer $messages = $component->validate(Component::REPAIR); - $this->assertEquals(1, count($messages)); + $this->assertCount(1, $messages); $this->assertEquals(3, $messages[0]['level']); - $this->assertEquals(2, count($component->GIR)); + $this->assertCount(2, $component->GIR); } public function testValidateRepairShouldNotDeduplicatePropertiesWhenParametersDiffer() @@ -500,9 +509,9 @@ public function testValidateRepairShouldNotDeduplicatePropertiesWhenParametersDi $messages = $component->validate(Component::REPAIR); - $this->assertEquals(1, count($messages)); + $this->assertCount(1, $messages); $this->assertEquals(3, $messages[0]['level']); - $this->assertEquals(2, count($component->GIR)); + $this->assertCount(2, $component->GIR); } public function testValidateRepairShouldDeduplicatePropertiesWhenValuesAndParametersAreEqual() @@ -516,9 +525,9 @@ public function testValidateRepairShouldDeduplicatePropertiesWhenValuesAndParame $messages = $component->validate(Component::REPAIR); - $this->assertEquals(1, count($messages)); + $this->assertCount(1, $messages); $this->assertEquals(1, $messages[0]['level']); - $this->assertEquals(1, count($component->GIR)); + $this->assertCount(1, $component->GIR); } public function testValidateRepairShouldDeduplicatePropertiesWhenValuesAreEqual() @@ -532,12 +541,12 @@ public function testValidateRepairShouldDeduplicatePropertiesWhenValuesAreEqual( $messages = $component->validate(Component::REPAIR); - $this->assertEquals(1, count($messages)); + $this->assertCount(1, $messages); $this->assertEquals(1, $messages[0]['level']); - $this->assertEquals(1, count($component->GIR)); + $this->assertCount(1, $component->GIR); } - public function ruleData() + public function ruleData(): array { return [ [[], 2], @@ -554,7 +563,7 @@ public function ruleData() class FakeComponent extends Component { - public function getValidationRules() + public function getValidationRules(): array { return [ 'FOO' => '0', @@ -565,7 +574,7 @@ public function getValidationRules() ]; } - public function getDefaults() + public function getDefaults(): array { return [ 'BAR' => 'yow', diff --git a/tests/VObject/DateTimeParserTest.php b/tests/VObject/DateTimeParserTest.php index ede81e321..0317e9f86 100644 --- a/tests/VObject/DateTimeParserTest.php +++ b/tests/VObject/DateTimeParserTest.php @@ -9,17 +9,23 @@ class DateTimeParserTest extends TestCase { + /** + * @throws InvalidDataException + */ public function testParseICalendarDuration() { - $this->assertEquals('+1 weeks', DateTimeParser::parseDuration('P1W', true)); - $this->assertEquals('+5 days', DateTimeParser::parseDuration('P5D', true)); - $this->assertEquals('+5 days 3 hours 50 minutes 12 seconds', DateTimeParser::parseDuration('P5DT3H50M12S', true)); - $this->assertEquals('-1 weeks 50 minutes', DateTimeParser::parseDuration('-P1WT50M', true)); - $this->assertEquals('+50 days 3 hours 2 seconds', DateTimeParser::parseDuration('+P50DT3H2S', true)); - $this->assertEquals('+0 seconds', DateTimeParser::parseDuration('+PT0S', true)); + $this->assertEquals('+1 weeks', DateTimeParser::parseDurationAsString('P1W')); + $this->assertEquals('+5 days', DateTimeParser::parseDurationAsString('P5D')); + $this->assertEquals('+5 days 3 hours 50 minutes 12 seconds', DateTimeParser::parseDurationAsString('P5DT3H50M12S')); + $this->assertEquals('-1 weeks 50 minutes', DateTimeParser::parseDurationAsString('-P1WT50M')); + $this->assertEquals('+50 days 3 hours 2 seconds', DateTimeParser::parseDurationAsString('+P50DT3H2S')); + $this->assertEquals('+0 seconds', DateTimeParser::parseDurationAsString('+PT0S')); $this->assertEquals(new DateInterval('PT0S'), DateTimeParser::parseDuration('PT0S')); } + /** + * @throws InvalidDataException + */ public function testParseICalendarDurationDateInterval() { $expected = new DateInterval('P7D'); @@ -34,7 +40,7 @@ public function testParseICalendarDurationDateInterval() public function testParseICalendarDurationFail() { $this->expectException(InvalidDataException::class); - DateTimeParser::parseDuration('P1X', true); + DateTimeParser::parseDurationAsString('P1X'); } public function testParseICalendarDateTime() diff --git a/tests/VObject/DocumentTest.php b/tests/VObject/DocumentTest.php index f2698f65f..f710671be 100644 --- a/tests/VObject/DocumentTest.php +++ b/tests/VObject/DocumentTest.php @@ -8,7 +8,7 @@ class DocumentTest extends TestCase { public function testGetDocumentType() { - $doc = new MockDocument(); + $doc = new MockDocument('WHATEVER'); $this->assertEquals(Document::UNKNOWN, $doc->getDocumentType()); } @@ -59,6 +59,9 @@ public function testGetClassNameForPropertyValue() $this->assertNull($vcal->getClassNameForPropertyValue('FOO')); } + /** + * @throws InvalidDataException + */ public function testDestroy() { $vcal = new Component\VCalendar([], false); diff --git a/tests/VObject/ITip/BrokerNewEventTest.php b/tests/VObject/ITip/BrokerNewEventTest.php index f5b89b0e8..8a5ec9a46 100644 --- a/tests/VObject/ITip/BrokerNewEventTest.php +++ b/tests/VObject/ITip/BrokerNewEventTest.php @@ -2,6 +2,8 @@ namespace Sabre\VObject\ITip; +use Sabre\VObject\Version; + class BrokerNewEventTest extends BrokerTester { public function testNoAttendee() @@ -47,7 +49,7 @@ public function testSimpleInvite() END:VCALENDAR ICS; - $version = \Sabre\VObject\Version::VERSION; + $version = Version::VERSION; $expectedMessage = <<parse(null, $message, [], 'mailto:strunk@example.org'); } @@ -479,7 +481,7 @@ public function testMultipleUID() END:VCALENDAR ICS; - $version = \Sabre\VObject\Version::VERSION; + $version = Version::VERSION; $this->parse(null, $message, [], 'mailto:strunk@example.org'); } diff --git a/tests/VObject/ITip/BrokerTester.php b/tests/VObject/ITip/BrokerTester.php index 9e9956e03..0d49e3ad2 100644 --- a/tests/VObject/ITip/BrokerTester.php +++ b/tests/VObject/ITip/BrokerTester.php @@ -3,7 +3,14 @@ namespace Sabre\VObject\ITip; use PHPUnit\Framework\TestCase; +use Sabre\VObject\Component\VEvent; +use Sabre\VObject\InvalidDataException; +use Sabre\VObject\ParseException; +use Sabre\VObject\PHPUnitAssertions; use Sabre\VObject\Reader; +use Sabre\VObject\Recur\MaxInstancesExceededException; +use Sabre\VObject\Recur\NoInstancesException; +use Sabre\VObject\Version; /** * Utilities for testing the broker. @@ -14,7 +21,7 @@ */ abstract class BrokerTester extends TestCase { - use \Sabre\VObject\PHPUnitAssertions; + use PHPUnitAssertions; public function parse($oldMessage, $newMessage, $expected = [], $currentUser = 'mailto:one@example.org') { @@ -39,13 +46,19 @@ public function parse($oldMessage, $newMessage, $expected = [], $currentUser = ' } } + /** + * @throws ParseException + * @throws MaxInstancesExceededException + * @throws NoInstancesException + * @throws InvalidDataException + */ public function process($input, $existingObject = null, $expected = false) { - $version = \Sabre\VObject\Version::VERSION; + $version = Version::VERSION; $vcal = Reader::read($input); - $mainComponent = new \Sabre\VObject\Component\VEvent($vcal, 'VEVENT'); + $mainComponent = new VEvent($vcal, 'VEVENT'); foreach ($vcal->getComponents() as $mainComponent) { if ('VEVENT' === $mainComponent->name) { break; diff --git a/tests/VObject/Property/BooleanTest.php b/tests/VObject/Property/BooleanTest.php index ad2ccbcd7..4e122ae31 100644 --- a/tests/VObject/Property/BooleanTest.php +++ b/tests/VObject/Property/BooleanTest.php @@ -7,6 +7,9 @@ class BooleanTest extends TestCase { + /** + * @throws VObject\ParseException + */ public function testMimeDir() { $input = "BEGIN:VCARD\r\nX-AWESOME;VALUE=BOOLEAN:TRUE\r\nX-SUCKS;VALUE=BOOLEAN:FALSE\r\nEND:VCARD\r\n"; diff --git a/tests/VObject/PropertyTest.php b/tests/VObject/PropertyTest.php index 1f6e07022..d0356727c 100644 --- a/tests/VObject/PropertyTest.php +++ b/tests/VObject/PropertyTest.php @@ -272,16 +272,22 @@ public function testValidateControlChars() $this->assertEquals("chars[7F()5E(^)5C(\\\\)3B(\\;)3A(:)2C(\\,)22(\")20( )1F()1E()1D()1C()1B()1A()19()18()17()16()15()14()13()12()11()10()0F()0E()0D()0C()0B()0A(\\n)09(\t)08()07()06()05()04()03()02()01()00()]end", $property->getRawMimeDirValue()); } + /** + * @throws InvalidDataException + */ public function testValidateBadPropertyName() { $calendar = new VCalendar(); $property = $calendar->createProperty('X_*&PROP*', 'Bla'); - $result = $property->validate(Property::REPAIR); + $result = $property->validate(Node::REPAIR); - $this->assertEquals($result[0]['message'], 'The propertyname: X_*&PROP* contains invalid characters. Only A-Z, 0-9 and - are allowed'); + $this->assertEquals('The propertyname: X_*&PROP* contains invalid characters. Only A-Z, 0-9 and - are allowed', $result[0]['message']); $this->assertEquals('X-PROP', $property->name); } + /** + * @throws InvalidDataException + */ public function testGetValue() { $calendar = new VCalendar(); diff --git a/tests/VObject/ReaderTest.php b/tests/VObject/ReaderTest.php index cc2838a1a..6069f14d2 100644 --- a/tests/VObject/ReaderTest.php +++ b/tests/VObject/ReaderTest.php @@ -410,7 +410,7 @@ public function testReadBrokenInput() public function testReadBOM() { - $data = chr(0xef).chr(0xbb).chr(0xbf)."BEGIN:VCALENDAR\r\nEND:VCALENDAR"; + $data = chr(0xEF).chr(0xBB).chr(0xBF)."BEGIN:VCALENDAR\r\nEND:VCALENDAR"; $result = Reader::read($data); $this->assertInstanceOf(Component::class, $result); diff --git a/tests/VObject/Recur/EventIterator/MainTest.php b/tests/VObject/Recur/EventIterator/MainTest.php index cf317f3ea..15ef85a06 100644 --- a/tests/VObject/Recur/EventIterator/MainTest.php +++ b/tests/VObject/Recur/EventIterator/MainTest.php @@ -4,19 +4,32 @@ use DateTimeImmutable; use DateTimeZone; +use Exception; +use InvalidArgumentException; use PHPUnit\Framework\TestCase; use Sabre\VObject\Component\VCalendar; +use Sabre\VObject\Component\VEvent; use Sabre\VObject\InvalidDataException; +use Sabre\VObject\Property\ICalendar\DateTime; use Sabre\VObject\Recur\EventIterator; +use Sabre\VObject\Recur\MaxInstancesExceededException; +use Sabre\VObject\Recur\NoInstancesException; class MainTest extends TestCase { + /** + * @throws MaxInstancesExceededException + * @throws NoInstancesException + * @throws InvalidDataException + */ public function testValues() { $vcal = new VCalendar(); + /** @var VEvent $ev */ $ev = $vcal->createComponent('VEVENT'); $ev->UID = 'bla'; $ev->RRULE = 'FREQ=DAILY;BYHOUR=10;BYMINUTE=5;BYSECOND=16;BYWEEKNO=32;BYYEARDAY=100,200'; + /** @var DateTime $dtStart */ $dtStart = $vcal->createProperty('DTSTART'); $dtStart->setDateTime(new DateTimeImmutable('2011-10-07')); @@ -31,47 +44,66 @@ public function testValues() /** * @depends testValues + * + * @throws Exception */ public function testInvalidFreq() { $this->expectException(InvalidDataException::class); $vcal = new VCalendar(); + /** @var VEvent $ev */ $ev = $vcal->createComponent('VEVENT'); $ev->RRULE = 'FREQ=SMONTHLY;INTERVAL=3;UNTIL=20111025T000000Z'; $ev->UID = 'foo'; + /** @var DateTime $dtStart */ $dtStart = $vcal->createProperty('DTSTART'); $dtStart->setDateTime(new DateTimeImmutable('2011-10-07', new DateTimeZone('UTC'))); $ev->add($dtStart); $vcal->add($ev); - $it = new EventIterator($vcal, (string) $ev->UID); + new EventIterator($vcal, (string) $ev->UID); } + /** + * @throws MaxInstancesExceededException + * @throws InvalidDataException + * @throws NoInstancesException + */ public function testVCalendarNoUID() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $vcal = new VCalendar(); - $it = new EventIterator($vcal); + new EventIterator($vcal); } + /** + * @throws MaxInstancesExceededException + * @throws NoInstancesException + * @throws InvalidDataException + */ public function testVCalendarInvalidUID() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $vcal = new VCalendar(); - $it = new EventIterator($vcal, 'foo'); + new EventIterator($vcal, 'foo'); } /** * @depends testValues + * + * @throws InvalidDataException + * @throws Exception */ public function testHourly() { $vcal = new VCalendar(); + /** @var VEvent $ev */ $ev = $vcal->createComponent('VEVENT'); $ev->UID = 'bla'; $ev->RRULE = 'FREQ=HOURLY;INTERVAL=3;UNTIL=20111025T000000Z'; + /** @var DateTime $dtStart */ $dtStart = $vcal->createProperty('DTSTART'); $dtStart->setDateTime(new DateTimeImmutable('2011-10-07 12:00:00', new DateTimeZone('UTC'))); @@ -115,14 +147,21 @@ public function testHourly() /** * @depends testValues + * + * @throws InvalidDataException + * @throws MaxInstancesExceededException + * @throws NoInstancesException + * @throws Exception */ public function testDaily() { $vcal = new VCalendar(); + /** @var VEvent $ev */ $ev = $vcal->createComponent('VEVENT'); $ev->UID = 'bla'; $ev->RRULE = 'FREQ=DAILY;INTERVAL=3;UNTIL=20111025T000000Z'; + /** @var DateTime $dtStart */ $dtStart = $vcal->createProperty('DTSTART'); $dtStart->setDateTime(new DateTimeImmutable('2011-10-07', new DateTimeZone('UTC'))); @@ -662,14 +701,21 @@ public function testMonthlyEndOfMonth() /** * @depends testValues + * + * @throws InvalidDataException + * @throws MaxInstancesExceededException + * @throws NoInstancesException + * @throws Exception */ public function testMonthlyByMonthDay() { $vcal = new VCalendar(); + /** @var VEvent $ev */ $ev = $vcal->createComponent('VEVENT'); $ev->UID = 'bla'; $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=5;COUNT=9;BYMONTHDAY=1,31,-7'; + /** @var DateTime $dtStart */ $dtStart = $vcal->createProperty('DTSTART'); $dtStart->setDateTime(new DateTimeImmutable('2011-01-01', new DateTimeZone('UTC'))); @@ -867,14 +913,19 @@ public function testMonthlyByDayBySetPos() /** * @depends testValues + * + * @throws InvalidDataException + * @throws Exception */ public function testYearly() { $vcal = new VCalendar(); + /** @var VEvent $ev */ $ev = $vcal->createComponent('VEVENT'); $ev->UID = 'bla'; $ev->RRULE = 'FREQ=YEARLY;COUNT=10;INTERVAL=3'; + /** @var DateTime $dtStart */ $dtStart = $vcal->createProperty('DTSTART'); $dtStart->setDateTime(new DateTimeImmutable('2011-01-01', new DateTimeZone('UTC'))); @@ -1118,21 +1169,30 @@ public function testFastForwardAllDayEventThatStopAtTheStartTime() /** * @depends testValues + * + * @throws InvalidDataException + * @throws MaxInstancesExceededException + * @throws NoInstancesException + * @throws Exception */ public function testComplexExclusions() { $vcal = new VCalendar(); + /** @var VEvent $ev */ $ev = $vcal->createComponent('VEVENT'); $ev->UID = 'bla'; $ev->RRULE = 'FREQ=YEARLY;COUNT=10'; + /** @var DateTime $dtStart */ $dtStart = $vcal->createProperty('DTSTART'); $tz = new DateTimeZone('Canada/Eastern'); $dtStart->setDateTime(new DateTimeImmutable('2011-01-01 13:50:20', $tz)); + /** @var DateTime $exDate1 */ $exDate1 = $vcal->createProperty('EXDATE'); $exDate1->setDateTimes([new DateTimeImmutable('2012-01-01 13:50:20', $tz), new DateTimeImmutable('2014-01-01 13:50:20', $tz)]); + /** @var DateTime $exDate2 */ $exDate2 = $vcal->createProperty('EXDATE'); $exDate2->setDateTimes([new DateTimeImmutable('2016-01-01 13:50:20', $tz)]); @@ -1386,7 +1446,7 @@ public function testRDATE() */ public function testNoMasterBadUID() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $vcal = new VCalendar(); // ev2 overrides an event, and puts it on 2pm instead. $ev2 = $vcal->createComponent('VEVENT'); diff --git a/tests/VObject/StringUtilTest.php b/tests/VObject/StringUtilTest.php index c614f6aac..67cce4fec 100644 --- a/tests/VObject/StringUtilTest.php +++ b/tests/VObject/StringUtilTest.php @@ -8,7 +8,7 @@ class StringUtilTest extends TestCase { public function testNonUTF8() { - $string = StringUtil::isUTF8(chr(0xbf)); + $string = StringUtil::isUTF8(chr(0xBF)); $this->assertEquals(false, $string); } @@ -29,9 +29,9 @@ public function testUTF8ControlChar() public function testConvertToUTF8nonUTF8() { - $string = StringUtil::convertToUTF8(chr(0xbf)); + $string = StringUtil::convertToUTF8(chr(0xBF)); - $this->assertEquals(utf8_encode(chr(0xbf)), $string); + $this->assertEquals(utf8_encode(chr(0xBF)), $string); } public function testConvertToUTF8IsUTF8() diff --git a/tests/VObject/VCardConverterTest.php b/tests/VObject/VCardConverterTest.php index 7b31809a5..d27e7ff14 100644 --- a/tests/VObject/VCardConverterTest.php +++ b/tests/VObject/VCardConverterTest.php @@ -2,13 +2,18 @@ namespace Sabre\VObject; +use InvalidArgumentException; use PHPUnit\Framework\TestCase; +use Sabre\VObject\Component\VCard; class VCardConverterTest extends TestCase { - use \Sabre\VObject\PHPUnitAssertions; + use PHPUnitAssertions; - public function testConvert30to40() + /** + * @throws InvalidDataException + */ + public function testConvert30to40(): void { $input = <<convert(Document::VCARD40); @@ -50,7 +56,10 @@ public function testConvert30to40() ); } - public function testConvert40to40() + /** + * @throws InvalidDataException + */ + public function testConvert40to40(): void { $input = <<convert(Document::VCARD40); @@ -87,7 +97,10 @@ public function testConvert40to40() ); } - public function testConvert21to40() + /** + * @throws InvalidDataException + */ + public function testConvert21to40(): void { $input = <<convert(Document::VCARD40); @@ -125,7 +139,10 @@ public function testConvert21to40() ); } - public function testConvert30to30() + /** + * @throws InvalidDataException + */ + public function testConvert30to30(): void { $input = <<convert(Document::VCARD30); @@ -164,7 +182,10 @@ public function testConvert30to30() ); } - public function testConvert40to30() + /** + * @throws InvalidDataException + */ + public function testConvert40to30(): void { $input = <<convert(Document::VCARD30); @@ -204,7 +226,10 @@ public function testConvert40to30() ); } - public function testConvertGroupCard() + /** + * @throws InvalidDataException + */ + public function testConvertGroupCard(): void { $input = <<convert(Document::VCARD40); @@ -246,6 +272,7 @@ public function testConvertGroupCard() OUT; + /** @var VCard $vcard */ $vcard = Reader::read($input); $vcard = $vcard->convert(Document::VCARD30); @@ -255,6 +282,9 @@ public function testConvertGroupCard() ); } + /** + * @throws InvalidDataException + */ public function testBDAYConversion() { $input = <<convert(Document::VCARD40); @@ -291,6 +322,7 @@ public function testBDAYConversion() OUT; + /** @var VCard $vcard */ $vcard = Reader::read($input); $vcard = $vcard->convert(Document::VCARD30); @@ -300,9 +332,12 @@ public function testBDAYConversion() ); } - public function testUnknownSourceVCardVersion() + /** + * @throws InvalidDataException + */ + public function testUnknownSourceVCardVersion(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $input = <<convert(Document::VCARD40); } + /** + * @throws InvalidDataException + */ public function testUnknownTargetVCardVersion() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $input = <<convert(Document::VCARD21); } - public function testConvertIndividualCard() + /** + * @throws InvalidDataException + */ + public function testConvertIndividualCard(): void { $input = <<convert(Document::VCARD30); @@ -373,6 +417,7 @@ public function testConvertIndividualCard() OUT; + /** @var VCard $vcard */ $vcard = Reader::read($input); $vcard = $vcard->convert(Document::VCARD40); @@ -382,7 +427,10 @@ public function testConvertIndividualCard() ); } - public function testAnniversary() + /** + * @throws InvalidDataException + */ + public function testAnniversary(): void { $input = <<convert(Document::VCARD30); @@ -419,6 +468,7 @@ public function testAnniversary() $input, ]; + /** @var VCard $vcard */ $vcard = Reader::read($input); $vcard = $vcard->convert(Document::VCARD40); @@ -428,7 +478,10 @@ public function testAnniversary() ); } - public function testMultipleAnniversaries() + /** + * @throws InvalidDataException + */ + public function testMultipleAnniversaries(): void { $input = <<convert(Document::VCARD30); @@ -473,6 +527,7 @@ public function testMultipleAnniversaries() $input, ]; + /** @var VCard $vcard */ $vcard = Reader::read($input); $vcard = $vcard->convert(Document::VCARD40); @@ -482,7 +537,10 @@ public function testMultipleAnniversaries() ); } - public function testNoLabel() + /** + * @throws InvalidDataException + */ + public function testNoLabel(): void { $input = <<assertInstanceOf(Component\VCard::class, $vcard); + /** @var VCard $vcard */ $vcard = $vcard->convert(Document::VCARD40); $vcard = $vcard->serialize(); + /** @var VCard $converted */ $converted = Reader::read($vcard); $converted->validate(); @@ -521,7 +581,10 @@ public function testNoLabel() $this->assertEquals($expected, str_replace("\r", '', $vcard)); } - public function testPhoneNumberValueTypeGetsRemoved() + /** + * @throws InvalidDataException + */ + public function testPhoneNumberValueTypeGetsRemoved(): void { $input = <<convert(Document::VCARD40); diff --git a/tests/phpunit.xml b/tests/phpunit.xml index 16a75c3da..01ba374c1 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -13,15 +13,14 @@ + + + ../lib/ + + . - - - - ../lib/ - - From 0e77fafac4238f4f7bdb02aa820803d9ee79d4e7 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Fri, 21 Jan 2022 11:40:43 +0100 Subject: [PATCH 126/165] Disable php version < 7.4 on CI Signed-off-by: Thomas Citharel --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a019fe77..f9661560b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,11 +12,11 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1'] + php-versions: ['7.4', '8.0', '8.1'] coverage: ['pcov'] code-analysis: ['no'] include: - - php-versions: '7.1' + - php-versions: '7.4' coverage: 'none' code-analysis: 'yes' steps: From 790cfeb69ac89aad2f281f7b6e996d65f28441a7 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Fri, 19 Aug 2022 14:21:33 +0545 Subject: [PATCH 127/165] Update composer dependcies to the latest --- composer.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index fcbadf31e..392cf92d7 100644 --- a/composer.json +++ b/composer.json @@ -35,13 +35,13 @@ "php" : "^7.4 || ^8.0", "ext-mbstring" : "*", "ext-json" : "*", - "sabre/xml" : "^2.1" + "sabre/xml" : "^3.0" }, "require-dev" : { - "friendsofphp/php-cs-fixer": "^3.5.0", - "phpunit/phpunit" : "^7.5 || ^8.5 || ^9.0", + "friendsofphp/php-cs-fixer": "^3.10.0", + "phpunit/phpunit" : "^9.0", "phpunit/php-invoker" : "^2.0 || ^3.1", - "phpstan/phpstan": "^1.4.2" + "phpstan/phpstan": "^1.8" }, "suggest" : { "hoa/bench" : "If you would like to run the benchmark scripts" From 48edc23a10f04ef282bcfc2f3d9d098189d66f55 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Fri, 19 Aug 2022 14:22:54 +0545 Subject: [PATCH 128/165] Apply cs-fixer code style changes --- bin/bench_freebusygenerator.php | 2 +- bin/bench_manipulatevcard.php | 2 +- bin/generateicalendardata.php | 2 +- bin/rrulebench.php | 2 +- lib/Cli.php | 14 +- lib/Component.php | 3 +- lib/FreeBusyGenerator.php | 22 +- lib/Node.php | 8 +- lib/Parameter.php | 16 +- lib/Parser/MimeDir.php | 12 +- lib/Parser/XML.php | 4 +- lib/Property.php | 5 +- lib/Property/ICalendar/DateTime.php | 4 +- lib/Property/ICalendar/Duration.php | 4 +- lib/Property/ICalendar/Recur.php | 2 +- lib/Property/Text.php | 2 + lib/Property/VCard/DateAndOrTime.php | 2 +- lib/Recur/RRuleIterator.php | 2 +- .../FindFromTimezoneIdentifier.php | 6 +- lib/VCardConverter.php | 14 +- tests/VObject/CliTest.php | 28 +- tests/VObject/Component/VAvailabilityTest.php | 22 +- tests/VObject/Component/VCalendarTest.php | 10 +- tests/VObject/Parser/XmlTest.php | 396 +++++++++--------- tests/VObject/PropertyTest.php | 2 +- 25 files changed, 298 insertions(+), 288 deletions(-) diff --git a/bin/bench_freebusygenerator.php b/bin/bench_freebusygenerator.php index 963623d18..4cb4bd2be 100644 --- a/bin/bench_freebusygenerator.php +++ b/bin/bench_freebusygenerator.php @@ -11,7 +11,7 @@ echo "The process will be repeated 100 times to get accurate stats\n"; echo "\n"; echo 'Usage: '.$argv[0]." inputfile.ics\n"; - exit(); + exit; } list(, $inputFile) = $argv; diff --git a/bin/bench_manipulatevcard.php b/bin/bench_manipulatevcard.php index df6d9f23d..96a506907 100644 --- a/bin/bench_manipulatevcard.php +++ b/bin/bench_manipulatevcard.php @@ -10,7 +10,7 @@ echo 'system.'; echo "\n"; echo 'Usage: '.$argv[0]." inputfile.vcf\n"; - exit(); + exit; } list(, $inputFile) = $argv; diff --git a/bin/generateicalendardata.php b/bin/generateicalendardata.php index 019ed9745..a3dd3f24e 100755 --- a/bin/generateicalendardata.php +++ b/bin/generateicalendardata.php @@ -18,7 +18,7 @@ HI ); - exit(); + exit; } $events = 100; diff --git a/bin/rrulebench.php b/bin/rrulebench.php index 69008002e..c8be08d46 100644 --- a/bin/rrulebench.php +++ b/bin/rrulebench.php @@ -9,7 +9,7 @@ echo 'system.'; echo "\n"; echo 'Usage: '.$argv[0]." inputfile.ics startdate enddate\n"; - exit(); + exit; } list(, $inputFile, $startDate, $endDate) = $argv; diff --git a/lib/Cli.php b/lib/Cli.php index 987665afa..6499cb0a8 100644 --- a/lib/Cli.php +++ b/lib/Cli.php @@ -131,15 +131,15 @@ public function main(array $argv): int // jcard/jcal documents case 'jcard': case 'jcal': - // specific document versions + // specific document versions case 'vcard21': case 'vcard30': case 'vcard40': case 'icalendar20': - // specific formats + // specific formats case 'json': case 'mimedir': - // icalendar/vcad + // icalendar/vcad case 'icalendar': case 'vcard': $this->format = $value; @@ -166,7 +166,7 @@ public function main(array $argv): int $this->inputFormat = 'json'; break; - // mimedir formats + // mimedir formats case 'mimedir': case 'icalendar': case 'vcard': @@ -281,7 +281,7 @@ protected function showHelp(): void $this->log($this->colorize('green', ' convert').' source_file [output_file] Converts a file.'); $this->log($this->colorize('green', ' color').' source_file Colorize a file, useful for debugging.'); $this->log( - <<inputFormat) { - $this->parser = new MimeDir($this->stdin, ($this->forgiving ? Reader::OPTION_FORGIVING : 0)); + $this->parser = new MimeDir($this->stdin, $this->forgiving ? Reader::OPTION_FORGIVING : 0); } else { - $this->parser = new Json($this->stdin, ($this->forgiving ? Reader::OPTION_FORGIVING : 0)); + $this->parser = new Json($this->stdin, $this->forgiving ? Reader::OPTION_FORGIVING : 0); } } diff --git a/lib/Component.php b/lib/Component.php index 9a54d4ea8..3e9cc551c 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -49,8 +49,7 @@ class Component extends Node * an iCalendar object, this may be something like CALSCALE:GREGORIAN. To * ensure that this does not happen, set $defaults to false. * - * @param string|null $name such as VCALENDAR, VEVENT - * @param bool $defaults + * @param string|null $name such as VCALENDAR, VEVENT */ public function __construct(Document $root, ?string $name, array $children = [], bool $defaults = true) { diff --git a/lib/FreeBusyGenerator.php b/lib/FreeBusyGenerator.php index 48927d317..14983e30a 100644 --- a/lib/FreeBusyGenerator.php +++ b/lib/FreeBusyGenerator.php @@ -305,18 +305,18 @@ function ($a, $b) { foreach ($vavail->AVAILABLE as $available) { list($availStart, $availEnd) = $available->getEffectiveStartEnd(); $fbData->add( - $availStart->getTimeStamp(), - $availEnd->getTimeStamp(), - 'FREE' - ); + $availStart->getTimeStamp(), + $availEnd->getTimeStamp(), + 'FREE' + ); if ($available->RRULE) { // Our favourite thing: recurrence!! $rruleIterator = new Recur\RRuleIterator( - $available->RRULE->getValue(), - $availStart - ); + $available->RRULE->getValue(), + $availStart + ); $rruleIterator->fastForward($vavailStart); $startEndDiff = $availStart->diff($availEnd); @@ -337,10 +337,10 @@ function ($a, $b) { } $fbData->add( - $recurStart->getTimeStamp(), - $recurEnd->getTimeStamp(), - 'FREE' - ); + $recurStart->getTimeStamp(), + $recurEnd->getTimeStamp(), + 'FREE' + ); $rruleIterator->next(); } diff --git a/lib/Node.php b/lib/Node.php index efb18347f..228f23ba6 100644 --- a/lib/Node.php +++ b/lib/Node.php @@ -207,8 +207,8 @@ public function offsetSet($offset, $value) // @codeCoverageIgnoreStart // - // This method always throws an exception, so we ignore the closing - // brace + // This method always throws an exception, so we ignore the closing + // brace } // @codeCoverageIgnoreEnd @@ -228,8 +228,8 @@ public function offsetUnset($offset) // @codeCoverageIgnoreStart // - // This method always throws an exception, so we ignore the closing - // brace + // This method always throws an exception, so we ignore the closing + // brace } // @codeCoverageIgnoreEnd diff --git a/lib/Parameter.php b/lib/Parameter.php index ef3461b85..039fa1965 100644 --- a/lib/Parameter.php +++ b/lib/Parameter.php @@ -82,16 +82,16 @@ public static function guessParameterNameByValue(string $value): string $name = 'ENCODING'; break; - // Common types + // Common types case 'WORK': case 'HOME': case 'PREF': - // Delivery Label Type + // Delivery Label Type case 'DOM': case 'INTL': case 'POSTAL': case 'PARCEL': - // Telephone types + // Telephone types case 'VOICE': case 'FAX': case 'MSG': @@ -102,7 +102,7 @@ public static function guessParameterNameByValue(string $value): string case 'CAR': case 'ISDN': case 'VIDEO': - // EMAIL types (lol) + // EMAIL types (lol) case 'AOL': case 'APPLELINK': case 'ATTMAIL': @@ -115,7 +115,7 @@ public static function guessParameterNameByValue(string $value): string case 'PRODIGY': case 'TLX': case 'X400': - // Photo / Logo format types + // Photo / Logo format types case 'GIF': case 'CGM': case 'WMF': @@ -130,17 +130,17 @@ public static function guessParameterNameByValue(string $value): string case 'MPEG2': case 'AVI': case 'QTIME': - // Sound Digital Audio Type + // Sound Digital Audio Type case 'WAVE': case 'PCM': case 'AIFF': - // Key types + // Key types case 'X509': case 'PGP': $name = 'TYPE'; break; - // Value types + // Value types case 'INLINE': case 'URL': case 'CONTENT-ID': diff --git a/lib/Parser/MimeDir.php b/lib/Parser/MimeDir.php index b06a16d33..cff33c8cd 100644 --- a/lib/Parser/MimeDir.php +++ b/lib/Parser/MimeDir.php @@ -4,10 +4,15 @@ use function feof; use function fgets; + use InvalidArgumentException; + use function is_null; + use LogicException; + use function rtrim; + use Sabre\VObject\Component; use Sabre\VObject\Component\VCalendar; use Sabre\VObject\Component\VCard; @@ -17,6 +22,7 @@ use Sabre\VObject\Node; use Sabre\VObject\ParseException; use Sabre\VObject\Property; + use function substr; /** @@ -361,7 +367,7 @@ protected function readProperty(string $line) ) (?=[;:,]) /xi"; - //echo $regex, "\n"; exit(); + // echo $regex, "\n"; exit(); preg_match_all($regex, $line, $matches, PREG_SET_ORDER); $property = [ @@ -640,9 +646,9 @@ function ($matches) { case '\'': return '"'; - // @codeCoverageIgnoreStart + // @codeCoverageIgnoreStart } - // @codeCoverageIgnoreEnd + // @codeCoverageIgnoreEnd }, $input ); diff --git a/lib/Parser/XML.php b/lib/Parser/XML.php index a64f5c50f..22a3857a9 100644 --- a/lib/Parser/XML.php +++ b/lib/Parser/XML.php @@ -343,9 +343,9 @@ protected function createProperty(Component $parentComponent, string $name, arra * * @param resource|string|array $input * - * @throws SabreXml\LibXMLException - * * @return void + * + * @throws SabreXml\LibXMLException */ public function setInput($input) { diff --git a/lib/Property.php b/lib/Property.php index 310e66e59..4f580e17e 100644 --- a/lib/Property.php +++ b/lib/Property.php @@ -3,8 +3,11 @@ namespace Sabre\VObject; use Exception; + use function preg_replace; + use Sabre\Xml; + use function substr; /** @@ -546,7 +549,7 @@ public function validate(int $options = 0): array break; case Document::VCARD30: $allowedEncoding = ['B']; - //Repair vCard30 that use BASE64 encoding + // Repair vCard30 that use BASE64 encoding if ($options & self::REPAIR) { if ('BASE64' === strtoupper($encoding)) { $encoding = 'B'; diff --git a/lib/Property/ICalendar/DateTime.php b/lib/Property/ICalendar/DateTime.php index 774ab7180..1b3c2ebcc 100644 --- a/lib/Property/ICalendar/DateTime.php +++ b/lib/Property/ICalendar/DateTime.php @@ -148,9 +148,9 @@ public function getDateTime(DateTimeZone $timeZone = null): ?DateTimeImmutable * property or floating time, we will use the DateTimeZone argument to * figure out the exact date. * - * @throws InvalidDataException - * * @return DateInterval[]|DateTimeImmutable[] + * + * @throws InvalidDataException */ public function getDateTimes(DateTimeZone $timeZone = null): array { diff --git a/lib/Property/ICalendar/Duration.php b/lib/Property/ICalendar/Duration.php index 0a189b14e..39d74e400 100644 --- a/lib/Property/ICalendar/Duration.php +++ b/lib/Property/ICalendar/Duration.php @@ -61,9 +61,9 @@ public function getValueType(): string * * If the property has more than one value, only the first is returned. * - * @throws InvalidDataException - * * @return DateInterval|string + * + * @throws InvalidDataException */ public function getDateInterval() { diff --git a/lib/Property/ICalendar/Recur.php b/lib/Property/ICalendar/Recur.php index 36e4e8f6b..b92779391 100644 --- a/lib/Property/ICalendar/Recur.php +++ b/lib/Property/ICalendar/Recur.php @@ -42,7 +42,7 @@ class Recur extends Property public function setValue($value): void { // If we're getting the data from json, we'll be receiving an object - if ($value instanceof \StdClass) { + if ($value instanceof \stdClass) { $value = (array) $value; } diff --git a/lib/Property/Text.php b/lib/Property/Text.php index 281e65e8a..13b442563 100644 --- a/lib/Property/Text.php +++ b/lib/Property/Text.php @@ -9,12 +9,14 @@ use function is_null; use function ord; use function preg_replace; + use Sabre\VObject\Component; use Sabre\VObject\Document; use Sabre\VObject\InvalidDataException; use Sabre\VObject\Parser\MimeDir; use Sabre\VObject\Property; use Sabre\Xml; + use function str_replace; use function strlen; use function strpos; diff --git a/lib/Property/VCard/DateAndOrTime.php b/lib/Property/VCard/DateAndOrTime.php index 470725c89..fc8ade5b0 100644 --- a/lib/Property/VCard/DateAndOrTime.php +++ b/lib/Property/VCard/DateAndOrTime.php @@ -261,7 +261,7 @@ protected function xmlSerializeValue(Xml\Writer $writer): void $value .= '---'.$r('date'); } - // # 4.3.2 + // # 4.3.2 // value-time = element time { // xsd:string { pattern = "(\d\d(\d\d(\d\d)?)?|-\d\d(\d\d?)|--\d\d)" // ~ "(Z|[+\-]\d\d(\d\d)?)?" } diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index 0cb9e57bc..fb964f3c5 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -31,7 +31,7 @@ class RRuleIterator implements Iterator * we want to iterate. The value is a unix timestamp and currently * corresponds to the datetime 9999-12-31 11:59:59 UTC. */ - const dateUpperLimit = 253402300799; + public const dateUpperLimit = 253402300799; /** * Creates the Iterator. diff --git a/lib/TimezoneGuesser/FindFromTimezoneIdentifier.php b/lib/TimezoneGuesser/FindFromTimezoneIdentifier.php index 8424e14a4..2449b4fa7 100644 --- a/lib/TimezoneGuesser/FindFromTimezoneIdentifier.php +++ b/lib/TimezoneGuesser/FindFromTimezoneIdentifier.php @@ -41,9 +41,9 @@ public function find(string $tzid, bool $failIfUncertain = false): ?DateTimeZone try { if ( - (in_array($tzid, $tzIdentifiers)) || - (preg_match('/^GMT(\+|-)([0-9]{4})$/', $tzid, $matches)) || - (in_array($tzid, $this->getIdentifiersBC())) + in_array($tzid, $tzIdentifiers) || + preg_match('/^GMT(\+|-)([0-9]{4})$/', $tzid, $matches) || + in_array($tzid, $this->getIdentifiersBC()) ) { return new DateTimeZone($tzid); } diff --git a/lib/VCardConverter.php b/lib/VCardConverter.php index 8480421d9..6feedd854 100644 --- a/lib/VCardConverter.php +++ b/lib/VCardConverter.php @@ -217,7 +217,7 @@ protected function convertProperty(Component\VCard $input, Component\VCard $outp } $newProperty->name = 'ANNIVERSARY'; break; - // Apple's per-property label system. + // Apple's per-property label system. case 'X-ABLABEL': if ('_$!!$_' === $newProperty->getValue()) { // We can safely remove these, as they are converted to @@ -377,7 +377,7 @@ protected function convertParameters40(Property $newProperty, array $parameters) } } break; - // These no longer exist in vCard 4 + // These no longer exist in vCard 4 case 'ENCODING': case 'CHARSET': break; @@ -410,11 +410,11 @@ protected function convertParameters30(Property $newProperty, array $parameters) } break; - /* - * Converting PREF=1 to TYPE=PREF. - * - * Any other PREF numbers we'll drop. - */ + /* + * Converting PREF=1 to TYPE=PREF. + * + * Any other PREF numbers we'll drop. + */ case 'PREF': if ('1' == $param->getValue()) { $newProperty->add('TYPE', 'PREF'); diff --git a/tests/VObject/CliTest.php b/tests/VObject/CliTest.php index a4124b76b..bc21b9b84 100644 --- a/tests/VObject/CliTest.php +++ b/tests/VObject/CliTest.php @@ -135,7 +135,7 @@ public function testConvertJson() FN:Cowboy Henk END:VCARD ICS - ); + ); rewind($inputStream); $this->cli->stdin = $inputStream; @@ -166,7 +166,7 @@ public function testConvertJCardPretty() FN:Cowboy Henk END:VCARD ICS - ); + ); rewind($inputStream); $this->cli->stdin = $inputStream; @@ -203,7 +203,7 @@ public function testConvertJCalFail() FN:Cowboy Henk END:VCARD ICS - ); + ); rewind($inputStream); $this->cli->stdin = $inputStream; @@ -248,7 +248,7 @@ public function testConvertMimeDir() ] ] JCARD - ); + ); rewind($inputStream); $this->cli->stdin = $inputStream; @@ -311,7 +311,7 @@ public function testVCard3040() END:VCARD VCARD - ); + ); rewind($inputStream); $this->cli->stdin = $inputStream; @@ -350,7 +350,7 @@ public function testVCard4030() END:VCARD VCARD - ); + ); rewind($inputStream); $this->cli->stdin = $inputStream; @@ -389,7 +389,7 @@ public function testVCard4021() END:VCARD VCARD - ); + ); rewind($inputStream); $this->cli->stdin = $inputStream; @@ -412,7 +412,7 @@ public function testValidate() END:VCARD VCARD - ); + ); rewind($inputStream); $this->cli->stdin = $inputStream; $result = $this->cli->main(['vobject', 'validate', '-']); @@ -433,7 +433,7 @@ public function testValidateFail() END:VCARD VCARD - ); + ); rewind($inputStream); $this->cli->stdin = $inputStream; // vCard 2.0 is not supported yet, so this returns a failure. @@ -453,7 +453,7 @@ public function testValidateFail2() END:VCALENDAR VCARD - ); + ); rewind($inputStream); $this->cli->stdin = $inputStream; @@ -473,7 +473,7 @@ public function testRepair() END:VCARD VCARD - ); + ); rewind($inputStream); $this->cli->stdin = $inputStream; @@ -510,7 +510,7 @@ public function testRepairNothing() END:VCALENDAR VCARD - ); + ); rewind($inputStream); $this->cli->stdin = $inputStream; @@ -556,7 +556,7 @@ public function testColorCalendar() END:VCALENDAR VCARD - ); + ); rewind($inputStream); $this->cli->stdin = $inputStream; @@ -597,7 +597,7 @@ public function testColorVCard() END:VCARD VCARD - ); + ); rewind($inputStream); $this->cli->stdin = $inputStream; diff --git a/tests/VObject/Component/VAvailabilityTest.php b/tests/VObject/Component/VAvailabilityTest.php index edd06b02b..ba86c900e 100644 --- a/tests/VObject/Component/VAvailabilityTest.php +++ b/tests/VObject/Component/VAvailabilityTest.php @@ -126,7 +126,7 @@ public function testRFCxxxSection3Part1AvailabilitypropRequired() { // UID and DTSTAMP are present. $this->assertIsValid(Reader::read( -<<assertIsNotValid(Reader::read( -<<assertIsNotValid(Reader::read( -<<assertIsNotValid(Reader::read( -<<assertIsValid(Reader::read( -<<assertIsNotValid(Reader::read( -<<assertIsNotValid(Reader::read( -<<assertIsNotValid(Reader::read( -<<assertIsNotValid(Reader::read( -<<assertXMLEqualsToMimeDir( -<< @@ -48,7 +48,7 @@ public function testRFC6321Example1() XML -, + , 'BEGIN:VCALENDAR'."\n". // VERSION comes first because this is required by vCard 4.0. 'VERSION:2.0'."\n". @@ -265,13 +265,13 @@ public function testRFC6321Example2() public function testRFC6321Section3Part2() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< XML -, + , 'BEGIN:VCALENDAR'."\n". 'END:VCALENDAR'."\n" ); @@ -283,7 +283,7 @@ public function testRFC6321Section3Part2() public function testRFC6321Section3Part3() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -300,7 +300,7 @@ public function testRFC6321Section3Part3() XML -, + , 'BEGIN:VCALENDAR'."\n". 'BEGIN:VTIMEZONE'."\n". 'END:VTIMEZONE'."\n". @@ -328,7 +328,7 @@ public function testRFC6321Section3Part3() public function testRFC6321Section3Part4Part1Part2() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -341,7 +341,7 @@ public function testRFC6321Section3Part4Part1Part2() XML -, + , 'BEGIN:VCALENDAR'."\n". 'GEO:37.386013;-122.082932'."\n". 'END:VCALENDAR'."\n" @@ -355,7 +355,7 @@ public function testRFC6321Section3Part4Part1Part3() { // Example 1 of RFC5545, Section 3.8.8.3. $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -368,7 +368,7 @@ public function testRFC6321Section3Part4Part1Part3() XML -, + , 'BEGIN:VCALENDAR'."\n". 'REQUEST-STATUS:2.0;Success'."\n". 'END:VCALENDAR'."\n" @@ -376,7 +376,7 @@ public function testRFC6321Section3Part4Part1Part3() // Example 2 of RFC5545, Section 3.8.8.3. $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -390,7 +390,7 @@ public function testRFC6321Section3Part4Part1Part3() XML -, + , 'BEGIN:VCALENDAR'."\n". 'REQUEST-STATUS:3.1;Invalid property value;DTSTART:96-Apr-01'."\n". 'END:VCALENDAR'."\n" @@ -398,7 +398,7 @@ public function testRFC6321Section3Part4Part1Part3() // Example 3 of RFC5545, Section 3.8.8.3. $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -412,7 +412,7 @@ public function testRFC6321Section3Part4Part1Part3() XML -, + , 'BEGIN:VCALENDAR'."\n". 'REQUEST-STATUS:2.8;Success\, repeating event ignored. Scheduled as a single'."\n". ' event.;RRULE:FREQ=WEEKLY\;INTERVAL=2'."\n". @@ -421,7 +421,7 @@ public function testRFC6321Section3Part4Part1Part3() // Example 4 of RFC5545, Section 3.8.8.3. $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -434,7 +434,7 @@ public function testRFC6321Section3Part4Part1Part3() XML -, + , 'BEGIN:VCALENDAR'."\n". 'REQUEST-STATUS:4.1;Event conflict. Date-time is busy.'."\n". 'END:VCALENDAR'."\n" @@ -442,7 +442,7 @@ public function testRFC6321Section3Part4Part1Part3() // Example 5 of RFC5545, Section 3.8.8.3. $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -456,7 +456,7 @@ public function testRFC6321Section3Part4Part1Part3() XML -, + , 'BEGIN:VCALENDAR'."\n". 'REQUEST-STATUS:3.7;Invalid calendar user;ATTENDEE:mailto:jsmith@example.com'."\n". 'END:VCALENDAR'."\n" @@ -469,7 +469,7 @@ public function testRFC6321Section3Part4Part1Part3() public function testRFC6321Section3Part6Part1() { $this->assertXMLEqualsToMimeDir( -<< @@ -481,7 +481,7 @@ public function testRFC6321Section3Part6Part1() XML -, + , 'BEGIN:VCALENDAR'."\n". 'ATTACH:SGVsbG8gV29ybGQh'."\n". 'END:VCALENDAR'."\n" @@ -489,7 +489,7 @@ public function testRFC6321Section3Part6Part1() // In vCard 4, BINARY no longer exists and is replaced by URI. $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -501,7 +501,7 @@ public function testRFC6321Section3Part6Part1() XML -, + , 'BEGIN:VCALENDAR'."\n". 'ATTACH:SGVsbG8gV29ybGQh'."\n". 'END:VCALENDAR'."\n" @@ -514,7 +514,7 @@ public function testRFC6321Section3Part6Part1() public function testRFC6321Section3Part6Part2() { $this->assertXMLEqualsToMimeDir( -<< @@ -529,7 +529,7 @@ public function testRFC6321Section3Part6Part2() XML -, + , 'BEGIN:VCALENDAR'."\n". 'ATTENDEE;RSVP=true:mailto:cyrus@example.com'."\n". 'END:VCALENDAR'."\n" @@ -542,7 +542,7 @@ public function testRFC6321Section3Part6Part2() public function testRFC6321Section3Part6Part3() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -554,7 +554,7 @@ public function testRFC6321Section3Part6Part3() XML -, + , 'BEGIN:VCALENDAR'."\n". 'ATTENDEE:mailto:cyrus@example.com'."\n". 'END:VCALENDAR'."\n" @@ -567,7 +567,7 @@ public function testRFC6321Section3Part6Part3() public function testRFC6321Section3Part6Part4() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -579,7 +579,7 @@ public function testRFC6321Section3Part6Part4() XML -, + , 'BEGIN:VCALENDAR'."\n". 'DTSTART;VALUE=DATE:20110517'."\n". 'END:VCALENDAR'."\n" @@ -592,7 +592,7 @@ public function testRFC6321Section3Part6Part4() public function testRFC6321Section3Part6Part5() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -604,7 +604,7 @@ public function testRFC6321Section3Part6Part5() XML -, + , 'BEGIN:VCALENDAR'."\n". 'DTSTART:20110517T120000'."\n". 'END:VCALENDAR'."\n" @@ -617,7 +617,7 @@ public function testRFC6321Section3Part6Part5() public function testRFC6321Section3Part6Part6() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -629,7 +629,7 @@ public function testRFC6321Section3Part6Part6() XML -, + , 'BEGIN:VCALENDAR'."\n". 'DURATION:P1D'."\n". 'END:VCALENDAR'."\n" @@ -651,7 +651,7 @@ public function testRFC6321Section3Part6Part7() public function testRFC6321Section3Part6Part8() { $this->assertXMLEqualsToMimeDir( -<< @@ -663,14 +663,14 @@ public function testRFC6321Section3Part6Part8() XML -, + , 'BEGIN:VCALENDAR'."\n". 'FOO:42'."\n". 'END:VCALENDAR'."\n" ); $this->assertXMLEqualsToMimeDir( -<< @@ -682,7 +682,7 @@ public function testRFC6321Section3Part6Part8() XML -, + , 'BEGIN:VCALENDAR'."\n". 'FOO:-42'."\n". 'END:VCALENDAR'."\n" @@ -695,7 +695,7 @@ public function testRFC6321Section3Part6Part8() public function testRFC6321Section3Part6Part9() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -710,14 +710,14 @@ public function testRFC6321Section3Part6Part9() XML -, + , 'BEGIN:VCALENDAR'."\n". 'FREEBUSY:20110517T120000/P1H'."\n". 'END:VCALENDAR'."\n" ); $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -732,7 +732,7 @@ public function testRFC6321Section3Part6Part9() XML -, + , 'BEGIN:VCALENDAR'."\n". 'FREEBUSY:20110517T120000/20120517T120000'."\n". 'END:VCALENDAR'."\n" @@ -745,7 +745,7 @@ public function testRFC6321Section3Part6Part9() public function testRFC6321Section3Part6Part10() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -762,7 +762,7 @@ public function testRFC6321Section3Part6Part10() XML -, + , 'BEGIN:VCALENDAR'."\n". 'RRULE:FREQ=YEARLY;COUNT=5;BYDAY=-1SU;BYMONTH=10'."\n". 'END:VCALENDAR'."\n" @@ -775,7 +775,7 @@ public function testRFC6321Section3Part6Part10() public function testRFC6321Section3Part6Part11() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -787,7 +787,7 @@ public function testRFC6321Section3Part6Part11() XML -, + , 'BEGIN:VCALENDAR'."\n". 'CALSCALE:GREGORIAN'."\n". 'END:VCALENDAR'."\n" @@ -800,7 +800,7 @@ public function testRFC6321Section3Part6Part11() public function testRFC6321Section3Part6Part12() { $this->assertXMLEqualsToMimeDir( -<< @@ -812,7 +812,7 @@ public function testRFC6321Section3Part6Part12() XML -, + , 'BEGIN:VCALENDAR'."\n". 'FOO:120000'."\n". 'END:VCALENDAR'."\n" @@ -825,7 +825,7 @@ public function testRFC6321Section3Part6Part12() public function testRFC6321Section3Part6Part13() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -837,7 +837,7 @@ public function testRFC6321Section3Part6Part13() XML -, + , 'BEGIN:VCALENDAR'."\n". 'ATTACH:http://calendar.example.com'."\n". 'END:VCALENDAR'."\n" @@ -851,7 +851,7 @@ public function testRFC6321Section3Part6Part14() { // Example 1 of RFC5545, Section 3.3.14. $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -863,7 +863,7 @@ public function testRFC6321Section3Part6Part14() XML -, + , 'BEGIN:VCALENDAR'."\n". 'TZOFFSETFROM:-0500'."\n". 'END:VCALENDAR'."\n" @@ -871,7 +871,7 @@ public function testRFC6321Section3Part6Part14() // Example 2 of RFC5545, Section 3.3.14. $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -883,7 +883,7 @@ public function testRFC6321Section3Part6Part14() XML -, + , 'BEGIN:VCALENDAR'."\n". 'TZOFFSETFROM:+0100'."\n". 'END:VCALENDAR'."\n" @@ -896,7 +896,7 @@ public function testRFC6321Section3Part6Part14() public function testRFC6321Section5() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -908,14 +908,14 @@ public function testRFC6321Section5() XML -, + , 'BEGIN:VCALENDAR'."\n". 'X-PROPERTY:20110512T120000Z'."\n". 'END:VCALENDAR'."\n" ); $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -932,7 +932,7 @@ public function testRFC6321Section5() XML -, + , 'BEGIN:VCALENDAR'."\n". 'DTSTART;X-PARAM=PT30M:20110512T130000Z'."\n". 'END:VCALENDAR'."\n" @@ -942,7 +942,7 @@ public function testRFC6321Section5() public function testRDateWithDateTime() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -954,14 +954,14 @@ public function testRDateWithDateTime() XML -, + , 'BEGIN:VCALENDAR'."\n". 'RDATE:20080205T191224Z'."\n". 'END:VCALENDAR'."\n" ); $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -974,7 +974,7 @@ public function testRDateWithDateTime() XML -, + , 'BEGIN:VCALENDAR'."\n". 'RDATE:20080205T191224Z,20090205T191224Z'."\n". 'END:VCALENDAR'."\n" @@ -984,7 +984,7 @@ public function testRDateWithDateTime() public function testRDateWithDate() { $this->assertXMLEqualsToMimeDir( -<< @@ -996,14 +996,14 @@ public function testRDateWithDate() XML -, + , 'BEGIN:VCALENDAR'."\n". 'RDATE:20081006'."\n". 'END:VCALENDAR'."\n" ); $this->assertXMLEqualsToMimeDir( -<< @@ -1017,7 +1017,7 @@ public function testRDateWithDate() XML -, + , 'BEGIN:VCALENDAR'."\n". 'RDATE:20081006,20091006,20101006'."\n". 'END:VCALENDAR'."\n" @@ -1027,7 +1027,7 @@ public function testRDateWithDate() public function testRDateWithPeriod() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1047,14 +1047,14 @@ public function testRDateWithPeriod() XML -, + , 'BEGIN:VCALENDAR'."\n". 'RDATE;TZID=US/Eastern;VALUE=PERIOD:20060102T150000/PT2H'."\n". 'END:VCALENDAR'."\n" ); $this->assertXMLEqualsToMimeDir( -<< @@ -1078,7 +1078,7 @@ public function testRDateWithPeriod() XML -, + , 'BEGIN:VCALENDAR'."\n". 'RDATE;TZID=US/Eastern;VALUE=PERIOD:20060102T150000/PT2H,20080102T150000/PT1'."\n". ' H'."\n". @@ -1092,7 +1092,7 @@ public function testRDateWithPeriod() public function testRFC6351Basic() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1109,7 +1109,7 @@ public function testRFC6351Basic() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'FN:J. Doe'."\n". @@ -1124,7 +1124,7 @@ public function testRFC6351Basic() public function testRFC6351Example1() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1150,7 +1150,7 @@ public function testRFC6351Example1() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'FN:J. Doe'."\n". @@ -1168,7 +1168,7 @@ public function testRFC6351Example1() public function testRFC6351Section5() { $this->assertXMLEqualsToMimeDir( -<< @@ -1184,7 +1184,7 @@ public function testRFC6351Section5() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'TEL;TYPE="voice,video":tel:+1-555-555-555'."\n". @@ -1192,7 +1192,7 @@ public function testRFC6351Section5() ); $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1208,7 +1208,7 @@ public function testRFC6351Section5() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'TEL;TYPE="voice,video":tel:+1-555-555-555'."\n". @@ -1222,7 +1222,7 @@ public function testRFC6351Section5() public function testRFC6351Section5Group() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1245,7 +1245,7 @@ public function testRFC6351Section5Group() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'TEL:tel:+1-555-555-556'."\n". @@ -1262,7 +1262,7 @@ public function testRFC6351Section5Group() public function testRFC6351Section5Part1NoNamespace() { $this->assertXMLEqualsToMimeDir( -<< @@ -1277,7 +1277,7 @@ public function testRFC6351Section5Part1NoNamespace() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'X-MY-PROP;PREF=1:value goes here'."\n". @@ -1291,7 +1291,7 @@ public function testRFC6351Section5Part1NoNamespace() public function testRFC6351ValueDateWithYearMonthDay() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1301,7 +1301,7 @@ public function testRFC6351ValueDateWithYearMonthDay() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:20150128'."\n". @@ -1315,7 +1315,7 @@ public function testRFC6351ValueDateWithYearMonthDay() public function testRFC6351ValueDateWithYearMonth() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1325,7 +1325,7 @@ public function testRFC6351ValueDateWithYearMonth() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:2015-01'."\n". @@ -1339,7 +1339,7 @@ public function testRFC6351ValueDateWithYearMonth() public function testRFC6351ValueDateWithMonth() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1349,7 +1349,7 @@ public function testRFC6351ValueDateWithMonth() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:--01'."\n". @@ -1363,7 +1363,7 @@ public function testRFC6351ValueDateWithMonth() public function testRFC6351ValueDateWithMonthDay() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1373,7 +1373,7 @@ public function testRFC6351ValueDateWithMonthDay() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:--0128'."\n". @@ -1387,7 +1387,7 @@ public function testRFC6351ValueDateWithMonthDay() public function testRFC6351ValueDateWithDay() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1397,7 +1397,7 @@ public function testRFC6351ValueDateWithDay() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:---28'."\n". @@ -1411,7 +1411,7 @@ public function testRFC6351ValueDateWithDay() public function testRFC6351ValueTimeWithHour() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1421,7 +1421,7 @@ public function testRFC6351ValueTimeWithHour() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:13'."\n". @@ -1435,7 +1435,7 @@ public function testRFC6351ValueTimeWithHour() public function testRFC6351ValueTimeWithHourMinute() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1445,7 +1445,7 @@ public function testRFC6351ValueTimeWithHourMinute() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:1353'."\n". @@ -1459,7 +1459,7 @@ public function testRFC6351ValueTimeWithHourMinute() public function testRFC6351ValueTimeWithHourMinuteSecond() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1469,7 +1469,7 @@ public function testRFC6351ValueTimeWithHourMinuteSecond() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:135301'."\n". @@ -1483,7 +1483,7 @@ public function testRFC6351ValueTimeWithHourMinuteSecond() public function testRFC6351ValueTimeWithMinute() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1493,7 +1493,7 @@ public function testRFC6351ValueTimeWithMinute() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:-53'."\n". @@ -1507,7 +1507,7 @@ public function testRFC6351ValueTimeWithMinute() public function testRFC6351ValueTimeWithMinuteSecond() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1517,7 +1517,7 @@ public function testRFC6351ValueTimeWithMinuteSecond() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:-5301'."\n". @@ -1564,7 +1564,7 @@ public function testRFC6351ValueTimeWithSecond() public function testRFC6351ValueTimeWithSecondZ() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1574,7 +1574,7 @@ public function testRFC6351ValueTimeWithSecondZ() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:--01Z'."\n". @@ -1588,7 +1588,7 @@ public function testRFC6351ValueTimeWithSecondZ() public function testRFC6351ValueTimeWithSecondTZ() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1598,7 +1598,7 @@ public function testRFC6351ValueTimeWithSecondTZ() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:--01+1234'."\n". @@ -1612,7 +1612,7 @@ public function testRFC6351ValueTimeWithSecondTZ() public function testRFC6351ValueDateTimeWithYearMonthDayHour() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1622,7 +1622,7 @@ public function testRFC6351ValueDateTimeWithYearMonthDayHour() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:20150128T13'."\n". @@ -1636,7 +1636,7 @@ public function testRFC6351ValueDateTimeWithYearMonthDayHour() public function testRFC6351ValueDateTimeWithMonthDayHour() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1646,7 +1646,7 @@ public function testRFC6351ValueDateTimeWithMonthDayHour() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:--0128T13'."\n". @@ -1660,7 +1660,7 @@ public function testRFC6351ValueDateTimeWithMonthDayHour() public function testRFC6351ValueDateTimeWithDayHour() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1670,7 +1670,7 @@ public function testRFC6351ValueDateTimeWithDayHour() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:---28T13'."\n". @@ -1684,7 +1684,7 @@ public function testRFC6351ValueDateTimeWithDayHour() public function testRFC6351ValueDateTimeWithDayHourMinute() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1694,7 +1694,7 @@ public function testRFC6351ValueDateTimeWithDayHourMinute() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:---28T1353'."\n". @@ -1708,7 +1708,7 @@ public function testRFC6351ValueDateTimeWithDayHourMinute() public function testRFC6351ValueDateTimeWithDayHourMinuteSecond() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1718,7 +1718,7 @@ public function testRFC6351ValueDateTimeWithDayHourMinuteSecond() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:---28T135301'."\n". @@ -1732,7 +1732,7 @@ public function testRFC6351ValueDateTimeWithDayHourMinuteSecond() public function testRFC6351ValueDateTimeWithDayHourZ() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1742,7 +1742,7 @@ public function testRFC6351ValueDateTimeWithDayHourZ() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:---28T13Z'."\n". @@ -1756,7 +1756,7 @@ public function testRFC6351ValueDateTimeWithDayHourZ() public function testRFC6351ValueDateTimeWithDayHourTZ() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1766,7 +1766,7 @@ public function testRFC6351ValueDateTimeWithDayHourTZ() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:---28T13+1234'."\n". @@ -1780,7 +1780,7 @@ public function testRFC6351ValueDateTimeWithDayHourTZ() public function testRFC6350Section6Part1Part3() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1790,7 +1790,7 @@ public function testRFC6350Section6Part1Part3() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'SOURCE:ldap://ldap.example.com/cn=Babs%20Jensen\,%20o=Babsco\,%20c=US'."\n". @@ -1804,7 +1804,7 @@ public function testRFC6350Section6Part1Part3() public function testRFC6350Section6Part1Part4() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1814,7 +1814,7 @@ public function testRFC6350Section6Part1Part4() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'KIND:individual'."\n". @@ -1828,7 +1828,7 @@ public function testRFC6350Section6Part1Part4() public function testRFC6350Section6Part2Part1() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1838,7 +1838,7 @@ public function testRFC6350Section6Part2Part1() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'FN:Mr. John Q. Public\, Esq.'."\n". @@ -1852,7 +1852,7 @@ public function testRFC6350Section6Part2Part1() public function testRFC6350Section6Part2Part2() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1866,7 +1866,7 @@ public function testRFC6350Section6Part2Part2() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'N:Stevenson;John;Philip\,Paul;Dr.;Jr.\,M.D.\,A.C.P.'."\n". @@ -1880,7 +1880,7 @@ public function testRFC6350Section6Part2Part2() public function testRFC6350Section6Part2Part3() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1891,7 +1891,7 @@ public function testRFC6350Section6Part2Part3() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'NICKNAME:Jim,Jimmie'."\n". @@ -1905,7 +1905,7 @@ public function testRFC6350Section6Part2Part3() public function testRFC6350Section6Part2Part4() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1915,7 +1915,7 @@ public function testRFC6350Section6Part2Part4() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'PHOTO:http://www.example.com/pub/photos/jqpublic.gif'."\n". @@ -1926,7 +1926,7 @@ public function testRFC6350Section6Part2Part4() public function testRFC6350Section6Part2Part5() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1936,7 +1936,7 @@ public function testRFC6350Section6Part2Part5() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:19531015T231000Z'."\n". @@ -1947,7 +1947,7 @@ public function testRFC6350Section6Part2Part5() public function testRFC6350Section6Part2Part6() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1957,7 +1957,7 @@ public function testRFC6350Section6Part2Part6() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'ANNIVERSARY:19960415'."\n". @@ -1971,7 +1971,7 @@ public function testRFC6350Section6Part2Part6() public function testRFC6350Section6Part2Part7() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -1982,7 +1982,7 @@ public function testRFC6350Section6Part2Part7() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'GENDER:Jim;Jimmie'."\n". @@ -1996,7 +1996,7 @@ public function testRFC6350Section6Part2Part7() public function testRFC6350Section6Part3Part1() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2012,7 +2012,7 @@ public function testRFC6350Section6Part3Part1() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'ADR:;;123 Main Street;Any Town;CA;91921-1234;U.S.A.'."\n". @@ -2036,7 +2036,7 @@ public function testRFC6350Section6Part4Part1() * Then, we test xCard/TEXT to vCard/TEXT to xCard/TEXT. */ $this->assertXMLEqualsToMimeDir( -<< @@ -2051,7 +2051,7 @@ public function testRFC6350Section6Part4Part1() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'TEL;TYPE=home:tel:+33-01-23-45-67'."\n". @@ -2059,7 +2059,7 @@ public function testRFC6350Section6Part4Part1() ); $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2074,7 +2074,7 @@ public function testRFC6350Section6Part4Part1() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'TEL;TYPE=home:tel:+33-01-23-45-67'."\n". @@ -2088,7 +2088,7 @@ public function testRFC6350Section6Part4Part1() public function testRFC6350Section6Part4Part2() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2103,7 +2103,7 @@ public function testRFC6350Section6Part4Part2() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'EMAIL;TYPE=work:jqpublic@xyz.example.com'."\n". @@ -2117,7 +2117,7 @@ public function testRFC6350Section6Part4Part2() public function testRFC6350Section6Part4Part3() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2132,7 +2132,7 @@ public function testRFC6350Section6Part4Part3() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'IMPP;PREF=1:xmpp:alice@example.com'."\n". @@ -2146,7 +2146,7 @@ public function testRFC6350Section6Part4Part3() public function testRFC6350Section6Part4Part4() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2164,7 +2164,7 @@ public function testRFC6350Section6Part4Part4() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'LANG;TYPE=work;PREF=2:en'."\n". @@ -2178,7 +2178,7 @@ public function testRFC6350Section6Part4Part4() public function testRFC6350Section6Part5Part1() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2188,7 +2188,7 @@ public function testRFC6350Section6Part5Part1() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'TZ:Raleigh/North America'."\n". @@ -2202,7 +2202,7 @@ public function testRFC6350Section6Part5Part1() public function testRFC6350Section6Part5Part2() { $this->assertXMLEqualsToMimeDir( -<< @@ -2212,7 +2212,7 @@ public function testRFC6350Section6Part5Part2() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'GEO:geo:37.386013\,-122.082932'."\n". @@ -2220,7 +2220,7 @@ public function testRFC6350Section6Part5Part2() ); $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2230,7 +2230,7 @@ public function testRFC6350Section6Part5Part2() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'GEO:geo:37.386013\,-122.082932'."\n". @@ -2244,7 +2244,7 @@ public function testRFC6350Section6Part5Part2() public function testRFC6350Section6Part6Part1() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2254,7 +2254,7 @@ public function testRFC6350Section6Part6Part1() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'TITLE:Research Scientist'."\n". @@ -2268,7 +2268,7 @@ public function testRFC6350Section6Part6Part1() public function testRFC6350Section6Part6Part2() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2278,7 +2278,7 @@ public function testRFC6350Section6Part6Part2() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'ROLE:Project Leader'."\n". @@ -2292,7 +2292,7 @@ public function testRFC6350Section6Part6Part2() public function testRFC6350Section6Part6Part3() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2302,7 +2302,7 @@ public function testRFC6350Section6Part6Part3() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'LOGO:http://www.example.com/pub/logos/abccorp.jpg'."\n". @@ -2316,7 +2316,7 @@ public function testRFC6350Section6Part6Part3() public function testRFC6350Section6Part6Part4() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2328,7 +2328,7 @@ public function testRFC6350Section6Part6Part4() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'ORG:ABC\, Inc.;North American Division;Marketing'."\n". @@ -2342,7 +2342,7 @@ public function testRFC6350Section6Part6Part4() public function testRFC6350Section6Part6Part5() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2352,7 +2352,7 @@ public function testRFC6350Section6Part6Part5() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'MEMBER:urn:uuid:03a0e51f-d1aa-4385-8a53-e29025acd8af'."\n". @@ -2360,7 +2360,7 @@ public function testRFC6350Section6Part6Part5() ); $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2379,7 +2379,7 @@ public function testRFC6350Section6Part6Part5() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'MEMBER:mailto:subscriber1@example.com'."\n". @@ -2396,7 +2396,7 @@ public function testRFC6350Section6Part6Part5() public function testRFC6350Section6Part6Part6() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2411,7 +2411,7 @@ public function testRFC6350Section6Part6Part6() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'RELATED;TYPE=friend:urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6'."\n". @@ -2425,7 +2425,7 @@ public function testRFC6350Section6Part6Part6() public function testRFC6350Section6Part7Part1() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2438,7 +2438,7 @@ public function testRFC6350Section6Part7Part1() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'CATEGORIES:INTERNET,IETF,INDUSTRY,INFORMATION TECHNOLOGY'."\n". @@ -2452,7 +2452,7 @@ public function testRFC6350Section6Part7Part1() public function testRFC6350Section6Part7Part2() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2462,7 +2462,7 @@ public function testRFC6350Section6Part7Part2() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'NOTE:Foo\, bar'."\n". @@ -2476,7 +2476,7 @@ public function testRFC6350Section6Part7Part2() public function testRFC6350Section6Part7Part3() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2486,7 +2486,7 @@ public function testRFC6350Section6Part7Part3() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'PRODID:-//ONLINE DIRECTORY//NONSGML Version 1//EN'."\n". @@ -2497,7 +2497,7 @@ public function testRFC6350Section6Part7Part3() public function testRFC6350Section6Part7Part4() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2507,7 +2507,7 @@ public function testRFC6350Section6Part7Part4() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'REV:19951031T222710Z'."\n". @@ -2521,7 +2521,7 @@ public function testRFC6350Section6Part7Part4() public function testRFC6350Section6Part7Part5() { $this->assertXMLEqualsToMimeDir( -<< @@ -2531,7 +2531,7 @@ public function testRFC6350Section6Part7Part5() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'SOUND:CID:JOHNQPUBLIC.part8.19960229T080000.xyzMail@example.com'."\n". @@ -2539,7 +2539,7 @@ public function testRFC6350Section6Part7Part5() ); $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2549,7 +2549,7 @@ public function testRFC6350Section6Part7Part5() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'SOUND:CID:JOHNQPUBLIC.part8.19960229T080000.xyzMail@example.com'."\n". @@ -2563,7 +2563,7 @@ public function testRFC6350Section6Part7Part5() public function testRFC6350Section6Part7Part6() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2573,7 +2573,7 @@ public function testRFC6350Section6Part7Part6() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'UID:urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6'."\n". @@ -2587,7 +2587,7 @@ public function testRFC6350Section6Part7Part6() public function testRFC6350Section6Part7Part7() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2598,7 +2598,7 @@ public function testRFC6350Section6Part7Part7() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'CLIENTPIDMAP:1;urn:uuid:3df403f4-5924-4bb7-b077-3c711d9eb34b'."\n". @@ -2612,7 +2612,7 @@ public function testRFC6350Section6Part7Part7() public function testRFC6350Section6Part7Part8() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2622,7 +2622,7 @@ public function testRFC6350Section6Part7Part8() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'URL:http://example.org/restaurant.french/~chezchic.html'."\n". @@ -2636,13 +2636,13 @@ public function testRFC6350Section6Part7Part8() public function testRFC6350Section6Part7Part9() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'END:VCARD'."\n" @@ -2655,7 +2655,7 @@ public function testRFC6350Section6Part7Part9() public function testRFC6350Section6Part8Part1() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2670,7 +2670,7 @@ public function testRFC6350Section6Part8Part1() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'KEY;MEDIATYPE=application/pgp-keys:ftp://example.com/keys/jdoe'."\n". @@ -2684,7 +2684,7 @@ public function testRFC6350Section6Part8Part1() public function testRFC6350Section6Part9Part1() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2699,7 +2699,7 @@ public function testRFC6350Section6Part9Part1() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'FBURL;PREF=1:http://www.example.com/busy/janedoe'."\n". @@ -2713,7 +2713,7 @@ public function testRFC6350Section6Part9Part1() public function testRFC6350Section6Part9Part2() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2723,7 +2723,7 @@ public function testRFC6350Section6Part9Part2() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'CALADRURI:http://example.com/calendar/jdoe'."\n". @@ -2737,7 +2737,7 @@ public function testRFC6350Section6Part9Part2() public function testRFC6350Section6Part9Part3() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2752,7 +2752,7 @@ public function testRFC6350Section6Part9Part3() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'CALURI;PREF=1:http://cal.example.com/calA'."\n". @@ -2766,7 +2766,7 @@ public function testRFC6350Section6Part9Part3() public function testRFC6350SectionAPart3() { $this->assertXMLReflexivelyEqualsToMimeDir( -<< @@ -2776,7 +2776,7 @@ public function testRFC6350SectionAPart3() XML -, + , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'CAPURI:http://cap.example.com/capA'."\n". diff --git a/tests/VObject/PropertyTest.php b/tests/VObject/PropertyTest.php index d0356727c..3fa4692a6 100644 --- a/tests/VObject/PropertyTest.php +++ b/tests/VObject/PropertyTest.php @@ -373,7 +373,7 @@ public function testValidateBadEncodingVCard3() $this->assertEquals('ENCODING=BASE64 is not valid for this document type.', $result[0]['message']); $this->assertEquals(3, $result[0]['level']); - //Validate the reparation of BASE64 formatted vCard v3 + // Validate the reparation of BASE64 formatted vCard v3 $result = $property->validate(Property::REPAIR); $this->assertEquals('ENCODING=BASE64 has been transformed to ENCODING=B.', $result[0]['message']); From c00f27ae3e2125d9ce10eab6bc8eeff0120170e8 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Fri, 19 Aug 2022 17:06:35 +0545 Subject: [PATCH 129/165] Remove unneeded VEvent variable declaration --- lib/BirthdayCalendarGenerator.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/BirthdayCalendarGenerator.php b/lib/BirthdayCalendarGenerator.php index 1d17353b5..760461815 100644 --- a/lib/BirthdayCalendarGenerator.php +++ b/lib/BirthdayCalendarGenerator.php @@ -5,7 +5,6 @@ use DateTime; use InvalidArgumentException; use Sabre\VObject\Component\VCalendar; -use Sabre\VObject\Component\VEvent; /** * This class generates birthday calendars. @@ -141,7 +140,6 @@ public function getResult(): VCalendar } // Create event. - /** @var VEvent $event */ $event = $calendar->add('VEVENT', [ 'SUMMARY' => sprintf($this->format, $object->FN->getValue()), 'DTSTART' => new DateTime($object->BDAY->getValue()), From 3c0b05dc7616eb54872051a8a60d5532d7038a1d Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Fri, 19 Aug 2022 17:11:25 +0545 Subject: [PATCH 130/165] Remove unneeded VCard variable declaration --- lib/Cli.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/Cli.php b/lib/Cli.php index 6499cb0a8..19165abd6 100644 --- a/lib/Cli.php +++ b/lib/Cli.php @@ -4,7 +4,6 @@ use Exception; use InvalidArgumentException; -use Sabre\VObject\Component\VCard; use Sabre\VObject\Parser\Json; use Sabre\VObject\Parser\MimeDir; use Sabre\VObject\Parser\Parser; @@ -421,7 +420,6 @@ protected function convert(Component $vObj): int throw new Exception('You cannot convert a '.strtolower($vObj->name).' to '.$this->format); } if ($convertVersion) { - /** @var VCard $vObj */ $vObj = $vObj->convert($convertVersion); } if ($json) { From 45f674040f5edd78bbf4baa3dd5d3dccf89cfb2b Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Fri, 19 Aug 2022 16:46:44 +0545 Subject: [PATCH 131/165] More type declaration stuff (1) --- lib/BirthdayCalendarGenerator.php | 10 +-- lib/Cli.php | 50 ++++----------- lib/Component.php | 12 ++-- lib/Component/VCalendar.php | 8 +-- lib/Component/VEvent.php | 4 +- lib/DateTimeParser.php | 6 +- lib/Document.php | 8 +-- lib/ElementList.php | 4 +- lib/FreeBusyData.php | 22 ++----- lib/FreeBusyGenerator.php | 46 +++++--------- lib/ITip/Broker.php | 12 ++-- lib/Node.php | 8 +-- lib/PHPUnitAssertions.php | 2 +- lib/Parameter.php | 4 +- lib/Property.php | 12 +--- lib/Settings.php | 6 +- lib/TimeZoneUtil.php | 11 ++-- lib/VCardConverter.php | 10 ++- tests/VObject/CliTest.php | 88 ++++++++++++++------------ tests/VObject/Component/VEventTest.php | 4 +- tests/VObject/PropertyTest.php | 2 +- 21 files changed, 134 insertions(+), 195 deletions(-) diff --git a/lib/BirthdayCalendarGenerator.php b/lib/BirthdayCalendarGenerator.php index 760461815..330b8aa83 100644 --- a/lib/BirthdayCalendarGenerator.php +++ b/lib/BirthdayCalendarGenerator.php @@ -17,10 +17,8 @@ class BirthdayCalendarGenerator { /** * Input objects. - * - * @var array */ - protected $objects = []; + protected array $objects = []; /** * Default year. @@ -30,10 +28,8 @@ class BirthdayCalendarGenerator /** * Output format for the SUMMARY. - * - * @var string */ - protected $format = '%1$s\'s Birthday'; + protected string $format = '%1$s\'s Birthday'; /** * Creates the generator. @@ -109,7 +105,7 @@ public function getResult(): VCalendar continue; } - // We're always converting to vCard 4.0 so we can rely on the + // We're always converting to vCard 4.0, so we can rely on the // VCardConverter handling the X-APPLE-OMIT-YEAR property for us. $object = $object->convert(Document::VCARD40); diff --git a/lib/Cli.php b/lib/Cli.php index 19165abd6..f0904de6f 100644 --- a/lib/Cli.php +++ b/lib/Cli.php @@ -19,38 +19,28 @@ class Cli { /** * No output. - * - * @var bool */ - protected $quiet = false; + protected bool $quiet = false; /** * Whether to spit out 'mimedir' or 'json' format. - * - * @var string */ - protected $format; + protected ?string $format = null; /** * JSON pretty print. - * - * @var bool */ - protected $pretty; + protected bool $pretty = false; /** * Source file. - * - * @var string */ - protected $inputPath; + protected string $inputPath; /** * Destination file. - * - * @var string */ - protected $outputPath; + protected string $outputPath; /** * output stream. @@ -75,17 +65,13 @@ class Cli /** * Input format (one of json or mimedir). - * - * @var string */ - protected $inputFormat; + protected ?string $inputFormat = null; /** * Makes the parser less strict. - * - * @var bool */ - protected $forgiving = false; + protected bool $forgiving = false; /** * Main function. @@ -138,7 +124,7 @@ public function main(array $argv): int // specific formats case 'json': case 'mimedir': - // icalendar/vcad + // icalendar/vcard case 'icalendar': case 'vcard': $this->format = $value; @@ -149,9 +135,7 @@ public function main(array $argv): int } break; case 'pretty': - if (version_compare(PHP_VERSION, '5.4.0') >= 0) { - $this->pretty = true; - } + $this->pretty = true; break; case 'forgiving': $this->forgiving = true; @@ -218,14 +202,14 @@ public function main(array $argv): int $this->stdout = fopen($this->outputPath, 'w'); } - if (!$this->inputFormat) { + if (null === $this->inputFormat) { if ('.json' === substr($this->inputPath, -5)) { $this->inputFormat = 'json'; } else { $this->inputFormat = 'mimedir'; } } - if (!$this->format) { + if (null === $this->format) { if ('.json' === substr($this->outputPath, -5)) { $this->format = 'json'; } else { @@ -269,10 +253,7 @@ protected function showHelp(): void $this->log(' vcard30, vcard40, icalendar20, jcal, jcard, json, mimedir.'); $this->log($this->colorize('green', ' --inputformat ').'If the input format cannot be guessed from the extension, it'); $this->log(' must be specified here.'); - // Only PHP 5.4 and up - if (version_compare(PHP_VERSION, '5.4.0') >= 0) { - $this->log($this->colorize('green', ' --pretty ').'json pretty-print.'); - } + $this->log($this->colorize('green', ' --pretty ').'json pretty-print.'); $this->log(''); $this->log('Commands:', 'yellow'); $this->log($this->colorize('green', ' validate').' source_file Validates a file for correctness.'); @@ -486,13 +467,8 @@ protected function serializeComponent(Component $vObj): void * To avoid score collisions, each "score category" has a reasonable * space to accommodate elements. The $key is added to the $score to * preserve the original relative order of elements. - * - * @param int $key - * @param array $array - * - * @return int */ - $sortScore = function (int $key, array $array): ?int { + $sortScore = function (int $key, array $array): int { if ($array[$key] instanceof Component) { // We want to encode VTIMEZONE first, this is a personal // preference. diff --git a/lib/Component.php b/lib/Component.php index 3e9cc551c..dd8d0a0b0 100644 --- a/lib/Component.php +++ b/lib/Component.php @@ -26,17 +26,15 @@ class Component extends Node * Component name. * * This will contain a string such as VEVENT, VTODO, VCALENDAR, VCARD. - * - * @var string */ - public $name; + public string $name; /** * A list of properties and/or sub-components. * * @var array */ - protected $children = []; + protected array $children = []; /** * Creates a new component. @@ -139,13 +137,11 @@ public function add(): Node * exact item will be removed. * * @param string|Property|Component $item - * - * @return void */ - public function remove($item) + public function remove($item): void { if (is_string($item)) { - // If there's no dot in the name, it's an exact property name and + // If there's no dot in the name, it's an exact property name, // we can just wipe out all those properties. // if (false === strpos($item, '.')) { diff --git a/lib/Component/VCalendar.php b/lib/Component/VCalendar.php index da7a211f9..6d5900414 100644 --- a/lib/Component/VCalendar.php +++ b/lib/Component/VCalendar.php @@ -168,7 +168,7 @@ public function getDocumentType(): int * * @return VObject\Component[] */ - public function getBaseComponents(string $componentName = null): array + public function getBaseComponents(?string $componentName = null): array { $isBaseComponent = function ($component): bool { if (!$component instanceof VObject\Component) { @@ -219,7 +219,7 @@ public function getBaseComponents(string $componentName = null): array * * @return VObject\Component|null */ - public function getBaseComponent(string $componentName = null): ?Component + public function getBaseComponent(?string $componentName = null): ?Component { $isBaseComponent = function ($component): bool { if (!$component instanceof VObject\Component) { @@ -265,7 +265,7 @@ public function getBaseComponent(string $componentName = null): ?Component * can be used to expand the event into multiple sub-events. * * Each event will be stripped from its recurrence information, and only - * the instances of the event in the specified timerange will be left + * the instances of the event in the specified time range will be left * alone. * * In addition, this method will cause timezone information to be stripped, @@ -277,7 +277,7 @@ public function getBaseComponent(string $componentName = null): ?Component * @throws InvalidDataException * @throws VObject\Recur\MaxInstancesExceededException */ - public function expand(DateTimeInterface $start, DateTimeInterface $end, DateTimeZone $timeZone = null): VCalendar + public function expand(DateTimeInterface $start, DateTimeInterface $end, ?DateTimeZone $timeZone = null): VCalendar { $newChildren = []; $recurringEvents = []; diff --git a/lib/Component/VEvent.php b/lib/Component/VEvent.php index e6dfc7a3b..4682756a4 100644 --- a/lib/Component/VEvent.php +++ b/lib/Component/VEvent.php @@ -57,14 +57,14 @@ public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end): // recurrence instance exceeded the start of the requested // time-range. // - // If the starttime of the recurrence did not exceed the + // If the start time of the recurrence did not exceed the // end of the time range as well, we have a match. return $it->getDTStart() < $end && $it->getDTEnd() > $start; } $effectiveStart = $this->DTSTART->getDateTime($start->getTimezone()); if (isset($this->DTEND)) { - // The DTEND property is considered non inclusive. So for a 3 day + // The DTEND property is considered non-inclusive. So for a 3-day // event in july, dtstart and dtend would have to be July 1st and // July 4th respectively. // diff --git a/lib/DateTimeParser.php b/lib/DateTimeParser.php index bcd9a828a..34c53c6c4 100644 --- a/lib/DateTimeParser.php +++ b/lib/DateTimeParser.php @@ -10,7 +10,7 @@ /** * DateTimeParser. * - * This class is responsible for parsing the several different date and time + * This class is responsible for parsing the several date and time * formats iCalendar and vCards have. * * @copyright Copyright (C) fruux GmbH (https://fruux.com/) @@ -29,7 +29,7 @@ class DateTimeParser * * @throws InvalidDataException */ - public static function parseDateTime(string $dt, DateTimeZone $tz = null): DateTimeImmutable + public static function parseDateTime(string $dt, ?DateTimeZone $tz = null): DateTimeImmutable { // Format is YYYYMMDD + "T" + hhmmss $result = preg_match('/^([0-9]{4})([0-1][0-9])([0-3][0-9])T([0-2][0-9])([0-5][0-9])([0-5][0-9])([Z]?)$/', $dt, $matches); @@ -56,7 +56,7 @@ public static function parseDateTime(string $dt, DateTimeZone $tz = null): DateT * * @throws InvalidDataException */ - public static function parseDate(string $date, DateTimeZone $tz = null): DateTimeImmutable + public static function parseDate(string $date, ?DateTimeZone $tz = null): DateTimeImmutable { // Format is YYYYMMDD $result = preg_match('/^([0-9]{4})([0-1][0-9])([0-3][0-9])$/', $date, $matches); diff --git a/lib/Document.php b/lib/Document.php index e59938075..6b212c956 100644 --- a/lib/Document.php +++ b/lib/Document.php @@ -117,8 +117,6 @@ public function getDocumentType(): int * If it's a known component, we will automatically call createComponent. * otherwise, we'll assume it's a property and call createProperty instead. * - * @param string $arg1,... Unlimited number of args - * * @return mixed */ public function create(string $name) @@ -144,7 +142,7 @@ public function create(string $name) * an iCalendar object, this may be something like CALSCALE:GREGORIAN. To * ensure that this does not happen, set $defaults to false. */ - public function createComponent(string $name, array $children = null, bool $defaults = true): Component + public function createComponent(string $name, ?array $children = null, bool $defaults = true): Component { $name = strtoupper($name); $class = Component::class; @@ -174,9 +172,9 @@ public function createComponent(string $name, array $children = null, bool $defa * * @throws InvalidDataException */ - public function createProperty(string $name, $value = null, array $parameters = null, string $valueType = null): Property + public function createProperty(string $name, $value = null, ?array $parameters = null, ?string $valueType = null): Property { - // If there's a . in the name, it means it's prefixed by a groupname. + // If there's a . in the name, it means it's prefixed by a group name. if (false !== ($i = strpos($name, '.'))) { $group = substr($name, 0, $i); $name = strtoupper(substr($name, $i + 1)); diff --git a/lib/ElementList.php b/lib/ElementList.php index 860512649..7197b31cc 100644 --- a/lib/ElementList.php +++ b/lib/ElementList.php @@ -26,7 +26,7 @@ class ElementList extends ArrayIterator * @param mixed $value */ #[\ReturnTypeWillChange] - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { throw new LogicException('You can not add new objects to an ElementList'); } @@ -39,7 +39,7 @@ public function offsetSet($offset, $value) * @param int $offset */ #[\ReturnTypeWillChange] - public function offsetUnset($offset) + public function offsetUnset($offset): void { throw new LogicException('You can not remove objects from an ElementList'); } diff --git a/lib/FreeBusyData.php b/lib/FreeBusyData.php index 9ea7958a3..405a5886d 100644 --- a/lib/FreeBusyData.php +++ b/lib/FreeBusyData.php @@ -13,26 +13,20 @@ class FreeBusyData { /** * Start timestamp. - * - * @var int */ - protected $start; + protected int $start; /** * End timestamp. - * - * @var int */ - protected $end; + protected int $end; /** * A list of free-busy times. - * - * @var array */ - protected $data; + protected array $data; - public function __construct($start, $end) + public function __construct(int $start, int $end) { $this->start = $start; $this->end = $end; @@ -46,16 +40,14 @@ public function __construct($start, $end) } /** - * Adds free or busytime to the data. + * Adds free or busy time to the data. * * @param string $type FREE, BUSY, BUSY-UNAVAILABLE or BUSY-TENTATIVE - * - * @return void */ - public function add(int $start, int $end, string $type) + public function add(int $start, int $end, string $type): void { if ($start > $this->end || $end < $this->start) { - // This new data is outside our timerange. + // This new data is outside our time range. return; } diff --git a/lib/FreeBusyGenerator.php b/lib/FreeBusyGenerator.php index 14983e30a..fb0ef19b3 100644 --- a/lib/FreeBusyGenerator.php +++ b/lib/FreeBusyGenerator.php @@ -31,31 +31,23 @@ class FreeBusyGenerator { /** * Input objects. - * - * @var array */ - protected $objects = []; + protected array $objects = []; /** * Start of range. - * - * @var DateTimeInterface|null */ - protected $start; + protected ?DateTimeInterface $start; /** * End of range. - * - * @var DateTimeInterface|null */ - protected $end; + protected ?DateTimeInterface $end; /** * VCALENDAR object. - * - * @var Document */ - protected $baseObject; + protected ?Document $baseObject = null; /** * Reference timezone. @@ -67,20 +59,16 @@ class FreeBusyGenerator * This is also used for all-day events. * * This defaults to UTC. - * - * @var DateTimeZone */ - protected $timeZone; + protected DateTimeZone $timeZone; /** * A VAVAILABILITY document. * * If this is set, its information will be included when calculating * freebusy time. - * - * @var Document */ - protected $vavailability; + protected ?Document $vavailability = null; /** * Creates the generator. @@ -90,7 +78,7 @@ class FreeBusyGenerator * * @param mixed $objects */ - public function __construct(DateTimeInterface $start = null, DateTimeInterface $end = null, $objects = null, DateTimeZone $timeZone = null) + public function __construct(?DateTimeInterface $start = null, ?DateTimeInterface $end = null, $objects = null, ?DateTimeZone $timeZone = null) { $this->setTimeRange($start, $end); @@ -154,11 +142,11 @@ public function setObjects($objects): void /** * Sets the time range. * - * Any freebusy object falling outside of this time range will be ignored. + * Any freebusy object falling outside this time range will be ignored. * * @throws Exception */ - public function setTimeRange(DateTimeInterface $start = null, DateTimeInterface $end = null): void + public function setTimeRange(?DateTimeInterface $start = null, ?DateTimeInterface $end = null): void { if (!$start) { $start = new DateTimeImmutable(Settings::$minDate); @@ -181,16 +169,14 @@ public function setTimeZone(DateTimeZone $timeZone): void /** * Parses the input data and returns a correct VFREEBUSY object, wrapped in * a VCALENDAR. - * - * @return Component */ - public function getResult() + public function getResult(): Component { $fbData = new FreeBusyData( $this->start->getTimeStamp(), $this->end->getTimeStamp() ); - if ($this->vavailability) { + if (null !== $this->vavailability) { $this->calculateAvailability($fbData, $this->vavailability); } @@ -231,7 +217,7 @@ function ($a, $b) { // Now we go over all the VAVAILABILITY components and figure if // there's any we don't need to consider. // - // This is can be because of one of two reasons: either the + // This is because of one of two reasons: either the // VAVAILABILITY component falls outside the time we are interested in, // or a different VAVAILABILITY component with a higher priority has // already completely covered the time-range. @@ -241,7 +227,7 @@ function ($a, $b) { foreach ($old as $vavail) { list($compStart, $compEnd) = $vavail->getEffectiveStartEnd(); - // We don't care about datetimes that are earlier or later than the + // We don't care about date-times that are earlier or later than the // start and end of the freebusy report, so this gets normalized // first. if (is_null($compStart) || $compStart < $this->start) { @@ -251,7 +237,7 @@ function ($a, $b) { $compEnd = $this->end; } - // If the item fell out of the timerange, we can just skip it. + // If the item fell out of the time range, we can just skip it. if ($compStart > $this->end || $compEnd < $this->start) { continue; } @@ -326,7 +312,7 @@ function ($a, $b) { $recurEnd = $recurStart->add($startEndDiff); if ($recurStart > $vavailEnd) { - // We're beyond the legal timerange. + // We're beyond the legal time range. break; } @@ -500,7 +486,7 @@ protected function calculateBusy(FreeBusyData $fbData, array $objects): void */ protected function generateFreeBusyCalendar(FreeBusyData $fbData): VCalendar { - if ($this->baseObject) { + if (null !== $this->baseObject) { $calendar = $this->baseObject; } else { $calendar = new VCalendar(); diff --git a/lib/ITip/Broker.php b/lib/ITip/Broker.php index c740453b0..279452735 100644 --- a/lib/ITip/Broker.php +++ b/lib/ITip/Broker.php @@ -18,7 +18,7 @@ * * iTip is defined in rfc5546, stands for iCalendar Transport-Independent * Interoperability Protocol, and describes the underlying mechanism for - * using iCalendar for scheduling for for example through email (also known as + * using iCalendar for scheduling, for example, through email (also known as * IMip) and CalDAV Scheduling. * * This class helps by: @@ -32,7 +32,7 @@ * a received invite. * 4. It can also process an invite update on a local event, ensuring that any * overridden properties from attendees are retained. - * 5. It can create a accepted or declined iTip reply based on an invite. + * 5. It can create an accepted or declined iTip reply based on an invite. * 6. It can process a reply from an invite and update an events attendee * status based on a reply. * @@ -222,7 +222,7 @@ public function parseEvent($calendar, $userHref, $oldCalendar = null): array // The calendar object got deleted, we need to process this as a // cancellation / decline. if (!$oldCalendar) { - // No old and no new calendar, there's no thing to do. + // No old and no new calendar, there's nothing to do. return []; } @@ -268,7 +268,7 @@ public function parseEvent($calendar, $userHref, $oldCalendar = null): array * This is message from an organizer, and is either a new event * invite, or an update to an existing one. */ - protected function processMessageRequest(Message $itipMessage, VCalendar $existingObject = null): ?VCalendar + protected function processMessageRequest(Message $itipMessage, ?VCalendar $existingObject = null): ?VCalendar { if (!$existingObject) { // This is a new invite, and we're just going to copy over @@ -296,7 +296,7 @@ protected function processMessageRequest(Message $itipMessage, VCalendar $existi * attendee got removed from an event, or an event got cancelled * altogether. */ - protected function processMessageCancel(Message $itipMessage, VCalendar $existingObject = null): ?VCalendar + protected function processMessageCancel(Message $itipMessage, ?VCalendar $existingObject = null): ?VCalendar { if (!$existingObject) { // The event didn't exist in the first place, so we're just @@ -323,7 +323,7 @@ protected function processMessageCancel(Message $itipMessage, VCalendar $existin * @throws MaxInstancesExceededException * @throws NoInstancesException */ - protected function processMessageReply(Message $itipMessage, VCalendar $existingObject = null) + protected function processMessageReply(Message $itipMessage, ?VCalendar $existingObject = null) { // A reply can only be processed based on an existing object. // If the object is not available, the reply is ignored. diff --git a/lib/Node.php b/lib/Node.php index 228f23ba6..5ecc2c00e 100644 --- a/lib/Node.php +++ b/lib/Node.php @@ -81,10 +81,8 @@ abstract public function xmlSerialize(Xml\Writer $writer): void; * * It's intended to remove all circular references, so PHP can easily clean * it up. - * - * @return void */ - public function destroy() + public function destroy(): void { $this->parent = null; $this->root = null; @@ -200,7 +198,7 @@ public function offsetGet($offset) * @param mixed $value */ #[\ReturnTypeWillChange] - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { $iterator = $this->getIterator(); $iterator->offsetSet($offset, $value); @@ -221,7 +219,7 @@ public function offsetSet($offset, $value) * @param int $offset */ #[\ReturnTypeWillChange] - public function offsetUnset($offset) + public function offsetUnset($offset): void { $iterator = $this->getIterator(); $iterator->offsetUnset($offset); diff --git a/lib/PHPUnitAssertions.php b/lib/PHPUnitAssertions.php index fcaaafd5a..1976c3afd 100644 --- a/lib/PHPUnitAssertions.php +++ b/lib/PHPUnitAssertions.php @@ -31,7 +31,7 @@ trait PHPUnitAssertions * @param resource|string|Component $expected * @param resource|string|Component $actual */ - public function assertVObjectEqualsVObject($expected, $actual, string $message = '') + public function assertVObjectEqualsVObject($expected, $actual, string $message = ''): void { $getObj = function ($input) { if (is_resource($input)) { diff --git a/lib/Parameter.php b/lib/Parameter.php index 039fa1965..1900cb634 100644 --- a/lib/Parameter.php +++ b/lib/Parameter.php @@ -226,8 +226,8 @@ public function addValue($part): void /** * Checks if this parameter contains the specified value. * - * This is a case-insensitive match. It makes sense to call this for for - * instance the TYPE parameter, to see if it contains a keyword such as + * This is a case-insensitive match. It makes sense to call this for + * the TYPE parameter, for instance, to see if it contains a keyword such as * 'WORK' or 'FAX'. */ public function has(string $value): bool diff --git a/lib/Property.php b/lib/Property.php index 4f580e17e..dbd1782e5 100644 --- a/lib/Property.php +++ b/lib/Property.php @@ -2,8 +2,6 @@ namespace Sabre\VObject; -use Exception; - use function preg_replace; use Sabre\Xml; @@ -68,10 +66,8 @@ abstract class Property extends Node * @param string|array|null $value * @param array $parameters List of parameters * @param string|null $group The vcard property group - * - * @throws InvalidDataException */ - public function __construct(Component $root, ?string $name, $value = null, array $parameters = [], string $group = null) + public function __construct(Component $root, ?string $name, $value = null, array $parameters = [], ?string $group = null) { $this->name = $name; $this->group = $group; @@ -247,8 +243,6 @@ public function getJsonValue(): array * Sets the JSON value, as it would appear in a jCard or jCal object. * * The value must always be an array. - * - * @throws InvalidDataException */ public function setJsonValue(array $value): void { @@ -510,11 +504,11 @@ public function validate(int $options = 0): array ]; } - // Checking if the propertyname does not contain any invalid bytes. + // Checking if the property name does not contain any invalid bytes. if (!preg_match('/^([A-Z0-9-]+)$/', $this->name)) { $warnings[] = [ 'level' => $options & self::REPAIR ? 1 : 3, - 'message' => 'The propertyname: '.$this->name.' contains invalid characters. Only A-Z, 0-9 and - are allowed', + 'message' => 'The property name: '.$this->name.' contains invalid characters. Only A-Z, 0-9 and - are allowed', 'node' => $this, ]; if ($options & self::REPAIR) { diff --git a/lib/Settings.php b/lib/Settings.php index b0bb80a82..5e50f914f 100644 --- a/lib/Settings.php +++ b/lib/Settings.php @@ -25,7 +25,7 @@ class Settings * use-cases. In particular, it covers birthdates for virtually everyone * alive on earth, which is less than 5 people at the time of writing. */ - public static $minDate = '1900-01-01'; + public static string $minDate = '1900-01-01'; /** * The maximum date we accept for various calculations with dates, such as @@ -34,7 +34,7 @@ class Settings * The choice of 2100 is pretty arbitrary, but should cover most * appointments made for many years to come. */ - public static $maxDate = '2100-01-01'; + public static string $maxDate = '2100-01-01'; /** * The maximum number of recurrences that will be generated. @@ -51,5 +51,5 @@ class Settings * * Set this value to -1 to disable this control altogether. */ - public static $maxRecurrences = 3500; + public static int $maxRecurrences = 3500; } diff --git a/lib/TimeZoneUtil.php b/lib/TimeZoneUtil.php index dac2a87d2..c77aa19f1 100644 --- a/lib/TimeZoneUtil.php +++ b/lib/TimeZoneUtil.php @@ -24,14 +24,13 @@ */ class TimeZoneUtil { - /** @var self */ - private static $instance = null; + private static ?TimeZoneUtil $instance = null; /** @var TimezoneGuesser[] */ - private $timezoneGuessers = []; + private array $timezoneGuessers = []; /** @var TimezoneFinder[] */ - private $timezoneFinders = []; + private array $timezoneFinders = []; private function __construct() { @@ -75,7 +74,7 @@ private function addFinder(string $key, TimezoneFinder $finder): void * Alternatively, if $failIfUncertain is set to true, it will throw an * exception if we cannot accurately determine the timezone. */ - private function findTimeZone(string $tzid, Component $vcalendar = null, bool $failIfUncertain = false): DateTimeZone + private function findTimeZone(string $tzid, ?Component $vcalendar = null, bool $failIfUncertain = false): DateTimeZone { foreach ($this->timezoneFinders as $timezoneFinder) { $timezone = $timezoneFinder->find($tzid, $failIfUncertain); @@ -120,7 +119,7 @@ public static function addTimezoneFinder(string $key, TimezoneFinder $finder): v self::getInstance()->addFinder($key, $finder); } - public static function getTimeZone(string $tzid, Component $vcalendar = null, bool $failIfUncertain = false): DateTimeZone + public static function getTimeZone(string $tzid, ?Component $vcalendar = null, bool $failIfUncertain = false): DateTimeZone { return self::getInstance()->findTimeZone($tzid, $vcalendar, $failIfUncertain); } diff --git a/lib/VCardConverter.php b/lib/VCardConverter.php index 6feedd854..c59add9cd 100644 --- a/lib/VCardConverter.php +++ b/lib/VCardConverter.php @@ -65,11 +65,9 @@ public function convert(Component\VCard $input, int $targetVersion): Component\V /** * Handles conversion of a single property. * - * @return void - * * @throws InvalidDataException */ - protected function convertProperty(Component\VCard $input, Component\VCard $output, Property $property, int $targetVersion) + protected function convertProperty(Component\VCard $input, Component\VCard $output, Property $property, int $targetVersion): void { // Skipping these, those are automatically added. if (in_array($property->name, ['VERSION', 'PRODID'])) { @@ -103,9 +101,9 @@ protected function convertProperty(Component\VCard $input, Component\VCard $outp // In vCard 4, the birth year may be optional. This is not the // case for vCard 3. Apple has a workaround for this that // allows applications that support Apple's extension still - // omit birthyears in vCard 3, but applications that do not - // support this, will just use a random birthyear. We're - // choosing 1604 for the birthyear, because that's what apple + // omit birth years in vCard 3, but applications that do not + // support this, will just use a random birth year. We're + // choosing 1604 for the birth year, because that's what apple // uses. $parts = DateTimeParser::parseVCardDateTime($property->getValue()); if (is_null($parts['year'])) { diff --git a/tests/VObject/CliTest.php b/tests/VObject/CliTest.php index bc21b9b84..083f36016 100644 --- a/tests/VObject/CliTest.php +++ b/tests/VObject/CliTest.php @@ -11,10 +11,9 @@ */ class CliTest extends TestCase { - /** @var CliMock */ - private $cli; + private CliMock $cli; - private $sabreTempDir = __DIR__.'/../temp/'; + private string $sabreTempDir = __DIR__.'/../temp/'; public function setUp(): void { @@ -27,7 +26,7 @@ public function setUp(): void $this->cli->stdout = fopen('php://memory', 'r+'); } - public function testInvalidArg() + public function testInvalidArg(): void { $this->assertEquals( 1, @@ -37,7 +36,7 @@ public function testInvalidArg() $this->assertTrue(strlen(stream_get_contents($this->cli->stderr)) > 100); } - public function testQuiet() + public function testQuiet(): void { $this->assertEquals( 1, @@ -49,7 +48,7 @@ public function testQuiet() $this->assertEquals(0, strlen(stream_get_contents($this->cli->stderr))); } - public function testHelp() + public function testHelp(): void { $this->assertEquals( 0, @@ -59,7 +58,7 @@ public function testHelp() $this->assertTrue(strlen(stream_get_contents($this->cli->stderr)) > 100); } - public function testFormat() + public function testFormat(): void { $this->assertEquals( 1, @@ -72,7 +71,7 @@ public function testFormat() $this->assertEquals('jcard', $this->cli->format); } - public function testFormatInvalid() + public function testFormatInvalid(): void { $this->assertEquals( 1, @@ -85,7 +84,7 @@ public function testFormatInvalid() $this->assertNull($this->cli->format); } - public function testInputFormatInvalid() + public function testInputFormatInvalid(): void { $this->assertEquals( 1, @@ -98,7 +97,7 @@ public function testInputFormatInvalid() $this->assertNull($this->cli->format); } - public function testNoInputFile() + public function testNoInputFile(): void { $this->assertEquals( 1, @@ -109,7 +108,7 @@ public function testNoInputFile() $this->assertTrue(strlen(stream_get_contents($this->cli->stderr)) > 100); } - public function testTooManyArgs() + public function testTooManyArgs(): void { $this->assertEquals( 1, @@ -117,7 +116,7 @@ public function testTooManyArgs() ); } - public function testUnknownCommand() + public function testUnknownCommand(): void { $this->assertEquals( 1, @@ -125,7 +124,7 @@ public function testUnknownCommand() ); } - public function testConvertJson() + public function testConvertJson(): void { $inputStream = fopen('php://memory', 'r+'); @@ -152,7 +151,7 @@ public function testConvertJson() ); } - public function testConvertJCardPretty() + public function testConvertJCardPretty(): void { if (version_compare(PHP_VERSION, '5.4.0') < 0) { $this->markTestSkipped('This test required PHP 5.4.0'); @@ -193,7 +192,7 @@ public function testConvertJCardPretty() ); } - public function testConvertJCalFail() + public function testConvertJCalFail(): void { $inputStream = fopen('php://memory', 'r+'); @@ -213,7 +212,7 @@ public function testConvertJCalFail() ); } - public function testConvertMimeDir() + public function testConvertMimeDir(): void { $inputStream = fopen('php://memory', 'r+'); @@ -273,7 +272,7 @@ public function testConvertMimeDir() ); } - public function testConvertDefaultFormats() + public function testConvertDefaultFormats(): void { $outputFile = $this->sabreTempDir.'bar.json'; @@ -286,7 +285,7 @@ public function testConvertDefaultFormats() $this->assertEquals('json', $this->cli->format); } - public function testConvertDefaultFormats2() + public function testConvertDefaultFormats2(): void { $outputFile = $this->sabreTempDir.'bar.ics'; @@ -299,7 +298,7 @@ public function testConvertDefaultFormats2() $this->assertEquals('mimedir', $this->cli->format); } - public function testVCard3040() + public function testVCard3040(): void { $inputStream = fopen('php://memory', 'r+'); @@ -338,7 +337,7 @@ public function testVCard3040() ); } - public function testVCard4030() + public function testVCard4030(): void { $inputStream = fopen('php://memory', 'r+'); @@ -377,7 +376,7 @@ public function testVCard4030() ); } - public function testVCard4021() + public function testVCard4021(): void { $inputStream = fopen('php://memory', 'r+'); @@ -399,7 +398,7 @@ public function testVCard4021() ); } - public function testValidate() + public function testValidate(): void { $inputStream = fopen('php://memory', 'r+'); @@ -423,7 +422,7 @@ public function testValidate() ); } - public function testValidateFail() + public function testValidateFail(): void { $inputStream = fopen('php://memory', 'r+'); @@ -443,7 +442,7 @@ public function testValidateFail() ); } - public function testValidateFail2() + public function testValidateFail2(): void { $inputStream = fopen('php://memory', 'r+'); @@ -463,7 +462,7 @@ public function testValidateFail2() ); } - public function testRepair() + public function testRepair(): void { $inputStream = fopen('php://memory', 'r+'); @@ -485,16 +484,10 @@ public function testRepair() rewind($this->cli->stdout); $regularExpression = "/^BEGIN:VCARD\r\nVERSION:2.1\r\nUID:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\r\nEND:VCARD\r\n$/"; $data = stream_get_contents($this->cli->stdout); - // ToDo: when we do not need to run phpunit 7 or 8, remove this 'if' block and just use - // the new assertMatchesRegularExpression that exists since phpunit 9. - if (method_exists($this, 'assertMatchesRegularExpression')) { - $this->assertMatchesRegularExpression($regularExpression, $data); - } else { - $this->assertRegExp($regularExpression, $data); - } + $this->assertMatchesRegularExpression($regularExpression, $data); } - public function testRepairNothing() + public function testRepairNothing(): void { $inputStream = fopen('php://memory', 'r+'); @@ -532,7 +525,7 @@ public function testRepairNothing() * * The colorizer is not a critical component, it's mostly a debugging tool. */ - public function testColorCalendar() + public function testColorCalendar(): void { $inputStream = fopen('php://memory', 'r+'); @@ -578,7 +571,7 @@ public function testColorCalendar() * * The colorizer is not a critical component, it's mostly a debugging tool. */ - public function testColorVCard() + public function testColorVCard(): void { $inputStream = fopen('php://memory', 'r+'); @@ -616,19 +609,32 @@ public function testColorVCard() class CliMock extends Cli { - public $quiet = false; + public bool $quiet = false; - public $format; + public ?string $format = null; - public $pretty; + public bool $pretty = false; + /** + * stdin. + * + * @var resource + */ public $stdin; + /** + * output stream. + * + * @var resource + */ public $stdout; + /** + * stderr. + * + * @var resource + */ public $stderr; - public $inputFormat; - - public $outputFormat; + public ?string $inputFormat = null; } diff --git a/tests/VObject/Component/VEventTest.php b/tests/VObject/Component/VEventTest.php index 635ae5acd..5587ea2e2 100644 --- a/tests/VObject/Component/VEventTest.php +++ b/tests/VObject/Component/VEventTest.php @@ -44,7 +44,7 @@ public function timeRangeTestData() $tests[] = [$vevent4, new \DateTime('2011-12-25 16:00:00'), new \DateTime('2011-12-25 17:00:00'), true]; // DTEND is non inclusive so all day events should not be returned on the next day. $tests[] = [$vevent4, new \DateTime('2011-12-26 00:00:00'), new \DateTime('2011-12-26 17:00:00'), false]; - // The timezone of timerange in question also needs to be considered. + // The timezone of time range in question also needs to be considered. $tests[] = [$vevent4, new \DateTime('2011-12-26 00:00:00', new \DateTimeZone('Europe/Berlin')), new \DateTime('2011-12-26 17:00:00', new \DateTimeZone('Europe/Berlin')), false]; $vevent5 = clone $vevent; @@ -70,7 +70,7 @@ public function timeRangeTestData() $vevent7->DTSTART['VALUE'] = 'DATE'; $vevent7->RRULE = 'FREQ=MONTHLY'; $tests[] = [$vevent7, new \DateTime('2012-02-01 15:00:00'), new \DateTime('2012-02-02'), true]; - // The timezone of timerange in question should also be considered. + // The timezone of time range in question should also be considered. $tests[] = [$vevent7, new \DateTime('2012-02-02 00:00:00', new \DateTimeZone('Europe/Berlin')), new \DateTime('2012-02-03 00:00:00', new \DateTimeZone('Europe/Berlin')), false]; // Added this test to check recurring events that have no instances. diff --git a/tests/VObject/PropertyTest.php b/tests/VObject/PropertyTest.php index 3fa4692a6..3c08264c3 100644 --- a/tests/VObject/PropertyTest.php +++ b/tests/VObject/PropertyTest.php @@ -281,7 +281,7 @@ public function testValidateBadPropertyName() $property = $calendar->createProperty('X_*&PROP*', 'Bla'); $result = $property->validate(Node::REPAIR); - $this->assertEquals('The propertyname: X_*&PROP* contains invalid characters. Only A-Z, 0-9 and - are allowed', $result[0]['message']); + $this->assertEquals('The property name: X_*&PROP* contains invalid characters. Only A-Z, 0-9 and - are allowed', $result[0]['message']); $this->assertEquals('X-PROP', $property->name); } From 82505daaa82abf0b729e51817874f2e181fb8753 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sun, 21 Aug 2022 18:38:40 +0545 Subject: [PATCH 132/165] calendar parameter to parseEventInfo cannot be null --- lib/ITip/Broker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ITip/Broker.php b/lib/ITip/Broker.php index 279452735..deefb5d38 100644 --- a/lib/ITip/Broker.php +++ b/lib/ITip/Broker.php @@ -796,7 +796,7 @@ protected function parseEventForAttendee(VCalendar $calendar, array $eventInfo, * @throws ITipException * @throws SameOrganizerForAllComponentsException */ - protected function parseEventInfo(VCalendar $calendar = null): array + protected function parseEventInfo(VCalendar $calendar): array { $uid = null; $organizer = null; From 19d99290e871484a55a88ba3a6168075f4650518 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sun, 21 Aug 2022 18:41:58 +0545 Subject: [PATCH 133/165] Make Broker processMessageReply return null instead of void --- lib/ITip/Broker.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/ITip/Broker.php b/lib/ITip/Broker.php index deefb5d38..6d627537b 100644 --- a/lib/ITip/Broker.php +++ b/lib/ITip/Broker.php @@ -317,18 +317,16 @@ protected function processMessageCancel(Message $itipMessage, ?VCalendar $existi * The message is a reply. This is for example an attendee telling * an organizer he accepted the invite, or declined it. * - * @return VCalendar|void - * * @throws InvalidDataException * @throws MaxInstancesExceededException * @throws NoInstancesException */ - protected function processMessageReply(Message $itipMessage, ?VCalendar $existingObject = null) + protected function processMessageReply(Message $itipMessage, ?VCalendar $existingObject = null): ?VCalendar { // A reply can only be processed based on an existing object. // If the object is not available, the reply is ignored. if (!$existingObject) { - return; + return null; } $instances = []; $requestStatus = '2.0'; @@ -383,7 +381,7 @@ protected function processMessageReply(Message $itipMessage, ?VCalendar $existin if (!$masterObject) { // No master object, we can't add new instances. - return; + return null; } // If we got replies to instances that did not exist in the // original list, it means that new exceptions must be created. From 39e499b670c645b23ddda70da0cd4cd7c5d9014b Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Mon, 22 Aug 2022 16:36:27 +0545 Subject: [PATCH 134/165] Adjust lib/Parser code --- lib/Parser/MimeDir.php | 27 ++++++++++----------------- lib/Parser/XML.php | 4 +--- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/lib/Parser/MimeDir.php b/lib/Parser/MimeDir.php index cff33c8cd..ba80e4541 100644 --- a/lib/Parser/MimeDir.php +++ b/lib/Parser/MimeDir.php @@ -13,7 +13,6 @@ use function rtrim; -use Sabre\VObject\Component; use Sabre\VObject\Component\VCalendar; use Sabre\VObject\Component\VCard; use Sabre\VObject\Document; @@ -53,7 +52,7 @@ class MimeDir extends Parser protected ?Document $root; /** - * By default all input will be assumed to be UTF-8. + * By default, all input will be assumed to be UTF-8. * * However, both iCalendar and vCard might be encoded using different * character sets. The character set is usually set in the mime-type. @@ -103,7 +102,7 @@ public function parse($input = null, int $options = 0): ?Document } /** - * By default all input will be assumed to be UTF-8. + * By default, all input will be assumed to be UTF-8. * * However, both iCalendar and vCard might be encoded using different * character sets. The character set is usually set in the mime-type. @@ -255,30 +254,24 @@ protected function parseLine(string $line) * the next line. * * If that was not the case, we store it here. - * - * @var string|null */ - protected $lineBuffer; + protected ?string $lineBuffer = null; /** * The real current line number. */ - protected $lineIndex = 0; + protected int $lineIndex = 0; /** * In the case of unfolded lines, this property holds the line number for * the start of the line. - * - * @var int */ - protected $startLine = 0; + protected int $startLine = 0; /** * Contains a 'raw' representation of the current line. - * - * @var string */ - protected $rawLine; + protected string $rawLine; /** * Reads a single line from the buffer. @@ -514,9 +507,9 @@ protected function readProperty(string $line) * * vCard 3.0 says: * * (rfc2425) Backslashes, newlines (\n or \N) and comma's must be - * escaped, all time time. - * * Comma's are used for delimiters in multiple values - * * (rfc2426) Adds to to this that the semi-colon MUST also be escaped, + * escaped, all the time. + * * Commas are used for delimiters in multiple values + * * (rfc2426) Adds to this that the semi-colon MUST also be escaped, * as in some properties semi-colon is used for separators. * * Properties using semi-colons: N, ADR, GEO, ORG * * Both ADR and N's individual parts may be broken up further with a @@ -549,7 +542,7 @@ protected function readProperty(string $line) * insignificant. * * Semi-colons are described as the delimiter for 'structured values'. * They are specifically used in Semi-colons are used as a delimiter in - * REQUEST-STATUS, RRULE, GEO and EXRULE. EXRULE is deprecated however. + * REQUEST-STATUS, RRULE, GEO and EXRULE. EXRULE is deprecated, however. * * Now for the parameters * diff --git a/lib/Parser/XML.php b/lib/Parser/XML.php index 22a3857a9..bb0b0cd3f 100644 --- a/lib/Parser/XML.php +++ b/lib/Parser/XML.php @@ -343,11 +343,9 @@ protected function createProperty(Component $parentComponent, string $name, arra * * @param resource|string|array $input * - * @return void - * * @throws SabreXml\LibXMLException */ - public function setInput($input) + public function setInput($input): void { if (is_resource($input)) { $input = stream_get_contents($input); From 3abc8177b3d69b7eb44085800b86fb1e1c0f4c70 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Mon, 22 Aug 2022 16:52:39 +0545 Subject: [PATCH 135/165] Adjust lib/Property code --- lib/Property/ICalendar/DateTime.php | 4 ++-- lib/Property/ICalendar/Duration.php | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/Property/ICalendar/DateTime.php b/lib/Property/ICalendar/DateTime.php index 1b3c2ebcc..09804aa99 100644 --- a/lib/Property/ICalendar/DateTime.php +++ b/lib/Property/ICalendar/DateTime.php @@ -131,7 +131,7 @@ public function isFloating(): bool * * @throws InvalidDataException */ - public function getDateTime(DateTimeZone $timeZone = null): ?DateTimeImmutable + public function getDateTime(?DateTimeZone $timeZone = null): ?DateTimeImmutable { $dt = $this->getDateTimes($timeZone); if (!$dt) { @@ -152,7 +152,7 @@ public function getDateTime(DateTimeZone $timeZone = null): ?DateTimeImmutable * * @throws InvalidDataException */ - public function getDateTimes(DateTimeZone $timeZone = null): array + public function getDateTimes(?DateTimeZone $timeZone = null): array { // Does the property have a TZID? /** @var Property\FlatText $tzid */ diff --git a/lib/Property/ICalendar/Duration.php b/lib/Property/ICalendar/Duration.php index 39d74e400..d8fd99281 100644 --- a/lib/Property/ICalendar/Duration.php +++ b/lib/Property/ICalendar/Duration.php @@ -61,11 +61,9 @@ public function getValueType(): string * * If the property has more than one value, only the first is returned. * - * @return DateInterval|string - * * @throws InvalidDataException */ - public function getDateInterval() + public function getDateInterval(): DateInterval { $parts = $this->getParts(); $value = $parts[0]; From b775bd6bf451141583e5d01d361506869c2bd6de Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Mon, 22 Aug 2022 17:28:10 +0545 Subject: [PATCH 136/165] Adjust lib/Recur code --- lib/Recur/EventIterator.php | 10 +++------- lib/Recur/RDateIterator.php | 12 ++++-------- lib/Recur/RRuleIterator.php | 38 ++++++++++++------------------------- 3 files changed, 19 insertions(+), 41 deletions(-) diff --git a/lib/Recur/EventIterator.php b/lib/Recur/EventIterator.php index 9362ba47f..13c5f7bcd 100644 --- a/lib/Recur/EventIterator.php +++ b/lib/Recur/EventIterator.php @@ -94,7 +94,7 @@ class EventIterator implements Iterator * @throws NoInstancesException * @throws InvalidDataException */ - public function __construct($input, string $uid = null, DateTimeZone $timeZone = null) + public function __construct($input, ?string $uid = null, DateTimeZone $timeZone = null) { if (is_null($timeZone)) { $timeZone = new DateTimeZone('UTC'); @@ -319,12 +319,10 @@ public function valid(): bool /** * Sets the iterator back to the starting point. * - * @return void - * * @throws InvalidDataException */ #[\ReturnTypeWillChange] - public function rewind() + public function rewind(): void { $this->recurIterator->rewind(); // re-creating overridden event index. @@ -348,12 +346,10 @@ public function rewind() /** * Advances the iterator with one step. * - * @return void - * * @throws InvalidDataException */ #[\ReturnTypeWillChange] - public function next() + public function next(): void { $this->currentOverriddenEvent = null; ++$this->counter; diff --git a/lib/Recur/RDateIterator.php b/lib/Recur/RDateIterator.php index b5337fb15..ecf25d847 100644 --- a/lib/Recur/RDateIterator.php +++ b/lib/Recur/RDateIterator.php @@ -37,10 +37,10 @@ public function __construct($rrule, DateTimeInterface $start) /* Implementation of the Iterator interface {{{ */ #[\ReturnTypeWillChange] - public function current() + public function current(): ?DateTimeInterface { if (!$this->valid()) { - return; + return null; } return clone $this->currentDate; @@ -67,11 +67,9 @@ public function valid(): bool /** * Resets the iterator. - * - * @return void */ #[\ReturnTypeWillChange] - public function rewind() + public function rewind(): void { $this->currentDate = clone $this->startDate; $this->counter = 0; @@ -80,12 +78,10 @@ public function rewind() /** * Goes on to the next iteration. * - * @return void - * * @throws InvalidDataException */ #[\ReturnTypeWillChange] - public function next() + public function next(): void { ++$this->counter; if (!$this->valid()) { diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index fb964f3c5..bdd92f52c 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -50,10 +50,10 @@ public function __construct($rrule, DateTimeInterface $start) /* Implementation of the Iterator interface {{{ */ #[\ReturnTypeWillChange] - public function current() + public function current(): ?DateTimeInterface { if (!$this->valid()) { - return; + return null; } return clone $this->currentDate; @@ -61,11 +61,9 @@ public function current() /** * Returns the current item number. - * - * @return int */ #[\ReturnTypeWillChange] - public function key() + public function key(): int { return $this->counter; } @@ -74,11 +72,9 @@ public function key() * Returns whether the current item is a valid item for the recurrence * iterator. This will return false if we've gone beyond the UNTIL or COUNT * statements. - * - * @return bool */ #[\ReturnTypeWillChange] - public function valid() + public function valid(): bool { if (null === $this->currentDate) { return false; @@ -92,11 +88,9 @@ public function valid() /** * Resets the iterator. - * - * @return void */ #[\ReturnTypeWillChange] - public function rewind() + public function rewind(): void { $this->currentDate = clone $this->startDate; $this->counter = 0; @@ -104,11 +98,9 @@ public function rewind() /** * Goes on to the next iteration. - * - * @return void */ #[\ReturnTypeWillChange] - public function next() + public function next(): void { // Otherwise, we find the next event in the normal RRULE // sequence. @@ -438,7 +430,7 @@ protected function nextMonthly(): void $occurrences = $this->getMonthlyOccurrences(); foreach ($occurrences as $occurrence) { - // The first occurrence thats higher than the current + // The first occurrence that's higher than the current // day of the month wins. if ($occurrence > $currentDayOfMonth) { break 2; @@ -461,7 +453,7 @@ protected function nextMonthly(): void $currentDayOfMonth = 0; // For some reason the "until" parameter was not being used here, - // that's why the workaround of the 10000 year bug was needed at all + // that's why the workaround of the 10000-year bug was needed at all // let's stop it before the "until" parameter date if ($this->until && $this->currentDate->getTimestamp() >= $this->until->getTimestamp()) { return; @@ -805,10 +797,8 @@ protected function parseRRule($rrule): void /** * Mappings between the day number and english day name. - * - * @var array */ - protected $dayNames = [ + protected array $dayNames = [ 0 => 'Sunday', 1 => 'Monday', 2 => 'Tuesday', @@ -824,11 +814,9 @@ protected function parseRRule($rrule): void * * The returned list is an array of integers with the day of month (1-31). * - * @return array - * * @throws Exception */ - protected function getMonthlyOccurrences() + protected function getMonthlyOccurrences(): array { $startDate = clone $this->currentDate; @@ -877,7 +865,7 @@ protected function getMonthlyOccurrences() } } else { // There was no counter (first, second, last wednesdays), so we - // just need to add the all to the list). + // just need to add the all to the list. $byDayResults = array_merge($byDayResults, $dayHits); } } @@ -936,10 +924,8 @@ protected function getMonthlyOccurrences() /** * Simple mapping from iCalendar day names to day numbers. - * - * @var array */ - protected $dayMap = [ + protected array $dayMap = [ 'SU' => 0, 'MO' => 1, 'TU' => 2, From 3139aba3a0621442bf9bb8445d041111ac014889 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Mon, 22 Aug 2022 17:31:09 +0545 Subject: [PATCH 137/165] Adjust lib/Splitter code --- lib/Splitter/SplitterInterface.php | 2 +- lib/Splitter/VCard.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Splitter/SplitterInterface.php b/lib/Splitter/SplitterInterface.php index 6827e1422..c4014abf3 100644 --- a/lib/Splitter/SplitterInterface.php +++ b/lib/Splitter/SplitterInterface.php @@ -22,7 +22,7 @@ interface SplitterInterface /** * Constructor. * - * The splitter should receive an readable file stream as its input. + * The splitter should receive a readable file stream as its input. * * @param resource $input */ diff --git a/lib/Splitter/VCard.php b/lib/Splitter/VCard.php index dfe596d5f..e63ae837d 100644 --- a/lib/Splitter/VCard.php +++ b/lib/Splitter/VCard.php @@ -37,7 +37,7 @@ class VCard implements SplitterInterface /** * Constructor. * - * The splitter should receive an readable file stream as its input. + * The splitter should receive a readable file stream as its input. * * @param resource $input * @param int $options parser options, see the OPTIONS constants From 0a2c6e2b2d2524be3cde443075fee2167d3f1469 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Mon, 22 Aug 2022 18:30:27 +0545 Subject: [PATCH 138/165] Adjust lib/TimezoneGuesser code --- lib/TimezoneGuesser/FindFromOffset.php | 2 +- lib/TimezoneGuesser/FindFromTimezoneIdentifier.php | 2 +- lib/TimezoneGuesser/FindFromTimezoneMap.php | 2 +- lib/TimezoneGuesser/GuessFromLicEntry.php | 2 +- lib/TimezoneGuesser/GuessFromMsTzId.php | 4 ++-- lib/TimezoneGuesser/TimezoneFinder.php | 2 +- lib/TimezoneGuesser/TimezoneGuesser.php | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/TimezoneGuesser/FindFromOffset.php b/lib/TimezoneGuesser/FindFromOffset.php index 990ac9692..657f01a0a 100644 --- a/lib/TimezoneGuesser/FindFromOffset.php +++ b/lib/TimezoneGuesser/FindFromOffset.php @@ -11,7 +11,7 @@ */ class FindFromOffset implements TimezoneFinder { - public function find(string $tzid, bool $failIfUncertain = false): ?DateTimeZone + public function find(string $tzid, ?bool $failIfUncertain = false): ?DateTimeZone { // Maybe the author was hyper-lazy and just included an offset. We // support it, but we aren't happy about it. diff --git a/lib/TimezoneGuesser/FindFromTimezoneIdentifier.php b/lib/TimezoneGuesser/FindFromTimezoneIdentifier.php index 2449b4fa7..a1a189ba1 100644 --- a/lib/TimezoneGuesser/FindFromTimezoneIdentifier.php +++ b/lib/TimezoneGuesser/FindFromTimezoneIdentifier.php @@ -12,7 +12,7 @@ */ class FindFromTimezoneIdentifier implements TimezoneFinder { - public function find(string $tzid, bool $failIfUncertain = false): ?DateTimeZone + public function find(string $tzid, ?bool $failIfUncertain = false): ?DateTimeZone { // First we will just see if the tzid is a support timezone identifier. // diff --git a/lib/TimezoneGuesser/FindFromTimezoneMap.php b/lib/TimezoneGuesser/FindFromTimezoneMap.php index 89263f69e..723161e91 100644 --- a/lib/TimezoneGuesser/FindFromTimezoneMap.php +++ b/lib/TimezoneGuesser/FindFromTimezoneMap.php @@ -18,7 +18,7 @@ class FindFromTimezoneMap implements TimezoneFinder '/^\((UTC|GMT)(\+|\-)[\d]{2}\.[\d]{2}\) (.*)/', ]; - public function find(string $tzid, bool $failIfUncertain = false): ?DateTimeZone + public function find(string $tzid, ?bool $failIfUncertain = false): ?DateTimeZone { // Next, we check if the tzid is somewhere in our tzid map. if ($this->hasTzInMap($tzid)) { diff --git a/lib/TimezoneGuesser/GuessFromLicEntry.php b/lib/TimezoneGuesser/GuessFromLicEntry.php index f340a3962..b2938e6ab 100644 --- a/lib/TimezoneGuesser/GuessFromLicEntry.php +++ b/lib/TimezoneGuesser/GuessFromLicEntry.php @@ -13,7 +13,7 @@ */ class GuessFromLicEntry implements TimezoneGuesser { - public function guess(VTimeZone $vtimezone, bool $failIfUncertain = false): ?DateTimeZone + public function guess(VTimeZone $vtimezone, ?bool $failIfUncertain = false): ?DateTimeZone { if (!isset($vtimezone->{'X-LIC-LOCATION'})) { return null; diff --git a/lib/TimezoneGuesser/GuessFromMsTzId.php b/lib/TimezoneGuesser/GuessFromMsTzId.php index 0e4847f9d..176d3c55b 100644 --- a/lib/TimezoneGuesser/GuessFromMsTzId.php +++ b/lib/TimezoneGuesser/GuessFromMsTzId.php @@ -19,7 +19,7 @@ class GuessFromMsTzId implements TimezoneGuesser 31 => 'Africa/Casablanca', // Insanely, id #2 is used for both Europe/Lisbon, and Europe/Sarajevo. - // I'm not even kidding.. We handle this special case in the + // I'm not even kidding. We handle this special case in the // getTimeZone method. 2 => 'Europe/Lisbon', 1 => 'Europe/London', @@ -96,7 +96,7 @@ class GuessFromMsTzId implements TimezoneGuesser 39 => 'Pacific/Kwajalein', ]; - public function guess(VTimeZone $vtimezone, bool $failIfUncertain = false): ?DateTimeZone + public function guess(VTimeZone $vtimezone, ?bool $failIfUncertain = false): ?DateTimeZone { // Microsoft may add a magic number, which we also have an // answer for. diff --git a/lib/TimezoneGuesser/TimezoneFinder.php b/lib/TimezoneGuesser/TimezoneFinder.php index 5aa880a1c..a5c6a9fbd 100644 --- a/lib/TimezoneGuesser/TimezoneFinder.php +++ b/lib/TimezoneGuesser/TimezoneFinder.php @@ -6,5 +6,5 @@ interface TimezoneFinder { - public function find(string $tzid, bool $failIfUncertain = false): ?DateTimeZone; + public function find(string $tzid, ?bool $failIfUncertain = false): ?DateTimeZone; } diff --git a/lib/TimezoneGuesser/TimezoneGuesser.php b/lib/TimezoneGuesser/TimezoneGuesser.php index 5e193bb52..facb29634 100644 --- a/lib/TimezoneGuesser/TimezoneGuesser.php +++ b/lib/TimezoneGuesser/TimezoneGuesser.php @@ -7,5 +7,5 @@ interface TimezoneGuesser { - public function guess(VTimeZone $vtimezone, bool $failIfUncertain = false): ?DateTimeZone; + public function guess(VTimeZone $vtimezone, ?bool $failIfUncertain = false): ?DateTimeZone; } From bfadbad9c15dba8f09d30b87a6f8e45814569617 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Mon, 22 Aug 2022 22:33:03 +0545 Subject: [PATCH 139/165] Adjust parameters, return types, new methods in tests --- tests/VObject/AttachIssueTest.php | 2 +- .../VObject/BirthdayCalendarGeneratorTest.php | 30 +-- tests/VObject/Component/AvailableTest.php | 6 +- tests/VObject/Component/VAlarmTest.php | 8 +- tests/VObject/Component/VAvailabilityTest.php | 32 ++-- tests/VObject/Component/VCalendarTest.php | 66 +++---- tests/VObject/Component/VCardTest.php | 34 ++-- tests/VObject/Component/VEventTest.php | 6 +- tests/VObject/Component/VFreeBusyTest.php | 4 +- tests/VObject/Component/VJournalTest.php | 8 +- tests/VObject/Component/VTimeZoneTest.php | 4 +- tests/VObject/Component/VTodoTest.php | 12 +- tests/VObject/ComponentTest.php | 84 ++++----- tests/VObject/DateTimeParserTest.php | 86 ++++----- tests/VObject/DocumentTest.php | 12 +- tests/VObject/ElementListTest.php | 2 +- tests/VObject/EmClientTest.php | 2 +- tests/VObject/EmptyParameterTest.php | 4 +- tests/VObject/EmptyValueIssueTest.php | 2 +- tests/VObject/FreeBusyDataTest.php | 14 +- tests/VObject/FreeBusyGeneratorTest.php | 65 ++++--- tests/VObject/GoogleColonEscapingTest.php | 2 +- tests/VObject/ICalendar/AttachParseTest.php | 2 +- .../VObject/ITip/BrokerAttendeeReplyTest.php | 40 ++-- tests/VObject/ITip/BrokerDeleteEventTest.php | 14 +- tests/VObject/ITip/BrokerNewEventTest.php | 33 ++-- .../VObject/ITip/BrokerProcessMessageTest.php | 24 +-- tests/VObject/ITip/BrokerProcessReplyTest.php | 44 ++--- .../ITip/BrokerSignificantChangesTest.php | 10 +- tests/VObject/ITip/BrokerTester.php | 6 +- ...ezoneInParseEventInfoWithoutMasterTest.php | 4 +- tests/VObject/ITip/BrokerUpdateEventTest.php | 44 ++--- tests/VObject/ITip/EvolutionTest.php | 10 +- tests/VObject/ITip/MessageTest.php | 6 +- tests/VObject/Issue153Test.php | 2 +- tests/VObject/Issue259Test.php | 4 +- tests/VObject/Issue36WorkAroundTest.php | 2 +- tests/VObject/Issue40Test.php | 2 +- tests/VObject/Issue64Test.php | 4 +- tests/VObject/Issue96Test.php | 2 +- tests/VObject/IssueUndefinedIndexTest.php | 4 +- tests/VObject/JCalTest.php | 2 +- tests/VObject/JCardTest.php | 2 +- tests/VObject/LineFoldingIssueTest.php | 2 +- tests/VObject/ParameterTest.php | 24 +-- tests/VObject/Parser/JsonTest.php | 8 +- tests/VObject/Parser/MimeDirTest.php | 34 ++-- tests/VObject/Parser/QuotedPrintableTest.php | 21 ++- tests/VObject/Parser/XmlTest.php | 174 +++++++++--------- tests/VObject/Property/BinaryTest.php | 2 +- tests/VObject/Property/BooleanTest.php | 2 +- tests/VObject/Property/CompoundTest.php | 12 +- tests/VObject/Property/FloatTest.php | 2 +- .../Property/ICalendar/CalAddressTest.php | 4 +- .../Property/ICalendar/DateTimeTest.php | 54 +++--- .../Property/ICalendar/DurationTest.php | 2 +- .../VObject/Property/ICalendar/RecurTest.php | 72 ++++---- tests/VObject/Property/TextTest.php | 20 +- tests/VObject/Property/UriTest.php | 2 +- .../Property/VCard/DateAndOrTimeTest.php | 30 +-- .../Property/VCard/LanguageTagTest.php | 4 +- .../Property/VCard/PhoneNumberTest.php | 2 +- tests/VObject/PropertyTest.php | 82 ++++----- tests/VObject/ReaderTest.php | 106 +++++------ .../EventIterator/ByMonthInDailyTest.php | 2 +- .../Recur/EventIterator/BySetPosHangTest.php | 2 +- .../EventIterator/ExpandFloatingTimesTest.php | 4 +- .../EventIterator/FifthTuesdayProblemTest.php | 2 +- .../EventIterator/HandleRDateExpandTest.php | 4 +- .../EventIterator/IncorrectExpandTest.php | 2 +- .../EventIterator/InfiniteLoopProblemTest.php | 9 +- .../Recur/EventIterator/Issue26Test.php | 4 +- .../Recur/EventIterator/Issue48Test.php | 2 +- .../Recur/EventIterator/Issue50Test.php | 2 +- .../VObject/Recur/EventIterator/MainTest.php | 66 +++---- .../Recur/EventIterator/MaxInstancesTest.php | 2 +- .../EventIterator/MissingOverriddenTest.php | 2 +- .../Recur/EventIterator/NoInstancesTest.php | 4 +- .../EventIterator/OverrideDurationTest.php | 18 +- .../EventIterator/OverrideFirstEventTest.php | 4 +- .../SameDateForRecurringEventsTest.php | 2 +- tests/VObject/Recur/RDateIteratorTest.php | 6 +- tests/VObject/Recur/RRuleIteratorTest.php | 126 ++++++------- tests/VObject/SlashRTest.php | 2 +- tests/VObject/Splitter/ICalendarTest.php | 26 +-- tests/VObject/Splitter/VCardTest.php | 30 +-- tests/VObject/StringUtilTest.php | 12 +- tests/VObject/TimeZoneUtilTest.php | 36 ++-- tests/VObject/UUIDUtilTest.php | 4 +- tests/VObject/VCard21Test.php | 4 +- tests/VObject/VersionTest.php | 2 +- tests/VObject/WriterTest.php | 8 +- 92 files changed, 889 insertions(+), 903 deletions(-) diff --git a/tests/VObject/AttachIssueTest.php b/tests/VObject/AttachIssueTest.php index fb2b8b037..74c93cd00 100644 --- a/tests/VObject/AttachIssueTest.php +++ b/tests/VObject/AttachIssueTest.php @@ -6,7 +6,7 @@ class AttachIssueTest extends TestCase { - public function testRead() + public function testRead(): void { $event = <<expectException(ParseException::class); $generator = new BirthdayCalendarGenerator(); @@ -471,7 +471,7 @@ public function testParseException() $generator->setObjects($input); } - public function testInvalidArgumentException() + public function testInvalidArgumentException(): void { $this->expectException(\InvalidArgumentException::class); $generator = new BirthdayCalendarGenerator(); @@ -488,7 +488,7 @@ public function testInvalidArgumentException() $generator->setObjects($input); } - public function testInvalidArgumentExceptionForPartiallyInvalidArray() + public function testInvalidArgumentExceptionForPartiallyInvalidArray(): void { $this->expectException(\InvalidArgumentException::class); $generator = new BirthdayCalendarGenerator(); @@ -513,7 +513,7 @@ public function testInvalidArgumentExceptionForPartiallyInvalidArray() $generator->setObjects($input); } - public function testBrokenVcardWithoutFN() + public function testBrokenVcardWithoutFN(): void { $generator = new BirthdayCalendarGenerator(); $input = <<assertInstanceOf(Available::class, $document->AVAILABLE); } - public function testGetEffectiveStartEnd() + public function testGetEffectiveStartEnd(): void { $vcal = <<assertEquals($outcome, $valarm->isInTimeRange($start, $end)); } - public function timeRangeTestData() + public function timeRangeTestData(): array { $tests = []; @@ -127,7 +127,7 @@ public function timeRangeTestData() return $tests; } - public function testInTimeRangeInvalidComponent() + public function testInTimeRangeInvalidComponent(): void { $this->expectException(InvalidDataException::class); $calendar = new VCalendar(); @@ -144,7 +144,7 @@ public function testInTimeRangeInvalidComponent() /** * This bug was found and reported on the mailing list. */ - public function testInTimeRangeBuggy() + public function testInTimeRangeBuggy(): void { $input = <<assertInstanceOf(VAvailability::class, $document->VAVAILABILITY); } - public function testGetEffectiveStartEnd() + public function testGetEffectiveStartEnd(): void { $vcal = <<assertIsValid(Reader::read( @@ -177,7 +177,7 @@ public function testRFCxxxSection3Part1AvailabilitypropRequired() )); } - public function testRFCxxxSection3Part1AvailabilitypropOptionalOnce() + public function testRFCxxxSection3Part1AvailabilityPropOptionalOnce(): void { $properties = [ 'BUSYTYPE:BUSY', @@ -205,7 +205,7 @@ public function testRFCxxxSection3Part1AvailabilitypropOptionalOnce() } } - public function testRFCxxxSection3Part1AvailabilitypropDtendDuration() + public function testRFCxxxSection3Part1AvailabilityPropDtendDuration(): void { // Only DTEND. $this->assertIsValid(Reader::read($this->template([ @@ -224,7 +224,7 @@ public function testRFCxxxSection3Part1AvailabilitypropDtendDuration() ]))); } - public function testAvailableSubComponent() + public function testAvailableSubComponent(): void { $vcal = <<assertInstanceOf(Available::class, $document->VAVAILABILITY->AVAILABLE); } - public function testRFCxxxSection3Part1AvailablepropRequired() + public function testRFCxxxSection3Part1AvailablePropRequired(): void { // UID, DTSTAMP and DTSTART are present. $this->assertIsValid(Reader::read( @@ -331,7 +331,7 @@ public function testRFCxxxSection3Part1AvailablepropRequired() )); } - public function testRFCxxxSection3Part1AvailableDtendDuration() + public function testRFCxxxSection3Part1AvailableDtendDuration(): void { // Only DTEND. $this->assertIsValid(Reader::read($this->templateAvailable([ @@ -350,7 +350,7 @@ public function testRFCxxxSection3Part1AvailableDtendDuration() ]))); } - public function testRFCxxxSection3Part1AvailableOptionalOnce() + public function testRFCxxxSection3Part1AvailableOptionalOnce(): void { $properties = [ 'CREATED:20111005T135125Z', @@ -373,7 +373,7 @@ public function testRFCxxxSection3Part1AvailableOptionalOnce() } } - public function testRFCxxxSection3Part2() + public function testRFCxxxSection3Part2(): void { $this->assertEquals( 'BUSY', @@ -409,7 +409,7 @@ public function testRFCxxxSection3Part2() ); } - protected function assertIsValid(VObject\Document $document) + protected function assertIsValid(VObject\Document $document): void { $validationResult = $document->validate(); if ($validationResult) { @@ -419,7 +419,7 @@ protected function assertIsValid(VObject\Document $document) $this->assertEmpty($document->validate()); } - protected function assertIsNotValid(VObject\Document $document) + protected function assertIsNotValid(VObject\Document $document): void { $this->assertNotEmpty($document->validate()); } diff --git a/tests/VObject/Component/VCalendarTest.php b/tests/VObject/Component/VCalendarTest.php index dd029a455..2dfeff581 100644 --- a/tests/VObject/Component/VCalendarTest.php +++ b/tests/VObject/Component/VCalendarTest.php @@ -14,7 +14,7 @@ class VCalendarTest extends TestCase /** * @dataProvider expandData */ - public function testExpand($input, $output, $timeZone = 'UTC', $start = '2011-12-01', $end = '2011-12-31') + public function testExpand(string $input, string $output, string $timeZone = 'UTC', string $start = '2011-12-01', string $end = '2011-12-31'): void { $vcal = VObject\Reader::read($input); @@ -32,7 +32,7 @@ public function testExpand($input, $output, $timeZone = 'UTC', $start = '2011-12 $this->assertVObjectEqualsVObject($output, $vcal->serialize()); } - public function expandData() + public function expandData(): array { $tests = []; @@ -331,7 +331,7 @@ public function expandData() return $tests; } - public function testBrokenEventExpand() + public function testBrokenEventExpand(): void { $this->expectException(InvalidDataException::class); $input = 'BEGIN:VCALENDAR @@ -357,7 +357,7 @@ public function testBrokenEventExpand() * * @medium */ - public function testEventExpandYearly() + public function testEventExpandYearly(): void { $input = 'BEGIN:VCALENDAR BEGIN:VEVENT @@ -377,14 +377,14 @@ public function testEventExpandYearly() $this->assertCount(7, $events->VEVENT); } - public function testGetDocumentType() + public function testGetDocumentType(): void { $vcard = new VCalendar(); $vcard->VERSION = '2.0'; $this->assertEquals(VCalendar::ICALENDAR20, $vcard->getDocumentType()); } - public function testValidateCorrect() + public function testValidateCorrect(): void { $input = 'BEGIN:VCALENDAR CALSCALE:GREGORIAN @@ -402,7 +402,7 @@ public function testValidateCorrect() $this->assertEquals([], $vcal->validate(), 'Got an error'); } - public function testValidateNoVersion() + public function testValidateNoVersion(): void { $input = 'BEGIN:VCALENDAR CALSCALE:GREGORIAN @@ -416,10 +416,10 @@ public function testValidateNoVersion() '; $vcal = VObject\Reader::read($input); - $this->assertEquals(1, count($vcal->validate())); + $this->assertCount(1, $vcal->validate()); } - public function testValidateWrongVersion() + public function testValidateWrongVersion(): void { $input = 'BEGIN:VCALENDAR CALSCALE:GREGORIAN @@ -434,10 +434,10 @@ public function testValidateWrongVersion() '; $vcal = VObject\Reader::read($input); - $this->assertEquals(1, count($vcal->validate())); + $this->assertCount(1, $vcal->validate()); } - public function testValidateNoProdId() + public function testValidateNoProdId(): void { $input = 'BEGIN:VCALENDAR CALSCALE:GREGORIAN @@ -451,10 +451,10 @@ public function testValidateNoProdId() '; $vcal = VObject\Reader::read($input); - $this->assertEquals(1, count($vcal->validate())); + $this->assertCount(1, $vcal->validate()); } - public function testValidateDoubleCalScale() + public function testValidateDoubleCalScale(): void { $input = 'BEGIN:VCALENDAR VERSION:2.0 @@ -470,10 +470,10 @@ public function testValidateDoubleCalScale() '; $vcal = VObject\Reader::read($input); - $this->assertEquals(1, count($vcal->validate())); + $this->assertCount(1, $vcal->validate()); } - public function testValidateDoubleMethod() + public function testValidateDoubleMethod(): void { $input = 'BEGIN:VCALENDAR VERSION:2.0 @@ -489,10 +489,10 @@ public function testValidateDoubleMethod() '; $vcal = VObject\Reader::read($input); - $this->assertEquals(1, count($vcal->validate())); + $this->assertCount(1, $vcal->validate()); } - public function testValidateTwoMasterEvents() + public function testValidateTwoMasterEvents(): void { $input = 'BEGIN:VCALENDAR VERSION:2.0 @@ -512,10 +512,10 @@ public function testValidateTwoMasterEvents() '; $vcal = VObject\Reader::read($input); - $this->assertEquals(1, count($vcal->validate())); + $this->assertCount(1, $vcal->validate()); } - public function testValidateOneMasterEvent() + public function testValidateOneMasterEvent(): void { $input = 'BEGIN:VCALENDAR VERSION:2.0 @@ -536,10 +536,10 @@ public function testValidateOneMasterEvent() '; $vcal = VObject\Reader::read($input); - $this->assertEquals(0, count($vcal->validate())); + $this->assertCount(0, $vcal->validate()); } - public function testGetBaseComponent() + public function testGetBaseComponent(): void { $input = 'BEGIN:VCALENDAR VERSION:2.0 @@ -566,7 +566,7 @@ public function testGetBaseComponent() $this->assertEquals('test', $result->SUMMARY->getValue()); } - public function testGetBaseComponentNoResult() + public function testGetBaseComponentNoResult(): void { $input = 'BEGIN:VCALENDAR VERSION:2.0 @@ -594,7 +594,7 @@ public function testGetBaseComponentNoResult() $this->assertNull($result); } - public function testGetBaseComponentWithFilter() + public function testGetBaseComponentWithFilter(): void { $input = 'BEGIN:VCALENDAR VERSION:2.0 @@ -621,7 +621,7 @@ public function testGetBaseComponentWithFilter() $this->assertEquals('test', $result->SUMMARY->getValue()); } - public function testGetBaseComponentWithFilterNoResult() + public function testGetBaseComponentWithFilterNoResult(): void { $input = 'BEGIN:VCALENDAR VERSION:2.0 @@ -641,7 +641,7 @@ public function testGetBaseComponentWithFilterNoResult() $this->assertNull($result); } - public function testNoComponents() + public function testNoComponents(): void { $input = <<validate($options); @@ -765,7 +765,7 @@ public function assertValidate($ics, $options, $expectedLevel, $expectedMessage $this->assertValidateResult($result, $expectedLevel, $expectedMessage); } - public function assertValidateResult($input, $expectedLevel, $expectedMessage = null) + public function assertValidateResult($input, $expectedLevel, ?string $expectedMessage = null): void { $messages = []; foreach ($input as $warning) { @@ -773,9 +773,9 @@ public function assertValidateResult($input, $expectedLevel, $expectedMessage = } if (0 === $expectedLevel) { - $this->assertEquals(0, count($input), 'No validation messages were expected. We got: '.implode(', ', $messages)); + $this->assertCount(0, $input, 'No validation messages were expected. We got: '.implode(', ', $messages)); } else { - $this->assertEquals(1, count($input), 'We expected exactly 1 validation message, We got: '.implode(', ', $messages)); + $this->assertCount(1, $input, 'We expected exactly 1 validation message, We got: '.implode(', ', $messages)); $this->assertEquals($expectedMessage, $input[0]['message']); $this->assertEquals($expectedLevel, $input[0]['level']); diff --git a/tests/VObject/Component/VCardTest.php b/tests/VObject/Component/VCardTest.php index 45743ff67..da15de1cf 100644 --- a/tests/VObject/Component/VCardTest.php +++ b/tests/VObject/Component/VCardTest.php @@ -10,7 +10,7 @@ class VCardTest extends TestCase /** * @dataProvider validateData */ - public function testValidate($input, $expectedWarnings, $expectedRepairedOutput) + public function testValidate(string $input, array $expectedWarnings, string $expectedRepairedOutput): void { $vcard = VObject\Reader::read($input); @@ -31,7 +31,7 @@ public function testValidate($input, $expectedWarnings, $expectedRepairedOutput) ); } - public function validateData() + public function validateData(): array { $tests = []; @@ -112,7 +112,7 @@ public function validateData() return $tests; } - public function testGetDocumentType() + public function testGetDocumentType(): void { $vcard = new VCard([], false); $vcard->VERSION = '2.1'; @@ -130,7 +130,7 @@ public function testGetDocumentType() $this->assertEquals(VCard::UNKNOWN, $vcard->getDocumentType()); } - public function testGetByType() + public function testGetByType(): void { $vcard = <<assertNull($vcard->getByType('ADR', 'non-existent')); } - public function testPreferredNoPref() + public function testPreferredNoPref(): void { $vcard = <<assertEquals('1@example.org', $vcard->preferred('EMAIL')->getValue()); } - public function testPreferredWithPref() + public function testPreferredWithPref(): void { $vcard = <<assertEquals('2@example.org', $vcard->preferred('EMAIL')->getValue()); } - public function testPreferredWith40Pref() + public function testPreferredWith40Pref(): void { $vcard = <<assertEquals('3@example.org', $vcard->preferred('EMAIL')->getValue()); } - public function testPreferredNotFound() + public function testPreferredNotFound(): void { $vcard = <<assertNull($vcard->preferred('EMAIL')); } - public function testNoUIDCardDAV() + public function testNoUIDCardDAV(): void { $vcard = <<validate($options); @@ -291,7 +291,7 @@ public function assertValidate($vcf, $options, $expectedLevel, $expectedMessage $this->assertValidateResult($result, $expectedLevel, $expectedMessage); } - public function assertValidateResult($input, $expectedLevel, $expectedMessage = null) + public function assertValidateResult($input, int $expectedLevel, ?string $expectedMessage = null): void { $messages = []; foreach ($input as $warning) { @@ -299,9 +299,9 @@ public function assertValidateResult($input, $expectedLevel, $expectedMessage = } if (0 === $expectedLevel) { - $this->assertEquals(0, count($input), 'No validation messages were expected. We got: '.implode(', ', $messages)); + $this->assertCount(0, $input, 'No validation messages were expected. We got: '.implode(', ', $messages)); } else { - $this->assertEquals(1, count($input), 'We expected exactly 1 validation message, We got: '.implode(', ', $messages)); + $this->assertCount(1, $input, 'We expected exactly 1 validation message, We got: '.implode(', ', $messages)); $this->assertEquals($expectedMessage, $input[0]['message']); $this->assertEquals($expectedLevel, $input[0]['level']); diff --git a/tests/VObject/Component/VEventTest.php b/tests/VObject/Component/VEventTest.php index 5587ea2e2..8d73ac114 100644 --- a/tests/VObject/Component/VEventTest.php +++ b/tests/VObject/Component/VEventTest.php @@ -9,12 +9,12 @@ class VEventTest extends TestCase /** * @dataProvider timeRangeTestData */ - public function testInTimeRange(VEvent $vevent, $start, $end, $outcome) + public function testInTimeRange(VEvent $vevent, \DateTime $start, \DateTime $end, bool $outcome): void { $this->assertEquals($outcome, $vevent->isInTimeRange($start, $end)); } - public function timeRangeTestData() + public function timeRangeTestData(): array { $tests = []; @@ -42,7 +42,7 @@ public function timeRangeTestData() $tests[] = [$vevent4, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false]; // Event with no end date should be treated as lasting the entire day. $tests[] = [$vevent4, new \DateTime('2011-12-25 16:00:00'), new \DateTime('2011-12-25 17:00:00'), true]; - // DTEND is non inclusive so all day events should not be returned on the next day. + // DTEND is non-inclusive so all day events should not be returned on the next day. $tests[] = [$vevent4, new \DateTime('2011-12-26 00:00:00'), new \DateTime('2011-12-26 17:00:00'), false]; // The timezone of time range in question also needs to be considered. $tests[] = [$vevent4, new \DateTime('2011-12-26 00:00:00', new \DateTimeZone('Europe/Berlin')), new \DateTime('2011-12-26 17:00:00', new \DateTimeZone('Europe/Berlin')), false]; diff --git a/tests/VObject/Component/VFreeBusyTest.php b/tests/VObject/Component/VFreeBusyTest.php index 2aa4351ca..c1e22dd13 100644 --- a/tests/VObject/Component/VFreeBusyTest.php +++ b/tests/VObject/Component/VFreeBusyTest.php @@ -8,7 +8,7 @@ class VFreeBusyTest extends TestCase { - public function testIsFree() + public function testIsFree(): void { $input = <<assertTrue($vfb->isFree(new \DateTime('2012-09-12 11:00:00', $tz), new \DateTime('2012-09-12 12:00:00', $tz))); } - public function testValidate() + public function testValidate(): void { $input = <<assertEquals($outcome, $vtodo->isInTimeRange($start, $end)); } - public function testValidate() + public function testValidate(): void { $input = <<assertEquals([], $messages); } - public function testValidateBroken() + public function testValidateBroken(): void { $input = <<assertEquals([], $messages); } - public function testGetTimeZone() + public function testGetTimeZone(): void { $input = <<assertEquals($outcome, $vtodo->isInTimeRange($start, $end)); } - public function timeRangeTestData() + public function timeRangeTestData(): array { $tests = []; @@ -64,7 +64,7 @@ public function timeRangeTestData() return $tests; } - public function testValidate() + public function testValidate(): void { $input = <<assertEquals([], $messages); } - public function testValidateInvalid() + public function testValidateInvalid(): void { $input = <<assertEquals(2, $count); } - public function testMagicGet() + public function testMagicGet(): void { $comp = new VCalendar([], false); @@ -50,7 +50,7 @@ public function testMagicGet() /** * @throws InvalidDataException */ - public function testMagicGetGroups() + public function testMagicGetGroups(): void { $comp = new VCard(); @@ -90,7 +90,7 @@ public function testMagicGetGroups() } } - public function testAddGroupProperties() + public function testAddGroupProperties(): void { $comp = new VCard([ 'VERSION' => '3.0', @@ -107,7 +107,7 @@ public function testAddGroupProperties() } } - public function testMagicIsset() + public function testMagicIsset(): void { $comp = new VCalendar(); @@ -122,7 +122,7 @@ public function testMagicIsset() $this->assertFalse(isset($comp->vjournal)); } - public function testMagicSetScalar() + public function testMagicSetScalar(): void { $comp = new VCalendar(); $comp->myProp = 'myValue'; @@ -131,7 +131,7 @@ public function testMagicSetScalar() $this->assertEquals('myValue', (string) $comp->MYPROP); } - public function testMagicSetScalarTwice() + public function testMagicSetScalarTwice(): void { $comp = new VCalendar([], false); $comp->myProp = 'myValue'; @@ -142,7 +142,7 @@ public function testMagicSetScalarTwice() $this->assertEquals('myValue', (string) $comp->MYPROP); } - public function testMagicSetArray() + public function testMagicSetArray(): void { $comp = new VCalendar(); $comp->ORG = ['Acme Inc', 'Section 9']; @@ -151,7 +151,7 @@ public function testMagicSetArray() $this->assertEquals(['Acme Inc', 'Section 9'], $comp->ORG->getParts()); } - public function testMagicSetComponent() + public function testMagicSetComponent(): void { $comp = new VCalendar(); @@ -163,7 +163,7 @@ public function testMagicSetComponent() $this->assertEquals('VEVENT', $comp->VEVENT->name); } - public function testMagicSetTwice() + public function testMagicSetTwice(): void { $comp = new VCalendar([], false); @@ -175,7 +175,7 @@ public function testMagicSetTwice() $this->assertEquals('VEVENT', $comp->VEVENT->name); } - public function testArrayAccessGet() + public function testArrayAccessGet(): void { $comp = new VCalendar([], false); @@ -189,12 +189,12 @@ public function testArrayAccessGet() $comp->add($event2); - $this->assertEquals(2, count($comp->children())); + $this->assertCount(2, $comp->children()); $this->assertTrue($comp->vevent[1] instanceof Component); $this->assertEquals('Event 2', (string) $comp->vevent[1]->summary); } - public function testArrayAccessExists() + public function testArrayAccessExists(): void { $comp = new VCalendar(); @@ -212,21 +212,21 @@ public function testArrayAccessExists() $this->assertTrue(isset($comp->vevent[1])); } - public function testArrayAccessSet() + public function testArrayAccessSet(): void { $this->expectException(\LogicException::class); $comp = new VCalendar(); $comp['hey'] = 'hi there'; } - public function testArrayAccessUnset() + public function testArrayAccessUnset(): void { $this->expectException(\LogicException::class); $comp = new VCalendar(); unset($comp[0]); } - public function testAddScalar() + public function testAddScalar(): void { $comp = new VCalendar([], false); @@ -241,7 +241,7 @@ public function testAddScalar() $this->assertEquals('value', (string) $bla); } - public function testAddScalarParams() + public function testAddScalarParams(): void { $comp = new VCalendar([], false); @@ -261,7 +261,7 @@ public function testAddScalarParams() $this->assertEquals('value1', $bla->parameters['PARAM1']->getValue()); } - public function testAddComponent() + public function testAddComponent(): void { $comp = new VCalendar([], false); @@ -272,7 +272,7 @@ public function testAddComponent() $this->assertEquals('VEVENT', $comp->VEVENT->name); } - public function testAddComponentTwice() + public function testAddComponentTwice(): void { $comp = new VCalendar([], false); @@ -284,21 +284,21 @@ public function testAddComponentTwice() $this->assertEquals('VEVENT', $comp->VEVENT->name); } - public function testAddArgFail() + public function testAddArgFail(): void { $this->expectException(\InvalidArgumentException::class); $comp = new VCalendar(); $comp->add($comp->createComponent('VEVENT'), 'hello'); } - public function testAddArgFail2() + public function testAddArgFail2(): void { $this->expectException(\InvalidArgumentException::class); $comp = new VCalendar(); $comp->add([]); } - public function testMagicUnset() + public function testMagicUnset(): void { $comp = new VCalendar([], false); $comp->add($comp->createComponent('VEVENT')); @@ -308,13 +308,13 @@ public function testMagicUnset() $this->assertCount(0, $comp->children()); } - public function testCount() + public function testCount(): void { $comp = new VCalendar(); $this->assertEquals(1, $comp->count()); } - public function testChildren() + public function testChildren(): void { $comp = new VCalendar([], false); @@ -330,7 +330,7 @@ public function testChildren() /** * @throws InvalidDataException */ - public function testGetComponents() + public function testGetComponents(): void { $comp = new VCalendar(); @@ -343,13 +343,13 @@ public function testGetComponents() $this->assertEquals('VTODO', $r[0]->name); } - public function testSerialize() + public function testSerialize(): void { $comp = new VCalendar([], false); $this->assertEquals("BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n", $comp->serialize()); } - public function testSerializeChildren() + public function testSerializeChildren(): void { $comp = new VCalendar([], false); $event = $comp->add($comp->createComponent('VEVENT')); @@ -362,7 +362,7 @@ public function testSerializeChildren() $this->assertEquals("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n", $str); } - public function testSerializeOrderCompAndProp() + public function testSerializeOrderCompAndProp(): void { $comp = new VCalendar([], false); $comp->add($event = $comp->createComponent('VEVENT')); @@ -376,7 +376,7 @@ public function testSerializeOrderCompAndProp() $this->assertEquals("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPROP1:BLABLA\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n", $str); } - public function testAnotherSerializeOrderProp() + public function testAnotherSerializeOrderProp(): void { $prop4s = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']; @@ -402,7 +402,7 @@ public function testAnotherSerializeOrderProp() $this->assertEquals("BEGIN:VCARD\r\nVERSION:2.0\r\nSOMEPROP:FOO\r\nANOTHERPROP:FOO\r\nTHIRDPROP:FOO\r\nPROP4:FOO 1\r\nPROP4:FOO 2\r\nPROP4:FOO 3\r\nPROP4:FOO 4\r\nPROP4:FOO 5\r\nPROP4:FOO 6\r\nPROP4:FOO 7\r\nPROP4:FOO 8\r\nPROP4:FOO 9\r\nPROP4:FOO 10\r\nPROPNUMBERFIVE:FOO\r\nPROPNUMBERSIX:FOO\r\nPROPNUMBERSEVEN:FOO\r\nPROPNUMBEREIGHT:FOO\r\nPROPNUMBERNINE:FOO\r\nPROPNUMBERTEN:FOO\r\nUID:FOO\r\nEND:VCARD\r\n", $str); } - public function testInstantiateWithChildren() + public function testInstantiateWithChildren(): void { $comp = new VCard([ 'ORG' => ['Acme Inc.', 'Section 9'], @@ -413,7 +413,7 @@ public function testInstantiateWithChildren() $this->assertEquals('Finn The Human', $comp->FN->getValue()); } - public function testInstantiateSubComponent() + public function testInstantiateSubComponent(): void { $comp = new VCalendar(); $event = $comp->createComponent('VEVENT', [ @@ -424,7 +424,7 @@ public function testInstantiateSubComponent() $this->assertEquals('12345', $comp->VEVENT->UID->getValue()); } - public function testRemoveByName() + public function testRemoveByName(): void { $comp = new VCalendar([], false); $comp->add('prop1', 'val1'); @@ -436,7 +436,7 @@ public function testRemoveByName() $this->assertTrue(isset($comp->prop1)); } - public function testRemoveByObj() + public function testRemoveByObj(): void { $comp = new VCalendar([], false); $comp->add('prop1', 'val1'); @@ -450,7 +450,7 @@ public function testRemoveByObj() /** * @throws InvalidDataException */ - public function testRemoveNotFound() + public function testRemoveNotFound(): void { $this->expectException(\InvalidArgumentException::class); $comp = new VCalendar([], false); @@ -461,11 +461,11 @@ public function testRemoveNotFound() /** * @dataProvider ruleData */ - public function testValidateRules($componentList, $errorCount) + public function testValidateRules(array $componentList, int $errorCount): void { $vcard = new Component\VCard(); - $component = new FakeComponent($vcard, 'Hi', [], $defaults = false); + $component = new FakeComponent($vcard, 'Hi', [], false); foreach ($componentList as $v) { $component->add($v, 'Hello.'); } @@ -473,16 +473,16 @@ public function testValidateRules($componentList, $errorCount) $this->assertCount($errorCount, $component->validate()); } - public function testValidateRepair() + public function testValidateRepair(): void { $vcard = new Component\VCard(); - $component = new FakeComponent($vcard, 'Hi', [], $defaults = false); + $component = new FakeComponent($vcard, 'Hi', [], false); $component->validate(Component::REPAIR); $this->assertEquals('yow', $component->BAR->getValue()); } - public function testValidateRepairShouldNotDeduplicatePropertiesWhenValuesDiffer() + public function testValidateRepairShouldNotDeduplicatePropertiesWhenValuesDiffer(): void { $vcard = new Component\VCard(); @@ -498,7 +498,7 @@ public function testValidateRepairShouldNotDeduplicatePropertiesWhenValuesDiffer $this->assertCount(2, $component->GIR); } - public function testValidateRepairShouldNotDeduplicatePropertiesWhenParametersDiffer() + public function testValidateRepairShouldNotDeduplicatePropertiesWhenParametersDiffer(): void { $vcard = new Component\VCard(); @@ -514,7 +514,7 @@ public function testValidateRepairShouldNotDeduplicatePropertiesWhenParametersDi $this->assertCount(2, $component->GIR); } - public function testValidateRepairShouldDeduplicatePropertiesWhenValuesAndParametersAreEqual() + public function testValidateRepairShouldDeduplicatePropertiesWhenValuesAndParametersAreEqual(): void { $vcard = new Component\VCard(); @@ -530,7 +530,7 @@ public function testValidateRepairShouldDeduplicatePropertiesWhenValuesAndParame $this->assertCount(1, $component->GIR); } - public function testValidateRepairShouldDeduplicatePropertiesWhenValuesAreEqual() + public function testValidateRepairShouldDeduplicatePropertiesWhenValuesAreEqual(): void { $vcard = new Component\VCard(); diff --git a/tests/VObject/DateTimeParserTest.php b/tests/VObject/DateTimeParserTest.php index 0317e9f86..643d021d0 100644 --- a/tests/VObject/DateTimeParserTest.php +++ b/tests/VObject/DateTimeParserTest.php @@ -12,7 +12,7 @@ class DateTimeParserTest extends TestCase /** * @throws InvalidDataException */ - public function testParseICalendarDuration() + public function testParseICalendarDuration(): void { $this->assertEquals('+1 weeks', DateTimeParser::parseDurationAsString('P1W')); $this->assertEquals('+5 days', DateTimeParser::parseDurationAsString('P5D')); @@ -26,7 +26,7 @@ public function testParseICalendarDuration() /** * @throws InvalidDataException */ - public function testParseICalendarDurationDateInterval() + public function testParseICalendarDurationDateInterval(): void { $expected = new DateInterval('P7D'); $this->assertEquals($expected, DateTimeParser::parseDuration('P1W')); @@ -37,13 +37,13 @@ public function testParseICalendarDurationDateInterval() $this->assertEquals($expected, DateTimeParser::parseDuration('-PT3M')); } - public function testParseICalendarDurationFail() + public function testParseICalendarDurationFail(): void { $this->expectException(InvalidDataException::class); DateTimeParser::parseDurationAsString('P1X'); } - public function testParseICalendarDateTime() + public function testParseICalendarDateTime(): void { $dateTime = DateTimeParser::parseDateTime('20100316T141405'); @@ -55,25 +55,25 @@ public function testParseICalendarDateTime() /** * @depends testParseICalendarDateTime */ - public function testParseICalendarDateTimeBadFormat() + public function testParseICalendarDateTimeBadFormat(): void { $this->expectException(InvalidDataException::class); - $dateTime = DateTimeParser::parseDateTime('20100316T141405 '); + DateTimeParser::parseDateTime('20100316T141405 '); } /** * @depends testParseICalendarDateTime */ - public function testParseICalendarDateTimeInvalidTime() + public function testParseICalendarDateTimeInvalidTime(): void { $this->expectException(InvalidDataException::class); - $dateTime = DateTimeParser::parseDateTime('20100316T251405'); + DateTimeParser::parseDateTime('20100316T251405'); } /** * @depends testParseICalendarDateTime */ - public function testParseICalendarDateTimeUTC() + public function testParseICalendarDateTimeUTC(): void { $dateTime = DateTimeParser::parseDateTime('20100316T141405Z'); @@ -84,7 +84,7 @@ public function testParseICalendarDateTimeUTC() /** * @depends testParseICalendarDateTime */ - public function testParseICalendarDateTimeUTC2() + public function testParseICalendarDateTimeUTC2(): void { $dateTime = DateTimeParser::parseDateTime('20101211T160000Z'); @@ -95,7 +95,7 @@ public function testParseICalendarDateTimeUTC2() /** * @depends testParseICalendarDateTime */ - public function testParseICalendarDateTimeCustomTimeZone() + public function testParseICalendarDateTimeCustomTimeZone(): void { $dateTime = DateTimeParser::parseDateTime('20100316T141405', new DateTimeZone('Europe/Amsterdam')); @@ -103,7 +103,7 @@ public function testParseICalendarDateTimeCustomTimeZone() $this->assertEquals($compare, $dateTime); } - public function testParseICalendarDate() + public function testParseICalendarDate(): void { $dateTime = DateTimeParser::parseDate('20100316'); @@ -118,7 +118,7 @@ public function testParseICalendarDate() /** * TCheck if a date with year > 4000 will not throw an exception. iOS seems to use 45001231 in yearly recurring events. */ - public function testParseICalendarDateGreaterThan4000() + public function testParseICalendarDateGreaterThan4000(): void { $dateTime = DateTimeParser::parseDate('45001231'); @@ -133,7 +133,7 @@ public function testParseICalendarDateGreaterThan4000() /** * Check if a datetime with year > 4000 will not throw an exception. iOS seems to use 45001231T235959 in yearly recurring events. */ - public function testParseICalendarDateTimeGreaterThan4000() + public function testParseICalendarDateTimeGreaterThan4000(): void { $dateTime = DateTimeParser::parseDateTime('45001231T235959'); @@ -148,25 +148,25 @@ public function testParseICalendarDateTimeGreaterThan4000() /** * @depends testParseICalendarDate */ - public function testParseICalendarDateBadFormat() + public function testParseICalendarDateBadFormat(): void { $this->expectException(InvalidDataException::class); - $dateTime = DateTimeParser::parseDate('20100316T141405'); + DateTimeParser::parseDate('20100316T141405'); } /** * @depends testParseICalendarDate */ - public function testParseICalendarDateInvalidDate() + public function testParseICalendarDateInvalidDate(): void { $this->expectException(InvalidDataException::class); - $dateTime = DateTimeParser::parseDate('20101331'); + DateTimeParser::parseDate('20101331'); } /** * @dataProvider vcardDates */ - public function testVCardDate($input, $output) + public function testVCardDate(string $input, array $output): void { $this->assertEquals( $output, @@ -174,19 +174,19 @@ public function testVCardDate($input, $output) ); } - public function testBadVCardDate() + public function testBadVCardDate(): void { $this->expectException(InvalidDataException::class); DateTimeParser::parseVCardDateTime('1985---01'); } - public function testBadVCardTime() + public function testBadVCardTime(): void { $this->expectException(InvalidDataException::class); DateTimeParser::parseVCardTime('23:12:166'); } - public function vcardDates() + public function vcardDates(): array { return [ [ @@ -414,7 +414,7 @@ public function vcardDates() ]; } - public function testDateAndOrTimeDateWithYearMonthDay() + public function testDateAndOrTimeDateWithYearMonthDay(): void { $this->assertDateAndOrTimeEqualsTo( '20150128', @@ -426,7 +426,7 @@ public function testDateAndOrTimeDateWithYearMonthDay() ); } - public function testDateAndOrTimeDateWithYearMonth() + public function testDateAndOrTimeDateWithYearMonth(): void { $this->assertDateAndOrTimeEqualsTo( '2015-01', @@ -437,7 +437,7 @@ public function testDateAndOrTimeDateWithYearMonth() ); } - public function testDateAndOrTimeDateWithMonth() + public function testDateAndOrTimeDateWithMonth(): void { $this->assertDateAndOrTimeEqualsTo( '--01', @@ -447,7 +447,7 @@ public function testDateAndOrTimeDateWithMonth() ); } - public function testDateAndOrTimeDateWithMonthDay() + public function testDateAndOrTimeDateWithMonthDay(): void { $this->assertDateAndOrTimeEqualsTo( '--0128', @@ -458,7 +458,7 @@ public function testDateAndOrTimeDateWithMonthDay() ); } - public function testDateAndOrTimeDateWithDay() + public function testDateAndOrTimeDateWithDay(): void { $this->assertDateAndOrTimeEqualsTo( '---28', @@ -468,7 +468,7 @@ public function testDateAndOrTimeDateWithDay() ); } - public function testDateAndOrTimeTimeWithHour() + public function testDateAndOrTimeTimeWithHour(): void { $this->assertDateAndOrTimeEqualsTo( '13', @@ -478,7 +478,7 @@ public function testDateAndOrTimeTimeWithHour() ); } - public function testDateAndOrTimeTimeWithHourMinute() + public function testDateAndOrTimeTimeWithHourMinute(): void { $this->assertDateAndOrTimeEqualsTo( '1353', @@ -489,7 +489,7 @@ public function testDateAndOrTimeTimeWithHourMinute() ); } - public function testDateAndOrTimeTimeWithHourSecond() + public function testDateAndOrTimeTimeWithHourSecond(): void { $this->assertDateAndOrTimeEqualsTo( '135301', @@ -501,7 +501,7 @@ public function testDateAndOrTimeTimeWithHourSecond() ); } - public function testDateAndOrTimeTimeWithMinute() + public function testDateAndOrTimeTimeWithMinute(): void { $this->assertDateAndOrTimeEqualsTo( '-53', @@ -511,7 +511,7 @@ public function testDateAndOrTimeTimeWithMinute() ); } - public function testDateAndOrTimeTimeWithMinuteSecond() + public function testDateAndOrTimeTimeWithMinuteSecond(): void { $this->assertDateAndOrTimeEqualsTo( '-5301', @@ -522,7 +522,7 @@ public function testDateAndOrTimeTimeWithMinuteSecond() ); } - public function testDateAndOrTimeTimeWithSecond() + public function testDateAndOrTimeTimeWithSecond(): void { $this->assertTrue(true); @@ -532,7 +532,7 @@ public function testDateAndOrTimeTimeWithSecond() */ } - public function testDateAndOrTimeTimeWithSecondZ() + public function testDateAndOrTimeTimeWithSecondZ(): void { $this->assertDateAndOrTimeEqualsTo( '--01Z', @@ -543,7 +543,7 @@ public function testDateAndOrTimeTimeWithSecondZ() ); } - public function testDateAndOrTimeTimeWithSecondTZ() + public function testDateAndOrTimeTimeWithSecondTZ(): void { $this->assertDateAndOrTimeEqualsTo( '--01+1234', @@ -554,7 +554,7 @@ public function testDateAndOrTimeTimeWithSecondTZ() ); } - public function testDateAndOrTimeDateTimeWithYearMonthDayHour() + public function testDateAndOrTimeDateTimeWithYearMonthDayHour(): void { $this->assertDateAndOrTimeEqualsTo( '20150128T13', @@ -567,7 +567,7 @@ public function testDateAndOrTimeDateTimeWithYearMonthDayHour() ); } - public function testDateAndOrTimeDateTimeWithMonthDayHour() + public function testDateAndOrTimeDateTimeWithMonthDayHour(): void { $this->assertDateAndOrTimeEqualsTo( '--0128T13', @@ -579,7 +579,7 @@ public function testDateAndOrTimeDateTimeWithMonthDayHour() ); } - public function testDateAndOrTimeDateTimeWithDayHour() + public function testDateAndOrTimeDateTimeWithDayHour(): void { $this->assertDateAndOrTimeEqualsTo( '---28T13', @@ -590,7 +590,7 @@ public function testDateAndOrTimeDateTimeWithDayHour() ); } - public function testDateAndOrTimeDateTimeWithDayHourMinute() + public function testDateAndOrTimeDateTimeWithDayHourMinute(): void { $this->assertDateAndOrTimeEqualsTo( '---28T1353', @@ -602,7 +602,7 @@ public function testDateAndOrTimeDateTimeWithDayHourMinute() ); } - public function testDateAndOrTimeDateTimeWithDayHourMinuteSecond() + public function testDateAndOrTimeDateTimeWithDayHourMinuteSecond(): void { $this->assertDateAndOrTimeEqualsTo( '---28T135301', @@ -615,7 +615,7 @@ public function testDateAndOrTimeDateTimeWithDayHourMinuteSecond() ); } - public function testDateAndOrTimeDateTimeWithDayHourZ() + public function testDateAndOrTimeDateTimeWithDayHourZ(): void { $this->assertDateAndOrTimeEqualsTo( '---28T13Z', @@ -627,7 +627,7 @@ public function testDateAndOrTimeDateTimeWithDayHourZ() ); } - public function testDateAndOrTimeDateTimeWithDayHourTZ() + public function testDateAndOrTimeDateTimeWithDayHourTZ(): void { $this->assertDateAndOrTimeEqualsTo( '---28T13+1234', @@ -639,7 +639,7 @@ public function testDateAndOrTimeDateTimeWithDayHourTZ() ); } - protected function assertDateAndOrTimeEqualsTo($date, $parts) + protected function assertDateAndOrTimeEqualsTo(string $date, array $parts): void { $this->assertSame( DateTimeParser::parseVCardDateAndOrTime($date), diff --git a/tests/VObject/DocumentTest.php b/tests/VObject/DocumentTest.php index f710671be..d5b2f145d 100644 --- a/tests/VObject/DocumentTest.php +++ b/tests/VObject/DocumentTest.php @@ -6,19 +6,19 @@ class DocumentTest extends TestCase { - public function testGetDocumentType() + public function testGetDocumentType(): void { $doc = new MockDocument('WHATEVER'); $this->assertEquals(Document::UNKNOWN, $doc->getDocumentType()); } - public function testConstruct() + public function testConstruct(): void { $doc = new MockDocument('VLIST'); $this->assertEquals('VLIST', $doc->name); } - public function testCreateComponent() + public function testCreateComponent(): void { $vcal = new Component\VCalendar([], false); @@ -41,7 +41,7 @@ public function testCreateComponent() $this->assertEquals("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nX-PROP;X-PARAM=3:1234256\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n", $out); } - public function testCreate() + public function testCreate(): void { $vcal = new Component\VCalendar([], false); @@ -52,7 +52,7 @@ public function testCreate() $this->assertInstanceOf(Property\Text::class, $prop); } - public function testGetClassNameForPropertyValue() + public function testGetClassNameForPropertyValue(): void { $vcal = new Component\VCalendar([], false); $this->assertEquals(Property\Text::class, $vcal->getClassNameForPropertyValue('TEXT')); @@ -62,7 +62,7 @@ public function testGetClassNameForPropertyValue() /** * @throws InvalidDataException */ - public function testDestroy() + public function testDestroy(): void { $vcal = new Component\VCalendar([], false); $event = $vcal->createComponent('VEVENT'); diff --git a/tests/VObject/ElementListTest.php b/tests/VObject/ElementListTest.php index f3bb8f2bb..9cf4c7fde 100644 --- a/tests/VObject/ElementListTest.php +++ b/tests/VObject/ElementListTest.php @@ -6,7 +6,7 @@ class ElementListTest extends TestCase { - public function testIterate() + public function testIterate(): void { $cal = new Component\VCalendar(); $sub = $cal->createComponent('VEVENT'); diff --git a/tests/VObject/EmClientTest.php b/tests/VObject/EmClientTest.php index bb586ba97..55f98dab2 100644 --- a/tests/VObject/EmClientTest.php +++ b/tests/VObject/EmClientTest.php @@ -7,7 +7,7 @@ class EmClientTest extends TestCase { - public function testParseTz() + public function testParseTz(): void { $str = 'BEGIN:VCALENDAR X-WR-CALNAME:Blackhawks Schedule 2011-12 diff --git a/tests/VObject/EmptyParameterTest.php b/tests/VObject/EmptyParameterTest.php index 52fe878e2..86b3c82d3 100644 --- a/tests/VObject/EmptyParameterTest.php +++ b/tests/VObject/EmptyParameterTest.php @@ -6,7 +6,7 @@ class EmptyParameterTest extends TestCase { - public function testRead() + public function testRead(): void { $input = <<assertEquals($expected, str_replace("\r", '', $vcard)); } - public function testVCard21Parameter() + public function testVCard21Parameter(): void { $vcard = new Component\VCard([], false); $vcard->VERSION = '2.1'; diff --git a/tests/VObject/EmptyValueIssueTest.php b/tests/VObject/EmptyValueIssueTest.php index 0798d9c4a..7c90b0dc8 100644 --- a/tests/VObject/EmptyValueIssueTest.php +++ b/tests/VObject/EmptyValueIssueTest.php @@ -11,7 +11,7 @@ */ class EmptyValueIssueTest extends TestCase { - public function testDecodeValue() + public function testDecodeValue(): void { $input = <<METHOD = 'PUBLISH'; @@ -22,10 +22,10 @@ public function testGeneratorBaseObject() $this->assertEquals('PUBLISH', $result->METHOD->getValue()); } - public function testInvalidArg() + public function testInvalidArg(): void { $this->expectException(\InvalidArgumentException::class); - $gen = new FreeBusyGenerator( + new FreeBusyGenerator( new \DateTime('2012-01-01'), new \DateTime('2012-12-31'), new \stdClass() @@ -42,12 +42,11 @@ public function testInvalidArg() * It only generates the freebusy report for the following time-range: * 2011-01-01 11:00:00 until 2011-01-03 11:11:11 * - * @param string $expected - * @param array $input - * @param string|null $timeZone - * @param string $vavailability + * @param array|string $input + * + * @throws ParseException */ - public function assertFreeBusyReport($expected, $input, $timeZone = null, $vavailability = null) + public function assertFreeBusyReport(string $expected, $input, \DateTimeZone $timeZone = null, ?string $vavailability = null): void { $gen = new FreeBusyGenerator( new \DateTime('20110101T110000Z', new \DateTimeZone('UTC')), @@ -82,7 +81,7 @@ public function assertFreeBusyReport($expected, $input, $timeZone = null, $vavai $this->assertVObjectEqualsVObject($expected, $output); } - public function testSimple() + public function testSimple(): void { $blob = <<