[ini]
This commit is contained in:
commit
6033cea60e
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/.geany
|
||||
/build/
|
||||
13
conf/example.json
Normal file
13
conf/example.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"auth": {
|
||||
"kind": "none",
|
||||
"data": null
|
||||
},
|
||||
"source": {
|
||||
"kind": "ics_feed",
|
||||
"data": {
|
||||
"url": "https://export.kalender.digital/ics/0/3e10dae66950379d4cc8/gesamterkalender.ics?past_months=1&future_months=2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
6
lib/composer/composer.json
Normal file
6
lib/composer/composer.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"require": {
|
||||
"sabre/dav": "^4.7",
|
||||
"johngrogg/ics-parser": "^3.4"
|
||||
}
|
||||
}
|
||||
578
lib/composer/composer.lock
generated
Normal file
578
lib/composer/composer.lock
generated
Normal file
|
|
@ -0,0 +1,578 @@
|
|||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "4bccd22e60e62b03ff088076eeaf58ba",
|
||||
"packages": [
|
||||
{
|
||||
"name": "johngrogg/ics-parser",
|
||||
"version": "v3.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/u01jmg3/ics-parser.git",
|
||||
"reference": "abb41a4a46256389aa4e6f582bad76f0d4cb3ebc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/u01jmg3/ics-parser/zipball/abb41a4a46256389aa4e6f582bad76f0d4cb3ebc",
|
||||
"reference": "abb41a4a46256389aa4e6f582bad76f0d4cb3ebc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=5.6.40"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5|^9|^10"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"ICal": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jonathan Goode",
|
||||
"role": "Developer/Owner"
|
||||
},
|
||||
{
|
||||
"name": "John Grogg",
|
||||
"email": "john.grogg@gmail.com",
|
||||
"role": "Developer/Prior Owner"
|
||||
}
|
||||
],
|
||||
"description": "ICS Parser",
|
||||
"homepage": "https://github.com/u01jmg3/ics-parser",
|
||||
"keywords": [
|
||||
"iCalendar",
|
||||
"ical",
|
||||
"ical-parser",
|
||||
"ics",
|
||||
"ics-parser",
|
||||
"ifb"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/u01jmg3/ics-parser/issues",
|
||||
"source": "https://github.com/u01jmg3/ics-parser/tree/v3.4.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sponsors/u01jmg3",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-06-26T08:18:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "3.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/log.git",
|
||||
"reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
|
||||
"reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Log\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for logging libraries",
|
||||
"homepage": "https://github.com/php-fig/log",
|
||||
"keywords": [
|
||||
"log",
|
||||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/log/tree/3.0.2"
|
||||
},
|
||||
"time": "2024-09-11T13:17:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sabre/dav",
|
||||
"version": "4.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sabre-io/dav.git",
|
||||
"reference": "074373bcd689a30bcf5aaa6bbb20a3395964ce7a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sabre-io/dav/zipball/074373bcd689a30bcf5aaa6bbb20a3395964ce7a",
|
||||
"reference": "074373bcd689a30bcf5aaa6bbb20a3395964ce7a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"ext-date": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-iconv": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-spl": "*",
|
||||
"lib-libxml": ">=2.7.0",
|
||||
"php": "^7.1.0 || ^8.0",
|
||||
"psr/log": "^1.0 || ^2.0 || ^3.0",
|
||||
"sabre/event": "^5.0",
|
||||
"sabre/http": "^5.0.5",
|
||||
"sabre/uri": "^2.0",
|
||||
"sabre/vobject": "^4.2.1",
|
||||
"sabre/xml": "^2.0.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.19",
|
||||
"monolog/monolog": "^1.27 || ^2.0",
|
||||
"phpstan/phpstan": "^0.12 || ^1.0",
|
||||
"phpstan/phpstan-phpunit": "^1.0",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.6"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-curl": "*",
|
||||
"ext-imap": "*",
|
||||
"ext-pdo": "*"
|
||||
},
|
||||
"bin": [
|
||||
"bin/sabredav",
|
||||
"bin/naturalselection"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Sabre\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Evert Pot",
|
||||
"email": "me@evertpot.com",
|
||||
"homepage": "http://evertpot.com/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "WebDAV Framework for PHP",
|
||||
"homepage": "http://sabre.io/",
|
||||
"keywords": [
|
||||
"CalDAV",
|
||||
"CardDAV",
|
||||
"WebDAV",
|
||||
"framework",
|
||||
"iCalendar"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://groups.google.com/group/sabredav-discuss",
|
||||
"issues": "https://github.com/sabre-io/dav/issues",
|
||||
"source": "https://github.com/fruux/sabre-dav"
|
||||
},
|
||||
"time": "2024-10-29T11:46:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sabre/event",
|
||||
"version": "5.1.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sabre-io/event.git",
|
||||
"reference": "86d57e305c272898ba3c28e9bd3d65d5464587c2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sabre-io/event/zipball/86d57e305c272898ba3c28e9bd3d65d5464587c2",
|
||||
"reference": "86d57e305c272898ba3c28e9bd3d65d5464587c2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "~2.17.1||^3.63",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.6"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/coroutine.php",
|
||||
"lib/Loop/functions.php",
|
||||
"lib/Promise/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Sabre\\Event\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Evert Pot",
|
||||
"email": "me@evertpot.com",
|
||||
"homepage": "http://evertpot.com/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "sabre/event is a library for lightweight event-based programming",
|
||||
"homepage": "http://sabre.io/event/",
|
||||
"keywords": [
|
||||
"EventEmitter",
|
||||
"async",
|
||||
"coroutine",
|
||||
"eventloop",
|
||||
"events",
|
||||
"hooks",
|
||||
"plugin",
|
||||
"promise",
|
||||
"reactor",
|
||||
"signal"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://groups.google.com/group/sabredav-discuss",
|
||||
"issues": "https://github.com/sabre-io/event/issues",
|
||||
"source": "https://github.com/fruux/sabre-event"
|
||||
},
|
||||
"time": "2024-08-27T11:23:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sabre/http",
|
||||
"version": "5.1.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sabre-io/http.git",
|
||||
"reference": "dedff73f3995578bc942fa4c8484190cac14f139"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sabre-io/http/zipball/dedff73f3995578bc942fa4c8484190cac14f139",
|
||||
"reference": "dedff73f3995578bc942fa4c8484190cac14f139",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"sabre/event": ">=4.0 <6.0",
|
||||
"sabre/uri": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "~2.17.1||^3.63",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.6"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-curl": " to make http requests with the Client class"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Sabre\\HTTP\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Evert Pot",
|
||||
"email": "me@evertpot.com",
|
||||
"homepage": "http://evertpot.com/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "The sabre/http library provides utilities for dealing with http requests and responses. ",
|
||||
"homepage": "https://github.com/fruux/sabre-http",
|
||||
"keywords": [
|
||||
"http"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://groups.google.com/group/sabredav-discuss",
|
||||
"issues": "https://github.com/sabre-io/http/issues",
|
||||
"source": "https://github.com/fruux/sabre-http"
|
||||
},
|
||||
"time": "2024-08-27T16:07:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sabre/uri",
|
||||
"version": "2.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sabre-io/uri.git",
|
||||
"reference": "b76524c22de90d80ca73143680a8e77b1266c291"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sabre-io/uri/zipball/b76524c22de90d80ca73143680a8e77b1266c291",
|
||||
"reference": "b76524c22de90d80ca73143680a8e77b1266c291",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.63",
|
||||
"phpstan/extension-installer": "^1.4",
|
||||
"phpstan/phpstan": "^1.12",
|
||||
"phpstan/phpstan-phpunit": "^1.4",
|
||||
"phpstan/phpstan-strict-rules": "^1.6",
|
||||
"phpunit/phpunit": "^9.6"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Sabre\\Uri\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Evert Pot",
|
||||
"email": "me@evertpot.com",
|
||||
"homepage": "http://evertpot.com/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Functions for making sense out of URIs.",
|
||||
"homepage": "http://sabre.io/uri/",
|
||||
"keywords": [
|
||||
"rfc3986",
|
||||
"uri",
|
||||
"url"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://groups.google.com/group/sabredav-discuss",
|
||||
"issues": "https://github.com/sabre-io/uri/issues",
|
||||
"source": "https://github.com/fruux/sabre-uri"
|
||||
},
|
||||
"time": "2024-08-27T12:18:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sabre/vobject",
|
||||
"version": "4.5.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sabre-io/vobject.git",
|
||||
"reference": "ff22611a53782e90c97be0d0bc4a5f98a5c0a12c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sabre-io/vobject/zipball/ff22611a53782e90c97be0d0bc4a5f98a5c0a12c",
|
||||
"reference": "ff22611a53782e90c97be0d0bc4a5f98a5c0a12c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"sabre/xml": "^2.1 || ^3.0 || ^4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "~2.17.1",
|
||||
"phpstan/phpstan": "^0.12 || ^1.12 || ^2.0",
|
||||
"phpunit/php-invoker": "^2.0 || ^3.1",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.6"
|
||||
},
|
||||
"suggest": {
|
||||
"hoa/bench": "If you would like to run the benchmark scripts"
|
||||
},
|
||||
"bin": [
|
||||
"bin/vobject",
|
||||
"bin/generate_vcards"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Sabre\\VObject\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Evert Pot",
|
||||
"email": "me@evertpot.com",
|
||||
"homepage": "http://evertpot.com/",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Dominik Tobschall",
|
||||
"email": "dominik@fruux.com",
|
||||
"homepage": "http://tobschall.de/",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Ivan Enderlin",
|
||||
"email": "ivan.enderlin@hoa-project.net",
|
||||
"homepage": "http://mnt.io/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects",
|
||||
"homepage": "http://sabre.io/vobject/",
|
||||
"keywords": [
|
||||
"availability",
|
||||
"freebusy",
|
||||
"iCalendar",
|
||||
"ical",
|
||||
"ics",
|
||||
"jCal",
|
||||
"jCard",
|
||||
"recurrence",
|
||||
"rfc2425",
|
||||
"rfc2426",
|
||||
"rfc2739",
|
||||
"rfc4770",
|
||||
"rfc5545",
|
||||
"rfc5546",
|
||||
"rfc6321",
|
||||
"rfc6350",
|
||||
"rfc6351",
|
||||
"rfc6474",
|
||||
"rfc6638",
|
||||
"rfc6715",
|
||||
"rfc6868",
|
||||
"vCalendar",
|
||||
"vCard",
|
||||
"vcf",
|
||||
"xCal",
|
||||
"xCard"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://groups.google.com/group/sabredav-discuss",
|
||||
"issues": "https://github.com/sabre-io/vobject/issues",
|
||||
"source": "https://github.com/fruux/sabre-vobject"
|
||||
},
|
||||
"time": "2025-04-17T09:22:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sabre/xml",
|
||||
"version": "2.2.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sabre-io/xml.git",
|
||||
"reference": "01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sabre-io/xml/zipball/01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc",
|
||||
"reference": "01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-xmlreader": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"lib-libxml": ">=2.6.20",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"sabre/uri": ">=1.0,<3.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "~2.17.1||3.63.2",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.6"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/Deserializer/functions.php",
|
||||
"lib/Serializer/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Sabre\\Xml\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Evert Pot",
|
||||
"email": "me@evertpot.com",
|
||||
"homepage": "http://evertpot.com/",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Markus Staab",
|
||||
"email": "markus.staab@redaxo.de",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "sabre/xml is an XML library that you may not hate.",
|
||||
"homepage": "https://sabre.io/xml/",
|
||||
"keywords": [
|
||||
"XMLReader",
|
||||
"XMLWriter",
|
||||
"dom",
|
||||
"xml"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://groups.google.com/group/sabredav-discuss",
|
||||
"issues": "https://github.com/sabre-io/xml/issues",
|
||||
"source": "https://github.com/fruux/sabre-xml"
|
||||
},
|
||||
"time": "2024-09-06T07:37:46+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
25
lib/composer/vendor/autoload.php
vendored
Normal file
25
lib/composer/vendor/autoload.php
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, $err);
|
||||
} elseif (!headers_sent()) {
|
||||
echo $err;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
$err,
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInite6a6e754980b2e4ee0099ab3b538a42e::getLoader();
|
||||
119
lib/composer/vendor/bin/generate_vcards
vendored
Executable file
119
lib/composer/vendor/bin/generate_vcards
vendored
Executable file
|
|
@ -0,0 +1,119 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../sabre/vobject/bin/generate_vcards)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? flock($this->handle, $operation) : true;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = ftell($this->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = substr($path, 17);
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||
) {
|
||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/sabre/vobject/bin/generate_vcards');
|
||||
}
|
||||
}
|
||||
|
||||
return include __DIR__ . '/..'.'/sabre/vobject/bin/generate_vcards';
|
||||
37
lib/composer/vendor/bin/naturalselection
vendored
Executable file
37
lib/composer/vendor/bin/naturalselection
vendored
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Support bash to support `source` with fallback on $0 if this does not run with bash
|
||||
# https://stackoverflow.com/a/35006505/6512
|
||||
selfArg="$BASH_SOURCE"
|
||||
if [ -z "$selfArg" ]; then
|
||||
selfArg="$0"
|
||||
fi
|
||||
|
||||
self=$(realpath $selfArg 2> /dev/null)
|
||||
if [ -z "$self" ]; then
|
||||
self="$selfArg"
|
||||
fi
|
||||
|
||||
dir=$(cd "${self%[/\\]*}" > /dev/null; cd '../sabre/dav/bin' && pwd)
|
||||
|
||||
if [ -d /proc/cygdrive ]; then
|
||||
case $(which php) in
|
||||
$(readlink -n /proc/cygdrive)/*)
|
||||
# We are in Cygwin using Windows php, so the path must be translated
|
||||
dir=$(cygpath -m "$dir");
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
export COMPOSER_RUNTIME_BIN_DIR="$(cd "${self%[/\\]*}" > /dev/null; pwd)"
|
||||
|
||||
# If bash is sourcing this file, we have to source the target as well
|
||||
bashSource="$BASH_SOURCE"
|
||||
if [ -n "$bashSource" ]; then
|
||||
if [ "$bashSource" != "$0" ]; then
|
||||
source "${dir}/naturalselection" "$@"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
"${dir}/naturalselection" "$@"
|
||||
37
lib/composer/vendor/bin/sabredav
vendored
Executable file
37
lib/composer/vendor/bin/sabredav
vendored
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Support bash to support `source` with fallback on $0 if this does not run with bash
|
||||
# https://stackoverflow.com/a/35006505/6512
|
||||
selfArg="$BASH_SOURCE"
|
||||
if [ -z "$selfArg" ]; then
|
||||
selfArg="$0"
|
||||
fi
|
||||
|
||||
self=$(realpath $selfArg 2> /dev/null)
|
||||
if [ -z "$self" ]; then
|
||||
self="$selfArg"
|
||||
fi
|
||||
|
||||
dir=$(cd "${self%[/\\]*}" > /dev/null; cd '../sabre/dav/bin' && pwd)
|
||||
|
||||
if [ -d /proc/cygdrive ]; then
|
||||
case $(which php) in
|
||||
$(readlink -n /proc/cygdrive)/*)
|
||||
# We are in Cygwin using Windows php, so the path must be translated
|
||||
dir=$(cygpath -m "$dir");
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
export COMPOSER_RUNTIME_BIN_DIR="$(cd "${self%[/\\]*}" > /dev/null; pwd)"
|
||||
|
||||
# If bash is sourcing this file, we have to source the target as well
|
||||
bashSource="$BASH_SOURCE"
|
||||
if [ -n "$bashSource" ]; then
|
||||
if [ "$bashSource" != "$0" ]; then
|
||||
source "${dir}/sabredav" "$@"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
"${dir}/sabredav" "$@"
|
||||
119
lib/composer/vendor/bin/vobject
vendored
Executable file
119
lib/composer/vendor/bin/vobject
vendored
Executable file
|
|
@ -0,0 +1,119 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../sabre/vobject/bin/vobject)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? flock($this->handle, $operation) : true;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = ftell($this->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = substr($path, 17);
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||
) {
|
||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/sabre/vobject/bin/vobject');
|
||||
}
|
||||
}
|
||||
|
||||
return include __DIR__ . '/..'.'/sabre/vobject/bin/vobject';
|
||||
585
lib/composer/vendor/composer/ClassLoader.php
vendored
Normal file
585
lib/composer/vendor/composer/ClassLoader.php
vendored
Normal file
|
|
@ -0,0 +1,585 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see https://www.php-fig.org/psr/psr-0/
|
||||
* @see https://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
/** @var \Closure(string):void */
|
||||
private static $includeFile;
|
||||
|
||||
/** @var ?string */
|
||||
private $vendorDir;
|
||||
|
||||
// PSR-4
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, int>>
|
||||
*/
|
||||
private $prefixLengthsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<int, string>>
|
||||
*/
|
||||
private $prefixDirsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, string[]>>
|
||||
*/
|
||||
private $prefixesPsr0 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
/** @var bool */
|
||||
private $useIncludePath = false;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $classMap = array();
|
||||
|
||||
/** @var bool */
|
||||
private $classMapAuthoritative = false;
|
||||
|
||||
/**
|
||||
* @var bool[]
|
||||
* @psalm-var array<string, bool>
|
||||
*/
|
||||
private $missingClasses = array();
|
||||
|
||||
/** @var ?string */
|
||||
private $apcuPrefix;
|
||||
|
||||
/**
|
||||
* @var self[]
|
||||
*/
|
||||
private static $registeredLoaders = array();
|
||||
|
||||
/**
|
||||
* @param ?string $vendorDir
|
||||
*/
|
||||
public function __construct($vendorDir = null)
|
||||
{
|
||||
$this->vendorDir = $vendorDir;
|
||||
self::initializeIncludeClosure();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, array<int, string>>
|
||||
*/
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Array of classname => path
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $classMap Class to filename map
|
||||
* @psalm-param array<string, string> $classMap
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 base directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApcuPrefix()
|
||||
{
|
||||
return $this->apcuPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
|
||||
if (null === $this->vendorDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($prepend) {
|
||||
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
||||
} else {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
self::$registeredLoaders[$this->vendorDir] = $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
|
||||
if (null !== $this->vendorDir) {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return true|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
$includeFile = self::$includeFile;
|
||||
$includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (null !== $this->apcuPrefix) {
|
||||
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||
if ($hit) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if (false === $file && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if (null !== $this->apcuPrefix) {
|
||||
apcu_add($this->apcuPrefix.$class, $file);
|
||||
}
|
||||
|
||||
if (false === $file) {
|
||||
// Remember that this class does not exist.
|
||||
$this->missingClasses[$class] = true;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered loaders indexed by their corresponding vendor directories.
|
||||
*
|
||||
* @return self[]
|
||||
*/
|
||||
public static function getRegisteredLoaders()
|
||||
{
|
||||
return self::$registeredLoaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param string $ext
|
||||
* @return string|false
|
||||
*/
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath . '\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
if (file_exists($file = $dir . $pathEnd)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private static function initializeIncludeClosure()
|
||||
{
|
||||
if (self::$includeFile !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
self::$includeFile = \Closure::bind(static function($file) {
|
||||
include $file;
|
||||
}, null, null);
|
||||
}
|
||||
}
|
||||
359
lib/composer/vendor/composer/InstalledVersions.php
vendored
Normal file
359
lib/composer/vendor/composer/InstalledVersions.php
vendored
Normal file
|
|
@ -0,0 +1,359 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
use Composer\Autoload\ClassLoader;
|
||||
use Composer\Semver\VersionParser;
|
||||
|
||||
/**
|
||||
* This class is copied in every Composer installed project and available to all
|
||||
*
|
||||
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
||||
*
|
||||
* To require its presence, you can require `composer-runtime-api ^2.0`
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class InstalledVersions
|
||||
{
|
||||
/**
|
||||
* @var mixed[]|null
|
||||
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||
*/
|
||||
private static $installed;
|
||||
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
private static $canGetVendors;
|
||||
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static $installedByVendor = array();
|
||||
|
||||
/**
|
||||
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
||||
*
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackages()
|
||||
{
|
||||
$packages = array();
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
$packages[] = array_keys($installed['versions']);
|
||||
}
|
||||
|
||||
if (1 === \count($packages)) {
|
||||
return $packages[0];
|
||||
}
|
||||
|
||||
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all package names with a specific type e.g. 'library'
|
||||
*
|
||||
* @param string $type
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackagesByType($type)
|
||||
{
|
||||
$packagesByType = array();
|
||||
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
foreach ($installed['versions'] as $name => $package) {
|
||||
if (isset($package['type']) && $package['type'] === $type) {
|
||||
$packagesByType[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $packagesByType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package is installed
|
||||
*
|
||||
* This also returns true if the package name is provided or replaced by another package
|
||||
*
|
||||
* @param string $packageName
|
||||
* @param bool $includeDevRequirements
|
||||
* @return bool
|
||||
*/
|
||||
public static function isInstalled($packageName, $includeDevRequirements = true)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (isset($installed['versions'][$packageName])) {
|
||||
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package satisfies a version constraint
|
||||
*
|
||||
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
||||
*
|
||||
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
||||
*
|
||||
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
||||
* @param string $packageName
|
||||
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
||||
* @return bool
|
||||
*/
|
||||
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
||||
{
|
||||
$constraint = $parser->parseConstraints((string) $constraint);
|
||||
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
||||
|
||||
return $provided->matches($constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a version constraint representing all the range(s) which are installed for a given package
|
||||
*
|
||||
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
||||
* whether a given version of a package is installed, and not just whether it exists
|
||||
*
|
||||
* @param string $packageName
|
||||
* @return string Version constraint usable with composer/semver
|
||||
*/
|
||||
public static function getVersionRanges($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ranges = array();
|
||||
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
||||
}
|
||||
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
||||
}
|
||||
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
||||
}
|
||||
|
||||
return implode(' || ', $ranges);
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getPrettyVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
||||
*/
|
||||
public static function getReference($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['reference'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['reference'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
||||
*/
|
||||
public static function getInstallPath($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
|
||||
*/
|
||||
public static function getRootPackage()
|
||||
{
|
||||
$installed = self::getInstalled();
|
||||
|
||||
return $installed[0]['root'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw installed.php data for custom implementations
|
||||
*
|
||||
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
||||
* @return array[]
|
||||
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
|
||||
*/
|
||||
public static function getRawData()
|
||||
{
|
||||
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
self::$installed = include __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
return self::$installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
||||
*
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
public static function getAllRawData()
|
||||
{
|
||||
return self::getInstalled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets you reload the static array from another file
|
||||
*
|
||||
* This is only useful for complex integrations in which a project needs to use
|
||||
* this class but then also needs to execute another project's autoloader in process,
|
||||
* and wants to ensure both projects have access to their version of installed.php.
|
||||
*
|
||||
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
||||
* the data it needs from this class, then call reload() with
|
||||
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
||||
* the project in which it runs can then also use this class safely, without
|
||||
* interference between PHPUnit's dependencies and the project's dependencies.
|
||||
*
|
||||
* @param array[] $data A vendor/composer/installed.php data set
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
|
||||
*/
|
||||
public static function reload($data)
|
||||
{
|
||||
self::$installed = $data;
|
||||
self::$installedByVendor = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static function getInstalled()
|
||||
{
|
||||
if (null === self::$canGetVendors) {
|
||||
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
||||
}
|
||||
|
||||
$installed = array();
|
||||
|
||||
if (self::$canGetVendors) {
|
||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir];
|
||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||
$required = require $vendorDir.'/composer/installed.php';
|
||||
$installed[] = self::$installedByVendor[$vendorDir] = $required;
|
||||
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
||||
self::$installed = $installed[count($installed) - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||
$required = require __DIR__ . '/installed.php';
|
||||
self::$installed = $required;
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
if (self::$installed !== array()) {
|
||||
$installed[] = self::$installed;
|
||||
}
|
||||
|
||||
return $installed;
|
||||
}
|
||||
}
|
||||
19
lib/composer/vendor/composer/LICENSE
vendored
Normal file
19
lib/composer/vendor/composer/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||
|
||||
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.
|
||||
10
lib/composer/vendor/composer/autoload_classmap.php
vendored
Normal file
10
lib/composer/vendor/composer/autoload_classmap.php
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
);
|
||||
16
lib/composer/vendor/composer/autoload_files.php
vendored
Normal file
16
lib/composer/vendor/composer/autoload_files.php
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
// autoload_files.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'383eaff206634a77a1be54e64e6459c7' => $vendorDir . '/sabre/uri/lib/functions.php',
|
||||
'2b9d0f43f9552984cfa82fee95491826' => $vendorDir . '/sabre/event/lib/coroutine.php',
|
||||
'd81bab31d3feb45bfe2f283ea3c8fdf7' => $vendorDir . '/sabre/event/lib/Loop/functions.php',
|
||||
'a1cce3d26cc15c00fcd0b3354bd72c88' => $vendorDir . '/sabre/event/lib/Promise/functions.php',
|
||||
'3569eecfeed3bcf0bad3c998a494ecb8' => $vendorDir . '/sabre/xml/lib/Deserializer/functions.php',
|
||||
'93aa591bc4ca510c520999e34229ee79' => $vendorDir . '/sabre/xml/lib/Serializer/functions.php',
|
||||
'ebdb698ed4152ae445614b69b5e4bb6a' => $vendorDir . '/sabre/http/lib/functions.php',
|
||||
);
|
||||
10
lib/composer/vendor/composer/autoload_namespaces.php
vendored
Normal file
10
lib/composer/vendor/composer/autoload_namespaces.php
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'ICal' => array($vendorDir . '/johngrogg/ics-parser/src'),
|
||||
);
|
||||
16
lib/composer/vendor/composer/autoload_psr4.php
vendored
Normal file
16
lib/composer/vendor/composer/autoload_psr4.php
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Sabre\\Xml\\' => array($vendorDir . '/sabre/xml/lib'),
|
||||
'Sabre\\VObject\\' => array($vendorDir . '/sabre/vobject/lib'),
|
||||
'Sabre\\Uri\\' => array($vendorDir . '/sabre/uri/lib'),
|
||||
'Sabre\\HTTP\\' => array($vendorDir . '/sabre/http/lib'),
|
||||
'Sabre\\Event\\' => array($vendorDir . '/sabre/event/lib'),
|
||||
'Sabre\\' => array($vendorDir . '/sabre/dav/lib'),
|
||||
'Psr\\Log\\' => array($vendorDir . '/psr/log/src'),
|
||||
);
|
||||
50
lib/composer/vendor/composer/autoload_real.php
vendored
Normal file
50
lib/composer/vendor/composer/autoload_real.php
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInite6a6e754980b2e4ee0099ab3b538a42e
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
require __DIR__ . '/platform_check.php';
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInite6a6e754980b2e4ee0099ab3b538a42e', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInite6a6e754980b2e4ee0099ab3b538a42e', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInite6a6e754980b2e4ee0099ab3b538a42e::getInitializer($loader));
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInite6a6e754980b2e4ee0099ab3b538a42e::$files;
|
||||
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
||||
require $file;
|
||||
}
|
||||
}, null, null);
|
||||
foreach ($filesToLoad as $fileIdentifier => $file) {
|
||||
$requireFile($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
90
lib/composer/vendor/composer/autoload_static.php
vendored
Normal file
90
lib/composer/vendor/composer/autoload_static.php
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInite6a6e754980b2e4ee0099ab3b538a42e
|
||||
{
|
||||
public static $files = array (
|
||||
'383eaff206634a77a1be54e64e6459c7' => __DIR__ . '/..' . '/sabre/uri/lib/functions.php',
|
||||
'2b9d0f43f9552984cfa82fee95491826' => __DIR__ . '/..' . '/sabre/event/lib/coroutine.php',
|
||||
'd81bab31d3feb45bfe2f283ea3c8fdf7' => __DIR__ . '/..' . '/sabre/event/lib/Loop/functions.php',
|
||||
'a1cce3d26cc15c00fcd0b3354bd72c88' => __DIR__ . '/..' . '/sabre/event/lib/Promise/functions.php',
|
||||
'3569eecfeed3bcf0bad3c998a494ecb8' => __DIR__ . '/..' . '/sabre/xml/lib/Deserializer/functions.php',
|
||||
'93aa591bc4ca510c520999e34229ee79' => __DIR__ . '/..' . '/sabre/xml/lib/Serializer/functions.php',
|
||||
'ebdb698ed4152ae445614b69b5e4bb6a' => __DIR__ . '/..' . '/sabre/http/lib/functions.php',
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'S' =>
|
||||
array (
|
||||
'Sabre\\Xml\\' => 10,
|
||||
'Sabre\\VObject\\' => 14,
|
||||
'Sabre\\Uri\\' => 10,
|
||||
'Sabre\\HTTP\\' => 11,
|
||||
'Sabre\\Event\\' => 12,
|
||||
'Sabre\\' => 6,
|
||||
),
|
||||
'P' =>
|
||||
array (
|
||||
'Psr\\Log\\' => 8,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'Sabre\\Xml\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/sabre/xml/lib',
|
||||
),
|
||||
'Sabre\\VObject\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/sabre/vobject/lib',
|
||||
),
|
||||
'Sabre\\Uri\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/sabre/uri/lib',
|
||||
),
|
||||
'Sabre\\HTTP\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/sabre/http/lib',
|
||||
),
|
||||
'Sabre\\Event\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/sabre/event/lib',
|
||||
),
|
||||
'Sabre\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/sabre/dav/lib',
|
||||
),
|
||||
'Psr\\Log\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/log/src',
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixesPsr0 = array (
|
||||
'I' =>
|
||||
array (
|
||||
'ICal' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/johngrogg/ics-parser/src',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
public static $classMap = array (
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInite6a6e754980b2e4ee0099ab3b538a42e::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInite6a6e754980b2e4ee0099ab3b538a42e::$prefixDirsPsr4;
|
||||
$loader->prefixesPsr0 = ComposerStaticInite6a6e754980b2e4ee0099ab3b538a42e::$prefixesPsr0;
|
||||
$loader->classMap = ComposerStaticInite6a6e754980b2e4ee0099ab3b538a42e::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
||||
589
lib/composer/vendor/composer/installed.json
vendored
Normal file
589
lib/composer/vendor/composer/installed.json
vendored
Normal file
|
|
@ -0,0 +1,589 @@
|
|||
{
|
||||
"packages": [
|
||||
{
|
||||
"name": "johngrogg/ics-parser",
|
||||
"version": "v3.4.1",
|
||||
"version_normalized": "3.4.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/u01jmg3/ics-parser.git",
|
||||
"reference": "abb41a4a46256389aa4e6f582bad76f0d4cb3ebc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/u01jmg3/ics-parser/zipball/abb41a4a46256389aa4e6f582bad76f0d4cb3ebc",
|
||||
"reference": "abb41a4a46256389aa4e6f582bad76f0d4cb3ebc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=5.6.40"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5|^9|^10"
|
||||
},
|
||||
"time": "2024-06-26T08:18:40+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"ICal": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jonathan Goode",
|
||||
"role": "Developer/Owner"
|
||||
},
|
||||
{
|
||||
"name": "John Grogg",
|
||||
"email": "john.grogg@gmail.com",
|
||||
"role": "Developer/Prior Owner"
|
||||
}
|
||||
],
|
||||
"description": "ICS Parser",
|
||||
"homepage": "https://github.com/u01jmg3/ics-parser",
|
||||
"keywords": [
|
||||
"iCalendar",
|
||||
"ical",
|
||||
"ical-parser",
|
||||
"ics",
|
||||
"ics-parser",
|
||||
"ifb"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/u01jmg3/ics-parser/issues",
|
||||
"source": "https://github.com/u01jmg3/ics-parser/tree/v3.4.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sponsors/u01jmg3",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"install-path": "../johngrogg/ics-parser"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "3.0.2",
|
||||
"version_normalized": "3.0.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/log.git",
|
||||
"reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
|
||||
"reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.0"
|
||||
},
|
||||
"time": "2024-09-11T13:17:53+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Log\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for logging libraries",
|
||||
"homepage": "https://github.com/php-fig/log",
|
||||
"keywords": [
|
||||
"log",
|
||||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/log/tree/3.0.2"
|
||||
},
|
||||
"install-path": "../psr/log"
|
||||
},
|
||||
{
|
||||
"name": "sabre/dav",
|
||||
"version": "4.7.0",
|
||||
"version_normalized": "4.7.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sabre-io/dav.git",
|
||||
"reference": "074373bcd689a30bcf5aaa6bbb20a3395964ce7a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sabre-io/dav/zipball/074373bcd689a30bcf5aaa6bbb20a3395964ce7a",
|
||||
"reference": "074373bcd689a30bcf5aaa6bbb20a3395964ce7a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"ext-date": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-iconv": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-spl": "*",
|
||||
"lib-libxml": ">=2.7.0",
|
||||
"php": "^7.1.0 || ^8.0",
|
||||
"psr/log": "^1.0 || ^2.0 || ^3.0",
|
||||
"sabre/event": "^5.0",
|
||||
"sabre/http": "^5.0.5",
|
||||
"sabre/uri": "^2.0",
|
||||
"sabre/vobject": "^4.2.1",
|
||||
"sabre/xml": "^2.0.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.19",
|
||||
"monolog/monolog": "^1.27 || ^2.0",
|
||||
"phpstan/phpstan": "^0.12 || ^1.0",
|
||||
"phpstan/phpstan-phpunit": "^1.0",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.6"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-curl": "*",
|
||||
"ext-imap": "*",
|
||||
"ext-pdo": "*"
|
||||
},
|
||||
"time": "2024-10-29T11:46:02+00:00",
|
||||
"bin": [
|
||||
"bin/sabredav",
|
||||
"bin/naturalselection"
|
||||
],
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Sabre\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Evert Pot",
|
||||
"email": "me@evertpot.com",
|
||||
"homepage": "http://evertpot.com/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "WebDAV Framework for PHP",
|
||||
"homepage": "http://sabre.io/",
|
||||
"keywords": [
|
||||
"CalDAV",
|
||||
"CardDAV",
|
||||
"WebDAV",
|
||||
"framework",
|
||||
"iCalendar"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://groups.google.com/group/sabredav-discuss",
|
||||
"issues": "https://github.com/sabre-io/dav/issues",
|
||||
"source": "https://github.com/fruux/sabre-dav"
|
||||
},
|
||||
"install-path": "../sabre/dav"
|
||||
},
|
||||
{
|
||||
"name": "sabre/event",
|
||||
"version": "5.1.7",
|
||||
"version_normalized": "5.1.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sabre-io/event.git",
|
||||
"reference": "86d57e305c272898ba3c28e9bd3d65d5464587c2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sabre-io/event/zipball/86d57e305c272898ba3c28e9bd3d65d5464587c2",
|
||||
"reference": "86d57e305c272898ba3c28e9bd3d65d5464587c2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "~2.17.1||^3.63",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.6"
|
||||
},
|
||||
"time": "2024-08-27T11:23:05+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/coroutine.php",
|
||||
"lib/Loop/functions.php",
|
||||
"lib/Promise/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Sabre\\Event\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Evert Pot",
|
||||
"email": "me@evertpot.com",
|
||||
"homepage": "http://evertpot.com/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "sabre/event is a library for lightweight event-based programming",
|
||||
"homepage": "http://sabre.io/event/",
|
||||
"keywords": [
|
||||
"EventEmitter",
|
||||
"async",
|
||||
"coroutine",
|
||||
"eventloop",
|
||||
"events",
|
||||
"hooks",
|
||||
"plugin",
|
||||
"promise",
|
||||
"reactor",
|
||||
"signal"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://groups.google.com/group/sabredav-discuss",
|
||||
"issues": "https://github.com/sabre-io/event/issues",
|
||||
"source": "https://github.com/fruux/sabre-event"
|
||||
},
|
||||
"install-path": "../sabre/event"
|
||||
},
|
||||
{
|
||||
"name": "sabre/http",
|
||||
"version": "5.1.12",
|
||||
"version_normalized": "5.1.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sabre-io/http.git",
|
||||
"reference": "dedff73f3995578bc942fa4c8484190cac14f139"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sabre-io/http/zipball/dedff73f3995578bc942fa4c8484190cac14f139",
|
||||
"reference": "dedff73f3995578bc942fa4c8484190cac14f139",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"sabre/event": ">=4.0 <6.0",
|
||||
"sabre/uri": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "~2.17.1||^3.63",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.6"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-curl": " to make http requests with the Client class"
|
||||
},
|
||||
"time": "2024-08-27T16:07:41+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Sabre\\HTTP\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Evert Pot",
|
||||
"email": "me@evertpot.com",
|
||||
"homepage": "http://evertpot.com/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "The sabre/http library provides utilities for dealing with http requests and responses. ",
|
||||
"homepage": "https://github.com/fruux/sabre-http",
|
||||
"keywords": [
|
||||
"http"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://groups.google.com/group/sabredav-discuss",
|
||||
"issues": "https://github.com/sabre-io/http/issues",
|
||||
"source": "https://github.com/fruux/sabre-http"
|
||||
},
|
||||
"install-path": "../sabre/http"
|
||||
},
|
||||
{
|
||||
"name": "sabre/uri",
|
||||
"version": "2.3.4",
|
||||
"version_normalized": "2.3.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sabre-io/uri.git",
|
||||
"reference": "b76524c22de90d80ca73143680a8e77b1266c291"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sabre-io/uri/zipball/b76524c22de90d80ca73143680a8e77b1266c291",
|
||||
"reference": "b76524c22de90d80ca73143680a8e77b1266c291",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.63",
|
||||
"phpstan/extension-installer": "^1.4",
|
||||
"phpstan/phpstan": "^1.12",
|
||||
"phpstan/phpstan-phpunit": "^1.4",
|
||||
"phpstan/phpstan-strict-rules": "^1.6",
|
||||
"phpunit/phpunit": "^9.6"
|
||||
},
|
||||
"time": "2024-08-27T12:18:16+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Sabre\\Uri\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Evert Pot",
|
||||
"email": "me@evertpot.com",
|
||||
"homepage": "http://evertpot.com/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Functions for making sense out of URIs.",
|
||||
"homepage": "http://sabre.io/uri/",
|
||||
"keywords": [
|
||||
"rfc3986",
|
||||
"uri",
|
||||
"url"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://groups.google.com/group/sabredav-discuss",
|
||||
"issues": "https://github.com/sabre-io/uri/issues",
|
||||
"source": "https://github.com/fruux/sabre-uri"
|
||||
},
|
||||
"install-path": "../sabre/uri"
|
||||
},
|
||||
{
|
||||
"name": "sabre/vobject",
|
||||
"version": "4.5.7",
|
||||
"version_normalized": "4.5.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sabre-io/vobject.git",
|
||||
"reference": "ff22611a53782e90c97be0d0bc4a5f98a5c0a12c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sabre-io/vobject/zipball/ff22611a53782e90c97be0d0bc4a5f98a5c0a12c",
|
||||
"reference": "ff22611a53782e90c97be0d0bc4a5f98a5c0a12c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"sabre/xml": "^2.1 || ^3.0 || ^4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "~2.17.1",
|
||||
"phpstan/phpstan": "^0.12 || ^1.12 || ^2.0",
|
||||
"phpunit/php-invoker": "^2.0 || ^3.1",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.6"
|
||||
},
|
||||
"suggest": {
|
||||
"hoa/bench": "If you would like to run the benchmark scripts"
|
||||
},
|
||||
"time": "2025-04-17T09:22:48+00:00",
|
||||
"bin": [
|
||||
"bin/vobject",
|
||||
"bin/generate_vcards"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Sabre\\VObject\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Evert Pot",
|
||||
"email": "me@evertpot.com",
|
||||
"homepage": "http://evertpot.com/",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Dominik Tobschall",
|
||||
"email": "dominik@fruux.com",
|
||||
"homepage": "http://tobschall.de/",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Ivan Enderlin",
|
||||
"email": "ivan.enderlin@hoa-project.net",
|
||||
"homepage": "http://mnt.io/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects",
|
||||
"homepage": "http://sabre.io/vobject/",
|
||||
"keywords": [
|
||||
"availability",
|
||||
"freebusy",
|
||||
"iCalendar",
|
||||
"ical",
|
||||
"ics",
|
||||
"jCal",
|
||||
"jCard",
|
||||
"recurrence",
|
||||
"rfc2425",
|
||||
"rfc2426",
|
||||
"rfc2739",
|
||||
"rfc4770",
|
||||
"rfc5545",
|
||||
"rfc5546",
|
||||
"rfc6321",
|
||||
"rfc6350",
|
||||
"rfc6351",
|
||||
"rfc6474",
|
||||
"rfc6638",
|
||||
"rfc6715",
|
||||
"rfc6868",
|
||||
"vCalendar",
|
||||
"vCard",
|
||||
"vcf",
|
||||
"xCal",
|
||||
"xCard"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://groups.google.com/group/sabredav-discuss",
|
||||
"issues": "https://github.com/sabre-io/vobject/issues",
|
||||
"source": "https://github.com/fruux/sabre-vobject"
|
||||
},
|
||||
"install-path": "../sabre/vobject"
|
||||
},
|
||||
{
|
||||
"name": "sabre/xml",
|
||||
"version": "2.2.11",
|
||||
"version_normalized": "2.2.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sabre-io/xml.git",
|
||||
"reference": "01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sabre-io/xml/zipball/01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc",
|
||||
"reference": "01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-xmlreader": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"lib-libxml": ">=2.6.20",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"sabre/uri": ">=1.0,<3.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "~2.17.1||3.63.2",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.6"
|
||||
},
|
||||
"time": "2024-09-06T07:37:46+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/Deserializer/functions.php",
|
||||
"lib/Serializer/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Sabre\\Xml\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Evert Pot",
|
||||
"email": "me@evertpot.com",
|
||||
"homepage": "http://evertpot.com/",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Markus Staab",
|
||||
"email": "markus.staab@redaxo.de",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "sabre/xml is an XML library that you may not hate.",
|
||||
"homepage": "https://sabre.io/xml/",
|
||||
"keywords": [
|
||||
"XMLReader",
|
||||
"XMLWriter",
|
||||
"dom",
|
||||
"xml"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://groups.google.com/group/sabredav-discuss",
|
||||
"issues": "https://github.com/sabre-io/xml/issues",
|
||||
"source": "https://github.com/fruux/sabre-xml"
|
||||
},
|
||||
"install-path": "../sabre/xml"
|
||||
}
|
||||
],
|
||||
"dev": true,
|
||||
"dev-package-names": []
|
||||
}
|
||||
95
lib/composer/vendor/composer/installed.php
vendored
Normal file
95
lib/composer/vendor/composer/installed.php
vendored
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
<?php return array(
|
||||
'root' => array(
|
||||
'name' => '__root__',
|
||||
'pretty_version' => '1.0.0+no-version-set',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => null,
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev' => true,
|
||||
),
|
||||
'versions' => array(
|
||||
'__root__' => array(
|
||||
'pretty_version' => '1.0.0+no-version-set',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => null,
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'johngrogg/ics-parser' => array(
|
||||
'pretty_version' => 'v3.4.1',
|
||||
'version' => '3.4.1.0',
|
||||
'reference' => 'abb41a4a46256389aa4e6f582bad76f0d4cb3ebc',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../johngrogg/ics-parser',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/log' => array(
|
||||
'pretty_version' => '3.0.2',
|
||||
'version' => '3.0.2.0',
|
||||
'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/log',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'sabre/dav' => array(
|
||||
'pretty_version' => '4.7.0',
|
||||
'version' => '4.7.0.0',
|
||||
'reference' => '074373bcd689a30bcf5aaa6bbb20a3395964ce7a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../sabre/dav',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'sabre/event' => array(
|
||||
'pretty_version' => '5.1.7',
|
||||
'version' => '5.1.7.0',
|
||||
'reference' => '86d57e305c272898ba3c28e9bd3d65d5464587c2',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../sabre/event',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'sabre/http' => array(
|
||||
'pretty_version' => '5.1.12',
|
||||
'version' => '5.1.12.0',
|
||||
'reference' => 'dedff73f3995578bc942fa4c8484190cac14f139',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../sabre/http',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'sabre/uri' => array(
|
||||
'pretty_version' => '2.3.4',
|
||||
'version' => '2.3.4.0',
|
||||
'reference' => 'b76524c22de90d80ca73143680a8e77b1266c291',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../sabre/uri',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'sabre/vobject' => array(
|
||||
'pretty_version' => '4.5.7',
|
||||
'version' => '4.5.7.0',
|
||||
'reference' => 'ff22611a53782e90c97be0d0bc4a5f98a5c0a12c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../sabre/vobject',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'sabre/xml' => array(
|
||||
'pretty_version' => '2.2.11',
|
||||
'version' => '2.2.11.0',
|
||||
'reference' => '01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../sabre/xml',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
),
|
||||
);
|
||||
26
lib/composer/vendor/composer/platform_check.php
vendored
Normal file
26
lib/composer/vendor/composer/platform_check.php
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
// platform_check.php @generated by Composer
|
||||
|
||||
$issues = array();
|
||||
|
||||
if (!(PHP_VERSION_ID >= 80000)) {
|
||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 8.0.0". You are running ' . PHP_VERSION . '.';
|
||||
}
|
||||
|
||||
if ($issues) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
||||
} elseif (!headers_sent()) {
|
||||
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
11
lib/composer/vendor/johngrogg/ics-parser/.editorconfig
vendored
Normal file
11
lib/composer/vendor/johngrogg/ics-parser/.editorconfig
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# https://editorconfig.org/
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
53
lib/composer/vendor/johngrogg/ics-parser/.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
53
lib/composer/vendor/johngrogg/ics-parser/.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
name: Bug Report
|
||||
description: "Report something that's broken."
|
||||
labels: ["bug-normal"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "Before raising an issue, please check the issue has not already been fixed in `dev-master`. You can also search through our [closed issues](../issues?q=is%3Aissue+is%3Aclosed+)."
|
||||
- type: input
|
||||
id: php-version
|
||||
attributes:
|
||||
label: PHP Version
|
||||
description: Provide the PHP version that you are using.
|
||||
placeholder: 8.1.4
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: php-date-timezone
|
||||
attributes:
|
||||
label: PHP date.timezone
|
||||
description: Provide the PHP date.timezone that you are using.
|
||||
placeholder: "[Country] / [City]"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: ics-parser-version
|
||||
attributes:
|
||||
label: ICS Parser Version
|
||||
description: Provide the `ics-parser` library version that you are using.
|
||||
placeholder: 3.2.1
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: operating-system
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: Provide the operating system that you are using.
|
||||
placeholder: "Windows / Mac / Linux"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: Provide a detailed description of the issue that you are facing.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: steps-to-reproduce
|
||||
attributes:
|
||||
label: Steps to Reproduce
|
||||
description: Provide detailed steps to reproduce your issue. It is **essential** that you supply a copy of the iCal file that is causing the parser to behave incorrectly to allow us to investigate. Prior to uploading the iCal file, please remove any personal or identifying information.
|
||||
validations:
|
||||
required: true
|
||||
12
lib/composer/vendor/johngrogg/ics-parser/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
vendored
Normal file
12
lib/composer/vendor/johngrogg/ics-parser/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
> :information_source:
|
||||
> - File a bug on our [issue tracker](https://github.com/u01jmg3/ics-parser/issues) (if there isn't one already).
|
||||
> - If your patch is going to be large it might be a good idea to get the discussion started early. We are happy to discuss it in a new issue beforehand.
|
||||
> - Please follow the coding standards already adhered to in the file you're editing before committing
|
||||
> - This includes the use of *4 spaces* over tabs for indentation
|
||||
> - Trim all trailing whitespace
|
||||
> - Using single quotes (`'`) where possible
|
||||
> - Use `PHP_EOL` where possible or default to `\n`
|
||||
> - Using the [1TBS](https://en.wikipedia.org/wiki/Indent_style#Variant:_1TBS_.28OTBS.29) indent style
|
||||
> - If a function is added or changed, please remember to update the [API documentation in the README](https://github.com/u01jmg3/ics-parser/blob/master/README.md#api)
|
||||
> - Please include unit tests to verify any new functionality
|
||||
> - Also check that existing tests still pass: `composer test`
|
||||
13
lib/composer/vendor/johngrogg/ics-parser/.github/dependabot.yml
vendored
Normal file
13
lib/composer/vendor/johngrogg/ics-parser/.github/dependabot.yml
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: composer
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- u01jmg3
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
9
lib/composer/vendor/johngrogg/ics-parser/.github/release_template.md
vendored
Normal file
9
lib/composer/vendor/johngrogg/ics-parser/.github/release_template.md
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Release Checklist
|
||||
|
||||
- [ ] Update docblock in `src/ICal/ICal.php`
|
||||
- [ ] Ensure the documentation is up to date
|
||||
- [ ] Push the code changes to GitHub (`git push`)
|
||||
- [ ] Tag the release (`git tag v1.2.3`)
|
||||
- [ ] Push the tag (`git push --tag`)
|
||||
- [ ] Check [Packagist](https://packagist.org/packages/johngrogg/ics-parser) is updated
|
||||
- [ ] Notify anyone who opened [an issue or PR](https://github.com/u01jmg3/ics-parser/issues?q=is%3Aopen) of the fix
|
||||
67
lib/composer/vendor/johngrogg/ics-parser/.github/workflows/coding-standards.yml
vendored
Normal file
67
lib/composer/vendor/johngrogg/ics-parser/.github/workflows/coding-standards.yml
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
name: Coding Standards
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
Scan:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php: [5.6, 7.4, '8.0', 8.1, 8.2, 8.3, 8.4]
|
||||
|
||||
name: PHP ${{ matrix.php }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
tools: composer:2.2
|
||||
coverage: none
|
||||
|
||||
- name: Install dependencies for PHP 5.6
|
||||
run: composer update --quiet --no-scripts
|
||||
if: matrix.php == 5.6
|
||||
|
||||
- name: Install dependencies for PHP 7.4+
|
||||
run: composer install --quiet --no-scripts
|
||||
if: matrix.php >= 7.4
|
||||
|
||||
- name: Execute tests
|
||||
run: vendor/bin/phpunit --verbose
|
||||
|
||||
- name: Install additional dependencies
|
||||
run: |
|
||||
composer config allow-plugins.bamarni/composer-bin-plugin true --no-plugins
|
||||
composer require bamarni/composer-bin-plugin rector/rector squizlabs/php_codesniffer --dev --quiet --no-scripts
|
||||
composer bin easy-coding-standard config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
|
||||
composer bin easy-coding-standard require symplify/easy-coding-standard slevomat/coding-standard --dev --quiet --no-scripts
|
||||
if: matrix.php == 8.3
|
||||
|
||||
- name: Execute PHPCodeSniffer
|
||||
run: vendor/bin/phpcs -n -s --standard=psr12 src
|
||||
if: matrix.php == 8.3
|
||||
|
||||
- name: Execute Rector
|
||||
run: vendor/bin/rector process src --dry-run
|
||||
if: matrix.php == 8.3
|
||||
|
||||
- name: Execute ECS
|
||||
run: vendor/bin/ecs check src
|
||||
if: matrix.php == 8.3
|
||||
|
||||
- name: Execute PHPStan
|
||||
run: vendor/bin/phpstan analyse src
|
||||
if: matrix.php == 8.3
|
||||
59
lib/composer/vendor/johngrogg/ics-parser/.gitignore
vendored
Normal file
59
lib/composer/vendor/johngrogg/ics-parser/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
###################
|
||||
# Compiled Source #
|
||||
###################
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.o
|
||||
*.so
|
||||
|
||||
############
|
||||
# Packages #
|
||||
############
|
||||
*.7z
|
||||
*.dmg
|
||||
*.gz
|
||||
*.iso
|
||||
*.jar
|
||||
*.rar
|
||||
*.tar
|
||||
*.zip
|
||||
|
||||
######################
|
||||
# Logs and Databases #
|
||||
######################
|
||||
*.log
|
||||
*.sqlite
|
||||
|
||||
######################
|
||||
# OS Generated Files #
|
||||
######################
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
.phpunit.result.cache
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
workbench
|
||||
|
||||
####################
|
||||
# Package Managers #
|
||||
####################
|
||||
auth.json
|
||||
node_modules
|
||||
vendor
|
||||
|
||||
##########
|
||||
# Custom #
|
||||
##########
|
||||
*.git
|
||||
*-report.*
|
||||
|
||||
########
|
||||
# IDEs #
|
||||
########
|
||||
.idea
|
||||
*.iml
|
||||
18
lib/composer/vendor/johngrogg/ics-parser/CONTRIBUTING.md
vendored
Normal file
18
lib/composer/vendor/johngrogg/ics-parser/CONTRIBUTING.md
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
## Contributing
|
||||
|
||||
ICS Parser is an open source project. It is licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
||||
We appreciate pull requests, here are our guidelines:
|
||||
|
||||
1. Firstly, check if your issue is present within the latest version (`dev-master`) as the problem may already have been fixed.
|
||||
1. Log a bug in our [issue tracker](https://github.com/u01jmg3/ics-parser/issues) (if there isn't one already).
|
||||
- If your patch is going to be large it might be a good idea to get the discussion started early.
|
||||
- We are happy to discuss it in an issue beforehand.
|
||||
- If you could provide an iCal snippet causing the parser to behave incorrectly it is extremely useful for debugging
|
||||
- Please remove all irrelevant events
|
||||
1. Please follow the coding standard already present in the file you are editing _before_ committing
|
||||
- Adhere to the [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) coding standard
|
||||
- Use *4 spaces* instead of tabs for indentation
|
||||
- Trim all trailing whitespace and blank lines
|
||||
- Use single quotes (`'`) where possible instead of double
|
||||
- Use `PHP_EOL` where possible or default to `\n`
|
||||
- Abide by the [1TBS](https://en.wikipedia.org/wiki/Indent_style#Variant:_1TBS_.28OTBS.29) indentation style
|
||||
1
lib/composer/vendor/johngrogg/ics-parser/FUNDING.yml
vendored
Normal file
1
lib/composer/vendor/johngrogg/ics-parser/FUNDING.yml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
github: u01jmg3
|
||||
15
lib/composer/vendor/johngrogg/ics-parser/LICENSE
vendored
Normal file
15
lib/composer/vendor/johngrogg/ics-parser/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
The MIT License (MIT)
|
||||
Copyright (c) 2018
|
||||
|
||||
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.
|
||||
256
lib/composer/vendor/johngrogg/ics-parser/README.md
vendored
Normal file
256
lib/composer/vendor/johngrogg/ics-parser/README.md
vendored
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
# PHP ICS Parser
|
||||
|
||||
[](https://packagist.org/packages/johngrogg/ics-parser)
|
||||
[](https://packagist.org/packages/johngrogg/ics-parser)
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### Requirements
|
||||
- PHP 5 (≥ 5.6.40)
|
||||
- [Valid ICS](https://icalendar.org/validator.html) (`.ics`, `.ical`, `.ifb`) file
|
||||
- [IANA](https://www.iana.org/time-zones), [Unicode CLDR](http://cldr.unicode.org/translation/timezones) or [Windows](https://support.microsoft.com/en-ca/help/973627/microsoft-time-zone-index-values) Time Zones
|
||||
|
||||
### Setup
|
||||
|
||||
- Install [Composer](https://getcomposer.org/)
|
||||
- Add the following dependency to `composer.json`
|
||||
- :warning: **Note with Composer the owner is `johngrogg` and not `u01jmg3`**
|
||||
- To access the latest stable branch (`v3`) use the following
|
||||
- To access new features you can require [`dev-master`](https://getcomposer.org/doc/articles/aliases.md#branch-alias)
|
||||
|
||||
```yaml
|
||||
{
|
||||
"require": {
|
||||
"johngrogg/ics-parser": "^3"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Running tests
|
||||
|
||||
```sh
|
||||
composer test
|
||||
```
|
||||
|
||||
## How to use
|
||||
|
||||
### How to instantiate the Parser
|
||||
|
||||
- Using the example script as a guide, [refer to this code](https://github.com/u01jmg3/ics-parser/blob/master/examples/index.php#L1-L22)
|
||||
|
||||
#### What will the parser return?
|
||||
|
||||
- Each key/value pair from the iCal file will be parsed creating an associative array for both the calendar and every event it contains.
|
||||
- Also injected will be content under `dtstart_tz` and `dtend_tz` for accessing start and end dates with time zone data applied.
|
||||
- Where possible [`DateTime`](https://secure.php.net/manual/en/class.datetime.php) objects are used and returned.
|
||||
- :information_source: **Note the parser is limited to [relative date formats](https://www.php.net/manual/en/datetime.formats.relative.php) which can inhibit how complex recurrence rule parts are processed (e.g. `BYDAY` combined with `BYSETPOS`)**
|
||||
|
||||
```php
|
||||
// Dump the whole calendar
|
||||
var_dump($ical->cal);
|
||||
|
||||
// Dump every event
|
||||
var_dump($ical->events());
|
||||
```
|
||||
|
||||
- Also included are special `{property}_array` arrays which further resolve the contents of a key/value pair.
|
||||
|
||||
```php
|
||||
// Dump a parsed event's start date
|
||||
var_dump($event->dtstart_array);
|
||||
|
||||
// array (size=4)
|
||||
// 0 =>
|
||||
// array (size=1)
|
||||
// 'TZID' => string 'America/Detroit' (length=15)
|
||||
// 1 => string '20160409T090000' (length=15)
|
||||
// 2 => int 1460192400
|
||||
// 3 => string 'TZID=America/Detroit:20160409T090000' (length=36)
|
||||
```
|
||||
|
||||
### Are you using Outlook?
|
||||
|
||||
Outlook has a quirk where it requires the User Agent string to be set in your request headers.
|
||||
|
||||
We have done this for you by injecting a default User Agent string, if one has not been specified.
|
||||
|
||||
If you wish to provide your own User agent string you can do so by using the `httpUserAgent` argument when creating your ICal object.
|
||||
|
||||
```php
|
||||
$ical = new ICal($url, array('httpUserAgent' => 'A Different User Agent'));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## When Parsing an iCal Feed
|
||||
|
||||
Parsing [iCal/iCalendar/ICS](https://en.wikipedia.org/wiki/ICalendar) resources can pose several challenges. One challenge is that
|
||||
the specification is a moving target; the original RFC has only been updated four times in ten years. The other challenge is that vendors
|
||||
were both liberal (read: creative) in interpreting the specification and productive implementing proprietary extensions.
|
||||
|
||||
However, what impedes efficient parsing most directly are recurrence rules for events. This library parses the original
|
||||
calendar into an easy to work with memory model. This requires that each recurring event is expanded or exploded. Hence,
|
||||
a single event that occurs daily will generate a new event instance for each day as this parser processes the
|
||||
calendar ([`$defaultSpan`](#variables) limits this). To get an idea how this is done take a look at the
|
||||
[call graph](https://user-images.githubusercontent.com/624195/45904641-f3cd0a80-bded-11e8-925f-7bcee04b8575.png).
|
||||
|
||||
As a consequence the _entire_ calendar is parsed line-by-line, and thus loaded into memory, first. As you can imagine
|
||||
large calendars tend to get huge when exploded i.e. with all their recurrence rules evaluated. This is exacerbated when
|
||||
old calendars do not remove past events as they get fatter and fatter every year.
|
||||
|
||||
This limitation is particularly painful if you only need a window into the original calendar. It seems wasteful to parse
|
||||
the entire fully exploded calendar into memory if you later are going to call the
|
||||
[`eventsFromInterval()` or `eventsFromRange()`](#methods) on it.
|
||||
|
||||
In late 2018 [#190](https://github.com/u01jmg3/ics-parser/pull/190) added the option to drop all events outside a given
|
||||
range very early in the parsing process at the cost of some precision (time zone calculations are not calculated at that point). This
|
||||
massively reduces the total time for parsing a calendar. The same goes for memory consumption. The precondition is that
|
||||
you know upfront that you don't care about events outside a given range.
|
||||
|
||||
Let's say you are only interested in events from yesterday, today and tomorrow. To compensate for the fact that the
|
||||
tricky time zone transformations and calculations have not been executed yet by the time the parser has to decide whether
|
||||
to keep or drop an event you can set it to filter for **+-2d** instead of +-1d. Once it is done you would then call
|
||||
`eventsFromRange()` with +-1d to get precisely the events in the window you are interested in. That is what the variables
|
||||
[`$filterDaysBefore` and `$filterDaysAfter`](#variables) are for.
|
||||
|
||||
In Q1 2019 [#213](https://github.com/u01jmg3/ics-parser/pull/213) further improved the performance by immediately
|
||||
dropping _non-recurring_ events once parsed if they are outside that fuzzy window. This greatly reduces the maximum
|
||||
memory consumption for large calendars. PHP by default does not allocate more than 128MB heap and would otherwise crash
|
||||
with `Fatal error: Allowed memory size of 134217728 bytes exhausted`. It goes without saying that recurring events first
|
||||
need to be evaluated before non-fitting events can be dropped.
|
||||
|
||||
---
|
||||
|
||||
## API
|
||||
|
||||
### `ICal` API
|
||||
|
||||
#### Variables
|
||||
|
||||
| Name | Configurable | Default Value | Description |
|
||||
|--------------------------------|:------------------------:|-------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `$alarmCount` | :heavy_multiplication_x: | N/A | Tracks the number of alarms in the current iCal feed |
|
||||
| `$cal` | :heavy_multiplication_x: | N/A | The parsed calendar |
|
||||
| `$defaultSpan` | :ballot_box_with_check: | `2` | The value in years to use for indefinite, recurring events |
|
||||
| `$defaultTimeZone` | :ballot_box_with_check: | [System default](https://secure.php.net/manual/en/function.date-default-timezone-get.php) | Enables customisation of the default time zone |
|
||||
| `$defaultWeekStart` | :ballot_box_with_check: | `MO` | The two letter representation of the first day of the week |
|
||||
| `$disableCharacterReplacement` | :ballot_box_with_check: | `false` | Toggles whether to disable all character replacement. Will replace curly quotes and other special characters with their standard equivalents if `false`. Can be a costly operation! |
|
||||
| `$eventCount` | :heavy_multiplication_x: | N/A | Tracks the number of events in the current iCal feed |
|
||||
| `$filterDaysAfter` | :ballot_box_with_check: | `null` | When set the parser will ignore all events more than roughly this many days _after_ now. To be on the safe side it is advised that you make the filter window `+/- 1` day larger than necessary. For performance reasons this filter is applied before any date and time zone calculations are done. Hence, depending the time zone settings of the parser and the calendar the cut-off date is not "calibrated". You can then use `$ical->eventsFromRange()` to precisely shrink the window. |
|
||||
| `$filterDaysBefore` | :ballot_box_with_check: | `null` | When set the parser will ignore all events more than roughly this many days _before_ now. See `$filterDaysAfter` above for more details. |
|
||||
| `$freeBusyCount` | :heavy_multiplication_x: | N/A | Tracks the free/busy count in the current iCal feed |
|
||||
| `$httpBasicAuth` | :heavy_multiplication_x: | `array()` | Holds the username and password for HTTP basic authentication |
|
||||
| `$httpUserAgent` | :ballot_box_with_check: | `null` | Holds the custom User Agent string header |
|
||||
| `$httpAcceptLanguage` | :heavy_multiplication_x: | `null` | Holds the custom Accept Language request header, e.g. "en" or "de" |
|
||||
| `$httpProtocolVersion` | :heavy_multiplication_x: | `null` | Holds the custom HTTP Protocol version, e.g. "1.0" or "1.1" |
|
||||
| `$shouldFilterByWindow` | :heavy_multiplication_x: | `false` | `true` if either `$filterDaysBefore` or `$filterDaysAfter` are set |
|
||||
| `$skipRecurrence` | :ballot_box_with_check: | `false` | Toggles whether to skip the parsing of recurrence rules |
|
||||
| `$todoCount` | :heavy_multiplication_x: | N/A | Tracks the number of todos in the current iCal feed |
|
||||
| `$windowMaxTimestamp` | :heavy_multiplication_x: | `null` | If `$filterDaysBefore` or `$filterDaysAfter` are set then the events are filtered according to the window defined by this field and `$windowMinTimestamp` |
|
||||
| `$windowMinTimestamp` | :heavy_multiplication_x: | `null` | If `$filterDaysBefore` or `$filterDaysAfter` are set then the events are filtered according to the window defined by this field and `$windowMaxTimestamp` |
|
||||
|
||||
#### Methods
|
||||
|
||||
| Method | Parameter(s) | Visibility | Description |
|
||||
|-------------------------------------------------|-----------------------------------------------------------------------------------------------|-------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `__construct` | `$files = false`, `$options = array()` | `public` | Creates the ICal object |
|
||||
| `initFile` | `$file` | `protected` | Initialises lines from a file |
|
||||
| `initLines` | `$lines` | `protected` | Initialises the parser using an array containing each line of iCal content |
|
||||
| `initString` | `$string` | `protected` | Initialises lines from a string |
|
||||
| `initUrl` | `$url`, `$username = null`, `$password = null`, `$userAgent = null`, `$acceptLanguage = null` | `protected` | Initialises lines from a URL. Accepts a username/password combination for HTTP basic authentication, a custom User Agent string and the accepted client language |
|
||||
| `addCalendarComponentWithKeyAndValue` | `$component`, `$keyword`, `$value` | `protected` | Add one key and value pair to the `$this->cal` array |
|
||||
| `calendarDescription` | - | `public` | Returns the calendar description |
|
||||
| `calendarName` | - | `public` | Returns the calendar name |
|
||||
| `calendarTimeZone` | `$ignoreUtc` | `public` | Returns the calendar time zone |
|
||||
| `cleanCharacters` | `$data` | `protected` | Replaces curly quotes and other special characters with their standard equivalents |
|
||||
| `eventsFromInterval` | `$interval` | `public` | Returns a sorted array of events following a given string |
|
||||
| `eventsFromRange` | `$rangeStart = false`, `$rangeEnd = false` | `public` | Returns a sorted array of events in a given range, or an empty array if no events exist in the range |
|
||||
| `events` | - | `public` | Returns an array of Events |
|
||||
| `fileOrUrl` | `$filename` | `protected` | Reads an entire file or URL into an array |
|
||||
| `filterValuesUsingBySetPosRRule` | `$bysetpos`, `$valueslist` | `protected` | Filters a provided values-list by applying a BYSETPOS RRule |
|
||||
| `freeBusyEvents` | - | `public` | Returns an array of arrays with all free/busy events |
|
||||
| `getDaysOfMonthMatchingByDayRRule` | `$bydays`, `$initialDateTime` | `protected` | Find all days of a month that match the BYDAY stanza of an RRULE |
|
||||
| `getDaysOfMonthMatchingByMonthDayRRule` | `$byMonthDays`, `$initialDateTime` | `protected` | Find all days of a month that match the BYMONTHDAY stanza of an RRULE |
|
||||
| `getDaysOfYearMatchingByDayRRule` | `$byDays`, `$initialDateTime` | `protected` | Find all days of a year that match the BYDAY stanza of an RRULE |
|
||||
| `getDaysOfYearMatchingByMonthDayRRule` | `$byMonthDays`, `$initialDateTime` | `protected` | Find all days of a year that match the BYMONTHDAY stanza of an RRULE |
|
||||
| `getDaysOfYearMatchingByWeekNoRRule` | `$byWeekNums`, `$initialDateTime` | `protected` | Find all days of a year that match the BYWEEKNO stanza of an RRULE |
|
||||
| `getDaysOfYearMatchingByYearDayRRule` | `$byYearDays`, `$initialDateTime` | `protected` | Find all days of a year that match the BYYEARDAY stanza of an RRULE |
|
||||
| `getDefaultTimeZone` | `$forceReturnSystemDefault` | `private` | Returns the default time zone if set or falls back to the system default if not set |
|
||||
| `hasEvents` | - | `public` | Returns a boolean value whether the current calendar has events or not |
|
||||
| `iCalDateToDateTime` | `$icalDate` | `public` | Returns a `DateTime` object from an iCal date time format |
|
||||
| `iCalDateToUnixTimestamp` | `$icalDate` | `public` | Returns a Unix timestamp from an iCal date time format |
|
||||
| `iCalDateWithTimeZone` | `$event`, `$key`, `$format = DATE_TIME_FORMAT` | `public` | Returns a date adapted to the calendar time zone depending on the event `TZID` |
|
||||
| `doesEventStartOutsideWindow` | `$event` | `protected` | Determines whether the event start date is outside `$windowMinTimestamp` / `$windowMaxTimestamp` |
|
||||
| `isFileOrUrl` | `$filename` | `protected` | Checks if a filename exists as a file or URL |
|
||||
| `isOutOfRange` | `$calendarDate`, `$minTimestamp`, `$maxTimestamp` | `protected` | Determines whether a valid iCalendar date is within a given range |
|
||||
| `isValidCldrTimeZoneId` | `$timeZone` | `protected` | Checks if a time zone is a valid CLDR time zone |
|
||||
| `isValidDate` | `$value` | `public` | Checks if a date string is a valid date |
|
||||
| `isValidIanaTimeZoneId` | `$timeZone` | `protected` | Checks if a time zone is a valid IANA time zone |
|
||||
| `isValidWindowsTimeZoneId` | `$timeZone` | `protected` | Checks if a time zone is a recognised Windows (non-CLDR) time zone |
|
||||
| `isValidTimeZoneId` | `$timeZone` | `protected` | Checks if a time zone is valid (IANA, CLDR, or Windows) |
|
||||
| `keyValueFromString` | `$text` | `public` | Gets the key value pair from an iCal string |
|
||||
| `parseLine` | `$line` | `protected` | Parses a line from an iCal file into an array of tokens |
|
||||
| `mb_chr` | `$code` | `protected` | Provides a polyfill for PHP 7.2's `mb_chr()`, which is a multibyte safe version of `chr()` |
|
||||
| `escapeParamText` | `$candidateText` | `protected` | Places double-quotes around texts that have characters not permitted in parameter-texts, but are permitted in quoted-texts. |
|
||||
| `parseDuration` | `$date`, `$duration` | `protected` | Parses a duration and applies it to a date |
|
||||
| `parseExdates` | `$event` | `public` | Parses a list of excluded dates to be applied to an Event |
|
||||
| `processDateConversions` | - | `protected` | Processes date conversions using the time zone |
|
||||
| `processEvents` | - | `protected` | Performs admin tasks on all events as read from the iCal file |
|
||||
| `processRecurrences` | - | `protected` | Processes recurrence rules |
|
||||
| `reduceEventsToMinMaxRange` | | `protected` | Reduces the number of events to the defined minimum and maximum range |
|
||||
| `removeLastEventIfOutsideWindowAndNonRecurring` | | `protected` | Removes the last event (i.e. most recently parsed) if its start date is outside the window spanned by `$windowMinTimestamp` / `$windowMaxTimestamp` |
|
||||
| `removeUnprintableChars` | `$data` | `protected` | Removes unprintable ASCII and UTF-8 characters |
|
||||
| `resolveIndicesOfRange` | `$indexes`, `$limit` | `protected` | Resolves values from indices of the range 1 -> `$limit` |
|
||||
| `sortEventsWithOrder` | `$events`, `$sortOrder = SORT_ASC` | `public` | Sorts events based on a given sort order |
|
||||
| `timeZoneStringToDateTimeZone` | `$timeZoneString` | `public` | Returns a `DateTimeZone` object based on a string containing a time zone name. |
|
||||
| `unfold` | `$lines` | `protected` | Unfolds an iCal file in preparation for parsing |
|
||||
|
||||
#### Constants
|
||||
|
||||
| Name | Description |
|
||||
|---------------------------|-----------------------------------------------|
|
||||
| `DATE_TIME_FORMAT_PRETTY` | Default pretty date time format to use |
|
||||
| `DATE_TIME_FORMAT` | Default date time format to use |
|
||||
| `ICAL_DATE_TIME_TEMPLATE` | String template to generate an iCal date time |
|
||||
| `ISO_8601_WEEK_START` | First day of the week, as defined by ISO-8601 |
|
||||
| `RECURRENCE_EVENT` | Used to isolate generated recurrence events |
|
||||
| `SECONDS_IN_A_WEEK` | The number of seconds in a week |
|
||||
| `TIME_FORMAT` | Default time format to use |
|
||||
| `TIME_ZONE_UTC` | UTC time zone string |
|
||||
| `UNIX_FORMAT` | Unix timestamp date format |
|
||||
| `UNIX_MIN_YEAR` | The year Unix time began |
|
||||
|
||||
---
|
||||
|
||||
### `Event` API (extends `ICal` API)
|
||||
|
||||
#### Methods
|
||||
|
||||
| Method | Parameter(s) | Visibility | Description |
|
||||
|---------------|---------------------------------------------|-------------|---------------------------------------------------------------------|
|
||||
| `__construct` | `$data = array()` | `public` | Creates the Event object |
|
||||
| `prepareData` | `$value` | `protected` | Prepares the data for output |
|
||||
| `printData` | `$html = HTML_TEMPLATE` | `public` | Returns Event data excluding anything blank within an HTML template |
|
||||
| `snakeCase` | `$input`, `$glue = '_'`, `$separator = '-'` | `protected` | Converts the given input to snake_case |
|
||||
|
||||
#### Constants
|
||||
|
||||
| Name | Description |
|
||||
|-----------------|-----------------------------------------------------|
|
||||
| `HTML_TEMPLATE` | String template to use when pretty printing content |
|
||||
|
||||
---
|
||||
|
||||
## Credits
|
||||
- [Jonathan Goode](https://github.com/u01jmg3) (programming, bug fixing, codebase enhancement, coding standard adoption)
|
||||
- [s0600204](https://github.com/s0600204) (major enhancements to RRULE support, many bug fixes and other contributions)
|
||||
|
||||
---
|
||||
|
||||
## Tools for Testing
|
||||
|
||||
- [iCal Validator](https://icalendar.org/validator.html)
|
||||
- [Recurrence Rule Tester](https://jkbrzt.github.io/rrule/)
|
||||
- [Unix Timestamp Converter](https://www.unixtimestamp.com)
|
||||
49
lib/composer/vendor/johngrogg/ics-parser/composer.json
vendored
Normal file
49
lib/composer/vendor/johngrogg/ics-parser/composer.json
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"name": "johngrogg/ics-parser",
|
||||
"description": "ICS Parser",
|
||||
"homepage": "https://github.com/u01jmg3/ics-parser",
|
||||
"keywords": [
|
||||
"ical",
|
||||
"ical-parser",
|
||||
"icalendar",
|
||||
"ics",
|
||||
"ics-parser",
|
||||
"ifb"
|
||||
],
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jonathan Goode",
|
||||
"role": "Developer/Owner"
|
||||
},
|
||||
{
|
||||
"name": "John Grogg",
|
||||
"email": "john.grogg@gmail.com",
|
||||
"role": "Developer/Prior Owner"
|
||||
}
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/u01jmg3"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.6.40",
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5|^9|^10"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"ICal": "src/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": [
|
||||
"phpunit --colors=always"
|
||||
]
|
||||
}
|
||||
}
|
||||
1763
lib/composer/vendor/johngrogg/ics-parser/composer.lock
generated
vendored
Normal file
1763
lib/composer/vendor/johngrogg/ics-parser/composer.lock
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
205
lib/composer/vendor/johngrogg/ics-parser/ecs.php
vendored
Normal file
205
lib/composer/vendor/johngrogg/ics-parser/ecs.php
vendored
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use PHP_CodeSniffer\Standards\Generic\Sniffs\Formatting\SpaceAfterNotSniff;
|
||||
use PHP_CodeSniffer\Standards\Squiz\Sniffs\Classes\SelfMemberReferenceSniff;
|
||||
use PhpCsFixer\Fixer\Alias\NoAliasFunctionsFixer;
|
||||
use PhpCsFixer\Fixer\Alias\NoMixedEchoPrintFixer;
|
||||
use PhpCsFixer\Fixer\ArrayNotation\ArraySyntaxFixer;
|
||||
use PhpCsFixer\Fixer\ArrayNotation\NoMultilineWhitespaceAroundDoubleArrowFixer;
|
||||
use PhpCsFixer\Fixer\ArrayNotation\NormalizeIndexBraceFixer;
|
||||
use PhpCsFixer\Fixer\ArrayNotation\TrimArraySpacesFixer;
|
||||
use PhpCsFixer\Fixer\Basic\EncodingFixer;
|
||||
use PhpCsFixer\Fixer\Basic\NoTrailingCommaInSinglelineFixer;
|
||||
use PhpCsFixer\Fixer\Casing\ConstantCaseFixer;
|
||||
use PhpCsFixer\Fixer\Casing\LowercaseKeywordsFixer;
|
||||
use PhpCsFixer\Fixer\Casing\LowercaseStaticReferenceFixer;
|
||||
use PhpCsFixer\Fixer\Casing\MagicConstantCasingFixer;
|
||||
use PhpCsFixer\Fixer\Casing\MagicMethodCasingFixer;
|
||||
use PhpCsFixer\Fixer\Casing\NativeFunctionCasingFixer;
|
||||
use PhpCsFixer\Fixer\Casing\NativeFunctionTypeDeclarationCasingFixer;
|
||||
use PhpCsFixer\Fixer\CastNotation\CastSpacesFixer;
|
||||
use PhpCsFixer\Fixer\CastNotation\NoShortBoolCastFixer;
|
||||
use PhpCsFixer\Fixer\ClassNotation\ClassDefinitionFixer;
|
||||
use PhpCsFixer\Fixer\ClassNotation\SingleClassElementPerStatementFixer;
|
||||
use PhpCsFixer\Fixer\Comment\NoTrailingWhitespaceInCommentFixer;
|
||||
use PhpCsFixer\Fixer\Comment\SingleLineCommentStyleFixer;
|
||||
use PhpCsFixer\Fixer\ControlStructure\ElseifFixer;
|
||||
use PhpCsFixer\Fixer\ControlStructure\IncludeFixer;
|
||||
use PhpCsFixer\Fixer\ControlStructure\NoUnneededControlParenthesesFixer;
|
||||
use PhpCsFixer\Fixer\ControlStructure\NoUnneededCurlyBracesFixer;
|
||||
use PhpCsFixer\Fixer\ControlStructure\SwitchCaseSemicolonToColonFixer;
|
||||
use PhpCsFixer\Fixer\ControlStructure\SwitchCaseSpaceFixer;
|
||||
use PhpCsFixer\Fixer\ControlStructure\TrailingCommaInMultilineFixer;
|
||||
use PhpCsFixer\Fixer\ControlStructure\YodaStyleFixer;
|
||||
use PhpCsFixer\Fixer\FunctionNotation\FunctionDeclarationFixer;
|
||||
use PhpCsFixer\Fixer\FunctionNotation\LambdaNotUsedImportFixer;
|
||||
use PhpCsFixer\Fixer\FunctionNotation\MethodArgumentSpaceFixer;
|
||||
use PhpCsFixer\Fixer\FunctionNotation\NoSpacesAfterFunctionNameFixer;
|
||||
use PhpCsFixer\Fixer\FunctionNotation\NoUnreachableDefaultArgumentValueFixer;
|
||||
use PhpCsFixer\Fixer\Import\NoUnusedImportsFixer;
|
||||
use PhpCsFixer\Fixer\Import\SingleImportPerStatementFixer;
|
||||
use PhpCsFixer\Fixer\Import\SingleLineAfterImportsFixer;
|
||||
use PhpCsFixer\Fixer\ListNotation\ListSyntaxFixer;
|
||||
use PhpCsFixer\Fixer\NamespaceNotation\BlankLinesBeforeNamespaceFixer;
|
||||
use PhpCsFixer\Fixer\NamespaceNotation\NoLeadingNamespaceWhitespaceFixer;
|
||||
use PhpCsFixer\Fixer\Operator\ObjectOperatorWithoutWhitespaceFixer;
|
||||
use PhpCsFixer\Fixer\Operator\StandardizeNotEqualsFixer;
|
||||
use PhpCsFixer\Fixer\Phpdoc\NoEmptyPhpdocFixer;
|
||||
use PhpCsFixer\Fixer\Phpdoc\PhpdocIndentFixer;
|
||||
use PhpCsFixer\Fixer\Phpdoc\PhpdocInlineTagNormalizerFixer;
|
||||
use PhpCsFixer\Fixer\Phpdoc\PhpdocNoAccessFixer;
|
||||
use PhpCsFixer\Fixer\Phpdoc\PhpdocNoPackageFixer;
|
||||
use PhpCsFixer\Fixer\Phpdoc\PhpdocNoUselessInheritdocFixer;
|
||||
use PhpCsFixer\Fixer\Phpdoc\PhpdocParamOrderFixer;
|
||||
use PhpCsFixer\Fixer\Phpdoc\PhpdocSingleLineVarSpacingFixer;
|
||||
use PhpCsFixer\Fixer\Phpdoc\PhpdocToCommentFixer;
|
||||
use PhpCsFixer\Fixer\Phpdoc\PhpdocTrimFixer;
|
||||
use PhpCsFixer\Fixer\Phpdoc\PhpdocTypesFixer;
|
||||
use PhpCsFixer\Fixer\PhpTag\FullOpeningTagFixer;
|
||||
use PhpCsFixer\Fixer\PhpTag\NoClosingTagFixer;
|
||||
use PhpCsFixer\Fixer\ReturnNotation\NoUselessReturnFixer;
|
||||
use PhpCsFixer\Fixer\Semicolon\MultilineWhitespaceBeforeSemicolonsFixer;
|
||||
use PhpCsFixer\Fixer\Semicolon\NoEmptyStatementFixer;
|
||||
use PhpCsFixer\Fixer\Semicolon\SpaceAfterSemicolonFixer;
|
||||
use PhpCsFixer\Fixer\StringNotation\HeredocToNowdocFixer;
|
||||
use PhpCsFixer\Fixer\StringNotation\SingleQuoteFixer;
|
||||
use PhpCsFixer\Fixer\Whitespace\BlankLineBeforeStatementFixer;
|
||||
use PhpCsFixer\Fixer\Whitespace\CompactNullableTypehintFixer;
|
||||
use PhpCsFixer\Fixer\Whitespace\LineEndingFixer;
|
||||
use PhpCsFixer\Fixer\Whitespace\NoExtraBlankLinesFixer;
|
||||
use PhpCsFixer\Fixer\Whitespace\NoSpacesInsideParenthesisFixer;
|
||||
use PhpCsFixer\Fixer\Whitespace\NoWhitespaceInBlankLineFixer;
|
||||
use PhpCsFixer\Fixer\Whitespace\SingleBlankLineAtEofFixer;
|
||||
use PhpCsFixer\Fixer\Whitespace\TypeDeclarationSpacesFixer;
|
||||
use SlevomatCodingStandard\Sniffs\Namespaces\AlphabeticallySortedUsesSniff;
|
||||
use SlevomatCodingStandard\Sniffs\Variables\UnusedVariableSniff;
|
||||
use Symplify\EasyCodingStandard\Config\ECSConfig;
|
||||
use Symplify\EasyCodingStandard\ValueObject\Set\SetList;
|
||||
|
||||
// ecs check --fix .
|
||||
|
||||
return static function (ECSConfig $ecsConfig): void {
|
||||
$ecsConfig->disableParallel();
|
||||
|
||||
// https://github.com/easy-coding-standard/easy-coding-standard/blob/main/config/set/psr12.php
|
||||
$ecsConfig->import(SetList::PSR_12);
|
||||
|
||||
$ecsConfig->lineEnding("\n");
|
||||
|
||||
$ecsConfig->skip(array(
|
||||
// Fixers
|
||||
'PhpCsFixer\Fixer\Whitespace\StatementIndentationFixer' => array('examples/index.php'),
|
||||
'PhpCsFixer\Fixer\Basic\BracesFixer' => null,
|
||||
'PhpCsFixer\Fixer\Operator\BinaryOperatorSpacesFixer' => null,
|
||||
'PhpCsFixer\Fixer\Operator\NotOperatorWithSuccessorSpaceFixer' => null,
|
||||
'PhpCsFixer\Fixer\Phpdoc\PhpdocScalarFixer' => null,
|
||||
'PhpCsFixer\Fixer\Phpdoc\PhpdocSummaryFixer' => null,
|
||||
'PhpCsFixer\Fixer\Phpdoc\PhpdocVarWithoutNameFixer' => null,
|
||||
'PhpCsFixer\Fixer\ReturnNotation\SimplifiedNullReturnFixer' => null,
|
||||
// Requires PHP 7.1 and above
|
||||
'PhpCsFixer\Fixer\ClassNotation\VisibilityRequiredFixer' => null,
|
||||
));
|
||||
|
||||
$ecsConfig->ruleWithConfiguration(SpaceAfterNotSniff::class, array('spacing' => 0));
|
||||
|
||||
$ecsConfig->ruleWithConfiguration(ArraySyntaxFixer::class, array('syntax' => 'long'));
|
||||
|
||||
$ecsConfig->ruleWithConfiguration(
|
||||
YodaStyleFixer::class,
|
||||
array(
|
||||
'equal' => false,
|
||||
'identical' => false,
|
||||
'less_and_greater' => false,
|
||||
)
|
||||
);
|
||||
|
||||
$ecsConfig->ruleWithConfiguration(ListSyntaxFixer::class, array('syntax' => 'long')); // PHP 5.6
|
||||
|
||||
$ecsConfig->ruleWithConfiguration(
|
||||
BlankLineBeforeStatementFixer::class,
|
||||
array(
|
||||
'statements' => array(
|
||||
'continue',
|
||||
'declare',
|
||||
'return',
|
||||
'throw',
|
||||
'try',
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
$ecsConfig->rules(
|
||||
array(
|
||||
AlphabeticallySortedUsesSniff::class,
|
||||
UnusedVariableSniff::class,
|
||||
SelfMemberReferenceSniff::class,
|
||||
BlankLinesBeforeNamespaceFixer::class,
|
||||
CastSpacesFixer::class,
|
||||
ClassDefinitionFixer::class,
|
||||
CompactNullableTypehintFixer::class,
|
||||
ConstantCaseFixer::class,
|
||||
ElseifFixer::class,
|
||||
EncodingFixer::class,
|
||||
FullOpeningTagFixer::class,
|
||||
FunctionDeclarationFixer::class,
|
||||
HeredocToNowdocFixer::class,
|
||||
IncludeFixer::class,
|
||||
LambdaNotUsedImportFixer::class,
|
||||
LineEndingFixer::class,
|
||||
LowercaseKeywordsFixer::class,
|
||||
LowercaseStaticReferenceFixer::class,
|
||||
MagicConstantCasingFixer::class,
|
||||
MagicMethodCasingFixer::class,
|
||||
MethodArgumentSpaceFixer::class,
|
||||
MultilineWhitespaceBeforeSemicolonsFixer::class,
|
||||
NativeFunctionCasingFixer::class,
|
||||
NativeFunctionTypeDeclarationCasingFixer::class,
|
||||
NoAliasFunctionsFixer::class,
|
||||
NoClosingTagFixer::class,
|
||||
NoEmptyPhpdocFixer::class,
|
||||
NoEmptyStatementFixer::class,
|
||||
NoExtraBlankLinesFixer::class,
|
||||
NoLeadingNamespaceWhitespaceFixer::class,
|
||||
NoMixedEchoPrintFixer::class,
|
||||
NoMultilineWhitespaceAroundDoubleArrowFixer::class,
|
||||
NoShortBoolCastFixer::class,
|
||||
NoSpacesAfterFunctionNameFixer::class,
|
||||
NoSpacesInsideParenthesisFixer::class,
|
||||
NoTrailingCommaInSinglelineFixer::class,
|
||||
NoTrailingWhitespaceInCommentFixer::class,
|
||||
NoUnneededControlParenthesesFixer::class,
|
||||
NoUnneededCurlyBracesFixer::class,
|
||||
NoUnreachableDefaultArgumentValueFixer::class,
|
||||
NoUnusedImportsFixer::class,
|
||||
NoUselessReturnFixer::class,
|
||||
NoWhitespaceInBlankLineFixer::class,
|
||||
NormalizeIndexBraceFixer::class,
|
||||
ObjectOperatorWithoutWhitespaceFixer::class,
|
||||
PhpdocIndentFixer::class,
|
||||
PhpdocInlineTagNormalizerFixer::class,
|
||||
PhpdocNoAccessFixer::class,
|
||||
PhpdocNoPackageFixer::class,
|
||||
PhpdocNoUselessInheritdocFixer::class,
|
||||
PhpdocParamOrderFixer::class,
|
||||
PhpdocSingleLineVarSpacingFixer::class,
|
||||
PhpdocToCommentFixer::class,
|
||||
PhpdocTrimFixer::class,
|
||||
PhpdocTypesFixer::class,
|
||||
SingleBlankLineAtEofFixer::class,
|
||||
SingleClassElementPerStatementFixer::class,
|
||||
SingleImportPerStatementFixer::class,
|
||||
SingleLineAfterImportsFixer::class,
|
||||
SingleLineCommentStyleFixer::class,
|
||||
SingleQuoteFixer::class,
|
||||
SpaceAfterSemicolonFixer::class,
|
||||
StandardizeNotEqualsFixer::class,
|
||||
SwitchCaseSemicolonToColonFixer::class,
|
||||
SwitchCaseSpaceFixer::class,
|
||||
TrailingCommaInMultilineFixer::class,
|
||||
TrimArraySpacesFixer::class,
|
||||
TypeDeclarationSpacesFixer::class,
|
||||
)
|
||||
);
|
||||
};
|
||||
338
lib/composer/vendor/johngrogg/ics-parser/examples/ICal.ics
vendored
Normal file
338
lib/composer/vendor/johngrogg/ics-parser/examples/ICal.ics
vendored
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
BEGIN:VCALENDAR
|
||||
PRODID:-//Google Inc//Google Calendar 70.9054//EN
|
||||
VERSION:2.0
|
||||
CALSCALE:GREGORIAN
|
||||
METHOD:PUBLISH
|
||||
X-WR-CALNAME:Testkalender
|
||||
X-WR-TIMEZONE:UTC
|
||||
X-WR-CALDESC:Nur zum testen vom Google Kalender
|
||||
BEGIN:VFREEBUSY
|
||||
UID:f06ff6b3564b2f696bf42d393f8dea59
|
||||
ORGANIZER:MAILTO:jane_smith@host1.com
|
||||
DTSTAMP:20170316T204607Z
|
||||
DTSTART:20170213T204607Z
|
||||
DTEND:20180517T204607Z
|
||||
URL:https://www.host.com/calendar/busytime/jsmith.ifb
|
||||
FREEBUSY;FBTYPE=BUSY:20170623T070000Z/20170223T110000Z
|
||||
FREEBUSY;FBTYPE=BUSY:20170624T131500Z/20170316T151500Z
|
||||
FREEBUSY;FBTYPE=BUSY:20170715T131500Z/20170416T150000Z
|
||||
FREEBUSY;FBTYPE=BUSY:20170716T131500Z/20170516T100500Z
|
||||
END:VFREEBUSY
|
||||
BEGIN:VEVENT
|
||||
DTSTART:20171032T000000
|
||||
DTEND:20171101T2300
|
||||
DESCRIPTION:Invalid date - parser will skip the event
|
||||
SUMMARY:Invalid date - parser will skip the event
|
||||
DTSTAMP:20170406T063924
|
||||
LOCATION:
|
||||
UID:f81b0b41a2e138ae0903daee0a966e1e
|
||||
SEQUENCE:0
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;VALUE=DATE;TZID=America/Los_Angeles:19410512
|
||||
DTEND;VALUE=DATE;TZID=America/Los_Angeles:19410512
|
||||
DTSTAMP;TZID=America/Los_Angeles:19410512T195741Z
|
||||
UID:dh3fki5du0opa7cs5n5s87ca02@google.com
|
||||
CREATED:20380101T141901Z
|
||||
DESCRIPTION;LANGUAGE=en-gb:
|
||||
LAST-MODIFIED:20380101T141901Z
|
||||
LOCATION:
|
||||
SEQUENCE:0
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY;LANGUAGE=en-gb:Before 1970-Test: Konrad Zuse invents the Z3, the "first
|
||||
digital Computer"
|
||||
TRANSP:TRANSPARENT
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;VALUE=DATE:20380201
|
||||
DTEND;VALUE=DATE:20380202
|
||||
DTSTAMP;TZID="GMT Standard Time":20380101T195741Z
|
||||
UID:dh3fki5du0opa7cs5n5s87ca01@google.com
|
||||
CREATED:20380101T141901Z
|
||||
DESCRIPTION;LANGUAGE=en-gb:
|
||||
LAST-MODIFIED:20380101T141901Z
|
||||
LOCATION:
|
||||
SEQUENCE:0
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY;LANGUAGE=en-gb:Year 2038 problem test
|
||||
TRANSP:TRANSPARENT
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART:20160105T090000Z
|
||||
DTEND:20160107T173000Z
|
||||
DTSTAMP;TZID="Greenwich Mean Time:Dublin; Edinburgh; Lisbon; London":20110121T195741Z
|
||||
UID:15lc1nvupht8dtfiptenljoiv4@google.com
|
||||
CREATED:20110121T195616Z
|
||||
DESCRIPTION;LANGUAGE=en-gb:This is a short description\nwith a new line. Some "special" 's
|
||||
igns' may be interesting\, too.
|
||||
And a non-breaking space.
|
||||
LAST-MODIFIED:20150409T150000Z
|
||||
LOCATION:Kansas
|
||||
SEQUENCE:2
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY;LANGUAGE=en-gb:My Holidays
|
||||
TRANSP:TRANSPARENT
|
||||
ORGANIZER;CN="My Name":mailto:my.name@mydomain.com
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
ATTENDEE;CN="Page, Larry <l.page@google.com> (l.page@google.com)";ROLE=REQ-PARTICIPANT;RSVP=FALSE:mailto:l.page@google.com
|
||||
ATTENDEE;CN="Brin, Sergey <s.brin@google.com> (s.brin@google.com)";ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:s.brin@google.com
|
||||
DTSTART;VALUE=DATE:20160112
|
||||
DTEND;VALUE=DATE:20160116
|
||||
DTSTAMP;TZID="GMT Standard Time":20110121T195741Z
|
||||
UID:1koigufm110c5hnq6ln57murd4@google.com
|
||||
CREATED:20110119T142901Z
|
||||
DESCRIPTION;LANGUAGE=en-gb:Project xyz Review Meeting Minutes\n
|
||||
Agenda\n1. Review of project version 1.0 requirements.\n2.
|
||||
Definition
|
||||
of project processes.\n3. Review of project schedule.\n
|
||||
Participants: John Smith, Jane Doe, Jim Dandy\n-It was
|
||||
decided that the requirements need to be signed off by
|
||||
product marketing.\n-Project processes were accepted.\n
|
||||
-Project schedule needs to account for scheduled holidays
|
||||
and employee vacation time. Check with HR for specific
|
||||
dates.\n-New schedule will be distributed by Friday.\n-
|
||||
Next weeks meeting is cancelled. No meeting until 3/23.
|
||||
LAST-MODIFIED:20150409T150000Z
|
||||
LOCATION:
|
||||
SEQUENCE:2
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY;LANGUAGE=en-gb:Test 2
|
||||
TRANSP:TRANSPARENT
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;VALUE=DATE:20160119
|
||||
DTEND;VALUE=DATE:20160120
|
||||
DTSTAMP;TZID="GMT Standard Time":20110121T195741Z
|
||||
UID:rq8jng4jgq0m1lvpj8486fttu0@google.com
|
||||
CREATED:20110119T141904Z
|
||||
DESCRIPTION;LANGUAGE=en-gb:
|
||||
LAST-MODIFIED:20150409T150000Z
|
||||
LOCATION:
|
||||
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
||||
SEQUENCE:0
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY;LANGUAGE=en-gb:DST Change
|
||||
TRANSP:TRANSPARENT
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;VALUE=DATE:20160119
|
||||
DTEND;VALUE=DATE:20160120
|
||||
DTSTAMP;TZID="GMT Standard Time":20110121T195741Z
|
||||
UID:dh3fki5du0opa7cs5n5s87ca00@google.com
|
||||
CREATED:20110119T141901Z
|
||||
DESCRIPTION;LANGUAGE=en-gb:
|
||||
LAST-MODIFIED:20150409T150000Z
|
||||
LOCATION:
|
||||
RRULE:FREQ=WEEKLY;COUNT=5;INTERVAL=2;BYDAY=TU
|
||||
SEQUENCE:0
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY;LANGUAGE=en-gb:Test 1
|
||||
TRANSP:TRANSPARENT
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
SUMMARY:Duration Test
|
||||
DTSTART:20160425T150000Z
|
||||
DTSTAMP:20160424T150000Z
|
||||
DURATION:PT1H15M5S
|
||||
RRULE:FREQ=DAILY;COUNT=2
|
||||
UID:calendar-62-e7c39bf02382917349672271dd781c89
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
SUMMARY:BYMONTHDAY Test
|
||||
DTSTART:20160922T130000Z
|
||||
DTEND:20160922T150000Z
|
||||
DTSTAMP:20160921T130000Z
|
||||
RRULE:FREQ=MONTHLY;UNTIL=20170923T000000Z;INTERVAL=1;BYMONTHDAY=23
|
||||
UID:33844fe8df15fbfc13c97fc41c0c4b00392c6870@google.com
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;TZID=Europe/Paris:20160921T080000
|
||||
DTEND;TZID=Europe/Paris:20160921T090000
|
||||
RRULE:FREQ=WEEKLY;BYDAY=WE
|
||||
DTSTAMP:20161117T165045Z
|
||||
UID:884bc8350185031337d9ec49d2e7e101dd5ae5fb@google.com
|
||||
CREATED:20160920T133918Z
|
||||
DESCRIPTION:
|
||||
LAST-MODIFIED:20160920T133923Z
|
||||
LOCATION:
|
||||
SEQUENCE:1
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY:Paris Timezone Test
|
||||
TRANSP:OPAQUE
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART:20160215T080000Z
|
||||
DTEND:20160515T090000Z
|
||||
DTSTAMP:20161121T113027Z
|
||||
CREATED:20161121T113027Z
|
||||
UID:65323c541a30dd1f180e2bbfa2724995
|
||||
DESCRIPTION:
|
||||
LAST-MODIFIED:20161121T113027Z
|
||||
LOCATION:
|
||||
SEQUENCE:1
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY:Long event covering the range from example with special chars:
|
||||
ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÕÖÒÓÔØÙÚÛÜÝÞß
|
||||
àáâãäåæçèéêėëìíîïðñòóôõöøùúûüūýþÿž
|
||||
‘ ’ ‚ ‛ “ ” „ ‟ – — …
|
||||
TRANSP:OPAQUE
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
CLASS:PUBLIC
|
||||
CREATED:20160706T161104Z
|
||||
DTEND;TZID="(UTC-05:00) Eastern Time (US & Canada)":20160409T110000
|
||||
DTSTAMP:20160706T150005Z
|
||||
DTSTART;TZID="(UTC-05:00) Eastern Time (US & Canada)":20160409T090000
|
||||
EXDATE;TZID="(UTC-05:00) Eastern Time (US & Canada)":
|
||||
20160528T090000,
|
||||
20160625T090000
|
||||
LAST-MODIFIED:20160707T182011Z
|
||||
EXDATE;TZID="(UTC-05:00) Eastern Time (US & Canada)":20160709T090000
|
||||
EXDATE;TZID="(UTC-05:00) Eastern Time (US & Canada)":20160723T090000
|
||||
LOCATION:Sanctuary
|
||||
PRIORITY:5
|
||||
RRULE:FREQ=WEEKLY;COUNT=15;BYDAY=SA
|
||||
SEQUENCE:0
|
||||
SUMMARY:Microsoft Unicode CLDR EXDATE Test
|
||||
TRANSP:OPAQUE
|
||||
UID:040000008200E00074C5B7101A82E0080000000020F6512D0B48CF0100000000000000001000000058BFB8CBB85D504CB99FBA637BCFD6BF
|
||||
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
|
||||
X-MICROSOFT-CDO-IMPORTANCE:1
|
||||
X-MICROSOFT-DISALLOW-COUNTER:FALSE
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;VALUE=DATE:20170118
|
||||
DTEND;VALUE=DATE:20170118
|
||||
DTSTAMP;TZID="GMT Standard Time":20170121T195741Z
|
||||
RRULE:FREQ=MONTHLY;BYSETPOS=3;BYDAY=WE;COUNT=5
|
||||
UID:4dnsuc3nknin15kv25cn7ridss@google.com
|
||||
CREATED:20170119T142059Z
|
||||
DESCRIPTION;LANGUAGE=en-gb:BYDAY Test 1
|
||||
LAST-MODIFIED:20170409T150000Z
|
||||
SEQUENCE:0
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY;LANGUAGE=en-gb:BYDAY Test 1
|
||||
TRANSP:TRANSPARENT
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;VALUE=DATE:20190101
|
||||
DTEND;VALUE=DATE:20190101
|
||||
DTSTAMP;TZID="GMT Standard Time":20190101T195741Z
|
||||
RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1
|
||||
UID:4dnsuc3nknin15kv25cn7ridssy@google.com
|
||||
CREATED:20190101T142059Z
|
||||
DESCRIPTION;LANGUAGE=en-gb:BYSETPOS First weekday of every month
|
||||
LAST-MODIFIED:20190101T150000Z
|
||||
SEQUENCE:0
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY;LANGUAGE=en-gb:BYSETPOS First weekday of every month
|
||||
TRANSP:TRANSPARENT
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;VALUE=DATE:20190131
|
||||
DTEND;VALUE=DATE:20190131
|
||||
DTSTAMP;TZID="GMT Standard Time":20190121T195741Z
|
||||
RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=SU,MO,TU,WE,TH,FR,SA;BYSETPOS=-1
|
||||
UID:4dnsuc3nknin15kv25cn7ridssx@google.com
|
||||
CREATED:20190119T142059Z
|
||||
DESCRIPTION;LANGUAGE=en-gb:BYSETPOS Last day of every month
|
||||
LAST-MODIFIED:20190409T150000Z
|
||||
SEQUENCE:0
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY;LANGUAGE=en-gb:BYSETPOS Last day of every month
|
||||
TRANSP:TRANSPARENT
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;VALUE=DATE:20170301
|
||||
DTEND;VALUE=DATE:20170301
|
||||
DTSTAMP;TZID="GMT Standard Time":20170121T195741Z
|
||||
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=WE
|
||||
UID:h6f7sdjbpt47v3dkral8lnsgcc@google.com
|
||||
CREATED:20170119T142040Z
|
||||
DESCRIPTION;LANGUAGE=en-gb:BYDAY Test 2
|
||||
LAST-MODIFIED:20170409T150000Z
|
||||
SEQUENCE:0
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY;LANGUAGE=en-gb:BYDAY Test 2
|
||||
TRANSP:TRANSPARENT
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;VALUE=DATE:20170111
|
||||
DTEND;VALUE=DATE:20170111
|
||||
DTSTAMP;TZID="GMT Standard Time":20170121T195741Z
|
||||
RRULE:FREQ=YEARLY;INTERVAL=2;COUNT=5;BYMONTH=1,2,3
|
||||
UID:f50e8b89a4a3b0070e0b687d03@google.com
|
||||
CREATED:20170119T142040Z
|
||||
DESCRIPTION;LANGUAGE=en-gb:BYMONTH Multiple Test 1
|
||||
LAST-MODIFIED:20170409T150000Z
|
||||
SEQUENCE:0
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY;LANGUAGE=en-gb:BYMONTH Multiple Test 1
|
||||
TRANSP:TRANSPARENT
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;VALUE=DATE:20170405
|
||||
DTEND;VALUE=DATE:20170405
|
||||
DTSTAMP;TZID="GMT Standard Time":20170121T195741Z
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4,5,6;BYDAY=WE;COUNT=5
|
||||
UID:675f06aa795665ae50904ebf0e@google.com
|
||||
CREATED:20170119T142040Z
|
||||
DESCRIPTION;LANGUAGE=en-gb:BYMONTH Multiple Test 2
|
||||
LAST-MODIFIED:20170409T150000Z
|
||||
SEQUENCE:0
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY;LANGUAGE=en-gb:BYMONTH Multiple Test 2
|
||||
TRANSP:TRANSPARENT
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
BEGIN:VALARM
|
||||
TRIGGER;VALUE=DURATION:-PT30M
|
||||
ACTION:DISPLAY
|
||||
DESCRIPTION:Buzz buzz
|
||||
END:VALARM
|
||||
DTSTART;VALUE=DATE;TZID=Germany/Berlin:20170123
|
||||
DTEND;VALUE=DATE;TZID=Germany/Berlin:20170123
|
||||
DTSTAMP;TZID="GMT Standard Time":20170121T195741Z
|
||||
RRULE:FREQ=MONTHLY;BYDAY=-2MO;COUNT=5
|
||||
EXDATE;VALUE=DATE:20171020
|
||||
UID:d287b7ec808fcf084983f10837@google.com
|
||||
CREATED:20170119T142040Z
|
||||
DESCRIPTION;LANGUAGE=en-gb:Negative BYDAY
|
||||
LAST-MODIFIED:20170409T150000Z
|
||||
SEQUENCE:0
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY;LANGUAGE=en-gb:Negative BYDAY
|
||||
TRANSP:TRANSPARENT
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;TZID=Australia/Sydney:20170813T190000
|
||||
DTEND;TZID=Australia/Sydney:20170813T213000
|
||||
RRULE:FREQ=MONTHLY;INTERVAL=2;BYDAY=2SU;COUNT=2
|
||||
DTSTAMP:20170809T114431Z
|
||||
UID:testuid@google.com
|
||||
CREATED:20170802T135539Z
|
||||
DESCRIPTION:
|
||||
LAST-MODIFIED:20170802T135935Z
|
||||
LOCATION:
|
||||
SEQUENCE:1
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY:Parent Recurrence Event
|
||||
TRANSP:OPAQUE
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;TZID=Australia/Sydney:20170813T190000
|
||||
DTEND;TZID=Australia/Sydney:20170813T213000
|
||||
DTSTAMP:20170809T114431Z
|
||||
UID:testuid@google.com
|
||||
RECURRENCE-ID;TZID=Australia/Sydney:20170813T190000
|
||||
CREATED:20170802T135539Z
|
||||
DESCRIPTION:
|
||||
LAST-MODIFIED:20170809T105604Z
|
||||
LOCATION:Melbourne VIC\, Australia
|
||||
SEQUENCE:1
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY:Override Parent Recurrence Event
|
||||
TRANSP:OPAQUE
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
175
lib/composer/vendor/johngrogg/ics-parser/examples/index.php
vendored
Normal file
175
lib/composer/vendor/johngrogg/ics-parser/examples/index.php
vendored
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
<?php
|
||||
// phpcs:disable Generic.Arrays.DisallowLongArraySyntax
|
||||
|
||||
require_once '../vendor/autoload.php';
|
||||
|
||||
use ICal\ICal;
|
||||
|
||||
try {
|
||||
$ical = new ICal('ICal.ics', array(
|
||||
'defaultSpan' => 2, // Default value
|
||||
'defaultTimeZone' => 'UTC',
|
||||
'defaultWeekStart' => 'MO', // Default value
|
||||
'disableCharacterReplacement' => false, // Default value
|
||||
'filterDaysAfter' => null, // Default value
|
||||
'filterDaysBefore' => null, // Default value
|
||||
'httpUserAgent' => null, // Default value
|
||||
'skipRecurrence' => false, // Default value
|
||||
));
|
||||
// $ical->initFile('ICal.ics');
|
||||
// $ical->initUrl('https://raw.githubusercontent.com/u01jmg3/ics-parser/master/examples/ICal.ics', $username = null, $password = null, $userAgent = null);
|
||||
} catch (\Exception $e) {
|
||||
die($e);
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<!-- Latest compiled and minified CSS -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
|
||||
<title>PHP ICS Parser example</title>
|
||||
<style>body { background-color: #eee }</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-fluid">
|
||||
<h4 class="mt-3 mb-2">PHP ICS Parser example</h3>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
The number of events
|
||||
<span class="badge rounded-pill bg-secondary float-end"><?php echo $ical->eventCount ?></span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
The number of free/busy time slots
|
||||
<span class="badge rounded-pill bg-secondary float-end"><?php echo $ical->freeBusyCount ?></span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
The number of todos
|
||||
<span class="badge rounded-pill bg-secondary float-end"><?php echo $ical->todoCount ?></span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
The number of alarms
|
||||
<span class="badge rounded-pill bg-secondary float-end"><?php echo $ical->alarmCount ?></span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<?php
|
||||
$showExample = array(
|
||||
'interval' => true,
|
||||
'range' => true,
|
||||
'all' => true,
|
||||
);
|
||||
?>
|
||||
|
||||
<?php
|
||||
if ($showExample['interval']) {
|
||||
$events = $ical->eventsFromInterval('1 week');
|
||||
|
||||
if ($events) {
|
||||
echo '<h4 class="mt-3 mb-2">Events in the next 7 days:</h4>';
|
||||
}
|
||||
|
||||
$count = 1;
|
||||
?>
|
||||
<div class="row">
|
||||
<?php
|
||||
foreach ($events as $event) : ?>
|
||||
<div class="col-md-4">
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<h4 class="mt-3 mb-2"><?php
|
||||
$dtstart = $ical->iCalDateToDateTime($event->dtstart_array[3]);
|
||||
echo $event->summary . ' (' . $dtstart->format('d-m-Y H:i') . ')';
|
||||
?></h3>
|
||||
<?php echo $event->printData() ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
if ($count > 1 && $count % 3 === 0) {
|
||||
echo '</div><div class="row">';
|
||||
}
|
||||
|
||||
$count++;
|
||||
?>
|
||||
<?php
|
||||
endforeach
|
||||
?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php
|
||||
if ($showExample['range']) {
|
||||
$events = $ical->eventsFromRange('2017-03-01 12:00:00', '2017-04-31 17:00:00');
|
||||
|
||||
if ($events) {
|
||||
echo '<h4 class="mt-3 mb-2">Events March through April:</h4>';
|
||||
}
|
||||
|
||||
$count = 1;
|
||||
?>
|
||||
<div class="row">
|
||||
<?php
|
||||
foreach ($events as $event) : ?>
|
||||
<div class="col-md-4">
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<h4 class="mt-3 mb-2"><?php
|
||||
$dtstart = $ical->iCalDateToDateTime($event->dtstart_array[3]);
|
||||
echo $event->summary . ' (' . $dtstart->format('d-m-Y H:i') . ')';
|
||||
?></h3>
|
||||
<?php echo $event->printData() ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
if ($count > 1 && $count % 3 === 0) {
|
||||
echo '</div><div class="row">';
|
||||
}
|
||||
|
||||
$count++;
|
||||
?>
|
||||
<?php
|
||||
endforeach
|
||||
?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php
|
||||
if ($showExample['all']) {
|
||||
$events = $ical->sortEventsWithOrder($ical->events());
|
||||
|
||||
if ($events) {
|
||||
echo '<h4 class="mt-3 mb-2">All Events:</h4>';
|
||||
}
|
||||
?>
|
||||
<div class="row">
|
||||
<?php
|
||||
$count = 1;
|
||||
foreach ($events as $event) : ?>
|
||||
<div class="col-md-4">
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<h4 class="mt-3 mb-2"><?php
|
||||
$dtstart = $ical->iCalDateToDateTime($event->dtstart_array[3]);
|
||||
echo $event->summary . ' (' . $dtstart->format('d-m-Y H:i') . ')';
|
||||
?></h3>
|
||||
<?php echo $event->printData() ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
if ($count > 1 && $count % 3 === 0) {
|
||||
echo '</div><div class="row">';
|
||||
}
|
||||
|
||||
$count++;
|
||||
?>
|
||||
<?php
|
||||
endforeach
|
||||
?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
9
lib/composer/vendor/johngrogg/ics-parser/phpstan.neon.dist
vendored
Normal file
9
lib/composer/vendor/johngrogg/ics-parser/phpstan.neon.dist
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
parameters:
|
||||
paths:
|
||||
- src
|
||||
|
||||
level: max
|
||||
|
||||
ignoreErrors:
|
||||
-
|
||||
identifier: missingType.iterableValue
|
||||
7
lib/composer/vendor/johngrogg/ics-parser/phpunit.xml
vendored
Normal file
7
lib/composer/vendor/johngrogg/ics-parser/phpunit.xml
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<phpunit>
|
||||
<testsuites>
|
||||
<testsuite name="ics-parser">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
||||
79
lib/composer/vendor/johngrogg/ics-parser/rector.php
vendored
Normal file
79
lib/composer/vendor/johngrogg/ics-parser/rector.php
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Config\RectorConfig;
|
||||
use Rector\Php53\Rector\Ternary\TernaryToElvisRector;
|
||||
use Rector\Set\ValueObject\SetList;
|
||||
use Rector\ValueObject\PhpVersion;
|
||||
|
||||
// phpcs:disable Generic.Arrays.DisallowLongArraySyntax
|
||||
|
||||
// rector process src
|
||||
|
||||
return static function (RectorConfig $rectorConfig): void {
|
||||
$rectorConfig->disableParallel();
|
||||
|
||||
$rectorConfig->importShortClasses(false);
|
||||
|
||||
$rectorConfig->phpVersion(PhpVersion::PHP_56);
|
||||
|
||||
$rectorConfig->skip(
|
||||
array(
|
||||
Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector::class,
|
||||
Rector\CodeQuality\Rector\Concat\JoinStringConcatRector::class,
|
||||
Rector\CodeQuality\Rector\FuncCall\ChangeArrayPushToArrayAssignRector::class,
|
||||
Rector\CodeQuality\Rector\FuncCall\CompactToVariablesRector::class,
|
||||
Rector\CodeQuality\Rector\FuncCall\InlineIsAInstanceOfRector::class,
|
||||
Rector\CodeQuality\Rector\FunctionLike\SimplifyUselessVariableRector::class,
|
||||
Rector\CodeQuality\Rector\Identical\BooleanNotIdenticalToNotIdenticalRector::class,
|
||||
Rector\CodeQuality\Rector\Identical\SimplifyBoolIdenticalTrueRector::class,
|
||||
Rector\CodeQuality\Rector\If_\CombineIfRector::class,
|
||||
Rector\CodeQuality\Rector\If_\ExplicitBoolCompareRector::class,
|
||||
Rector\CodeQuality\Rector\If_\SimplifyIfElseToTernaryRector::class,
|
||||
Rector\CodeQuality\Rector\If_\SimplifyIfReturnBoolRector::class,
|
||||
Rector\CodeQuality\Rector\Isset_\IssetOnPropertyObjectToPropertyExistsRector::class,
|
||||
Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector::class,
|
||||
Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector::class,
|
||||
Rector\CodingStyle\Rector\String_\SymplifyQuoteEscapeRector::class,
|
||||
Rector\DeadCode\Rector\Assign\RemoveUnusedVariableAssignRector::class,
|
||||
Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPromotedPropertyRector::class,
|
||||
Rector\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector::class,
|
||||
Rector\DeadCode\Rector\ClassMethod\RemoveUselessReturnTagRector::class,
|
||||
Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
|
||||
Rector\Php70\Rector\MethodCall\ThisCallOnStaticMethodToStaticCallRector::class,
|
||||
Rector\Php70\Rector\StaticCall\StaticCallOnNonStaticToInstanceCallRector::class,
|
||||
Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
|
||||
// PHP 5.6 incompatible
|
||||
Rector\CodeQuality\Rector\Ternary\ArrayKeyExistsTernaryThenValueToCoalescingRector::class, // PHP 7
|
||||
Rector\Php70\Rector\If_\IfToSpaceshipRector::class,
|
||||
Rector\Php70\Rector\Ternary\TernaryToSpaceshipRector::class,
|
||||
Rector\Php71\Rector\BooleanOr\IsIterableRector::class,
|
||||
Rector\Php71\Rector\List_\ListToArrayDestructRector::class,
|
||||
Rector\Php71\Rector\TryCatch\MultiExceptionCatchRector::class,
|
||||
Rector\Php73\Rector\FuncCall\ArrayKeyFirstLastRector::class,
|
||||
Rector\Php73\Rector\BooleanOr\IsCountableRector::class,
|
||||
Rector\Php74\Rector\Assign\NullCoalescingOperatorRector::class,
|
||||
Rector\Php74\Rector\StaticCall\ExportToReflectionFunctionRector::class,
|
||||
Rector\CodingStyle\Rector\ClassConst\RemoveFinalFromConstRector::class, // PHP 8
|
||||
)
|
||||
);
|
||||
|
||||
$rectorConfig->sets(
|
||||
array(
|
||||
SetList::CODE_QUALITY,
|
||||
SetList::CODING_STYLE,
|
||||
SetList::DEAD_CODE,
|
||||
SetList::PHP_70,
|
||||
SetList::PHP_71,
|
||||
SetList::PHP_72,
|
||||
SetList::PHP_73,
|
||||
SetList::PHP_74,
|
||||
SetList::PHP_80,
|
||||
SetList::PHP_81,
|
||||
SetList::PHP_82,
|
||||
)
|
||||
);
|
||||
|
||||
$rectorConfig->rule(TernaryToElvisRector::class);
|
||||
};
|
||||
264
lib/composer/vendor/johngrogg/ics-parser/src/ICal/Event.php
vendored
Normal file
264
lib/composer/vendor/johngrogg/ics-parser/src/ICal/Event.php
vendored
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
<?php
|
||||
|
||||
namespace ICal;
|
||||
|
||||
class Event
|
||||
{
|
||||
// phpcs:disable Generic.Arrays.DisallowLongArraySyntax
|
||||
|
||||
const HTML_TEMPLATE = '<p>%s: %s</p>';
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/summary.html
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $summary;
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/dtstart.html
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $dtstart;
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/dtend.html
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $dtend;
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/duration.html
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $duration;
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/dtstamp.html
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $dtstamp;
|
||||
|
||||
/**
|
||||
* When the event starts, represented as a timezone-adjusted string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $dtstart_tz;
|
||||
|
||||
/**
|
||||
* When the event ends, represented as a timezone-adjusted string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $dtend_tz;
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/uid.html
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $uid;
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/created.html
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $created;
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/lastModified.html
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $last_modified;
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/description.html
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $description;
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/location.html
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $location;
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/sequence.html
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $sequence;
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/status.html
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $status;
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/transp.html
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $transp;
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/organizer.html
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $organizer;
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/attendee.html
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $attendee;
|
||||
|
||||
/**
|
||||
* Manage additional properties
|
||||
*
|
||||
* @var array<string, mixed>
|
||||
*/
|
||||
public $additionalProperties = array();
|
||||
|
||||
/**
|
||||
* Creates the Event object
|
||||
*
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(array $data = array())
|
||||
{
|
||||
foreach ($data as $key => $value) {
|
||||
$variable = self::snakeCase($key);
|
||||
if (property_exists($this, $variable)) {
|
||||
$this->{$variable} = $this->prepareData($value);
|
||||
} else {
|
||||
$this->additionalProperties[$variable] = $this->prepareData($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic getter method
|
||||
*
|
||||
* @param string $additionalPropertyName
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($additionalPropertyName)
|
||||
{
|
||||
if (array_key_exists($additionalPropertyName, $this->additionalProperties)) {
|
||||
return $this->additionalProperties[$additionalPropertyName];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic isset method
|
||||
*
|
||||
* @param string $name
|
||||
* @return boolean
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
return is_null($this->$name) === false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the data for output
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
protected function prepareData($value)
|
||||
{
|
||||
if (is_string($value)) {
|
||||
return stripslashes(trim(str_replace('\n', "\n", $value)));
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
return array_map(function ($value) {
|
||||
return $this->prepareData($value);
|
||||
}, $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Event data excluding anything blank
|
||||
* within an HTML template
|
||||
*
|
||||
* @param string $html HTML template to use
|
||||
* @return string
|
||||
*/
|
||||
public function printData($html = self::HTML_TEMPLATE)
|
||||
{
|
||||
$data = array(
|
||||
'SUMMARY' => $this->summary,
|
||||
'DTSTART' => $this->dtstart,
|
||||
'DTEND' => $this->dtend,
|
||||
'DTSTART_TZ' => $this->dtstart_tz,
|
||||
'DTEND_TZ' => $this->dtend_tz,
|
||||
'DURATION' => $this->duration,
|
||||
'DTSTAMP' => $this->dtstamp,
|
||||
'UID' => $this->uid,
|
||||
'CREATED' => $this->created,
|
||||
'LAST-MODIFIED' => $this->last_modified,
|
||||
'DESCRIPTION' => $this->description,
|
||||
'LOCATION' => $this->location,
|
||||
'SEQUENCE' => $this->sequence,
|
||||
'STATUS' => $this->status,
|
||||
'TRANSP' => $this->transp,
|
||||
'ORGANISER' => $this->organizer,
|
||||
'ATTENDEE(S)' => $this->attendee,
|
||||
);
|
||||
|
||||
// Remove any blank values
|
||||
$data = array_filter($data);
|
||||
|
||||
$output = '';
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
$output .= sprintf($html, $key, $value);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given input to snake_case
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $glue
|
||||
* @param string $separator
|
||||
* @return string
|
||||
*/
|
||||
protected static function snakeCase($input, $glue = '_', $separator = '-')
|
||||
{
|
||||
$inputSplit = preg_split('/(?<=[a-z])(?=[A-Z])/x', $input);
|
||||
|
||||
if ($inputSplit === false) {
|
||||
return $input;
|
||||
}
|
||||
|
||||
$inputSplit = implode($glue, $inputSplit);
|
||||
$inputSplit = str_replace($separator, $glue, $inputSplit);
|
||||
|
||||
return strtolower($inputSplit);
|
||||
}
|
||||
}
|
||||
2731
lib/composer/vendor/johngrogg/ics-parser/src/ICal/ICal.php
vendored
Normal file
2731
lib/composer/vendor/johngrogg/ics-parser/src/ICal/ICal.php
vendored
Normal file
File diff suppressed because it is too large
Load diff
53
lib/composer/vendor/johngrogg/ics-parser/tests/CleanCharacterTest.php
vendored
Normal file
53
lib/composer/vendor/johngrogg/ics-parser/tests/CleanCharacterTest.php
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
use ICal\ICal;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CleanCharacterTest extends TestCase
|
||||
{
|
||||
// phpcs:disable Generic.Arrays.DisallowLongArraySyntax
|
||||
// phpcs:disable Squiz.Commenting.FunctionComment
|
||||
|
||||
protected static function getMethod($name)
|
||||
{
|
||||
$class = new ReflectionClass(ICal::class);
|
||||
$method = $class->getMethod($name);
|
||||
|
||||
// < PHP 8.1.0
|
||||
$method->setAccessible(true);
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
public function testCleanCharactersWithUnicodeCharacters()
|
||||
{
|
||||
$ical = new ICal();
|
||||
|
||||
self::assertSame(
|
||||
'...',
|
||||
self::getMethod('cleanCharacters')->invokeArgs($ical, array("\xe2\x80\xa6"))
|
||||
);
|
||||
}
|
||||
|
||||
public function testCleanCharactersWithEmojis()
|
||||
{
|
||||
$ical = new ICal();
|
||||
$input = 'Test with emoji 🔴👍🏻';
|
||||
|
||||
self::assertSame(
|
||||
$input,
|
||||
self::getMethod('cleanCharacters')->invokeArgs($ical, array($input))
|
||||
);
|
||||
}
|
||||
|
||||
public function testCleanCharactersWithWindowsCharacters()
|
||||
{
|
||||
$ical = new ICal();
|
||||
$input = self::getMethod('mb_chr')->invokeArgs($ical, array(133));
|
||||
|
||||
self::assertSame(
|
||||
'...',
|
||||
self::getMethod('cleanCharacters')->invokeArgs($ical, array($input))
|
||||
);
|
||||
}
|
||||
}
|
||||
24
lib/composer/vendor/johngrogg/ics-parser/tests/DynamicPropertiesTest.php
vendored
Normal file
24
lib/composer/vendor/johngrogg/ics-parser/tests/DynamicPropertiesTest.php
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
use ICal\ICal;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DynamicPropertiesTest extends TestCase
|
||||
{
|
||||
// phpcs:disable Squiz.Commenting.FunctionComment
|
||||
|
||||
public function testDynamicArraysAreSet()
|
||||
{
|
||||
$ical = new ICal('./tests/ical/ical-monthly.ics');
|
||||
|
||||
foreach ($ical->events() as $event) {
|
||||
$this->assertTrue(isset($event->dtstart_array));
|
||||
$this->assertTrue(isset($event->dtend_array));
|
||||
$this->assertTrue(isset($event->dtstamp_array));
|
||||
$this->assertTrue(isset($event->uid_array));
|
||||
$this->assertTrue(isset($event->created_array));
|
||||
$this->assertTrue(isset($event->last_modified_array));
|
||||
$this->assertTrue(isset($event->summary_array));
|
||||
}
|
||||
}
|
||||
}
|
||||
86
lib/composer/vendor/johngrogg/ics-parser/tests/KeyValueTest.php
vendored
Normal file
86
lib/composer/vendor/johngrogg/ics-parser/tests/KeyValueTest.php
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
use ICal\ICal;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class KeyValueTest extends TestCase
|
||||
{
|
||||
// phpcs:disable Generic.Arrays.DisallowLongArraySyntax
|
||||
// phpcs:disable Squiz.Commenting.FunctionComment
|
||||
|
||||
public function testBoundaryCharactersInsideQuotes()
|
||||
{
|
||||
$checks = array(
|
||||
0 => 'ATTENDEE',
|
||||
1 => array(
|
||||
0 => 'mailto:julien@ag.com',
|
||||
1 => array(
|
||||
'PARTSTAT' => 'TENTATIVE',
|
||||
'CN' => 'ju: @ag.com = Ju ; ',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->assertLines(
|
||||
'ATTENDEE;PARTSTAT=TENTATIVE;CN="ju: @ag.com = Ju ; ":mailto:julien@ag.com',
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testUtf8Characters()
|
||||
{
|
||||
$checks = array(
|
||||
0 => 'ATTENDEE',
|
||||
1 => array(
|
||||
0 => 'mailto:juëǯ@ag.com',
|
||||
1 => array(
|
||||
'PARTSTAT' => 'TENTATIVE',
|
||||
'CN' => 'juëǯĻ',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->assertLines(
|
||||
'ATTENDEE;PARTSTAT=TENTATIVE;CN=juëǯĻ:mailto:juëǯ@ag.com',
|
||||
$checks
|
||||
);
|
||||
|
||||
$checks = array(
|
||||
0 => 'SUMMARY',
|
||||
1 => ' I love emojis 😀😁😁 ë, ǯ, Ļ',
|
||||
);
|
||||
|
||||
$this->assertLines(
|
||||
'SUMMARY: I love emojis 😀😁😁 ë, ǯ, Ļ',
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testParametersOfKeysWithMultipleValues()
|
||||
{
|
||||
$checks = array(
|
||||
0 => 'ATTENDEE',
|
||||
1 => array(
|
||||
0 => 'mailto:jsmith@example.com',
|
||||
1 => array(
|
||||
'DELEGATED-TO' => array(
|
||||
0 => 'mailto:jdoe@example.com',
|
||||
1 => 'mailto:jqpublic@example.com',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->assertLines(
|
||||
'ATTENDEE;DELEGATED-TO="mailto:jdoe@example.com","mailto:jqpublic@example.com":mailto:jsmith@example.com',
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
private function assertLines($lines, array $checks)
|
||||
{
|
||||
$ical = new ICal();
|
||||
|
||||
self::assertSame($ical->keyValueFromString($lines), $checks);
|
||||
}
|
||||
}
|
||||
580
lib/composer/vendor/johngrogg/ics-parser/tests/RecurrencesTest.php
vendored
Normal file
580
lib/composer/vendor/johngrogg/ics-parser/tests/RecurrencesTest.php
vendored
Normal file
|
|
@ -0,0 +1,580 @@
|
|||
<?php
|
||||
|
||||
use ICal\ICal;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class RecurrencesTest extends TestCase
|
||||
{
|
||||
// phpcs:disable Generic.Arrays.DisallowLongArraySyntax
|
||||
// phpcs:disable Squiz.Commenting.FunctionComment
|
||||
// phpcs:disable Squiz.Commenting.VariableComment
|
||||
|
||||
private $originalTimeZone = null;
|
||||
|
||||
/**
|
||||
* @before
|
||||
*/
|
||||
public function setUpFixtures()
|
||||
{
|
||||
$this->originalTimeZone = date_default_timezone_get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @after
|
||||
*/
|
||||
public function tearDownFixtures()
|
||||
{
|
||||
date_default_timezone_set($this->originalTimeZone);
|
||||
}
|
||||
|
||||
public function testYearlyFullDayTimeZoneBerlin()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20000301', 'message' => '1st event, CET: '),
|
||||
array('index' => 1, 'dateString' => '20010301T000000', 'message' => '2nd event, CET: '),
|
||||
array('index' => 2, 'dateString' => '20020301T000000', 'message' => '3rd event, CET: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
array(
|
||||
'DTSTART;VALUE=DATE:20000301',
|
||||
'DTEND;VALUE=DATE:20000302',
|
||||
'RRULE:FREQ=YEARLY;WKST=SU;COUNT=3',
|
||||
),
|
||||
3,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testMonthlyFullDayTimeZoneBerlin()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20000301', 'message' => '1st event, CET: '),
|
||||
array('index' => 1, 'dateString' => '20000401T000000', 'message' => '2nd event, CEST: '),
|
||||
array('index' => 2, 'dateString' => '20000501T000000', 'message' => '3rd event, CEST: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
array(
|
||||
'DTSTART;VALUE=DATE:20000301',
|
||||
'DTEND;VALUE=DATE:20000302',
|
||||
'RRULE:FREQ=MONTHLY;BYMONTHDAY=1;WKST=SU;COUNT=3',
|
||||
),
|
||||
3,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testMonthlyFullDayTimeZoneBerlinSummerTime()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20180701', 'message' => '1st event, CEST: '),
|
||||
array('index' => 1, 'dateString' => '20180801T000000', 'message' => '2nd event, CEST: '),
|
||||
array('index' => 2, 'dateString' => '20180901T000000', 'message' => '3rd event, CEST: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
array(
|
||||
'DTSTART;VALUE=DATE:20180701',
|
||||
'DTEND;VALUE=DATE:20180702',
|
||||
'RRULE:FREQ=MONTHLY;WKST=SU;COUNT=3',
|
||||
),
|
||||
3,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testMonthlyFullDayTimeZoneBerlinFromFile()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20180701', 'message' => '1st event, CEST: '),
|
||||
array('index' => 1, 'dateString' => '20180801T000000', 'message' => '2nd event, CEST: '),
|
||||
array('index' => 2, 'dateString' => '20180901T000000', 'message' => '3rd event, CEST: '),
|
||||
);
|
||||
$this->assertEventFile(
|
||||
'Europe/Berlin',
|
||||
'./tests/ical/ical-monthly.ics',
|
||||
25,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testIssue196FromFile()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20191105T190000', 'timezone' => 'Europe/Berlin', 'message' => '1st event, CEST: '),
|
||||
array('index' => 1, 'dateString' => '20191106T190000', 'timezone' => 'Europe/Berlin', 'message' => '2nd event, CEST: '),
|
||||
array('index' => 2, 'dateString' => '20191107T190000', 'timezone' => 'Europe/Berlin', 'message' => '3rd event, CEST: '),
|
||||
array('index' => 3, 'dateString' => '20191108T190000', 'timezone' => 'Europe/Berlin', 'message' => '4th event, CEST: '),
|
||||
array('index' => 4, 'dateString' => '20191109T170000', 'timezone' => 'Europe/Berlin', 'message' => '5th event, CEST: '),
|
||||
array('index' => 5, 'dateString' => '20191110T180000', 'timezone' => 'Europe/Berlin', 'message' => '6th event, CEST: '),
|
||||
);
|
||||
$this->assertEventFile(
|
||||
'UTC',
|
||||
'./tests/ical/issue-196.ics',
|
||||
7,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testWeeklyFullDayTimeZoneBerlin()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20000301', 'message' => '1st event, CET: '),
|
||||
array('index' => 1, 'dateString' => '20000308T000000', 'message' => '2nd event, CET: '),
|
||||
array('index' => 2, 'dateString' => '20000315T000000', 'message' => '3rd event, CET: '),
|
||||
array('index' => 3, 'dateString' => '20000322T000000', 'message' => '4th event, CET: '),
|
||||
array('index' => 4, 'dateString' => '20000329T000000', 'message' => '5th event, CEST: '),
|
||||
array('index' => 5, 'dateString' => '20000405T000000', 'message' => '6th event, CEST: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
array(
|
||||
'DTSTART;VALUE=DATE:20000301',
|
||||
'DTEND;VALUE=DATE:20000302',
|
||||
'RRULE:FREQ=WEEKLY;WKST=SU;COUNT=6',
|
||||
),
|
||||
6,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testDailyFullDayTimeZoneBerlin()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20000301', 'message' => '1st event, CET: '),
|
||||
array('index' => 1, 'dateString' => '20000302T000000', 'message' => '2nd event, CET: '),
|
||||
array('index' => 30, 'dateString' => '20000331T000000', 'message' => '31st event, CEST: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
array(
|
||||
'DTSTART;VALUE=DATE:20000301',
|
||||
'DTEND;VALUE=DATE:20000302',
|
||||
'RRULE:FREQ=DAILY;WKST=SU;COUNT=31',
|
||||
),
|
||||
31,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testWeeklyFullDayTimeZoneBerlinLocal()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20000301T000000', 'message' => '1st event, CET: '),
|
||||
array('index' => 1, 'dateString' => '20000308T000000', 'message' => '2nd event, CET: '),
|
||||
array('index' => 2, 'dateString' => '20000315T000000', 'message' => '3rd event, CET: '),
|
||||
array('index' => 3, 'dateString' => '20000322T000000', 'message' => '4th event, CET: '),
|
||||
array('index' => 4, 'dateString' => '20000329T000000', 'message' => '5th event, CEST: '),
|
||||
array('index' => 5, 'dateString' => '20000405T000000', 'message' => '6th event, CEST: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
array(
|
||||
'DTSTART;TZID=Europe/Berlin:20000301T000000',
|
||||
'DTEND;TZID=Europe/Berlin:20000302T000000',
|
||||
'RRULE:FREQ=WEEKLY;WKST=SU;COUNT=6',
|
||||
),
|
||||
6,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testRFCDaily10NewYork()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '19970902T090000', 'timezone' => 'America/New_York', 'message' => '1st event, EDT: '),
|
||||
array('index' => 1, 'dateString' => '19970903T090000', 'timezone' => 'America/New_York', 'message' => '2nd event, EDT: '),
|
||||
array('index' => 9, 'dateString' => '19970911T090000', 'timezone' => 'America/New_York', 'message' => '10th event, EDT: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
array(
|
||||
'DTSTART;TZID=America/New_York:19970902T090000',
|
||||
'RRULE:FREQ=DAILY;COUNT=10',
|
||||
),
|
||||
10,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testRFCDaily10Berlin()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '19970902T090000', 'timezone' => 'Europe/Berlin', 'message' => '1st event, CEST: '),
|
||||
array('index' => 1, 'dateString' => '19970903T090000', 'timezone' => 'Europe/Berlin', 'message' => '2nd event, CEST: '),
|
||||
array('index' => 9, 'dateString' => '19970911T090000', 'timezone' => 'Europe/Berlin', 'message' => '10th event, CEST: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
array(
|
||||
'DTSTART;TZID=Europe/Berlin:19970902T090000',
|
||||
'RRULE:FREQ=DAILY;COUNT=10',
|
||||
),
|
||||
10,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testStartDateIsExdateUsingUntil()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20190918T095000', 'timezone' => 'Europe/London', 'message' => '1st event: '),
|
||||
array('index' => 1, 'dateString' => '20191002T095000', 'timezone' => 'Europe/London', 'message' => '2nd event: '),
|
||||
array('index' => 2, 'dateString' => '20191016T095000', 'timezone' => 'Europe/London', 'message' => '3rd event: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/London',
|
||||
array(
|
||||
'DTSTART;TZID=Europe/London:20190911T095000',
|
||||
'RRULE:FREQ=WEEKLY;WKST=SU;UNTIL=20191027T235959Z;BYDAY=WE',
|
||||
'EXDATE;TZID=Europe/London:20191023T095000',
|
||||
'EXDATE;TZID=Europe/London:20191009T095000',
|
||||
'EXDATE;TZID=Europe/London:20190925T095000',
|
||||
'EXDATE;TZID=Europe/London:20190911T095000',
|
||||
),
|
||||
3,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testStartDateIsExdateUsingCount()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20190918T095000', 'timezone' => 'Europe/London', 'message' => '1st event: '),
|
||||
array('index' => 1, 'dateString' => '20191002T095000', 'timezone' => 'Europe/London', 'message' => '2nd event: '),
|
||||
array('index' => 2, 'dateString' => '20191016T095000', 'timezone' => 'Europe/London', 'message' => '3rd event: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/London',
|
||||
array(
|
||||
'DTSTART;TZID=Europe/London:20190911T095000',
|
||||
'RRULE:FREQ=WEEKLY;WKST=SU;COUNT=7;BYDAY=WE',
|
||||
'EXDATE;TZID=Europe/London:20191023T095000',
|
||||
'EXDATE;TZID=Europe/London:20191009T095000',
|
||||
'EXDATE;TZID=Europe/London:20190925T095000',
|
||||
'EXDATE;TZID=Europe/London:20190911T095000',
|
||||
),
|
||||
3,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testCountWithExdate()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20200323T050000', 'timezone' => 'Europe/Paris', 'message' => '1st event: '),
|
||||
array('index' => 1, 'dateString' => '20200324T050000', 'timezone' => 'Europe/Paris', 'message' => '2nd event: '),
|
||||
array('index' => 2, 'dateString' => '20200327T050000', 'timezone' => 'Europe/Paris', 'message' => '3rd event: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/London',
|
||||
array(
|
||||
'DTSTART;TZID=Europe/Paris:20200323T050000',
|
||||
'DTEND;TZID=Europe/Paris:20200323T070000',
|
||||
'RRULE:FREQ=DAILY;COUNT=5',
|
||||
'EXDATE;TZID=Europe/Paris:20200326T050000',
|
||||
'EXDATE;TZID=Europe/Paris:20200325T050000',
|
||||
'DTSTAMP:20200318T141057Z',
|
||||
),
|
||||
3,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testRFCDaily10BerlinFromNewYork()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '19970902T090000', 'timezone' => 'Europe/Berlin', 'message' => '1st event, CEST: '),
|
||||
array('index' => 1, 'dateString' => '19970903T090000', 'timezone' => 'Europe/Berlin', 'message' => '2nd event, CEST: '),
|
||||
array('index' => 9, 'dateString' => '19970911T090000', 'timezone' => 'Europe/Berlin', 'message' => '10th event, CEST: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'America/New_York',
|
||||
array(
|
||||
'DTSTART;TZID=Europe/Berlin:19970902T090000',
|
||||
'RRULE:FREQ=DAILY;COUNT=10',
|
||||
),
|
||||
10,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testExdatesInDifferentTimezone()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20170503T190000', 'message' => '1st event: '),
|
||||
array('index' => 1, 'dateString' => '20170510T190000', 'message' => '2nd event: '),
|
||||
array('index' => 9, 'dateString' => '20170712T190000', 'message' => '10th event: '),
|
||||
array('index' => 19, 'dateString' => '20171004T190000', 'message' => '20th event: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'America/Chicago',
|
||||
array(
|
||||
'DTSTART;TZID=America/Chicago:20170503T190000',
|
||||
'RRULE:FREQ=WEEKLY;BYDAY=WE;WKST=SU;UNTIL=20180101',
|
||||
'EXDATE:20170601T000000Z',
|
||||
'EXDATE:20170803T000000Z',
|
||||
'EXDATE:20170824T000000Z',
|
||||
'EXDATE:20171026T000000Z',
|
||||
'EXDATE:20171102T000000Z',
|
||||
'EXDATE:20171123T010000Z',
|
||||
'EXDATE:20171221T010000Z',
|
||||
),
|
||||
28,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testYearlyWithBySetPos()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '19970306T090000', 'message' => '1st occurrence: '),
|
||||
array('index' => 1, 'dateString' => '19970313T090000', 'message' => '2nd occurrence: '),
|
||||
array('index' => 2, 'dateString' => '19970325T090000', 'message' => '3rd occurrence: '),
|
||||
array('index' => 3, 'dateString' => '19980305T090000', 'message' => '4th occurrence: '),
|
||||
array('index' => 4, 'dateString' => '19980312T090000', 'message' => '5th occurrence: '),
|
||||
array('index' => 5, 'dateString' => '19980326T090000', 'message' => '6th occurrence: '),
|
||||
array('index' => 9, 'dateString' => '20000307T090000', 'message' => '10th occurrence: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'America/New_York',
|
||||
array(
|
||||
'DTSTART;TZID=America/New_York:19970306T090000',
|
||||
'RRULE:FREQ=YEARLY;COUNT=10;BYMONTH=3;BYDAY=TU,TH;BYSETPOS=2,4,-2',
|
||||
),
|
||||
10,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testDailyWithByMonthDay()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20000206T120000', 'message' => '1st event: '),
|
||||
array('index' => 1, 'dateString' => '20000211T120000', 'message' => '2nd event: '),
|
||||
array('index' => 2, 'dateString' => '20000216T120000', 'message' => '3rd event: '),
|
||||
array('index' => 4, 'dateString' => '20000226T120000', 'message' => '5th event, transition from February to March: '),
|
||||
array('index' => 5, 'dateString' => '20000301T120000', 'message' => '6th event, transition to March from February: '),
|
||||
array('index' => 11, 'dateString' => '20000331T120000', 'message' => '12th event, transition from March to April: '),
|
||||
array('index' => 12, 'dateString' => '20000401T120000', 'message' => '13th event, transition to April from March: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
array(
|
||||
'DTSTART:20000206T120000',
|
||||
'DTEND:20000206T130000',
|
||||
'RRULE:FREQ=DAILY;BYMONTHDAY=1,6,11,16,21,26,31;COUNT=16',
|
||||
),
|
||||
16,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testYearlyWithByMonthDay()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20001214T120000', 'message' => '1st event: '),
|
||||
array('index' => 1, 'dateString' => '20001221T120000', 'message' => '2nd event: '),
|
||||
array('index' => 2, 'dateString' => '20010107T120000', 'message' => '3rd event: '),
|
||||
array('index' => 3, 'dateString' => '20010114T120000', 'message' => '4th event: '),
|
||||
array('index' => 6, 'dateString' => '20010214T120000', 'message' => '7th event: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
array(
|
||||
'DTSTART:20001214T120000',
|
||||
'DTEND:20001214T130000',
|
||||
'RRULE:FREQ=YEARLY;BYMONTHDAY=7,14,21;COUNT=8',
|
||||
),
|
||||
8,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testYearlyWithByMonthDayAndByDay()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20001214T120000', 'message' => '1st event: '),
|
||||
array('index' => 1, 'dateString' => '20001221T120000', 'message' => '2nd event: '),
|
||||
array('index' => 2, 'dateString' => '20010607T120000', 'message' => '3rd event: '),
|
||||
array('index' => 3, 'dateString' => '20010614T120000', 'message' => '4th event: '),
|
||||
array('index' => 6, 'dateString' => '20020214T120000', 'message' => '7th event: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
array(
|
||||
'DTSTART:20001214T120000',
|
||||
'DTEND:20001214T130000',
|
||||
'RRULE:FREQ=YEARLY;BYMONTHDAY=7,14,21;BYDAY=TH;COUNT=8',
|
||||
),
|
||||
8,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testYearlyWithByMonthAndByMonthDay()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20001214T120000', 'message' => '1st event: '),
|
||||
array('index' => 1, 'dateString' => '20001221T120000', 'message' => '2nd event: '),
|
||||
array('index' => 2, 'dateString' => '20010607T120000', 'message' => '3rd event: '),
|
||||
array('index' => 3, 'dateString' => '20010614T120000', 'message' => '4th event: '),
|
||||
array('index' => 6, 'dateString' => '20011214T120000', 'message' => '7th event: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
array(
|
||||
'DTSTART:20001214T120000',
|
||||
'DTEND:20001214T130000',
|
||||
'RRULE:FREQ=YEARLY;BYMONTH=12,6;BYMONTHDAY=7,14,21;COUNT=8',
|
||||
),
|
||||
8,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testCountIsOne()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20211201T090000', 'message' => '1st and only expected event: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'UTC',
|
||||
array(
|
||||
'DTSTART:20211201T090000',
|
||||
'DTEND:20211201T100000',
|
||||
'RRULE:FREQ=DAILY;COUNT=1',
|
||||
),
|
||||
1,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function test5thByDayOfMonth()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20200103T090000', 'message' => '1st event: '),
|
||||
array('index' => 1, 'dateString' => '20200129T090000', 'message' => '2nd event: '),
|
||||
array('index' => 2, 'dateString' => '20200429T090000', 'message' => '3rd event: '),
|
||||
array('index' => 3, 'dateString' => '20200501T090000', 'message' => '4th event: '),
|
||||
array('index' => 4, 'dateString' => '20200703T090000', 'message' => '5th event: '),
|
||||
array('index' => 5, 'dateString' => '20200729T090000', 'message' => '6th event: '),
|
||||
array('index' => 6, 'dateString' => '20200930T090000', 'message' => '7th event: '),
|
||||
array('index' => 7, 'dateString' => '20201002T090000', 'message' => '8th event: '),
|
||||
array('index' => 8, 'dateString' => '20201230T090000', 'message' => '9th event: '),
|
||||
array('index' => 9, 'dateString' => '20210101T090000', 'message' => '10th and last event: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'UTC',
|
||||
array(
|
||||
'DTSTART:20200103T090000',
|
||||
'DTEND:20200103T100000',
|
||||
'RRULE:FREQ=MONTHLY;BYDAY=5WE,-5FR;UNTIL=20210102T090000',
|
||||
),
|
||||
10,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function assertVEVENT($defaultTimezone, $veventParts, $count, $checks)
|
||||
{
|
||||
$options = $this->getOptions($defaultTimezone);
|
||||
|
||||
$testIcal = implode(PHP_EOL, $this->getIcalHeader());
|
||||
$testIcal .= PHP_EOL;
|
||||
$testIcal .= implode(PHP_EOL, $this->formatIcalEvent($veventParts));
|
||||
$testIcal .= PHP_EOL;
|
||||
$testIcal .= implode(PHP_EOL, $this->getIcalFooter());
|
||||
|
||||
$ical = new ICal(false, $options);
|
||||
$ical->initString($testIcal);
|
||||
|
||||
$events = $ical->events();
|
||||
|
||||
$this->assertCount($count, $events);
|
||||
|
||||
foreach ($checks as $check) {
|
||||
$this->assertEvent($events[$check['index']], $check['dateString'], $check['message'], isset($check['timezone']) ? $check['timezone'] : $defaultTimezone);
|
||||
}
|
||||
}
|
||||
|
||||
public function assertEventFile($defaultTimezone, $file, $count, $checks)
|
||||
{
|
||||
$options = $this->getOptions($defaultTimezone);
|
||||
|
||||
$ical = new ICal($file, $options);
|
||||
|
||||
$events = $ical->events();
|
||||
|
||||
$this->assertCount($count, $events);
|
||||
|
||||
$events = $ical->sortEventsWithOrder($events);
|
||||
|
||||
foreach ($checks as $check) {
|
||||
$this->assertEvent($events[$check['index']], $check['dateString'], $check['message'], isset($check['timezone']) ? $check['timezone'] : $defaultTimezone);
|
||||
}
|
||||
}
|
||||
|
||||
public function assertEvent($event, $expectedDateString, $message, $timeZone = null)
|
||||
{
|
||||
if (!is_null($timeZone)) {
|
||||
date_default_timezone_set($timeZone);
|
||||
}
|
||||
|
||||
$expectedTimeStamp = strtotime($expectedDateString);
|
||||
|
||||
$this->assertSame($expectedTimeStamp, $event->dtstart_array[2], $message . 'timestamp mismatch (expected ' . $expectedDateString . ' vs actual ' . $event->dtstart . ')');
|
||||
$this->assertSame($expectedDateString, $event->dtstart, $message . 'dtstart mismatch (timestamp is okay)');
|
||||
}
|
||||
|
||||
public function getOptions($defaultTimezone)
|
||||
{
|
||||
$options = array(
|
||||
'defaultSpan' => 2, // Default value
|
||||
'defaultTimeZone' => $defaultTimezone, // Default value: UTC
|
||||
'defaultWeekStart' => 'MO', // Default value
|
||||
'disableCharacterReplacement' => false, // Default value
|
||||
'filterDaysAfter' => null, // Default value
|
||||
'filterDaysBefore' => null, // Default value
|
||||
'httpUserAgent' => null, // Default value
|
||||
'skipRecurrence' => false, // Default value
|
||||
);
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
public function formatIcalEvent($veventParts)
|
||||
{
|
||||
return array_merge(
|
||||
array(
|
||||
'BEGIN:VEVENT',
|
||||
'CREATED:' . gmdate('Ymd\THis\Z'),
|
||||
'UID:M2CD-1-1-5FB000FB-BBE4-4F3F-9E7E-217F1FF97209',
|
||||
),
|
||||
$veventParts,
|
||||
array(
|
||||
'SUMMARY:test',
|
||||
'LAST-MODIFIED:' . gmdate('Ymd\THis\Z', filemtime(__FILE__)),
|
||||
'END:VEVENT',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function getIcalHeader()
|
||||
{
|
||||
return array(
|
||||
'BEGIN:VCALENDAR',
|
||||
'VERSION:2.0',
|
||||
'PRODID:-//Google Inc//Google Calendar 70.9054//EN',
|
||||
'X-WR-CALNAME:Private',
|
||||
'X-APPLE-CALENDAR-COLOR:#FF2968',
|
||||
'X-WR-CALDESC:',
|
||||
);
|
||||
}
|
||||
|
||||
public function getIcalFooter()
|
||||
{
|
||||
return array('END:VCALENDAR');
|
||||
}
|
||||
}
|
||||
1059
lib/composer/vendor/johngrogg/ics-parser/tests/Rfc5545RecurrenceTest.php
vendored
Normal file
1059
lib/composer/vendor/johngrogg/ics-parser/tests/Rfc5545RecurrenceTest.php
vendored
Normal file
File diff suppressed because it is too large
Load diff
509
lib/composer/vendor/johngrogg/ics-parser/tests/SingleEventsTest.php
vendored
Normal file
509
lib/composer/vendor/johngrogg/ics-parser/tests/SingleEventsTest.php
vendored
Normal file
|
|
@ -0,0 +1,509 @@
|
|||
<?php
|
||||
|
||||
use ICal\ICal;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class SingleEventsTest extends TestCase
|
||||
{
|
||||
// phpcs:disable Generic.Arrays.DisallowLongArraySyntax
|
||||
// phpcs:disable Squiz.Commenting.FunctionComment
|
||||
// phpcs:disable Squiz.Commenting.VariableComment
|
||||
|
||||
private $originalTimeZone = null;
|
||||
|
||||
/**
|
||||
* @before
|
||||
*/
|
||||
public function setUpFixtures()
|
||||
{
|
||||
$this->originalTimeZone = date_default_timezone_get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @after
|
||||
*/
|
||||
public function tearDownFixtures()
|
||||
{
|
||||
date_default_timezone_set($this->originalTimeZone);
|
||||
}
|
||||
|
||||
public function testFullDayTimeZoneBerlin()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20000301', 'message' => '1st event, CET: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
'DTSTART;VALUE=DATE:20000301',
|
||||
'DTEND;VALUE=DATE:20000302',
|
||||
1,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testSeveralFullDaysTimeZoneBerlin()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20000301', 'message' => '1st event, CET: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
'DTSTART;VALUE=DATE:20000301',
|
||||
'DTEND;VALUE=DATE:20000304',
|
||||
1,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testEventTimeZoneUTC()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20180626T070000Z', 'message' => '1st event, UTC: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
'DTSTART:20180626T070000Z',
|
||||
'DTEND:20180626T110000Z',
|
||||
1,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function testEventTimeZoneBerlin()
|
||||
{
|
||||
$checks = array(
|
||||
array('index' => 0, 'dateString' => '20180626T070000', 'message' => '1st event, CEST: '),
|
||||
);
|
||||
$this->assertVEVENT(
|
||||
'Europe/Berlin',
|
||||
'DTSTART:20180626T070000',
|
||||
'DTEND:20180626T110000',
|
||||
1,
|
||||
$checks
|
||||
);
|
||||
}
|
||||
|
||||
public function assertVEVENT($defaultTimezone, $dtstart, $dtend, $count, $checks)
|
||||
{
|
||||
$options = $this->getOptions($defaultTimezone);
|
||||
|
||||
$testIcal = implode(PHP_EOL, $this->getIcalHeader());
|
||||
$testIcal .= PHP_EOL;
|
||||
$testIcal .= implode(PHP_EOL, $this->formatIcalEvent($dtstart, $dtend));
|
||||
$testIcal .= PHP_EOL;
|
||||
$testIcal .= implode(PHP_EOL, $this->getIcalTimezones());
|
||||
$testIcal .= PHP_EOL;
|
||||
$testIcal .= implode(PHP_EOL, $this->getIcalFooter());
|
||||
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
$ical = new ICal(false, $options);
|
||||
$ical->initString($testIcal);
|
||||
|
||||
$events = $ical->events();
|
||||
|
||||
$this->assertCount($count, $events);
|
||||
|
||||
foreach ($checks as $check) {
|
||||
$this->assertEvent(
|
||||
$events[$check['index']],
|
||||
$check['dateString'],
|
||||
$check['message'],
|
||||
isset($check['timezone']) ? $check['timezone'] : $defaultTimezone
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function getOptions($defaultTimezone)
|
||||
{
|
||||
$options = array(
|
||||
'defaultSpan' => 2, // Default value
|
||||
'defaultTimeZone' => $defaultTimezone, // Default value: UTC
|
||||
'defaultWeekStart' => 'MO', // Default value
|
||||
'disableCharacterReplacement' => false, // Default value
|
||||
'filterDaysAfter' => null, // Default value
|
||||
'filterDaysBefore' => null, // Default value
|
||||
'httpUserAgent' => null, // Default value
|
||||
'skipRecurrence' => false, // Default value
|
||||
);
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
public function getIcalHeader()
|
||||
{
|
||||
return array(
|
||||
'BEGIN:VCALENDAR',
|
||||
'VERSION:2.0',
|
||||
'PRODID:-//Google Inc//Google Calendar 70.9054//EN',
|
||||
'X-WR-CALNAME:Private',
|
||||
'X-APPLE-CALENDAR-COLOR:#FF2968',
|
||||
'X-WR-CALDESC:',
|
||||
);
|
||||
}
|
||||
|
||||
public function formatIcalEvent($dtstart, $dtend)
|
||||
{
|
||||
return array(
|
||||
'BEGIN:VEVENT',
|
||||
'CREATED:20090213T195947Z',
|
||||
'UID:M2CD-1-1-5FB000FB-BBE4-4F3F-9E7E-217F1FF97209',
|
||||
$dtstart,
|
||||
$dtend,
|
||||
'SUMMARY:test',
|
||||
'DESCRIPTION;LANGUAGE=en-gb:This is a short description\nwith a new line. Some "special" \'s',
|
||||
' igns\' may be interesting\, too.',
|
||||
' And a non-breaking space.',
|
||||
'LAST-MODIFIED:20110429T222101Z',
|
||||
'DTSTAMP:20170630T105724Z',
|
||||
'SEQUENCE:0',
|
||||
'END:VEVENT',
|
||||
);
|
||||
}
|
||||
|
||||
public function getIcalTimezones()
|
||||
{
|
||||
return array(
|
||||
'BEGIN:VTIMEZONE',
|
||||
'TZID:Europe/Berlin',
|
||||
'X-LIC-LOCATION:Europe/Berlin',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:18930401T000000',
|
||||
'RDATE:18930401T000000',
|
||||
'TZNAME:CEST',
|
||||
'TZOFFSETFROM:+005328',
|
||||
'TZOFFSETTO:+0100',
|
||||
'END:STANDARD',
|
||||
'BEGIN:DAYLIGHT',
|
||||
'DTSTART:19160430T230000',
|
||||
'RDATE:19160430T230000',
|
||||
'RDATE:19400401T020000',
|
||||
'RDATE:19430329T020000',
|
||||
'RDATE:19460414T020000',
|
||||
'RDATE:19470406T030000',
|
||||
'RDATE:19480418T020000',
|
||||
'RDATE:19490410T020000',
|
||||
'RDATE:19800406T020000',
|
||||
'TZNAME:CEST',
|
||||
'TZOFFSETFROM:+0100',
|
||||
'TZOFFSETTO:+0200',
|
||||
'END:DAYLIGHT',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19161001T010000',
|
||||
'RDATE:19161001T010000',
|
||||
'RDATE:19421102T030000',
|
||||
'RDATE:19431004T030000',
|
||||
'RDATE:19441002T030000',
|
||||
'RDATE:19451118T030000',
|
||||
'RDATE:19461007T030000',
|
||||
'TZNAME:CET',
|
||||
'TZOFFSETFROM:+0200',
|
||||
'TZOFFSETTO:+0100',
|
||||
'END:STANDARD',
|
||||
'BEGIN:DAYLIGHT',
|
||||
'DTSTART:19170416T020000',
|
||||
'RRULE:FREQ=YEARLY;UNTIL=19180415T010000Z;BYMONTH=4;BYDAY=3MO',
|
||||
'TZNAME:CEST',
|
||||
'TZOFFSETFROM:+0100',
|
||||
'TZOFFSETTO:+0200',
|
||||
'END:DAYLIGHT',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19170917T030000',
|
||||
'RRULE:FREQ=YEARLY;UNTIL=19180916T010000Z;BYMONTH=9;BYDAY=3MO',
|
||||
'TZNAME:CET',
|
||||
'TZOFFSETFROM:+0200',
|
||||
'TZOFFSETTO:+0100',
|
||||
'END:STANDARD',
|
||||
'BEGIN:DAYLIGHT',
|
||||
'DTSTART:19440403T020000',
|
||||
'RRULE:FREQ=YEARLY;UNTIL=19450402T010000Z;BYMONTH=4;BYDAY=1MO',
|
||||
'TZNAME:CEST',
|
||||
'TZOFFSETFROM:+0100',
|
||||
'TZOFFSETTO:+0200',
|
||||
'END:DAYLIGHT',
|
||||
'BEGIN:DAYLIGHT',
|
||||
'DTSTART:19450524T020000',
|
||||
'RDATE:19450524T020000',
|
||||
'RDATE:19470511T030000',
|
||||
'TZNAME:CEMT',
|
||||
'TZOFFSETFROM:+0200',
|
||||
'TZOFFSETTO:+0300',
|
||||
'END:DAYLIGHT',
|
||||
'BEGIN:DAYLIGHT',
|
||||
'DTSTART:19450924T030000',
|
||||
'RDATE:19450924T030000',
|
||||
'RDATE:19470629T030000',
|
||||
'TZNAME:CEST',
|
||||
'TZOFFSETFROM:+0300',
|
||||
'TZOFFSETTO:+0200',
|
||||
'END:DAYLIGHT',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19460101T000000',
|
||||
'RDATE:19460101T000000',
|
||||
'RDATE:19800101T000000',
|
||||
'TZNAME:CEST',
|
||||
'TZOFFSETFROM:+0100',
|
||||
'TZOFFSETTO:+0100',
|
||||
'END:STANDARD',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19471005T030000',
|
||||
'RRULE:FREQ=YEARLY;UNTIL=19491002T010000Z;BYMONTH=10;BYDAY=1SU',
|
||||
'TZNAME:CET',
|
||||
'TZOFFSETFROM:+0200',
|
||||
'TZOFFSETTO:+0100',
|
||||
'END:STANDARD',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19800928T030000',
|
||||
'RRULE:FREQ=YEARLY;UNTIL=19950924T010000Z;BYMONTH=9;BYDAY=-1SU',
|
||||
'TZNAME:CET',
|
||||
'TZOFFSETFROM:+0200',
|
||||
'TZOFFSETTO:+0100',
|
||||
'END:STANDARD',
|
||||
'BEGIN:DAYLIGHT',
|
||||
'DTSTART:19810329T020000',
|
||||
'RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU',
|
||||
'TZNAME:CEST',
|
||||
'TZOFFSETFROM:+0100',
|
||||
'TZOFFSETTO:+0200',
|
||||
'END:DAYLIGHT',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19961027T030000',
|
||||
'RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU',
|
||||
'TZNAME:CET',
|
||||
'TZOFFSETFROM:+0200',
|
||||
'TZOFFSETTO:+0100',
|
||||
'END:STANDARD',
|
||||
'END:VTIMEZONE',
|
||||
'BEGIN:VTIMEZONE',
|
||||
'TZID:Europe/Paris',
|
||||
'X-LIC-LOCATION:Europe/Paris',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:18910315T000100',
|
||||
'RDATE:18910315T000100',
|
||||
'TZNAME:PMT',
|
||||
'TZOFFSETFROM:+000921',
|
||||
'TZOFFSETTO:+000921',
|
||||
'END:STANDARD',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19110311T000100',
|
||||
'RDATE:19110311T000100',
|
||||
'TZNAME:WEST',
|
||||
'TZOFFSETFROM:+000921',
|
||||
'TZOFFSETTO:+0000',
|
||||
'END:STANDARD',
|
||||
'BEGIN:DAYLIGHT',
|
||||
'DTSTART:19160614T230000',
|
||||
'RDATE:19160614T230000',
|
||||
'RDATE:19170324T230000',
|
||||
'RDATE:19180309T230000',
|
||||
'RDATE:19190301T230000',
|
||||
'RDATE:19200214T230000',
|
||||
'RDATE:19210314T230000',
|
||||
'RDATE:19220325T230000',
|
||||
'RDATE:19230526T230000',
|
||||
'RDATE:19240329T230000',
|
||||
'RDATE:19250404T230000',
|
||||
'RDATE:19260417T230000',
|
||||
'RDATE:19270409T230000',
|
||||
'RDATE:19280414T230000',
|
||||
'RDATE:19290420T230000',
|
||||
'RDATE:19300412T230000',
|
||||
'RDATE:19310418T230000',
|
||||
'RDATE:19320402T230000',
|
||||
'RDATE:19330325T230000',
|
||||
'RDATE:19340407T230000',
|
||||
'RDATE:19350330T230000',
|
||||
'RDATE:19360418T230000',
|
||||
'RDATE:19370403T230000',
|
||||
'RDATE:19380326T230000',
|
||||
'RDATE:19390415T230000',
|
||||
'RDATE:19400225T020000',
|
||||
'TZNAME:WEST',
|
||||
'TZOFFSETFROM:+0000',
|
||||
'TZOFFSETTO:+0100',
|
||||
'END:DAYLIGHT',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19161002T000000',
|
||||
'RRULE:FREQ=YEARLY;UNTIL=19191005T230000Z;BYMONTH=10;BYMONTHDAY=2,3,4,5,6,',
|
||||
' 7,8;BYDAY=MO',
|
||||
'TZNAME:WET',
|
||||
'TZOFFSETFROM:+0100',
|
||||
'TZOFFSETTO:+0000',
|
||||
'END:STANDARD',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19201024T000000',
|
||||
'RDATE:19201024T000000',
|
||||
'RDATE:19211026T000000',
|
||||
'RDATE:19391119T000000',
|
||||
'TZNAME:WET',
|
||||
'TZOFFSETFROM:+0100',
|
||||
'TZOFFSETTO:+0000',
|
||||
'END:STANDARD',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19221008T000000',
|
||||
'RRULE:FREQ=YEARLY;UNTIL=19381001T230000Z;BYMONTH=10;BYMONTHDAY=2,3,4,5,6,',
|
||||
' 7,8;BYDAY=SU',
|
||||
'TZNAME:WET',
|
||||
'TZOFFSETFROM:+0100',
|
||||
'TZOFFSETTO:+0000',
|
||||
'END:STANDARD',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19400614T230000',
|
||||
'RDATE:19400614T230000',
|
||||
'TZNAME:CEST',
|
||||
'TZOFFSETFROM:+0100',
|
||||
'TZOFFSETTO:+0200',
|
||||
'END:STANDARD',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19421102T030000',
|
||||
'RDATE:19421102T030000',
|
||||
'RDATE:19431004T030000',
|
||||
'RDATE:19760926T010000',
|
||||
'RDATE:19770925T030000',
|
||||
'RDATE:19781001T030000',
|
||||
'TZNAME:CET',
|
||||
'TZOFFSETFROM:+0200',
|
||||
'TZOFFSETTO:+0100',
|
||||
'END:STANDARD',
|
||||
'BEGIN:DAYLIGHT',
|
||||
'DTSTART:19430329T020000',
|
||||
'RDATE:19430329T020000',
|
||||
'RDATE:19440403T020000',
|
||||
'RDATE:19760328T010000',
|
||||
'TZNAME:CEST',
|
||||
'TZOFFSETFROM:+0100',
|
||||
'TZOFFSETTO:+0200',
|
||||
'END:DAYLIGHT',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19440825T000000',
|
||||
'RDATE:19440825T000000',
|
||||
'TZNAME:WEST',
|
||||
'TZOFFSETFROM:+0200',
|
||||
'TZOFFSETTO:+0200',
|
||||
'END:STANDARD',
|
||||
'BEGIN:DAYLIGHT',
|
||||
'DTSTART:19441008T010000',
|
||||
'RDATE:19441008T010000',
|
||||
'TZNAME:WEST',
|
||||
'TZOFFSETFROM:+0200',
|
||||
'TZOFFSETTO:+0100',
|
||||
'END:DAYLIGHT',
|
||||
'BEGIN:DAYLIGHT',
|
||||
'DTSTART:19450402T020000',
|
||||
'RDATE:19450402T020000',
|
||||
'TZNAME:WEMT',
|
||||
'TZOFFSETFROM:+0100',
|
||||
'TZOFFSETTO:+0200',
|
||||
'END:DAYLIGHT',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19450916T030000',
|
||||
'RDATE:19450916T030000',
|
||||
'TZNAME:CEST',
|
||||
'TZOFFSETFROM:+0200',
|
||||
'TZOFFSETTO:+0100',
|
||||
'END:STANDARD',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19770101T000000',
|
||||
'RDATE:19770101T000000',
|
||||
'TZNAME:CEST',
|
||||
'TZOFFSETFROM:+0100',
|
||||
'TZOFFSETTO:+0100',
|
||||
'END:STANDARD',
|
||||
'BEGIN:DAYLIGHT',
|
||||
'DTSTART:19770403T020000',
|
||||
'RRULE:FREQ=YEARLY;UNTIL=19800406T010000Z;BYMONTH=4;BYDAY=1SU',
|
||||
'TZNAME:CEST',
|
||||
'TZOFFSETFROM:+0100',
|
||||
'TZOFFSETTO:+0200',
|
||||
'END:DAYLIGHT',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19790930T030000',
|
||||
'RRULE:FREQ=YEARLY;UNTIL=19950924T010000Z;BYMONTH=9;BYDAY=-1SU',
|
||||
'TZNAME:CET',
|
||||
'TZOFFSETFROM:+0200',
|
||||
'TZOFFSETTO:+0100',
|
||||
'END:STANDARD',
|
||||
'BEGIN:DAYLIGHT',
|
||||
'DTSTART:19810329T020000',
|
||||
'RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU',
|
||||
'TZNAME:CEST',
|
||||
'TZOFFSETFROM:+0100',
|
||||
'TZOFFSETTO:+0200',
|
||||
'END:DAYLIGHT',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19961027T030000',
|
||||
'RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU',
|
||||
'TZNAME:CET',
|
||||
'TZOFFSETFROM:+0200',
|
||||
'TZOFFSETTO:+0100',
|
||||
'END:STANDARD',
|
||||
'END:VTIMEZONE',
|
||||
'BEGIN:VTIMEZONE',
|
||||
'TZID:US-Eastern',
|
||||
'LAST-MODIFIED:19870101T000000Z',
|
||||
'TZURL:http://zones.stds_r_us.net/tz/US-Eastern',
|
||||
'BEGIN:STANDARD',
|
||||
'DTSTART:19671029T020000',
|
||||
'RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10',
|
||||
'TZOFFSETFROM:-0400',
|
||||
'TZOFFSETTO:-0500',
|
||||
'TZNAME:EST',
|
||||
'END:STANDARD',
|
||||
'BEGIN:DAYLIGHT',
|
||||
'DTSTART:19870405T020000',
|
||||
'RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4',
|
||||
'TZOFFSETFROM:-0500',
|
||||
'TZOFFSETTO:-0400',
|
||||
'TZNAME:EDT',
|
||||
'END:DAYLIGHT',
|
||||
'END:VTIMEZONE',
|
||||
);
|
||||
}
|
||||
|
||||
public function getIcalFooter()
|
||||
{
|
||||
return array('END:VCALENDAR');
|
||||
}
|
||||
|
||||
public function assertEvent($event, $expectedDateString, $message, $timezone = null)
|
||||
{
|
||||
if ($timezone !== null) {
|
||||
date_default_timezone_set($timezone);
|
||||
}
|
||||
|
||||
$expectedTimeStamp = strtotime($expectedDateString);
|
||||
|
||||
$this->assertSame(
|
||||
$expectedTimeStamp,
|
||||
$event->dtstart_array[2],
|
||||
$message . 'timestamp mismatch (expected ' . $expectedDateString . ' vs actual ' . $event->dtstart . ')'
|
||||
);
|
||||
$this->assertSame(
|
||||
$expectedDateString,
|
||||
$event->dtstart,
|
||||
$message . 'dtstart mismatch (timestamp is okay)'
|
||||
);
|
||||
}
|
||||
|
||||
public function assertEventFile($defaultTimezone, $file, $count, $checks)
|
||||
{
|
||||
$options = $this->getOptions($defaultTimezone);
|
||||
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
$ical = new ICal($file, $options);
|
||||
|
||||
$events = $ical->events();
|
||||
|
||||
$this->assertCount($count, $events);
|
||||
|
||||
foreach ($checks as $check) {
|
||||
$this->assertEvent(
|
||||
$events[$check['index']],
|
||||
$check['dateString'],
|
||||
$check['message'],
|
||||
isset($check['timezone']) ? $check['timezone'] : $defaultTimezone
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
18
lib/composer/vendor/johngrogg/ics-parser/tests/ical/ical-monthly.ics
vendored
Normal file
18
lib/composer/vendor/johngrogg/ics-parser/tests/ical/ical-monthly.ics
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
BEGIN:VCALENDAR
|
||||
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
|
||||
VERSION:2.0
|
||||
X-WR-CALNAME:Private
|
||||
X-APPLE-CALENDAR-COLOR:#FF2968
|
||||
X-WR-CALDESC:
|
||||
BEGIN:VEVENT
|
||||
CREATED:20090213T195947Z
|
||||
UID:M2CD-1-1-5FB000FB-BBE4-4F3F-9E7E-217F1FF97208
|
||||
RRULE:FREQ=MONTHLY;BYMONTHDAY=1;WKST=SU;COUNT=25
|
||||
DTSTART;VALUE=DATE:20180701
|
||||
DTEND;VALUE=DATE:20180702
|
||||
SUMMARY:Monthly
|
||||
LAST-MODIFIED:20110429T222101Z
|
||||
DTSTAMP:20170630T105724Z
|
||||
SEQUENCE:0
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
64
lib/composer/vendor/johngrogg/ics-parser/tests/ical/issue-196.ics
vendored
Normal file
64
lib/composer/vendor/johngrogg/ics-parser/tests/ical/issue-196.ics
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
BEGIN:VCALENDAR
|
||||
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
|
||||
VERSION:2.0
|
||||
X-WR-CALNAME:Test-Calendar
|
||||
X-WR-TIMEZONE:Europe/Berlin
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Europe/Berlin
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+0100
|
||||
TZOFFSETTO:+0200
|
||||
TZNAME:CEST
|
||||
DTSTART:19700329T020000
|
||||
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+0200
|
||||
TZOFFSETTO:+0100
|
||||
TZNAME:CET
|
||||
DTSTART:19701025T030000
|
||||
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
CREATED:20180101T152047Z
|
||||
LAST-MODIFIED:20181202T202056Z
|
||||
DTSTAMP:20181202T202056Z
|
||||
UID:529b1ea3-8de8-484d-b878-c20c7fb72bf5
|
||||
SUMMARY:test
|
||||
RRULE:FREQ=DAILY;UNTIL=20191111T180000Z
|
||||
DTSTART;TZID=Europe/Berlin:20191105T190000
|
||||
DTEND;TZID=Europe/Berlin:20191105T220000
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:24
|
||||
X-MOZ-GENERATION:37
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
CREATED:20181202T202042Z
|
||||
LAST-MODIFIED:20181202T202053Z
|
||||
DTSTAMP:20181202T202053Z
|
||||
UID:529b1ea3-8de8-484d-b878-c20c7fb72bf5
|
||||
SUMMARY:test
|
||||
RECURRENCE-ID;TZID=Europe/Berlin:20191109T190000
|
||||
DTSTART;TZID=Europe/Berlin:20191109T170000
|
||||
DTEND;TZID=Europe/Berlin:20191109T220000
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:25
|
||||
X-MOZ-GENERATION:37
|
||||
DURATION:PT0S
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
CREATED:20181202T202053Z
|
||||
LAST-MODIFIED:20181202T202056Z
|
||||
DTSTAMP:20181202T202056Z
|
||||
UID:529b1ea3-8de8-484d-b878-c20c7fb72bf5
|
||||
SUMMARY:test
|
||||
RECURRENCE-ID;TZID=Europe/Berlin:20191110T190000
|
||||
DTSTART;TZID=Europe/Berlin:20191110T180000
|
||||
DTEND;TZID=Europe/Berlin:20191110T220000
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:25
|
||||
X-MOZ-GENERATION:37
|
||||
DURATION:PT0S
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
19
lib/composer/vendor/psr/log/LICENSE
vendored
Normal file
19
lib/composer/vendor/psr/log/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2012 PHP Framework Interoperability Group
|
||||
|
||||
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.
|
||||
58
lib/composer/vendor/psr/log/README.md
vendored
Normal file
58
lib/composer/vendor/psr/log/README.md
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
PSR Log
|
||||
=======
|
||||
|
||||
This repository holds all interfaces/classes/traits related to
|
||||
[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md).
|
||||
|
||||
Note that this is not a logger of its own. It is merely an interface that
|
||||
describes a logger. See the specification for more details.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
```bash
|
||||
composer require psr/log
|
||||
```
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
If you need a logger, you can use the interface like this:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Foo
|
||||
{
|
||||
private $logger;
|
||||
|
||||
public function __construct(LoggerInterface $logger = null)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function doSomething()
|
||||
{
|
||||
if ($this->logger) {
|
||||
$this->logger->info('Doing work');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->doSomethingElse();
|
||||
} catch (Exception $exception) {
|
||||
$this->logger->error('Oh no!', array('exception' => $exception));
|
||||
}
|
||||
|
||||
// do something useful
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can then pick one of the implementations of the interface to get a logger.
|
||||
|
||||
If you want to implement the interface, you can require this package and
|
||||
implement `Psr\Log\LoggerInterface` in your code. Please read the
|
||||
[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
|
||||
for details.
|
||||
26
lib/composer/vendor/psr/log/composer.json
vendored
Normal file
26
lib/composer/vendor/psr/log/composer.json
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "psr/log",
|
||||
"description": "Common interface for logging libraries",
|
||||
"keywords": ["psr", "psr-3", "log"],
|
||||
"homepage": "https://github.com/php-fig/log",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.0.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Log\\": "src"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
15
lib/composer/vendor/psr/log/src/AbstractLogger.php
vendored
Normal file
15
lib/composer/vendor/psr/log/src/AbstractLogger.php
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace Psr\Log;
|
||||
|
||||
/**
|
||||
* This is a simple Logger implementation that other Loggers can inherit from.
|
||||
*
|
||||
* It simply delegates all log-level-specific methods to the `log` method to
|
||||
* reduce boilerplate code that a simple Logger that does the same thing with
|
||||
* messages regardless of the error level has to implement.
|
||||
*/
|
||||
abstract class AbstractLogger implements LoggerInterface
|
||||
{
|
||||
use LoggerTrait;
|
||||
}
|
||||
7
lib/composer/vendor/psr/log/src/InvalidArgumentException.php
vendored
Normal file
7
lib/composer/vendor/psr/log/src/InvalidArgumentException.php
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Psr\Log;
|
||||
|
||||
class InvalidArgumentException extends \InvalidArgumentException
|
||||
{
|
||||
}
|
||||
18
lib/composer/vendor/psr/log/src/LogLevel.php
vendored
Normal file
18
lib/composer/vendor/psr/log/src/LogLevel.php
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Psr\Log;
|
||||
|
||||
/**
|
||||
* Describes log levels.
|
||||
*/
|
||||
class LogLevel
|
||||
{
|
||||
const EMERGENCY = 'emergency';
|
||||
const ALERT = 'alert';
|
||||
const CRITICAL = 'critical';
|
||||
const ERROR = 'error';
|
||||
const WARNING = 'warning';
|
||||
const NOTICE = 'notice';
|
||||
const INFO = 'info';
|
||||
const DEBUG = 'debug';
|
||||
}
|
||||
14
lib/composer/vendor/psr/log/src/LoggerAwareInterface.php
vendored
Normal file
14
lib/composer/vendor/psr/log/src/LoggerAwareInterface.php
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Psr\Log;
|
||||
|
||||
/**
|
||||
* Describes a logger-aware instance.
|
||||
*/
|
||||
interface LoggerAwareInterface
|
||||
{
|
||||
/**
|
||||
* Sets a logger instance on the object.
|
||||
*/
|
||||
public function setLogger(LoggerInterface $logger): void;
|
||||
}
|
||||
22
lib/composer/vendor/psr/log/src/LoggerAwareTrait.php
vendored
Normal file
22
lib/composer/vendor/psr/log/src/LoggerAwareTrait.php
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Psr\Log;
|
||||
|
||||
/**
|
||||
* Basic Implementation of LoggerAwareInterface.
|
||||
*/
|
||||
trait LoggerAwareTrait
|
||||
{
|
||||
/**
|
||||
* The logger instance.
|
||||
*/
|
||||
protected ?LoggerInterface $logger = null;
|
||||
|
||||
/**
|
||||
* Sets a logger.
|
||||
*/
|
||||
public function setLogger(LoggerInterface $logger): void
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
}
|
||||
98
lib/composer/vendor/psr/log/src/LoggerInterface.php
vendored
Normal file
98
lib/composer/vendor/psr/log/src/LoggerInterface.php
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
namespace Psr\Log;
|
||||
|
||||
/**
|
||||
* Describes a logger instance.
|
||||
*
|
||||
* The message MUST be a string or object implementing __toString().
|
||||
*
|
||||
* The message MAY contain placeholders in the form: {foo} where foo
|
||||
* will be replaced by the context data in key "foo".
|
||||
*
|
||||
* The context array can contain arbitrary data. The only assumption that
|
||||
* can be made by implementors is that if an Exception instance is given
|
||||
* to produce a stack trace, it MUST be in a key named "exception".
|
||||
*
|
||||
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
|
||||
* for the full interface specification.
|
||||
*/
|
||||
interface LoggerInterface
|
||||
{
|
||||
/**
|
||||
* System is unusable.
|
||||
*
|
||||
* @param mixed[] $context
|
||||
*/
|
||||
public function emergency(string|\Stringable $message, array $context = []): void;
|
||||
|
||||
/**
|
||||
* Action must be taken immediately.
|
||||
*
|
||||
* Example: Entire website down, database unavailable, etc. This should
|
||||
* trigger the SMS alerts and wake you up.
|
||||
*
|
||||
* @param mixed[] $context
|
||||
*/
|
||||
public function alert(string|\Stringable $message, array $context = []): void;
|
||||
|
||||
/**
|
||||
* Critical conditions.
|
||||
*
|
||||
* Example: Application component unavailable, unexpected exception.
|
||||
*
|
||||
* @param mixed[] $context
|
||||
*/
|
||||
public function critical(string|\Stringable $message, array $context = []): void;
|
||||
|
||||
/**
|
||||
* Runtime errors that do not require immediate action but should typically
|
||||
* be logged and monitored.
|
||||
*
|
||||
* @param mixed[] $context
|
||||
*/
|
||||
public function error(string|\Stringable $message, array $context = []): void;
|
||||
|
||||
/**
|
||||
* Exceptional occurrences that are not errors.
|
||||
*
|
||||
* Example: Use of deprecated APIs, poor use of an API, undesirable things
|
||||
* that are not necessarily wrong.
|
||||
*
|
||||
* @param mixed[] $context
|
||||
*/
|
||||
public function warning(string|\Stringable $message, array $context = []): void;
|
||||
|
||||
/**
|
||||
* Normal but significant events.
|
||||
*
|
||||
* @param mixed[] $context
|
||||
*/
|
||||
public function notice(string|\Stringable $message, array $context = []): void;
|
||||
|
||||
/**
|
||||
* Interesting events.
|
||||
*
|
||||
* Example: User logs in, SQL logs.
|
||||
*
|
||||
* @param mixed[] $context
|
||||
*/
|
||||
public function info(string|\Stringable $message, array $context = []): void;
|
||||
|
||||
/**
|
||||
* Detailed debug information.
|
||||
*
|
||||
* @param mixed[] $context
|
||||
*/
|
||||
public function debug(string|\Stringable $message, array $context = []): void;
|
||||
|
||||
/**
|
||||
* Logs with an arbitrary level.
|
||||
*
|
||||
* @param mixed $level
|
||||
* @param mixed[] $context
|
||||
*
|
||||
* @throws \Psr\Log\InvalidArgumentException
|
||||
*/
|
||||
public function log($level, string|\Stringable $message, array $context = []): void;
|
||||
}
|
||||
98
lib/composer/vendor/psr/log/src/LoggerTrait.php
vendored
Normal file
98
lib/composer/vendor/psr/log/src/LoggerTrait.php
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
namespace Psr\Log;
|
||||
|
||||
/**
|
||||
* This is a simple Logger trait that classes unable to extend AbstractLogger
|
||||
* (because they extend another class, etc) can include.
|
||||
*
|
||||
* It simply delegates all log-level-specific methods to the `log` method to
|
||||
* reduce boilerplate code that a simple Logger that does the same thing with
|
||||
* messages regardless of the error level has to implement.
|
||||
*/
|
||||
trait LoggerTrait
|
||||
{
|
||||
/**
|
||||
* System is unusable.
|
||||
*/
|
||||
public function emergency(string|\Stringable $message, array $context = []): void
|
||||
{
|
||||
$this->log(LogLevel::EMERGENCY, $message, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Action must be taken immediately.
|
||||
*
|
||||
* Example: Entire website down, database unavailable, etc. This should
|
||||
* trigger the SMS alerts and wake you up.
|
||||
*/
|
||||
public function alert(string|\Stringable $message, array $context = []): void
|
||||
{
|
||||
$this->log(LogLevel::ALERT, $message, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Critical conditions.
|
||||
*
|
||||
* Example: Application component unavailable, unexpected exception.
|
||||
*/
|
||||
public function critical(string|\Stringable $message, array $context = []): void
|
||||
{
|
||||
$this->log(LogLevel::CRITICAL, $message, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime errors that do not require immediate action but should typically
|
||||
* be logged and monitored.
|
||||
*/
|
||||
public function error(string|\Stringable $message, array $context = []): void
|
||||
{
|
||||
$this->log(LogLevel::ERROR, $message, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exceptional occurrences that are not errors.
|
||||
*
|
||||
* Example: Use of deprecated APIs, poor use of an API, undesirable things
|
||||
* that are not necessarily wrong.
|
||||
*/
|
||||
public function warning(string|\Stringable $message, array $context = []): void
|
||||
{
|
||||
$this->log(LogLevel::WARNING, $message, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal but significant events.
|
||||
*/
|
||||
public function notice(string|\Stringable $message, array $context = []): void
|
||||
{
|
||||
$this->log(LogLevel::NOTICE, $message, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interesting events.
|
||||
*
|
||||
* Example: User logs in, SQL logs.
|
||||
*/
|
||||
public function info(string|\Stringable $message, array $context = []): void
|
||||
{
|
||||
$this->log(LogLevel::INFO, $message, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detailed debug information.
|
||||
*/
|
||||
public function debug(string|\Stringable $message, array $context = []): void
|
||||
{
|
||||
$this->log(LogLevel::DEBUG, $message, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs with an arbitrary level.
|
||||
*
|
||||
* @param mixed $level
|
||||
*
|
||||
* @throws \Psr\Log\InvalidArgumentException
|
||||
*/
|
||||
abstract public function log($level, string|\Stringable $message, array $context = []): void;
|
||||
}
|
||||
26
lib/composer/vendor/psr/log/src/NullLogger.php
vendored
Normal file
26
lib/composer/vendor/psr/log/src/NullLogger.php
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Psr\Log;
|
||||
|
||||
/**
|
||||
* This Logger can be used to avoid conditional log calls.
|
||||
*
|
||||
* Logging should always be optional, and if no logger is provided to your
|
||||
* library creating a NullLogger instance to have something to throw logs at
|
||||
* is a good way to avoid littering your code with `if ($this->logger) { }`
|
||||
* blocks.
|
||||
*/
|
||||
class NullLogger extends AbstractLogger
|
||||
{
|
||||
/**
|
||||
* Logs with an arbitrary level.
|
||||
*
|
||||
* @param mixed[] $context
|
||||
*
|
||||
* @throws \Psr\Log\InvalidArgumentException
|
||||
*/
|
||||
public function log($level, string|\Stringable $message, array $context = []): void
|
||||
{
|
||||
// noop
|
||||
}
|
||||
}
|
||||
27
lib/composer/vendor/sabre/dav/LICENSE
vendored
Normal file
27
lib/composer/vendor/sabre/dav/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
Copyright (C) 2007-2016 fruux GmbH (https://fruux.com/).
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of SabreDAV nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
39
lib/composer/vendor/sabre/dav/README.md
vendored
Normal file
39
lib/composer/vendor/sabre/dav/README.md
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
 sabre/dav
|
||||
=======================================================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
sabre/dav is the most popular WebDAV framework for PHP. Use it to create WebDAV, CalDAV and CardDAV servers.
|
||||
|
||||
Full documentation can be found on the website:
|
||||
|
||||
http://sabre.io/
|
||||
|
||||
|
||||
Build status
|
||||
------------
|
||||
|
||||
| branch | status | PHP version |
|
||||
|------------|---------------------------------------------------------------------------|--------------------|
|
||||
| master 4.* |  | PHP 7.1 up, 8.0 up |
|
||||
| 3.2 | unmaintained | PHP 5.5 to 7.1 |
|
||||
| 3.1 | unmaintained | PHP 5.5 |
|
||||
| 3.0 | unmaintained | PHP 5.4 |
|
||||
| 2.1 | unmaintained | PHP 5.4 |
|
||||
| 2.0 | unmaintained | PHP 5.4 |
|
||||
| 1.8 | unmaintained | PHP 5.3 |
|
||||
| 1.7 | unmaintained | PHP 5.3 |
|
||||
| 1.6 | unmaintained | PHP 5.3 |
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
* [Introduction](http://sabre.io/dav/).
|
||||
* [Installation](http://sabre.io/dav/install/).
|
||||
|
||||
|
||||
Made at fruux
|
||||
-------------
|
||||
|
||||
SabreDAV is being developed by [fruux](https://fruux.com/). Drop us a line for commercial services or enterprise support.
|
||||
169
lib/composer/vendor/sabre/dav/bin/build.php
vendored
Executable file
169
lib/composer/vendor/sabre/dav/bin/build.php
vendored
Executable file
|
|
@ -0,0 +1,169 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
$tasks = [
|
||||
'buildzip' => [
|
||||
'init', 'test', 'clean',
|
||||
],
|
||||
'markrelease' => [
|
||||
'init', 'test', 'clean',
|
||||
],
|
||||
'clean' => [],
|
||||
'test' => [
|
||||
'composerupdate',
|
||||
],
|
||||
'init' => [],
|
||||
'composerupdate' => [],
|
||||
];
|
||||
|
||||
$default = 'buildzip';
|
||||
|
||||
$baseDir = __DIR__.'/../';
|
||||
chdir($baseDir);
|
||||
|
||||
$currentTask = $default;
|
||||
if ($argc > 1) {
|
||||
$currentTask = $argv[1];
|
||||
}
|
||||
$version = null;
|
||||
if ($argc > 2) {
|
||||
$version = $argv[2];
|
||||
}
|
||||
|
||||
if (!isset($tasks[$currentTask])) {
|
||||
echo 'Task not found: ', $currentTask, "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Creating the dependency graph
|
||||
$newTaskList = [];
|
||||
$oldTaskList = [$currentTask => true];
|
||||
|
||||
while (count($oldTaskList) > 0) {
|
||||
foreach ($oldTaskList as $task => $foo) {
|
||||
if (!isset($tasks[$task])) {
|
||||
echo 'Dependency not found: '.$task, "\n";
|
||||
exit(1);
|
||||
}
|
||||
$dependencies = $tasks[$task];
|
||||
|
||||
$fullFilled = true;
|
||||
foreach ($dependencies as $dependency) {
|
||||
if (isset($newTaskList[$dependency])) {
|
||||
// Already in the fulfilled task list.
|
||||
continue;
|
||||
} else {
|
||||
$oldTaskList[$dependency] = true;
|
||||
$fullFilled = false;
|
||||
}
|
||||
}
|
||||
if ($fullFilled) {
|
||||
unset($oldTaskList[$task]);
|
||||
$newTaskList[$task] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (array_keys($newTaskList) as $task) {
|
||||
echo 'task: '.$task, "\n";
|
||||
call_user_func($task);
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
function init()
|
||||
{
|
||||
global $version;
|
||||
if (!$version) {
|
||||
include __DIR__.'/../vendor/autoload.php';
|
||||
$version = Sabre\DAV\Version::VERSION;
|
||||
}
|
||||
|
||||
echo ' Building sabre/dav '.$version, "\n";
|
||||
}
|
||||
|
||||
function clean()
|
||||
{
|
||||
global $baseDir;
|
||||
echo " Removing build files\n";
|
||||
$outputDir = $baseDir.'/build/SabreDAV';
|
||||
if (is_dir($outputDir)) {
|
||||
system('rm -r '.$baseDir.'/build/SabreDAV');
|
||||
}
|
||||
}
|
||||
|
||||
function composerupdate()
|
||||
{
|
||||
global $baseDir;
|
||||
echo " Updating composer packages to latest version\n\n";
|
||||
system('cd '.$baseDir.'; composer update');
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
global $baseDir;
|
||||
|
||||
echo " Running all unittests.\n";
|
||||
echo " This may take a while.\n\n";
|
||||
system(__DIR__.'/phpunit --configuration '.$baseDir.'/tests/phpunit.xml.dist --stop-on-failure', $code);
|
||||
if (0 != $code) {
|
||||
echo "PHPUnit reported error code $code\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
function buildzip()
|
||||
{
|
||||
global $baseDir, $version;
|
||||
echo " Generating composer.json\n";
|
||||
|
||||
$input = json_decode(file_get_contents(__DIR__.'/../composer.json'), true);
|
||||
$newComposer = [
|
||||
'require' => $input['require'],
|
||||
'config' => [
|
||||
'bin-dir' => './bin',
|
||||
],
|
||||
'prefer-stable' => true,
|
||||
'minimum-stability' => 'alpha',
|
||||
];
|
||||
unset(
|
||||
$newComposer['require']['sabre/vobject'],
|
||||
$newComposer['require']['sabre/http'],
|
||||
$newComposer['require']['sabre/uri'],
|
||||
$newComposer['require']['sabre/event']
|
||||
);
|
||||
$newComposer['require']['sabre/dav'] = $version;
|
||||
mkdir('build/SabreDAV');
|
||||
file_put_contents('build/SabreDAV/composer.json', json_encode($newComposer, JSON_PRETTY_PRINT));
|
||||
|
||||
echo " Downloading dependencies\n";
|
||||
system('cd build/SabreDAV; composer install -n', $code);
|
||||
if (0 !== $code) {
|
||||
echo "Composer reported error code $code\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo " Removing pointless files\n";
|
||||
unlink('build/SabreDAV/composer.json');
|
||||
unlink('build/SabreDAV/composer.lock');
|
||||
|
||||
echo " Moving important files to the root of the project\n";
|
||||
|
||||
$fileNames = [
|
||||
'CHANGELOG.md',
|
||||
'LICENSE',
|
||||
'README.md',
|
||||
'examples',
|
||||
];
|
||||
foreach ($fileNames as $fileName) {
|
||||
echo " $fileName\n";
|
||||
rename('build/SabreDAV/vendor/sabre/dav/'.$fileName, 'build/SabreDAV/'.$fileName);
|
||||
}
|
||||
|
||||
// <zip destfile="build/SabreDAV-${sabredav.version}.zip" basedir="build/SabreDAV" prefix="SabreDAV/" />
|
||||
|
||||
echo "\n";
|
||||
echo "Zipping the sabredav distribution\n\n";
|
||||
system('cd build; zip -qr sabredav-'.$version.'.zip SabreDAV');
|
||||
|
||||
echo 'Done.';
|
||||
}
|
||||
414
lib/composer/vendor/sabre/dav/bin/migrateto20.php
vendored
Executable file
414
lib/composer/vendor/sabre/dav/bin/migrateto20.php
vendored
Executable file
|
|
@ -0,0 +1,414 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
echo "SabreDAV migrate script for version 2.0\n";
|
||||
|
||||
if ($argc < 2) {
|
||||
echo <<<HELLO
|
||||
|
||||
This script help you migrate from a pre-2.0 database to 2.0 and later
|
||||
|
||||
The 'calendars', 'addressbooks' and 'cards' tables will be upgraded, and new
|
||||
tables (calendarchanges, addressbookchanges, propertystorage) will be added.
|
||||
|
||||
If you don't use the default PDO CalDAV or CardDAV backend, it's pointless to
|
||||
run this script.
|
||||
|
||||
Keep in mind that ALTER TABLE commands will be executed. If you have a large
|
||||
dataset this may mean that this process takes a while.
|
||||
|
||||
Lastly: Make a back-up first. This script has been tested, but the amount of
|
||||
potential variants are extremely high, so it's impossible to deal with every
|
||||
possible situation.
|
||||
|
||||
In the worst case, you will lose all your data. This is not an overstatement.
|
||||
|
||||
Usage:
|
||||
|
||||
php {$argv[0]} [pdo-dsn] [username] [password]
|
||||
|
||||
For example:
|
||||
|
||||
php {$argv[0]} "mysql:host=localhost;dbname=sabredav" root password
|
||||
php {$argv[0]} sqlite:data/sabredav.db
|
||||
|
||||
HELLO;
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
// There's a bunch of places where the autoloader could be, so we'll try all of
|
||||
// them.
|
||||
$paths = [
|
||||
__DIR__.'/../vendor/autoload.php',
|
||||
__DIR__.'/../../../autoload.php',
|
||||
];
|
||||
|
||||
foreach ($paths as $path) {
|
||||
if (file_exists($path)) {
|
||||
include $path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$dsn = $argv[1];
|
||||
$user = isset($argv[2]) ? $argv[2] : null;
|
||||
$pass = isset($argv[3]) ? $argv[3] : null;
|
||||
|
||||
echo 'Connecting to database: '.$dsn."\n";
|
||||
|
||||
$pdo = new PDO($dsn, $user, $pass);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
||||
|
||||
$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
echo "Detected MySQL.\n";
|
||||
break;
|
||||
case 'sqlite':
|
||||
echo "Detected SQLite.\n";
|
||||
break;
|
||||
default:
|
||||
echo 'Error: unsupported driver: '.$driver."\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
foreach (['calendar', 'addressbook'] as $itemType) {
|
||||
$tableName = $itemType.'s';
|
||||
$tableNameOld = $tableName.'_old';
|
||||
$changesTable = $itemType.'changes';
|
||||
|
||||
echo "Upgrading '$tableName'\n";
|
||||
|
||||
// The only cross-db way to do this, is to just fetch a single record.
|
||||
$row = $pdo->query("SELECT * FROM $tableName LIMIT 1")->fetch();
|
||||
|
||||
if (!$row) {
|
||||
echo "No records were found in the '$tableName' table.\n";
|
||||
echo "\n";
|
||||
echo "We're going to rename the old table to $tableNameOld (just in case).\n";
|
||||
echo "and re-create the new table.\n";
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$pdo->exec("RENAME TABLE $tableName TO $tableNameOld");
|
||||
switch ($itemType) {
|
||||
case 'calendar':
|
||||
$pdo->exec("
|
||||
CREATE TABLE calendars (
|
||||
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
principaluri VARCHAR(100),
|
||||
displayname VARCHAR(100),
|
||||
uri VARCHAR(200),
|
||||
synctoken INT(11) UNSIGNED NOT NULL DEFAULT '1',
|
||||
description TEXT,
|
||||
calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
calendarcolor VARCHAR(10),
|
||||
timezone TEXT,
|
||||
components VARCHAR(20),
|
||||
transparent TINYINT(1) NOT NULL DEFAULT '0',
|
||||
UNIQUE(principaluri, uri)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
");
|
||||
break;
|
||||
case 'addressbook':
|
||||
$pdo->exec("
|
||||
CREATE TABLE addressbooks (
|
||||
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
principaluri VARCHAR(255),
|
||||
displayname VARCHAR(255),
|
||||
uri VARCHAR(200),
|
||||
description TEXT,
|
||||
synctoken INT(11) UNSIGNED NOT NULL DEFAULT '1',
|
||||
UNIQUE(principaluri, uri)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'sqlite':
|
||||
$pdo->exec("ALTER TABLE $tableName RENAME TO $tableNameOld");
|
||||
|
||||
switch ($itemType) {
|
||||
case 'calendar':
|
||||
$pdo->exec('
|
||||
CREATE TABLE calendars (
|
||||
id integer primary key asc,
|
||||
principaluri text,
|
||||
displayname text,
|
||||
uri text,
|
||||
synctoken integer,
|
||||
description text,
|
||||
calendarorder integer,
|
||||
calendarcolor text,
|
||||
timezone text,
|
||||
components text,
|
||||
transparent bool
|
||||
);
|
||||
');
|
||||
break;
|
||||
case 'addressbook':
|
||||
$pdo->exec('
|
||||
CREATE TABLE addressbooks (
|
||||
id integer primary key asc,
|
||||
principaluri text,
|
||||
displayname text,
|
||||
uri text,
|
||||
description text,
|
||||
synctoken integer
|
||||
);
|
||||
');
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
echo "Creation of 2.0 $tableName table is complete\n";
|
||||
} else {
|
||||
// Checking if there's a synctoken field already.
|
||||
if (array_key_exists('synctoken', $row)) {
|
||||
echo "The 'synctoken' field already exists in the $tableName table.\n";
|
||||
echo "It's likely you already upgraded, so we're simply leaving\n";
|
||||
echo "the $tableName table alone\n";
|
||||
} else {
|
||||
echo "1.8 table schema detected\n";
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$pdo->exec("ALTER TABLE $tableName ADD synctoken INT(11) UNSIGNED NOT NULL DEFAULT '1'");
|
||||
$pdo->exec("ALTER TABLE $tableName DROP ctag");
|
||||
$pdo->exec("UPDATE $tableName SET synctoken = '1'");
|
||||
break;
|
||||
case 'sqlite':
|
||||
$pdo->exec("ALTER TABLE $tableName ADD synctoken integer");
|
||||
$pdo->exec("UPDATE $tableName SET synctoken = '1'");
|
||||
echo "Note: there's no easy way to remove fields in sqlite.\n";
|
||||
echo "The ctag field is no longer used, but it's kept in place\n";
|
||||
break;
|
||||
}
|
||||
|
||||
echo "Upgraded '$tableName' to 2.0 schema.\n";
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$pdo->query("SELECT * FROM $changesTable LIMIT 1");
|
||||
|
||||
echo "'$changesTable' already exists. Assuming that this part of the\n";
|
||||
echo "upgrade was already completed.\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Creating '$changesTable' table.\n";
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$pdo->exec("
|
||||
CREATE TABLE $changesTable (
|
||||
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
uri VARCHAR(200) NOT NULL,
|
||||
synctoken INT(11) UNSIGNED NOT NULL,
|
||||
{$itemType}id INT(11) UNSIGNED NOT NULL,
|
||||
operation TINYINT(1) NOT NULL,
|
||||
INDEX {$itemType}id_synctoken ({$itemType}id, synctoken)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
");
|
||||
break;
|
||||
case 'sqlite':
|
||||
$pdo->exec("
|
||||
|
||||
CREATE TABLE $changesTable (
|
||||
id integer primary key asc,
|
||||
uri text,
|
||||
synctoken integer,
|
||||
{$itemType}id integer,
|
||||
operation bool
|
||||
);
|
||||
|
||||
");
|
||||
$pdo->exec("CREATE INDEX {$itemType}id_synctoken ON $changesTable ({$itemType}id, synctoken);");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$pdo->query('SELECT * FROM calendarsubscriptions LIMIT 1');
|
||||
|
||||
echo "'calendarsubscriptions' already exists. Assuming that this part of the\n";
|
||||
echo "upgrade was already completed.\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Creating calendarsubscriptions table.\n";
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$pdo->exec("
|
||||
CREATE TABLE calendarsubscriptions (
|
||||
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
uri VARCHAR(200) NOT NULL,
|
||||
principaluri VARCHAR(100) NOT NULL,
|
||||
source TEXT,
|
||||
displayname VARCHAR(100),
|
||||
refreshrate VARCHAR(10),
|
||||
calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
calendarcolor VARCHAR(10),
|
||||
striptodos TINYINT(1) NULL,
|
||||
stripalarms TINYINT(1) NULL,
|
||||
stripattachments TINYINT(1) NULL,
|
||||
lastmodified INT(11) UNSIGNED,
|
||||
UNIQUE(principaluri, uri)
|
||||
);
|
||||
");
|
||||
break;
|
||||
case 'sqlite':
|
||||
$pdo->exec('
|
||||
|
||||
CREATE TABLE calendarsubscriptions (
|
||||
id integer primary key asc,
|
||||
uri text,
|
||||
principaluri text,
|
||||
source text,
|
||||
displayname text,
|
||||
refreshrate text,
|
||||
calendarorder integer,
|
||||
calendarcolor text,
|
||||
striptodos bool,
|
||||
stripalarms bool,
|
||||
stripattachments bool,
|
||||
lastmodified int
|
||||
);
|
||||
');
|
||||
|
||||
$pdo->exec('CREATE INDEX principaluri_uri ON calendarsubscriptions (principaluri, uri);');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$pdo->query('SELECT * FROM propertystorage LIMIT 1');
|
||||
|
||||
echo "'propertystorage' already exists. Assuming that this part of the\n";
|
||||
echo "upgrade was already completed.\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Creating propertystorage table.\n";
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$pdo->exec('
|
||||
CREATE TABLE propertystorage (
|
||||
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
path VARBINARY(1024) NOT NULL,
|
||||
name VARBINARY(100) NOT NULL,
|
||||
value MEDIUMBLOB
|
||||
);
|
||||
');
|
||||
$pdo->exec('
|
||||
CREATE UNIQUE INDEX path_property ON propertystorage (path(600), name(100));
|
||||
');
|
||||
break;
|
||||
case 'sqlite':
|
||||
$pdo->exec('
|
||||
CREATE TABLE propertystorage (
|
||||
id integer primary key asc,
|
||||
path TEXT,
|
||||
name TEXT,
|
||||
value TEXT
|
||||
);
|
||||
');
|
||||
$pdo->exec('
|
||||
CREATE UNIQUE INDEX path_property ON propertystorage (path, name);
|
||||
');
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
echo "Upgrading cards table to 2.0 schema\n";
|
||||
|
||||
try {
|
||||
$create = false;
|
||||
$row = $pdo->query('SELECT * FROM cards LIMIT 1')->fetch();
|
||||
if (!$row) {
|
||||
$random = mt_rand(1000, 9999);
|
||||
echo "There was no data in the cards table, so we're re-creating it\n";
|
||||
echo "The old table will be renamed to cards_old$random, just in case.\n";
|
||||
|
||||
$create = true;
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$pdo->exec("RENAME TABLE cards TO cards_old$random");
|
||||
break;
|
||||
case 'sqlite':
|
||||
$pdo->exec("ALTER TABLE cards RENAME TO cards_old$random");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo "Exception while checking cards table. Assuming that the table does not yet exist.\n";
|
||||
echo 'Debug: ', $e->getMessage(), "\n";
|
||||
$create = true;
|
||||
}
|
||||
|
||||
if ($create) {
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$pdo->exec('
|
||||
CREATE TABLE cards (
|
||||
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
addressbookid INT(11) UNSIGNED NOT NULL,
|
||||
carddata MEDIUMBLOB,
|
||||
uri VARCHAR(200),
|
||||
lastmodified INT(11) UNSIGNED,
|
||||
etag VARBINARY(32),
|
||||
size INT(11) UNSIGNED NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
');
|
||||
break;
|
||||
|
||||
case 'sqlite':
|
||||
$pdo->exec('
|
||||
CREATE TABLE cards (
|
||||
id integer primary key asc,
|
||||
addressbookid integer,
|
||||
carddata blob,
|
||||
uri text,
|
||||
lastmodified integer,
|
||||
etag text,
|
||||
size integer
|
||||
);
|
||||
');
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$pdo->exec('
|
||||
ALTER TABLE cards
|
||||
ADD etag VARBINARY(32),
|
||||
ADD size INT(11) UNSIGNED NOT NULL;
|
||||
');
|
||||
break;
|
||||
|
||||
case 'sqlite':
|
||||
$pdo->exec('
|
||||
ALTER TABLE cards ADD etag text;
|
||||
ALTER TABLE cards ADD size integer;
|
||||
');
|
||||
break;
|
||||
}
|
||||
echo "Reading all old vcards and populating etag and size fields.\n";
|
||||
$result = $pdo->query('SELECT id, carddata FROM cards');
|
||||
$stmt = $pdo->prepare('UPDATE cards SET etag = ?, size = ? WHERE id = ?');
|
||||
while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$stmt->execute([
|
||||
md5($row['carddata']),
|
||||
strlen($row['carddata']),
|
||||
$row['id'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
echo "Upgrade to 2.0 schema completed.\n";
|
||||
166
lib/composer/vendor/sabre/dav/bin/migrateto21.php
vendored
Executable file
166
lib/composer/vendor/sabre/dav/bin/migrateto21.php
vendored
Executable file
|
|
@ -0,0 +1,166 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
echo "SabreDAV migrate script for version 2.1\n";
|
||||
|
||||
if ($argc < 2) {
|
||||
echo <<<HELLO
|
||||
|
||||
This script help you migrate from a pre-2.1 database to 2.1.
|
||||
|
||||
Changes:
|
||||
The 'calendarobjects' table will be upgraded.
|
||||
'schedulingobjects' will be created.
|
||||
|
||||
If you don't use the default PDO CalDAV or CardDAV backend, it's pointless to
|
||||
run this script.
|
||||
|
||||
Keep in mind that ALTER TABLE commands will be executed. If you have a large
|
||||
dataset this may mean that this process takes a while.
|
||||
|
||||
Lastly: Make a back-up first. This script has been tested, but the amount of
|
||||
potential variants are extremely high, so it's impossible to deal with every
|
||||
possible situation.
|
||||
|
||||
In the worst case, you will lose all your data. This is not an overstatement.
|
||||
|
||||
Usage:
|
||||
|
||||
php {$argv[0]} [pdo-dsn] [username] [password]
|
||||
|
||||
For example:
|
||||
|
||||
php {$argv[0]} "mysql:host=localhost;dbname=sabredav" root password
|
||||
php {$argv[0]} sqlite:data/sabredav.db
|
||||
|
||||
HELLO;
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
// There's a bunch of places where the autoloader could be, so we'll try all of
|
||||
// them.
|
||||
$paths = [
|
||||
__DIR__.'/../vendor/autoload.php',
|
||||
__DIR__.'/../../../autoload.php',
|
||||
];
|
||||
|
||||
foreach ($paths as $path) {
|
||||
if (file_exists($path)) {
|
||||
include $path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$dsn = $argv[1];
|
||||
$user = isset($argv[2]) ? $argv[2] : null;
|
||||
$pass = isset($argv[3]) ? $argv[3] : null;
|
||||
|
||||
echo 'Connecting to database: '.$dsn."\n";
|
||||
|
||||
$pdo = new PDO($dsn, $user, $pass);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
||||
|
||||
$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
echo "Detected MySQL.\n";
|
||||
break;
|
||||
case 'sqlite':
|
||||
echo "Detected SQLite.\n";
|
||||
break;
|
||||
default:
|
||||
echo 'Error: unsupported driver: '.$driver."\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
echo "Upgrading 'calendarobjects'\n";
|
||||
$addUid = false;
|
||||
try {
|
||||
$result = $pdo->query('SELECT * FROM calendarobjects LIMIT 1');
|
||||
$row = $result->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$row) {
|
||||
echo "No data in table. Going to try to add the uid field anyway.\n";
|
||||
$addUid = true;
|
||||
} elseif (array_key_exists('uid', $row)) {
|
||||
echo "uid field exists. Assuming that this part of the migration has\n";
|
||||
echo "Already been completed.\n";
|
||||
} else {
|
||||
echo "2.0 schema detected.\n";
|
||||
$addUid = true;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo "Could not find a calendarobjects table. Skipping this part of the\n";
|
||||
echo "upgrade.\n";
|
||||
}
|
||||
|
||||
if ($addUid) {
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$pdo->exec('ALTER TABLE calendarobjects ADD uid VARCHAR(200)');
|
||||
break;
|
||||
case 'sqlite':
|
||||
$pdo->exec('ALTER TABLE calendarobjects ADD uid TEXT');
|
||||
break;
|
||||
}
|
||||
|
||||
$result = $pdo->query('SELECT id, calendardata FROM calendarobjects');
|
||||
$stmt = $pdo->prepare('UPDATE calendarobjects SET uid = ? WHERE id = ?');
|
||||
$counter = 0;
|
||||
|
||||
while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
|
||||
try {
|
||||
$vobj = \Sabre\VObject\Reader::read($row['calendardata']);
|
||||
} catch (\Exception $e) {
|
||||
echo "Warning! Item with id $row[id] could not be parsed!\n";
|
||||
continue;
|
||||
}
|
||||
$uid = null;
|
||||
$item = $vobj->getBaseComponent();
|
||||
if (!isset($item->UID)) {
|
||||
echo "Warning! Item with id $item[id] does NOT have a UID property and this is required.\n";
|
||||
continue;
|
||||
}
|
||||
$uid = (string) $item->UID;
|
||||
$stmt->execute([$uid, $row['id']]);
|
||||
++$counter;
|
||||
}
|
||||
}
|
||||
|
||||
echo "Creating 'schedulingobjects'\n";
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$pdo->exec('CREATE TABLE IF NOT EXISTS schedulingobjects
|
||||
(
|
||||
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
principaluri VARCHAR(255),
|
||||
calendardata MEDIUMBLOB,
|
||||
uri VARCHAR(200),
|
||||
lastmodified INT(11) UNSIGNED,
|
||||
etag VARCHAR(32),
|
||||
size INT(11) UNSIGNED NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
');
|
||||
break;
|
||||
|
||||
case 'sqlite':
|
||||
$pdo->exec('CREATE TABLE IF NOT EXISTS schedulingobjects (
|
||||
id integer primary key asc,
|
||||
principaluri text,
|
||||
calendardata blob,
|
||||
uri text,
|
||||
lastmodified integer,
|
||||
etag text,
|
||||
size integer
|
||||
)
|
||||
');
|
||||
break;
|
||||
}
|
||||
|
||||
echo "Done.\n";
|
||||
|
||||
echo "Upgrade to 2.1 schema completed.\n";
|
||||
161
lib/composer/vendor/sabre/dav/bin/migrateto30.php
vendored
Executable file
161
lib/composer/vendor/sabre/dav/bin/migrateto30.php
vendored
Executable file
|
|
@ -0,0 +1,161 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
echo "SabreDAV migrate script for version 3.0\n";
|
||||
|
||||
if ($argc < 2) {
|
||||
echo <<<HELLO
|
||||
|
||||
This script help you migrate from a pre-3.0 database to 3.0 and later
|
||||
|
||||
Changes:
|
||||
* The propertystorage table has changed to allow storage of complex
|
||||
properties.
|
||||
* the vcardurl field in the principals table is no more. This was moved to
|
||||
the propertystorage table.
|
||||
|
||||
Keep in mind that ALTER TABLE commands will be executed. If you have a large
|
||||
dataset this may mean that this process takes a while.
|
||||
|
||||
Lastly: Make a back-up first. This script has been tested, but the amount of
|
||||
potential variants are extremely high, so it's impossible to deal with every
|
||||
possible situation.
|
||||
|
||||
In the worst case, you will lose all your data. This is not an overstatement.
|
||||
|
||||
Usage:
|
||||
|
||||
php {$argv[0]} [pdo-dsn] [username] [password]
|
||||
|
||||
For example:
|
||||
|
||||
php {$argv[0]} "mysql:host=localhost;dbname=sabredav" root password
|
||||
php {$argv[0]} sqlite:data/sabredav.db
|
||||
|
||||
HELLO;
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
// There's a bunch of places where the autoloader could be, so we'll try all of
|
||||
// them.
|
||||
$paths = [
|
||||
__DIR__.'/../vendor/autoload.php',
|
||||
__DIR__.'/../../../autoload.php',
|
||||
];
|
||||
|
||||
foreach ($paths as $path) {
|
||||
if (file_exists($path)) {
|
||||
include $path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$dsn = $argv[1];
|
||||
$user = isset($argv[2]) ? $argv[2] : null;
|
||||
$pass = isset($argv[3]) ? $argv[3] : null;
|
||||
|
||||
echo 'Connecting to database: '.$dsn."\n";
|
||||
|
||||
$pdo = new PDO($dsn, $user, $pass);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
||||
|
||||
$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
echo "Detected MySQL.\n";
|
||||
break;
|
||||
case 'sqlite':
|
||||
echo "Detected SQLite.\n";
|
||||
break;
|
||||
default:
|
||||
echo 'Error: unsupported driver: '.$driver."\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
echo "Upgrading 'propertystorage'\n";
|
||||
$addValueType = false;
|
||||
try {
|
||||
$result = $pdo->query('SELECT * FROM propertystorage LIMIT 1');
|
||||
$row = $result->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$row) {
|
||||
echo "No data in table. Going to re-create the table.\n";
|
||||
$random = mt_rand(1000, 9999);
|
||||
echo "Renaming propertystorage -> propertystorage_old$random and creating new table.\n";
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$pdo->exec('RENAME TABLE propertystorage TO propertystorage_old'.$random);
|
||||
$pdo->exec('
|
||||
CREATE TABLE propertystorage (
|
||||
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
path VARBINARY(1024) NOT NULL,
|
||||
name VARBINARY(100) NOT NULL,
|
||||
valuetype INT UNSIGNED,
|
||||
value MEDIUMBLOB
|
||||
);
|
||||
');
|
||||
$pdo->exec('CREATE UNIQUE INDEX path_property_'.$random.' ON propertystorage (path(600), name(100));');
|
||||
break;
|
||||
case 'sqlite':
|
||||
$pdo->exec('ALTER TABLE propertystorage RENAME TO propertystorage_old'.$random);
|
||||
$pdo->exec('
|
||||
CREATE TABLE propertystorage (
|
||||
id integer primary key asc,
|
||||
path text,
|
||||
name text,
|
||||
valuetype integer,
|
||||
value blob
|
||||
);');
|
||||
|
||||
$pdo->exec('CREATE UNIQUE INDEX path_property_'.$random.' ON propertystorage (path, name);');
|
||||
break;
|
||||
}
|
||||
} elseif (array_key_exists('valuetype', $row)) {
|
||||
echo "valuetype field exists. Assuming that this part of the migration has\n";
|
||||
echo "Already been completed.\n";
|
||||
} else {
|
||||
echo "2.1 schema detected. Going to perform upgrade.\n";
|
||||
$addValueType = true;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo "Could not find a propertystorage table. Skipping this part of the\n";
|
||||
echo "upgrade.\n";
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
if ($addValueType) {
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$pdo->exec('ALTER TABLE propertystorage ADD valuetype INT UNSIGNED');
|
||||
break;
|
||||
case 'sqlite':
|
||||
$pdo->exec('ALTER TABLE propertystorage ADD valuetype INT');
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$pdo->exec('UPDATE propertystorage SET valuetype = 1 WHERE valuetype IS NULL ');
|
||||
}
|
||||
|
||||
echo "Migrating vcardurl\n";
|
||||
|
||||
$result = $pdo->query('SELECT id, uri, vcardurl FROM principals WHERE vcardurl IS NOT NULL');
|
||||
$stmt1 = $pdo->prepare('INSERT INTO propertystorage (path, name, valuetype, value) VALUES (?, ?, 3, ?)');
|
||||
|
||||
while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
|
||||
// Inserting the new record
|
||||
$stmt1->execute([
|
||||
'addressbooks/'.basename($row['uri']),
|
||||
'{http://calendarserver.org/ns/}me-card',
|
||||
serialize(new Sabre\DAV\Xml\Property\Href($row['vcardurl'])),
|
||||
]);
|
||||
|
||||
echo serialize(new Sabre\DAV\Xml\Property\Href($row['vcardurl']));
|
||||
}
|
||||
|
||||
echo "Done.\n";
|
||||
echo "Upgrade to 3.0 schema completed.\n";
|
||||
258
lib/composer/vendor/sabre/dav/bin/migrateto32.php
vendored
Executable file
258
lib/composer/vendor/sabre/dav/bin/migrateto32.php
vendored
Executable file
|
|
@ -0,0 +1,258 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
echo "SabreDAV migrate script for version 3.2\n";
|
||||
|
||||
if ($argc < 2) {
|
||||
echo <<<HELLO
|
||||
|
||||
This script help you migrate from a 3.1 database to 3.2 and later
|
||||
|
||||
Changes:
|
||||
* Created a new calendarinstances table to support calendar sharing.
|
||||
* Remove a lot of columns from calendars.
|
||||
|
||||
Keep in mind that ALTER TABLE commands will be executed. If you have a large
|
||||
dataset this may mean that this process takes a while.
|
||||
|
||||
Make a back-up first. This script has been tested, but the amount of
|
||||
potential variants are extremely high, so it's impossible to deal with every
|
||||
possible situation.
|
||||
|
||||
In the worst case, you will lose all your data. This is not an overstatement.
|
||||
|
||||
Lastly, if you are upgrading from an older version than 3.1, make sure you run
|
||||
the earlier migration script first. Migration scripts must be ran in order.
|
||||
|
||||
Usage:
|
||||
|
||||
php {$argv[0]} [pdo-dsn] [username] [password]
|
||||
|
||||
For example:
|
||||
|
||||
php {$argv[0]} "mysql:host=localhost;dbname=sabredav" root password
|
||||
php {$argv[0]} sqlite:data/sabredav.db
|
||||
|
||||
HELLO;
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
// There's a bunch of places where the autoloader could be, so we'll try all of
|
||||
// them.
|
||||
$paths = [
|
||||
__DIR__.'/../vendor/autoload.php',
|
||||
__DIR__.'/../../../autoload.php',
|
||||
];
|
||||
|
||||
foreach ($paths as $path) {
|
||||
if (file_exists($path)) {
|
||||
include $path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$dsn = $argv[1];
|
||||
$user = isset($argv[2]) ? $argv[2] : null;
|
||||
$pass = isset($argv[3]) ? $argv[3] : null;
|
||||
|
||||
$backupPostfix = time();
|
||||
|
||||
echo 'Connecting to database: '.$dsn."\n";
|
||||
|
||||
$pdo = new PDO($dsn, $user, $pass);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
||||
|
||||
$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
echo "Detected MySQL.\n";
|
||||
break;
|
||||
case 'sqlite':
|
||||
echo "Detected SQLite.\n";
|
||||
break;
|
||||
default:
|
||||
echo 'Error: unsupported driver: '.$driver."\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
echo "Creating 'calendarinstances'\n";
|
||||
$addValueType = false;
|
||||
try {
|
||||
$result = $pdo->query('SELECT * FROM calendarinstances LIMIT 1');
|
||||
$result->fetch(\PDO::FETCH_ASSOC);
|
||||
echo "calendarinstances exists. Assuming this part of the migration has already been done.\n";
|
||||
} catch (Exception $e) {
|
||||
echo "calendarinstances does not yet exist. Creating table and migrating data.\n";
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$pdo->exec(<<<SQL
|
||||
CREATE TABLE calendarinstances (
|
||||
id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
calendarid INTEGER UNSIGNED NOT NULL,
|
||||
principaluri VARBINARY(100),
|
||||
access TINYINT(1) NOT NULL DEFAULT '1' COMMENT '1 = owner, 2 = read, 3 = readwrite',
|
||||
displayname VARCHAR(100),
|
||||
uri VARBINARY(200),
|
||||
description TEXT,
|
||||
calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
calendarcolor VARBINARY(10),
|
||||
timezone TEXT,
|
||||
transparent TINYINT(1) NOT NULL DEFAULT '0',
|
||||
share_href VARBINARY(100),
|
||||
share_displayname VARCHAR(100),
|
||||
share_invitestatus TINYINT(1) NOT NULL DEFAULT '2' COMMENT '1 = noresponse, 2 = accepted, 3 = declined, 4 = invalid',
|
||||
UNIQUE(principaluri, uri),
|
||||
UNIQUE(calendarid, principaluri),
|
||||
UNIQUE(calendarid, share_href)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
SQL
|
||||
);
|
||||
$pdo->exec('
|
||||
INSERT INTO calendarinstances
|
||||
(
|
||||
calendarid,
|
||||
principaluri,
|
||||
access,
|
||||
displayname,
|
||||
uri,
|
||||
description,
|
||||
calendarorder,
|
||||
calendarcolor,
|
||||
transparent
|
||||
)
|
||||
SELECT
|
||||
id,
|
||||
principaluri,
|
||||
1,
|
||||
displayname,
|
||||
uri,
|
||||
description,
|
||||
calendarorder,
|
||||
calendarcolor,
|
||||
transparent
|
||||
FROM calendars
|
||||
');
|
||||
break;
|
||||
case 'sqlite':
|
||||
$pdo->exec(<<<SQL
|
||||
CREATE TABLE calendarinstances (
|
||||
id integer primary key asc NOT NULL,
|
||||
calendarid integer,
|
||||
principaluri text,
|
||||
access integer COMMENT '1 = owner, 2 = read, 3 = readwrite' NOT NULL DEFAULT '1',
|
||||
displayname text,
|
||||
uri text NOT NULL,
|
||||
description text,
|
||||
calendarorder integer,
|
||||
calendarcolor text,
|
||||
timezone text,
|
||||
transparent bool,
|
||||
share_href text,
|
||||
share_displayname text,
|
||||
share_invitestatus integer DEFAULT '2',
|
||||
UNIQUE (principaluri, uri),
|
||||
UNIQUE (calendarid, principaluri),
|
||||
UNIQUE (calendarid, share_href)
|
||||
);
|
||||
SQL
|
||||
);
|
||||
$pdo->exec('
|
||||
INSERT INTO calendarinstances
|
||||
(
|
||||
calendarid,
|
||||
principaluri,
|
||||
access,
|
||||
displayname,
|
||||
uri,
|
||||
description,
|
||||
calendarorder,
|
||||
calendarcolor,
|
||||
transparent
|
||||
)
|
||||
SELECT
|
||||
id,
|
||||
principaluri,
|
||||
1,
|
||||
displayname,
|
||||
uri,
|
||||
description,
|
||||
calendarorder,
|
||||
calendarcolor,
|
||||
transparent
|
||||
FROM calendars
|
||||
');
|
||||
break;
|
||||
}
|
||||
}
|
||||
try {
|
||||
$result = $pdo->query('SELECT * FROM calendars LIMIT 1');
|
||||
$row = $result->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$row) {
|
||||
echo "Source table is empty.\n";
|
||||
$migrateCalendars = true;
|
||||
}
|
||||
|
||||
$columnCount = count($row);
|
||||
if (3 === $columnCount) {
|
||||
echo "The calendars table has 3 columns already. Assuming this part of the migration was already done.\n";
|
||||
$migrateCalendars = false;
|
||||
} else {
|
||||
echo 'The calendars table has '.$columnCount." columns.\n";
|
||||
$migrateCalendars = true;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo "calendars table does not exist. This is a major problem. Exiting.\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ($migrateCalendars) {
|
||||
$calendarBackup = 'calendars_3_1_'.$backupPostfix;
|
||||
echo "Backing up 'calendars' to '", $calendarBackup, "'\n";
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$pdo->exec('RENAME TABLE calendars TO '.$calendarBackup);
|
||||
break;
|
||||
case 'sqlite':
|
||||
$pdo->exec('ALTER TABLE calendars RENAME TO '.$calendarBackup);
|
||||
break;
|
||||
}
|
||||
|
||||
echo "Creating new calendars table.\n";
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
$pdo->exec(<<<SQL
|
||||
CREATE TABLE calendars (
|
||||
id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
synctoken INTEGER UNSIGNED NOT NULL DEFAULT '1',
|
||||
components VARBINARY(21)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
SQL
|
||||
);
|
||||
break;
|
||||
case 'sqlite':
|
||||
$pdo->exec(<<<SQL
|
||||
CREATE TABLE calendars (
|
||||
id integer primary key asc NOT NULL,
|
||||
synctoken integer DEFAULT 1 NOT NULL,
|
||||
components text NOT NULL
|
||||
);
|
||||
SQL
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
echo "Migrating data from old to new table\n";
|
||||
|
||||
$pdo->exec(<<<SQL
|
||||
INSERT INTO calendars (id, synctoken, components) SELECT id, synctoken, COALESCE(components,"VEVENT,VTODO,VJOURNAL") as components FROM $calendarBackup
|
||||
SQL
|
||||
);
|
||||
}
|
||||
|
||||
echo "Upgrade to 3.2 schema completed.\n";
|
||||
140
lib/composer/vendor/sabre/dav/bin/naturalselection
vendored
Executable file
140
lib/composer/vendor/sabre/dav/bin/naturalselection
vendored
Executable file
|
|
@ -0,0 +1,140 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
#
|
||||
# Copyright (c) 2009-2010 Evert Pot
|
||||
# All rights reserved.
|
||||
# http://www.rooftopsolutions.nl/
|
||||
#
|
||||
# This utility is distributed along with SabreDAV
|
||||
# license: http://sabre.io/license/ Modified BSD License
|
||||
|
||||
import os
|
||||
from optparse import OptionParser
|
||||
import time
|
||||
|
||||
def getfreespace(path):
|
||||
stat = os.statvfs(path)
|
||||
return stat.f_frsize * stat.f_bavail
|
||||
|
||||
def getbytesleft(path,threshold):
|
||||
return getfreespace(path)-threshold
|
||||
|
||||
def run(cacheDir, threshold, sleep=5, simulate=False, min_erase = 0):
|
||||
|
||||
bytes = getbytesleft(cacheDir,threshold)
|
||||
if (bytes>0):
|
||||
print "Bytes to go before we hit threshold:", bytes
|
||||
else:
|
||||
print "Threshold exceeded with:", -bytes, "bytes"
|
||||
dir = os.listdir(cacheDir)
|
||||
dir2 = []
|
||||
for file in dir:
|
||||
path = cacheDir + '/' + file
|
||||
dir2.append({
|
||||
"path" : path,
|
||||
"atime": os.stat(path).st_atime,
|
||||
"size" : os.stat(path).st_size
|
||||
})
|
||||
|
||||
dir2.sort(lambda x,y: int(x["atime"]-y["atime"]))
|
||||
|
||||
filesunlinked = 0
|
||||
gainedspace = 0
|
||||
|
||||
# Left is the amount of bytes that need to be freed up
|
||||
# The default is the 'min_erase setting'
|
||||
left = min_erase
|
||||
|
||||
# If the min_erase setting is lower than the amount of bytes over
|
||||
# the threshold, we use that number instead.
|
||||
if left < -bytes :
|
||||
left = -bytes
|
||||
|
||||
print "Need to delete at least:", left;
|
||||
|
||||
for file in dir2:
|
||||
|
||||
# Only deleting files if we're not simulating
|
||||
if not simulate: os.unlink(file["path"])
|
||||
left = int(left - file["size"])
|
||||
gainedspace = gainedspace + file["size"]
|
||||
filesunlinked = filesunlinked + 1
|
||||
|
||||
if(left<0):
|
||||
break
|
||||
|
||||
print "%d files deleted (%d bytes)" % (filesunlinked, gainedspace)
|
||||
|
||||
|
||||
time.sleep(sleep)
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
parser = OptionParser(
|
||||
version="naturalselection v0.3",
|
||||
description="Cache directory manager. Deletes cache entries based on accesstime and free space thresholds.\n" +
|
||||
"This utility is distributed alongside SabreDAV.",
|
||||
usage="usage: %prog [options] cacheDirectory",
|
||||
)
|
||||
parser.add_option(
|
||||
'-s',
|
||||
dest="simulate",
|
||||
action="store_true",
|
||||
help="Don't actually make changes, but just simulate the behaviour",
|
||||
)
|
||||
parser.add_option(
|
||||
'-r','--runs',
|
||||
help="How many times to check before exiting. -1 is infinite, which is the default",
|
||||
type="int",
|
||||
dest="runs",
|
||||
default=-1
|
||||
)
|
||||
parser.add_option(
|
||||
'-n','--interval',
|
||||
help="Sleep time in seconds (default = 5)",
|
||||
type="int",
|
||||
dest="sleep",
|
||||
default=5
|
||||
)
|
||||
parser.add_option(
|
||||
'-l','--threshold',
|
||||
help="Threshold in bytes (default = 10737418240, which is 10GB)",
|
||||
type="int",
|
||||
dest="threshold",
|
||||
default=10737418240
|
||||
)
|
||||
parser.add_option(
|
||||
'-m', '--min-erase',
|
||||
help="Minimum number of bytes to erase when the threshold is reached. " +
|
||||
"Setting this option higher will reduce the number of times the cache directory will need to be scanned. " +
|
||||
"(the default is 1073741824, which is 1GB.)",
|
||||
type="int",
|
||||
dest="min_erase",
|
||||
default=1073741824
|
||||
)
|
||||
|
||||
options,args = parser.parse_args()
|
||||
if len(args)<1:
|
||||
parser.error("This utility requires at least 1 argument")
|
||||
cacheDir = args[0]
|
||||
|
||||
print "Natural Selection"
|
||||
print "Cache directory:", cacheDir
|
||||
free = getfreespace(cacheDir);
|
||||
print "Current free disk space:", free
|
||||
|
||||
runs = options.runs;
|
||||
while runs!=0 :
|
||||
run(
|
||||
cacheDir,
|
||||
sleep=options.sleep,
|
||||
simulate=options.simulate,
|
||||
threshold=options.threshold,
|
||||
min_erase=options.min_erase
|
||||
)
|
||||
if runs>0:
|
||||
runs = runs - 1
|
||||
|
||||
if __name__ == '__main__' :
|
||||
main()
|
||||
2
lib/composer/vendor/sabre/dav/bin/sabredav
vendored
Executable file
2
lib/composer/vendor/sabre/dav/bin/sabredav
vendored
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
php -S 0.0.0.0:8080 `dirname $0`/sabredav.php
|
||||
51
lib/composer/vendor/sabre/dav/bin/sabredav.php
vendored
Executable file
51
lib/composer/vendor/sabre/dav/bin/sabredav.php
vendored
Executable file
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
// SabreDAV test server.
|
||||
|
||||
class CliLog
|
||||
{
|
||||
protected $stream;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->stream = fopen('php://stdout', 'w');
|
||||
}
|
||||
|
||||
public function log($msg)
|
||||
{
|
||||
fwrite($this->stream, $msg."\n");
|
||||
}
|
||||
}
|
||||
|
||||
$log = new CliLog();
|
||||
|
||||
if ('cli-server' !== php_sapi_name()) {
|
||||
exit('This script is intended to run on the built-in php webserver');
|
||||
}
|
||||
|
||||
// Finding composer
|
||||
|
||||
$paths = [
|
||||
__DIR__.'/../vendor/autoload.php',
|
||||
__DIR__.'/../../../autoload.php',
|
||||
];
|
||||
|
||||
foreach ($paths as $path) {
|
||||
if (file_exists($path)) {
|
||||
include $path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
use Sabre\DAV;
|
||||
|
||||
// Root
|
||||
$root = new DAV\FS\Directory(getcwd());
|
||||
|
||||
// Setting up server.
|
||||
$server = new DAV\Server($root);
|
||||
|
||||
// Browser plugin
|
||||
$server->addPlugin(new DAV\Browser\Plugin());
|
||||
|
||||
$server->exec();
|
||||
81
lib/composer/vendor/sabre/dav/composer.json
vendored
Normal file
81
lib/composer/vendor/sabre/dav/composer.json
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
"name": "sabre/dav",
|
||||
"type": "library",
|
||||
"description": "WebDAV Framework for PHP",
|
||||
"keywords": ["Framework", "WebDAV", "CalDAV", "CardDAV", "iCalendar"],
|
||||
"homepage": "http://sabre.io/",
|
||||
"license" : "BSD-3-Clause",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Evert Pot",
|
||||
"email": "me@evertpot.com",
|
||||
"homepage" : "http://evertpot.com/",
|
||||
"role" : "Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1.0 || ^8.0",
|
||||
"sabre/vobject": "^4.2.1",
|
||||
"sabre/event" : "^5.0",
|
||||
"sabre/xml" : "^2.0.1",
|
||||
"sabre/http" : "^5.0.5",
|
||||
"sabre/uri" : "^2.0",
|
||||
"ext-dom": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-spl": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-mbstring" : "*",
|
||||
"ext-ctype" : "*",
|
||||
"ext-date" : "*",
|
||||
"ext-iconv" : "*",
|
||||
"lib-libxml" : ">=2.7.0",
|
||||
"psr/log": "^1.0 || ^2.0 || ^3.0",
|
||||
"ext-json": "*"
|
||||
},
|
||||
"require-dev" : {
|
||||
"friendsofphp/php-cs-fixer": "^2.19",
|
||||
"monolog/monolog": "^1.27 || ^2.0",
|
||||
"phpstan/phpstan": "^0.12 || ^1.0",
|
||||
"phpstan/phpstan-phpunit": "^1.0",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.6"
|
||||
},
|
||||
"suggest" : {
|
||||
"ext-curl" : "*",
|
||||
"ext-pdo" : "*",
|
||||
"ext-imap": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4" : {
|
||||
"Sabre\\" : "lib/"
|
||||
}
|
||||
},
|
||||
"autoload-dev" : {
|
||||
"psr-4" : {
|
||||
"Sabre\\" : "tests/Sabre/"
|
||||
}
|
||||
},
|
||||
"support" : {
|
||||
"forum" : "https://groups.google.com/group/sabredav-discuss",
|
||||
"source" : "https://github.com/fruux/sabre-dav"
|
||||
},
|
||||
"bin" : [
|
||||
"bin/sabredav",
|
||||
"bin/naturalselection"
|
||||
],
|
||||
"scripts": {
|
||||
"phpstan": [
|
||||
"phpstan analyse lib tests"
|
||||
],
|
||||
"cs-fixer": [
|
||||
"php-cs-fixer fix"
|
||||
],
|
||||
"phpunit": [
|
||||
"phpunit --configuration tests/phpunit.xml"
|
||||
],
|
||||
"test": [
|
||||
"composer phpstan",
|
||||
"composer cs-fixer",
|
||||
"composer phpunit"
|
||||
]
|
||||
}
|
||||
}
|
||||
216
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php
vendored
Normal file
216
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php
vendored
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
use Sabre\CalDAV;
|
||||
use Sabre\VObject;
|
||||
|
||||
/**
|
||||
* Abstract Calendaring backend. Extend this class to create your own backends.
|
||||
*
|
||||
* Checkout the BackendInterface for all the methods that must be implemented.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
abstract class AbstractBackend implements BackendInterface
|
||||
{
|
||||
/**
|
||||
* Updates properties for a calendar.
|
||||
*
|
||||
* The list of mutations is stored in a Sabre\DAV\PropPatch object.
|
||||
* To do the actual updates, you must tell this object which properties
|
||||
* you're going to process with the handle() method.
|
||||
*
|
||||
* Calling the handle method is like telling the PropPatch object "I
|
||||
* promise I can handle updating this property".
|
||||
*
|
||||
* Read the PropPatch documentation for more info and examples.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
*/
|
||||
public function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of calendar objects.
|
||||
*
|
||||
* This method should work identical to getCalendarObject, but instead
|
||||
* return all the calendar objects in the list as an array.
|
||||
*
|
||||
* If the backend supports this, it may allow for some speed-ups.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMultipleCalendarObjects($calendarId, array $uris)
|
||||
{
|
||||
return array_map(function ($uri) use ($calendarId) {
|
||||
return $this->getCalendarObject($calendarId, $uri);
|
||||
}, $uris);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a calendar-query on the contents of this calendar.
|
||||
*
|
||||
* The calendar-query is defined in RFC4791 : CalDAV. Using the
|
||||
* calendar-query it is possible for a client to request a specific set of
|
||||
* object, based on contents of iCalendar properties, date-ranges and
|
||||
* iCalendar component types (VTODO, VEVENT).
|
||||
*
|
||||
* This method should just return a list of (relative) urls that match this
|
||||
* query.
|
||||
*
|
||||
* The list of filters are specified as an array. The exact array is
|
||||
* documented by \Sabre\CalDAV\CalendarQueryParser.
|
||||
*
|
||||
* Note that it is extremely likely that getCalendarObject for every path
|
||||
* returned from this method will be called almost immediately after. You
|
||||
* may want to anticipate this to speed up these requests.
|
||||
*
|
||||
* This method provides a default implementation, which parses *all* the
|
||||
* iCalendar objects in the specified calendar.
|
||||
*
|
||||
* This default may well be good enough for personal use, and calendars
|
||||
* that aren't very large. But if you anticipate high usage, big calendars
|
||||
* or high loads, you are strongly advised to optimize certain paths.
|
||||
*
|
||||
* The best way to do so is override this method and to optimize
|
||||
* specifically for 'common filters'.
|
||||
*
|
||||
* Requests that are extremely common are:
|
||||
* * requests for just VEVENTS
|
||||
* * requests for just VTODO
|
||||
* * requests with a time-range-filter on either VEVENT or VTODO.
|
||||
*
|
||||
* ..and combinations of these requests. It may not be worth it to try to
|
||||
* handle every possible situation and just rely on the (relatively
|
||||
* easy to use) CalendarQueryValidator to handle the rest.
|
||||
*
|
||||
* Note that especially time-range-filters may be difficult to parse. A
|
||||
* time-range filter specified on a VEVENT must for instance also handle
|
||||
* recurrence rules correctly.
|
||||
* A good example of how to interpret all these filters can also simply
|
||||
* be found in \Sabre\CalDAV\CalendarQueryFilter. This class is as correct
|
||||
* as possible, so it gives you a good idea on what type of stuff you need
|
||||
* to think of.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function calendarQuery($calendarId, array $filters)
|
||||
{
|
||||
$result = [];
|
||||
$objects = $this->getCalendarObjects($calendarId);
|
||||
|
||||
foreach ($objects as $object) {
|
||||
if ($this->validateFilterForObject($object, $filters)) {
|
||||
$result[] = $object['uri'];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method validates if a filter (as passed to calendarQuery) matches
|
||||
* the given object.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateFilterForObject(array $object, array $filters)
|
||||
{
|
||||
// Unfortunately, setting the 'calendardata' here is optional. If
|
||||
// it was excluded, we actually need another call to get this as
|
||||
// well.
|
||||
if (!isset($object['calendardata'])) {
|
||||
$object = $this->getCalendarObject($object['calendarid'], $object['uri']);
|
||||
}
|
||||
|
||||
$vObject = VObject\Reader::read($object['calendardata']);
|
||||
|
||||
$validator = new CalDAV\CalendarQueryValidator();
|
||||
$result = $validator->validate($vObject, $filters);
|
||||
|
||||
// Destroy circular references so PHP will GC the object.
|
||||
$vObject->destroy();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches through all of a users calendars and calendar objects to find
|
||||
* an object with a specific UID.
|
||||
*
|
||||
* This method should return the path to this object, relative to the
|
||||
* calendar home, so this path usually only contains two parts:
|
||||
*
|
||||
* calendarpath/objectpath.ics
|
||||
*
|
||||
* If the uid is not found, return null.
|
||||
*
|
||||
* This method should only consider * objects that the principal owns, so
|
||||
* any calendars owned by other principals that also appear in this
|
||||
* collection should be ignored.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @param string $uid
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCalendarObjectByUID($principalUri, $uid)
|
||||
{
|
||||
// Note: this is a super slow naive implementation of this method. You
|
||||
// are highly recommended to optimize it, if your backend allows it.
|
||||
foreach ($this->getCalendarsForUser($principalUri) as $calendar) {
|
||||
// We must ignore calendars owned by other principals.
|
||||
if ($calendar['principaluri'] !== $principalUri) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore calendars that are shared.
|
||||
if (isset($calendar['{http://sabredav.org/ns}owner-principal']) && $calendar['{http://sabredav.org/ns}owner-principal'] !== $principalUri) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$results = $this->calendarQuery(
|
||||
$calendar['id'],
|
||||
[
|
||||
'name' => 'VCALENDAR',
|
||||
'prop-filters' => [],
|
||||
'comp-filters' => [
|
||||
[
|
||||
'name' => 'VEVENT',
|
||||
'is-not-defined' => false,
|
||||
'time-range' => null,
|
||||
'comp-filters' => [],
|
||||
'prop-filters' => [
|
||||
[
|
||||
'name' => 'UID',
|
||||
'is-not-defined' => false,
|
||||
'time-range' => null,
|
||||
'text-match' => [
|
||||
'value' => $uid,
|
||||
'negate-condition' => false,
|
||||
'collation' => 'i;octet',
|
||||
],
|
||||
'param-filters' => [],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
if ($results) {
|
||||
// We have a match
|
||||
return $calendar['uri'].'/'.$results[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
273
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/BackendInterface.php
vendored
Normal file
273
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/BackendInterface.php
vendored
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
/**
|
||||
* Every CalDAV backend must at least implement this interface.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface BackendInterface
|
||||
{
|
||||
/**
|
||||
* Returns a list of calendars for a principal.
|
||||
*
|
||||
* Every project is an array with the following keys:
|
||||
* * id, a unique id that will be used by other functions to modify the
|
||||
* calendar. This can be the same as the uri or a database key.
|
||||
* * uri, which is the basename of the uri with which the calendar is
|
||||
* accessed.
|
||||
* * principaluri. The owner of the calendar. Almost always the same as
|
||||
* principalUri passed to this method.
|
||||
*
|
||||
* Furthermore it can contain webdav properties in clark notation. A very
|
||||
* common one is '{DAV:}displayname'.
|
||||
*
|
||||
* Many clients also require:
|
||||
* {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
|
||||
* For this property, you can just return an instance of
|
||||
* Sabre\CalDAV\Property\SupportedCalendarComponentSet.
|
||||
*
|
||||
* If you return {http://sabredav.org/ns}read-only and set the value to 1,
|
||||
* ACL will automatically be put in read-only mode.
|
||||
*
|
||||
* @param string $principalUri
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCalendarsForUser($principalUri);
|
||||
|
||||
/**
|
||||
* Creates a new calendar for a principal.
|
||||
*
|
||||
* If the creation was a success, an id must be returned that can be used to
|
||||
* reference this calendar in other methods, such as updateCalendar.
|
||||
*
|
||||
* The id can be any type, including ints, strings, objects or array.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @param string $calendarUri
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function createCalendar($principalUri, $calendarUri, array $properties);
|
||||
|
||||
/**
|
||||
* Updates properties for a calendar.
|
||||
*
|
||||
* The list of mutations is stored in a Sabre\DAV\PropPatch object.
|
||||
* To do the actual updates, you must tell this object which properties
|
||||
* you're going to process with the handle() method.
|
||||
*
|
||||
* Calling the handle method is like telling the PropPatch object "I
|
||||
* promise I can handle updating this property".
|
||||
*
|
||||
* Read the PropPatch documentation for more info and examples.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
*/
|
||||
public function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch);
|
||||
|
||||
/**
|
||||
* Delete a calendar and all its objects.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
*/
|
||||
public function deleteCalendar($calendarId);
|
||||
|
||||
/**
|
||||
* Returns all calendar objects within a calendar.
|
||||
*
|
||||
* Every item contains an array with the following keys:
|
||||
* * calendardata - The iCalendar-compatible calendar data
|
||||
* * uri - a unique key which will be used to construct the uri. This can
|
||||
* be any arbitrary string, but making sure it ends with '.ics' is a
|
||||
* good idea. This is only the basename, or filename, not the full
|
||||
* path.
|
||||
* * lastmodified - a timestamp of the last modification time
|
||||
* * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
|
||||
* '"abcdef"')
|
||||
* * size - The size of the calendar objects, in bytes.
|
||||
* * component - optional, a string containing the type of object, such
|
||||
* as 'vevent' or 'vtodo'. If specified, this will be used to populate
|
||||
* the Content-Type header.
|
||||
*
|
||||
* Note that the etag is optional, but it's highly encouraged to return for
|
||||
* speed reasons.
|
||||
*
|
||||
* The calendardata is also optional. If it's not returned
|
||||
* 'getCalendarObject' will be called later, which *is* expected to return
|
||||
* calendardata.
|
||||
*
|
||||
* If neither etag or size are specified, the calendardata will be
|
||||
* used/fetched to determine these numbers. If both are specified the
|
||||
* amount of times this is needed is reduced by a great degree.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCalendarObjects($calendarId);
|
||||
|
||||
/**
|
||||
* Returns information from a single calendar object, based on it's object
|
||||
* uri.
|
||||
*
|
||||
* The object uri is only the basename, or filename and not a full path.
|
||||
*
|
||||
* The returned array must have the same keys as getCalendarObjects. The
|
||||
* 'calendardata' object is required here though, while it's not required
|
||||
* for getCalendarObjects.
|
||||
*
|
||||
* This method must return null if the object did not exist.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param string $objectUri
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getCalendarObject($calendarId, $objectUri);
|
||||
|
||||
/**
|
||||
* Returns a list of calendar objects.
|
||||
*
|
||||
* This method should work identical to getCalendarObject, but instead
|
||||
* return all the calendar objects in the list as an array.
|
||||
*
|
||||
* If the backend supports this, it may allow for some speed-ups.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMultipleCalendarObjects($calendarId, array $uris);
|
||||
|
||||
/**
|
||||
* Creates a new calendar object.
|
||||
*
|
||||
* The object uri is only the basename, or filename and not a full path.
|
||||
*
|
||||
* It is possible to return an etag from this function, which will be used
|
||||
* in the response to this PUT request. Note that the ETag must be
|
||||
* surrounded by double-quotes.
|
||||
*
|
||||
* However, you should only really return this ETag if you don't mangle the
|
||||
* calendar-data. If the result of a subsequent GET to this object is not
|
||||
* the exact same as this request body, you should omit the ETag.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function createCalendarObject($calendarId, $objectUri, $calendarData);
|
||||
|
||||
/**
|
||||
* Updates an existing calendarobject, based on it's uri.
|
||||
*
|
||||
* The object uri is only the basename, or filename and not a full path.
|
||||
*
|
||||
* It is possible return an etag from this function, which will be used in
|
||||
* the response to this PUT request. Note that the ETag must be surrounded
|
||||
* by double-quotes.
|
||||
*
|
||||
* However, you should only really return this ETag if you don't mangle the
|
||||
* calendar-data. If the result of a subsequent GET to this object is not
|
||||
* the exact same as this request body, you should omit the ETag.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function updateCalendarObject($calendarId, $objectUri, $calendarData);
|
||||
|
||||
/**
|
||||
* Deletes an existing calendar object.
|
||||
*
|
||||
* The object uri is only the basename, or filename and not a full path.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param string $objectUri
|
||||
*/
|
||||
public function deleteCalendarObject($calendarId, $objectUri);
|
||||
|
||||
/**
|
||||
* Performs a calendar-query on the contents of this calendar.
|
||||
*
|
||||
* The calendar-query is defined in RFC4791 : CalDAV. Using the
|
||||
* calendar-query it is possible for a client to request a specific set of
|
||||
* object, based on contents of iCalendar properties, date-ranges and
|
||||
* iCalendar component types (VTODO, VEVENT).
|
||||
*
|
||||
* This method should just return a list of (relative) urls that match this
|
||||
* query.
|
||||
*
|
||||
* The list of filters are specified as an array. The exact array is
|
||||
* documented by Sabre\CalDAV\CalendarQueryParser.
|
||||
*
|
||||
* Note that it is extremely likely that getCalendarObject for every path
|
||||
* returned from this method will be called almost immediately after. You
|
||||
* may want to anticipate this to speed up these requests.
|
||||
*
|
||||
* This method provides a default implementation, which parses *all* the
|
||||
* iCalendar objects in the specified calendar.
|
||||
*
|
||||
* This default may well be good enough for personal use, and calendars
|
||||
* that aren't very large. But if you anticipate high usage, big calendars
|
||||
* or high loads, you are strongly advised to optimize certain paths.
|
||||
*
|
||||
* The best way to do so is override this method and to optimize
|
||||
* specifically for 'common filters'.
|
||||
*
|
||||
* Requests that are extremely common are:
|
||||
* * requests for just VEVENTS
|
||||
* * requests for just VTODO
|
||||
* * requests with a time-range-filter on either VEVENT or VTODO.
|
||||
*
|
||||
* ..and combinations of these requests. It may not be worth it to try to
|
||||
* handle every possible situation and just rely on the (relatively
|
||||
* easy to use) CalendarQueryValidator to handle the rest.
|
||||
*
|
||||
* Note that especially time-range-filters may be difficult to parse. A
|
||||
* time-range filter specified on a VEVENT must for instance also handle
|
||||
* recurrence rules correctly.
|
||||
* A good example of how to interprete all these filters can also simply
|
||||
* be found in Sabre\CalDAV\CalendarQueryFilter. This class is as correct
|
||||
* as possible, so it gives you a good idea on what type of stuff you need
|
||||
* to think of.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function calendarQuery($calendarId, array $filters);
|
||||
|
||||
/**
|
||||
* Searches through all of a users calendars and calendar objects to find
|
||||
* an object with a specific UID.
|
||||
*
|
||||
* This method should return the path to this object, relative to the
|
||||
* calendar home, so this path usually only contains two parts:
|
||||
*
|
||||
* calendarpath/objectpath.ics
|
||||
*
|
||||
* If the uid is not found, return null.
|
||||
*
|
||||
* This method should only consider * objects that the principal owns, so
|
||||
* any calendars owned by other principals that also appear in this
|
||||
* collection should be ignored.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @param string $uid
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCalendarObjectByUID($principalUri, $uid);
|
||||
}
|
||||
62
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php
vendored
Normal file
62
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
use Sabre\CalDAV\Xml\Notification\NotificationInterface;
|
||||
|
||||
/**
|
||||
* Adds caldav notification support to a backend.
|
||||
*
|
||||
* Note: This feature is experimental, and may change in between different
|
||||
* SabreDAV versions.
|
||||
*
|
||||
* Notifications are defined at:
|
||||
* http://svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk/doc/Extensions/caldav-notifications.txt
|
||||
*
|
||||
* These notifications are basically a list of server-generated notifications
|
||||
* displayed to the user. Users can dismiss notifications by deleting them.
|
||||
*
|
||||
* The primary usecase is to allow for calendar-sharing.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface NotificationSupport extends BackendInterface
|
||||
{
|
||||
/**
|
||||
* Returns a list of notifications for a given principal url.
|
||||
*
|
||||
* @param string $principalUri
|
||||
*
|
||||
* @return NotificationInterface[]
|
||||
*/
|
||||
public function getNotificationsForPrincipal($principalUri);
|
||||
|
||||
/**
|
||||
* This deletes a specific notification.
|
||||
*
|
||||
* This may be called by a client once it deems a notification handled.
|
||||
*
|
||||
* @param string $principalUri
|
||||
*/
|
||||
public function deleteNotification($principalUri, NotificationInterface $notification);
|
||||
|
||||
/**
|
||||
* This method is called when a user replied to a request to share.
|
||||
*
|
||||
* If the user chose to accept the share, this method should return the
|
||||
* newly created calendar url.
|
||||
*
|
||||
* @param string $href The sharee who is replying (often a mailto: address)
|
||||
* @param int $status One of the SharingPlugin::STATUS_* constants
|
||||
* @param string $calendarUri The url to the calendar thats being shared
|
||||
* @param string $inReplyTo The unique id this message is a response to
|
||||
* @param string $summary A description of the reply
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null);
|
||||
}
|
||||
1487
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php
vendored
Normal file
1487
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php
vendored
Normal file
File diff suppressed because it is too large
Load diff
66
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/SchedulingSupport.php
vendored
Normal file
66
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/SchedulingSupport.php
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
/**
|
||||
* Implementing this interface adds CalDAV Scheduling support to your caldav
|
||||
* server, as defined in rfc6638.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface SchedulingSupport extends BackendInterface
|
||||
{
|
||||
/**
|
||||
* Returns a single scheduling object for the inbox collection.
|
||||
*
|
||||
* The returned array should contain the following elements:
|
||||
* * uri - A unique basename for the object. This will be used to
|
||||
* construct a full uri.
|
||||
* * calendardata - The iCalendar object
|
||||
* * lastmodified - The last modification date. Can be an int for a unix
|
||||
* timestamp, or a PHP DateTime object.
|
||||
* * etag - A unique token that must change if the object changed.
|
||||
* * size - The size of the object, in bytes.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @param string $objectUri
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSchedulingObject($principalUri, $objectUri);
|
||||
|
||||
/**
|
||||
* Returns all scheduling objects for the inbox collection.
|
||||
*
|
||||
* These objects should be returned as an array. Every item in the array
|
||||
* should follow the same structure as returned from getSchedulingObject.
|
||||
*
|
||||
* The main difference is that 'calendardata' is optional.
|
||||
*
|
||||
* @param string $principalUri
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSchedulingObjects($principalUri);
|
||||
|
||||
/**
|
||||
* Deletes a scheduling object from the inbox collection.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @param string $objectUri
|
||||
*/
|
||||
public function deleteSchedulingObject($principalUri, $objectUri);
|
||||
|
||||
/**
|
||||
* Creates a new scheduling object. This should land in a users' inbox.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @param string $objectUri
|
||||
* @param string|resource $objectData
|
||||
*/
|
||||
public function createSchedulingObject($principalUri, $objectUri, $objectData);
|
||||
}
|
||||
60
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/SharingSupport.php
vendored
Normal file
60
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/SharingSupport.php
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
/**
|
||||
* Adds support for sharing features to a CalDAV server.
|
||||
*
|
||||
* CalDAV backends that implement this interface, must make the following
|
||||
* modifications to getCalendarsForUser:
|
||||
*
|
||||
* 1. Return shared calendars for users.
|
||||
* 2. For every calendar, return calendar-resource-uri. This strings is a URI or
|
||||
* relative URI reference that must be unique for every calendar, but
|
||||
* identical for every instance of the same shared calendar.
|
||||
* 3. For every calendar, you must return a share-access element. This element
|
||||
* should contain one of the Sabre\DAV\Sharing\Plugin:ACCESS_* constants and
|
||||
* indicates the access level the user has.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface SharingSupport extends BackendInterface
|
||||
{
|
||||
/**
|
||||
* Updates the list of shares.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param \Sabre\DAV\Xml\Element\Sharee[] $sharees
|
||||
*/
|
||||
public function updateInvites($calendarId, array $sharees);
|
||||
|
||||
/**
|
||||
* Returns the list of people whom this calendar is shared with.
|
||||
*
|
||||
* Every item in the returned list must be a Sharee object with at
|
||||
* least the following properties set:
|
||||
* $href
|
||||
* $shareAccess
|
||||
* $inviteStatus
|
||||
*
|
||||
* and optionally:
|
||||
* $properties
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
*
|
||||
* @return \Sabre\DAV\Xml\Element\Sharee[]
|
||||
*/
|
||||
public function getInvites($calendarId);
|
||||
|
||||
/**
|
||||
* Publishes a calendar.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setPublishStatus($calendarId, $value);
|
||||
}
|
||||
289
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/SimplePDO.php
vendored
Normal file
289
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/SimplePDO.php
vendored
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
use Sabre\CalDAV;
|
||||
use Sabre\DAV;
|
||||
|
||||
/**
|
||||
* Simple PDO CalDAV backend.
|
||||
*
|
||||
* This class is basically the most minimum example to get a caldav backend up
|
||||
* and running. This class uses the following schema (MySQL example):
|
||||
*
|
||||
* CREATE TABLE simple_calendars (
|
||||
* id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
* uri VARBINARY(200) NOT NULL,
|
||||
* principaluri VARBINARY(200) NOT NULL
|
||||
* );
|
||||
*
|
||||
* CREATE TABLE simple_calendarobjects (
|
||||
* id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
* calendarid INT UNSIGNED NOT NULL,
|
||||
* uri VARBINARY(200) NOT NULL,
|
||||
* calendardata MEDIUMBLOB
|
||||
* )
|
||||
*
|
||||
* To make this class work, you absolutely need to have the PropertyStorage
|
||||
* plugin enabled.
|
||||
*
|
||||
* @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class SimplePDO extends AbstractBackend
|
||||
{
|
||||
/**
|
||||
* pdo.
|
||||
*
|
||||
* @var \PDO
|
||||
*/
|
||||
protected $pdo;
|
||||
|
||||
/**
|
||||
* Creates the backend.
|
||||
*/
|
||||
public function __construct(\PDO $pdo)
|
||||
{
|
||||
$this->pdo = $pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of calendars for a principal.
|
||||
*
|
||||
* Every project is an array with the following keys:
|
||||
* * id, a unique id that will be used by other functions to modify the
|
||||
* calendar. This can be the same as the uri or a database key.
|
||||
* * uri. This is just the 'base uri' or 'filename' of the calendar.
|
||||
* * principaluri. The owner of the calendar. Almost always the same as
|
||||
* principalUri passed to this method.
|
||||
*
|
||||
* Furthermore it can contain webdav properties in clark notation. A very
|
||||
* common one is '{DAV:}displayname'.
|
||||
*
|
||||
* Many clients also require:
|
||||
* {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
|
||||
* For this property, you can just return an instance of
|
||||
* Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet.
|
||||
*
|
||||
* If you return {http://sabredav.org/ns}read-only and set the value to 1,
|
||||
* ACL will automatically be put in read-only mode.
|
||||
*
|
||||
* @param string $principalUri
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCalendarsForUser($principalUri)
|
||||
{
|
||||
// Making fields a comma-delimited list
|
||||
$stmt = $this->pdo->prepare('SELECT id, uri FROM simple_calendars WHERE principaluri = ? ORDER BY id ASC');
|
||||
$stmt->execute([$principalUri]);
|
||||
|
||||
$calendars = [];
|
||||
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$calendars[] = [
|
||||
'id' => $row['id'],
|
||||
'uri' => $row['uri'],
|
||||
'principaluri' => $principalUri,
|
||||
];
|
||||
}
|
||||
|
||||
return $calendars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new calendar for a principal.
|
||||
*
|
||||
* If the creation was a success, an id must be returned that can be used
|
||||
* to reference this calendar in other methods, such as updateCalendar.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @param string $calendarUri
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function createCalendar($principalUri, $calendarUri, array $properties)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('INSERT INTO simple_calendars (principaluri, uri) VALUES (?, ?)');
|
||||
$stmt->execute([$principalUri, $calendarUri]);
|
||||
|
||||
return $this->pdo->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a calendar and all it's objects.
|
||||
*
|
||||
* @param string $calendarId
|
||||
*/
|
||||
public function deleteCalendar($calendarId)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('DELETE FROM simple_calendarobjects WHERE calendarid = ?');
|
||||
$stmt->execute([$calendarId]);
|
||||
|
||||
$stmt = $this->pdo->prepare('DELETE FROM simple_calendars WHERE id = ?');
|
||||
$stmt->execute([$calendarId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all calendar objects within a calendar.
|
||||
*
|
||||
* Every item contains an array with the following keys:
|
||||
* * calendardata - The iCalendar-compatible calendar data
|
||||
* * uri - a unique key which will be used to construct the uri. This can
|
||||
* be any arbitrary string, but making sure it ends with '.ics' is a
|
||||
* good idea. This is only the basename, or filename, not the full
|
||||
* path.
|
||||
* * lastmodified - a timestamp of the last modification time
|
||||
* * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
|
||||
* ' "abcdef"')
|
||||
* * size - The size of the calendar objects, in bytes.
|
||||
* * component - optional, a string containing the type of object, such
|
||||
* as 'vevent' or 'vtodo'. If specified, this will be used to populate
|
||||
* the Content-Type header.
|
||||
*
|
||||
* Note that the etag is optional, but it's highly encouraged to return for
|
||||
* speed reasons.
|
||||
*
|
||||
* The calendardata is also optional. If it's not returned
|
||||
* 'getCalendarObject' will be called later, which *is* expected to return
|
||||
* calendardata.
|
||||
*
|
||||
* If neither etag or size are specified, the calendardata will be
|
||||
* used/fetched to determine these numbers. If both are specified the
|
||||
* amount of times this is needed is reduced by a great degree.
|
||||
*
|
||||
* @param string $calendarId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCalendarObjects($calendarId)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('SELECT id, uri, calendardata FROM simple_calendarobjects WHERE calendarid = ?');
|
||||
$stmt->execute([$calendarId]);
|
||||
|
||||
$result = [];
|
||||
foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
|
||||
$result[] = [
|
||||
'id' => $row['id'],
|
||||
'uri' => $row['uri'],
|
||||
'etag' => '"'.md5($row['calendardata']).'"',
|
||||
'calendarid' => $calendarId,
|
||||
'size' => strlen($row['calendardata']),
|
||||
'calendardata' => $row['calendardata'],
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information from a single calendar object, based on it's object
|
||||
* uri.
|
||||
*
|
||||
* The object uri is only the basename, or filename and not a full path.
|
||||
*
|
||||
* The returned array must have the same keys as getCalendarObjects. The
|
||||
* 'calendardata' object is required here though, while it's not required
|
||||
* for getCalendarObjects.
|
||||
*
|
||||
* This method must return null if the object did not exist.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getCalendarObject($calendarId, $objectUri)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('SELECT id, uri, calendardata FROM simple_calendarobjects WHERE calendarid = ? AND uri = ?');
|
||||
$stmt->execute([$calendarId, $objectUri]);
|
||||
$row = $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$row) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $row['id'],
|
||||
'uri' => $row['uri'],
|
||||
'etag' => '"'.md5($row['calendardata']).'"',
|
||||
'calendarid' => $calendarId,
|
||||
'size' => strlen($row['calendardata']),
|
||||
'calendardata' => $row['calendardata'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new calendar object.
|
||||
*
|
||||
* The object uri is only the basename, or filename and not a full path.
|
||||
*
|
||||
* It is possible return an etag from this function, which will be used in
|
||||
* the response to this PUT request. Note that the ETag must be surrounded
|
||||
* by double-quotes.
|
||||
*
|
||||
* However, you should only really return this ETag if you don't mangle the
|
||||
* calendar-data. If the result of a subsequent GET to this object is not
|
||||
* the exact same as this request body, you should omit the ETag.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function createCalendarObject($calendarId, $objectUri, $calendarData)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('INSERT INTO simple_calendarobjects (calendarid, uri, calendardata) VALUES (?,?,?)');
|
||||
$stmt->execute([
|
||||
$calendarId,
|
||||
$objectUri,
|
||||
$calendarData,
|
||||
]);
|
||||
|
||||
return '"'.md5($calendarData).'"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing calendarobject, based on it's uri.
|
||||
*
|
||||
* The object uri is only the basename, or filename and not a full path.
|
||||
*
|
||||
* It is possible return an etag from this function, which will be used in
|
||||
* the response to this PUT request. Note that the ETag must be surrounded
|
||||
* by double-quotes.
|
||||
*
|
||||
* However, you should only really return this ETag if you don't mangle the
|
||||
* calendar-data. If the result of a subsequent GET to this object is not
|
||||
* the exact same as this request body, you should omit the ETag.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function updateCalendarObject($calendarId, $objectUri, $calendarData)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('UPDATE simple_calendarobjects SET calendardata = ? WHERE calendarid = ? AND uri = ?');
|
||||
$stmt->execute([$calendarData, $calendarId, $objectUri]);
|
||||
|
||||
return '"'.md5($calendarData).'"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an existing calendar object.
|
||||
*
|
||||
* The object uri is only the basename, or filename and not a full path.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
*/
|
||||
public function deleteCalendarObject($calendarId, $objectUri)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('DELETE FROM simple_calendarobjects WHERE calendarid = ? AND uri = ?');
|
||||
$stmt->execute([$calendarId, $objectUri]);
|
||||
}
|
||||
}
|
||||
89
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php
vendored
Normal file
89
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php
vendored
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
||||
/**
|
||||
* Every CalDAV backend must at least implement this interface.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface SubscriptionSupport extends BackendInterface
|
||||
{
|
||||
/**
|
||||
* Returns a list of subscriptions for a principal.
|
||||
*
|
||||
* Every subscription is an array with the following keys:
|
||||
* * id, a unique id that will be used by other functions to modify the
|
||||
* subscription. This can be the same as the uri or a database key.
|
||||
* * uri. This is just the 'base uri' or 'filename' of the subscription.
|
||||
* * principaluri. The owner of the subscription. Almost always the same as
|
||||
* principalUri passed to this method.
|
||||
*
|
||||
* Furthermore, all the subscription info must be returned too:
|
||||
*
|
||||
* 1. {DAV:}displayname
|
||||
* 2. {http://apple.com/ns/ical/}refreshrate
|
||||
* 3. {http://calendarserver.org/ns/}subscribed-strip-todos (omit if todos
|
||||
* should not be stripped).
|
||||
* 4. {http://calendarserver.org/ns/}subscribed-strip-alarms (omit if alarms
|
||||
* should not be stripped).
|
||||
* 5. {http://calendarserver.org/ns/}subscribed-strip-attachments (omit if
|
||||
* attachments should not be stripped).
|
||||
* 6. {http://calendarserver.org/ns/}source (Must be a
|
||||
* Sabre\DAV\Property\Href).
|
||||
* 7. {http://apple.com/ns/ical/}calendar-color
|
||||
* 8. {http://apple.com/ns/ical/}calendar-order
|
||||
* 9. {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
|
||||
* (should just be an instance of
|
||||
* Sabre\CalDAV\Property\SupportedCalendarComponentSet, with a bunch of
|
||||
* default components).
|
||||
*
|
||||
* @param string $principalUri
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSubscriptionsForUser($principalUri);
|
||||
|
||||
/**
|
||||
* Creates a new subscription for a principal.
|
||||
*
|
||||
* If the creation was a success, an id must be returned that can be used to reference
|
||||
* this subscription in other methods, such as updateSubscription.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @param string $uri
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function createSubscription($principalUri, $uri, array $properties);
|
||||
|
||||
/**
|
||||
* Updates a subscription.
|
||||
*
|
||||
* The list of mutations is stored in a Sabre\DAV\PropPatch object.
|
||||
* To do the actual updates, you must tell this object which properties
|
||||
* you're going to process with the handle() method.
|
||||
*
|
||||
* Calling the handle method is like telling the PropPatch object "I
|
||||
* promise I can handle updating this property".
|
||||
*
|
||||
* Read the PropPatch documentation for more info and examples.
|
||||
*
|
||||
* @param mixed $subscriptionId
|
||||
* @param \Sabre\DAV\PropPatch $propPatch
|
||||
*/
|
||||
public function updateSubscription($subscriptionId, DAV\PropPatch $propPatch);
|
||||
|
||||
/**
|
||||
* Deletes a subscription.
|
||||
*
|
||||
* @param mixed $subscriptionId
|
||||
*/
|
||||
public function deleteSubscription($subscriptionId);
|
||||
}
|
||||
83
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/SyncSupport.php
vendored
Normal file
83
lib/composer/vendor/sabre/dav/lib/CalDAV/Backend/SyncSupport.php
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
/**
|
||||
* WebDAV-sync support for CalDAV backends.
|
||||
*
|
||||
* In order for backends to advertise support for WebDAV-sync, this interface
|
||||
* must be implemented.
|
||||
*
|
||||
* Implementing this can result in a significant reduction of bandwidth and CPU
|
||||
* time.
|
||||
*
|
||||
* For this to work, you _must_ return a {http://sabredav.org/ns}sync-token
|
||||
* property from getCalendarsFromUser.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface SyncSupport extends BackendInterface
|
||||
{
|
||||
/**
|
||||
* The getChanges method returns all the changes that have happened, since
|
||||
* the specified syncToken in the specified calendar.
|
||||
*
|
||||
* This function should return an array, such as the following:
|
||||
*
|
||||
* [
|
||||
* 'syncToken' => 'The current synctoken',
|
||||
* 'added' => [
|
||||
* 'new.txt',
|
||||
* ],
|
||||
* 'modified' => [
|
||||
* 'modified.txt',
|
||||
* ],
|
||||
* 'deleted' => [
|
||||
* 'foo.php.bak',
|
||||
* 'old.txt'
|
||||
* ]
|
||||
* );
|
||||
*
|
||||
* The returned syncToken property should reflect the *current* syncToken
|
||||
* of the calendar, as reported in the {http://sabredav.org/ns}sync-token
|
||||
* property This is * needed here too, to ensure the operation is atomic.
|
||||
*
|
||||
* If the $syncToken argument is specified as null, this is an initial
|
||||
* sync, and all members should be reported.
|
||||
*
|
||||
* The modified property is an array of nodenames that have changed since
|
||||
* the last token.
|
||||
*
|
||||
* The deleted property is an array with nodenames, that have been deleted
|
||||
* from collection.
|
||||
*
|
||||
* The $syncLevel argument is basically the 'depth' of the report. If it's
|
||||
* 1, you only have to report changes that happened only directly in
|
||||
* immediate descendants. If it's 2, it should also include changes from
|
||||
* the nodes below the child collections. (grandchildren)
|
||||
*
|
||||
* The $limit argument allows a client to specify how many results should
|
||||
* be returned at most. If the limit is not specified, it should be treated
|
||||
* as infinite.
|
||||
*
|
||||
* If the limit (infinite or not) is higher than you're willing to return,
|
||||
* you should throw a Sabre\DAV\Exception\TooMuchMatches() exception.
|
||||
*
|
||||
* If the syncToken is expired (due to data cleanup) or unknown, you must
|
||||
* return null.
|
||||
*
|
||||
* The limit is 'suggestive'. You are free to ignore it.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param string $syncToken
|
||||
* @param int $syncLevel
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit = null);
|
||||
}
|
||||
460
lib/composer/vendor/sabre/dav/lib/CalDAV/Calendar.php
vendored
Normal file
460
lib/composer/vendor/sabre/dav/lib/CalDAV/Calendar.php
vendored
Normal file
|
|
@ -0,0 +1,460 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use Sabre\DAV;
|
||||
use Sabre\DAV\PropPatch;
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* This object represents a CalDAV calendar.
|
||||
*
|
||||
* A calendar can contain multiple TODO and or Events. These are represented
|
||||
* as \Sabre\CalDAV\CalendarObject objects.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection, DAV\IMultiGet
|
||||
{
|
||||
use DAVACL\ACLTrait;
|
||||
|
||||
/**
|
||||
* This is an array with calendar information.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $calendarInfo;
|
||||
|
||||
/**
|
||||
* CalDAV backend.
|
||||
*
|
||||
* @var Backend\BackendInterface
|
||||
*/
|
||||
protected $caldavBackend;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $calendarInfo
|
||||
*/
|
||||
public function __construct(Backend\BackendInterface $caldavBackend, $calendarInfo)
|
||||
{
|
||||
$this->caldavBackend = $caldavBackend;
|
||||
$this->calendarInfo = $calendarInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the calendar.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->calendarInfo['uri'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates properties on this node.
|
||||
*
|
||||
* This method received a PropPatch object, which contains all the
|
||||
* information about the update.
|
||||
*
|
||||
* To update specific properties, call the 'handle' method on this object.
|
||||
* Read the PropPatch documentation for more information.
|
||||
*/
|
||||
public function propPatch(PropPatch $propPatch)
|
||||
{
|
||||
return $this->caldavBackend->updateCalendar($this->calendarInfo['id'], $propPatch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of properties.
|
||||
*
|
||||
* @param array $requestedProperties
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProperties($requestedProperties)
|
||||
{
|
||||
$response = [];
|
||||
|
||||
foreach ($this->calendarInfo as $propName => $propValue) {
|
||||
if (!is_null($propValue) && '{' === $propName[0]) {
|
||||
$response[$propName] = $this->calendarInfo[$propName];
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a calendar object.
|
||||
*
|
||||
* The contained calendar objects are for example Events or Todo's.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return \Sabre\CalDAV\ICalendarObject
|
||||
*/
|
||||
public function getChild($name)
|
||||
{
|
||||
$obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $name);
|
||||
|
||||
if (!$obj) {
|
||||
throw new DAV\Exception\NotFound('Calendar object not found');
|
||||
}
|
||||
$obj['acl'] = $this->getChildACL();
|
||||
|
||||
return new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full list of calendar objects.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getChildren()
|
||||
{
|
||||
$objs = $this->caldavBackend->getCalendarObjects($this->calendarInfo['id']);
|
||||
$children = [];
|
||||
foreach ($objs as $obj) {
|
||||
$obj['acl'] = $this->getChildACL();
|
||||
$children[] = new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj);
|
||||
}
|
||||
|
||||
return $children;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method receives a list of paths in it's first argument.
|
||||
* It must return an array with Node objects.
|
||||
*
|
||||
* If any children are not found, you do not have to return them.
|
||||
*
|
||||
* @param string[] $paths
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMultipleChildren(array $paths)
|
||||
{
|
||||
$objs = $this->caldavBackend->getMultipleCalendarObjects($this->calendarInfo['id'], $paths);
|
||||
$children = [];
|
||||
foreach ($objs as $obj) {
|
||||
$obj['acl'] = $this->getChildACL();
|
||||
$children[] = new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj);
|
||||
}
|
||||
|
||||
return $children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a child-node exists.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function childExists($name)
|
||||
{
|
||||
$obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $name);
|
||||
if (!$obj) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new directory.
|
||||
*
|
||||
* We actually block this, as subdirectories are not allowed in calendars.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function createDirectory($name)
|
||||
{
|
||||
throw new DAV\Exception\MethodNotAllowed('Creating collections in calendar objects is not allowed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new file.
|
||||
*
|
||||
* The contents of the new file must be a valid ICalendar string.
|
||||
*
|
||||
* @param string $name
|
||||
* @param resource $data
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function createFile($name, $data = null)
|
||||
{
|
||||
if (is_resource($data)) {
|
||||
$data = stream_get_contents($data);
|
||||
}
|
||||
|
||||
return $this->caldavBackend->createCalendarObject($this->calendarInfo['id'], $name, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the calendar.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$this->caldavBackend->deleteCalendar($this->calendarInfo['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames the calendar. Note that most calendars use the
|
||||
* {DAV:}displayname to display a name to display a name.
|
||||
*
|
||||
* @param string $newName
|
||||
*/
|
||||
public function setName($newName)
|
||||
{
|
||||
throw new DAV\Exception\MethodNotAllowed('Renaming calendars is not yet supported');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification date as a unix timestamp.
|
||||
*/
|
||||
public function getLastModified()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal.
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->calendarInfo['principaluri'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of ACE's for this node.
|
||||
*
|
||||
* Each ACE has the following properties:
|
||||
* * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
|
||||
* currently the only supported privileges
|
||||
* * 'principal', a url to the principal who owns the node
|
||||
* * 'protected' (optional), indicating that this ACE is not allowed to
|
||||
* be updated.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getACL()
|
||||
{
|
||||
$acl = [
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->getOwner(),
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{'.Plugin::NS_CALDAV.'}read-free-busy',
|
||||
'principal' => '{DAV:}authenticated',
|
||||
'protected' => true,
|
||||
],
|
||||
];
|
||||
if (empty($this->calendarInfo['{http://sabredav.org/ns}read-only'])) {
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->getOwner(),
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
];
|
||||
}
|
||||
|
||||
return $acl;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the ACL's for calendar objects in this calendar.
|
||||
* The result of this method automatically gets passed to the
|
||||
* calendar-object nodes in the calendar.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getChildACL()
|
||||
{
|
||||
$acl = [
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->getOwner(),
|
||||
'protected' => true,
|
||||
],
|
||||
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
],
|
||||
];
|
||||
if (empty($this->calendarInfo['{http://sabredav.org/ns}read-only'])) {
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->getOwner(),
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
];
|
||||
}
|
||||
|
||||
return $acl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a calendar-query on the contents of this calendar.
|
||||
*
|
||||
* The calendar-query is defined in RFC4791 : CalDAV. Using the
|
||||
* calendar-query it is possible for a client to request a specific set of
|
||||
* object, based on contents of iCalendar properties, date-ranges and
|
||||
* iCalendar component types (VTODO, VEVENT).
|
||||
*
|
||||
* This method should just return a list of (relative) urls that match this
|
||||
* query.
|
||||
*
|
||||
* The list of filters are specified as an array. The exact array is
|
||||
* documented by Sabre\CalDAV\CalendarQueryParser.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function calendarQuery(array $filters)
|
||||
{
|
||||
return $this->caldavBackend->calendarQuery($this->calendarInfo['id'], $filters);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the current sync-token for this collection.
|
||||
* This can be any string.
|
||||
*
|
||||
* If null is returned from this function, the plugin assumes there's no
|
||||
* sync information available.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getSyncToken()
|
||||
{
|
||||
if (
|
||||
$this->caldavBackend instanceof Backend\SyncSupport &&
|
||||
isset($this->calendarInfo['{DAV:}sync-token'])
|
||||
) {
|
||||
return $this->calendarInfo['{DAV:}sync-token'];
|
||||
}
|
||||
if (
|
||||
$this->caldavBackend instanceof Backend\SyncSupport &&
|
||||
isset($this->calendarInfo['{http://sabredav.org/ns}sync-token'])
|
||||
) {
|
||||
return $this->calendarInfo['{http://sabredav.org/ns}sync-token'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The getChanges method returns all the changes that have happened, since
|
||||
* the specified syncToken and the current collection.
|
||||
*
|
||||
* This function should return an array, such as the following:
|
||||
*
|
||||
* [
|
||||
* 'syncToken' => 'The current synctoken',
|
||||
* 'added' => [
|
||||
* 'new.txt',
|
||||
* ],
|
||||
* 'modified' => [
|
||||
* 'modified.txt',
|
||||
* ],
|
||||
* 'deleted' => [
|
||||
* 'foo.php.bak',
|
||||
* 'old.txt'
|
||||
* ],
|
||||
* 'result_truncated' : true
|
||||
* ];
|
||||
*
|
||||
* The syncToken property should reflect the *current* syncToken of the
|
||||
* collection, as reported getSyncToken(). This is needed here too, to
|
||||
* ensure the operation is atomic.
|
||||
*
|
||||
* If the syncToken is specified as null, this is an initial sync, and all
|
||||
* members should be reported.
|
||||
*
|
||||
* If result is truncated due to server limitation or limit by client,
|
||||
* set result_truncated to true, otherwise set to false or do not add the key.
|
||||
*
|
||||
* The modified property is an array of nodenames that have changed since
|
||||
* the last token.
|
||||
*
|
||||
* The deleted property is an array with nodenames, that have been deleted
|
||||
* from collection.
|
||||
*
|
||||
* The second argument is basically the 'depth' of the report. If it's 1,
|
||||
* you only have to report changes that happened only directly in immediate
|
||||
* descendants. If it's 2, it should also include changes from the nodes
|
||||
* below the child collections. (grandchildren)
|
||||
*
|
||||
* The third (optional) argument allows a client to specify how many
|
||||
* results should be returned at most. If the limit is not specified, it
|
||||
* should be treated as infinite.
|
||||
*
|
||||
* If the limit (infinite or not) is higher than you're willing to return,
|
||||
* the result should be truncated to fit the limit.
|
||||
* Note that even when the result is truncated, syncToken must be consistent
|
||||
* with the truncated result, not the result before truncation.
|
||||
* (See RFC6578 Section 3.6 for detail)
|
||||
*
|
||||
* If the syncToken is expired (due to data cleanup) or unknown, you must
|
||||
* return null.
|
||||
*
|
||||
* The limit is 'suggestive'. You are free to ignore it.
|
||||
* TODO: RFC6578 Section 3.7 says that the server must fail when the server
|
||||
* cannot truncate according to the limit, so it may not be just suggestive.
|
||||
*
|
||||
* @param string $syncToken
|
||||
* @param int $syncLevel
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getChanges($syncToken, $syncLevel, $limit = null)
|
||||
{
|
||||
if (!$this->caldavBackend instanceof Backend\SyncSupport) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->caldavBackend->getChangesForCalendar(
|
||||
$this->calendarInfo['id'],
|
||||
$syncToken,
|
||||
$syncLevel,
|
||||
$limit
|
||||
);
|
||||
}
|
||||
}
|
||||
356
lib/composer/vendor/sabre/dav/lib/CalDAV/CalendarHome.php
vendored
Normal file
356
lib/composer/vendor/sabre/dav/lib/CalDAV/CalendarHome.php
vendored
Normal file
|
|
@ -0,0 +1,356 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use Sabre\DAV;
|
||||
use Sabre\DAV\Exception\NotFound;
|
||||
use Sabre\DAV\MkCol;
|
||||
use Sabre\DAVACL;
|
||||
use Sabre\Uri;
|
||||
|
||||
/**
|
||||
* The CalendarHome represents a node that is usually in a users'
|
||||
* calendar-homeset.
|
||||
*
|
||||
* It contains all the users' calendars, and can optionally contain a
|
||||
* notifications collection, calendar subscriptions, a users' inbox, and a
|
||||
* users' outbox.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL
|
||||
{
|
||||
use DAVACL\ACLTrait;
|
||||
|
||||
/**
|
||||
* CalDAV backend.
|
||||
*
|
||||
* @var Backend\BackendInterface
|
||||
*/
|
||||
protected $caldavBackend;
|
||||
|
||||
/**
|
||||
* Principal information.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $principalInfo;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $principalInfo
|
||||
*/
|
||||
public function __construct(Backend\BackendInterface $caldavBackend, $principalInfo)
|
||||
{
|
||||
$this->caldavBackend = $caldavBackend;
|
||||
$this->principalInfo = $principalInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
list(, $name) = Uri\split($this->principalInfo['uri']);
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the name of this object.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
throw new DAV\Exception\Forbidden();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes this object.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
throw new DAV\Exception\Forbidden();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification date.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLastModified()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new file under this object.
|
||||
*
|
||||
* This is currently not allowed
|
||||
*
|
||||
* @param string $name
|
||||
* @param resource $data
|
||||
*/
|
||||
public function createFile($name, $data = null)
|
||||
{
|
||||
throw new DAV\Exception\MethodNotAllowed('Creating new files in this collection is not supported');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new directory under this object.
|
||||
*
|
||||
* This is currently not allowed.
|
||||
*
|
||||
* @param string $filename
|
||||
*/
|
||||
public function createDirectory($filename)
|
||||
{
|
||||
throw new DAV\Exception\MethodNotAllowed('Creating new collections in this collection is not supported');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single calendar, by name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Calendar
|
||||
*/
|
||||
public function getChild($name)
|
||||
{
|
||||
// Special nodes
|
||||
if ('inbox' === $name && $this->caldavBackend instanceof Backend\SchedulingSupport) {
|
||||
return new Schedule\Inbox($this->caldavBackend, $this->principalInfo['uri']);
|
||||
}
|
||||
if ('outbox' === $name && $this->caldavBackend instanceof Backend\SchedulingSupport) {
|
||||
return new Schedule\Outbox($this->principalInfo['uri']);
|
||||
}
|
||||
if ('notifications' === $name && $this->caldavBackend instanceof Backend\NotificationSupport) {
|
||||
return new Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']);
|
||||
}
|
||||
|
||||
// Calendars
|
||||
foreach ($this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']) as $calendar) {
|
||||
if ($calendar['uri'] === $name) {
|
||||
if ($this->caldavBackend instanceof Backend\SharingSupport) {
|
||||
return new SharedCalendar($this->caldavBackend, $calendar);
|
||||
} else {
|
||||
return new Calendar($this->caldavBackend, $calendar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->caldavBackend instanceof Backend\SubscriptionSupport) {
|
||||
foreach ($this->caldavBackend->getSubscriptionsForUser($this->principalInfo['uri']) as $subscription) {
|
||||
if ($subscription['uri'] === $name) {
|
||||
return new Subscriptions\Subscription($this->caldavBackend, $subscription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotFound('Node with name \''.$name.'\' could not be found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a calendar exists.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function childExists($name)
|
||||
{
|
||||
try {
|
||||
return (bool) $this->getChild($name);
|
||||
} catch (NotFound $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of calendars.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getChildren()
|
||||
{
|
||||
$calendars = $this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']);
|
||||
$objs = [];
|
||||
foreach ($calendars as $calendar) {
|
||||
if ($this->caldavBackend instanceof Backend\SharingSupport) {
|
||||
$objs[] = new SharedCalendar($this->caldavBackend, $calendar);
|
||||
} else {
|
||||
$objs[] = new Calendar($this->caldavBackend, $calendar);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->caldavBackend instanceof Backend\SchedulingSupport) {
|
||||
$objs[] = new Schedule\Inbox($this->caldavBackend, $this->principalInfo['uri']);
|
||||
$objs[] = new Schedule\Outbox($this->principalInfo['uri']);
|
||||
}
|
||||
|
||||
// We're adding a notifications node, if it's supported by the backend.
|
||||
if ($this->caldavBackend instanceof Backend\NotificationSupport) {
|
||||
$objs[] = new Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']);
|
||||
}
|
||||
|
||||
// If the backend supports subscriptions, we'll add those as well,
|
||||
if ($this->caldavBackend instanceof Backend\SubscriptionSupport) {
|
||||
foreach ($this->caldavBackend->getSubscriptionsForUser($this->principalInfo['uri']) as $subscription) {
|
||||
$objs[] = new Subscriptions\Subscription($this->caldavBackend, $subscription);
|
||||
}
|
||||
}
|
||||
|
||||
return $objs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new calendar or subscription.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @throws DAV\Exception\InvalidResourceType
|
||||
*/
|
||||
public function createExtendedCollection($name, MkCol $mkCol)
|
||||
{
|
||||
$isCalendar = false;
|
||||
$isSubscription = false;
|
||||
foreach ($mkCol->getResourceType() as $rt) {
|
||||
switch ($rt) {
|
||||
case '{DAV:}collection':
|
||||
case '{http://calendarserver.org/ns/}shared-owner':
|
||||
// ignore
|
||||
break;
|
||||
case '{urn:ietf:params:xml:ns:caldav}calendar':
|
||||
$isCalendar = true;
|
||||
break;
|
||||
case '{http://calendarserver.org/ns/}subscribed':
|
||||
$isSubscription = true;
|
||||
break;
|
||||
default:
|
||||
throw new DAV\Exception\InvalidResourceType('Unknown resourceType: '.$rt);
|
||||
}
|
||||
}
|
||||
|
||||
$properties = $mkCol->getRemainingValues();
|
||||
$mkCol->setRemainingResultCode(201);
|
||||
|
||||
if ($isSubscription) {
|
||||
if (!$this->caldavBackend instanceof Backend\SubscriptionSupport) {
|
||||
throw new DAV\Exception\InvalidResourceType('This backend does not support subscriptions');
|
||||
}
|
||||
$this->caldavBackend->createSubscription($this->principalInfo['uri'], $name, $properties);
|
||||
} elseif ($isCalendar) {
|
||||
$this->caldavBackend->createCalendar($this->principalInfo['uri'], $name, $properties);
|
||||
} else {
|
||||
throw new DAV\Exception\InvalidResourceType('You can only create calendars and subscriptions in this collection');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner of the calendar home.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->principalInfo['uri'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of ACE's for this node.
|
||||
*
|
||||
* Each ACE has the following properties:
|
||||
* * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
|
||||
* currently the only supported privileges
|
||||
* * 'principal', a url to the principal who owns the node
|
||||
* * 'protected' (optional), indicating that this ACE is not allowed to
|
||||
* be updated.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getACL()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->principalInfo['uri'],
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->principalInfo['uri'],
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->principalInfo['uri'].'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->principalInfo['uri'].'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->principalInfo['uri'].'/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when a user replied to a request to share.
|
||||
*
|
||||
* This method should return the url of the newly created calendar if the
|
||||
* share was accepted.
|
||||
*
|
||||
* @param string $href The sharee who is replying (often a mailto: address)
|
||||
* @param int $status One of the SharingPlugin::STATUS_* constants
|
||||
* @param string $calendarUri The url to the calendar thats being shared
|
||||
* @param string $inReplyTo The unique id this message is a response to
|
||||
* @param string $summary A description of the reply
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null)
|
||||
{
|
||||
if (!$this->caldavBackend instanceof Backend\SharingSupport) {
|
||||
throw new DAV\Exception\NotImplemented('Sharing support is not implemented by this backend.');
|
||||
}
|
||||
|
||||
return $this->caldavBackend->shareReply($href, $status, $calendarUri, $inReplyTo, $summary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches through all of a users calendars and calendar objects to find
|
||||
* an object with a specific UID.
|
||||
*
|
||||
* This method should return the path to this object, relative to the
|
||||
* calendar home, so this path usually only contains two parts:
|
||||
*
|
||||
* calendarpath/objectpath.ics
|
||||
*
|
||||
* If the uid is not found, return null.
|
||||
*
|
||||
* This method should only consider * objects that the principal owns, so
|
||||
* any calendars owned by other principals that also appear in this
|
||||
* collection should be ignored.
|
||||
*
|
||||
* @param string $uid
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCalendarObjectByUID($uid)
|
||||
{
|
||||
return $this->caldavBackend->getCalendarObjectByUID($this->principalInfo['uri'], $uid);
|
||||
}
|
||||
}
|
||||
223
lib/composer/vendor/sabre/dav/lib/CalDAV/CalendarObject.php
vendored
Normal file
223
lib/composer/vendor/sabre/dav/lib/CalDAV/CalendarObject.php
vendored
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
/**
|
||||
* The CalendarObject represents a single VEVENT or VTODO within a Calendar.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\DAVACL\IACL
|
||||
{
|
||||
use \Sabre\DAVACL\ACLTrait;
|
||||
|
||||
/**
|
||||
* Sabre\CalDAV\Backend\BackendInterface.
|
||||
*
|
||||
* @var Backend\AbstractBackend
|
||||
*/
|
||||
protected $caldavBackend;
|
||||
|
||||
/**
|
||||
* Array with information about this CalendarObject.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $objectData;
|
||||
|
||||
/**
|
||||
* Array with information about the containing calendar.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $calendarInfo;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* The following properties may be passed within $objectData:
|
||||
*
|
||||
* * calendarid - This must refer to a calendarid from a caldavBackend
|
||||
* * uri - A unique uri. Only the 'basename' must be passed.
|
||||
* * calendardata (optional) - The iCalendar data
|
||||
* * etag - (optional) The etag for this object, MUST be encloded with
|
||||
* double-quotes.
|
||||
* * size - (optional) The size of the data in bytes.
|
||||
* * lastmodified - (optional) format as a unix timestamp.
|
||||
* * acl - (optional) Use this to override the default ACL for the node.
|
||||
*/
|
||||
public function __construct(Backend\BackendInterface $caldavBackend, array $calendarInfo, array $objectData)
|
||||
{
|
||||
$this->caldavBackend = $caldavBackend;
|
||||
|
||||
if (!isset($objectData['uri'])) {
|
||||
throw new \InvalidArgumentException('The objectData argument must contain an \'uri\' property');
|
||||
}
|
||||
|
||||
$this->calendarInfo = $calendarInfo;
|
||||
$this->objectData = $objectData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the uri for this object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->objectData['uri'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ICalendar-formatted object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
// Pre-populating the 'calendardata' is optional, if we don't have it
|
||||
// already we fetch it from the backend.
|
||||
if (!isset($this->objectData['calendardata'])) {
|
||||
$this->objectData = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $this->objectData['uri']);
|
||||
}
|
||||
|
||||
return $this->objectData['calendardata'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the ICalendar-formatted object.
|
||||
*
|
||||
* @param string|resource $calendarData
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function put($calendarData)
|
||||
{
|
||||
if (is_resource($calendarData)) {
|
||||
$calendarData = stream_get_contents($calendarData);
|
||||
}
|
||||
$etag = $this->caldavBackend->updateCalendarObject($this->calendarInfo['id'], $this->objectData['uri'], $calendarData);
|
||||
$this->objectData['calendardata'] = $calendarData;
|
||||
$this->objectData['etag'] = $etag;
|
||||
|
||||
return $etag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the calendar object.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$this->caldavBackend->deleteCalendarObject($this->calendarInfo['id'], $this->objectData['uri']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mime content-type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getContentType()
|
||||
{
|
||||
$mime = 'text/calendar; charset=utf-8';
|
||||
if (isset($this->objectData['component']) && $this->objectData['component']) {
|
||||
$mime .= '; component='.$this->objectData['component'];
|
||||
}
|
||||
|
||||
return $mime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ETag for this object.
|
||||
*
|
||||
* The ETag is an arbitrary string, but MUST be surrounded by double-quotes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getETag()
|
||||
{
|
||||
if (isset($this->objectData['etag'])) {
|
||||
return $this->objectData['etag'];
|
||||
} else {
|
||||
return '"'.md5($this->get()).'"';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification date as a unix timestamp.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLastModified()
|
||||
{
|
||||
return $this->objectData['lastmodified'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of this object in bytes.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
if (array_key_exists('size', $this->objectData)) {
|
||||
return $this->objectData['size'];
|
||||
} else {
|
||||
return strlen($this->get());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal.
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->calendarInfo['principaluri'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of ACE's for this node.
|
||||
*
|
||||
* Each ACE has the following properties:
|
||||
* * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
|
||||
* currently the only supported privileges
|
||||
* * 'principal', a url to the principal who owns the node
|
||||
* * 'protected' (optional), indicating that this ACE is not allowed to
|
||||
* be updated.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getACL()
|
||||
{
|
||||
// An alternative acl may be specified in the object data.
|
||||
if (isset($this->objectData['acl'])) {
|
||||
return $this->objectData['acl'];
|
||||
}
|
||||
|
||||
// The default ACL
|
||||
return [
|
||||
[
|
||||
'privilege' => '{DAV:}all',
|
||||
'principal' => $this->calendarInfo['principaluri'],
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}all',
|
||||
'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
354
lib/composer/vendor/sabre/dav/lib/CalDAV/CalendarQueryValidator.php
vendored
Normal file
354
lib/composer/vendor/sabre/dav/lib/CalDAV/CalendarQueryValidator.php
vendored
Normal file
|
|
@ -0,0 +1,354 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use DateTime;
|
||||
use Sabre\VObject;
|
||||
|
||||
/**
|
||||
* CalendarQuery Validator.
|
||||
*
|
||||
* This class is responsible for checking if an iCalendar object matches a set
|
||||
* of filters. The main function to do this is 'validate'.
|
||||
*
|
||||
* This is used to determine which icalendar objects should be returned for a
|
||||
* calendar-query REPORT request.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class CalendarQueryValidator
|
||||
{
|
||||
/**
|
||||
* Verify if a list of filters applies to the calendar data object.
|
||||
*
|
||||
* The list of filters must be formatted as parsed by \Sabre\CalDAV\CalendarQueryParser
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validate(VObject\Component\VCalendar $vObject, array $filters)
|
||||
{
|
||||
// The top level object is always a component filter.
|
||||
// We'll parse it manually, as it's pretty simple.
|
||||
if ($vObject->name !== $filters['name']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return
|
||||
$this->validateCompFilters($vObject, $filters['comp-filters']) &&
|
||||
$this->validatePropFilters($vObject, $filters['prop-filters']);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks the validity of comp-filters.
|
||||
*
|
||||
* A list of comp-filters needs to be specified. Also the parent of the
|
||||
* component we're checking should be specified, not the component to check
|
||||
* itself.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateCompFilters(VObject\Component $parent, array $filters)
|
||||
{
|
||||
foreach ($filters as $filter) {
|
||||
$isDefined = isset($parent->{$filter['name']});
|
||||
|
||||
if ($filter['is-not-defined']) {
|
||||
if ($isDefined) {
|
||||
return false;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!$isDefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (array_key_exists('time-range', $filter) && $filter['time-range']) {
|
||||
foreach ($parent->{$filter['name']} as $subComponent) {
|
||||
$start = null;
|
||||
$end = null;
|
||||
if (array_key_exists('start', $filter['time-range'])) {
|
||||
$start = $filter['time-range']['start'];
|
||||
}
|
||||
if (array_key_exists('end', $filter['time-range'])) {
|
||||
$end = $filter['time-range']['end'];
|
||||
}
|
||||
if ($this->validateTimeRange($subComponent, $start, $end)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$filter['comp-filters'] && !$filter['prop-filters']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If there are sub-filters, we need to find at least one component
|
||||
// for which the subfilters hold true.
|
||||
foreach ($parent->{$filter['name']} as $subComponent) {
|
||||
if (
|
||||
$this->validateCompFilters($subComponent, $filter['comp-filters']) &&
|
||||
$this->validatePropFilters($subComponent, $filter['prop-filters'])) {
|
||||
// We had a match, so this comp-filter succeeds
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
// If we got here it means there were sub-comp-filters or
|
||||
// sub-prop-filters and there was no match. This means this filter
|
||||
// needs to return false.
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we got here it means we got through all comp-filters alive so the
|
||||
// filters were all true.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks the validity of prop-filters.
|
||||
*
|
||||
* A list of prop-filters needs to be specified. Also the parent of the
|
||||
* property we're checking should be specified, not the property to check
|
||||
* itself.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validatePropFilters(VObject\Component $parent, array $filters)
|
||||
{
|
||||
foreach ($filters as $filter) {
|
||||
$isDefined = isset($parent->{$filter['name']});
|
||||
|
||||
if ($filter['is-not-defined']) {
|
||||
if ($isDefined) {
|
||||
return false;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!$isDefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (array_key_exists('time-range', $filter) && $filter['time-range']) {
|
||||
foreach ($parent->{$filter['name']} as $subComponent) {
|
||||
$start = null;
|
||||
$end = null;
|
||||
if (array_key_exists('start', $filter['time-range'])) {
|
||||
$start = $filter['time-range']['start'];
|
||||
}
|
||||
if (array_key_exists('end', $filter['time-range'])) {
|
||||
$end = $filter['time-range']['end'];
|
||||
}
|
||||
if ($this->validateTimeRange($subComponent, $start, $end)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$filter['param-filters'] && !$filter['text-match']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If there are sub-filters, we need to find at least one property
|
||||
// for which the subfilters hold true.
|
||||
foreach ($parent->{$filter['name']} as $subComponent) {
|
||||
if (
|
||||
$this->validateParamFilters($subComponent, $filter['param-filters']) &&
|
||||
(!$filter['text-match'] || $this->validateTextMatch($subComponent, $filter['text-match']))
|
||||
) {
|
||||
// We had a match, so this prop-filter succeeds
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
// If we got here it means there were sub-param-filters or
|
||||
// text-match filters and there was no match. This means the
|
||||
// filter needs to return false.
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we got here it means we got through all prop-filters alive so the
|
||||
// filters were all true.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks the validity of param-filters.
|
||||
*
|
||||
* A list of param-filters needs to be specified. Also the parent of the
|
||||
* parameter we're checking should be specified, not the parameter to check
|
||||
* itself.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateParamFilters(VObject\Property $parent, array $filters)
|
||||
{
|
||||
foreach ($filters as $filter) {
|
||||
$isDefined = isset($parent[$filter['name']]);
|
||||
|
||||
if ($filter['is-not-defined']) {
|
||||
if ($isDefined) {
|
||||
return false;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!$isDefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$filter['text-match']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If there are sub-filters, we need to find at least one parameter
|
||||
// for which the subfilters hold true.
|
||||
foreach ($parent[$filter['name']]->getParts() as $paramPart) {
|
||||
if ($this->validateTextMatch($paramPart, $filter['text-match'])) {
|
||||
// We had a match, so this param-filter succeeds
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
// If we got here it means there was a text-match filter and there
|
||||
// were no matches. This means the filter needs to return false.
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we got here it means we got through all param-filters alive so the
|
||||
// filters were all true.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks the validity of a text-match.
|
||||
*
|
||||
* A single text-match should be specified as well as the specific property
|
||||
* or parameter we need to validate.
|
||||
*
|
||||
* @param VObject\Node|string $check value to check against
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateTextMatch($check, array $textMatch)
|
||||
{
|
||||
if ($check instanceof VObject\Node) {
|
||||
$check = $check->getValue();
|
||||
}
|
||||
|
||||
$isMatching = \Sabre\DAV\StringUtil::textMatch($check, $textMatch['value'], $textMatch['collation']);
|
||||
|
||||
return $textMatch['negate-condition'] xor $isMatching;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates if a component matches the given time range.
|
||||
*
|
||||
* This is all based on the rules specified in rfc4791, which are quite
|
||||
* complex.
|
||||
*
|
||||
* @param DateTime $start
|
||||
* @param DateTime $end
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateTimeRange(VObject\Node $component, $start, $end)
|
||||
{
|
||||
if (is_null($start)) {
|
||||
$start = new DateTime('1900-01-01');
|
||||
}
|
||||
if (is_null($end)) {
|
||||
$end = new DateTime('3000-01-01');
|
||||
}
|
||||
|
||||
switch ($component->name) {
|
||||
case 'VEVENT':
|
||||
case 'VTODO':
|
||||
case 'VJOURNAL':
|
||||
return $component->isInTimeRange($start, $end);
|
||||
|
||||
case 'VALARM':
|
||||
// If the valarm is wrapped in a recurring event, we need to
|
||||
// expand the recursions, and validate each.
|
||||
//
|
||||
// Our datamodel doesn't easily allow us to do this straight
|
||||
// in the VALARM component code, so this is a hack, and an
|
||||
// expensive one too.
|
||||
if ('VEVENT' === $component->parent->name && $component->parent->RRULE) {
|
||||
// Fire up the iterator!
|
||||
$it = new VObject\Recur\EventIterator($component->parent->parent, (string) $component->parent->UID);
|
||||
while ($it->valid()) {
|
||||
$expandedEvent = $it->getEventObject();
|
||||
|
||||
// We need to check from these expanded alarms, which
|
||||
// one is the first to trigger. Based on this, we can
|
||||
// determine if we can 'give up' expanding events.
|
||||
$firstAlarm = null;
|
||||
if (null !== $expandedEvent->VALARM) {
|
||||
foreach ($expandedEvent->VALARM as $expandedAlarm) {
|
||||
$effectiveTrigger = $expandedAlarm->getEffectiveTriggerTime();
|
||||
if ($expandedAlarm->isInTimeRange($start, $end)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ('DATE-TIME' === (string) $expandedAlarm->TRIGGER['VALUE']) {
|
||||
// This is an alarm with a non-relative trigger
|
||||
// time, likely created by a buggy client. The
|
||||
// implication is that every alarm in this
|
||||
// recurring event trigger at the exact same
|
||||
// time. It doesn't make sense to traverse
|
||||
// further.
|
||||
} else {
|
||||
// We store the first alarm as a means to
|
||||
// figure out when we can stop traversing.
|
||||
if (!$firstAlarm || $effectiveTrigger < $firstAlarm) {
|
||||
$firstAlarm = $effectiveTrigger;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_null($firstAlarm)) {
|
||||
// No alarm was found.
|
||||
//
|
||||
// Or technically: No alarm that will change for
|
||||
// every instance of the recurrence was found,
|
||||
// which means we can assume there was no match.
|
||||
return false;
|
||||
}
|
||||
if ($firstAlarm > $end) {
|
||||
return false;
|
||||
}
|
||||
$it->next();
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return $component->isInTimeRange($start, $end);
|
||||
}
|
||||
|
||||
// no break
|
||||
case 'VFREEBUSY':
|
||||
throw new \Sabre\DAV\Exception\NotImplemented('time-range filters are currently not supported on '.$component->name.' components');
|
||||
case 'COMPLETED':
|
||||
case 'CREATED':
|
||||
case 'DTEND':
|
||||
case 'DTSTAMP':
|
||||
case 'DTSTART':
|
||||
case 'DUE':
|
||||
case 'LAST-MODIFIED':
|
||||
return $start <= $component->getDateTime() && $end >= $component->getDateTime();
|
||||
|
||||
default:
|
||||
throw new \Sabre\DAV\Exception\BadRequest('You cannot create a time-range filter on a '.$component->name.' component');
|
||||
}
|
||||
}
|
||||
}
|
||||
75
lib/composer/vendor/sabre/dav/lib/CalDAV/CalendarRoot.php
vendored
Normal file
75
lib/composer/vendor/sabre/dav/lib/CalDAV/CalendarRoot.php
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use Sabre\DAVACL\PrincipalBackend;
|
||||
|
||||
/**
|
||||
* Calendars collection.
|
||||
*
|
||||
* This object is responsible for generating a list of calendar-homes for each
|
||||
* user.
|
||||
*
|
||||
* This is the top-most node for the calendars tree. In most servers this class
|
||||
* represents the "/calendars" path.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class CalendarRoot extends \Sabre\DAVACL\AbstractPrincipalCollection
|
||||
{
|
||||
/**
|
||||
* CalDAV backend.
|
||||
*
|
||||
* @var Backend\BackendInterface
|
||||
*/
|
||||
protected $caldavBackend;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* This constructor needs both an authentication and a caldav backend.
|
||||
*
|
||||
* By default this class will show a list of calendar collections for
|
||||
* principals in the 'principals' collection. If your main principals are
|
||||
* actually located in a different path, use the $principalPrefix argument
|
||||
* to override this.
|
||||
*
|
||||
* @param string $principalPrefix
|
||||
*/
|
||||
public function __construct(PrincipalBackend\BackendInterface $principalBackend, Backend\BackendInterface $caldavBackend, $principalPrefix = 'principals')
|
||||
{
|
||||
parent::__construct($principalBackend, $principalPrefix);
|
||||
$this->caldavBackend = $caldavBackend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nodename.
|
||||
*
|
||||
* We're overriding this, because the default will be the 'principalPrefix',
|
||||
* and we want it to be Sabre\CalDAV\Plugin::CALENDAR_ROOT
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return Plugin::CALENDAR_ROOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a node for a principal.
|
||||
*
|
||||
* The passed array contains principal information, and is guaranteed to
|
||||
* at least contain a uri item. Other properties may or may not be
|
||||
* supplied by the authentication backend.
|
||||
*
|
||||
* @return \Sabre\DAV\INode
|
||||
*/
|
||||
public function getChildForPrincipal(array $principal)
|
||||
{
|
||||
return new CalendarHome($this->caldavBackend, $principal);
|
||||
}
|
||||
}
|
||||
31
lib/composer/vendor/sabre/dav/lib/CalDAV/Exception/InvalidComponentType.php
vendored
Normal file
31
lib/composer/vendor/sabre/dav/lib/CalDAV/Exception/InvalidComponentType.php
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Exception;
|
||||
|
||||
use Sabre\CalDAV;
|
||||
use Sabre\DAV;
|
||||
|
||||
/**
|
||||
* InvalidComponentType.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class InvalidComponentType extends DAV\Exception\Forbidden
|
||||
{
|
||||
/**
|
||||
* Adds in extra information in the xml response.
|
||||
*
|
||||
* This method adds the {CALDAV:}supported-calendar-component as defined in rfc4791
|
||||
*/
|
||||
public function serialize(DAV\Server $server, \DOMElement $errorNode)
|
||||
{
|
||||
$doc = $errorNode->ownerDocument;
|
||||
|
||||
$np = $doc->createElementNS(CalDAV\Plugin::NS_CALDAV, 'cal:supported-calendar-component');
|
||||
$errorNode->appendChild($np);
|
||||
}
|
||||
}
|
||||
377
lib/composer/vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php
vendored
Normal file
377
lib/composer/vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php
vendored
Normal file
|
|
@ -0,0 +1,377 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
use Sabre\DAV;
|
||||
use Sabre\DAV\Exception\BadRequest;
|
||||
use Sabre\HTTP\RequestInterface;
|
||||
use Sabre\HTTP\ResponseInterface;
|
||||
use Sabre\VObject;
|
||||
|
||||
/**
|
||||
* ICS Exporter.
|
||||
*
|
||||
* This plugin adds the ability to export entire calendars as .ics files.
|
||||
* This is useful for clients that don't support CalDAV yet. They often do
|
||||
* support ics files.
|
||||
*
|
||||
* To use this, point a http client to a caldav calendar, and add ?expand to
|
||||
* the url.
|
||||
*
|
||||
* Further options that can be added to the url:
|
||||
* start=123456789 - Only return events after the given unix timestamp
|
||||
* end=123245679 - Only return events from before the given unix timestamp
|
||||
* expand=1 - Strip timezone information and expand recurring events.
|
||||
* If you'd like to expand, you _must_ also specify start
|
||||
* and end.
|
||||
*
|
||||
* By default this plugin returns data in the text/calendar format (iCalendar
|
||||
* 2.0). If you'd like to receive jCal data instead, you can use an Accept
|
||||
* header:
|
||||
*
|
||||
* Accept: application/calendar+json
|
||||
*
|
||||
* Alternatively, you can also specify this in the url using
|
||||
* accept=application/calendar+json, or accept=jcal for short. If the url
|
||||
* parameter and Accept header is specified, the url parameter wins.
|
||||
*
|
||||
* Note that specifying a start or end data implies that only events will be
|
||||
* returned. VTODO and VJOURNAL will be stripped.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class ICSExportPlugin extends DAV\ServerPlugin
|
||||
{
|
||||
/**
|
||||
* Reference to Server class.
|
||||
*
|
||||
* @var \Sabre\DAV\Server
|
||||
*/
|
||||
protected $server;
|
||||
|
||||
/**
|
||||
* Initializes the plugin and registers event handlers.
|
||||
*
|
||||
* @param \Sabre\DAV\Server $server
|
||||
*/
|
||||
public function initialize(DAV\Server $server)
|
||||
{
|
||||
$this->server = $server;
|
||||
$server->on('method:GET', [$this, 'httpGet'], 90);
|
||||
$server->on('browserButtonActions', function ($path, $node, &$actions) {
|
||||
if ($node instanceof ICalendar) {
|
||||
$actions .= '<a href="'.htmlspecialchars($path, ENT_QUOTES, 'UTF-8').'?export"><span class="oi" data-glyph="calendar"></span></a>';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Intercepts GET requests on calendar urls ending with ?export.
|
||||
*
|
||||
* @throws BadRequest
|
||||
* @throws DAV\Exception\NotFound
|
||||
* @throws VObject\InvalidDataException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function httpGet(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
$queryParams = $request->getQueryParameters();
|
||||
if (!array_key_exists('export', $queryParams)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$path = $request->getPath();
|
||||
|
||||
$node = $this->server->getProperties($path, [
|
||||
'{DAV:}resourcetype',
|
||||
'{DAV:}displayname',
|
||||
'{http://sabredav.org/ns}sync-token',
|
||||
'{DAV:}sync-token',
|
||||
'{http://apple.com/ns/ical/}calendar-color',
|
||||
]);
|
||||
|
||||
if (!isset($node['{DAV:}resourcetype']) || !$node['{DAV:}resourcetype']->is('{'.Plugin::NS_CALDAV.'}calendar')) {
|
||||
return;
|
||||
}
|
||||
// Marking the transactionType, for logging purposes.
|
||||
$this->server->transactionType = 'get-calendar-export';
|
||||
|
||||
$properties = $node;
|
||||
|
||||
$start = null;
|
||||
$end = null;
|
||||
$expand = false;
|
||||
$componentType = false;
|
||||
if (isset($queryParams['start'])) {
|
||||
if (!ctype_digit($queryParams['start'])) {
|
||||
throw new BadRequest('The start= parameter must contain a unix timestamp');
|
||||
}
|
||||
$start = DateTime::createFromFormat('U', $queryParams['start']);
|
||||
}
|
||||
if (isset($queryParams['end'])) {
|
||||
if (!ctype_digit($queryParams['end'])) {
|
||||
throw new BadRequest('The end= parameter must contain a unix timestamp');
|
||||
}
|
||||
$end = DateTime::createFromFormat('U', $queryParams['end']);
|
||||
}
|
||||
if (isset($queryParams['expand']) && (bool) $queryParams['expand']) {
|
||||
if (!$start || !$end) {
|
||||
throw new BadRequest('If you\'d like to expand recurrences, you must specify both a start= and end= parameter.');
|
||||
}
|
||||
$expand = true;
|
||||
$componentType = 'VEVENT';
|
||||
}
|
||||
if (isset($queryParams['componentType'])) {
|
||||
if (!in_array($queryParams['componentType'], ['VEVENT', 'VTODO', 'VJOURNAL'])) {
|
||||
throw new BadRequest('You are not allowed to search for components of type: '.$queryParams['componentType'].' here');
|
||||
}
|
||||
$componentType = $queryParams['componentType'];
|
||||
}
|
||||
|
||||
$format = \Sabre\HTTP\negotiateContentType(
|
||||
$request->getHeader('Accept'),
|
||||
[
|
||||
'text/calendar',
|
||||
'application/calendar+json',
|
||||
]
|
||||
);
|
||||
|
||||
if (isset($queryParams['accept'])) {
|
||||
if ('application/calendar+json' === $queryParams['accept'] || 'jcal' === $queryParams['accept']) {
|
||||
$format = 'application/calendar+json';
|
||||
}
|
||||
}
|
||||
if (!$format) {
|
||||
$format = 'text/calendar';
|
||||
}
|
||||
|
||||
$this->generateResponse($path, $start, $end, $expand, $componentType, $format, $properties, $response);
|
||||
|
||||
// Returning false to break the event chain
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is responsible for generating the actual, full response.
|
||||
*
|
||||
* @param string $path
|
||||
* @param DateTime|null $start
|
||||
* @param DateTime|null $end
|
||||
* @param bool $expand
|
||||
* @param string $componentType
|
||||
* @param string $format
|
||||
* @param array $properties
|
||||
*
|
||||
* @throws DAV\Exception\NotFound
|
||||
* @throws VObject\InvalidDataException
|
||||
*/
|
||||
protected function generateResponse($path, $start, $end, $expand, $componentType, $format, $properties, ResponseInterface $response)
|
||||
{
|
||||
$calDataProp = '{'.Plugin::NS_CALDAV.'}calendar-data';
|
||||
$calendarNode = $this->server->tree->getNodeForPath($path);
|
||||
|
||||
$blobs = [];
|
||||
if ($start || $end || $componentType) {
|
||||
// If there was a start or end filter, we need to enlist
|
||||
// calendarQuery for speed.
|
||||
$queryResult = $calendarNode->calendarQuery([
|
||||
'name' => 'VCALENDAR',
|
||||
'comp-filters' => [
|
||||
[
|
||||
'name' => $componentType,
|
||||
'comp-filters' => [],
|
||||
'prop-filters' => [],
|
||||
'is-not-defined' => false,
|
||||
'time-range' => [
|
||||
'start' => $start,
|
||||
'end' => $end,
|
||||
],
|
||||
],
|
||||
],
|
||||
'prop-filters' => [],
|
||||
'is-not-defined' => false,
|
||||
'time-range' => null,
|
||||
]);
|
||||
|
||||
// queryResult is just a list of base urls. We need to prefix the
|
||||
// calendar path.
|
||||
$queryResult = array_map(
|
||||
function ($item) use ($path) {
|
||||
return $path.'/'.$item;
|
||||
},
|
||||
$queryResult
|
||||
);
|
||||
$nodes = $this->server->getPropertiesForMultiplePaths($queryResult, [$calDataProp]);
|
||||
unset($queryResult);
|
||||
} else {
|
||||
$nodes = $this->server->getPropertiesForPath($path, [$calDataProp], 1);
|
||||
}
|
||||
|
||||
// Flattening the arrays
|
||||
foreach ($nodes as $node) {
|
||||
if (isset($node[200][$calDataProp])) {
|
||||
$blobs[$node['href']] = $node[200][$calDataProp];
|
||||
}
|
||||
}
|
||||
unset($nodes);
|
||||
|
||||
$mergedCalendar = $this->mergeObjects(
|
||||
$properties,
|
||||
$blobs
|
||||
);
|
||||
|
||||
if ($expand) {
|
||||
$calendarTimeZone = null;
|
||||
// We're expanding, and for that we need to figure out the
|
||||
// calendar's timezone.
|
||||
$tzProp = '{'.Plugin::NS_CALDAV.'}calendar-timezone';
|
||||
$tzResult = $this->server->getProperties($path, [$tzProp]);
|
||||
if (isset($tzResult[$tzProp])) {
|
||||
// This property contains a VCALENDAR with a single
|
||||
// VTIMEZONE.
|
||||
$vtimezoneObj = VObject\Reader::read($tzResult[$tzProp]);
|
||||
$calendarTimeZone = $vtimezoneObj->VTIMEZONE->getTimeZone();
|
||||
// Destroy circular references to PHP will GC the object.
|
||||
$vtimezoneObj->destroy();
|
||||
unset($vtimezoneObj);
|
||||
} else {
|
||||
// Defaulting to UTC.
|
||||
$calendarTimeZone = new DateTimeZone('UTC');
|
||||
}
|
||||
|
||||
$mergedCalendar = $mergedCalendar->expand($start, $end, $calendarTimeZone);
|
||||
}
|
||||
|
||||
$filenameExtension = '.ics';
|
||||
|
||||
switch ($format) {
|
||||
case 'text/calendar':
|
||||
$mergedCalendar = $mergedCalendar->serialize();
|
||||
$filenameExtension = '.ics';
|
||||
break;
|
||||
case 'application/calendar+json':
|
||||
$mergedCalendar = json_encode($mergedCalendar->jsonSerialize());
|
||||
$filenameExtension = '.json';
|
||||
break;
|
||||
}
|
||||
|
||||
$filename = preg_replace(
|
||||
'/[^a-zA-Z0-9-_ ]/um',
|
||||
'',
|
||||
$calendarNode->getName()
|
||||
);
|
||||
$filename .= '-'.date('Y-m-d').$filenameExtension;
|
||||
|
||||
$response->setHeader('Content-Disposition', 'attachment; filename="'.$filename.'"');
|
||||
$response->setHeader('Content-Type', $format);
|
||||
|
||||
$response->setStatus(200);
|
||||
$response->setBody($mergedCalendar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges all calendar objects, and builds one big iCalendar blob.
|
||||
*
|
||||
* @param array $properties Some CalDAV properties
|
||||
*
|
||||
* @return VObject\Component\VCalendar
|
||||
*/
|
||||
public function mergeObjects(array $properties, array $inputObjects)
|
||||
{
|
||||
$calendar = new VObject\Component\VCalendar();
|
||||
$calendar->VERSION = '2.0';
|
||||
if (DAV\Server::$exposeVersion) {
|
||||
$calendar->PRODID = '-//SabreDAV//SabreDAV '.DAV\Version::VERSION.'//EN';
|
||||
} else {
|
||||
$calendar->PRODID = '-//SabreDAV//SabreDAV//EN';
|
||||
}
|
||||
if (isset($properties['{DAV:}displayname'])) {
|
||||
$calendar->{'X-WR-CALNAME'} = $properties['{DAV:}displayname'];
|
||||
}
|
||||
if (isset($properties['{http://apple.com/ns/ical/}calendar-color'])) {
|
||||
$calendar->{'X-APPLE-CALENDAR-COLOR'} = $properties['{http://apple.com/ns/ical/}calendar-color'];
|
||||
}
|
||||
|
||||
$collectedTimezones = [];
|
||||
|
||||
$timezones = [];
|
||||
$objects = [];
|
||||
|
||||
foreach ($inputObjects as $href => $inputObject) {
|
||||
$nodeComp = VObject\Reader::read($inputObject);
|
||||
|
||||
foreach ($nodeComp->children() as $child) {
|
||||
switch ($child->name) {
|
||||
case 'VEVENT':
|
||||
case 'VTODO':
|
||||
case 'VJOURNAL':
|
||||
$objects[] = clone $child;
|
||||
break;
|
||||
|
||||
// VTIMEZONE is special, because we need to filter out the duplicates
|
||||
case 'VTIMEZONE':
|
||||
// Naively just checking tzid.
|
||||
if (in_array((string) $child->TZID, $collectedTimezones)) {
|
||||
break;
|
||||
}
|
||||
|
||||
$timezones[] = clone $child;
|
||||
$collectedTimezones[] = $child->TZID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Destroy circular references to PHP will GC the object.
|
||||
$nodeComp->destroy();
|
||||
unset($nodeComp);
|
||||
}
|
||||
|
||||
foreach ($timezones as $tz) {
|
||||
$calendar->add($tz);
|
||||
}
|
||||
foreach ($objects as $obj) {
|
||||
$calendar->add($obj);
|
||||
}
|
||||
|
||||
return $calendar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a plugin name.
|
||||
*
|
||||
* Using this name other plugins will be able to access other plugins
|
||||
* using \Sabre\DAV\Server::getPlugin
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPluginName()
|
||||
{
|
||||
return 'ics-export';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a bunch of meta-data about the plugin.
|
||||
*
|
||||
* Providing this information is optional, and is mainly displayed by the
|
||||
* Browser plugin.
|
||||
*
|
||||
* The description key in the returned array may contain html and will not
|
||||
* be sanitized.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPluginInfo()
|
||||
{
|
||||
return [
|
||||
'name' => $this->getPluginName(),
|
||||
'description' => 'Adds the ability to export CalDAV calendars as a single iCalendar file.',
|
||||
'link' => 'http://sabre.io/dav/ics-export-plugin/',
|
||||
];
|
||||
}
|
||||
}
|
||||
20
lib/composer/vendor/sabre/dav/lib/CalDAV/ICalendar.php
vendored
Normal file
20
lib/composer/vendor/sabre/dav/lib/CalDAV/ICalendar.php
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* Calendar interface.
|
||||
*
|
||||
* Implement this interface to allow a node to be recognized as an calendar.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface ICalendar extends ICalendarObjectContainer, DAVACL\IACL
|
||||
{
|
||||
}
|
||||
23
lib/composer/vendor/sabre/dav/lib/CalDAV/ICalendarObject.php
vendored
Normal file
23
lib/composer/vendor/sabre/dav/lib/CalDAV/ICalendarObject.php
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
||||
/**
|
||||
* CalendarObject interface.
|
||||
*
|
||||
* Extend the ICalendarObject interface to allow your custom nodes to be picked up as
|
||||
* CalendarObjects.
|
||||
*
|
||||
* Calendar objects are resources such as Events, Todo's or Journals.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface ICalendarObject extends DAV\IFile
|
||||
{
|
||||
}
|
||||
39
lib/composer/vendor/sabre/dav/lib/CalDAV/ICalendarObjectContainer.php
vendored
Normal file
39
lib/composer/vendor/sabre/dav/lib/CalDAV/ICalendarObjectContainer.php
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
/**
|
||||
* This interface represents a node that may contain calendar objects.
|
||||
*
|
||||
* This is the shared parent for both the Inbox collection and calendars
|
||||
* resources.
|
||||
*
|
||||
* In most cases you will likely want to look at ICalendar instead of this
|
||||
* interface.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface ICalendarObjectContainer extends \Sabre\DAV\ICollection
|
||||
{
|
||||
/**
|
||||
* Performs a calendar-query on the contents of this calendar.
|
||||
*
|
||||
* The calendar-query is defined in RFC4791 : CalDAV. Using the
|
||||
* calendar-query it is possible for a client to request a specific set of
|
||||
* object, based on contents of iCalendar properties, date-ranges and
|
||||
* iCalendar component types (VTODO, VEVENT).
|
||||
*
|
||||
* This method should just return a list of (relative) urls that match this
|
||||
* query.
|
||||
*
|
||||
* The list of filters are specified as an array. The exact array is
|
||||
* documented by \Sabre\CalDAV\CalendarQueryParser.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function calendarQuery(array $filters);
|
||||
}
|
||||
27
lib/composer/vendor/sabre/dav/lib/CalDAV/ISharedCalendar.php
vendored
Normal file
27
lib/composer/vendor/sabre/dav/lib/CalDAV/ISharedCalendar.php
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use Sabre\DAV\Sharing\ISharedNode;
|
||||
|
||||
/**
|
||||
* This interface represents a Calendar that is shared by a different user.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface ISharedCalendar extends ISharedNode
|
||||
{
|
||||
/**
|
||||
* Marks this calendar as published.
|
||||
*
|
||||
* Publishing a calendar should automatically create a read-only, public,
|
||||
* subscribable calendar.
|
||||
*
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setPublishStatus($value);
|
||||
}
|
||||
96
lib/composer/vendor/sabre/dav/lib/CalDAV/Notifications/Collection.php
vendored
Normal file
96
lib/composer/vendor/sabre/dav/lib/CalDAV/Notifications/Collection.php
vendored
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Notifications;
|
||||
|
||||
use Sabre\CalDAV;
|
||||
use Sabre\DAV;
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* This node represents a list of notifications.
|
||||
*
|
||||
* It provides no additional functionality, but you must implement this
|
||||
* interface to allow the Notifications plugin to mark the collection
|
||||
* as a notifications collection.
|
||||
*
|
||||
* This collection should only return Sabre\CalDAV\Notifications\INode nodes as
|
||||
* its children.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Collection extends DAV\Collection implements ICollection, DAVACL\IACL
|
||||
{
|
||||
use DAVACL\ACLTrait;
|
||||
|
||||
/**
|
||||
* The notification backend.
|
||||
*
|
||||
* @var CalDAV\Backend\NotificationSupport
|
||||
*/
|
||||
protected $caldavBackend;
|
||||
|
||||
/**
|
||||
* Principal uri.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $principalUri;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $principalUri
|
||||
*/
|
||||
public function __construct(CalDAV\Backend\NotificationSupport $caldavBackend, $principalUri)
|
||||
{
|
||||
$this->caldavBackend = $caldavBackend;
|
||||
$this->principalUri = $principalUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all notifications for a principal.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getChildren()
|
||||
{
|
||||
$children = [];
|
||||
$notifications = $this->caldavBackend->getNotificationsForPrincipal($this->principalUri);
|
||||
|
||||
foreach ($notifications as $notification) {
|
||||
$children[] = new Node(
|
||||
$this->caldavBackend,
|
||||
$this->principalUri,
|
||||
$notification
|
||||
);
|
||||
}
|
||||
|
||||
return $children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'notifications';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal.
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->principalUri;
|
||||
}
|
||||
}
|
||||
25
lib/composer/vendor/sabre/dav/lib/CalDAV/Notifications/ICollection.php
vendored
Normal file
25
lib/composer/vendor/sabre/dav/lib/CalDAV/Notifications/ICollection.php
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Notifications;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
||||
/**
|
||||
* This node represents a list of notifications.
|
||||
*
|
||||
* It provides no additional functionality, but you must implement this
|
||||
* interface to allow the Notifications plugin to mark the collection
|
||||
* as a notifications collection.
|
||||
*
|
||||
* This collection should only return Sabre\CalDAV\Notifications\INode nodes as
|
||||
* its children.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface ICollection extends DAV\ICollection
|
||||
{
|
||||
}
|
||||
41
lib/composer/vendor/sabre/dav/lib/CalDAV/Notifications/INode.php
vendored
Normal file
41
lib/composer/vendor/sabre/dav/lib/CalDAV/Notifications/INode.php
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Notifications;
|
||||
|
||||
use Sabre\CalDAV\Xml\Notification\NotificationInterface;
|
||||
|
||||
/**
|
||||
* This node represents a single notification.
|
||||
*
|
||||
* The signature is mostly identical to that of Sabre\DAV\IFile, but the get() method
|
||||
* MUST return an xml document that matches the requirements of the
|
||||
* 'caldav-notifications.txt' spec.
|
||||
*
|
||||
* For a complete example, check out the Notification class, which contains
|
||||
* some helper functions.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface INode
|
||||
{
|
||||
/**
|
||||
* This method must return an xml element, using the
|
||||
* Sabre\CalDAV\Xml\Notification\NotificationInterface classes.
|
||||
*
|
||||
* @return NotificationInterface
|
||||
*/
|
||||
public function getNotificationType();
|
||||
|
||||
/**
|
||||
* Returns the etag for the notification.
|
||||
*
|
||||
* The etag must be surrounded by literal double-quotes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getETag();
|
||||
}
|
||||
112
lib/composer/vendor/sabre/dav/lib/CalDAV/Notifications/Node.php
vendored
Normal file
112
lib/composer/vendor/sabre/dav/lib/CalDAV/Notifications/Node.php
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Notifications;
|
||||
|
||||
use Sabre\CalDAV;
|
||||
use Sabre\CalDAV\Xml\Notification\NotificationInterface;
|
||||
use Sabre\DAV;
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* This node represents a single notification.
|
||||
*
|
||||
* The signature is mostly identical to that of Sabre\DAV\IFile, but the get() method
|
||||
* MUST return an xml document that matches the requirements of the
|
||||
* 'caldav-notifications.txt' spec.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Node extends DAV\File implements INode, DAVACL\IACL
|
||||
{
|
||||
use DAVACL\ACLTrait;
|
||||
|
||||
/**
|
||||
* The notification backend.
|
||||
*
|
||||
* @var CalDAV\Backend\NotificationSupport
|
||||
*/
|
||||
protected $caldavBackend;
|
||||
|
||||
/**
|
||||
* The actual notification.
|
||||
*
|
||||
* @var NotificationInterface
|
||||
*/
|
||||
protected $notification;
|
||||
|
||||
/**
|
||||
* Owner principal of the notification.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $principalUri;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $principalUri
|
||||
*/
|
||||
public function __construct(CalDAV\Backend\NotificationSupport $caldavBackend, $principalUri, NotificationInterface $notification)
|
||||
{
|
||||
$this->caldavBackend = $caldavBackend;
|
||||
$this->principalUri = $principalUri;
|
||||
$this->notification = $notification;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path name for this notification.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->notification->getId().'.xml';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the etag for the notification.
|
||||
*
|
||||
* The etag must be surrounded by literal double-quotes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getETag()
|
||||
{
|
||||
return $this->notification->getETag();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method must return an xml element, using the
|
||||
* Sabre\CalDAV\Xml\Notification\NotificationInterface classes.
|
||||
*
|
||||
* @return NotificationInterface
|
||||
*/
|
||||
public function getNotificationType()
|
||||
{
|
||||
return $this->notification;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes this notification.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$this->caldavBackend->deleteNotification($this->getOwner(), $this->notification);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal.
|
||||
*
|
||||
* This must be an url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->principalUri;
|
||||
}
|
||||
}
|
||||
161
lib/composer/vendor/sabre/dav/lib/CalDAV/Notifications/Plugin.php
vendored
Normal file
161
lib/composer/vendor/sabre/dav/lib/CalDAV/Notifications/Plugin.php
vendored
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Notifications;
|
||||
|
||||
use Sabre\DAV;
|
||||
use Sabre\DAV\INode as BaseINode;
|
||||
use Sabre\DAV\PropFind;
|
||||
use Sabre\DAV\Server;
|
||||
use Sabre\DAV\ServerPlugin;
|
||||
use Sabre\DAVACL;
|
||||
use Sabre\HTTP\RequestInterface;
|
||||
use Sabre\HTTP\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Notifications plugin.
|
||||
*
|
||||
* This plugin implements several features required by the caldav-notification
|
||||
* draft specification.
|
||||
*
|
||||
* Before version 2.1.0 this functionality was part of Sabre\CalDAV\Plugin but
|
||||
* this has since been split up.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Plugin extends ServerPlugin
|
||||
{
|
||||
/**
|
||||
* This is the namespace for the proprietary calendarserver extensions.
|
||||
*/
|
||||
const NS_CALENDARSERVER = 'http://calendarserver.org/ns/';
|
||||
|
||||
/**
|
||||
* Reference to the main server object.
|
||||
*
|
||||
* @var Server
|
||||
*/
|
||||
protected $server;
|
||||
|
||||
/**
|
||||
* Returns a plugin name.
|
||||
*
|
||||
* Using this name other plugins will be able to access other plugins
|
||||
* using \Sabre\DAV\Server::getPlugin
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPluginName()
|
||||
{
|
||||
return 'notifications';
|
||||
}
|
||||
|
||||
/**
|
||||
* This initializes the plugin.
|
||||
*
|
||||
* This function is called by Sabre\DAV\Server, after
|
||||
* addPlugin is called.
|
||||
*
|
||||
* This method should set up the required event subscriptions.
|
||||
*/
|
||||
public function initialize(Server $server)
|
||||
{
|
||||
$this->server = $server;
|
||||
$server->on('method:GET', [$this, 'httpGet'], 90);
|
||||
$server->on('propFind', [$this, 'propFind']);
|
||||
|
||||
$server->xml->namespaceMap[self::NS_CALENDARSERVER] = 'cs';
|
||||
$server->resourceTypeMapping['\\Sabre\\CalDAV\\Notifications\\ICollection'] = '{'.self::NS_CALENDARSERVER.'}notification';
|
||||
|
||||
array_push($server->protectedProperties,
|
||||
'{'.self::NS_CALENDARSERVER.'}notification-URL',
|
||||
'{'.self::NS_CALENDARSERVER.'}notificationtype'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* PropFind.
|
||||
*/
|
||||
public function propFind(PropFind $propFind, BaseINode $node)
|
||||
{
|
||||
$caldavPlugin = $this->server->getPlugin('caldav');
|
||||
|
||||
if ($node instanceof DAVACL\IPrincipal) {
|
||||
$principalUrl = $node->getPrincipalUrl();
|
||||
|
||||
// notification-URL property
|
||||
$propFind->handle('{'.self::NS_CALENDARSERVER.'}notification-URL', function () use ($principalUrl, $caldavPlugin) {
|
||||
$notificationPath = $caldavPlugin->getCalendarHomeForPrincipal($principalUrl).'/notifications/';
|
||||
|
||||
return new DAV\Xml\Property\Href($notificationPath);
|
||||
});
|
||||
}
|
||||
|
||||
if ($node instanceof INode) {
|
||||
$propFind->handle(
|
||||
'{'.self::NS_CALENDARSERVER.'}notificationtype',
|
||||
[$node, 'getNotificationType']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This event is triggered before the usual GET request handler.
|
||||
*
|
||||
* We use this to intercept GET calls to notification nodes, and return the
|
||||
* proper response.
|
||||
*/
|
||||
public function httpGet(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
$path = $request->getPath();
|
||||
|
||||
try {
|
||||
$node = $this->server->tree->getNodeForPath($path);
|
||||
} catch (DAV\Exception\NotFound $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$node instanceof INode) {
|
||||
return;
|
||||
}
|
||||
|
||||
$writer = $this->server->xml->getWriter();
|
||||
$writer->contextUri = $this->server->getBaseUri();
|
||||
$writer->openMemory();
|
||||
$writer->startDocument('1.0', 'UTF-8');
|
||||
$writer->startElement('{http://calendarserver.org/ns/}notification');
|
||||
$node->getNotificationType()->xmlSerializeFull($writer);
|
||||
$writer->endElement();
|
||||
|
||||
$response->setHeader('Content-Type', 'application/xml');
|
||||
$response->setHeader('ETag', $node->getETag());
|
||||
$response->setStatus(200);
|
||||
$response->setBody($writer->outputMemory());
|
||||
|
||||
// Return false to break the event chain.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a bunch of meta-data about the plugin.
|
||||
*
|
||||
* Providing this information is optional, and is mainly displayed by the
|
||||
* Browser plugin.
|
||||
*
|
||||
* The description key in the returned array may contain html and will not
|
||||
* be sanitized.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPluginInfo()
|
||||
{
|
||||
return [
|
||||
'name' => $this->getPluginName(),
|
||||
'description' => 'Adds support for caldav-notifications, which is required to enable caldav-sharing.',
|
||||
'link' => 'http://sabre.io/dav/caldav-sharing/',
|
||||
];
|
||||
}
|
||||
}
|
||||
1011
lib/composer/vendor/sabre/dav/lib/CalDAV/Plugin.php
vendored
Normal file
1011
lib/composer/vendor/sabre/dav/lib/CalDAV/Plugin.php
vendored
Normal file
File diff suppressed because it is too large
Load diff
32
lib/composer/vendor/sabre/dav/lib/CalDAV/Principal/Collection.php
vendored
Normal file
32
lib/composer/vendor/sabre/dav/lib/CalDAV/Principal/Collection.php
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Principal;
|
||||
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* Principal collection.
|
||||
*
|
||||
* This is an alternative collection to the standard ACL principal collection.
|
||||
* This collection adds support for the calendar-proxy-read and
|
||||
* calendar-proxy-write sub-principals, as defined by the caldav-proxy
|
||||
* specification.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Collection extends DAVACL\PrincipalCollection
|
||||
{
|
||||
/**
|
||||
* Returns a child object based on principal information.
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function getChildForPrincipal(array $principalInfo)
|
||||
{
|
||||
return new User($this->principalBackend, $principalInfo);
|
||||
}
|
||||
}
|
||||
21
lib/composer/vendor/sabre/dav/lib/CalDAV/Principal/IProxyRead.php
vendored
Normal file
21
lib/composer/vendor/sabre/dav/lib/CalDAV/Principal/IProxyRead.php
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Principal;
|
||||
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* ProxyRead principal interface.
|
||||
*
|
||||
* Any principal node implementing this interface will be picked up as a 'proxy
|
||||
* principal group'.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface IProxyRead extends DAVACL\IPrincipal
|
||||
{
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue