Update vendor folder

This commit is contained in:
Frédéric Guillot 2020-08-17 21:21:20 -07:00
parent d958ddef2c
commit 81019680fa
81 changed files with 1655 additions and 1683 deletions

185
composer.lock generated
View File

@ -582,20 +582,20 @@
}, },
{ {
"name": "symfony/contracts", "name": "symfony/contracts",
"version": "v1.1.8", "version": "v1.1.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/contracts.git", "url": "https://github.com/symfony/contracts.git",
"reference": "f51bca9de06b7a25b19a4155da7bebad099a5def" "reference": "8c4de0cf797f2eba4334a1d7a9b788c1b30a7579"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/contracts/zipball/f51bca9de06b7a25b19a4155da7bebad099a5def", "url": "https://api.github.com/repos/symfony/contracts/zipball/8c4de0cf797f2eba4334a1d7a9b788c1b30a7579",
"reference": "f51bca9de06b7a25b19a4155da7bebad099a5def", "reference": "8c4de0cf797f2eba4334a1d7a9b788c1b30a7579",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.1.3", "php": ">=7.1.3",
"psr/cache": "^1.0", "psr/cache": "^1.0",
"psr/container": "^1.0" "psr/container": "^1.0"
}, },
@ -655,7 +655,7 @@
"interoperability", "interoperability",
"standards" "standards"
], ],
"time": "2019-11-07T12:44:51+00:00" "time": "2020-07-29T14:46:19+00:00"
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
@ -771,16 +771,16 @@
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.17.0", "version": "v1.18.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git", "url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "fa79b11539418b02fc5e1897267673ba2c19419c" "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/a6977d63bf9a0ad4c65cd352709e230876f9904a",
"reference": "fa79b11539418b02fc5e1897267673ba2c19419c", "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -792,7 +792,11 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.17-dev" "dev-master": "1.18-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
} }
}, },
"autoload": { "autoload": {
@ -826,21 +830,7 @@
"portable", "portable",
"shim" "shim"
], ],
"funding": [ "time": "2020-07-14T12:35:20+00:00"
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-05-12T16:47:27+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [
@ -898,20 +888,6 @@
"constructor", "constructor",
"instantiate" "instantiate"
], ],
"funding": [
{
"url": "https://www.doctrine-project.org/sponsorship.html",
"type": "custom"
},
{
"url": "https://www.patreon.com/phpdoctrine",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
"type": "tidelift"
}
],
"time": "2020-05-29T17:27:14+00:00" "time": "2020-05-29T17:27:14+00:00"
}, },
{ {
@ -960,12 +936,6 @@
"object", "object",
"object graph" "object graph"
], ],
"funding": [
{
"url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
"type": "tidelift"
}
],
"time": "2020-06-29T13:22:24+00:00" "time": "2020-06-29T13:22:24+00:00"
}, },
{ {
@ -1218,33 +1188,33 @@
}, },
{ {
"name": "phpspec/prophecy", "name": "phpspec/prophecy",
"version": "v1.10.3", "version": "1.11.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpspec/prophecy.git", "url": "https://github.com/phpspec/prophecy.git",
"reference": "451c3cd1418cf640de218914901e51b064abb093" "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b20034be5efcdab4fb60ca3a29cba2949aead160",
"reference": "451c3cd1418cf640de218914901e51b064abb093", "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"doctrine/instantiator": "^1.0.2", "doctrine/instantiator": "^1.2",
"php": "^5.3|^7.0", "php": "^7.2",
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", "phpdocumentor/reflection-docblock": "^5.0",
"sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", "sebastian/comparator": "^3.0 || ^4.0",
"sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" "sebastian/recursion-context": "^3.0 || ^4.0"
}, },
"require-dev": { "require-dev": {
"phpspec/phpspec": "^2.5 || ^3.2", "phpspec/phpspec": "^6.0",
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" "phpunit/phpunit": "^8.0"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.10.x-dev" "dev-master": "1.11.x-dev"
} }
}, },
"autoload": { "autoload": {
@ -1277,7 +1247,7 @@
"spy", "spy",
"stub" "stub"
], ],
"time": "2020-03-05T15:02:03+00:00" "time": "2020-07-08T12:44:21+00:00"
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
@ -1973,16 +1943,6 @@
} }
], ],
"description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
"funding": [
{
"url": "https://github.com/Ocramius",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/roave/security-advisories",
"type": "tidelift"
}
],
"time": "2020-08-16T05:16:28+00:00" "time": "2020-08-16T05:16:28+00:00"
}, },
{ {
@ -2606,20 +2566,6 @@
], ],
"description": "Symfony Debug Component", "description": "Symfony Debug Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-07-23T08:31:43+00:00" "time": "2020-07-23T08:31:43+00:00"
}, },
{ {
@ -2682,25 +2628,11 @@
"polyfill", "polyfill",
"portable" "portable"
], ],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-07-14T12:35:20+00:00" "time": "2020-07-14T12:35:20+00:00"
}, },
{ {
"name": "symfony/polyfill-php80", "name": "symfony/polyfill-php80",
"version": "v1.18.0", "version": "v1.18.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php80.git", "url": "https://github.com/symfony/polyfill-php80.git",
@ -2762,20 +2694,6 @@
"portable", "portable",
"shim" "shim"
], ],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-07-14T12:35:20+00:00" "time": "2020-07-14T12:35:20+00:00"
}, },
{ {
@ -2826,20 +2744,6 @@
], ],
"description": "Symfony Stopwatch Component", "description": "Symfony Stopwatch Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-05-20T08:37:50+00:00" "time": "2020-05-20T08:37:50+00:00"
}, },
{ {
@ -2899,41 +2803,27 @@
], ],
"description": "Symfony Yaml Component", "description": "Symfony Yaml Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-05-20T08:37:50+00:00" "time": "2020-05-20T08:37:50+00:00"
}, },
{ {
"name": "theseer/tokenizer", "name": "theseer/tokenizer",
"version": "1.1.3", "version": "1.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/theseer/tokenizer.git", "url": "https://github.com/theseer/tokenizer.git",
"reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" "reference": "75a63c33a8577608444246075ea0af0d052e452a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a",
"reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", "reference": "75a63c33a8577608444246075ea0af0d052e452a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-dom": "*", "ext-dom": "*",
"ext-tokenizer": "*", "ext-tokenizer": "*",
"ext-xmlwriter": "*", "ext-xmlwriter": "*",
"php": "^7.0" "php": "^7.2 || ^8.0"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -2953,7 +2843,7 @@
} }
], ],
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
"time": "2019-06-13T22:48:21+00:00" "time": "2020-07-12T23:59:07+00:00"
}, },
{ {
"name": "webmozart/assert", "name": "webmozart/assert",
@ -3026,6 +2916,5 @@
"ext-filter": "*", "ext-filter": "*",
"ext-session": "*" "ext-session": "*"
}, },
"platform-dev": [], "platform-dev": []
"plugin-api-version": "1.1.0"
} }

View File

@ -13,28 +13,29 @@ return array(
'ClassWithBeforeMethod' => $baseDir . '/libs/jsonrpc/tests/ProcedureHandlerTest.php', 'ClassWithBeforeMethod' => $baseDir . '/libs/jsonrpc/tests/ProcedureHandlerTest.php',
'ClientTest' => $baseDir . '/libs/jsonrpc/tests/ClientTest.php', 'ClientTest' => $baseDir . '/libs/jsonrpc/tests/ClientTest.php',
'DummyMiddleware' => $baseDir . '/libs/jsonrpc/tests/ServerTest.php', 'DummyMiddleware' => $baseDir . '/libs/jsonrpc/tests/ServerTest.php',
'Eluceo\\iCal\\Component' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Component.php', 'Eluceo\\iCal\\Component' => $vendorDir . '/eluceo/ical/src/Component.php',
'Eluceo\\iCal\\Component\\Alarm' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Component/Alarm.php', 'Eluceo\\iCal\\Component\\Alarm' => $vendorDir . '/eluceo/ical/src/Component/Alarm.php',
'Eluceo\\iCal\\Component\\Calendar' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Component/Calendar.php', 'Eluceo\\iCal\\Component\\Calendar' => $vendorDir . '/eluceo/ical/src/Component/Calendar.php',
'Eluceo\\iCal\\Component\\Event' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Component/Event.php', 'Eluceo\\iCal\\Component\\Event' => $vendorDir . '/eluceo/ical/src/Component/Event.php',
'Eluceo\\iCal\\Component\\Timezone' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Component/Timezone.php', 'Eluceo\\iCal\\Component\\Timezone' => $vendorDir . '/eluceo/ical/src/Component/Timezone.php',
'Eluceo\\iCal\\Component\\TimezoneRule' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Component/TimezoneRule.php', 'Eluceo\\iCal\\Component\\TimezoneRule' => $vendorDir . '/eluceo/ical/src/Component/TimezoneRule.php',
'Eluceo\\iCal\\ParameterBag' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/ParameterBag.php', 'Eluceo\\iCal\\ParameterBag' => $vendorDir . '/eluceo/ical/src/ParameterBag.php',
'Eluceo\\iCal\\Property' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property.php', 'Eluceo\\iCal\\Property' => $vendorDir . '/eluceo/ical/src/Property.php',
'Eluceo\\iCal\\PropertyBag' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/PropertyBag.php', 'Eluceo\\iCal\\PropertyBag' => $vendorDir . '/eluceo/ical/src/PropertyBag.php',
'Eluceo\\iCal\\Property\\ArrayValue' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/ArrayValue.php', 'Eluceo\\iCal\\Property\\ArrayValue' => $vendorDir . '/eluceo/ical/src/Property/ArrayValue.php',
'Eluceo\\iCal\\Property\\DateTimeProperty' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/DateTimeProperty.php', 'Eluceo\\iCal\\Property\\DateTimeProperty' => $vendorDir . '/eluceo/ical/src/Property/DateTimeProperty.php',
'Eluceo\\iCal\\Property\\DateTimesProperty' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/DateTimesProperty.php', 'Eluceo\\iCal\\Property\\DateTimesProperty' => $vendorDir . '/eluceo/ical/src/Property/DateTimesProperty.php',
'Eluceo\\iCal\\Property\\Event\\Attendees' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/Event/Attendees.php', 'Eluceo\\iCal\\Property\\Event\\Attachment' => $vendorDir . '/eluceo/ical/src/Property/Event/Attachment.php',
'Eluceo\\iCal\\Property\\Event\\Description' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/Event/Description.php', 'Eluceo\\iCal\\Property\\Event\\Attendees' => $vendorDir . '/eluceo/ical/src/Property/Event/Attendees.php',
'Eluceo\\iCal\\Property\\Event\\Organizer' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/Event/Organizer.php', 'Eluceo\\iCal\\Property\\Event\\Geo' => $vendorDir . '/eluceo/ical/src/Property/Event/Geo.php',
'Eluceo\\iCal\\Property\\Event\\RecurrenceId' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/Event/RecurrenceId.php', 'Eluceo\\iCal\\Property\\Event\\Organizer' => $vendorDir . '/eluceo/ical/src/Property/Event/Organizer.php',
'Eluceo\\iCal\\Property\\Event\\RecurrenceRule' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/Event/RecurrenceRule.php', 'Eluceo\\iCal\\Property\\Event\\RecurrenceId' => $vendorDir . '/eluceo/ical/src/Property/Event/RecurrenceId.php',
'Eluceo\\iCal\\Property\\StringValue' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/StringValue.php', 'Eluceo\\iCal\\Property\\Event\\RecurrenceRule' => $vendorDir . '/eluceo/ical/src/Property/Event/RecurrenceRule.php',
'Eluceo\\iCal\\Property\\ValueInterface' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/ValueInterface.php', 'Eluceo\\iCal\\Property\\RawStringValue' => $vendorDir . '/eluceo/ical/src/Property/RawStringValue.php',
'Eluceo\\iCal\\Util\\ComponentUtil' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Util/ComponentUtil.php', 'Eluceo\\iCal\\Property\\StringValue' => $vendorDir . '/eluceo/ical/src/Property/StringValue.php',
'Eluceo\\iCal\\Util\\DateUtil' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Util/DateUtil.php', 'Eluceo\\iCal\\Property\\ValueInterface' => $vendorDir . '/eluceo/ical/src/Property/ValueInterface.php',
'Eluceo\\iCal\\Util\\PropertyValueUtil' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Util/PropertyValueUtil.php', 'Eluceo\\iCal\\Util\\ComponentUtil' => $vendorDir . '/eluceo/ical/src/Util/ComponentUtil.php',
'Eluceo\\iCal\\Util\\DateUtil' => $vendorDir . '/eluceo/ical/src/Util/DateUtil.php',
'FirstMiddleware' => $baseDir . '/libs/jsonrpc/tests/MiddlewareHandlerTest.php', 'FirstMiddleware' => $baseDir . '/libs/jsonrpc/tests/MiddlewareHandlerTest.php',
'Gregwar\\Captcha\\CaptchaBuilder' => $vendorDir . '/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilder.php', 'Gregwar\\Captcha\\CaptchaBuilder' => $vendorDir . '/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilder.php',
'Gregwar\\Captcha\\CaptchaBuilderInterface' => $vendorDir . '/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilderInterface.php', 'Gregwar\\Captcha\\CaptchaBuilderInterface' => $vendorDir . '/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilderInterface.php',

View File

@ -9,6 +9,5 @@ return array(
'Pimple' => array($vendorDir . '/pimple/pimple/src'), 'Pimple' => array($vendorDir . '/pimple/pimple/src'),
'Parsedown' => array($vendorDir . '/erusev/parsedown'), 'Parsedown' => array($vendorDir . '/erusev/parsedown'),
'Otp' => array($vendorDir . '/christian-riesen/otp/src'), 'Otp' => array($vendorDir . '/christian-riesen/otp/src'),
'Eluceo\\iCal' => array($vendorDir . '/eluceo/ical/src'),
'' => array($baseDir . '/libs'), '' => array($baseDir . '/libs'),
); );

View File

@ -16,5 +16,6 @@ return array(
'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
'Kanboard\\' => array($baseDir . '/app'), 'Kanboard\\' => array($baseDir . '/app'),
'Gregwar\\' => array($vendorDir . '/gregwar/captcha/src/Gregwar'), 'Gregwar\\' => array($vendorDir . '/gregwar/captcha/src/Gregwar'),
'Eluceo\\iCal\\' => array($vendorDir . '/eluceo/ical/src'),
'Base32\\' => array($vendorDir . '/christian-riesen/base32/src'), 'Base32\\' => array($vendorDir . '/christian-riesen/base32/src'),
); );

View File

@ -35,6 +35,10 @@ class ComposerStaticInit80f59a55e693f3d5493bcaaa968d1851
array ( array (
'Gregwar\\' => 8, 'Gregwar\\' => 8,
), ),
'E' =>
array (
'Eluceo\\iCal\\' => 12,
),
'B' => 'B' =>
array ( array (
'Base32\\' => 7, 'Base32\\' => 7,
@ -82,6 +86,10 @@ class ComposerStaticInit80f59a55e693f3d5493bcaaa968d1851
array ( array (
0 => __DIR__ . '/..' . '/gregwar/captcha/src/Gregwar', 0 => __DIR__ . '/..' . '/gregwar/captcha/src/Gregwar',
), ),
'Eluceo\\iCal\\' =>
array (
0 => __DIR__ . '/..' . '/eluceo/ical/src',
),
'Base32\\' => 'Base32\\' =>
array ( array (
0 => __DIR__ . '/..' . '/christian-riesen/base32/src', 0 => __DIR__ . '/..' . '/christian-riesen/base32/src',
@ -107,13 +115,6 @@ class ComposerStaticInit80f59a55e693f3d5493bcaaa968d1851
0 => __DIR__ . '/..' . '/christian-riesen/otp/src', 0 => __DIR__ . '/..' . '/christian-riesen/otp/src',
), ),
), ),
'E' =>
array (
'Eluceo\\iCal' =>
array (
0 => __DIR__ . '/..' . '/eluceo/ical/src',
),
),
); );
public static $fallbackDirsPsr0 = array ( public static $fallbackDirsPsr0 = array (
@ -128,28 +129,29 @@ class ComposerStaticInit80f59a55e693f3d5493bcaaa968d1851
'ClassWithBeforeMethod' => __DIR__ . '/../..' . '/libs/jsonrpc/tests/ProcedureHandlerTest.php', 'ClassWithBeforeMethod' => __DIR__ . '/../..' . '/libs/jsonrpc/tests/ProcedureHandlerTest.php',
'ClientTest' => __DIR__ . '/../..' . '/libs/jsonrpc/tests/ClientTest.php', 'ClientTest' => __DIR__ . '/../..' . '/libs/jsonrpc/tests/ClientTest.php',
'DummyMiddleware' => __DIR__ . '/../..' . '/libs/jsonrpc/tests/ServerTest.php', 'DummyMiddleware' => __DIR__ . '/../..' . '/libs/jsonrpc/tests/ServerTest.php',
'Eluceo\\iCal\\Component' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Component.php', 'Eluceo\\iCal\\Component' => __DIR__ . '/..' . '/eluceo/ical/src/Component.php',
'Eluceo\\iCal\\Component\\Alarm' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Component/Alarm.php', 'Eluceo\\iCal\\Component\\Alarm' => __DIR__ . '/..' . '/eluceo/ical/src/Component/Alarm.php',
'Eluceo\\iCal\\Component\\Calendar' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Component/Calendar.php', 'Eluceo\\iCal\\Component\\Calendar' => __DIR__ . '/..' . '/eluceo/ical/src/Component/Calendar.php',
'Eluceo\\iCal\\Component\\Event' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Component/Event.php', 'Eluceo\\iCal\\Component\\Event' => __DIR__ . '/..' . '/eluceo/ical/src/Component/Event.php',
'Eluceo\\iCal\\Component\\Timezone' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Component/Timezone.php', 'Eluceo\\iCal\\Component\\Timezone' => __DIR__ . '/..' . '/eluceo/ical/src/Component/Timezone.php',
'Eluceo\\iCal\\Component\\TimezoneRule' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Component/TimezoneRule.php', 'Eluceo\\iCal\\Component\\TimezoneRule' => __DIR__ . '/..' . '/eluceo/ical/src/Component/TimezoneRule.php',
'Eluceo\\iCal\\ParameterBag' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/ParameterBag.php', 'Eluceo\\iCal\\ParameterBag' => __DIR__ . '/..' . '/eluceo/ical/src/ParameterBag.php',
'Eluceo\\iCal\\Property' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Property.php', 'Eluceo\\iCal\\Property' => __DIR__ . '/..' . '/eluceo/ical/src/Property.php',
'Eluceo\\iCal\\PropertyBag' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/PropertyBag.php', 'Eluceo\\iCal\\PropertyBag' => __DIR__ . '/..' . '/eluceo/ical/src/PropertyBag.php',
'Eluceo\\iCal\\Property\\ArrayValue' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Property/ArrayValue.php', 'Eluceo\\iCal\\Property\\ArrayValue' => __DIR__ . '/..' . '/eluceo/ical/src/Property/ArrayValue.php',
'Eluceo\\iCal\\Property\\DateTimeProperty' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Property/DateTimeProperty.php', 'Eluceo\\iCal\\Property\\DateTimeProperty' => __DIR__ . '/..' . '/eluceo/ical/src/Property/DateTimeProperty.php',
'Eluceo\\iCal\\Property\\DateTimesProperty' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Property/DateTimesProperty.php', 'Eluceo\\iCal\\Property\\DateTimesProperty' => __DIR__ . '/..' . '/eluceo/ical/src/Property/DateTimesProperty.php',
'Eluceo\\iCal\\Property\\Event\\Attendees' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Property/Event/Attendees.php', 'Eluceo\\iCal\\Property\\Event\\Attachment' => __DIR__ . '/..' . '/eluceo/ical/src/Property/Event/Attachment.php',
'Eluceo\\iCal\\Property\\Event\\Description' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Property/Event/Description.php', 'Eluceo\\iCal\\Property\\Event\\Attendees' => __DIR__ . '/..' . '/eluceo/ical/src/Property/Event/Attendees.php',
'Eluceo\\iCal\\Property\\Event\\Organizer' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Property/Event/Organizer.php', 'Eluceo\\iCal\\Property\\Event\\Geo' => __DIR__ . '/..' . '/eluceo/ical/src/Property/Event/Geo.php',
'Eluceo\\iCal\\Property\\Event\\RecurrenceId' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Property/Event/RecurrenceId.php', 'Eluceo\\iCal\\Property\\Event\\Organizer' => __DIR__ . '/..' . '/eluceo/ical/src/Property/Event/Organizer.php',
'Eluceo\\iCal\\Property\\Event\\RecurrenceRule' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Property/Event/RecurrenceRule.php', 'Eluceo\\iCal\\Property\\Event\\RecurrenceId' => __DIR__ . '/..' . '/eluceo/ical/src/Property/Event/RecurrenceId.php',
'Eluceo\\iCal\\Property\\StringValue' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Property/StringValue.php', 'Eluceo\\iCal\\Property\\Event\\RecurrenceRule' => __DIR__ . '/..' . '/eluceo/ical/src/Property/Event/RecurrenceRule.php',
'Eluceo\\iCal\\Property\\ValueInterface' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Property/ValueInterface.php', 'Eluceo\\iCal\\Property\\RawStringValue' => __DIR__ . '/..' . '/eluceo/ical/src/Property/RawStringValue.php',
'Eluceo\\iCal\\Util\\ComponentUtil' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Util/ComponentUtil.php', 'Eluceo\\iCal\\Property\\StringValue' => __DIR__ . '/..' . '/eluceo/ical/src/Property/StringValue.php',
'Eluceo\\iCal\\Util\\DateUtil' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Util/DateUtil.php', 'Eluceo\\iCal\\Property\\ValueInterface' => __DIR__ . '/..' . '/eluceo/ical/src/Property/ValueInterface.php',
'Eluceo\\iCal\\Util\\PropertyValueUtil' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Util/PropertyValueUtil.php', 'Eluceo\\iCal\\Util\\ComponentUtil' => __DIR__ . '/..' . '/eluceo/ical/src/Util/ComponentUtil.php',
'Eluceo\\iCal\\Util\\DateUtil' => __DIR__ . '/..' . '/eluceo/ical/src/Util/DateUtil.php',
'FirstMiddleware' => __DIR__ . '/../..' . '/libs/jsonrpc/tests/MiddlewareHandlerTest.php', 'FirstMiddleware' => __DIR__ . '/../..' . '/libs/jsonrpc/tests/MiddlewareHandlerTest.php',
'Gregwar\\Captcha\\CaptchaBuilder' => __DIR__ . '/..' . '/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilder.php', 'Gregwar\\Captcha\\CaptchaBuilder' => __DIR__ . '/..' . '/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilder.php',
'Gregwar\\Captcha\\CaptchaBuilderInterface' => __DIR__ . '/..' . '/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilderInterface.php', 'Gregwar\\Captcha\\CaptchaBuilderInterface' => __DIR__ . '/..' . '/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilderInterface.php',

View File

@ -111,31 +111,34 @@
}, },
{ {
"name": "eluceo/ical", "name": "eluceo/ical",
"version": "0.10.1", "version": "0.16.0",
"version_normalized": "0.10.1.0", "version_normalized": "0.16.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/markuspoerschke/iCal.git", "url": "https://github.com/markuspoerschke/iCal.git",
"reference": "2dd99c12c0aa961c541380ab0c113135e14af33e" "reference": "97da0d94c9716e65c141066a2d96aa098379721b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/markuspoerschke/iCal/zipball/2dd99c12c0aa961c541380ab0c113135e14af33e", "url": "https://api.github.com/repos/markuspoerschke/iCal/zipball/97da0d94c9716e65c141066a2d96aa098379721b",
"reference": "2dd99c12c0aa961c541380ab0c113135e14af33e", "reference": "97da0d94c9716e65c141066a2d96aa098379721b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.0" "php": ">=7.1"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "~4.3" "phpunit/phpunit": "^7.0"
}, },
"time": "2016-06-09T09:08:55+00:00", "suggest": {
"ext-mbstring": "Massive performance enhancement of line folding"
},
"time": "2019-12-29T22:08:56+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
"psr-0": { "psr-4": {
"Eluceo\\iCal": "src/" "Eluceo\\iCal\\": "src/"
} }
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
@ -143,18 +146,13 @@
"MIT" "MIT"
], ],
"authors": [ "authors": [
{
"name": "Maciej Łebkowski",
"email": "m.lebkowski@gmail.com",
"role": "Contributor"
},
{ {
"name": "Markus Poerschke", "name": "Markus Poerschke",
"email": "markus@eluceo.de", "email": "markus@eluceo.de",
"role": "Developer" "role": "Developer"
} }
], ],
"description": "The eluceo/iCal package offers a abstraction layer for creating iCalendars. You can easily create iCal files by using PHP object instead of typing your *.ics file by hand. The output will follow RFC 2445 as best as possible.", "description": "The eluceo/iCal package offers a abstraction layer for creating iCalendars. You can easily create iCal files by using PHP object instead of typing your *.ics file by hand. The output will follow RFC 5545 as best as possible.",
"homepage": "https://github.com/markuspoerschke/iCal", "homepage": "https://github.com/markuspoerschke/iCal",
"keywords": [ "keywords": [
"calendar", "calendar",
@ -599,21 +597,21 @@
}, },
{ {
"name": "symfony/contracts", "name": "symfony/contracts",
"version": "v1.1.8", "version": "v1.1.9",
"version_normalized": "1.1.8.0", "version_normalized": "1.1.9.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/contracts.git", "url": "https://github.com/symfony/contracts.git",
"reference": "f51bca9de06b7a25b19a4155da7bebad099a5def" "reference": "8c4de0cf797f2eba4334a1d7a9b788c1b30a7579"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/contracts/zipball/f51bca9de06b7a25b19a4155da7bebad099a5def", "url": "https://api.github.com/repos/symfony/contracts/zipball/8c4de0cf797f2eba4334a1d7a9b788c1b30a7579",
"reference": "f51bca9de06b7a25b19a4155da7bebad099a5def", "reference": "8c4de0cf797f2eba4334a1d7a9b788c1b30a7579",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.1.3", "php": ">=7.1.3",
"psr/cache": "^1.0", "psr/cache": "^1.0",
"psr/container": "^1.0" "psr/container": "^1.0"
}, },
@ -635,7 +633,7 @@
"symfony/service-implementation": "", "symfony/service-implementation": "",
"symfony/translation-implementation": "" "symfony/translation-implementation": ""
}, },
"time": "2019-11-07T12:44:51+00:00", "time": "2020-07-29T14:46:19+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
@ -794,17 +792,17 @@
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.17.0", "version": "v1.18.1",
"version_normalized": "1.17.0.0", "version_normalized": "1.18.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git", "url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "fa79b11539418b02fc5e1897267673ba2c19419c" "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/a6977d63bf9a0ad4c65cd352709e230876f9904a",
"reference": "fa79b11539418b02fc5e1897267673ba2c19419c", "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -813,11 +811,15 @@
"suggest": { "suggest": {
"ext-mbstring": "For best performance" "ext-mbstring": "For best performance"
}, },
"time": "2020-05-12T16:47:27+00:00", "time": "2020-07-14T12:35:20+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.17-dev" "dev-master": "1.18-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
} }
}, },
"installation-source": "dist", "installation-source": "dist",

View File

@ -1,3 +0,0 @@
vendor
composer.lock
bin

View File

@ -1,26 +0,0 @@
<?php
Symfony\CS\Fixer\Contrib\HeaderCommentFixer::setHeader(<<<EOF
This file is part of the eluceo/iCal package.
(c) Markus Poerschke <markus@eluceo.de>
This source file is subject to the MIT license that is bundled
with this source code in the file LICENSE.
EOF
);
$finder = Symfony\CS\Finder\DefaultFinder::create();
$finder->in(__DIR__ . '/src');
return Symfony\CS\Config\Config::create()
->fixers(array(
'header_comment',
'concat_with_spaces',
'align_equals',
'align_double_arrow',
'unused_use',
'long_array_syntax',
))
->finder($finder)
;

View File

@ -1,20 +0,0 @@
filter:
excluded_paths:
- tests/*
tools:
php_cs_fixer: true
php_code_sniffer:
config:
standard: PSR2
php_mess_detector: true
php_analyzer: true
sensiolabs_security_checker: true
external_code_coverage:
timeout: 300
runs: 1
checks:
php:
code_rating: true
duplication: true

View File

@ -1,19 +0,0 @@
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
- hhvm
before_script:
- composer self-update
- composer install
script: ./bin/phpunit --coverage-clover=coverage.clover
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover

View File

@ -1,31 +0,0 @@
# Change Log
All notable changes to this project will be documented in this file.
## [0.10.1] - 2016-05-09
### Fixed
- Problem with GEO property when importing into Google Calendar [#74](https://github.com/markuspoerschke/iCal/pull/74)
## [0.10.0] - 2016-04-26
### Changed
- Use 'escapeValue' to escape the new line character. [#60](https://github.com/markuspoerschke/iCal/pull/60)
- Order components by type when building ical file. [#65](https://github.com/markuspoerschke/iCal/pull/65)
### Added
- X-ALT-DESC for HTML types with new descriptionHTML field. [#55](https://github.com/markuspoerschke/iCal/pull/55)
- Added a property and setter for calendar color. [#68](https://github.com/markuspoerschke/iCal/pull/68)
- Write also GEO property if geo location is given. [#66](https://github.com/markuspoerschke/iCal/pull/66)
## [0.9.0] - 2015-11-13
### Added
- CHANGELOG.md based on [Keep a CHANGELOG](https://github.com/olivierlacan/keep-a-changelog)
- Support event properties EXDATE and RECURRENCE-ID [#50](https://github.com/markuspoerschke/iCal/pull/53)
### Changed
- Allow new lines in event descriptions [#53](https://github.com/markuspoerschke/iCal/pull/53)
- **Breaking Change:** Changed signature of the ```Event::setOrganizer``` method. Now there is is only one parameter that must be an instance of ```Property\Organizer```.
- Updated install section in README.md [#54](https://github.com/markuspoerschke/iCal/pull/53)
[Unreleased]: https://github.com/markuspoerschke/iCal/compare/0.10.1...HEAD
[0.10.1]: https://github.com/markuspoerschke/iCal/compare/0.10.0...0.10.1
[0.10.0]: https://github.com/markuspoerschke/iCal/compare/0.9.0...0.10.0
[0.9.0]: https://github.com/markuspoerschke/iCal/compare/0.8.0...0.9.0

View File

@ -1,4 +1,4 @@
Copyright (c) 2012-2015 Markus Poerschke Copyright (c) 2012-2019 Markus Poerschke
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,158 +0,0 @@
# eluceo — iCal
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/markuspoerschke/iCal/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/markuspoerschke/iCal/?branch=master) [![Code Coverage](https://scrutinizer-ci.com/g/markuspoerschke/iCal/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/markuspoerschke/iCal/?branch=master) [![Build Status](https://travis-ci.org/markuspoerschke/iCal.svg?branch=master)](https://travis-ci.org/markuspoerschke/iCal)
This package offers a abstraction layer for creating iCalendars. The output will
follow [RFC 5545](http://www.ietf.org/rfc/rfc5545.txt) as best as possible.
The following components are supported at this time:
* VCALENDAR
* VEVENT
* VALARM
* VTIMEZONE
## Installation
You can install this package by using [Composer](http://getcomposer.org), running this command:
```sh
composer require eluceo/ical
```
Link to Packagist: https://packagist.org/packages/eluceo/ical
## Usage
### Basic Usage
#### 1. Create a Calendar object
```PHP
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
```
#### 2. Create an Event object
```PHP
$vEvent = new \Eluceo\iCal\Component\Event();
```
#### 3. Add your information to the Event
```PHP
$vEvent
->setDtStart(new \DateTime('2012-12-24'))
->setDtEnd(new \DateTime('2012-12-24'))
->setNoTime(true)
->setSummary('Christmas')
;
```
#### 4. Add Event to Calendar
```PHP
$vCalendar->addComponent($vEvent);
```
#### 5. Set HTTP-headers
```PHP
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
```
#### 6. Send output
```PHP
echo $vCalendar->render();
```
### Timezone support
This package supports three different types of handling timezones:
#### 1. UTC (default)
In the default setting, UTC/GMT will be used as Timezone. The time will be formated as following:
```
DTSTART:20121224T180000Z
```
#### 2. Use explicit timezone
You can use an explicit timezone by calling `$vEvent->setUseTimezone(true);`. The timezone of your
`\DateTime` object will be used. In this case the non-standard field "X-WR-TIMEZONE" will be used.
Be awre that this is a simple solution which is not supported by all calendar clients.
The output will be as following:
```
DTSTART;TZID=Europe/Berlin:20121224T180000
```
#### 3. Use explicit timezone with definition
You can use an explicit timezone and define it using `Timezone()` and `TimezoneRule()` (see example5.php).
The timezone of your `\DateTime` object will be used. The output will be as following:
```
BEGIN:VTIMEZONE
TZID:Europe/Berlin
X-LIC-LOCATION:Europe/Berlin
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
DTSTART:19810329T030000
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
DTSTART:19961027T030000
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=10;BYDAY=-1SU
END:STANDARD
END:VTIMEZONE
...
DTSTART;TZID=Europe/Berlin:20121224T180000
```
#### 4. Use locale time
You can use local time by calling `$vEvent->setUseUtc(false);`. The output will be:
```
DTSTART:20121224T180000
```
## Running the tests
To setup and run tests:
- go to the root directory of this project
- download composer: `wget https://getcomposer.org/composer.phar`
- install dev dependencies: `php composer.phar install --dev`
- run `./bin/phpunit`
## License
This package is released under the __MIT license__.
Copyright (c) 2012-2015 Markus Poerschke
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,9 +0,0 @@
# v0.8.0 -> v0.9.0
- The signature of the ```Event::setOrganizer``` method was changed:
Now there is is only one parameter that must be an instance of ```Property\Organizer```.
# v0.7.0 -> v0.8.0
- The signature of the ```Event::setOrganizer``` method was changed: Now there are
two parameters name and email instead of an already formatted string.

View File

@ -1,6 +1,6 @@
{ {
"name": "eluceo/ical", "name": "eluceo/ical",
"description": "The eluceo/iCal package offers a abstraction layer for creating iCalendars. You can easily create iCal files by using PHP object instead of typing your *.ics file by hand. The output will follow RFC 2445 as best as possible.", "description": "The eluceo/iCal package offers a abstraction layer for creating iCalendars. You can easily create iCal files by using PHP object instead of typing your *.ics file by hand. The output will follow RFC 5545 as best as possible.",
"license": "MIT", "license": "MIT",
"homepage": "https://github.com/markuspoerschke/iCal", "homepage": "https://github.com/markuspoerschke/iCal",
"authors": [ "authors": [
@ -8,11 +8,6 @@
"name": "Markus Poerschke", "name": "Markus Poerschke",
"email": "markus@eluceo.de", "email": "markus@eluceo.de",
"role": "Developer" "role": "Developer"
},
{
"name": "Maciej Łebkowski",
"email": "m.lebkowski@gmail.com",
"role": "Contributor"
} }
], ],
"keywords": [ "keywords": [
@ -27,17 +22,25 @@
"source": "https://github.com/markuspoerschke/iCal" "source": "https://github.com/markuspoerschke/iCal"
}, },
"autoload": { "autoload": {
"psr-0": { "psr-4": {
"Eluceo\\iCal": "src/" "Eluceo\\iCal\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Eluceo\\iCal\\": "tests/"
} }
}, },
"require": { "require": {
"php": ">=5.3.0" "php": ">=7.1"
},
"suggest": {
"ext-mbstring" : "Massive performance enhancement of line folding"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "~4.3" "phpunit/phpunit": "^7.0"
}, },
"config": { "scripts": {
"bin-dir": "bin" "test": "phpunit"
} }
} }

View File

@ -1,30 +0,0 @@
<?php
// use composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// set default timezone (PHP 5.4)
date_default_timezone_set('Europe/Berlin');
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-12-24'));
$vEvent->setDtEnd(new \DateTime('2012-12-24'));
$vEvent->setNoTime(true);
$vEvent->setSummary('Christmas');
// Adding Timezone (optional)
$vEvent->setUseTimezone(true);
// 3. Add event to calendar
$vCalendar->addComponent($vEvent);
// 4. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
// 5. Output
echo $vCalendar->render();

View File

@ -1,31 +0,0 @@
<?php
// use composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// set default timezone (PHP 5.4)
date_default_timezone_set('Europe/Berlin');
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-12-24'));
$vEvent->setDtEnd(new \DateTime('2012-12-24'));
$vEvent->setNoTime(true);
$vEvent->setSummary('Summary with some german "umlauten" and a backslash \\: Kinder mögen Äpfel pflücken.');
$vEvent->setCategories(['holidays']);
// Adding Timezone (optional)
$vEvent->setUseTimezone(true);
// 3. Add event to calendar
$vCalendar->addComponent($vEvent);
// 4. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
// 5. Output
echo $vCalendar->render();

View File

@ -1,36 +0,0 @@
<?php
// use composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// set default timezone (PHP 5.4)
date_default_timezone_set('Europe/Berlin');
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-12-31'));
$vEvent->setDtEnd(new \DateTime('2012-12-31'));
$vEvent->setNoTime(true);
$vEvent->setSummary('New Years Eve');
// Set recurrence rule
$recurrenceRule = new \Eluceo\iCal\Property\Event\RecurrenceRule();
$recurrenceRule->setFreq(\Eluceo\iCal\Property\Event\RecurrenceRule::FREQ_YEARLY);
$recurrenceRule->setInterval(1);
$vEvent->setRecurrenceRule($recurrenceRule);
// Adding Timezone (optional)
$vEvent->setUseTimezone(true);
// 3. Add event to calendar
$vCalendar->addComponent($vEvent);
// 4. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
// 5. Output
echo $vCalendar->render();

View File

@ -1,35 +0,0 @@
<?php
// use composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// set default timezone (PHP 5.4)
date_default_timezone_set('Europe/Berlin');
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-11-11 13:00:00'));
$vEvent->setDtEnd(new \DateTime('2012-11-11 14:30:00'));
$vEvent->setSummary('Weekly lunch with Markus');
// Set recurrence rule
$recurrenceRule = new \Eluceo\iCal\Property\Event\RecurrenceRule();
$recurrenceRule->setFreq(\Eluceo\iCal\Property\Event\RecurrenceRule::FREQ_WEEKLY);
$recurrenceRule->setInterval(1);
$vEvent->setRecurrenceRule($recurrenceRule);
// Adding Timezone (optional)
$vEvent->setUseTimezone(true);
// 3. Add event to calendar
$vCalendar->addComponent($vEvent);
// 4. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
// 5. Output
echo $vCalendar->render();

View File

@ -1,66 +0,0 @@
<?php
/**
* example to show how to create an ICal calendar which
* provides a full timezone definition
*/
// use composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// set default timezone (PHP 5.4)
$tz = 'Europe/Berlin';
$dtz = new \DateTimeZone($tz);
date_default_timezone_set($tz);
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create timezone rule object for Daylight Saving Time
$vTimezoneRuleDst = new \Eluceo\iCal\Component\TimezoneRule(\Eluceo\iCal\Component\TimezoneRule::TYPE_DAYLIGHT);
$vTimezoneRuleDst->setTzName('CEST');
$vTimezoneRuleDst->setDtStart(new \DateTime('1981-03-29 02:00:00', $dtz));
$vTimezoneRuleDst->setTzOffsetFrom('+0100');
$vTimezoneRuleDst->setTzOffsetTo('+0200');
$dstRecurrenceRule = new \Eluceo\iCal\Property\Event\RecurrenceRule();
$dstRecurrenceRule->setFreq(\Eluceo\iCal\Property\Event\RecurrenceRule::FREQ_YEARLY);
$dstRecurrenceRule->setByMonth(3);
$dstRecurrenceRule->setByDay('-1SU');
$vTimezoneRuleDst->setRecurrenceRule($dstRecurrenceRule);
// 3. Create timezone rule object for Standard Time
$vTimezoneRuleStd = new \Eluceo\iCal\Component\TimezoneRule(\Eluceo\iCal\Component\TimezoneRule::TYPE_STANDARD);
$vTimezoneRuleStd->setTzName('CET');
$vTimezoneRuleStd->setDtStart(new \DateTime('1996-10-27 03:00:00', $dtz));
$vTimezoneRuleStd->setTzOffsetFrom('+0200');
$vTimezoneRuleStd->setTzOffsetTo('+0100');
$stdRecurrenceRule = new \Eluceo\iCal\Property\Event\RecurrenceRule();
$stdRecurrenceRule->setFreq(\Eluceo\iCal\Property\Event\RecurrenceRule::FREQ_YEARLY);
$stdRecurrenceRule->setByMonth(10);
$stdRecurrenceRule->setByDay('-1SU');
$vTimezoneRuleStd->setRecurrenceRule($stdRecurrenceRule);
// 4. Create timezone definition and add rules
$vTimezone = new \Eluceo\iCal\Component\Timezone($tz);
$vTimezone->addComponent($vTimezoneRuleDst);
$vTimezone->addComponent($vTimezoneRuleStd);
$vCalendar->setTimezone($vTimezone);
// 5. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-12-24', $dtz));
$vEvent->setDtEnd(new \DateTime('2012-12-24', $dtz));
$vEvent->setSummary('Summary with some german "umlauten" and a backslash \\: Kinder mögen Äpfel pflücken.');
// 6. Adding Timezone
$vEvent->setUseTimezone(true);
// 7. Add event to calendar
$vCalendar->addComponent($vEvent);
// 8. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
// 9. Output
echo $vCalendar->render();

View File

@ -1,30 +0,0 @@
<?php
// use composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// set default timezone (PHP 5.4)
date_default_timezone_set('Europe/Berlin');
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-12-24'));
$vEvent->setDtEnd(new \DateTime('2012-12-24'));
$vEvent->setNoTime(true);
$vEvent->setSummary('Christmas');
// add some location information for apple devices
$vEvent->setLocation("Infinite Loop\nCupertino CA 95014", 'Infinite Loop', '37.332095,-122.030743');
// 3. Add event to calendar
$vCalendar->addComponent($vEvent);
// 4. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
// 5. Output
echo $vCalendar->render();

View File

@ -1,33 +0,0 @@
<?php
// use composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// set default timezone (PHP 5.4)
date_default_timezone_set('Europe/Berlin');
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-12-24'));
$vEvent->setDtEnd(new \DateTime('2012-12-24'));
$vEvent->setNoTime(true);
$vEvent->setSummary('Christmas');
$vEvent->setDescription('Happy Christmas!');
$vEvent->setDescriptionHTML('<b>Happy Christmas!</b>');
// add some location information for apple devices
$vEvent->setLocation("Infinite Loop\nCupertino CA 95014", 'Infinite Loop', '37.332095,-122.030743');
// 3. Add event to calendar
$vCalendar->addComponent($vEvent);
// 4. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
// 5. Output
echo $vCalendar->render();

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="./vendor/autoload.php">
<logging>
<log type="coverage-text" target="php://stdout" showUncoveredFiles="true" showOnlySummary="true"/>
</logging>
<testsuites>
<testsuite name="eluceo iCal Test Suite">
<directory suffix="Test.php">./tests/Eluceo/iCal/</directory>
</testsuite>
</testsuites>
</phpunit>

View File

@ -23,7 +23,7 @@ abstract class Component
* *
* @var Component[] * @var Component[]
*/ */
protected $components = array(); protected $components = [];
/** /**
* The order in which the components will be rendered during build. * The order in which the components will be rendered during build.
@ -32,7 +32,7 @@ abstract class Component
* *
* @var array * @var array
*/ */
private $componentsBuildOrder = array('VTIMEZONE', 'DAYLIGHT', 'STANDARD'); private $componentsBuildOrder = ['VTIMEZONE', 'DAYLIGHT', 'STANDARD'];
/** /**
* The type of the concrete Component. * The type of the concrete Component.
@ -60,7 +60,7 @@ abstract class Component
* @param Component $component The Component that will be added * @param Component $component The Component that will be added
* @param null $key The key of the Component * @param null $key The key of the Component
*/ */
public function addComponent(Component $component, $key = null) public function addComponent(self $component, $key = null)
{ {
if (null == $key) { if (null == $key) {
$this->components[] = $component; $this->components[] = $component;
@ -69,6 +69,19 @@ abstract class Component
} }
} }
/**
* Set all Components.
*
* @param Component[] $components The array of Component that will be set
* @param null $key The key of the Component
*/
public function setComponents(array $components)
{
$this->components = $components;
return $this;
}
/** /**
* Renders an array containing the lines of the iCal file. * Renders an array containing the lines of the iCal file.
* *
@ -76,7 +89,7 @@ abstract class Component
*/ */
public function build() public function build()
{ {
$lines = array(); $lines = [];
$lines[] = sprintf('BEGIN:%s', $this->getType()); $lines[] = sprintf('BEGIN:%s', $this->getType());
@ -91,7 +104,7 @@ abstract class Component
$lines[] = sprintf('END:%s', $this->getType()); $lines[] = sprintf('END:%s', $this->getType());
$ret = array(); $ret = [];
foreach ($lines as $line) { foreach ($lines as $line) {
foreach (ComponentUtil::fold($line) as $l) { foreach (ComponentUtil::fold($line) as $l) {
@ -129,13 +142,13 @@ abstract class Component
*/ */
private function buildComponents(array &$lines) private function buildComponents(array &$lines)
{ {
$componentsByType = array(); $componentsByType = [];
/** @var $component Component */ /** @var $component Component */
foreach ($this->components as $component) { foreach ($this->components as $component) {
$type = $component->getType(); $type = $component->getType();
if (!isset($componentsByType[$type])) { if (!isset($componentsByType[$type])) {
$componentsByType[$type] = array(); $componentsByType[$type] = [];
} }
$componentsByType[$type][] = $component; $componentsByType[$type][] = $component;
} }
@ -160,10 +173,9 @@ abstract class Component
} }
/** /**
* @param array $lines
* @param Component $component * @param Component $component
*/ */
private function addComponentLines(array &$lines, Component $component) private function addComponentLines(array &$lines, self $component)
{ {
foreach ($component->build() as $l) { foreach ($component->build() as $l) {
$lines[] = $l; $lines[] = $l;

View File

@ -13,7 +13,6 @@ namespace Eluceo\iCal\Component;
use Eluceo\iCal\Component; use Eluceo\iCal\Component;
use Eluceo\iCal\PropertyBag; use Eluceo\iCal\PropertyBag;
use Eluceo\iCal\Property;
/** /**
* Implementation of the VALARM component. * Implementation of the VALARM component.
@ -25,11 +24,11 @@ class Alarm extends Component
* *
* According to RFC 5545: 3.8.6.1. Action * According to RFC 5545: 3.8.6.1. Action
* *
* @link http://tools.ietf.org/html/rfc5545#section-3.8.6.1 * @see http://tools.ietf.org/html/rfc5545#section-3.8.6.1
*/ */
const ACTION_AUDIO = 'AUDIO'; const ACTION_AUDIO = 'AUDIO';
const ACTION_DISPLAY = 'DISPLAY'; const ACTION_DISPLAY = 'DISPLAY';
const ACTION_EMAIL = 'EMAIL'; const ACTION_EMAIL = 'EMAIL';
protected $action; protected $action;
protected $repeat; protected $repeat;

View File

@ -19,20 +19,20 @@ class Calendar extends Component
/** /**
* Methods for calendar components. * Methods for calendar components.
* *
* According to RFP 5545: 3.7.2. Method * According to RFC 5545: 3.7.2. Method
* *
* @link http://tools.ietf.org/html/rfc5545#section-3.7.2 * @see http://tools.ietf.org/html/rfc5545#section-3.7.2
* *
* And then according to RFC 2446: 3 APPLICATION PROTOCOL ELEMENTS * And then according to RFC 2446: 3 APPLICATION PROTOCOL ELEMENTS
* @link https://www.ietf.org/rfc/rfc2446.txt * @see https://tools.ietf.org/html/rfc2446#section-3.2
*/ */
const METHOD_PUBLISH = 'PUBLISH'; const METHOD_PUBLISH = 'PUBLISH';
const METHOD_REQUEST = 'REQUEST'; const METHOD_REQUEST = 'REQUEST';
const METHOD_REPLY = 'REPLY'; const METHOD_REPLY = 'REPLY';
const METHOD_ADD = 'ADD'; const METHOD_ADD = 'ADD';
const METHOD_CANCEL = 'CANCEL'; const METHOD_CANCEL = 'CANCEL';
const METHOD_REFRESH = 'REFRESH'; const METHOD_REFRESH = 'REFRESH';
const METHOD_COUNTER = 'COUNTER'; const METHOD_COUNTER = 'COUNTER';
const METHOD_DECLINECOUNTER = 'DECLINECOUNTER'; const METHOD_DECLINECOUNTER = 'DECLINECOUNTER';
/** /**
@ -40,26 +40,26 @@ class Calendar extends Component
* *
* According to RFC 5545: 3.7.1. Calendar Scale * According to RFC 5545: 3.7.1. Calendar Scale
* *
* @link http://tools.ietf.org/html/rfc5545#section-3.7 * @see http://tools.ietf.org/html/rfc5545#section-3.7
*/ */
const CALSCALE_GREGORIAN = 'GREGORIAN'; const CALSCALE_GREGORIAN = 'GREGORIAN';
/** /**
* The Product Identifier. * The Product Identifier.
* *
* According to RFC 2445: 4.7.3 Product Identifier * According to RFC 5545: 3.7.3 Product Identifier
* *
* This property specifies the identifier for the product that created the Calendar object. * This property specifies the identifier for the product that created the Calendar object.
* *
* @link http://www.ietf.org/rfc/rfc2445.txt * @see https://tools.ietf.org/html/rfc5545#section-3.7.3
* *
* @var string * @var string
*/ */
protected $prodId = null; protected $prodId = null;
protected $method = null; protected $method = null;
protected $name = null; protected $name = null;
protected $description = null; protected $description = null;
protected $timezone = null; protected $timezone = null;
/** /**
* This property defines the calendar scale used for the * This property defines the calendar scale used for the
@ -96,11 +96,14 @@ class Calendar extends Component
* Specifies a suggested iCalendar file download frequency for clients and * Specifies a suggested iCalendar file download frequency for clients and
* servers with sync capabilities. * servers with sync capabilities.
* *
* For example you can set the value to 'P1W' if the calendar should be
* synced once a week. Use 'P3H' to sync the file every 3 hours.
*
* @var string * @var string
* *
* @see http://msdn.microsoft.com/en-us/library/ee178699(v=exchg.80).aspx * @see http://msdn.microsoft.com/en-us/library/ee178699(v=exchg.80).aspx
*/ */
protected $publishedTTL = 'P1W'; protected $publishedTTL = null;
/** /**
* Specifies a color for the calendar in calendar for Apple/Outlook. * Specifies a color for the calendar in calendar for Apple/Outlook.
@ -300,8 +303,6 @@ class Calendar extends Component
* *
* @see Eluceo\iCal::addComponent * @see Eluceo\iCal::addComponent
* @deprecated Please, use public method addComponent() from abstract Component class * @deprecated Please, use public method addComponent() from abstract Component class
*
* @param Event $event
*/ */
public function addEvent(Event $event) public function addEvent(Event $event)
{ {
@ -309,7 +310,7 @@ class Calendar extends Component
} }
/** /**
* @return null|string * @return string|null
*/ */
public function getProdId() public function getProdId()
{ {

View File

@ -14,26 +14,33 @@ namespace Eluceo\iCal\Component;
use Eluceo\iCal\Component; use Eluceo\iCal\Component;
use Eluceo\iCal\Property; use Eluceo\iCal\Property;
use Eluceo\iCal\Property\DateTimeProperty; use Eluceo\iCal\Property\DateTimeProperty;
use Eluceo\iCal\Property\Event\Attendees;
use Eluceo\iCal\Property\Event\Organizer;
use Eluceo\iCal\Property\Event\RecurrenceRule;
use Eluceo\iCal\Property\Event\Description;
use Eluceo\iCal\PropertyBag;
use Eluceo\iCal\Property\Event\RecurrenceId;
use Eluceo\iCal\Property\DateTimesProperty; use Eluceo\iCal\Property\DateTimesProperty;
use Eluceo\iCal\Property\Event\Attachment;
use Eluceo\iCal\Property\Event\Attendees;
use Eluceo\iCal\Property\Event\Geo;
use Eluceo\iCal\Property\Event\Organizer;
use Eluceo\iCal\Property\Event\RecurrenceId;
use Eluceo\iCal\Property\Event\RecurrenceRule;
use Eluceo\iCal\Property\RawStringValue;
use Eluceo\iCal\PropertyBag;
/** /**
* Implementation of the EVENT component. * Implementation of the EVENT component.
*/ */
class Event extends Component class Event extends Component
{ {
const TIME_TRANSPARENCY_OPAQUE = 'OPAQUE'; const TIME_TRANSPARENCY_OPAQUE = 'OPAQUE';
const TIME_TRANSPARENCY_TRANSPARENT = 'TRANSPARENT'; const TIME_TRANSPARENCY_TRANSPARENT = 'TRANSPARENT';
const STATUS_TENTATIVE = 'TENTATIVE'; const STATUS_TENTATIVE = 'TENTATIVE';
const STATUS_CONFIRMED = 'CONFIRMED'; const STATUS_CONFIRMED = 'CONFIRMED';
const STATUS_CANCELLED = 'CANCELLED'; const STATUS_CANCELLED = 'CANCELLED';
const MS_BUSYSTATUS_FREE = 'FREE';
const MS_BUSYSTATUS_TENTATIVE = 'TENTATIVE';
const MS_BUSYSTATUS_BUSY = 'BUSY';
const MS_BUSYSTATUS_OOF = 'OOF';
/** /**
* @var string * @var string
*/ */
@ -71,6 +78,11 @@ class Event extends Component
*/ */
protected $noTime = false; protected $noTime = false;
/**
* @var string
*/
protected $msBusyStatus = null;
/** /**
* @var string * @var string
*/ */
@ -87,7 +99,7 @@ class Event extends Component
protected $locationTitle; protected $locationTitle;
/** /**
* @var string * @var Geo
*/ */
protected $locationGeo; protected $locationGeo;
@ -102,7 +114,7 @@ class Event extends Component
protected $organizer; protected $organizer;
/** /**
* @see http://www.ietf.org/rfc/rfc2445.txt 4.8.2.7 Time Transparency * @see https://tools.ietf.org/html/rfc5545#section-3.8.2.7
* *
* @var string * @var string
*/ */
@ -115,6 +127,13 @@ class Event extends Component
*/ */
protected $useTimezone = false; protected $useTimezone = false;
/**
* If set will be used as the timezone identifier.
*
* @var string
*/
protected $timezoneString = '';
/** /**
* @var int * @var int
*/ */
@ -145,6 +164,11 @@ class Event extends Component
*/ */
protected $recurrenceRule; protected $recurrenceRule;
/**
* @var array
*/
protected $recurrenceRules = [];
/** /**
* This property specifies the date and time that the calendar * This property specifies the date and time that the calendar
* information was created. * information was created.
@ -198,22 +222,28 @@ class Event extends Component
/** /**
* Dates to be excluded from a series of events. * Dates to be excluded from a series of events.
* *
* @var \DateTime[] * @var \DateTimeInterface[]
*/ */
protected $exDates = array(); protected $exDates = [];
/** /**
* @var RecurrenceId * @var RecurrenceId
*/ */
protected $recurrenceId; protected $recurrenceId;
public function __construct($uniqueId = null) /**
* @var Attachment[]
*/
protected $attachments = [];
public function __construct(string $uniqueId = null)
{ {
if (null == $uniqueId) { if (null == $uniqueId) {
$uniqueId = uniqid(); $uniqueId = uniqid();
} }
$this->uniqueId = $uniqueId; $this->uniqueId = $uniqueId;
$this->attendees = new Attendees();
} }
/** /**
@ -234,7 +264,7 @@ class Event extends Component
// mandatory information // mandatory information
$propertyBag->set('UID', $this->uniqueId); $propertyBag->set('UID', $this->uniqueId);
$propertyBag->add(new DateTimeProperty('DTSTART', $this->dtStart, $this->noTime, $this->useTimezone, $this->useUtc)); $propertyBag->add(new DateTimeProperty('DTSTART', $this->dtStart, $this->noTime, $this->useTimezone, $this->useUtc, $this->timezoneString));
$propertyBag->set('SEQUENCE', $this->sequence); $propertyBag->set('SEQUENCE', $this->sequence);
$propertyBag->set('TRANSP', $this->transparency); $propertyBag->set('TRANSP', $this->transparency);
@ -243,9 +273,13 @@ class Event extends Component
} }
// An event can have a 'dtend' or 'duration', but not both. // An event can have a 'dtend' or 'duration', but not both.
if (null != $this->dtEnd) { if ($this->dtEnd !== null) {
$propertyBag->add(new DateTimeProperty('DTEND', $this->dtEnd, $this->noTime, $this->useTimezone, $this->useUtc)); $dtEnd = clone $this->dtEnd;
} elseif (null != $this->duration) { if ($this->noTime === true) {
$dtEnd = $dtEnd->add(new \DateInterval('P1D'));
}
$propertyBag->add(new DateTimeProperty('DTEND', $dtEnd, $this->noTime, $this->useTimezone, $this->useUtc, $this->timezoneString));
} elseif ($this->duration !== null) {
$propertyBag->set('DURATION', $this->duration->format('P%dDT%hH%iM%sS')); $propertyBag->set('DURATION', $this->duration->format('P%dDT%hH%iM%sS'));
} }
@ -261,19 +295,22 @@ class Event extends Component
$propertyBag->add( $propertyBag->add(
new Property( new Property(
'X-APPLE-STRUCTURED-LOCATION', 'X-APPLE-STRUCTURED-LOCATION',
'geo:' . $this->locationGeo, new RawStringValue('geo:' . $this->locationGeo->getGeoLocationAsString(',')),
array( [
'VALUE' => 'URI', 'VALUE' => 'URI',
'X-ADDRESS' => $this->location, 'X-ADDRESS' => $this->location,
'X-APPLE-RADIUS' => 49, 'X-APPLE-RADIUS' => 49,
'X-TITLE' => $this->locationTitle, 'X-TITLE' => $this->locationTitle,
) ]
) )
); );
$propertyBag->set('GEO', str_replace(',', ';', $this->locationGeo));
} }
} }
if (null != $this->locationGeo) {
$propertyBag->add($this->locationGeo);
}
if (null != $this->summary) { if (null != $this->summary) {
$propertyBag->set('SUMMARY', $this->summary); $propertyBag->set('SUMMARY', $this->summary);
} }
@ -285,7 +322,7 @@ class Event extends Component
$propertyBag->set('CLASS', $this->isPrivate ? 'PRIVATE' : 'PUBLIC'); $propertyBag->set('CLASS', $this->isPrivate ? 'PRIVATE' : 'PUBLIC');
if (null != $this->description) { if (null != $this->description) {
$propertyBag->set('DESCRIPTION', new Description($this->description)); $propertyBag->set('DESCRIPTION', $this->description);
} }
if (null != $this->descriptionHTML) { if (null != $this->descriptionHTML) {
@ -293,9 +330,9 @@ class Event extends Component
new Property( new Property(
'X-ALT-DESC', 'X-ALT-DESC',
$this->descriptionHTML, $this->descriptionHTML,
array( [
'FMTTYPE' => 'text/html', 'FMTTYPE' => 'text/html',
) ]
) )
); );
} }
@ -304,13 +341,17 @@ class Event extends Component
$propertyBag->set('RRULE', $this->recurrenceRule); $propertyBag->set('RRULE', $this->recurrenceRule);
} }
foreach ($this->recurrenceRules as $recurrenceRule) {
$propertyBag->set('RRULE', $recurrenceRule);
}
if (null != $this->recurrenceId) { if (null != $this->recurrenceId) {
$this->recurrenceId->applyTimeSettings($this->noTime, $this->useTimezone, $this->useUtc); $this->recurrenceId->applyTimeSettings($this->noTime, $this->useTimezone, $this->useUtc, $this->timezoneString);
$propertyBag->add($this->recurrenceId); $propertyBag->add($this->recurrenceId);
} }
if (!empty($this->exDates)) { if (!empty($this->exDates)) {
$propertyBag->add(new DateTimesProperty('EXDATE', $this->exDates, $this->noTime, $this->useTimezone, $this->useUtc)); $propertyBag->add(new DateTimesProperty('EXDATE', $this->exDates, $this->noTime, $this->useTimezone, $this->useUtc, $this->timezoneString));
} }
if ($this->cancelled) { if ($this->cancelled) {
@ -325,12 +366,17 @@ class Event extends Component
$propertyBag->set('X-MICROSOFT-CDO-ALLDAYEVENT', 'TRUE'); $propertyBag->set('X-MICROSOFT-CDO-ALLDAYEVENT', 'TRUE');
} }
if (null != $this->msBusyStatus) {
$propertyBag->set('X-MICROSOFT-CDO-BUSYSTATUS', $this->msBusyStatus);
$propertyBag->set('X-MICROSOFT-CDO-INTENDEDSTATUS', $this->msBusyStatus);
}
if (null != $this->categories) { if (null != $this->categories) {
$propertyBag->set('CATEGORIES', $this->categories); $propertyBag->set('CATEGORIES', $this->categories);
} }
$propertyBag->add( $propertyBag->add(
new DateTimeProperty('DTSTAMP', $this->dtStamp ?: new \DateTime(), false, false, true) new DateTimeProperty('DTSTAMP', $this->dtStamp ?: new \DateTimeImmutable(), false, false, true)
); );
if ($this->created) { if ($this->created) {
@ -341,6 +387,10 @@ class Event extends Component
$propertyBag->add(new DateTimeProperty('LAST-MODIFIED', $this->modified, false, false, true)); $propertyBag->add(new DateTimeProperty('LAST-MODIFIED', $this->modified, false, false, true));
} }
foreach ($this->attachments as $attachment) {
$propertyBag->add($attachment);
}
return $propertyBag; return $propertyBag;
} }
@ -368,6 +418,11 @@ class Event extends Component
return $this; return $this;
} }
public function getDtStart()
{
return $this->dtStart;
}
/** /**
* @param $dtStamp * @param $dtStamp
* *
@ -393,17 +448,34 @@ class Event extends Component
} }
/** /**
* @param $location * @param string $location
* @param string $title * @param string $title
* @param null $geo * @param Geo|string $geo
* *
* @return $this * @return $this
*/ */
public function setLocation($location, $title = '', $geo = null) public function setLocation($location, $title = '', $geo = null)
{ {
$this->location = $location; if (is_scalar($geo)) {
$geo = Geo::fromString($geo);
} elseif (!is_null($geo) && !$geo instanceof Geo) {
$className = get_class($geo);
throw new \InvalidArgumentException("The parameter 'geo' must be a string or an instance of " . Geo::class . " but an instance of {$className} was given.");
}
$this->location = $location;
$this->locationTitle = $title; $this->locationTitle = $title;
$this->locationGeo = $geo; $this->locationGeo = $geo;
return $this;
}
/**
* @return $this
*/
public function setGeoLocation(Geo $geoProperty)
{
$this->locationGeo = $geoProperty;
return $this; return $this;
} }
@ -420,6 +492,37 @@ class Event extends Component
return $this; return $this;
} }
/**
* @param $msBusyStatus
*
* @return $this
*
* @throws \InvalidArgumentException
*/
public function setMsBusyStatus($msBusyStatus)
{
$msBusyStatus = strtoupper($msBusyStatus);
if ($msBusyStatus == self::MS_BUSYSTATUS_FREE
|| $msBusyStatus == self::MS_BUSYSTATUS_TENTATIVE
|| $msBusyStatus == self::MS_BUSYSTATUS_BUSY
|| $msBusyStatus == self::MS_BUSYSTATUS_OOF
) {
$this->msBusyStatus = $msBusyStatus;
} else {
throw new \InvalidArgumentException('Invalid value for status');
}
return $this;
}
/**
* @return string|null
*/
public function getMsBusyStatus()
{
return $this->msBusyStatus;
}
/** /**
* @param int $sequence * @param int $sequence
* *
@ -441,8 +544,6 @@ class Event extends Component
} }
/** /**
* @param Organizer $organizer
*
* @return $this * @return $this
*/ */
public function setOrganizer(Organizer $organizer) public function setOrganizer(Organizer $organizer)
@ -517,10 +618,28 @@ class Event extends Component
} }
/** /**
* @param Attendees $attendees * @param $timezoneString
* *
* @return $this * @return $this
*/ */
public function setTimezoneString($timezoneString)
{
$this->timezoneString = $timezoneString;
return $this;
}
/**
* @return bool
*/
public function getTimezoneString()
{
return $this->timezoneString;
}
/**
* @return $this
*/
public function setAttendees(Attendees $attendees) public function setAttendees(Attendees $attendees)
{ {
$this->attendees = $attendees; $this->attendees = $attendees;
@ -534,20 +653,14 @@ class Event extends Component
* *
* @return $this * @return $this
*/ */
public function addAttendee($attendee, $params = array()) public function addAttendee($attendee, $params = [])
{ {
if (!isset($this->attendees)) {
$this->attendees = new Attendees();
}
$this->attendees->add($attendee, $params); $this->attendees->add($attendee, $params);
return $this; return $this;
} }
/** public function getAttendees(): Attendees
* @return Attendees
*/
public function getAttendees()
{ {
return $this->attendees; return $this->attendees;
} }
@ -660,25 +773,49 @@ class Event extends Component
} }
/** /**
* @param RecurrenceRule $recurrenceRule * @deprecated Deprecated since version 0.11.0, to be removed in 1.0. Use addRecurrenceRule instead.
* *
* @return $this * @return $this
*/ */
public function setRecurrenceRule(RecurrenceRule $recurrenceRule) public function setRecurrenceRule(RecurrenceRule $recurrenceRule)
{ {
@trigger_error('setRecurrenceRule() is deprecated since version 0.11.0 and will be removed in 1.0. Use addRecurrenceRule instead.', E_USER_DEPRECATED);
$this->recurrenceRule = $recurrenceRule; $this->recurrenceRule = $recurrenceRule;
return $this; return $this;
} }
/** /**
* @deprecated Deprecated since version 0.11.0, to be removed in 1.0. Use getRecurrenceRules instead.
*
* @return RecurrenceRule * @return RecurrenceRule
*/ */
public function getRecurrenceRule() public function getRecurrenceRule()
{ {
@trigger_error('getRecurrenceRule() is deprecated since version 0.11.0 and will be removed in 1.0. Use getRecurrenceRules instead.', E_USER_DEPRECATED);
return $this->recurrenceRule; return $this->recurrenceRule;
} }
/**
* @return $this
*/
public function addRecurrenceRule(RecurrenceRule $recurrenceRule)
{
$this->recurrenceRules[] = $recurrenceRule;
return $this;
}
/**
* @return array
*/
public function getRecurrenceRules()
{
return $this->recurrenceRules;
}
/** /**
* @param $dtStamp * @param $dtStamp
* *
@ -730,11 +867,9 @@ class Event extends Component
} }
/** /**
* @param \DateTime $dateTime
*
* @return \Eluceo\iCal\Component\Event * @return \Eluceo\iCal\Component\Event
*/ */
public function addExDate(\DateTime $dateTime) public function addExDate(\DateTimeInterface $dateTime)
{ {
$this->exDates[] = $dateTime; $this->exDates[] = $dateTime;
@ -742,7 +877,7 @@ class Event extends Component
} }
/** /**
* @return \DateTime[] * @return \DateTimeInterface[]
*/ */
public function getExDates() public function getExDates()
{ {
@ -750,7 +885,7 @@ class Event extends Component
} }
/** /**
* @param \DateTime[] * @param \DateTimeInterface[]
* *
* @return \Eluceo\iCal\Component\Event * @return \Eluceo\iCal\Component\Event
*/ */
@ -770,8 +905,6 @@ class Event extends Component
} }
/** /**
* @param RecurrenceId $recurrenceId
*
* @return \Eluceo\iCal\Component\Event * @return \Eluceo\iCal\Component\Event
*/ */
public function setRecurrenceId(RecurrenceId $recurrenceId) public function setRecurrenceId(RecurrenceId $recurrenceId)
@ -780,4 +913,29 @@ class Event extends Component
return $this; return $this;
} }
/**
* @param array $attachment
*
* @return $this
*/
public function addAttachment(Attachment $attachment)
{
$this->attachments[] = $attachment;
return $this;
}
/**
* @return array
*/
public function getAttachments()
{
return $this->attachments;
}
public function addUrlAttachment(string $url)
{
$this->addAttachment(new Attachment($url));
}
} }

View File

@ -12,8 +12,8 @@
namespace Eluceo\iCal\Component; namespace Eluceo\iCal\Component;
use Eluceo\iCal\Component; use Eluceo\iCal\Component;
use Eluceo\iCal\PropertyBag;
use Eluceo\iCal\Property\Event\RecurrenceRule; use Eluceo\iCal\Property\Event\RecurrenceRule;
use Eluceo\iCal\PropertyBag;
/** /**
* Implementation of Standard Time and Daylight Saving Time observances (or rules) * Implementation of Standard Time and Daylight Saving Time observances (or rules)
@ -45,7 +45,7 @@ class TimezoneRule extends Component
protected $tzName; protected $tzName;
/** /**
* @var \DateTime * @var \DateTimeInterface
*/ */
protected $dtStart; protected $dtStart;
@ -138,11 +138,9 @@ class TimezoneRule extends Component
} }
/** /**
* @param \DateTime $dtStart
*
* @return $this * @return $this
*/ */
public function setDtStart(\DateTime $dtStart) public function setDtStart(\DateTimeInterface $dtStart)
{ {
$this->dtStart = $dtStart; $this->dtStart = $dtStart;
@ -150,8 +148,6 @@ class TimezoneRule extends Component
} }
/** /**
* @param RecurrenceRule $recurrenceRule
*
* @return $this * @return $this
*/ */
public function setRecurrenceRule(RecurrenceRule $recurrenceRule) public function setRecurrenceRule(RecurrenceRule $recurrenceRule)

View File

@ -1,66 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Property\Event;
use Eluceo\iCal\Property\ValueInterface;
use Eluceo\iCal\Util\PropertyValueUtil;
/**
* Class Description
* Alows new line charectars to be in the description.
*/
class Description implements ValueInterface
{
/**
* The value.
*
* @var string
*/
protected $value;
public function __construct($value)
{
$this->value = $value;
}
/**
* Return the value of the Property as an escaped string.
*
* Escape values as per RFC 2445. See http://www.kanzaki.com/docs/ical/text.html
*
* @return string
*/
public function getEscapedValue()
{
return PropertyValueUtil::escapeValue((string) $this->value);
}
/**
* @param string $value
*
* @return $this
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* @return string
*/
public function getValue()
{
return $this->value;
}
}

View File

@ -1,61 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Property;
use Eluceo\iCal\Util\PropertyValueUtil;
class StringValue implements ValueInterface
{
/**
* The value.
*
* @var string
*/
protected $value;
public function __construct($value)
{
$this->value = $value;
}
/**
* Return the value of the Property as an escaped string.
*
* Escape values as per RFC 2445. See http://www.kanzaki.com/docs/ical/text.html
*
* @return string
*/
public function getEscapedValue()
{
return PropertyValueUtil::escapeValue((string) $this->value);
}
/**
* @param string $value
*
* @return $this
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* @return string
*/
public function getValue()
{
return $this->value;
}
}

View File

@ -1,48 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Util;
class ComponentUtil
{
/**
* Folds a single line.
*
* According to RFC 2445, all lines longer than 75 characters will be folded
*
* @link http://www.ietf.org/rfc/rfc2445.txt
*
* @param $string
*
* @return array
*/
public static function fold($string)
{
$lines = array();
$array = preg_split('/(?<!^)(?!$)/u', $string);
$line = '';
$lineNo = 0;
foreach ($array as $char) {
$charLen = strlen($char);
$lineLen = strlen($line);
if ($lineLen + $charLen > 75) {
$line = ' ' . $char;
++$lineNo;
} else {
$line .= $char;
}
$lines[$lineNo] = $line;
}
return $lines;
}
}

View File

@ -20,7 +20,7 @@ class ParameterBag
*/ */
protected $params; protected $params;
public function __construct($params = array()) public function __construct($params = [])
{ {
$this->params = $params; $this->params = $params;
} }
@ -36,33 +36,32 @@ class ParameterBag
/** /**
* @param $name * @param $name
*
* @return array|mixed
*/ */
public function getParam($name) public function getParam($name)
{ {
if (array_key_exists($name, $this->params)) { if (isset($this->params[$name])) {
return $this->params[$name]; return $this->params[$name];
} }
return null;
} }
/** /**
* Checks if there are any params. * Checks if there are any params.
*
* @return bool
*/ */
public function hasParams() public function hasParams(): bool
{ {
return count($this->params) > 0; return count($this->params) > 0;
} }
/** public function toString(): string
* @return string
*/
public function toString()
{ {
$line = ''; $line = '';
foreach ($this->params as $param => $paramValues) { foreach ($this->params as $param => $paramValues) {
if (!is_array($paramValues)) { if (!is_array($paramValues)) {
$paramValues = array($paramValues); $paramValues = [$paramValues];
} }
foreach ($paramValues as $k => $v) { foreach ($paramValues as $k => $v) {
$paramValues[$k] = $this->escapeParamValue($v); $paramValues[$k] = $this->escapeParamValue($v);
@ -85,7 +84,7 @@ class ParameterBag
* *
* @return string * @return string
*/ */
public function escapeParamValue($value) private function escapeParamValue($value)
{ {
$count = 0; $count = 0;
$value = str_replace('\\', '\\\\', $value); $value = str_replace('\\', '\\\\', $value);

View File

@ -16,9 +16,11 @@ use Eluceo\iCal\Property\StringValue;
use Eluceo\iCal\Property\ValueInterface; use Eluceo\iCal\Property\ValueInterface;
/** /**
* The Property Class represents a property as defined in RFC 2445. * The Property Class represents a property as defined in RFC 5545.
* *
* The content of a line (unfolded) will be rendered in this class * The content of a line (unfolded) will be rendered in this class.
*
* @see https://tools.ietf.org/html/rfc5545#section-3.5
*/ */
class Property class Property
{ {
@ -46,7 +48,7 @@ class Property
* @param $value * @param $value
* @param array $params * @param array $params
*/ */
public function __construct($name, $value, $params = array()) public function __construct($name, $value, $params = [])
{ {
$this->name = $name; $this->name = $name;
$this->setValue($value); $this->setValue($value);
@ -82,7 +84,7 @@ class Property
*/ */
public function toLines() public function toLines()
{ {
return array($this->toLine()); return [$this->toLine()];
} }
/** /**
@ -138,10 +140,7 @@ class Property
return $this->value; return $this->value;
} }
/** public function getName(): string
* @return string
*/
public function getName()
{ {
return $this->name; return $this->name;
} }

View File

@ -11,8 +11,6 @@
namespace Eluceo\iCal\Property; namespace Eluceo\iCal\Property;
use Eluceo\iCal\Util\PropertyValueUtil;
class ArrayValue implements ValueInterface class ArrayValue implements ValueInterface
{ {
/** /**
@ -34,10 +32,10 @@ class ArrayValue implements ValueInterface
return $this; return $this;
} }
public function getEscapedValue() public function getEscapedValue(): string
{ {
return implode(',', array_map(function ($value) { return implode(',', array_map(function (string $value): string {
return PropertyValueUtil::escapeValue((string) $value); return (new StringValue($value))->getEscapedValue();
}, $this->values)); }, $this->values));
} }
} }

View File

@ -17,21 +17,23 @@ use Eluceo\iCal\Util\DateUtil;
class DateTimeProperty extends Property class DateTimeProperty extends Property
{ {
/** /**
* @param string $name * @param string $name
* @param \DateTime $dateTime * @param \DateTimeInterface $dateTime
* @param bool $noTime * @param bool $noTime
* @param bool $useTimezone * @param bool $useTimezone
* @param bool $useUtc * @param bool $useUtc
* @param string $timezoneString
*/ */
public function __construct( public function __construct(
$name, $name,
\DateTime $dateTime = null, \DateTimeInterface $dateTime = null,
$noTime = false, $noTime = false,
$useTimezone = false, $useTimezone = false,
$useUtc = false $useUtc = false,
$timezoneString = ''
) { ) {
$dateString = DateUtil::getDateString($dateTime, $noTime, $useTimezone, $useUtc); $dateString = DateUtil::getDateString($dateTime, $noTime, $useTimezone, $useUtc);
$params = DateUtil::getDefaultParams($dateTime, $noTime, $useTimezone); $params = DateUtil::getDefaultParams($dateTime, $noTime, $useTimezone, $timezoneString);
parent::__construct($name, $dateString, $params); parent::__construct($name, $dateString, $params);
} }

View File

@ -17,24 +17,29 @@ use Eluceo\iCal\Util\DateUtil;
class DateTimesProperty extends Property class DateTimesProperty extends Property
{ {
/** /**
* @param string $name * @param string $name
* @param \DateTime[] $dateTimes * @param \DateTimeInterface[] $dateTimes
* @param bool $noTime * @param bool $noTime
* @param bool $useTimezone * @param bool $useTimezone
* @param bool $useUtc * @param bool $useUtc
* @param string $timezoneString
*/ */
public function __construct( public function __construct(
$name, $name,
$dateTimes = array(), $dateTimes = [],
$noTime = false, $noTime = false,
$useTimezone = false, $useTimezone = false,
$useUtc = false $useUtc = false,
$timezoneString = ''
) { ) {
$dates = array(); $dates = [];
$dateTime = new \DateTimeImmutable();
foreach ($dateTimes as $dateTime) { foreach ($dateTimes as $dateTime) {
$dates[] = DateUtil::getDateString($dateTime, $noTime, $useTimezone, $useUtc); $dates[] = DateUtil::getDateString($dateTime, $noTime, $useTimezone, $useUtc);
} }
$params = DateUtil::getDefaultParams($dateTime, $noTime, $useTimezone);
//@todo stop this triggering an E_NOTICE when $dateTimes is empty
$params = DateUtil::getDefaultParams($dateTime, $noTime, $useTimezone, $timezoneString);
parent::__construct($name, $dates, $params); parent::__construct($name, $dates, $params);
} }

View File

@ -0,0 +1,39 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Property\Event;
use Eluceo\iCal\Property;
/**
* Class Attachment.
*/
class Attachment extends Property
{
/**
* @param string $value
* @param array $params
*/
public function __construct($value, $params = [])
{
parent::__construct('ATTACH', $value, $params);
}
/**
* @param $url
*
* @throws \Exception
*/
public function setUrl($url)
{
$this->setValue($url);
}
}

View File

@ -15,14 +15,15 @@ use Eluceo\iCal\Property;
class Attendees extends Property class Attendees extends Property
{ {
/** @var Property[] */ /**
protected $attendees = array(); * @var Property[]
*/
const PROPERTY_NAME = 'ATTENDEES'; protected $attendees = [];
public function __construct() public function __construct()
{ {
// Overwrites constructor functionality of Property $this->name = 'ATTENDEES';
// prevent super constructor to be called
} }
/** /**
@ -31,7 +32,7 @@ class Attendees extends Property
* *
* @return $this * @return $this
*/ */
public function add($value, $params = array()) public function add($value, $params = [])
{ {
$this->attendees[] = new Property('ATTENDEE', $value, $params); $this->attendees[] = new Property('ATTENDEE', $value, $params);
@ -63,7 +64,7 @@ class Attendees extends Property
*/ */
public function toLines() public function toLines()
{ {
$lines = array(); $lines = [];
foreach ($this->attendees as $attendee) { foreach ($this->attendees as $attendee) {
$lines[] = $attendee->toLine(); $lines[] = $attendee->toLine();
} }
@ -91,12 +92,4 @@ class Attendees extends Property
{ {
throw new \BadMethodCallException('Cannot call getParam on Attendees Property'); throw new \BadMethodCallException('Cannot call getParam on Attendees Property');
} }
/**
* {@inheritdoc}
*/
public function getName()
{
return self::PROPERTY_NAME;
}
} }

View File

@ -0,0 +1,82 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Property\Event;
use Eluceo\iCal\Property;
/**
* GEO property.
*
* @see https://tools.ietf.org/html/rfc5545#section-3.8.1.6
*/
class Geo extends Property
{
/**
* @var float
*/
private $latitude;
/**
* @var float
*/
private $longitude;
public function __construct(float $latitude, float $longitude)
{
$this->latitude = $latitude;
$this->longitude = $longitude;
if ($this->latitude < -90 || $this->latitude > 90) {
throw new \InvalidArgumentException("The geographical latitude must be a value between -90 and 90 degrees. '{$this->latitude}' was given.");
}
if ($this->longitude < -180 || $this->longitude > 180) {
throw new \InvalidArgumentException("The geographical longitude must be a value between -180 and 180 degrees. '{$this->longitude}' was given.");
}
parent::__construct('GEO', new Property\RawStringValue($this->getGeoLocationAsString()));
}
/**
* @deprecated This method is used to allow backwards compatibility for Event::setLocation
*
* @return Geo
*/
public static function fromString(string $geoLocationString): self
{
$geoLocationString = str_replace(',', ';', $geoLocationString);
$geoLocationString = str_replace('GEO:', '', $geoLocationString);
$parts = explode(';', $geoLocationString);
return new static((float) $parts[0], (float) $parts[1]);
}
/**
* Returns the coordinates as a string.
*
* @example 37.386013;-122.082932
*/
public function getGeoLocationAsString(string $separator = ';'): string
{
return number_format($this->latitude, 6) . $separator . number_format($this->longitude, 6);
}
public function getLatitude(): float
{
return $this->latitude;
}
public function getLongitude(): float
{
return $this->longitude;
}
}

View File

@ -18,22 +18,12 @@ use Eluceo\iCal\Property;
*/ */
class Organizer extends Property class Organizer extends Property
{ {
const PROPERTY_NAME = 'ORGANIZER';
/** /**
* @param string $value * @param string $value
* @param array $params * @param array $params
*/ */
public function __construct($value, $params = array()) public function __construct($value, $params = [])
{ {
parent::__construct(self::PROPERTY_NAME, $value, $params); parent::__construct('ORGANIZER', $value, $params);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return self::PROPERTY_NAME;
} }
} }

View File

@ -13,29 +13,27 @@ namespace Eluceo\iCal\Property\Event;
use Eluceo\iCal\ParameterBag; use Eluceo\iCal\ParameterBag;
use Eluceo\iCal\Property; use Eluceo\iCal\Property;
use Eluceo\iCal\Util\DateUtil;
use Eluceo\iCal\Property\ValueInterface; use Eluceo\iCal\Property\ValueInterface;
use Eluceo\iCal\Util\DateUtil;
/** /**
* Implementation of Recurrence Id. * Implementation of Recurrence Id.
* *
* @see http://www.ietf.org/rfc/rfc2445.txt 4.8.4.4 Recurrence ID * @see https://tools.ietf.org/html/rfc5545#section-3.8.4.4
*/ */
class RecurrenceId extends Property class RecurrenceId extends Property
{ {
const PROPERTY_NAME = 'RECURRENCE-ID';
/** /**
* The effective range of recurrence instances from the instance * The effective range of recurrence instances from the instance
* specified by the recurrence identifier specified by the property. * specified by the recurrence identifier specified by the property.
*/ */
const RANGE_THISANDPRIOR = 'THISANDPRIOR'; const RANGE_THISANDPRIOR = 'THISANDPRIOR';
const RANGE_THISANDFUTURE = 'THISANDFUTURE'; const RANGE_THISANDFUTURE = 'THISANDFUTURE';
/** /**
* The dateTime to identify a particular instance of a recurring event which is getting modified. * The dateTime to identify a particular instance of a recurring event which is getting modified.
* *
* @var \DateTime * @var \DateTimeInterface
*/ */
protected $dateTime; protected $dateTime;
@ -46,17 +44,18 @@ class RecurrenceId extends Property
*/ */
protected $range; protected $range;
public function __construct(\DateTime $dateTime = null) public function __construct(\DateTimeInterface $dateTime = null)
{ {
$this->name = 'RECURRENCE-ID';
$this->parameterBag = new ParameterBag(); $this->parameterBag = new ParameterBag();
if (isset($dateTime)) { if (isset($dateTime)) {
$this->dateTime = $dateTime; $this->dateTime = $dateTime;
} }
} }
public function applyTimeSettings($noTime = false, $useTimezone = false, $useUtc = false) public function applyTimeSettings($noTime = false, $useTimezone = false, $useUtc = false, $timezoneString = '')
{ {
$params = DateUtil::getDefaultParams($this->dateTime, $noTime, $useTimezone, $useUtc); $params = DateUtil::getDefaultParams($this->dateTime, $noTime, $useTimezone, $timezoneString);
foreach ($params as $name => $value) { foreach ($params as $name => $value) {
$this->parameterBag->setParam($name, $value); $this->parameterBag->setParam($name, $value);
} }
@ -69,7 +68,7 @@ class RecurrenceId extends Property
} }
/** /**
* @return DateTime * @return \DateTimeInterface
*/ */
public function getDatetime() public function getDatetime()
{ {
@ -77,11 +76,9 @@ class RecurrenceId extends Property
} }
/** /**
* @param \DateTime $dateTime
*
* @return \Eluceo\iCal\Property\Event\RecurrenceId * @return \Eluceo\iCal\Property\Event\RecurrenceId
*/ */
public function setDatetime(\DateTime $dateTime) public function setDatetime(\DateTimeInterface $dateTime)
{ {
$this->dateTime = $dateTime; $this->dateTime = $dateTime;
@ -104,6 +101,8 @@ class RecurrenceId extends Property
public function setRange($range) public function setRange($range)
{ {
$this->range = $range; $this->range = $range;
return $this;
} }
/** /**
@ -119,12 +118,4 @@ class RecurrenceId extends Property
return parent::toLines(); return parent::toLines();
} }
} }
/**
* {@inheritdoc}
*/
public function getName()
{
return self::PROPERTY_NAME;
}
} }

View File

@ -11,29 +11,32 @@
namespace Eluceo\iCal\Property\Event; namespace Eluceo\iCal\Property\Event;
use Eluceo\iCal\Property\ValueInterface;
use Eluceo\iCal\ParameterBag; use Eluceo\iCal\ParameterBag;
use Eluceo\iCal\Property\ValueInterface;
use InvalidArgumentException; use InvalidArgumentException;
/** /**
* Implementation of Recurrence Rule. * Implementation of Recurrence Rule.
* *
* @see http://www.ietf.org/rfc/rfc2445.txt 3.3.10. Recurrence Rule * @see https://tools.ietf.org/html/rfc5545#section-3.8.5.3
*/ */
class RecurrenceRule implements ValueInterface class RecurrenceRule implements ValueInterface
{ {
const FREQ_YEARLY = 'YEARLY'; const FREQ_YEARLY = 'YEARLY';
const FREQ_MONTHLY = 'MONTHLY'; const FREQ_MONTHLY = 'MONTHLY';
const FREQ_WEEKLY = 'WEEKLY'; const FREQ_WEEKLY = 'WEEKLY';
const FREQ_DAILY = 'DAILY'; const FREQ_DAILY = 'DAILY';
const FREQ_HOURLY = 'HOURLY';
const FREQ_MINUTELY = 'MINUTELY';
const FREQ_SECONDLY = 'SECONDLY';
const WEEKDAY_SUNDAY = 'SU'; const WEEKDAY_SUNDAY = 'SU';
const WEEKDAY_MONDAY = 'MO'; const WEEKDAY_MONDAY = 'MO';
const WEEKDAY_TUESDAY = 'TU'; const WEEKDAY_TUESDAY = 'TU';
const WEEKDAY_WEDNESDAY = 'WE'; const WEEKDAY_WEDNESDAY = 'WE';
const WEEKDAY_THURSDAY = 'TH'; const WEEKDAY_THURSDAY = 'TH';
const WEEKDAY_FRIDAY = 'FR'; const WEEKDAY_FRIDAY = 'FR';
const WEEKDAY_SATURDAY = 'SA'; const WEEKDAY_SATURDAY = 'SA';
/** /**
* The frequency of an Event. * The frequency of an Event.
@ -43,73 +46,78 @@ class RecurrenceRule implements ValueInterface
protected $freq = self::FREQ_YEARLY; protected $freq = self::FREQ_YEARLY;
/** /**
* @var null|int * BYSETPOS must require use of other BY*.
*
* @var bool
*/
protected $canUseBySetPos = false;
/**
* @var int|null
*/ */
protected $interval = 1; protected $interval = 1;
/** /**
* @var null|int * @var int|null
*/ */
protected $count = null; protected $count = null;
/** /**
* @var null|\DateTime * @var \DateTimeInterface|null
*/ */
protected $until = null; protected $until = null;
/** /**
* @var null|string * @var string|null
*/ */
protected $wkst; protected $wkst;
/** /**
* @var null|string * @var array|null
*/
protected $bySetPos = null;
/**
* @var string|null
*/ */
protected $byMonth; protected $byMonth;
/** /**
* @var null|string * @var string|null
*/ */
protected $byWeekNo; protected $byWeekNo;
/** /**
* @var null|string * @var string|null
*/ */
protected $byYearDay; protected $byYearDay;
/** /**
* @var null|string * @var string|null
*/ */
protected $byMonthDay; protected $byMonthDay;
/** /**
* @var null|string * @var string|null
*/ */
protected $byDay; protected $byDay;
/** /**
* @var null|string * @var string|null
*/ */
protected $byHour; protected $byHour;
/** /**
* @var null|string * @var string|null
*/ */
protected $byMinute; protected $byMinute;
/** /**
* @var null|string * @var string|null
*/ */
protected $bySecond; protected $bySecond;
/** public function getEscapedValue(): string
* Return the value of the Property as an escaped string.
*
* Escape values as per RFC 2445. See http://www.kanzaki.com/docs/ical/text.html
*
* @return string
*/
public function getEscapedValue()
{ {
return $this->buildParameterBag()->toString(); return $this->buildParameterBag()->toString();
} }
@ -139,36 +147,40 @@ class RecurrenceRule implements ValueInterface
$parameterBag->setParam('WKST', $this->wkst); $parameterBag->setParam('WKST', $this->wkst);
} }
if (null !== $this->bySetPos && $this->canUseBySetPos) {
$parameterBag->setParam('BYSETPOS', $this->bySetPos);
}
if (null !== $this->byMonth) { if (null !== $this->byMonth) {
$parameterBag->setParam('BYMONTH', $this->byMonth); $parameterBag->setParam('BYMONTH', explode(',', $this->byMonth));
} }
if (null !== $this->byWeekNo) { if (null !== $this->byWeekNo) {
$parameterBag->setParam('BYWEEKNO', $this->byWeekNo); $parameterBag->setParam('BYWEEKNO', explode(',', $this->byWeekNo));
} }
if (null !== $this->byYearDay) { if (null !== $this->byYearDay) {
$parameterBag->setParam('BYYEARDAY', $this->byYearDay); $parameterBag->setParam('BYYEARDAY', explode(',', $this->byYearDay));
} }
if (null !== $this->byMonthDay) { if (null !== $this->byMonthDay) {
$parameterBag->setParam('BYMONTHDAY', $this->byMonthDay); $parameterBag->setParam('BYMONTHDAY', explode(',', $this->byMonthDay));
} }
if (null !== $this->byDay) { if (null !== $this->byDay) {
$parameterBag->setParam('BYDAY', $this->byDay); $parameterBag->setParam('BYDAY', explode(',', $this->byDay));
} }
if (null !== $this->byHour) { if (null !== $this->byHour) {
$parameterBag->setParam('BYHOUR', $this->byHour); $parameterBag->setParam('BYHOUR', explode(',', $this->byHour));
} }
if (null !== $this->byMinute) { if (null !== $this->byMinute) {
$parameterBag->setParam('BYMINUTE', $this->byMinute); $parameterBag->setParam('BYMINUTE', explode(',', $this->byMinute));
} }
if (null !== $this->bySecond) { if (null !== $this->bySecond) {
$parameterBag->setParam('BYSECOND', $this->bySecond); $parameterBag->setParam('BYSECOND', explode(',', $this->bySecond));
} }
return $parameterBag; return $parameterBag;
@ -195,11 +207,9 @@ class RecurrenceRule implements ValueInterface
} }
/** /**
* @param \DateTime|null $until
*
* @return $this * @return $this
*/ */
public function setUntil(\DateTime $until = null) public function setUntil(\DateTimeInterface $until = null)
{ {
$this->until = $until; $this->until = $until;
@ -207,7 +217,7 @@ class RecurrenceRule implements ValueInterface
} }
/** /**
* @return \DateTime|null * @return \DateTimeInterface|null
*/ */
public function getUntil() public function getUntil()
{ {
@ -235,10 +245,7 @@ class RecurrenceRule implements ValueInterface
*/ */
public function setFreq($freq) public function setFreq($freq)
{ {
if (self::FREQ_YEARLY === $freq || self::FREQ_MONTHLY === $freq if (@constant('static::FREQ_' . $freq) !== null) {
|| self::FREQ_WEEKLY === $freq
|| self::FREQ_DAILY === $freq
) {
$this->freq = $freq; $this->freq = $freq;
} else { } else {
throw new \InvalidArgumentException("The Frequency {$freq} is not supported."); throw new \InvalidArgumentException("The Frequency {$freq} is not supported.");
@ -294,23 +301,88 @@ class RecurrenceRule implements ValueInterface
} }
/** /**
* The BYMONTH rule part specifies a COMMA-separated list of months of the year. * The BYSETPOS filters one interval of events by the specified position.
* Valid values are 1 to 12. * A positive position will start from the beginning and go forward while
* a negative position will start at the end and move backward.
* *
* @param int $month * Valid values are a comma separated string or an array of integers
* from 1 to 366 or negative integers from -1 to -366.
*
* @param int|string|array|null $value
* *
* @throws InvalidArgumentException * @throws InvalidArgumentException
* *
* @return $this * @return $this
*/ */
public function setBySetPos($value)
{
if (null === $value) {
$this->bySetPos = $value;
return $this;
}
if (!(is_string($value) || is_array($value) || is_int($value))) {
throw new InvalidArgumentException('Invalid value for BYSETPOS');
}
$list = $value;
if (is_int($value)) {
if ($value === 0 || $value < -366 || $value > 366) {
throw new InvalidArgumentException('Invalid value for BYSETPOS');
}
$this->bySetPos = [$value];
return $this;
}
if (is_string($value)) {
$list = explode(',', $value);
}
$output = [];
foreach ($list as $item) {
if (is_string($item)) {
if (!preg_match('/^ *-?[0-9]* *$/', $item)) {
throw new InvalidArgumentException('Invalid value for BYSETPOS');
}
$item = intval($item);
}
if (!is_int($item) || $item === 0 || $item < -366 || $item > 366) {
throw new InvalidArgumentException('Invalid value for BYSETPOS');
}
$output[] = $item;
}
$this->bySetPos = $output;
return $this;
}
/**
* The BYMONTH rule part specifies a COMMA-separated list of months of the year.
* Valid values are 1 to 12.
*
* @param int $month
*
* @throws \InvalidArgumentException
*
* @return $this
*/
public function setByMonth($month) public function setByMonth($month)
{ {
if (!is_integer($month) || $month < 0 || $month > 12) { if (!is_integer($month) || $month <= 0 || $month > 12) {
throw new InvalidArgumentException('Invalid value for BYMONTH'); throw new InvalidArgumentException('Invalid value for BYMONTH');
} }
$this->byMonth = $month; $this->byMonth = $month;
$this->canUseBySetPos = true;
return $this; return $this;
} }
@ -320,12 +392,20 @@ class RecurrenceRule implements ValueInterface
* *
* @param int $value * @param int $value
* *
* @throws \InvalidArgumentException
*
* @return $this * @return $this
*/ */
public function setByWeekNo($value) public function setByWeekNo($value)
{ {
if (!is_integer($value) || $value > 53 || $value < -53 || $value === 0) {
throw new InvalidArgumentException('Invalid value for BYWEEKNO');
}
$this->byWeekNo = $value; $this->byWeekNo = $value;
$this->canUseBySetPos = true;
return $this; return $this;
} }
@ -335,12 +415,20 @@ class RecurrenceRule implements ValueInterface
* *
* @param int $day * @param int $day
* *
* @throws \InvalidArgumentException
*
* @return $this * @return $this
*/ */
public function setByYearDay($day) public function setByYearDay($day)
{ {
if (!is_integer($day) || $day > 366 || $day < -366 || $day === 0) {
throw new InvalidArgumentException('Invalid value for BYYEARDAY');
}
$this->byYearDay = $day; $this->byYearDay = $day;
$this->canUseBySetPos = true;
return $this; return $this;
} }
@ -351,11 +439,19 @@ class RecurrenceRule implements ValueInterface
* @param int $day * @param int $day
* *
* @return $this * @return $this
*
* @throws \InvalidArgumentException
*/ */
public function setByMonthDay($day) public function setByMonthDay($day)
{ {
if (!is_integer($day) || $day > 31 || $day < -31 || $day === 0) {
throw new InvalidArgumentException('Invalid value for BYMONTHDAY');
}
$this->byMonthDay = $day; $this->byMonthDay = $day;
$this->canUseBySetPos = true;
return $this; return $this;
} }
@ -368,14 +464,14 @@ class RecurrenceRule implements ValueInterface
* Each BYDAY value can also be preceded by a positive (+n) or negative (-n) integer. * Each BYDAY value can also be preceded by a positive (+n) or negative (-n) integer.
* If present, this indicates the nth occurrence of a specific day within the MONTHLY or YEARLY "RRULE". * If present, this indicates the nth occurrence of a specific day within the MONTHLY or YEARLY "RRULE".
* *
* @param string $day
*
* @return $this * @return $this
*/ */
public function setByDay($day) public function setByDay(string $day)
{ {
$this->byDay = $day; $this->byDay = $day;
$this->canUseBySetPos = true;
return $this; return $this;
} }
@ -397,6 +493,8 @@ class RecurrenceRule implements ValueInterface
$this->byHour = $value; $this->byHour = $value;
$this->canUseBySetPos = true;
return $this; return $this;
} }
@ -418,6 +516,8 @@ class RecurrenceRule implements ValueInterface
$this->byMinute = $value; $this->byMinute = $value;
$this->canUseBySetPos = true;
return $this; return $this;
} }
@ -439,6 +539,8 @@ class RecurrenceRule implements ValueInterface
$this->bySecond = $value; $this->bySecond = $value;
$this->canUseBySetPos = true;
return $this; return $this;
} }
} }

View File

@ -0,0 +1,20 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Property;
class RawStringValue extends StringValue
{
public function getEscapedValue(): string
{
return $this->getValue();
}
}

View File

@ -9,32 +9,59 @@
* with this source code in the file LICENSE. * with this source code in the file LICENSE.
*/ */
namespace Eluceo\iCal\Util; namespace Eluceo\iCal\Property;
class PropertyValueUtil class StringValue implements ValueInterface
{ {
public static function escapeValue($value) /**
{ * The value.
$value = self::escapeValueAllowNewLine($value); *
$value = str_replace("\n", '\\n', $value); * @var string
*/
protected $value;
return $value; public function __construct($value)
{
$this->value = $value;
} }
public static function escapeValueAllowNewLine($value) public function getEscapedValue(): string
{ {
$value = $this->value;
$value = str_replace('\\', '\\\\', $value); $value = str_replace('\\', '\\\\', $value);
$value = str_replace('"', '\\"', $value); $value = str_replace('"', '\\"', $value);
$value = str_replace(',', '\\,', $value); $value = str_replace(',', '\\,', $value);
$value = str_replace(';', '\\;', $value); $value = str_replace(';', '\\;', $value);
$value = str_replace(array( $value = str_replace("\n", '\\n', $value);
$value = str_replace([
"\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07",
"\x08", "\x09", /* \n*/ "\x0B", "\x0C", "\x0D", "\x0E", "\x0F", "\x08", "\x09", /* \n*/ "\x0B", "\x0C", "\x0D", "\x0E", "\x0F",
"\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17",
"\x18", "\x19", "\x1A", "\x1B", "\x1C", "\x1D", "\x1E", "\x1F", "\x18", "\x19", "\x1A", "\x1B", "\x1C", "\x1D", "\x1E", "\x1F",
"\x7F", "\x7F",
), '', $value); ], '', $value);
return $value; return $value;
} }
/**
* @param string $value
*
* @return $this
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* @return string
*/
public function getValue()
{
return $this->value;
}
} }

View File

@ -16,9 +16,9 @@ interface ValueInterface
/** /**
* Return the value of the Property as an escaped string. * Return the value of the Property as an escaped string.
* *
* Escape values as per RFC 2445. See http://www.kanzaki.com/docs/ical/text.html * Escape values as per RFC 5545.
* *
* @return string * @see https://tools.ietf.org/html/rfc5545#section-3.3.11
*/ */
public function getEscapedValue(); public function getEscapedValue(): string;
} }

View File

@ -16,7 +16,7 @@ class PropertyBag implements \IteratorAggregate
/** /**
* @var array * @var array
*/ */
protected $elements = array(); protected $elements = [];
/** /**
* Creates a new Property with $name, $value and $params. * Creates a new Property with $name, $value and $params.
@ -27,47 +27,41 @@ class PropertyBag implements \IteratorAggregate
* *
* @return $this * @return $this
*/ */
public function set($name, $value, $params = array()) public function set($name, $value, $params = [])
{ {
$property = new Property($name, $value, $params); $this->add(new Property($name, $value, $params));
$this->elements[] = $property;
return $this; return $this;
} }
/** /**
* @param string $name * @return Property|null
*
* @return null|Property
*/ */
public function get($name) public function get(string $name)
{ {
// Searching Property in elements-array if (isset($this->elements[$name])) {
/** @var $property Property */ return $this->elements[$name];
foreach ($this->elements as $property) {
if ($property->getName() == $name) {
return $property;
}
} }
return null;
} }
/** /**
* Adds a Property. If Property already exists an Exception will be thrown. * Adds a Property. If Property already exists an Exception will be thrown.
* *
* @param Property $property
*
* @return $this * @return $this
* *
* @throws \Exception * @throws \Exception
*/ */
public function add(Property $property) public function add(Property $property)
{ {
// Property already exists? $name = $property->getName();
if (null !== $this->get($property->getName())) {
throw new \Exception("Property with name '{$property->getName()}' already exists"); if (isset($this->elements[$name])) {
throw new \Exception("Property with name '{$name}' already exists");
} }
$this->elements[] = $property; $this->elements[$name] = $property;
return $this; return $this;
} }

View File

@ -0,0 +1,62 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Util;
class ComponentUtil
{
/**
* Folds a single line.
*
* According to RFC 5545, all lines longer than 75 characters should be folded
*
* @see https://tools.ietf.org/html/rfc5545#section-5
* @see https://tools.ietf.org/html/rfc5545#section-3.1
*
* @param string $string
*
* @return array
*/
public static function fold($string)
{
$lines = [];
if (function_exists('mb_strcut')) {
while (strlen($string) > 0) {
if (strlen($string) > 75) {
$lines[] = mb_strcut($string, 0, 75, 'utf-8');
$string = ' ' . mb_strcut($string, 75, strlen($string), 'utf-8');
} else {
$lines[] = $string;
$string = '';
break;
}
}
} else {
$array = preg_split('/(?<!^)(?!$)/u', $string);
$line = '';
$lineNo = 0;
foreach ($array as $char) {
$charLen = strlen($char);
$lineLen = strlen($line);
if ($lineLen + $charLen > 75) {
$line = ' ' . $char;
++$lineNo;
} else {
$line .= $char;
}
$lines[$lineNo] = $line;
}
}
return $lines;
}
}

View File

@ -13,12 +13,12 @@ namespace Eluceo\iCal\Util;
class DateUtil class DateUtil
{ {
public static function getDefaultParams(\DateTime $dateTime = null, $noTime = false, $useTimezone = false) public static function getDefaultParams(\DateTimeInterface $dateTime = null, $noTime = false, $useTimezone = false, $timezoneString = '')
{ {
$params = array(); $params = [];
if ($useTimezone) { if ($useTimezone && $noTime === false) {
$timeZone = $dateTime->getTimezone()->getName(); $timeZone = $timezoneString === '' ? $dateTime->getTimezone()->getName() : $timezoneString;
$params['TZID'] = $timeZone; $params['TZID'] = $timeZone;
} }
@ -32,17 +32,25 @@ class DateUtil
/** /**
* Returns a formatted date string. * Returns a formatted date string.
* *
* @param \DateTime|null $dateTime The DateTime object * @param \DateTimeInterface|null $dateTime The DateTime object
* @param bool $noTime Indicates if the time will be added * @param bool $noTime Indicates if the time will be added
* @param bool $useTimezone * @param bool $useTimezone
* @param bool $useUtc * @param bool $useUtc
* *
* @return mixed * @return mixed
*/ */
public static function getDateString(\DateTime $dateTime = null, $noTime = false, $useTimezone = false, $useUtc = false) public static function getDateString(\DateTimeInterface $dateTime = null, $noTime = false, $useTimezone = false, $useUtc = false)
{ {
if (empty($dateTime)) { if (empty($dateTime)) {
$dateTime = new \DateTime(); $dateTime = new \DateTimeImmutable();
}
// Only convert the DateTime to UTC if there is a time present. For date-only the
// timezone is meaningless and converting it might shift it to the wrong date.
// Do not convert DateTime to UTC if a timezone it specified, as it should be local time.
if (!$noTime && $useUtc && !$useTimezone) {
$dateTime = clone $dateTime;
$dateTime = $dateTime->setTimezone(new \DateTimeZone('UTC'));
} }
return $dateTime->format(self::getDateFormat($noTime, $useTimezone, $useUtc)); return $dateTime->format(self::getDateFormat($noTime, $useTimezone, $useUtc));

View File

@ -1,64 +0,0 @@
<?php
namespace Eluceo\iCal\Component;
class CalendarIntegrationTest extends \PHPUnit_Framework_TestCase
{
/**
* @coversNothing
*/
public function testExample3()
{
$timeZone = new \DateTimeZone('Europe/Berlin');
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event('123456');
$vEvent->setDtStart(new \DateTime('2012-12-31', $timeZone));
$vEvent->setDtEnd(new \DateTime('2012-12-31', $timeZone));
$vEvent->setNoTime(true);
$vEvent->setIsPrivate(true);
$vEvent->setSummary('New Years Eve');
// Set recurrence rule
$recurrenceRule = new \Eluceo\iCal\Property\Event\RecurrenceRule();
$recurrenceRule->setFreq(\Eluceo\iCal\Property\Event\RecurrenceRule::FREQ_YEARLY);
$recurrenceRule->setInterval(1);
$vEvent->setRecurrenceRule($recurrenceRule);
// Adding Timezone (optional)
$vEvent->setUseTimezone(true);
// 3. Add event to calendar
$vCalendar->addComponent($vEvent);
$lines = array(
'/BEGIN:VCALENDAR/',
'/VERSION:2\.0/',
'/PRODID:www\.example\.com/',
'/X-PUBLISHED-TTL:P1W/',
'/BEGIN:VEVENT/',
'/UID:123456/',
'/DTSTART;TZID=Europe\/Berlin;VALUE=DATE:20121231/',
'/SEQUENCE:0/',
'/TRANSP:OPAQUE/',
'/DTEND;TZID=Europe\/Berlin;VALUE=DATE:20121231/',
'/SUMMARY:New Years Eve/',
'/CLASS:PRIVATE/',
'/RRULE:FREQ=YEARLY;INTERVAL=1/',
'/X-MICROSOFT-CDO-ALLDAYEVENT:TRUE/',
'/DTSTAMP:20\d{6}T\d{6}Z/',
'/END:VEVENT/',
'/END:VCALENDAR/',
);
foreach (explode("\n", $vCalendar->render()) as $key => $line)
{
$this->assertTrue(isset($lines[$key]), 'Too many lines... ' . $line);
$this->assertRegExp($lines[$key], $line);
}
}
}

View File

@ -1,45 +0,0 @@
<?php
namespace Eluceo\iCal;
class ComponentTest extends \PHPUnit_Framework_TestCase
{
public function testFoldWithMultibyte()
{
$input = "x" . str_repeat("あいうえお", 5);
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2014-12-24'));
$vEvent->setDtEnd(new \DateTime('2014-12-24'));
$vEvent->setDescription($input);
$vAlarm = new \Eluceo\iCal\Component\Alarm;
$vAlarm->setAction(\Eluceo\iCal\Component\Alarm::ACTION_DISPLAY);
$vAlarm->setDescription($input);
$vAlarm->setTrigger('PT0S', true);
$vEvent->addComponent($vAlarm);
$vCalendar->addComponent($vEvent);
$output = $vCalendar->render();
$output = preg_replace('/\r\n /u', '', $output);
$this->assertContains($input, $output);
}
public function testDescriptionWithNewLines()
{
$input = "new string \n new line \n new line \n new string";
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2014-12-24'));
$vEvent->setDtEnd(new \DateTime('2014-12-24'));
$vEvent->setDescription($input);
$vCalendar->addComponent($vEvent);
$output = $vCalendar->render();
$this->assertContains(str_replace("\n", "\\n", $input), $output);
}
}

View File

@ -1,35 +0,0 @@
<?php
namespace Eluceo\iCal;
class ParameterBagTest extends \PHPUnit_Framework_TestCase
{
public function testEscapeParamValue()
{
$propertyObject = new ParameterBag;
$this->assertEquals(
'test string',
$propertyObject->escapeParamValue('test string'),
'No escaping necessary'
);
$this->assertEquals(
'"Containing \\"double-quotes\\""',
$propertyObject->escapeParamValue('Containing "double-quotes"'),
'Text contains double quotes'
);
$this->assertEquals(
'"Containing forbidden chars like a ;"',
$propertyObject->escapeParamValue('Containing forbidden chars like a ;'),
'Text with semicolon'
);
$this->assertEquals(
'"Containing forbidden chars like a :"',
$propertyObject->escapeParamValue('Containing forbidden chars like a :'),
'Text with colon'
);
}
}

View File

@ -1,26 +0,0 @@
<?php
namespace Eluceo\iCal\Property;
class ArrayValueTest extends \PHPUnit_Framework_TestCase
{
/**
* @dataProvider arrayValuesProvider
*/
public function testArrayValue($values, $expectedOutput)
{
$arrayValue = new ArrayValue($values);
$this->assertEquals($expectedOutput, $arrayValue->getEscapedValue());
}
public function arrayValuesProvider()
{
return array(
array(array(), ''),
array(array('Lorem'), 'Lorem'),
array(array('Lorem', 'Ipsum'), 'Lorem,Ipsum'),
array(array('Lorem', '"doublequotes"'), 'Lorem,\"doublequotes\"'),
);
}
}

View File

@ -1,17 +0,0 @@
<?php
namespace Eluceo\iCal\Property\Event;
class DescriptionTest extends \PHPUnit_Framework_TestCase
{
public function testAllowsNewLines()
{
$testString = "New String \n New Line";
$description = new Description($testString);
$this->assertEquals(
str_replace("\n", "\\n", $testString),
$description->getEscapedValue()
);
}
}

View File

@ -1,63 +0,0 @@
<?php
/**
* Eluceo\iCal\Property\Event\OrganizerTest
*
* @author Giulio Troccoli <giulio@troccoli.it>
*/
namespace Eluceo\iCal\Property\Event;
/**
* OrganizerTest
*/
class OrganizerTest extends \PHPUnit_Framework_TestCase
{
public function testOrganizerValueOnly()
{
$value = "MAILTO:name.lastname@example.com";
$expected = "ORGANIZER:$value";
$vCalendar = $this->createCalendarWithOrganizer(
new \Eluceo\iCal\Property\Event\Organizer($value)
);
foreach (explode("\n", $vCalendar->render()) as $line)
{
if (preg_match('/^ORGANIZER[:;](.*)$/', $line)) {
$this->assertEquals($expected, trim($line));
}
}
}
public function testOrganizerValueAndParameter()
{
$value = "MAILTO:name.lastname@example.com";
$param = "Name LastName";
$expected = "ORGANIZER;CN=$param:$value";
$vCalendar = $this->createCalendarWithOrganizer(
new \Eluceo\iCal\Property\Event\Organizer($value, array('CN' => $param))
);
foreach (explode("\n", $vCalendar->render()) as $line)
{
if (preg_match('/^ORGANIZER[:;](.*)$/', $line)) {
$this->assertEquals($expected, trim($line));
}
}
}
/**
* @param Organizer $vOrganizer
* @return \Eluceo\iCal\Component\Calendar
*/
private function createCalendarWithOrganizer(\Eluceo\iCal\Property\Event\Organizer $vOrganizer)
{
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
$vEvent = new \Eluceo\iCal\Component\Event('123456');
$vEvent->setOrganizer($vOrganizer);
$vCalendar->addComponent($vEvent);
return $vCalendar;
}
}

View File

@ -1,21 +0,0 @@
<?php
namespace Eluceo\iCal\Property\Event;
class RecurrenceRuleTest extends \PHPUnit_Framework_TestCase
{
/**
* Example taken from http://www.kanzaki.com/docs/ical/rrule.html
*/
public function testUntil()
{
$rule = new RecurrenceRule();
$rule->setFreq(RecurrenceRule::FREQ_DAILY);
$rule->setInterval(null);
$rule->setUntil(new \DateTime('1997-12-24'));
$this->assertEquals(
'FREQ=DAILY;UNTIL=19971224T000000Z',
$rule->getEscapedValue()
);
}
}

View File

@ -1,63 +0,0 @@
<?php
namespace Eluceo\iCal\Property;
use Eluceo\iCal\Property\StringValue;
class StringValueTest extends \PHPUnit_Framework_TestCase
{
public function testNoEscapeNeeded()
{
$stringValue = new StringValue('LOREM');
$this->assertEquals(
'LOREM',
$stringValue->getEscapedValue(),
'No escaping necessary'
);
}
public function testValueContainsBackslash()
{
$stringValue = new StringValue('text contains backslash: \\');
$this->assertEquals(
'text contains backslash: \\\\',
$stringValue->getEscapedValue(),
'Text contains backslash'
);
}
public function testEscapingDoubleQuotes()
{
$stringValue = new StringValue('text with "doublequotes" will be escaped');
$this->assertEquals(
'text with \\"doublequotes\\" will be escaped',
$stringValue->getEscapedValue(),
'Escaping double quotes'
);
}
public function testEscapingSemicolonAndComma()
{
$stringValue = new StringValue('text with , and ; will also be escaped');
$this->assertEquals(
'text with \\, and \\; will also be escaped',
$stringValue->getEscapedValue(),
'Escaping ; and ,'
);
}
public function testNewLineEscaping()
{
$stringValue = new StringValue("Text with new\n line");
$this->assertEquals(
'Text with new\\n line',
$stringValue->getEscapedValue(),
'Escape new line to text'
);
}
}

View File

@ -1,18 +0,0 @@
<?php
namespace Eluceo\iCal;
class PropertyBagTest extends \PHPUnit_Framework_TestCase
{
/**
* @todo Use Mocks instead of a real object!
*/
public function testPropertyAlreadyExistsOnAddingProperty()
{
$this->setExpectedException('\\Exception', "Property with name 'propName' already exists");
$propertyBag = new PropertyBag();
$propertyBag->add(new Property('propName', ''));
$propertyBag->add(new Property('propName', ''));
}
}

View File

@ -1,42 +0,0 @@
<?php
namespace Eluceo\iCal;
class PropertyTest extends \PHPUnit_Framework_TestCase
{
public function testPropertyWithSingleValue()
{
$property = new Property('DTSTAMP', '20131020T153112');
$this->assertEquals(
'DTSTAMP:20131020T153112',
$property->toLine()
);
}
public function testPropertyWithValueAndParams()
{
$property = new Property('DTSTAMP', '20131020T153112', array('TZID' => 'Europe/Berlin'));
$this->assertEquals(
'DTSTAMP;TZID=Europe/Berlin:20131020T153112',
$property->toLine()
);
}
public function testPropertyWithEscapedSingleValue()
{
$property = new Property('SOMEPROP', 'Escape me!"');
$this->assertEquals(
'SOMEPROP:Escape me!\\"',
$property->toLine()
);
}
public function testPropertyWithEscapedValues()
{
$property = new Property('SOMEPROP', 'Escape me!"', array('TEST' => 'Lorem "test" ipsum'));
$this->assertEquals(
'SOMEPROP;TEST="Lorem \\"test\\" ipsum":Escape me!\\"',
$property->toLine()
);
}
}

View File

@ -1,6 +1,11 @@
CHANGELOG CHANGELOG
========= =========
1.1.9
-----
* fixed compat with PHP 8
1.1.0 1.1.0
----- -----

View File

@ -15,6 +15,9 @@ use Psr\Cache\CacheItemPoolInterface;
use Psr\Cache\InvalidArgumentException; use Psr\Cache\InvalidArgumentException;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
// Help opcache.preload discover always-needed symbols
class_exists(InvalidArgumentException::class);
/** /**
* An implementation of CacheInterface for PSR-6 CacheItemPoolInterface classes. * An implementation of CacheInterface for PSR-6 CacheItemPoolInterface classes.
* *
@ -41,8 +44,7 @@ trait CacheTrait
private function doGet(CacheItemPoolInterface $pool, string $key, callable $callback, ?float $beta, array &$metadata = null, LoggerInterface $logger = null) private function doGet(CacheItemPoolInterface $pool, string $key, callable $callback, ?float $beta, array &$metadata = null, LoggerInterface $logger = null)
{ {
if (0 > $beta = $beta ?? 1.0) { if (0 > $beta = $beta ?? 1.0) {
throw new class(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', \get_class($this), $beta)) extends \InvalidArgumentException implements InvalidArgumentException { throw new class(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', static::class, $beta)) extends \InvalidArgumentException implements InvalidArgumentException { };
};
} }
$item = $pool->getItem($key); $item = $pool->getItem($key);

View File

@ -1,4 +1,4 @@
Copyright (c) 2018-2019 Fabien Potencier Copyright (c) 2018-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -16,7 +16,7 @@
} }
], ],
"require": { "require": {
"php": "^7.1.3", "php": ">=7.1.3",
"psr/cache": "^1.0" "psr/cache": "^1.0"
}, },
"suggest": { "suggest": {
@ -29,6 +29,10 @@
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.1-dev" "dev-master": "1.1-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
} }
} }
} }

View File

@ -1,4 +1,4 @@
Copyright (c) 2018-2019 Fabien Potencier Copyright (c) 2018-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -16,7 +16,7 @@
} }
], ],
"require": { "require": {
"php": "^7.1.3" "php": ">=7.1.3"
}, },
"suggest": { "suggest": {
"psr/event-dispatcher": "", "psr/event-dispatcher": "",
@ -29,6 +29,10 @@
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.1-dev" "dev-master": "1.1-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
} }
} }
} }

View File

@ -1,4 +1,4 @@
Copyright (c) 2018-2019 Fabien Potencier Copyright (c) 2018-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -155,6 +155,27 @@ switch ($vars['REQUEST_URI']) {
usleep(500); usleep(500);
} }
exit; exit;
case '/json':
header("Content-Type: application/json");
echo json_encode([
'documents' => [
['id' => '/json/1'],
['id' => '/json/2'],
['id' => '/json/3'],
],
]);
exit;
case '/json/1':
case '/json/2':
case '/json/3':
header("Content-Type: application/json");
echo json_encode([
'title' => $vars['REQUEST_URI'],
]);
exit;
} }
header('Content-Type: application/json', true); header('Content-Type: application/json', true);

View File

@ -24,8 +24,6 @@ use Symfony\Contracts\HttpClient\HttpClientInterface;
*/ */
abstract class HttpClientTestCase extends TestCase abstract class HttpClientTestCase extends TestCase
{ {
private static $server;
public static function setUpBeforeClass(): void public static function setUpBeforeClass(): void
{ {
TestHttpServer::start(); TestHttpServer::start();
@ -166,7 +164,7 @@ abstract class HttpClientTestCase extends TestCase
$client = $this->getHttpClient(__FUNCTION__); $client = $this->getHttpClient(__FUNCTION__);
$response = $client->request('GET', 'http://localhost:8057', ['buffer' => function () { $response = $client->request('GET', 'http://localhost:8057', ['buffer' => function () {
throw new \Exception('Boo'); throw new \Exception('Boo.');
}]); }]);
$this->assertSame(200, $response->getStatusCode()); $this->assertSame(200, $response->getStatusCode());
@ -648,7 +646,7 @@ abstract class HttpClientTestCase extends TestCase
$response = $client->request('GET', 'http://localhost:8057/timeout-body', [ $response = $client->request('GET', 'http://localhost:8057/timeout-body', [
'on_progress' => function ($dlNow) { 'on_progress' => function ($dlNow) {
if (0 < $dlNow) { if (0 < $dlNow) {
throw new \Exception('Aborting the request'); throw new \Exception('Aborting the request.');
} }
}, },
]); ]);
@ -658,7 +656,7 @@ abstract class HttpClientTestCase extends TestCase
} }
$this->fail(ClientExceptionInterface::class.' expected'); $this->fail(ClientExceptionInterface::class.' expected');
} catch (TransportExceptionInterface $e) { } catch (TransportExceptionInterface $e) {
$this->assertSame('Aborting the request', $e->getPrevious()->getMessage()); $this->assertSame('Aborting the request.', $e->getPrevious()->getMessage());
} }
$this->assertNotNull($response->getInfo('error')); $this->assertNotNull($response->getInfo('error'));
@ -672,7 +670,7 @@ abstract class HttpClientTestCase extends TestCase
$response = $client->request('GET', 'http://localhost:8057/timeout-body', [ $response = $client->request('GET', 'http://localhost:8057/timeout-body', [
'on_progress' => function ($dlNow) { 'on_progress' => function ($dlNow) {
if (0 < $dlNow) { if (0 < $dlNow) {
throw new \Error('BUG'); throw new \Error('BUG.');
} }
}, },
]); ]);
@ -682,7 +680,7 @@ abstract class HttpClientTestCase extends TestCase
} }
$this->fail('Error expected'); $this->fail('Error expected');
} catch (\Error $e) { } catch (\Error $e) {
$this->assertSame('BUG', $e->getMessage()); $this->assertSame('BUG.', $e->getMessage());
} }
$this->assertNotNull($response->getInfo('error')); $this->assertNotNull($response->getInfo('error'));
@ -705,6 +703,23 @@ abstract class HttpClientTestCase extends TestCase
$client->request('GET', 'http://symfony.com:8057/', ['timeout' => 1]); $client->request('GET', 'http://symfony.com:8057/', ['timeout' => 1]);
} }
public function testIdnResolve()
{
$client = $this->getHttpClient(__FUNCTION__);
$response = $client->request('GET', 'http://0-------------------------------------------------------------0.com:8057/', [
'resolve' => ['0-------------------------------------------------------------0.com' => '127.0.0.1'],
]);
$this->assertSame(200, $response->getStatusCode());
$response = $client->request('GET', 'http://Bücher.example:8057/', [
'resolve' => ['xn--bcher-kva.example' => '127.0.0.1'],
]);
$this->assertSame(200, $response->getStatusCode());
}
public function testNotATimeout() public function testNotATimeout()
{ {
$client = $this->getHttpClient(__FUNCTION__); $client = $this->getHttpClient(__FUNCTION__);
@ -771,6 +786,30 @@ abstract class HttpClientTestCase extends TestCase
} }
} }
public function testTimeoutWithActiveConcurrentStream()
{
$p1 = TestHttpServer::start(8067);
$p2 = TestHttpServer::start(8077);
$client = $this->getHttpClient(__FUNCTION__);
$streamingResponse = $client->request('GET', 'http://localhost:8067/max-duration');
$blockingResponse = $client->request('GET', 'http://localhost:8077/timeout-body', [
'timeout' => 0.25,
]);
$this->assertSame(200, $streamingResponse->getStatusCode());
$this->assertSame(200, $blockingResponse->getStatusCode());
$this->expectException(TransportExceptionInterface::class);
try {
$blockingResponse->getContent();
} finally {
$p1->stop();
$p2->stop();
}
}
public function testDestruct() public function testDestruct()
{ {
$client = $this->getHttpClient(__FUNCTION__); $client = $this->getHttpClient(__FUNCTION__);
@ -784,6 +823,18 @@ abstract class HttpClientTestCase extends TestCase
$this->assertLessThan(4, $duration); $this->assertLessThan(4, $duration);
} }
public function testGetContentAfterDestruct()
{
$client = $this->getHttpClient(__FUNCTION__);
try {
$client->request('GET', 'http://localhost:8057/404');
$this->fail(ClientExceptionInterface::class.' expected');
} catch (ClientExceptionInterface $e) {
$this->assertSame('GET', $e->getResponse()->toArray(false)['REQUEST_METHOD']);
}
}
public function testProxy() public function testProxy()
{ {
$client = $this->getHttpClient(__FUNCTION__); $client = $this->getHttpClient(__FUNCTION__);

View File

@ -19,31 +19,28 @@ use Symfony\Component\Process\Process;
*/ */
class TestHttpServer class TestHttpServer
{ {
private static $server; private static $process = [];
public static function start() public static function start(int $port = 8057)
{ {
if (null !== self::$server) { if (isset(self::$process[$port])) {
return; self::$process[$port]->stop();
} else {
register_shutdown_function(static function () use ($port) {
self::$process[$port]->stop();
});
} }
$finder = new PhpExecutableFinder(); $finder = new PhpExecutableFinder();
$process = new Process(array_merge([$finder->find(false)], $finder->findArguments(), ['-dopcache.enable=0', '-dvariables_order=EGPCS', '-S', '127.0.0.1:8057'])); $process = new Process(array_merge([$finder->find(false)], $finder->findArguments(), ['-dopcache.enable=0', '-dvariables_order=EGPCS', '-S', '127.0.0.1:'.$port]));
$process->setWorkingDirectory(__DIR__.'/Fixtures/web'); $process->setWorkingDirectory(__DIR__.'/Fixtures/web');
$process->setTimeout(300);
$process->start(); $process->start();
self::$process[$port] = $process;
self::$server = new class() { do {
public $process; usleep(50000);
} while (!@fopen('http://127.0.0.1:'.$port, 'r'));
public function __destruct() return $process;
{
$this->process->stop();
}
};
self::$server->process = $process;
sleep('\\' === \DIRECTORY_SEPARATOR ? 10 : 1);
} }
} }

View File

@ -16,7 +16,7 @@
} }
], ],
"require": { "require": {
"php": "^7.1.3" "php": ">=7.1.3"
}, },
"suggest": { "suggest": {
"symfony/http-client-implementation": "" "symfony/http-client-implementation": ""
@ -28,6 +28,10 @@
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.1-dev" "dev-master": "1.1-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
} }
} }
} }

View File

@ -1,4 +1,4 @@
Copyright (c) 2018-2019 Fabien Potencier Copyright (c) 2018-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,4 +1,4 @@
Copyright (c) 2018-2019 Fabien Potencier Copyright (c) 2018-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -14,6 +14,10 @@ namespace Symfony\Contracts\Service;
use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface; use Psr\Container\NotFoundExceptionInterface;
// Help opcache.preload discover always-needed symbols
class_exists(ContainerExceptionInterface::class);
class_exists(NotFoundExceptionInterface::class);
/** /**
* A trait to help implement ServiceProviderInterface. * A trait to help implement ServiceProviderInterface.
* *
@ -83,7 +87,7 @@ trait ServiceLocatorTrait
} else { } else {
$type = (new \ReflectionFunction($factory))->getReturnType(); $type = (new \ReflectionFunction($factory))->getReturnType();
$this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '').$type->getName() : '?'; $this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '').($type instanceof \ReflectionNamedType ? $type->getName() : $type) : '?';
} }
} }
} }

View File

@ -40,7 +40,7 @@ trait ServiceSubscriberTrait
} }
if (self::class === $method->getDeclaringClass()->name && ($returnType = $method->getReturnType()) && !$returnType->isBuiltin()) { if (self::class === $method->getDeclaringClass()->name && ($returnType = $method->getReturnType()) && !$returnType->isBuiltin()) {
$services[self::class.'::'.$method->name] = '?'.$returnType->getName(); $services[self::class.'::'.$method->name] = '?'.($returnType instanceof \ReflectionNamedType ? $returnType->getName() : $type);
} }
} }

View File

@ -16,7 +16,7 @@
} }
], ],
"require": { "require": {
"php": "^7.1.3", "php": ">=7.1.3",
"psr/container": "^1.0" "psr/container": "^1.0"
}, },
"suggest": { "suggest": {
@ -29,6 +29,10 @@
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.1-dev" "dev-master": "1.1-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
} }
} }
} }

View File

@ -1,4 +1,4 @@
Copyright (c) 2018-2019 Fabien Potencier Copyright (c) 2018-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -16,7 +16,7 @@
} }
], ],
"require": { "require": {
"php": "^7.1.3" "php": ">=7.1.3"
}, },
"suggest": { "suggest": {
"symfony/translation-implementation": "" "symfony/translation-implementation": ""
@ -28,6 +28,10 @@
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.1-dev" "dev-master": "1.1-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
} }
} }
} }

View File

@ -16,7 +16,7 @@
} }
], ],
"require": { "require": {
"php": "^7.1.3", "php": ">=7.1.3",
"psr/cache": "^1.0", "psr/cache": "^1.0",
"psr/container": "^1.0" "psr/container": "^1.0"
}, },

View File

@ -1,6 +1,6 @@
<?php <?php
return array( return array (
'A' => 'a', 'A' => 'a',
'B' => 'b', 'B' => 'b',
'C' => 'c', 'C' => 'c',
@ -510,6 +510,138 @@ return array(
'Ⴥ' => 'ⴥ', 'Ⴥ' => 'ⴥ',
'Ⴧ' => 'ⴧ', 'Ⴧ' => 'ⴧ',
'Ⴭ' => 'ⴭ', 'Ⴭ' => 'ⴭ',
'' => 'ꭰ',
'' => 'ꭱ',
'' => 'ꭲ',
'Ꭳ' => 'ꭳ',
'Ꭴ' => 'ꭴ',
'' => '',
'Ꭶ' => 'ꭶ',
'Ꭷ' => 'ꭷ',
'Ꭸ' => 'ꭸ',
'' => 'ꭹ',
'' => 'ꭺ',
'' => 'ꭻ',
'' => 'ꭼ',
'Ꭽ' => 'ꭽ',
'' => 'ꭾ',
'Ꭿ' => 'ꭿ',
'Ꮀ' => 'ꮀ',
'Ꮁ' => '',
'Ꮂ' => 'ꮂ',
'' => '',
'Ꮄ' => 'ꮄ',
'Ꮅ' => 'ꮅ',
'Ꮆ' => 'ꮆ',
'' => 'ꮇ',
'Ꮈ' => 'ꮈ',
'Ꮉ' => 'ꮉ',
'Ꮊ' => 'ꮊ',
'' => 'ꮋ',
'Ꮌ' => 'ꮌ',
'' => 'ꮍ',
'Ꮎ' => 'ꮎ',
'Ꮏ' => 'ꮏ',
'' => 'ꮐ',
'Ꮑ' => 'ꮑ',
'' => 'ꮒ',
'' => '',
'Ꮔ' => 'ꮔ',
'Ꮕ' => 'ꮕ',
'Ꮖ' => 'ꮖ',
'Ꮗ' => 'ꮗ',
'Ꮘ' => 'ꮘ',
'Ꮙ' => 'ꮙ',
'Ꮚ' => 'ꮚ',
'Ꮛ' => 'ꮛ',
'Ꮜ' => 'ꮜ',
'Ꮝ' => 'ꮝ',
'' => 'ꮞ',
'' => 'ꮟ',
'Ꮠ' => 'ꮠ',
'Ꮡ' => 'ꮡ',
'' => 'ꮢ',
'Ꮣ' => 'ꮣ',
'' => 'ꮤ',
'' => 'ꮥ',
'Ꮦ' => 'ꮦ',
'Ꮧ' => 'ꮧ',
'Ꮨ' => 'ꮨ',
'' => '',
'' => '',
'Ꮫ' => 'ꮫ',
'Ꮬ' => 'ꮬ',
'Ꮭ' => 'ꮭ',
'' => 'ꮮ',
'' => '',
'Ꮰ' => 'ꮰ',
'Ꮱ' => 'ꮱ',
'' => 'ꮲ',
'Ꮳ' => 'ꮳ',
'Ꮴ' => 'ꮴ',
'Ꮵ' => 'ꮵ',
'' => 'ꮶ',
'' => 'ꮷ',
'Ꮸ' => 'ꮸ',
'Ꮹ' => 'ꮹ',
'Ꮺ' => 'ꮺ',
'Ꮻ' => 'ꮻ',
'Ꮼ' => 'ꮼ',
'Ꮽ' => 'ꮽ',
'' => 'ꮾ',
'Ꮿ' => 'ꮿ',
'Ᏸ' => 'ᏸ',
'Ᏹ' => 'ᏹ',
'Ᏺ' => 'ᏺ',
'' => 'ᏻ',
'' => 'ᏼ',
'Ᏽ' => 'ᏽ',
'Ა' => 'ა',
'Ბ' => 'ბ',
'Გ' => 'გ',
'Დ' => 'დ',
'Ე' => 'ე',
'Ვ' => 'ვ',
'Ზ' => 'ზ',
'Თ' => 'თ',
'Ი' => 'ი',
'Კ' => 'კ',
'Ლ' => 'ლ',
'Მ' => 'მ',
'Ნ' => 'ნ',
'Ო' => 'ო',
'Პ' => 'პ',
'Ჟ' => 'ჟ',
'Რ' => 'რ',
'Ს' => 'ს',
'Ტ' => 'ტ',
'Უ' => 'უ',
'Ფ' => 'ფ',
'Ქ' => 'ქ',
'Ღ' => 'ღ',
'Ყ' => '',
'Შ' => 'შ',
'Ჩ' => 'ჩ',
'Ც' => 'ც',
'Ძ' => 'ძ',
'Წ' => 'წ',
'Ჭ' => 'ჭ',
'Ხ' => 'ხ',
'Ჯ' => 'ჯ',
'Ჰ' => 'ჰ',
'Ჱ' => 'ჱ',
'Ჲ' => 'ჲ',
'Ჳ' => 'ჳ',
'Ჴ' => 'ჴ',
'Ჵ' => 'ჵ',
'Ჶ' => 'ჶ',
'Ჷ' => 'ჷ',
'Ჸ' => 'ჸ',
'Ჹ' => 'ჹ',
'Ჺ' => 'ჺ',
'Ჽ' => 'ჽ',
'Ჾ' => 'ჾ',
'Ჿ' => '',
'Ḁ' => 'ḁ', 'Ḁ' => 'ḁ',
'Ḃ' => 'ḃ', 'Ḃ' => 'ḃ',
'Ḅ' => 'ḅ', 'Ḅ' => 'ḅ',
@ -993,8 +1125,24 @@ return array(
'' => 'ɜ', '' => 'ɜ',
'Ɡ' => 'ɡ', 'Ɡ' => 'ɡ',
'Ɬ' => 'ɬ', 'Ɬ' => 'ɬ',
'Ɪ' => 'ɪ',
'Ʞ' => 'ʞ', 'Ʞ' => 'ʞ',
'Ʇ' => 'ʇ', 'Ʇ' => 'ʇ',
'' => 'ʝ',
'' => 'ꭓ',
'' => 'ꞵ',
'Ꞷ' => 'ꞷ',
'Ꞹ' => 'ꞹ',
'Ꞻ' => 'ꞻ',
'Ꞽ' => 'ꞽ',
'Ꞿ' => 'ꞿ',
'Ꟃ' => 'ꟃ',
'Ꞔ' => 'ꞔ',
'Ʂ' => 'ʂ',
'Ᶎ' => 'ᶎ',
'Ꟈ' => 'ꟈ',
'Ꟊ' => 'ꟊ',
'Ꟶ' => 'ꟶ',
'' => '', '' => '',
'' => '', '' => '',
'' => '', '' => '',
@ -1061,6 +1209,93 @@ return array(
'𐐥' => '𐑍', '𐐥' => '𐑍',
'𐐦' => '𐑎', '𐐦' => '𐑎',
'𐐧' => '𐑏', '𐐧' => '𐑏',
'𐒰' => '𐓘',
'𐒱' => '𐓙',
'𐒲' => '𐓚',
'𐒳' => '𐓛',
'𐒴' => '𐓜',
'𐒵' => '𐓝',
'𐒶' => '𐓞',
'𐒷' => '𐓟',
'𐒸' => '𐓠',
'𐒹' => '𐓡',
'𐒺' => '𐓢',
'𐒻' => '𐓣',
'𐒼' => '𐓤',
'𐒽' => '𐓥',
'𐒾' => '𐓦',
'𐒿' => '𐓧',
'𐓀' => '𐓨',
'𐓁' => '𐓩',
'𐓂' => '𐓪',
'𐓃' => '𐓫',
'𐓄' => '𐓬',
'𐓅' => '𐓭',
'𐓆' => '𐓮',
'𐓇' => '𐓯',
'𐓈' => '𐓰',
'𐓉' => '𐓱',
'𐓊' => '𐓲',
'𐓋' => '𐓳',
'𐓌' => '𐓴',
'𐓍' => '𐓵',
'𐓎' => '𐓶',
'𐓏' => '𐓷',
'𐓐' => '𐓸',
'𐓑' => '𐓹',
'𐓒' => '𐓺',
'𐓓' => '𐓻',
'𐲀' => '𐳀',
'𐲁' => '𐳁',
'𐲂' => '𐳂',
'𐲃' => '𐳃',
'𐲄' => '𐳄',
'𐲅' => '𐳅',
'𐲆' => '𐳆',
'𐲇' => '𐳇',
'𐲈' => '𐳈',
'𐲉' => '𐳉',
'𐲊' => '𐳊',
'𐲋' => '𐳋',
'𐲌' => '𐳌',
'𐲍' => '𐳍',
'𐲎' => '𐳎',
'𐲏' => '𐳏',
'𐲐' => '𐳐',
'𐲑' => '𐳑',
'𐲒' => '𐳒',
'𐲓' => '𐳓',
'𐲔' => '𐳔',
'𐲕' => '𐳕',
'𐲖' => '𐳖',
'𐲗' => '𐳗',
'𐲘' => '𐳘',
'𐲙' => '𐳙',
'𐲚' => '𐳚',
'𐲛' => '𐳛',
'𐲜' => '𐳜',
'𐲝' => '𐳝',
'𐲞' => '𐳞',
'𐲟' => '𐳟',
'𐲠' => '𐳠',
'𐲡' => '𐳡',
'𐲢' => '𐳢',
'𐲣' => '𐳣',
'𐲤' => '𐳤',
'𐲥' => '𐳥',
'𐲦' => '𐳦',
'𐲧' => '𐳧',
'𐲨' => '𐳨',
'𐲩' => '𐳩',
'𐲪' => '𐳪',
'𐲫' => '𐳫',
'𐲬' => '𐳬',
'𐲭' => '𐳭',
'𐲮' => '𐳮',
'𐲯' => '𐳯',
'𐲰' => '𐳰',
'𐲱' => '𐳱',
'𐲲' => '𐳲',
'𑢠' => '𑣀', '𑢠' => '𑣀',
'𑢡' => '𑣁', '𑢡' => '𑣁',
'𑢢' => '𑣂', '𑢢' => '𑣂',
@ -1093,4 +1328,70 @@ return array(
'𑢽' => '𑣝', '𑢽' => '𑣝',
'𑢾' => '𑣞', '𑢾' => '𑣞',
'𑢿' => '𑣟', '𑢿' => '𑣟',
'𖹀' => '𖹠',
'𖹁' => '𖹡',
'𖹂' => '𖹢',
'𖹃' => '𖹣',
'𖹄' => '𖹤',
'𖹅' => '𖹥',
'𖹆' => '𖹦',
'𖹇' => '𖹧',
'𖹈' => '𖹨',
'𖹉' => '𖹩',
'𖹊' => '𖹪',
'𖹋' => '𖹫',
'𖹌' => '𖹬',
'𖹍' => '𖹭',
'𖹎' => '𖹮',
'𖹏' => '𖹯',
'𖹐' => '𖹰',
'𖹑' => '𖹱',
'𖹒' => '𖹲',
'𖹓' => '𖹳',
'𖹔' => '𖹴',
'𖹕' => '𖹵',
'𖹖' => '𖹶',
'𖹗' => '𖹷',
'𖹘' => '𖹸',
'𖹙' => '𖹹',
'𖹚' => '𖹺',
'𖹛' => '𖹻',
'𖹜' => '𖹼',
'𖹝' => '𖹽',
'𖹞' => '𖹾',
'𖹟' => '𖹿',
'𞤀' => '𞤢',
'𞤁' => '𞤣',
'𞤂' => '𞤤',
'𞤃' => '𞤥',
'𞤄' => '𞤦',
'𞤅' => '𞤧',
'𞤆' => '𞤨',
'𞤇' => '𞤩',
'𞤈' => '𞤪',
'𞤉' => '𞤫',
'𞤊' => '𞤬',
'𞤋' => '𞤭',
'𞤌' => '𞤮',
'𞤍' => '𞤯',
'𞤎' => '𞤰',
'𞤏' => '𞤱',
'𞤐' => '𞤲',
'𞤑' => '𞤳',
'𞤒' => '𞤴',
'𞤓' => '𞤵',
'𞤔' => '𞤶',
'𞤕' => '𞤷',
'𞤖' => '𞤸',
'𞤗' => '𞤹',
'𞤘' => '𞤺',
'𞤙' => '𞤻',
'𞤚' => '𞤼',
'𞤛' => '𞤽',
'𞤜' => '𞤾',
'𞤝' => '𞤿',
'𞤞' => '𞥀',
'𞤟' => '𞥁',
'𞤠' => '𞥂',
'𞤡' => '𞥃',
); );

View File

@ -1,6 +1,6 @@
<?php <?php
return array( return array (
'a' => 'A', 'a' => 'A',
'b' => 'B', 'b' => 'B',
'c' => 'C', 'c' => 'C',
@ -225,6 +225,7 @@ return array(
'ɦ' => 'Ɦ', 'ɦ' => 'Ɦ',
'ɨ' => 'Ɨ', 'ɨ' => 'Ɨ',
'ɩ' => 'Ɩ', 'ɩ' => 'Ɩ',
'ɪ' => 'Ɪ',
'ɫ' => 'Ɫ', 'ɫ' => 'Ɫ',
'ɬ' => 'Ɬ', 'ɬ' => 'Ɬ',
'ɯ' => 'Ɯ', 'ɯ' => 'Ɯ',
@ -233,6 +234,7 @@ return array(
'ɵ' => 'Ɵ', 'ɵ' => 'Ɵ',
'ɽ' => 'Ɽ', 'ɽ' => 'Ɽ',
'ʀ' => 'Ʀ', 'ʀ' => 'Ʀ',
'ʂ' => 'Ʂ',
'ʃ' => 'Ʃ', 'ʃ' => 'Ʃ',
'ʇ' => 'Ʇ', 'ʇ' => 'Ʇ',
'ʈ' => 'Ʈ', 'ʈ' => 'Ʈ',
@ -241,6 +243,7 @@ return array(
'ʋ' => 'Ʋ', 'ʋ' => 'Ʋ',
'ʌ' => 'Ʌ', 'ʌ' => 'Ʌ',
'ʒ' => 'Ʒ', 'ʒ' => 'Ʒ',
'ʝ' => '',
'ʞ' => 'Ʞ', 'ʞ' => 'Ʞ',
'ͅ' => 'Ι', 'ͅ' => 'Ι',
'ͱ' => 'Ͱ', 'ͱ' => 'Ͱ',
@ -493,8 +496,70 @@ return array(
'ք' => 'Ք', 'ք' => 'Ք',
'օ' => 'Օ', 'օ' => 'Օ',
'ֆ' => 'Ֆ', 'ֆ' => 'Ֆ',
'ა' => 'Ა',
'ბ' => 'Ბ',
'გ' => 'Გ',
'დ' => 'Დ',
'ე' => 'Ე',
'ვ' => 'Ვ',
'ზ' => 'Ზ',
'თ' => 'Თ',
'ი' => 'Ი',
'კ' => 'Კ',
'ლ' => 'Ლ',
'მ' => 'Მ',
'ნ' => 'Ნ',
'ო' => 'Ო',
'პ' => 'Პ',
'ჟ' => 'Ჟ',
'რ' => 'Რ',
'ს' => 'Ს',
'ტ' => 'Ტ',
'უ' => 'Უ',
'ფ' => 'Ფ',
'ქ' => 'Ქ',
'ღ' => 'Ღ',
'' => 'Ყ',
'შ' => 'Შ',
'ჩ' => 'Ჩ',
'ც' => 'Ც',
'ძ' => 'Ძ',
'წ' => 'Წ',
'ჭ' => 'Ჭ',
'ხ' => 'Ხ',
'ჯ' => 'Ჯ',
'ჰ' => 'Ჰ',
'ჱ' => 'Ჱ',
'ჲ' => 'Ჲ',
'ჳ' => 'Ჳ',
'ჴ' => 'Ჴ',
'ჵ' => 'Ჵ',
'ჶ' => 'Ჶ',
'ჷ' => 'Ჷ',
'ჸ' => 'Ჸ',
'ჹ' => 'Ჹ',
'ჺ' => 'Ჺ',
'ჽ' => 'Ჽ',
'ჾ' => 'Ჾ',
'' => 'Ჿ',
'ᏸ' => 'Ᏸ',
'ᏹ' => 'Ᏹ',
'ᏺ' => 'Ᏺ',
'ᏻ' => '',
'ᏼ' => '',
'ᏽ' => 'Ᏽ',
'ᲀ' => 'В',
'ᲁ' => 'Д',
'ᲂ' => 'О',
'ᲃ' => 'С',
'ᲄ' => 'Т',
'ᲅ' => 'Т',
'ᲆ' => 'Ъ',
'ᲇ' => 'Ѣ',
'ᲈ' => 'Ꙋ',
'ᵹ' => 'Ᵹ', 'ᵹ' => 'Ᵹ',
'ᵽ' => 'Ᵽ', 'ᵽ' => 'Ᵽ',
'ᶎ' => 'Ᶎ',
'ḁ' => 'Ḁ', 'ḁ' => 'Ḁ',
'ḃ' => 'Ḃ', 'ḃ' => 'Ḃ',
'ḅ' => 'Ḅ', 'ḅ' => 'Ḅ',
@ -993,6 +1058,7 @@ return array(
'' => 'Ꞌ', '' => 'Ꞌ',
'ꞑ' => 'Ꞑ', 'ꞑ' => 'Ꞑ',
'ꞓ' => 'Ꞓ', 'ꞓ' => 'Ꞓ',
'ꞔ' => 'Ꞔ',
'ꞗ' => 'Ꞗ', 'ꞗ' => 'Ꞗ',
'' => '', '' => '',
'ꞛ' => 'Ꞛ', 'ꞛ' => 'Ꞛ',
@ -1003,6 +1069,97 @@ return array(
'ꞥ' => 'Ꞥ', 'ꞥ' => 'Ꞥ',
'ꞧ' => 'Ꞧ', 'ꞧ' => 'Ꞧ',
'ꞩ' => 'Ꞩ', 'ꞩ' => 'Ꞩ',
'ꞵ' => '',
'ꞷ' => 'Ꞷ',
'ꞹ' => 'Ꞹ',
'ꞻ' => 'Ꞻ',
'ꞽ' => 'Ꞽ',
'ꞿ' => 'Ꞿ',
'ꟃ' => 'Ꟃ',
'ꟈ' => 'Ꟈ',
'ꟊ' => 'Ꟊ',
'ꟶ' => 'Ꟶ',
'ꭓ' => '',
'ꭰ' => '',
'ꭱ' => '',
'ꭲ' => '',
'ꭳ' => 'Ꭳ',
'ꭴ' => 'Ꭴ',
'' => '',
'ꭶ' => 'Ꭶ',
'ꭷ' => 'Ꭷ',
'ꭸ' => 'Ꭸ',
'ꭹ' => '',
'ꭺ' => '',
'ꭻ' => '',
'ꭼ' => '',
'ꭽ' => 'Ꭽ',
'ꭾ' => '',
'ꭿ' => 'Ꭿ',
'ꮀ' => 'Ꮀ',
'' => 'Ꮁ',
'ꮂ' => 'Ꮂ',
'' => '',
'ꮄ' => 'Ꮄ',
'ꮅ' => 'Ꮅ',
'ꮆ' => 'Ꮆ',
'ꮇ' => '',
'ꮈ' => 'Ꮈ',
'ꮉ' => 'Ꮉ',
'ꮊ' => 'Ꮊ',
'ꮋ' => '',
'ꮌ' => 'Ꮌ',
'ꮍ' => '',
'ꮎ' => 'Ꮎ',
'ꮏ' => 'Ꮏ',
'ꮐ' => '',
'ꮑ' => 'Ꮑ',
'ꮒ' => '',
'' => '',
'ꮔ' => 'Ꮔ',
'ꮕ' => 'Ꮕ',
'ꮖ' => 'Ꮖ',
'ꮗ' => 'Ꮗ',
'ꮘ' => 'Ꮘ',
'ꮙ' => 'Ꮙ',
'ꮚ' => 'Ꮚ',
'ꮛ' => 'Ꮛ',
'ꮜ' => 'Ꮜ',
'ꮝ' => 'Ꮝ',
'ꮞ' => '',
'ꮟ' => '',
'ꮠ' => 'Ꮠ',
'ꮡ' => 'Ꮡ',
'ꮢ' => '',
'ꮣ' => 'Ꮣ',
'ꮤ' => '',
'ꮥ' => '',
'ꮦ' => 'Ꮦ',
'ꮧ' => 'Ꮧ',
'ꮨ' => 'Ꮨ',
'' => '',
'' => '',
'ꮫ' => 'Ꮫ',
'ꮬ' => 'Ꮬ',
'ꮭ' => 'Ꮭ',
'ꮮ' => '',
'' => '',
'ꮰ' => 'Ꮰ',
'ꮱ' => 'Ꮱ',
'ꮲ' => '',
'ꮳ' => 'Ꮳ',
'ꮴ' => 'Ꮴ',
'ꮵ' => 'Ꮵ',
'ꮶ' => '',
'ꮷ' => '',
'ꮸ' => 'Ꮸ',
'ꮹ' => 'Ꮹ',
'ꮺ' => 'Ꮺ',
'ꮻ' => 'Ꮻ',
'ꮼ' => 'Ꮼ',
'ꮽ' => 'Ꮽ',
'ꮾ' => '',
'ꮿ' => 'Ꮿ',
'' => '', '' => '',
'' => '', '' => '',
'' => '', '' => '',
@ -1069,6 +1226,93 @@ return array(
'𐑍' => '𐐥', '𐑍' => '𐐥',
'𐑎' => '𐐦', '𐑎' => '𐐦',
'𐑏' => '𐐧', '𐑏' => '𐐧',
'𐓘' => '𐒰',
'𐓙' => '𐒱',
'𐓚' => '𐒲',
'𐓛' => '𐒳',
'𐓜' => '𐒴',
'𐓝' => '𐒵',
'𐓞' => '𐒶',
'𐓟' => '𐒷',
'𐓠' => '𐒸',
'𐓡' => '𐒹',
'𐓢' => '𐒺',
'𐓣' => '𐒻',
'𐓤' => '𐒼',
'𐓥' => '𐒽',
'𐓦' => '𐒾',
'𐓧' => '𐒿',
'𐓨' => '𐓀',
'𐓩' => '𐓁',
'𐓪' => '𐓂',
'𐓫' => '𐓃',
'𐓬' => '𐓄',
'𐓭' => '𐓅',
'𐓮' => '𐓆',
'𐓯' => '𐓇',
'𐓰' => '𐓈',
'𐓱' => '𐓉',
'𐓲' => '𐓊',
'𐓳' => '𐓋',
'𐓴' => '𐓌',
'𐓵' => '𐓍',
'𐓶' => '𐓎',
'𐓷' => '𐓏',
'𐓸' => '𐓐',
'𐓹' => '𐓑',
'𐓺' => '𐓒',
'𐓻' => '𐓓',
'𐳀' => '𐲀',
'𐳁' => '𐲁',
'𐳂' => '𐲂',
'𐳃' => '𐲃',
'𐳄' => '𐲄',
'𐳅' => '𐲅',
'𐳆' => '𐲆',
'𐳇' => '𐲇',
'𐳈' => '𐲈',
'𐳉' => '𐲉',
'𐳊' => '𐲊',
'𐳋' => '𐲋',
'𐳌' => '𐲌',
'𐳍' => '𐲍',
'𐳎' => '𐲎',
'𐳏' => '𐲏',
'𐳐' => '𐲐',
'𐳑' => '𐲑',
'𐳒' => '𐲒',
'𐳓' => '𐲓',
'𐳔' => '𐲔',
'𐳕' => '𐲕',
'𐳖' => '𐲖',
'𐳗' => '𐲗',
'𐳘' => '𐲘',
'𐳙' => '𐲙',
'𐳚' => '𐲚',
'𐳛' => '𐲛',
'𐳜' => '𐲜',
'𐳝' => '𐲝',
'𐳞' => '𐲞',
'𐳟' => '𐲟',
'𐳠' => '𐲠',
'𐳡' => '𐲡',
'𐳢' => '𐲢',
'𐳣' => '𐲣',
'𐳤' => '𐲤',
'𐳥' => '𐲥',
'𐳦' => '𐲦',
'𐳧' => '𐲧',
'𐳨' => '𐲨',
'𐳩' => '𐲩',
'𐳪' => '𐲪',
'𐳫' => '𐲫',
'𐳬' => '𐲬',
'𐳭' => '𐲭',
'𐳮' => '𐲮',
'𐳯' => '𐲯',
'𐳰' => '𐲰',
'𐳱' => '𐲱',
'𐳲' => '𐲲',
'𑣀' => '𑢠', '𑣀' => '𑢠',
'𑣁' => '𑢡', '𑣁' => '𑢡',
'𑣂' => '𑢢', '𑣂' => '𑢢',
@ -1101,4 +1345,70 @@ return array(
'𑣝' => '𑢽', '𑣝' => '𑢽',
'𑣞' => '𑢾', '𑣞' => '𑢾',
'𑣟' => '𑢿', '𑣟' => '𑢿',
'𖹠' => '𖹀',
'𖹡' => '𖹁',
'𖹢' => '𖹂',
'𖹣' => '𖹃',
'𖹤' => '𖹄',
'𖹥' => '𖹅',
'𖹦' => '𖹆',
'𖹧' => '𖹇',
'𖹨' => '𖹈',
'𖹩' => '𖹉',
'𖹪' => '𖹊',
'𖹫' => '𖹋',
'𖹬' => '𖹌',
'𖹭' => '𖹍',
'𖹮' => '𖹎',
'𖹯' => '𖹏',
'𖹰' => '𖹐',
'𖹱' => '𖹑',
'𖹲' => '𖹒',
'𖹳' => '𖹓',
'𖹴' => '𖹔',
'𖹵' => '𖹕',
'𖹶' => '𖹖',
'𖹷' => '𖹗',
'𖹸' => '𖹘',
'𖹹' => '𖹙',
'𖹺' => '𖹚',
'𖹻' => '𖹛',
'𖹼' => '𖹜',
'𖹽' => '𖹝',
'𖹾' => '𖹞',
'𖹿' => '𖹟',
'𞤢' => '𞤀',
'𞤣' => '𞤁',
'𞤤' => '𞤂',
'𞤥' => '𞤃',
'𞤦' => '𞤄',
'𞤧' => '𞤅',
'𞤨' => '𞤆',
'𞤩' => '𞤇',
'𞤪' => '𞤈',
'𞤫' => '𞤉',
'𞤬' => '𞤊',
'𞤭' => '𞤋',
'𞤮' => '𞤌',
'𞤯' => '𞤍',
'𞤰' => '𞤎',
'𞤱' => '𞤏',
'𞤲' => '𞤐',
'𞤳' => '𞤑',
'𞤴' => '𞤒',
'𞤵' => '𞤓',
'𞤶' => '𞤔',
'𞤷' => '𞤕',
'𞤸' => '𞤖',
'𞤹' => '𞤗',
'𞤺' => '𞤘',
'𞤻' => '𞤙',
'𞤼' => '𞤚',
'𞤽' => '𞤛',
'𞤾' => '𞤜',
'𞤿' => '𞤝',
'𞥀' => '𞤞',
'𞥁' => '𞤟',
'𞥂' => '𞤠',
'𞥃' => '𞤡',
); );

View File

@ -28,7 +28,11 @@
"minimum-stability": "dev", "minimum-stability": "dev",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.17-dev" "dev-master": "1.18-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
} }
} }
} }