first commit
This commit is contained in:
11
vendor/johngrogg/ics-parser/.editorconfig
vendored
Normal file
11
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
vendor/johngrogg/ics-parser/.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
53
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
vendor/johngrogg/ics-parser/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
vendored
Normal file
12
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
vendor/johngrogg/ics-parser/.github/dependabot.yml
vendored
Normal file
13
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
vendor/johngrogg/ics-parser/.github/release_template.md
vendored
Normal file
9
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
vendor/johngrogg/ics-parser/.github/workflows/coding-standards.yml
vendored
Normal file
67
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]
|
||||
|
||||
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.2
|
||||
|
||||
- name: Execute PHPCodeSniffer
|
||||
run: vendor/bin/phpcs -n -s --standard=psr12 src
|
||||
if: matrix.php == 8.2
|
||||
|
||||
- name: Execute Rector
|
||||
run: vendor/bin/rector process src --dry-run
|
||||
if: matrix.php == 8.2
|
||||
|
||||
- name: Execute ECS
|
||||
run: vendor/bin/ecs check .
|
||||
if: matrix.php == 8.2
|
||||
|
||||
- name: Execute PHPStan
|
||||
run: vendor/bin/phpstan analyse src
|
||||
if: matrix.php == 8.2
|
||||
59
vendor/johngrogg/ics-parser/.gitignore
vendored
Normal file
59
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
vendor/johngrogg/ics-parser/CONTRIBUTING.md
vendored
Normal file
18
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
vendor/johngrogg/ics-parser/FUNDING.yml
vendored
Normal file
1
vendor/johngrogg/ics-parser/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
github: u01jmg3
|
||||
15
vendor/johngrogg/ics-parser/LICENSE
vendored
Normal file
15
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.
|
||||
255
vendor/johngrogg/ics-parser/README.md
vendored
Normal file
255
vendor/johngrogg/ics-parser/README.md
vendored
Normal file
@@ -0,0 +1,255 @@
|
||||
# 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 |
|
||||
| `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`, `$format = 'U'` | `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://jakubroztocil.github.io/rrule/)
|
||||
- [Unix Timestamp Converter](https://www.unixtimestamp.com)
|
||||
49
vendor/johngrogg/ics-parser/composer.json
vendored
Normal file
49
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"
|
||||
]
|
||||
}
|
||||
}
|
||||
1754
vendor/johngrogg/ics-parser/composer.lock
generated
vendored
Normal file
1754
vendor/johngrogg/ics-parser/composer.lock
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
205
vendor/johngrogg/ics-parser/ecs.php
vendored
Normal file
205
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
vendor/johngrogg/ics-parser/examples/ICal.ics
vendored
Normal file
338
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
vendor/johngrogg/ics-parser/examples/index.php
vendored
Normal file
175
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>
|
||||
7
vendor/johngrogg/ics-parser/phpstan.neon.dist
vendored
Normal file
7
vendor/johngrogg/ics-parser/phpstan.neon.dist
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
parameters:
|
||||
paths:
|
||||
- src
|
||||
|
||||
level: 6
|
||||
|
||||
checkMissingIterableValueType: false
|
||||
7
vendor/johngrogg/ics-parser/phpunit.xml
vendored
Normal file
7
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>
|
||||
86
vendor/johngrogg/ics-parser/rector.php
vendored
Normal file
86
vendor/johngrogg/ics-parser/rector.php
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Config\RectorConfig;
|
||||
use Rector\Core\ValueObject\PhpVersion;
|
||||
use Rector\Php53\Rector\Ternary\TernaryToElvisRector;
|
||||
use Rector\Set\ValueObject\SetList;
|
||||
|
||||
// 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\FuncCall\IntvalToTypeCastRector::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\ClassMethod\UnSpreadOperatorRector::class,
|
||||
Rector\CodingStyle\Rector\Closure\StaticClosureRector::class,
|
||||
Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector::class,
|
||||
Rector\CodingStyle\Rector\PostInc\PostIncDecToPreIncDecRector::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\Php71\Rector\FuncCall\CountOnNullRector::class,
|
||||
Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
|
||||
Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
|
||||
Rector\Transform\Rector\String_\StringToClassConstantRector::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\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
|
||||
Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::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);
|
||||
};
|
||||
259
vendor/johngrogg/ics-parser/src/ICal/Event.php
vendored
Normal file
259
vendor/johngrogg/ics-parser/src/ICal/Event.php
vendored
Normal file
@@ -0,0 +1,259 @@
|
||||
<?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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public $description;
|
||||
|
||||
/**
|
||||
* https://www.kanzaki.com/docs/ical/location.html
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
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>
|
||||
*/
|
||||
private $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 = '-')
|
||||
{
|
||||
$input = preg_split('/(?<=[a-z])(?=[A-Z])/x', $input);
|
||||
$input = implode($glue, $input);
|
||||
$input = str_replace($separator, $glue, $input);
|
||||
|
||||
return strtolower($input);
|
||||
}
|
||||
}
|
||||
2658
vendor/johngrogg/ics-parser/src/ICal/ICal.php
vendored
Normal file
2658
vendor/johngrogg/ics-parser/src/ICal/ICal.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
32
vendor/johngrogg/ics-parser/tests/CleanCharacterTest.php
vendored
Normal file
32
vendor/johngrogg/ics-parser/tests/CleanCharacterTest.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?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 testCleanCharacters()
|
||||
{
|
||||
$ical = new ICal();
|
||||
$input = 'Test with emoji 🔴👍🏻';
|
||||
|
||||
self::assertSame(
|
||||
self::getMethod('cleanCharacters')->invokeArgs($ical, array($input)),
|
||||
$input
|
||||
);
|
||||
}
|
||||
}
|
||||
24
vendor/johngrogg/ics-parser/tests/DynamicPropertiesTest.php
vendored
Normal file
24
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
vendor/johngrogg/ics-parser/tests/KeyValueTest.php
vendored
Normal file
86
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
vendor/johngrogg/ics-parser/tests/RecurrencesTest.php
vendored
Normal file
580
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
vendor/johngrogg/ics-parser/tests/Rfc5545RecurrenceTest.php
vendored
Normal file
1059
vendor/johngrogg/ics-parser/tests/Rfc5545RecurrenceTest.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
509
vendor/johngrogg/ics-parser/tests/SingleEventsTest.php
vendored
Normal file
509
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
vendor/johngrogg/ics-parser/tests/ical/ical-monthly.ics
vendored
Normal file
18
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
vendor/johngrogg/ics-parser/tests/ical/issue-196.ics
vendored
Normal file
64
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
|
||||
Reference in New Issue
Block a user