├── .gitignore ├── vendor ├── simshaun │ └── recurr │ │ ├── .gitignore │ │ ├── .gitattributes │ │ ├── translations │ │ ├── no.php │ │ ├── eu.php │ │ ├── pt-br.php │ │ ├── tr.php │ │ ├── sv.php │ │ ├── da.php │ │ ├── es.php │ │ ├── nl.php │ │ ├── en.php │ │ ├── el.php │ │ ├── fr.php │ │ ├── de.php │ │ └── it.php │ │ ├── src │ │ └── Recurr │ │ │ ├── Transformer │ │ │ ├── TranslatorInterface.php │ │ │ ├── Constraint.php │ │ │ ├── ConstraintInterface.php │ │ │ ├── Translator.php │ │ │ ├── Constraint │ │ │ │ ├── AfterConstraint.php │ │ │ │ ├── BeforeConstraint.php │ │ │ │ └── BetweenConstraint.php │ │ │ └── ArrayTransformerConfig.php │ │ │ ├── Exception.php │ │ │ ├── Exception │ │ │ ├── InvalidRRule.php │ │ │ ├── InvalidArgument.php │ │ │ └── InvalidWeekday.php │ │ │ ├── Frequency.php │ │ │ ├── Time.php │ │ │ ├── DaySet.php │ │ │ ├── DateExclusion.php │ │ │ ├── DateInclusion.php │ │ │ ├── DateInfo.php │ │ │ ├── Weekday.php │ │ │ ├── Recurrence.php │ │ │ └── RecurrenceCollection.php │ │ ├── composer.json │ │ ├── LICENSE │ │ └── README.md ├── doctrine │ ├── collections │ │ ├── docs │ │ │ └── en │ │ │ │ ├── sidebar.rst │ │ │ │ ├── derived-collections.rst │ │ │ │ ├── lazy-collections.rst │ │ │ │ ├── expressions.rst │ │ │ │ ├── expression-builder.rst │ │ │ │ └── index.rst │ │ ├── lib │ │ │ └── Doctrine │ │ │ │ └── Common │ │ │ │ └── Collections │ │ │ │ ├── Expr │ │ │ │ ├── Expression.php │ │ │ │ ├── Value.php │ │ │ │ ├── ExpressionVisitor.php │ │ │ │ ├── CompositeExpression.php │ │ │ │ ├── Comparison.php │ │ │ │ └── ClosureExpressionVisitor.php │ │ │ │ ├── Selectable.php │ │ │ │ ├── Collection.php │ │ │ │ ├── ExpressionBuilder.php │ │ │ │ ├── Criteria.php │ │ │ │ ├── ReadableCollection.php │ │ │ │ └── AbstractLazyCollection.php │ │ ├── README.md │ │ ├── .doctrine-project.json │ │ ├── LICENSE │ │ ├── CONTRIBUTING.md │ │ └── composer.json │ └── deprecations │ │ ├── LICENSE │ │ ├── composer.json │ │ ├── lib │ │ └── Doctrine │ │ │ └── Deprecations │ │ │ └── PHPUnit │ │ │ └── VerifyDeprecations.php │ │ └── README.md ├── composer │ ├── autoload_namespaces.php │ ├── autoload_psr4.php │ ├── platform_check.php │ ├── LICENSE │ ├── autoload_real.php │ ├── installed.php │ ├── autoload_classmap.php │ └── autoload_static.php ├── getkirby │ └── composer-installer │ │ ├── composer.json │ │ ├── src │ │ └── ComposerInstaller │ │ │ ├── Plugin.php │ │ │ ├── CmsInstaller.php │ │ │ ├── Installer.php │ │ │ └── PluginInstaller.php │ │ └── readme.md └── autoload.php ├── snippets └── events │ └── upcoming.php ├── composer.json ├── blueprints └── fields │ └── event.yml ├── LICENSE.md ├── README.md └── index.php /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | /.idea/ 3 | /composer.lock 4 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/.gitattributes: -------------------------------------------------------------------------------- 1 | /tests export-ignore 2 | /.travis.yml export-ignore 3 | /phpunit.xml.dist export-ignore 4 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/translations/no.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashandSalt/kirby-recurr/HEAD/vendor/simshaun/recurr/translations/no.php -------------------------------------------------------------------------------- /vendor/doctrine/collections/docs/en/sidebar.rst: -------------------------------------------------------------------------------- 1 | .. toctree:: 2 | :depth: 3 3 | 4 | index 5 | expressions 6 | expression-builder 7 | derived-collections 8 | lazy-collections 9 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/Transformer/TranslatorInterface.php: -------------------------------------------------------------------------------- 1 |

Upcoming Events

2 | 3 | 13 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/Exception.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class InvalidRRule extends Exception 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/Exception/InvalidArgument.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class InvalidArgument extends Exception 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/Exception/InvalidWeekday.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class InvalidWeekday extends Exception 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/Transformer/Constraint.php: -------------------------------------------------------------------------------- 1 | stopsTransformer; 20 | } 21 | } -------------------------------------------------------------------------------- /vendor/composer/autoload_psr4.php: -------------------------------------------------------------------------------- 1 | array($vendorDir . '/simshaun/recurr/src/Recurr'), 10 | 'Kirby\\' => array($vendorDir . '/getkirby/composer-installer/src'), 11 | 'Doctrine\\Deprecations\\' => array($vendorDir . '/doctrine/deprecations/lib/Doctrine/Deprecations'), 12 | 'Doctrine\\Common\\Collections\\' => array($vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections'), 13 | ); 14 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/Transformer/ConstraintInterface.php: -------------------------------------------------------------------------------- 1 | value = $value; 14 | } 15 | 16 | /** @return mixed */ 17 | public function getValue() 18 | { 19 | return $this->value; 20 | } 21 | 22 | /** 23 | * {@inheritDoc} 24 | */ 25 | public function visit(ExpressionVisitor $visitor) 26 | { 27 | return $visitor->walkValue($this); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/Frequency.php: -------------------------------------------------------------------------------- 1 | foo = $foo; 18 | 19 | parent::__construct($elements); 20 | } 21 | 22 | protected function createFrom(array $elements) : self 23 | { 24 | return new static($this->foo, $elements); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/docs/en/lazy-collections.rst: -------------------------------------------------------------------------------- 1 | Lazy Collections 2 | ================ 3 | 4 | To create a lazy collection you can extend the 5 | ``Doctrine\Common\Collections\AbstractLazyCollection`` class 6 | and define the ``doInitialize`` method. Here is an example where 7 | we lazily query the database for a collection of user records: 8 | 9 | .. code-block:: php 10 | use Doctrine\DBAL\Connection; 11 | 12 | class UsersLazyCollection extends AbstractLazyCollection 13 | { 14 | /** @var Connection */ 15 | private $connection; 16 | 17 | public function __construct(Connection $connection) 18 | { 19 | $this->connection = $connection; 20 | } 21 | 22 | protected function doInitialize() : void 23 | { 24 | $this->collection = $this->connection->fetchAll('SELECT * FROM users'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simshaun/recurr", 3 | "description": "PHP library for working with recurrence rules", 4 | "keywords": ["rrule", "recurrence", "recurring", "events", "dates"], 5 | "homepage": "https://github.com/simshaun/recurr", 6 | "type": "library", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Shaun Simmons", 11 | "email": "shaun@shaun.pub", 12 | "homepage": "https://shaun.pub" 13 | } 14 | ], 15 | "require": { 16 | "php": ">=5.5.0", 17 | "doctrine/collections": "~1.3" 18 | }, 19 | "require-dev": { 20 | "phpunit/phpunit": "~5.7" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "Recurr\\": "src/Recurr/" 25 | } 26 | }, 27 | "autoload-dev": { 28 | "psr-4": { 29 | "Recurr\\Test\\": "tests/Recurr/Test" 30 | } 31 | }, 32 | "extra": { 33 | "branch-alias": { 34 | "dev-master": "0.x-dev" 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/Time.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class Time 23 | { 24 | /** @var int */ 25 | public $hour; 26 | 27 | /** @var int */ 28 | public $minute; 29 | 30 | /** @var int */ 31 | public $second; 32 | 33 | public function __construct($hour, $minute, $second) 34 | { 35 | $this->hour = $hour; 36 | $this->minute = $minute; 37 | $this->second = $second; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /vendor/composer/platform_check.php: -------------------------------------------------------------------------------- 1 | = 70103)) { 8 | $issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.3". You are running ' . PHP_VERSION . '.'; 9 | } 10 | 11 | if ($issues) { 12 | if (!headers_sent()) { 13 | header('HTTP/1.1 500 Internal Server Error'); 14 | } 15 | if (!ini_get('display_errors')) { 16 | if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { 17 | fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); 18 | } elseif (!headers_sent()) { 19 | echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; 20 | } 21 | } 22 | trigger_error( 23 | 'Composer detected issues in your platform: ' . implode(' ', $issues), 24 | E_USER_ERROR 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /blueprints/fields/event.yml: -------------------------------------------------------------------------------- 1 | type: group 2 | fields: 3 | estart: 4 | label: Event Start 5 | type: date 6 | time: true 7 | width: 1/4 8 | eend: 9 | label: Event End 10 | type: date 11 | time: true 12 | width: 1/4 13 | efreq: 14 | label: Event Frequency 15 | type: select 16 | width: 1/4 17 | options: 18 | secondly: Secondly 19 | minutely: Minutely 20 | hourly: Hourly 21 | daily: Daily 22 | weekly: Weekly 23 | monthly: Monthly 24 | yearly: Yearly 25 | erange: 26 | label: Event Range End 27 | type: date 28 | time: true 29 | width: 1/4 30 | ebyday: 31 | label: Event Days 32 | type: multiselect 33 | options: 34 | mo: Monday 35 | tu: Tuesday 36 | we: Wednesday 37 | th: Thursday 38 | fr: Friday 39 | sa: Saturday 40 | su: Sunday 41 | edescription: 42 | label: Event Description 43 | type: writer 44 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006-2013 Doctrine Project 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/doctrine/deprecations/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021 Doctrine Project 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/composer/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) Nils Adermann, Jordi Boggiano 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished 9 | to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/DaySet.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class DaySet 23 | { 24 | /** @var array */ 25 | public $set; 26 | 27 | /** @var int Day of year */ 28 | public $start; 29 | 30 | /** @var int Day of year */ 31 | public $end; 32 | 33 | /** 34 | * Constructor 35 | * 36 | * @param array $set Set of days 37 | * @param int $start Day of year of start day 38 | * @param int $end Day of year of end day 39 | */ 40 | public function __construct($set, $start, $end) 41 | { 42 | $this->set = $set; 43 | $this->start = $start; 44 | $this->end = $end; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/lib/Doctrine/Common/Collections/Selectable.php: -------------------------------------------------------------------------------- 1 | &Selectable 27 | * @psalm-return Collection&Selectable 28 | */ 29 | public function matching(Criteria $criteria); 30 | } 31 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/Transformer/Translator.php: -------------------------------------------------------------------------------- 1 | loadLocale($fallbackLocale); 12 | if ($locale !== $fallbackLocale) { 13 | $this->loadLocale($locale); 14 | } 15 | } 16 | 17 | public function loadLocale($locale, $path = null) 18 | { 19 | if (!$path) { 20 | $path = __DIR__ . '/../../../translations/' . $locale . '.php'; 21 | } 22 | if (!file_exists($path)) { 23 | throw new \InvalidArgumentException('Locale '.$locale.' could not be found in '.$path); 24 | } 25 | 26 | $this->data = array_merge($this->data, include $path); 27 | } 28 | 29 | public function trans($string, array $params = array()) 30 | { 31 | $res = $this->data[$string]; 32 | if (is_object($res) && is_callable($res)) { 33 | $res = $res($string, $params); 34 | } 35 | 36 | foreach ($params as $key => $val) { 37 | $res = str_replace('%' . $key . '%', $val, $res); 38 | } 39 | 40 | return $res; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /vendor/composer/autoload_real.php: -------------------------------------------------------------------------------- 1 | register(true); 35 | 36 | return $loader; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /vendor/doctrine/deprecations/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "doctrine/deprecations", 3 | "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", 4 | "license": "MIT", 5 | "type": "library", 6 | "homepage": "https://www.doctrine-project.org/", 7 | "require": { 8 | "php": "^7.1 || ^8.0" 9 | }, 10 | "require-dev": { 11 | "doctrine/coding-standard": "^9", 12 | "phpstan/phpstan": "1.4.10 || 1.10.15", 13 | "phpstan/phpstan-phpunit": "^1.0", 14 | "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", 15 | "psalm/plugin-phpunit": "0.18.4", 16 | "psr/log": "^1 || ^2 || ^3", 17 | "vimeo/psalm": "4.30.0 || 5.12.0" 18 | }, 19 | "suggest": { 20 | "psr/log": "Allows logging deprecations via PSR-3 logger implementation" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" 25 | } 26 | }, 27 | "autoload-dev": { 28 | "psr-4": { 29 | "DeprecationTests\\": "test_fixtures/src", 30 | "Doctrine\\Foo\\": "test_fixtures/vendor/doctrine/foo" 31 | } 32 | }, 33 | "config": { 34 | "allow-plugins": { 35 | "dealerdirect/phpcodesniffer-composer-installer": true 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/DateExclusion.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | class DateExclusion 25 | { 26 | /** @var \DateTimeInterface */ 27 | public $date; 28 | 29 | /** @var bool Day of year */ 30 | public $hasTime; 31 | 32 | /** @var bool */ 33 | public $isUtcExplicit; 34 | 35 | /** 36 | * Constructor 37 | * 38 | * @param \DateTimeInterface $date 39 | * @param bool $hasTime 40 | * @param bool $isUtcExplicit 41 | */ 42 | public function __construct(\DateTimeInterface $date, $hasTime = true, $isUtcExplicit = false) 43 | { 44 | $this->date = $date; 45 | $this->hasTime = $hasTime; 46 | $this->isUtcExplicit = $isUtcExplicit; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/DateInclusion.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | class DateInclusion 25 | { 26 | /** @var \DateTimeInterface */ 27 | public $date; 28 | 29 | /** @var bool Day of year */ 30 | public $hasTime; 31 | 32 | /** @var bool */ 33 | public $isUtcExplicit; 34 | 35 | /** 36 | * Constructor 37 | * 38 | * @param \DateTimeInterface $date 39 | * @param bool $hasTime 40 | * @param bool $isUtcExplicit 41 | */ 42 | public function __construct(\DateTimeInterface $date, $hasTime = true, $isUtcExplicit = false) 43 | { 44 | $this->date = $date; 45 | $this->hasTime = $hasTime; 46 | $this->isUtcExplicit = $isUtcExplicit; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/Transformer/Constraint/AfterConstraint.php: -------------------------------------------------------------------------------- 1 | after = $after; 32 | $this->inc = $inc; 33 | } 34 | 35 | /** 36 | * Passes if $date is after $after 37 | * 38 | * {@inheritdoc} 39 | */ 40 | public function test(\DateTimeInterface $date) 41 | { 42 | if ($this->inc) { 43 | return $date >= $this->after; 44 | } 45 | 46 | return $date > $this->after; 47 | } 48 | 49 | /** 50 | * @return \DateTimeInterface 51 | */ 52 | public function getAfter() 53 | { 54 | return $this->after; 55 | } 56 | 57 | /** 58 | * @return bool 59 | */ 60 | public function isInc() 61 | { 62 | return $this->inc; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/Transformer/Constraint/BeforeConstraint.php: -------------------------------------------------------------------------------- 1 | before = $before; 32 | $this->inc = $inc; 33 | } 34 | 35 | /** 36 | * Passes if $date is before $before 37 | * 38 | * {@inheritdoc} 39 | */ 40 | public function test(\DateTimeInterface $date) 41 | { 42 | if ($this->inc) { 43 | return $date <= $this->before; 44 | } 45 | 46 | return $date < $this->before; 47 | } 48 | 49 | /** 50 | * @return \DateTimeInterface 51 | */ 52 | public function getBefore() 53 | { 54 | return $this->before; 55 | } 56 | 57 | /** 58 | * @return bool 59 | */ 60 | public function isInc() 61 | { 62 | return $this->inc; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribute to Doctrine 2 | 3 | Thank you for contributing to Doctrine! 4 | 5 | Before we can merge your Pull-Request here are some guidelines that you need to follow. 6 | These guidelines exist not to annoy you, but to keep the code base clean, 7 | unified and future proof. 8 | 9 | ## Coding Standard 10 | 11 | We use the [Doctrine Coding Standard](https://github.com/doctrine/coding-standard). 12 | 13 | ## Unit-Tests 14 | 15 | Please try to add a test for your pull-request. 16 | 17 | * If you want to contribute new functionality add unit- or functional tests 18 | depending on the scope of the feature. 19 | 20 | You can run the unit-tests by calling ``vendor/bin/phpunit`` from the root of the project. 21 | It will run all the project tests. 22 | 23 | In order to do that, you will need a fresh copy of doctrine/collections, and you 24 | will have to run a composer installation in the project: 25 | 26 | ```sh 27 | git clone git@github.com:doctrine/collections.git 28 | cd collections 29 | curl -sS https://getcomposer.org/installer | php -- 30 | ./composer.phar install 31 | ``` 32 | 33 | ## Github Actions 34 | 35 | We automatically run your pull request through Github Actions against supported 36 | PHP versions. If you break the tests, we cannot merge your code, so please make 37 | sure that your code is working before opening up a Pull-Request. 38 | 39 | ## Getting merged 40 | 41 | Please allow us time to review your pull requests. We will give our best to review 42 | everything as fast as possible, but cannot always live up to our own expectations. 43 | 44 | Thank you very much again for your contribution! 45 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/Transformer/ArrayTransformerConfig.php: -------------------------------------------------------------------------------- 1 | virtualLimit = (int) $virtualLimit; 29 | 30 | return $this; 31 | } 32 | 33 | /** 34 | * Get the virtual limit imposed upon infinitely recurring events. 35 | * 36 | * @return int 37 | */ 38 | public function getVirtualLimit() 39 | { 40 | return $this->virtualLimit; 41 | } 42 | 43 | /** 44 | * By default, January 30 + 1 month results in March 30 because February doesn't have 30 days. 45 | * 46 | * Enabling this fix tells Recurr that +1 month means "last day of next month". 47 | */ 48 | public function enableLastDayOfMonthFix() 49 | { 50 | $this->lastDayOfMonthFix = true; 51 | } 52 | 53 | public function disableLastDayOfMonthFix() 54 | { 55 | $this->lastDayOfMonthFix = false; 56 | } 57 | 58 | /** 59 | * @return boolean 60 | */ 61 | public function isLastDayOfMonthFixEnabled() 62 | { 63 | return $this->lastDayOfMonthFix; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /vendor/getkirby/composer-installer/src/ComposerInstaller/Plugin.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier GmbH 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | class Plugin implements PluginInterface 17 | { 18 | /** 19 | * Apply plugin modifications to Composer 20 | * 21 | * @param \Composer\Composer $composer 22 | * @param \Composer\IO\IOInterface $io 23 | * @return void 24 | */ 25 | public function activate(Composer $composer, IOInterface $io): void 26 | { 27 | $installationManager = $composer->getInstallationManager(); 28 | $installationManager->addInstaller(new CmsInstaller($io, $composer)); 29 | $installationManager->addInstaller(new PluginInstaller($io, $composer)); 30 | } 31 | 32 | /** 33 | * Remove any hooks from Composer 34 | * 35 | * @codeCoverageIgnore 36 | * 37 | * @param \Composer\Composer $composer 38 | * @param \Composer\IO\IOInterface $io 39 | * @return void 40 | */ 41 | public function deactivate(Composer $composer, IOInterface $io): void 42 | { 43 | // nothing to do 44 | } 45 | 46 | /** 47 | * Prepare the plugin to be uninstalled 48 | * 49 | * @codeCoverageIgnore 50 | * 51 | * @param Composer $composer 52 | * @param IOInterface $io 53 | * @return void 54 | */ 55 | public function uninstall(Composer $composer, IOInterface $io): void 56 | { 57 | // nothing to do 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ExpressionVisitor.php: -------------------------------------------------------------------------------- 1 | walkComparison($expr); 48 | 49 | case $expr instanceof Value: 50 | return $this->walkValue($expr); 51 | 52 | case $expr instanceof CompositeExpression: 53 | return $this->walkCompositeExpression($expr); 54 | 55 | default: 56 | throw new RuntimeException('Unknown Expression ' . get_class($expr)); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/CompositeExpression.php: -------------------------------------------------------------------------------- 1 | type = $type; 30 | 31 | foreach ($expressions as $expr) { 32 | if ($expr instanceof Value) { 33 | throw new RuntimeException('Values are not supported expressions as children of and/or expressions.'); 34 | } 35 | 36 | if (! ($expr instanceof Expression)) { 37 | throw new RuntimeException('No expression given to CompositeExpression.'); 38 | } 39 | 40 | $this->expressions[] = $expr; 41 | } 42 | } 43 | 44 | /** 45 | * Returns the list of expressions nested in this composite. 46 | * 47 | * @return Expression[] 48 | */ 49 | public function getExpressionList() 50 | { 51 | return $this->expressions; 52 | } 53 | 54 | /** @return string */ 55 | public function getType() 56 | { 57 | return $this->type; 58 | } 59 | 60 | /** 61 | * {@inheritDoc} 62 | */ 63 | public function visit(ExpressionVisitor $visitor) 64 | { 65 | return $visitor->walkCompositeExpression($this); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/DateInfo.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class DateInfo 24 | { 25 | /** @var \DateTime */ 26 | public $dt; 27 | 28 | /** 29 | * @var int Number of days in the month. 30 | */ 31 | public $monthLength; 32 | 33 | /** 34 | * @var int Number of days in the year (365 normally, 366 on leap years) 35 | */ 36 | public $yearLength; 37 | 38 | /** 39 | * @var int Number of days in the next year (365 normally, 366 on leap years) 40 | */ 41 | public $nextYearLength; 42 | 43 | /** 44 | * @var array Day of year of last day of each month. 45 | */ 46 | public $mRanges; 47 | 48 | /** @var int Day of week */ 49 | public $dayOfWeek; 50 | 51 | /** @var int Day of week of the year's first day */ 52 | public $dayOfWeekYearDay1; 53 | 54 | /** 55 | * @var array Month number for each day of the year. 56 | */ 57 | public $mMask; 58 | 59 | /** 60 | * @var array Month-daynumber for each day of the year. 61 | */ 62 | public $mDayMask; 63 | 64 | /** 65 | * @var array Month-daynumber for each day of the year (in reverse). 66 | */ 67 | public $mDayMaskNeg; 68 | 69 | /** 70 | * @var array Day of week (0-6) for each day of the year, 0 being Monday 71 | */ 72 | public $wDayMask; 73 | } 74 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/translations/eu.php: -------------------------------------------------------------------------------- 1 | 'Ezin izan da rrule testura osoki bihurtu.', 5 | 'for %count% times' => '%count% aldiz', 6 | 'for %count% time' => '%count% aldia', 7 | '(~ approximate)' => '(~ inguru)', 8 | 'until %date%' => '%date% arte', // e.g. every year until July 4, 2014 9 | 'day_date' => defined('PHP_WINDOWS_VERSION_BUILD') ? '%B %#d, %Y' : '%B %e, %Y', 10 | 'and' => 'eta', 11 | 'or' => 'edo', 12 | 'in' => 'hilabete hauetan:', // e.g. every week in January, May and August 13 | 'on' => 'egun hauetan:', // e.g. every day on Tuesday, Wednesday and Friday 14 | 'the' => '', 15 | 'on the' => '', // e.g. every year on the 1st and 200th day 16 | 'every %count% years' => '%count% urtero', 17 | 'every year' => 'urtero', 18 | 'every_month_list' => 'hilabete hauetan', // e.g. every January, May and August 19 | 'every %count% months' => '%count% hilabetero', 20 | 'every month' => 'hilabetero', 21 | 'every %count% weeks' => '%count% astero', 22 | 'every week' => 'astero', 23 | 'every %count% days' => '%count% egunero', 24 | 'every day' => 'egunero', 25 | 'last' => 'azken', // e.g. 2nd last Friday 26 | 'days' => 'egun', 27 | 'day' => 'egun', 28 | 'weeks' => 'aste', 29 | 'week' => 'aste', 30 | 'ordinal_number' => function ($str, $params) { // formats a number with a prefix e.g. every year on the 1st and 200th day 31 | $number = $params['number']; 32 | 33 | $ends = array('garren', 'go', 'garren', 'garren', 'garren', 'garren', 'garren', 'garren', 'garren', 'garren'); 34 | 35 | if (($number % 100) >= 11 && ($number % 100) <= 13) { 36 | $abbreviation = $number.'garren'; 37 | } else { 38 | $abbreviation = $number.$ends[$number % 10]; 39 | } 40 | 41 | return $abbreviation; 42 | }, 43 | ); 44 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "doctrine/collections", 3 | "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.", 4 | "license": "MIT", 5 | "type": "library", 6 | "keywords": [ 7 | "php", 8 | "collections", 9 | "array", 10 | "iterators" 11 | ], 12 | "authors": [ 13 | { 14 | "name": "Guilherme Blanco", 15 | "email": "guilhermeblanco@gmail.com" 16 | }, 17 | { 18 | "name": "Roman Borschel", 19 | "email": "roman@code-factory.org" 20 | }, 21 | { 22 | "name": "Benjamin Eberlei", 23 | "email": "kontakt@beberlei.de" 24 | }, 25 | { 26 | "name": "Jonathan Wage", 27 | "email": "jonwage@gmail.com" 28 | }, 29 | { 30 | "name": "Johannes Schmitt", 31 | "email": "schmittjoh@gmail.com" 32 | } 33 | ], 34 | "homepage": "https://www.doctrine-project.org/projects/collections.html", 35 | "require": { 36 | "php": "^7.1.3 || ^8.0", 37 | "doctrine/deprecations": "^0.5.3 || ^1" 38 | }, 39 | "require-dev": { 40 | "doctrine/coding-standard": "^9.0 || ^10.0", 41 | "phpstan/phpstan": "^1.4.8", 42 | "phpunit/phpunit": "^7.5 || ^8.5 || ^9.1.5", 43 | "vimeo/psalm": "^4.22" 44 | }, 45 | "autoload": { 46 | "psr-4": { 47 | "Doctrine\\Common\\Collections\\": "lib/Doctrine/Common/Collections" 48 | } 49 | }, 50 | "autoload-dev": { 51 | "psr-4": { 52 | "Doctrine\\Tests\\": "tests/Doctrine/Tests" 53 | } 54 | }, 55 | "config": { 56 | "allow-plugins": { 57 | "composer/package-versions-deprecated": true, 58 | "dealerdirect/phpcodesniffer-composer-installer": true 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/Weekday.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | class Weekday 25 | { 26 | /** 27 | * Weekday number. 28 | * 29 | * 0 = Sunday 30 | * 1 = Monday 31 | * 2 = Tuesday 32 | * 3 = Wednesday 33 | * 4 = Thursday 34 | * 5 = Friday 35 | * 6 = Saturday 36 | * 37 | * @var string 38 | */ 39 | public $weekday; 40 | 41 | /** @var int nth occurrence of the weekday */ 42 | public $num; 43 | 44 | protected $days = array('MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU'); 45 | 46 | /** 47 | * @param int|string $weekday 0-6 or MO..SU 48 | * @param null|int $num 49 | * 50 | * @throws InvalidWeekday 51 | */ 52 | public function __construct($weekday, $num) 53 | { 54 | if (is_numeric($weekday) && $weekday > 6 || $weekday < 0) { 55 | throw new InvalidWeekday('Day is not a valid weekday (0-6)'); 56 | } elseif (!is_numeric($weekday) && !in_array($weekday, $this->days)) { 57 | throw new InvalidWeekday('Day is not a valid weekday (SU, MO, ...)'); 58 | } 59 | 60 | if (!is_numeric($weekday)) { 61 | $weekday = array_search($weekday, $this->days); 62 | } 63 | 64 | $this->weekday = $weekday; 65 | $this->num = $num; 66 | } 67 | 68 | public function __toString() 69 | { 70 | return $this->num . $this->days[$this->weekday]; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php: -------------------------------------------------------------------------------- 1 | '; 12 | public const LT = '<'; 13 | public const LTE = '<='; 14 | public const GT = '>'; 15 | public const GTE = '>='; 16 | public const IS = '='; // no difference with EQ 17 | public const IN = 'IN'; 18 | public const NIN = 'NIN'; 19 | public const CONTAINS = 'CONTAINS'; 20 | public const MEMBER_OF = 'MEMBER_OF'; 21 | public const STARTS_WITH = 'STARTS_WITH'; 22 | public const ENDS_WITH = 'ENDS_WITH'; 23 | 24 | /** @var string */ 25 | private $field; 26 | 27 | /** @var string */ 28 | private $op; 29 | 30 | /** @var Value */ 31 | private $value; 32 | 33 | /** 34 | * @param string $field 35 | * @param string $operator 36 | * @param mixed $value 37 | */ 38 | public function __construct($field, $operator, $value) 39 | { 40 | if (! ($value instanceof Value)) { 41 | $value = new Value($value); 42 | } 43 | 44 | $this->field = $field; 45 | $this->op = $operator; 46 | $this->value = $value; 47 | } 48 | 49 | /** @return string */ 50 | public function getField() 51 | { 52 | return $this->field; 53 | } 54 | 55 | /** @return Value */ 56 | public function getValue() 57 | { 58 | return $this->value; 59 | } 60 | 61 | /** @return string */ 62 | public function getOperator() 63 | { 64 | return $this->op; 65 | } 66 | 67 | /** 68 | * {@inheritDoc} 69 | */ 70 | public function visit(ExpressionVisitor $visitor) 71 | { 72 | return $visitor->walkComparison($this); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/Recurrence.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class Recurrence 20 | { 21 | /** @var \DateTimeInterface */ 22 | protected $start; 23 | 24 | /** @var \DateTimeInterface */ 25 | protected $end; 26 | 27 | /** @var int */ 28 | protected $index; 29 | 30 | public function __construct(\DateTimeInterface $start = null, \DateTimeInterface $end = null, $index = 0) 31 | { 32 | if ($start instanceof \DateTimeInterface) { 33 | $this->setStart($start); 34 | } 35 | 36 | if ($end instanceof \DateTimeInterface) { 37 | $this->setEnd($end); 38 | } 39 | 40 | $this->index = $index; 41 | } 42 | 43 | /** 44 | * @return \DateTimeInterface 45 | */ 46 | public function getStart() 47 | { 48 | return $this->start; 49 | } 50 | 51 | /** 52 | * @param \DateTime $start 53 | */ 54 | public function setStart($start) 55 | { 56 | $this->start = $start; 57 | } 58 | 59 | /** 60 | * @return \DateTime 61 | */ 62 | public function getEnd() 63 | { 64 | return $this->end; 65 | } 66 | 67 | /** 68 | * @param \DateTime $end 69 | */ 70 | public function setEnd($end) 71 | { 72 | $this->end = $end; 73 | } 74 | 75 | /** 76 | * @return int 77 | */ 78 | public function getIndex() 79 | { 80 | return $this->index; 81 | } 82 | 83 | /** 84 | * @param int $index 85 | */ 86 | public function setIndex($index) 87 | { 88 | $this->index = $index; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/src/Recurr/Transformer/Constraint/BetweenConstraint.php: -------------------------------------------------------------------------------- 1 | after = $after; 36 | $this->before = $before; 37 | $this->inc = $inc; 38 | } 39 | 40 | /** 41 | * Passes if $date is between $after and $before 42 | * 43 | * {@inheritdoc} 44 | */ 45 | public function test(\DateTimeInterface $date) 46 | { 47 | if ($date > $this->before) { 48 | $this->stopsTransformer = true; 49 | } 50 | 51 | if ($this->inc) { 52 | return $date >= $this->after && $date <= $this->before; 53 | } 54 | 55 | return $date > $this->after && $date < $this->before; 56 | } 57 | 58 | /** 59 | * @return \DateTimeInterface 60 | */ 61 | public function getBefore() 62 | { 63 | return $this->before; 64 | } 65 | 66 | /** 67 | * @return \DateTimeInterface 68 | */ 69 | public function getAfter() 70 | { 71 | return $this->after; 72 | } 73 | 74 | /** 75 | * @return bool 76 | */ 77 | public function isInc() 78 | { 79 | return $this->inc; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /vendor/getkirby/composer-installer/src/ComposerInstaller/CmsInstaller.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier GmbH 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | class CmsInstaller extends Installer 17 | { 18 | /** 19 | * Decides if the installer supports the given type 20 | * 21 | * @param string $packageType 22 | * @return bool 23 | */ 24 | public function supports($packageType): bool 25 | { 26 | return $packageType === 'kirby-cms'; 27 | } 28 | 29 | /** 30 | * Returns the installation path of a package 31 | * 32 | * @param \Composer\Package\PackageInterface $package 33 | * @return string 34 | */ 35 | public function getInstallPath(PackageInterface $package): string 36 | { 37 | // get the extra configuration of the top-level package 38 | if ($rootPackage = $this->composer->getPackage()) { 39 | $extra = $rootPackage->getExtra(); 40 | } else { 41 | $extra = []; 42 | } 43 | 44 | // use path from configuration, otherwise fall back to default 45 | if (isset($extra['kirby-cms-path']) === true) { 46 | $path = $extra['kirby-cms-path']; 47 | } else { 48 | $path = 'kirby'; 49 | } 50 | 51 | // if explicitly set to something invalid (e.g. `false`), install to vendor dir 52 | if (is_string($path) !== true) { 53 | return parent::getInstallPath($package); 54 | } 55 | 56 | // don't allow unsafe directories 57 | $vendorDir = $this->composer->getConfig()->get('vendor-dir', Config::RELATIVE_PATHS) ?? 'vendor'; 58 | if ($path === $vendorDir || $path === '.') { 59 | throw new InvalidArgumentException('The path ' . $path . ' is an unsafe installation directory for ' . $package->getPrettyName() . '.'); 60 | } 61 | 62 | return $path; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /vendor/doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php: -------------------------------------------------------------------------------- 1 | */ 14 | private $doctrineDeprecationsExpectations = []; 15 | 16 | /** @var array */ 17 | private $doctrineNoDeprecationsExpectations = []; 18 | 19 | public function expectDeprecationWithIdentifier(string $identifier): void 20 | { 21 | $this->doctrineDeprecationsExpectations[$identifier] = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0; 22 | } 23 | 24 | public function expectNoDeprecationWithIdentifier(string $identifier): void 25 | { 26 | $this->doctrineNoDeprecationsExpectations[$identifier] = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0; 27 | } 28 | 29 | /** 30 | * @before 31 | */ 32 | public function enableDeprecationTracking(): void 33 | { 34 | Deprecation::enableTrackingDeprecations(); 35 | } 36 | 37 | /** 38 | * @after 39 | */ 40 | public function verifyDeprecationsAreTriggered(): void 41 | { 42 | foreach ($this->doctrineDeprecationsExpectations as $identifier => $expectation) { 43 | $actualCount = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0; 44 | 45 | $this->assertTrue( 46 | $actualCount > $expectation, 47 | sprintf( 48 | "Expected deprecation with identifier '%s' was not triggered by code executed in test.", 49 | $identifier 50 | ) 51 | ); 52 | } 53 | 54 | foreach ($this->doctrineNoDeprecationsExpectations as $identifier => $expectation) { 55 | $actualCount = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0; 56 | 57 | $this->assertTrue( 58 | $actualCount === $expectation, 59 | sprintf( 60 | "Expected deprecation with identifier '%s' was triggered by code executed in test, but expected not to.", 61 | $identifier 62 | ) 63 | ); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /vendor/composer/installed.php: -------------------------------------------------------------------------------- 1 | array( 3 | 'name' => 'hashandsalt/kirby-recurr', 4 | 'pretty_version' => 'dev-master', 5 | 'version' => 'dev-master', 6 | 'reference' => '6a85ac439faef46dd177171169abdf98289367ce', 7 | 'type' => 'kirby-plugin', 8 | 'install_path' => __DIR__ . '/../../', 9 | 'aliases' => array(), 10 | 'dev' => true, 11 | ), 12 | 'versions' => array( 13 | 'doctrine/collections' => array( 14 | 'pretty_version' => '1.8.0', 15 | 'version' => '1.8.0.0', 16 | 'reference' => '2b44dd4cbca8b5744327de78bafef5945c7e7b5e', 17 | 'type' => 'library', 18 | 'install_path' => __DIR__ . '/../doctrine/collections', 19 | 'aliases' => array(), 20 | 'dev_requirement' => false, 21 | ), 22 | 'doctrine/deprecations' => array( 23 | 'pretty_version' => '1.1.2', 24 | 'version' => '1.1.2.0', 25 | 'reference' => '4f2d4f2836e7ec4e7a8625e75c6aa916004db931', 26 | 'type' => 'library', 27 | 'install_path' => __DIR__ . '/../doctrine/deprecations', 28 | 'aliases' => array(), 29 | 'dev_requirement' => false, 30 | ), 31 | 'getkirby/composer-installer' => array( 32 | 'pretty_version' => '1.2.1', 33 | 'version' => '1.2.1.0', 34 | 'reference' => 'c98ece30bfba45be7ce457e1102d1b169d922f3d', 35 | 'type' => 'composer-plugin', 36 | 'install_path' => __DIR__ . '/../getkirby/composer-installer', 37 | 'aliases' => array(), 38 | 'dev_requirement' => false, 39 | ), 40 | 'hashandsalt/kirby-recurr' => array( 41 | 'pretty_version' => 'dev-master', 42 | 'version' => 'dev-master', 43 | 'reference' => '6a85ac439faef46dd177171169abdf98289367ce', 44 | 'type' => 'kirby-plugin', 45 | 'install_path' => __DIR__ . '/../../', 46 | 'aliases' => array(), 47 | 'dev_requirement' => false, 48 | ), 49 | 'simshaun/recurr' => array( 50 | 'pretty_version' => 'v4.0.5', 51 | 'version' => '4.0.5.0', 52 | 'reference' => '08b0b46879f598cd11dd42b4c1a9c221a0562749', 53 | 'type' => 'library', 54 | 'install_path' => __DIR__ . '/../simshaun/recurr', 55 | 'aliases' => array(), 56 | 'dev_requirement' => false, 57 | ), 58 | ), 59 | ); 60 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/docs/en/expressions.rst: -------------------------------------------------------------------------------- 1 | Expressions 2 | =========== 3 | 4 | The ``Doctrine\Common\Collections\Expr\Comparison`` class 5 | can be used to create expressions to be used with the 6 | ``Doctrine\Common\Collections\Criteria`` class. It has the 7 | following operator constants: 8 | 9 | - ``Comparison::EQ`` 10 | - ``Comparison::NEQ`` 11 | - ``Comparison::LT`` 12 | - ``Comparison::LTE`` 13 | - ``Comparison::GT`` 14 | - ``Comparison::GTE`` 15 | - ``Comparison::IS`` 16 | - ``Comparison::IN`` 17 | - ``Comparison::NIN`` 18 | - ``Comparison::CONTAINS`` 19 | - ``Comparison::MEMBER_OF`` 20 | - ``Comparison::STARTS_WITH`` 21 | - ``Comparison::ENDS_WITH`` 22 | 23 | The ``Doctrine\Common\Collections\Criteria`` class has the following 24 | API to be used with expressions: 25 | 26 | where 27 | ----- 28 | 29 | Sets the where expression to evaluate when this Criteria is searched for. 30 | 31 | .. code-block:: php 32 | $expr = new Comparison('key', Comparison::EQ, 'value'); 33 | 34 | $criteria->where($expr); 35 | 36 | andWhere 37 | -------- 38 | 39 | Appends the where expression to evaluate when this Criteria is searched for 40 | using an AND with previous expression. 41 | 42 | .. code-block:: php 43 | $expr = new Comparison('key', Comparison::EQ, 'value'); 44 | 45 | $criteria->andWhere($expr); 46 | 47 | orWhere 48 | ------- 49 | 50 | Appends the where expression to evaluate when this Criteria is searched for 51 | using an OR with previous expression. 52 | 53 | .. code-block:: php 54 | $expr1 = new Comparison('key', Comparison::EQ, 'value1'); 55 | $expr2 = new Comparison('key', Comparison::EQ, 'value2'); 56 | 57 | $criteria->where($expr1); 58 | $criteria->orWhere($expr2); 59 | 60 | orderBy 61 | ------- 62 | 63 | Sets the ordering of the result of this Criteria. 64 | 65 | .. code-block:: php 66 | $criteria->orderBy(['name' => Criteria::ASC]); 67 | 68 | setFirstResult 69 | -------------- 70 | 71 | Set the number of first result that this Criteria should return. 72 | 73 | .. code-block:: php 74 | $criteria->setFirstResult(0); 75 | 76 | getFirstResult 77 | -------------- 78 | 79 | Gets the current first result option of this Criteria. 80 | 81 | .. code-block:: php 82 | $criteria->setFirstResult(10); 83 | 84 | echo $criteria->getFirstResult(); // 10 85 | 86 | setMaxResults 87 | ------------- 88 | 89 | Sets the max results that this Criteria should return. 90 | 91 | .. code-block:: php 92 | $criteria->setMaxResults(20); 93 | 94 | getMaxResults 95 | ------------- 96 | 97 | Gets the current max results option of this Criteria. 98 | 99 | .. code-block:: php 100 | $criteria->setMaxResults(20); 101 | 102 | echo $criteria->getMaxResults(); // 20 103 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Shaun Simmons 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | 21 | ---------------------------------------------- 22 | 23 | Recurr is heavily based on rrule.js: 24 | 25 | Copyright 2010, Jakub Roztocil and Lars Schöning 26 | 27 | Redistribution and use in source and binary forms, with or without 28 | modification, are permitted provided that the following conditions are met: 29 | 30 | 1. Redistributions of source code must retain the above copyright notice, 31 | this list of conditions and the following disclaimer. 32 | 33 | 2. Redistributions in binary form must reproduce the above copyright 34 | notice, this list of conditions and the following disclaimer in the 35 | documentation and/or other materials provided with the distribution. 36 | 37 | 3. Neither the name of The author nor the names of its contributors may 38 | be used to endorse or promote products derived from this software 39 | without specific prior written permission. 40 | 41 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND 42 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 43 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 44 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE FOR 45 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 46 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 48 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 50 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51 | -------------------------------------------------------------------------------- /vendor/getkirby/composer-installer/readme.md: -------------------------------------------------------------------------------- 1 | # Kirby Composer Installer 2 | 3 | [![CI Status](https://flat.badgen.net/github/checks/getkirby/composer-installer/master)](https://github.com/getkirby/composer-installer/actions?query=workflow%3ACI) 4 | [![Coverage Status](https://flat.badgen.net/coveralls/c/github/getkirby/composer-installer)](https://coveralls.io/github/getkirby/composer-installer) 5 | 6 | This is Kirby's custom [Composer installer](https://getcomposer.org/doc/articles/custom-installers.md) for the Kirby CMS. 7 | It is responsible for automatically choosing the correct installation paths if you install the CMS via Composer. 8 | 9 | It can also be used to automatically install Kirby plugins to the `site/plugins` directory. 10 | 11 | ## Installing the CMS 12 | 13 | ### Default configuration 14 | 15 | If you `require` the `getkirby/cms` package in your own `composer.json`, there is nothing else you need to do: 16 | 17 | ```js 18 | { 19 | "require": { 20 | "getkirby/cms": "^3.0" 21 | } 22 | } 23 | ``` 24 | 25 | Kirby's Composer installer (this repo) will run automatically and will install the CMS to the `kirby` directory. 26 | 27 | ### Custom installation path 28 | 29 | You might want to use a different installation path. The path can be configured like this in your `composer.json`: 30 | 31 | ```js 32 | { 33 | "require": { 34 | "getkirby/cms": "^3.0" 35 | }, 36 | "extra": { 37 | "kirby-cms-path": "kirby" // change this to your custom path 38 | } 39 | } 40 | ``` 41 | 42 | ### Disable the installer for the CMS 43 | 44 | If you prefer to have the CMS installed to the `vendor` directory, you can disable the custom path entirely: 45 | 46 | ```js 47 | { 48 | "require": { 49 | "getkirby/cms": "^3.0" 50 | }, 51 | "extra": { 52 | "kirby-cms-path": false 53 | } 54 | } 55 | ``` 56 | 57 | Please note that you will need to modify your site's `index.php` to load the `vendor/autoload.php` file instead of Kirby's `bootstrap.php`. 58 | 59 | ## Installing plugins 60 | 61 | ### Support in published plugins 62 | 63 | Plugins need to require this installer as a Composer dependency to make use of the automatic installation to the `site/plugins` directory. 64 | 65 | You can find out more about this in our [plugin documentation](https://getkirby.com/docs/guide/plugins/plugin-setup-basic). 66 | 67 | ### Usage for plugin users 68 | 69 | As a user of Kirby plugins that support this installer, you only need to `require` the plugins in your site's `composer.json`: 70 | 71 | ```js 72 | { 73 | "require": { 74 | "getkirby/cms": "^3.0", 75 | "superwoman/superplugin": "^1.0" 76 | } 77 | } 78 | ``` 79 | 80 | The installer (this repo) will run automatically, as the plugin dev added it to the plugin's `composer.json`. 81 | 82 | ### Custom installation path 83 | 84 | If your `site/plugins` directory is at a custom path, you can configure the installation path like this in your `composer.json`: 85 | 86 | ```js 87 | { 88 | "require": { 89 | "getkirby/cms": "^3.0", 90 | "superwoman/superplugin": "^1.0" 91 | }, 92 | "extra": { 93 | "kirby-plugin-path": "site/plugins" // change this to your custom path 94 | } 95 | } 96 | ``` 97 | 98 | ## License 99 | 100 | 101 | 102 | ## Author 103 | 104 | Lukas Bestle 105 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/translations/pt-br.php: -------------------------------------------------------------------------------- 1 | 'Não foi possível converter esta regra para texto.', 30 | 'for %count% times' => 'por %count% vezes', 31 | 'for one time' => 'uma vez', 32 | '(~ approximate)' => '(~ approximado)', 33 | 'until %date%' => 'até %date%', // e.g. every year until July 4, 2014 34 | 'day_date' => function ($str, $params) use ($days, $months) { // outputs a day date, e.g. July 4, 2014 35 | return date('j', $params['date']) . ' de ' . $months[date('n', $params['date']) - 1] . ' de ' . date('Y', $params['date']); 36 | }, 37 | 'day_month' => function ($str, $params) use ($days, $months) { // outputs a day month, e.g. July 4 38 | return $params['day'].' de '.$months[$params['month'] - 1]; 39 | }, 40 | 'day_names' => $days, 41 | 'month_names' => $months, 42 | 'and' => 'e', 43 | 'or' => 'ou', 44 | 'in_month' => 'em', // e.g. weekly in January, May and August 45 | 'in_week' => 'na', // e.g. yearly in week 3 46 | 'on' => 'à', // e.g. every day on Tuesday, Wednesday and Friday 47 | 'the_for_monthday' => 'o', // e.g. monthly on Tuesday the 1st 48 | 'the_for_weekday' => 'o', // e.g. monthly on the 4th Monday 49 | 'on the' => 'no', // e.g. every year on the 1st and 200th day 50 | 'of_the_month' => 'do mês', // e.g. every year on the 2nd or 3rd of the month 51 | 'every %count% years' => 'a cada %count% anos', 52 | 'every year' => 'anualmente', 53 | 'every_month_list' => 'sempre em', // e.g. every January, May and August 54 | 'every %count% months' => 'a cada %count% meses', 55 | 'every month' => 'mensalmente', 56 | 'every %count% weeks' => 'a cada %count% semanas', 57 | 'every week' => 'semanalmente', 58 | 'every %count% days' => 'a cada %count% dias', 59 | 'every day' => 'diariamente', 60 | 'last' => 'último', // e.g. 2nd last Friday 61 | 'days' => 'dias', 62 | 'day' => 'dia', 63 | 'weeks' => 'semanas', 64 | 'week' => 'semana', 65 | // formats a number with a prefix e.g. every year on the 1st and 200th day 66 | // negative numbers should be handled as in '5th to the last' or 'last' 67 | // 68 | // if has_negatives is true in the params, it is good form to add 'day' after 69 | // each number, as in: 'every month on the 5th day or 2nd to the last day' or 70 | // it may be confusing like 'every month on the 5th or 2nd to the last day' 71 | 'ordinal_number' => function ($str, $params) { 72 | $number = $params['number']; 73 | 74 | $abbreviation = $number.'°'; 75 | $isNegative = $number < 0; 76 | if ($isNegative) { 77 | $abbreviation = $abbreviation.' último'; 78 | } 79 | 80 | $suffix = ''; 81 | if (!empty($params['has_negatives'])) { 82 | $suffix .= ' dia'; 83 | } 84 | 85 | return $abbreviation . $suffix; 86 | }, 87 | ); 88 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/lib/Doctrine/Common/Collections/Collection.php: -------------------------------------------------------------------------------- 1 | ordered map that can also be used 13 | * like a list. 14 | * 15 | * A Collection has an internal iterator just like a PHP array. In addition, 16 | * a Collection can be iterated with external iterators, which is preferable. 17 | * To use an external iterator simply use the foreach language construct to 18 | * iterate over the collection (which calls {@link getIterator()} internally) or 19 | * explicitly retrieve an iterator though {@link getIterator()} which can then be 20 | * used to iterate over the collection. 21 | * You can not rely on the internal iterator of the collection being at a certain 22 | * position unless you explicitly positioned it before. Prefer iteration with 23 | * external iterators. 24 | * 25 | * @psalm-template TKey of array-key 26 | * @psalm-template T 27 | * @template-extends ReadableCollection 28 | * @template-extends ArrayAccess 29 | */ 30 | interface Collection extends ReadableCollection, ArrayAccess 31 | { 32 | /** 33 | * Adds an element at the end of the collection. 34 | * 35 | * @param mixed $element The element to add. 36 | * @psalm-param T $element 37 | * 38 | * @return true Always TRUE. 39 | */ 40 | public function add($element); 41 | 42 | /** 43 | * Clears the collection, removing all elements. 44 | * 45 | * @return void 46 | */ 47 | public function clear(); 48 | 49 | /** 50 | * Removes the element at the specified index from the collection. 51 | * 52 | * @param string|int $key The key/index of the element to remove. 53 | * @psalm-param TKey $key 54 | * 55 | * @return mixed The removed element or NULL, if the collection did not contain the element. 56 | * @psalm-return T|null 57 | */ 58 | public function remove($key); 59 | 60 | /** 61 | * Removes the specified element from the collection, if it is found. 62 | * 63 | * @param mixed $element The element to remove. 64 | * @psalm-param T $element 65 | * 66 | * @return bool TRUE if this collection contained the specified element, FALSE otherwise. 67 | */ 68 | public function removeElement($element); 69 | 70 | /** 71 | * Sets an element in the collection at the specified key/index. 72 | * 73 | * @param string|int $key The key/index of the element to set. 74 | * @param mixed $value The element to set. 75 | * @psalm-param TKey $key 76 | * @psalm-param T $value 77 | * 78 | * @return void 79 | */ 80 | public function set($key, $value); 81 | 82 | /** 83 | * {@inheritdoc} 84 | * 85 | * @return Collection A collection with the results of the filter operation. 86 | * @psalm-return Collection 87 | */ 88 | public function filter(Closure $p); 89 | 90 | /** 91 | * {@inheritdoc} 92 | * 93 | * @return Collection[] An array with two elements. The first element contains the collection 94 | * of elements where the predicate returned TRUE, the second element 95 | * contains the collection of elements where the predicate returned FALSE. 96 | * @psalm-return array{0: Collection, 1: Collection} 97 | */ 98 | public function partition(Closure $p); 99 | } 100 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/translations/tr.php: -------------------------------------------------------------------------------- 1 | 'Bu rrule tam metne dönüştürülemiyor.', 30 | 'for %count% times' => '%count% kez', 31 | 'for one time' => 'bir kere', 32 | '(~ approximate)' => '(~ yaklaşık)', 33 | 'until %date%' => 'kadar %date%', // e.g. 4 Temmuz 2014 e kadar her yıl 34 | 'day_date' => function ($str, $params) use ($days, $months) { // tarih çıktıları, e.g. Temmuz 4, 2014 35 | return $months[date('n', $params['date']) - 1] . ' '. date('j, Y', $params['date']); 36 | }, 37 | 'day_month' => function ($str, $params) use ($days, $months) { // outputs a day month, e.g. July 4 38 | return $months[$params['month'] - 1].' '.$params['day']; 39 | }, 40 | 'day_names' => $days, 41 | 'month_names' => $months, 42 | 'and' => 've', 43 | 'or' => 'veya', 44 | 'in_month' => 'içinde', // e.g. Ocak, Mayıs ve Ağustos'ta haftalık 45 | 'in_week' => 'içinde', // e.g. yıllık haftada 3 46 | 'on' => 'on', // e.g. her Salı, Çarşamba ve Cuma günü 47 | 'the_for_monthday' => 'the', // e.g. monthly on Tuesday the 1st 48 | 'the_for_weekday' => 'the', // e.g. monthly on the 4th Monday 49 | 'on the' => 'üzerinde', // e.g. her yıl 1. ve 200. günde 50 | 'of_the_month' => 'ayın', // e.g. her yıl 2. ve 3. ayın 51 | 'every %count% years' => 'every %count% years', 52 | 'every year' => 'yıllık', 53 | 'every_month_list' => 'her', // e.g. her Ocak, Mayıs ve Ağustos 54 | 'every %count% months' => 'her %count% ay', 55 | 'every month' => 'aylık', 56 | 'every %count% weeks' => 'her %count% hafta', 57 | 'every week' => 'haftalık', 58 | 'every %count% days' => 'her %count% gün', 59 | 'every day' => 'günlük', 60 | 'last' => 'son', // e.g. 2nd last Friday 61 | 'days' => 'günler', 62 | 'day' => 'gün', 63 | 'weeks' => 'haftalar', 64 | 'week' => 'hafta', 65 | // formats a number with a prefix e.g. every year on the 1st and 200th day 66 | // negative numbers should be handled as in '5th to the last' or 'last' 67 | // 68 | // if has_negatives is true in the params, it is good form to add 'day' after 69 | // each number, as in: 'every month on the 5th day or 2nd to the last day' or 70 | // it may be confusing like 'every month on the 5th or 2nd to the last day' 71 | 'ordinal_number' => function ($str, $params) { 72 | $number = $params['number']; 73 | 74 | $ends = array('th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th'); 75 | $suffix = ''; 76 | 77 | $isNegative = $number < 0; 78 | 79 | if ($number == -1) { 80 | $abbreviation = 'son'; 81 | } else { 82 | if ($isNegative) { 83 | $number = abs($number); 84 | $suffix = ' sonuna kadar'; 85 | } 86 | 87 | if (($number % 100) >= 11 && ($number % 100) <= 13) { 88 | $abbreviation = $number.'th'; 89 | } else { 90 | $abbreviation = $number.$ends[$number % 10]; 91 | } 92 | } 93 | 94 | if (!empty($params['has_negatives'])) { 95 | $suffix .= ' gün'; 96 | } 97 | 98 | return $abbreviation . $suffix; 99 | }, 100 | ); 101 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/translations/sv.php: -------------------------------------------------------------------------------- 1 | 'Kunde inte konvertera denna rrule till text.', 30 | 'for %count% times' => '%count% gånger', 31 | 'for one time' => 'en gång', 32 | '(~ approximate)' => '(~ ungefärlig)', 33 | 'until %date%' => 't.o.m. %date%', // e.g. every year until July 4, 2014 34 | 'day_date' => function ($str, $params) use ($days, $months) { // outputs a day date, e.g. July 4, 2014 35 | return $months[date('n', $params['date']) - 1] . ' '. date('j, Y', $params['date']); 36 | }, 37 | 'day_month' => function ($str, $params) use ($days, $months) { // outputs a day month, e.g. July 4 38 | return $months[$params['month'] - 1].' '.$params['day']; 39 | }, 40 | 'day_names' => $days, 41 | 'month_names' => $months, 42 | 'and' => 'och', 43 | 'or' => 'eller', 44 | 'in_month' => 'i', // e.g. weekly in January, May and August 45 | 'in_week' => 'i', // e.g. yearly in week 3 46 | 'on' => 'på', // e.g. every day on Tuesday, Wednesday and Friday 47 | 'the_for_monthday' => 'den', // e.g. monthly on Tuesday the 1st 48 | 'the_for_weekday' => 'den', // e.g. monthly on the 4th Monday 49 | 'on the' => 'på den', // e.g. every year on the 1st and 200th day 50 | 'of_the_month' => 'i månaden', // e.g. every year on the 2nd or 3rd of the month 51 | 'every %count% years' => 'varje %count% år', 52 | 'every year' => 'årligen', 53 | 'every_month_list' => 'varje', // e.g. every January, May and August 54 | 'every %count% months' => 'varje %count% månad', 55 | 'every month' => 'månadsvis', 56 | 'every %count% weeks' => 'varje %count% vecka', 57 | 'every week' => 'veckovis', 58 | 'every %count% days' => 'varje %count% dag', 59 | 'every day' => 'dagligen', 60 | 'last' => 'sista', // e.g. 2nd last Friday 61 | 'days' => 'dagar', 62 | 'day' => 'dag', 63 | 'weeks' => 'veckor', 64 | 'week' => 'vecka', 65 | // formats a number with a prefix e.g. every year on the 1st and 200th day 66 | // negative numbers should be handled as in '5th to the last' or 'last' 67 | // 68 | // if has_negatives is true in the params, it is good form to add 'day' after 69 | // each number, as in: 'every month on the 5th day or 2nd to the last day' or 70 | // it may be confusing like 'every month on the 5th or 2nd to the last day' 71 | 'ordinal_number' => function ($str, $params) { 72 | $number = $params['number']; 73 | 74 | $ends = array(':e', ':a', ':a', ':e', ':e', ':e', ':e', ':e', ':e', ':e'); 75 | $suffix = ''; 76 | 77 | $isNegative = $number < 0; 78 | 79 | if ($number == -1) { 80 | $abbreviation = 'last'; 81 | } else { 82 | if ($isNegative) { 83 | $number = abs($number); 84 | $suffix = ' to the last'; 85 | } 86 | 87 | if (($number % 100) >= 11 && ($number % 100) <= 13) { 88 | $abbreviation = $number.'th'; 89 | } else { 90 | $abbreviation = $number.$ends[$number % 10]; 91 | } 92 | } 93 | 94 | if (!empty($params['has_negatives'])) { 95 | $suffix .= ' dag'; 96 | } 97 | 98 | return $abbreviation . $suffix; 99 | }, 100 | ); 101 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/translations/da.php: -------------------------------------------------------------------------------- 1 | 'Kunne ikke konvertere denne regel til tekst.', 30 | 'for %count% times' => '%count% gange', 31 | 'for one time' => 'en gang', 32 | '(~ approximate)' => '(~ cirka)', 33 | 'until %date%' => 't.o.m. %date%', // e.g. every year until July 4, 2014 34 | 'day_date' => function ($str, $params) use ($days, $months) { // outputs a day date, e.g. July 4, 2014 35 | return date('j', $params['date']) . '. '. $months[date('n', $params['date']) - 1].date(', Y', $params['date']); 36 | }, 37 | 'day_month' => function ($str, $params) use ($days, $months) { // outputs a day month, e.g. July 4 38 | return $params['day'].'. '.$months[$params['month'] - 1]; 39 | }, 40 | 'day_names' => $days, 41 | 'month_names' => $months, 42 | 'and' => 'og', 43 | 'or' => 'eller', 44 | 'in_month' => 'i', // e.g. weekly in January, May and August 45 | 'in_week' => 'i', // e.g. yearly in week 3 46 | 'on' => 'hver', // e.g. every day on Tuesday, Wednesday and Friday 47 | 'the_for_monthday' => 'den', // e.g. monthly on Tuesday the 1st 48 | 'the_for_weekday' => 'den', // e.g. monthly on the 4th Monday 49 | 'on the' => 'på den', // e.g. every year on the 1st and 200th day 50 | 'of_the_month' => 'i måneden', // e.g. every year on the 2nd or 3rd of the month 51 | 'every %count% years' => 'hvert %count% år', 52 | 'every year' => 'årligt', 53 | 'every_month_list' => 'hver', // e.g. every January, May and August 54 | 'every %count% months' => 'hver %count% måned', 55 | 'every month' => 'månedsvis', 56 | 'every %count% weeks' => 'hver %count% uge', 57 | 'every week' => 'ugenligt', 58 | 'every %count% days' => 'hver %count% dag', 59 | 'every day' => 'dagligt', 60 | 'last' => 'sidste', // e.g. 2nd last Friday 61 | 'days' => 'dage', 62 | 'day' => 'dag', 63 | 'weeks' => 'uger', 64 | 'week' => 'uge', 65 | // formats a number with a prefix e.g. every year on the 1st and 200th day 66 | // negative numbers should be handled as in '5th to the last' or 'last' 67 | // 68 | // if has_negatives is true in the params, it is good form to add 'day' after 69 | // each number, as in: 'every month on the 5th day or 2nd to the last day' or 70 | // it may be confusing like 'every month on the 5th or 2nd to the last day' 71 | 'ordinal_number' => function ($str, $params) { 72 | $number = $params['number']; 73 | 74 | $ends = array(':e', ':a', ':a', ':e', ':e', ':e', ':e', ':e', ':e', ':e'); 75 | $suffix = ''; 76 | 77 | $isNegative = $number < 0; 78 | 79 | if ($number == -1) { 80 | $abbreviation = 'last'; 81 | } else { 82 | if ($isNegative) { 83 | $number = abs($number); 84 | $suffix = ' to the last'; 85 | } 86 | 87 | if (($number % 100) >= 11 && ($number % 100) <= 13) { 88 | $abbreviation = $number.'.'; 89 | } else { 90 | $abbreviation = $number.$ends[$number % 10]; 91 | } 92 | } 93 | 94 | if (!empty($params['has_negatives'])) { 95 | $suffix .= ' dag'; 96 | } 97 | 98 | return $abbreviation . $suffix; 99 | }, 100 | ); -------------------------------------------------------------------------------- /vendor/simshaun/recurr/translations/es.php: -------------------------------------------------------------------------------- 1 | 'No se puede convertir completamente este RRULE al texto.', 30 | 'for %count% times' => 'para %count% veces', 31 | 'for one time' => 'por una vez', 32 | '(~ approximate)' => '(~ aproximado)', 33 | 'until %date%' => 'hasta %date%', // e.g. every year until July 4, 2014 34 | 'day_date' => function ($str, $params) use ($days, $months) { // outputs a day date, e.g. July 4, 2014 35 | return $months[date('n', $params['date']) - 1] . ' '. date('j, Y', $params['date']); 36 | }, 37 | 'day_month' => function ($str, $params) use ($days, $months) { // outputs a day month, e.g. July 4 38 | return $months[$params['month'] - 1] . ' '. $params['day']; 39 | }, 40 | 'day_names' => $days, 41 | 'month_names' => $months, 42 | 'and' => 'y', 43 | 'or' => 'o', 44 | 'in_month' => 'en', // e.g. weekly in January, May and August 45 | 'in_week' => 'en', // e.g. yearly in week 3 46 | 'on' => 'en', // e.g. every day on Tuesday, Wednesday and Friday 47 | 'the_for_monthday' => 'el', // e.g. monthly on Tuesday the 1st 48 | 'the_for_weekday' => 'en el', // e.g. monthly on the 4th Monday 49 | 'on the' => 'en el', // e.g. every year on the 1st and 200th day 50 | 'of_the_month' => 'del mes', // e.g. every year on the 2nd or 3rd of the month 51 | 'every %count% years' => 'cada %count% años', 52 | 'every year' => 'anual', 53 | 'every_month_list' => 'cada', // e.g. every January, May and August 54 | 'every %count% months' => 'cada %count% meses', 55 | 'every month' => 'mensual', 56 | 'every %count% weeks' => 'cada %count% semanas', 57 | 'every week' => 'cada semana', 58 | 'every %count% days' => 'cada %count% días', 59 | 'every day' => 'diariamente', 60 | 'last' => 'pasado', // e.g. 2nd last Friday 61 | 'days' => 'día', 62 | 'day' => 'el día', 63 | 'weeks' => 'semanas', 64 | 'week' => 'semana', 65 | // formats a number with a prefix e.g. every year on the 1st and 200th day 66 | // negative numbers should be handled as in '5th to the last' or 'last' 67 | // 68 | // if has_negatives is true in the params, it is good form to add 'day' after 69 | // each number, as in: 'every month on the 5th day or 2nd to the last day' or 70 | // it may be confusing like 'every month on the 5th or 2nd to the last day' 71 | 'ordinal_number' => function ($str, $params) { 72 | $number = $params['number']; 73 | 74 | $ends = array('a', 'a', 'nd', 'a', 'a', 'a', 'a', 'a', 'a', 'a'); 75 | $suffix = ''; 76 | 77 | $isNegative = $number < 0; 78 | 79 | if ($number == -1) { 80 | $abbreviation = 'último'; 81 | } else { 82 | if ($isNegative) { 83 | $number = abs($number); 84 | $suffix = ' a la última'; 85 | } 86 | 87 | if (($number % 100) >= 11 && ($number % 100) <= 13) { 88 | $abbreviation = $number.'a'; 89 | } else { 90 | $abbreviation = $number.$ends[$number % 10]; 91 | } 92 | } 93 | 94 | if (!empty($params['has_negatives'])) { 95 | $suffix .= ' día'; 96 | } 97 | 98 | return $abbreviation . $suffix; 99 | }, 100 | ); 101 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/translations/nl.php: -------------------------------------------------------------------------------- 1 | 'Unable to fully convert this rrule to text.', 30 | 'for %count% times' => 'voor %count% keer', 31 | 'for one time' => 'eenmalig', 32 | '(~ approximate)' => '(~ ongeveer)', 33 | 'until %date%' => 'tot en met %date%', // e.g. every year until July 4, 2014 34 | 'day_date' => function ($str, $params) use ($days, $months) { // outputs a day date, e.g. July 4, 2014 35 | return date('j', $params['date']).' '.$months[date('n', $params['date']) - 1] . ' '. date('Y', $params['date']); 36 | }, 37 | 'day_month' => function ($str, $params) use ($days, $months) { // outputs a day month, e.g. July 4 38 | return $params['day'].' '.$months[$params['month'] - 1]; 39 | }, 40 | 'day_names' => $days, 41 | 'month_names' => $months, 42 | 'and' => 'en', 43 | 'or' => 'of', 44 | 'in_month' => 'op', // e.g. weekly in January, May and August 45 | 'in_week' => 'op', // e.g. yearly in week 3 46 | 'on' => 'op', // e.g. every day on Tuesday, Wednesday and Friday 47 | 'the_for_monthday' => 'de', // e.g. monthly on Tuesday the 1st 48 | 'the_for_weekday' => 'de', // e.g. monthly on the 4th Monday 49 | 'on the' => 'op de', // e.g. every year on the 1st and 200th day 50 | 'of_the_month' => 'van de maand', // e.g. every year on the 2nd or 3rd of the month 51 | 'every %count% years' => 'elke %count% jaar', 52 | 'every year' => 'jaarlijks', 53 | 'every_month_list' => 'elke', // e.g. every January, May and August 54 | 'every %count% months' => 'elke %count% maanden', 55 | 'every month' => 'maandelijks', 56 | 'every %count% weeks' => 'elke %count% weken', 57 | 'every week' => 'wekelijks', 58 | 'every %count% days' => 'elke %count% dagen', 59 | 'every day' => 'dagelijks', 60 | 'last' => 'laatste', // e.g. 2nd last Friday 61 | 'days' => 'dagen', 62 | 'day' => 'dag', 63 | 'weeks' => 'weken', 64 | 'week' => 'week', 65 | // formats a number with a prefix e.g. every year on the 1st and 200th day 66 | // negative numbers should be handled as in '5th to the last' or 'last' 67 | // 68 | // if has_negatives is true in the params, it is good form to add 'day' after 69 | // each number, as in: 'every month on the 5th day or 2nd to the last day' or 70 | // it may be confusing like 'every month on the 5th or 2nd to the last day' 71 | 'ordinal_number' => function ($str, $params) { 72 | $number = $params['number']; 73 | 74 | $ends = array('ste', 'de', 'de', 'de', 'de', 'de', 'de', 'de', 'de', 'de'); 75 | $suffix = ''; 76 | 77 | $isNegative = $number < 0; 78 | 79 | if ($number == -1) { 80 | $abbreviation = 'laatste'; 81 | } else { 82 | if ($isNegative) { 83 | $number = abs($number); 84 | $suffix = ' na laatste'; 85 | } 86 | 87 | if (($number % 100) >= 11 && ($number % 100) <= 13) { 88 | $abbreviation = $number.'ste'; 89 | } else { 90 | $abbreviation = $number.$ends[$number % 10]; 91 | } 92 | } 93 | 94 | if (!empty($params['has_negatives'])) { 95 | $suffix .= ' dag'; 96 | } 97 | 98 | return $abbreviation . $suffix; 99 | }, 100 | ); 101 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kirby Recurr 2 | 3 | This plugin integrates the Recurr library to make it easier to work with repeating dates (like events on a calender). 4 | 5 | ## Install 6 | 7 | ### Download 8 | 9 | Download and copy this repository to `/site/plugins/kirby-recurr`. 10 | 11 | ### Composer 12 | 13 | ``` 14 | composer require hashandsalt/kirby-recurr 15 | ``` 16 | 17 | **** 18 | 19 | ## Commerical Usage 20 | 21 | This plugin is free but if you use it in a commercial project please consider to 22 | - [make a donation 🍻](https://paypal.me/hashandsalt?locale.x=en_GB) or 23 | - [buy a Kirby license using this affiliate link](https://a.paddle.com/v2/click/1129/36141?link=1170) 24 | 25 | **** 26 | 27 | 28 | ## Usage 29 | 30 | Use as a site method with manual dates: 31 | 32 | ``` 33 | $datelist = $site->recurr('2019-09-10 20:00:00', '2019-09-11 02:00:00', 'WEEKLY', ['WE', 'TH', 'FR'], '2019-10-11'); 34 | ``` 35 | 36 | or with field data: 37 | 38 | ``` 39 | $datelist = $site->recurr($page->estart(), $page->eend()->or($page->estart()), $page->efreq()->recurrfreq(), $page->ebyday()->recurrdays(), $page->erange()); 40 | ``` 41 | 42 | By default the plugin returns an array of dates for start and end times for each. If you want an RRule instead, you set true on the end: 43 | 44 | ``` 45 | $datelist = $site->recurr($page->estart(), $page->eend()->or($page->estart()), $page->efreq()->recurrfreq(), $page->ebyday()->recurrdays(), $page->erange(), true); 46 | ``` 47 | 48 | End date is optional: 49 | 50 | ``` 51 | $datelist = $site->recurr($page->estart(), null, $page->efreq()->recurrfreq(), $page->ebyday()->recurrdays(), $page->erange()); 52 | ``` 53 | 54 | By day is only used if the frequency is set to either MONTHLY or YEARLY. 55 | 56 | ## Field Methods 57 | 58 | By day and Frequency need to be in uppercase, for convenience there are 2 field methods to do this for you: 59 | 60 | ``` 61 | $page->efreq()->recurrfreq() 62 | $page->ebyday()->recurrdays() 63 | 64 | ``` 65 | 66 | ## Example Use 67 | 68 | 69 | In the example above, we are feeding it Start Time, End Time, Frequency, Days to repeat on and the date to stop the range. The above example repeats every week but only on Wednesdays, Thursdays and Fridays. Then you can loop through it: 70 | 71 | ### Date/Time Array 72 | ``` 73 | 74 | 75 | 76 | 77 | 78 | 79 | recurr($page->estart(), $page->eend()->or($page->estart()), $page->efreq()->recurrfreq(), $page->ebyday()->recurrdays(), $page->erange()); 82 | 83 | foreach($datelist as $event): ?> 84 | 85 | 86 | 87 | 88 | 89 |
Session StartSession End
90 | ``` 91 | ### RRule 92 | 93 | If your working with a calendar like fullcalender.js that supports RRules, you can get that like so: 94 | 95 | ``` 96 | recurr($page->estart(), $page->eend()->or($page->estart()), $page->efreq()->recurrfreq(), $page->ebyday()->recurrdays(), $page->erange(), true); 98 | echo $datelist; 99 | ?> 100 | ``` 101 | 102 | ### Filter past dates 103 | 104 | For convenience, the plugin contains a collection filter that will remove events that have happened before a certain date. 105 | 106 | ``` 107 | $events = $kirby->collection('events')->filterBy($field, 'datebefore', $beforedate); 108 | ``` 109 | 110 | To see this in action, you can use the snippet provided with the plugin to list upcoming events, assuming you have a collection called 'events': 111 | 112 | ``` 113 | 'estart', 'beforedate' => date('Y-m-d H:i:s')]) ?> 114 | ``` 115 | 116 | 117 | ## Options 118 | 119 | Default time zone is `Europe/London`, and time format is `09-12-19 2:00am`. 120 | 121 | You can reset these in your config: 122 | 123 | ``` 124 | 'hashandsalt.recurr.timezone' => 'Europe/London', 125 | 'hashandsalt.recurr.format' => 'm-d-y g:ia', 126 | ``` 127 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/translations/en.php: -------------------------------------------------------------------------------- 1 | 'Unable to fully convert this rrule to text.', 30 | 'for %count% times' => 'for %count% times', 31 | 'for one time' => 'once', 32 | '(~ approximate)' => '(~ approximate)', 33 | 'until %date%' => 'until %date%', // e.g. every year until July 4, 2014 34 | 'day_date' => function ($str, $params) use ($days, $months) { // outputs a day date, e.g. July 4, 2014 35 | return $months[date('n', $params['date']) - 1] . ' '. date('j, Y', $params['date']); 36 | }, 37 | 'day_month' => function ($str, $params) use ($days, $months) { // outputs a day month, e.g. July 4 38 | return $months[$params['month'] - 1] . ' '. $params['day']; 39 | }, 40 | 'day_names' => $days, 41 | 'month_names' => $months, 42 | 'and' => 'and', 43 | 'or' => 'or', 44 | 'in_month' => 'in', // e.g. weekly in January, May and August 45 | 'in_week' => 'in', // e.g. yearly in week 3 46 | 'on' => 'on', // e.g. every day on Tuesday, Wednesday and Friday 47 | 'the_for_monthday' => 'the', // e.g. monthly on Tuesday the 1st 48 | 'the_for_weekday' => 'the', // e.g. monthly on the 4th Monday 49 | 'on the' => 'on the', // e.g. every year on the 1st and 200th day 50 | 'of_the_month' => 'of the month', // e.g. every year on the 2nd or 3rd of the month 51 | 'every %count% years' => 'every %count% years', 52 | 'every year' => 'yearly', 53 | 'every_month_list' => 'every', // e.g. every January, May and August 54 | 'every %count% months' => 'every %count% months', 55 | 'every month' => 'monthly', 56 | 'every %count% weeks' => 'every %count% weeks', 57 | 'every week' => 'weekly', 58 | 'every %count% days' => 'every %count% days', 59 | 'every day' => 'daily', 60 | 'every %count% hours' => 'every %count% hours', 61 | 'every hour' => 'hourly', 62 | 'last' => 'last', // e.g. 2nd last Friday 63 | 'days' => 'days', 64 | 'day' => 'day', 65 | 'weeks' => 'weeks', 66 | 'week' => 'week', 67 | 'hours' => 'hours', 68 | 'hour' => 'hour', 69 | // formats a number with a prefix e.g. every year on the 1st and 200th day 70 | // negative numbers should be handled as in '5th to the last' or 'last' 71 | // 72 | // if has_negatives is true in the params, it is good form to add 'day' after 73 | // each number, as in: 'every month on the 5th day or 2nd to the last day' or 74 | // it may be confusing like 'every month on the 5th or 2nd to the last day' 75 | 'ordinal_number' => function ($str, $params) { 76 | $number = $params['number']; 77 | 78 | $ends = array('th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th'); 79 | $suffix = ''; 80 | 81 | $isNegative = $number < 0; 82 | 83 | if ($number == -1) { 84 | $abbreviation = 'last'; 85 | } else { 86 | if ($isNegative) { 87 | $number = abs($number); 88 | $suffix = ' to the last'; 89 | } 90 | 91 | if (($number % 100) >= 11 && ($number % 100) <= 13) { 92 | $abbreviation = $number.'th'; 93 | } else { 94 | $abbreviation = $number.$ends[$number % 10]; 95 | } 96 | } 97 | 98 | if (!empty($params['has_negatives'])) { 99 | $suffix .= ' day'; 100 | } 101 | 102 | return $abbreviation . $suffix; 103 | }, 104 | ); 105 | -------------------------------------------------------------------------------- /vendor/getkirby/composer-installer/src/ComposerInstaller/Installer.php: -------------------------------------------------------------------------------- 1 | 14 | * @link https://getkirby.com 15 | * @copyright Bastian Allgeier GmbH 16 | * @license https://opensource.org/licenses/MIT 17 | */ 18 | class Installer extends LibraryInstaller 19 | { 20 | /** 21 | * Decides if the installer supports the given type 22 | * 23 | * @param string $packageType 24 | * @return bool 25 | */ 26 | public function supports($packageType): bool 27 | { 28 | throw new RuntimeException('This method needs to be overridden.'); // @codeCoverageIgnore 29 | } 30 | 31 | /** 32 | * Installs a specific package 33 | * 34 | * @param \Composer\Repository\InstalledRepositoryInterface $repo Repository in which to check 35 | * @param \Composer\Package\PackageInterface $package Package instance to install 36 | * @return \React\Promise\PromiseInterface|null 37 | */ 38 | public function install(InstalledRepositoryInterface $repo, PackageInterface $package) 39 | { 40 | // first install the package normally... 41 | $promise = parent::install($repo, $package); 42 | 43 | // ...then run custom code 44 | $postInstall = function () use ($package): void { 45 | $this->postInstall($package); 46 | }; 47 | 48 | // Composer 2 in async mode 49 | if ($promise instanceof PromiseInterface) { 50 | return $promise->then($postInstall); 51 | } 52 | 53 | // Composer 1 or Composer 2 without async 54 | $postInstall(); 55 | } 56 | 57 | /** 58 | * Updates a specific package 59 | * 60 | * @param \Composer\Repository\InstalledRepositoryInterface $repo Repository in which to check 61 | * @param \Composer\Package\PackageInterface $initial Already installed package version 62 | * @param \Composer\Package\PackageInterface $target Updated version 63 | * @return \React\Promise\PromiseInterface|null 64 | * 65 | * @throws \InvalidArgumentException if $initial package is not installed 66 | */ 67 | public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target) 68 | { 69 | // first update the package normally... 70 | $promise = parent::update($repo, $initial, $target); 71 | 72 | // ...then run custom code 73 | $postInstall = function () use ($target): void { 74 | $this->postInstall($target); 75 | }; 76 | 77 | // Composer 2 in async mode 78 | if ($promise instanceof PromiseInterface) { 79 | return $promise->then($postInstall); 80 | } 81 | 82 | // Composer 1 or Composer 2 without async 83 | $postInstall(); 84 | } 85 | 86 | /** 87 | * Custom handler that will be called after each package 88 | * installation or update 89 | * 90 | * @param \Composer\Package\PackageInterface $package 91 | * @return void 92 | */ 93 | protected function postInstall(PackageInterface $package) 94 | { 95 | // remove the package's `vendor` directory to avoid duplicated autoloader and vendor code 96 | $packageVendorDir = $this->getInstallPath($package) . '/vendor'; 97 | if (is_dir($packageVendorDir) === true) { 98 | $success = $this->filesystem->removeDirectory($packageVendorDir); 99 | 100 | if ($success !== true) { 101 | throw new RuntimeException('Could not completely delete ' . $packageVendorDir . ', aborting.'); // @codeCoverageIgnore 102 | } 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /vendor/getkirby/composer-installer/src/ComposerInstaller/PluginInstaller.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier GmbH 13 | * @license https://opensource.org/licenses/MIT 14 | */ 15 | class PluginInstaller extends Installer 16 | { 17 | /** 18 | * Decides if the installer supports the given type 19 | * 20 | * @param string $packageType 21 | * @return bool 22 | */ 23 | public function supports($packageType): bool 24 | { 25 | return $packageType === 'kirby-plugin'; 26 | } 27 | 28 | /** 29 | * Returns the installation path of a package 30 | * 31 | * @param \Composer\Package\PackageInterface $package 32 | * @return string path 33 | */ 34 | public function getInstallPath(PackageInterface $package): string 35 | { 36 | // place into `vendor` directory as usual if Pluginkit is not supported 37 | if ($this->supportsPluginkit($package) !== true) { 38 | return parent::getInstallPath($package); 39 | } 40 | 41 | // get the extra configuration of the top-level package 42 | if ($rootPackage = $this->composer->getPackage()) { 43 | $extra = $rootPackage->getExtra(); 44 | } else { 45 | $extra = []; 46 | } 47 | 48 | // use base path from configuration, otherwise fall back to default 49 | $basePath = $extra['kirby-plugin-path'] ?? 'site/plugins'; 50 | 51 | if (is_string($basePath) !== true) { 52 | throw new InvalidArgumentException('Invalid "kirby-plugin-path" option'); 53 | } 54 | 55 | // determine the plugin name from its package name; 56 | // can be overridden in the plugin's `composer.json` 57 | $prettyName = $package->getPrettyName(); 58 | $pluginExtra = $package->getExtra(); 59 | if (empty($pluginExtra['installer-name']) === false) { 60 | $name = $pluginExtra['installer-name']; 61 | 62 | if (is_string($name) !== true) { 63 | throw new InvalidArgumentException('Invalid "installer-name" option in plugin ' . $prettyName); 64 | } 65 | } elseif (strpos($prettyName, '/') !== false) { 66 | // use name after the slash 67 | $name = explode('/', $prettyName)[1]; 68 | } else { 69 | $name = $prettyName; 70 | } 71 | 72 | // build destination path from base path and plugin name 73 | return $basePath . '/' . $name; 74 | } 75 | 76 | /** 77 | * Custom handler that will be called after each package 78 | * installation or update 79 | * 80 | * @param \Composer\Package\PackageInterface $package 81 | * @return void 82 | */ 83 | protected function postInstall(PackageInterface $package): void 84 | { 85 | // only continue if Pluginkit is supported 86 | if ($this->supportsPluginkit($package) !== true) { 87 | return; 88 | } 89 | 90 | parent::postInstall($package); 91 | } 92 | 93 | /** 94 | * Checks if the package has explicitly required this installer; 95 | * otherwise (if the Pluginkit is not yet supported by the plugin) 96 | * the installer will fall back to the behavior of the LibraryInstaller 97 | * 98 | * @param \Composer\Package\PackageInterface $package 99 | * @return bool 100 | */ 101 | protected function supportsPluginkit(PackageInterface $package): bool 102 | { 103 | foreach ($package->getRequires() as $link) { 104 | if ($link->getTarget() === 'getkirby/composer-installer') { 105 | return true; 106 | } 107 | } 108 | 109 | // no required package is the installer 110 | return false; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/translations/el.php: -------------------------------------------------------------------------------- 1 | 'Αδυναμία πλήρους μετατροπής αυτού του κανόνα rrule σε κείμενο.', 44 | 'for %count% times' => 'για %count% φορές', 45 | 'for one time' => 'για μία φορά', 46 | '(~ approximate)' => '(~ κατά προσέγγιση)', 47 | 'until %date%' => 'μέχρι %date%', // e.g. every year until July 4, 2014 48 | 'day_date' => function ($str, $params) use ($days, $months_genitive) { // outputs a day date, e.g. 4 Ιουλίου 2014 49 | return date('j', $params['date']) . ' ' . $months_genitive[date('n', $params['date']) - 1] . ' '. date('Y', $params['date']); 50 | }, 51 | 'day_month' => function ($str, $params) use ($days, $months_genitive) { // outputs a day month, e.g. 4 Ιουλίου 52 | return $params['day'] . ' ' . $months_genitive[$params['month'] - 1]; 53 | }, 54 | 'day_names' => $days, 55 | 'month_names' => $months, 56 | 'and' => 'και', 57 | 'or' => 'ή', 58 | 'in_month' => 'τον', // e.g. weekly in January, May and August 59 | 'in_week' => 'την', // e.g. yearly in week 3 60 | 'on' => 'την', // e.g. every day on Tuesday, Wednesday and Friday 61 | 'the_for_monthday' => 'την', // e.g. monthly on Tuesday the 1st 62 | 'the_for_weekday' => 'την', // e.g. monthly on the 4th Monday 63 | 'on the' => 'την', // e.g. every year on the 1st and 200th day 64 | 'of_the_month' => 'του μήνα', // e.g. every year on the 2nd or 3rd of the month 65 | 'every %count% years' => 'κάθε %count% χρόνια', 66 | 'every year' => 'ετήσια', 67 | 'every_month_list' => 'κάθε', // e.g. every January, May and August 68 | 'every %count% months' => 'κάθε %count% μήνες', 69 | 'every month' => 'μηνιαία', 70 | 'every %count% weeks' => 'κάθε %count% εβδομάδες', 71 | 'every week' => 'εβδομαδιαία', 72 | 'every %count% days' => 'κάθε %count% ημέρες', 73 | 'every day' => 'καθημερινά', 74 | 'last' => 'τελευταία', // e.g. 2nd last Friday 75 | 'days' => 'ημέρες', 76 | 'day' => 'ημέρα', 77 | 'weeks' => 'εβδομάδες', 78 | 'week' => 'εβδομάδα', 79 | // formats a number with a prefix e.g. every year on the 1st and 200th day 80 | // negative numbers should be handled as in '5th to the last' or 'last' 81 | // 82 | // if has_negatives is true in the params, it is good form to add 'day' after 83 | // each number, as in: 'every month on the 5th day or 2nd to the last day' or 84 | // it may be confusing like 'every month on the 5th or 2nd to the last day' 85 | 'ordinal_number' => function ($str, $params) { 86 | $number = $params['number']; 87 | 88 | $ends = 'η'; 89 | $suffix = ''; 90 | 91 | $isNegative = $number < 0; 92 | 93 | if ($number == -1) { 94 | $abbreviation = 'τελευταία'; 95 | } else { 96 | if ($isNegative) { 97 | $number = abs($number); 98 | $suffix = ' μέχρι την τελευταία'; 99 | } 100 | 101 | $abbreviation = $number . $ends; 102 | } 103 | 104 | if (!empty($params['has_negatives'])) { 105 | $suffix .= ' ημέρα'; 106 | } 107 | 108 | return $abbreviation . $suffix; 109 | }, 110 | ); 111 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/translations/fr.php: -------------------------------------------------------------------------------- 1 | 'Cette règle de récurrence n\'a pas pu être convertie en texte.', 30 | 'for %count% times' => '%count% fois', 31 | 'for one time' => 'une fois', 32 | '(~ approximate)' => '(~ approximation)', 33 | 'until %date%' => 'jusqu\'au %date%', // e.g. every year until July 4, 2014 34 | 'day_date' => function ($str, $params) use ($days, $months) { // outputs a day date, e.g. 4 juillet, 2014 35 | return date('j ', $params['date']) . $months[date('n', $params['date']) - 1] . date(', Y', $params['date']); 36 | }, 37 | 'day_month' => function ($str, $params) use ($days, $months) { // outputs a day month, e.g. July 4 38 | return $params['day'].' '.$months[$params['month'] - 1]; 39 | }, 40 | 'day_names' => $days, 41 | 'month_names' => $months, 42 | 'and' => 'et', 43 | 'or' => 'ou', 44 | 'in_month' => 'en', // e.g. weekly in January, May and August 45 | 'in_week' => 'en', // e.g. yearly in week 3 46 | 'on' => 'le', // e.g. every day on Tuesday, Wednesday and Friday 47 | 'the_for_monthday' => 'le', // e.g. monthly on Tuesday the 1st 48 | 'the_for_weekday' => '', // e.g. monthly on the 4th Monday 49 | 'on the' => 'le', // e.g. every year on the 1st and 200th day 50 | 'of_the_month' => 'du mois', // e.g. every year on the 2nd or 3rd of the month 51 | 'every %count% years' => 'tous les %count% ans', 52 | 'every year' => 'chaque année', 53 | 'every_month_list' => 'chaque', // e.g. every January, May and August 54 | 'every %count% months' => 'tous les %count% mois', 55 | 'every month' => 'chaque mois', 56 | 'every %count% weeks' => 'toutes les %count% semaines', 57 | 'every week' => 'chaque semaine', 58 | 'every %count% days' => 'tous les %count% jours', 59 | 'every day' => 'chaque jour', 60 | 'every %count% hours' => 'toutes les %count% heures', 61 | 'every hour' => 'chaque heure', 62 | 'last' => 'dernier', // e.g. 2nd last Friday 63 | 'days' => 'jours', 64 | 'day' => 'jour', 65 | 'weeks' => 'semaines', 66 | 'week' => 'semaine', 67 | 'hours' => 'heures', 68 | 'hour' => 'heure', 69 | // formats a number with a prefix e.g. every year on the 1st and 200th day 70 | // negative numbers should be handled as in '5th to the last' or 'last' 71 | // 72 | // if has_negatives is true in the params, it is good form to add 'day' after 73 | // each number, as in: 'every month on the 5th day or 2nd to the last day' or 74 | // it may be confusing like 'every month on the 5th or 2nd to the last day' 75 | 'ordinal_number' => function ($str, $params) { 76 | $number = $params['number']; 77 | 78 | $suffix = ''; 79 | $isNegative = $number < 0; 80 | 81 | if ($number == -1) { 82 | $abbreviation = 'dernier'; 83 | } elseif ($number == -2) { 84 | $abbreviation = 'avant dernier'; 85 | } elseif ($isNegative) { 86 | $number = abs($number); 87 | $abbreviation = $number . 'ème au dernier'; 88 | } elseif ($number == 1 && (!$params['day_in_month'])) { 89 | $abbreviation = $number . 'er'; 90 | } else if (!$params['day_in_month']) { 91 | $abbreviation = $number . 'ème'; 92 | } 93 | else { 94 | $abbreviation = $number; 95 | } 96 | 97 | if (!empty($params['has_negatives'])) { 98 | $suffix .= ' jour'; 99 | } 100 | 101 | return $abbreviation . $suffix; 102 | }, 103 | ); 104 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 8 | * @copyright James Steel 9 | * @link https://github.com/HashandSalt/recurr 10 | * @license MIT 11 | */ 12 | 13 | @include_once __DIR__ . '/vendor/autoload.php'; 14 | 15 | Kirby::plugin('hashandsalt/recurr', [ 16 | 17 | // Options 18 | 'options' => [ 19 | 'timezone' => 'Europe/London', 20 | 'format' => 'm-d-y g:ia', 21 | ], 22 | 23 | // Snippets 24 | 'snippets' => [ 25 | // Upcoming 26 | 'events/upcoming' => __DIR__ . '/snippets/events/upcoming.php', 27 | ], 28 | 29 | // Blueprints 30 | 'blueprints' => [ 31 | // Fields 32 | 'fields/event' => __DIR__ . '/blueprints/fields/event.yml', 33 | ], 34 | 35 | // Filter Past Pages 36 | 'collectionFilters' => [ 37 | 'datebefore' => function ($collection, $field, $test, $split = false) { 38 | foreach ($collection->data as $key => $item ) { 39 | $datetime = $collection->getAttribute($item, $field, $split, $test); 40 | if (!$datetime || strtotime($datetime) > strtotime($test) ) { 41 | continue; 42 | } 43 | unset($collection->$key); 44 | } 45 | 46 | return $collection; 47 | } 48 | ], 49 | 50 | // Site Methods 51 | 'siteMethods' => [ 52 | 'recurr' => function ($start, $end, $freq, $byday, $until, $rrule = false) { 53 | 54 | $transformer = new \Recurr\Transformer\ArrayTransformer(); 55 | $rtimezone = option('hashandsalt.recurr.timezone'); 56 | 57 | $rstartDate = new \DateTime($start, new \DateTimeZone($rtimezone)); 58 | $rendDate = new \DateTime($end, new \DateTimeZone($rtimezone)); 59 | 60 | $rfreq = $freq; 61 | $rbyday = $byday; 62 | $runtil = $until; 63 | 64 | if ($rfreq == 'MONTHLY' || $rfreq == 'YEARLY') { 65 | 66 | if ($end !== null) { 67 | $recurr = (new \Recurr\Rule)->setTimezone($rtimezone)->setStartDate($rstartDate)->setEndDate($rendDate)->setFreq($freq)->setByDay($byday)->setUntil(new \DateTime($until)); 68 | } else { 69 | $recurr = (new \Recurr\Rule)->setTimezone($rtimezone)->setStartDate($rstartDate)->setFreq($freq)->setByDay($byday)->setUntil(new \DateTime($until)); 70 | } 71 | 72 | } else { 73 | 74 | if ($end !== null) { 75 | $recurr = (new \Recurr\Rule)->setTimezone($rtimezone)->setStartDate($rstartDate)->setEndDate($rendDate)->setFreq($freq)->setUntil(new \DateTime($until)); 76 | } else { 77 | $recurr = (new \Recurr\Rule)->setTimezone($rtimezone)->setStartDate($rstartDate)->setFreq($freq)->setUntil(new \DateTime($until)); 78 | } 79 | 80 | } 81 | 82 | // Output RRULE 83 | if ($rrule) { 84 | 85 | $dates = $recurr->getString(); 86 | 87 | } else { 88 | 89 | // Output Date time object 90 | $collection = $transformer->transform($recurr); 91 | // Output the dates 92 | $dates = $collection->map(function (\Recurr\Recurrence $recurrence) { 93 | 94 | $start = $recurrence->getStart()->format(option('hashandsalt.recurr.format')); 95 | $end = $recurrence->getEnd()->format(option('hashandsalt.recurr.format')); 96 | 97 | $datelist = ["start" => $start, "end" => $end]; 98 | 99 | return $datelist; 100 | 101 | })->toArray(); 102 | 103 | } 104 | 105 | 106 | return $dates; 107 | }, 108 | ], 109 | 110 | // Field Methods 111 | 'fieldMethods' => [ 112 | 'recurrdays' => function ($field) { 113 | $days = explode(', ', $field->upper()); 114 | return $days; 115 | }, 116 | 'recurrfreq' => function ($field) { 117 | $f = $field->upper()->value(); 118 | return $f; 119 | } 120 | ] 121 | 122 | 123 | ]); 124 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/docs/en/expression-builder.rst: -------------------------------------------------------------------------------- 1 | Expression Builder 2 | ================== 3 | 4 | The Expression Builder is a convenient fluent interface for 5 | building expressions to be used with the ``Doctrine\Common\Collections\Criteria`` 6 | class: 7 | 8 | .. code-block:: php 9 | $expressionBuilder = Criteria::expr(); 10 | 11 | $criteria = new Criteria(); 12 | $criteria->where($expressionBuilder->eq('name', 'jwage')); 13 | $criteria->orWhere($expressionBuilder->eq('name', 'romanb')); 14 | 15 | $collection->matching($criteria); 16 | 17 | The ``ExpressionBuilder`` has the following API: 18 | 19 | andX 20 | ---- 21 | 22 | .. code-block:: php 23 | $expressionBuilder = Criteria::expr(); 24 | 25 | $expression = $expressionBuilder->andX( 26 | $expressionBuilder->eq('foo', 1), 27 | $expressionBuilder->eq('bar', 1) 28 | ); 29 | 30 | $collection->matching(new Criteria($expression)); 31 | 32 | orX 33 | --- 34 | 35 | .. code-block:: php 36 | $expressionBuilder = Criteria::expr(); 37 | 38 | $expression = $expressionBuilder->orX( 39 | $expressionBuilder->eq('foo', 1), 40 | $expressionBuilder->eq('bar', 1) 41 | ); 42 | 43 | $collection->matching(new Criteria($expression)); 44 | 45 | eq 46 | --- 47 | 48 | .. code-block:: php 49 | $expressionBuilder = Criteria::expr(); 50 | 51 | $expression = $expressionBuilder->eq('foo', 1); 52 | 53 | $collection->matching(new Criteria($expression)); 54 | 55 | gt 56 | --- 57 | 58 | .. code-block:: php 59 | $expressionBuilder = Criteria::expr(); 60 | 61 | $expression = $expressionBuilder->gt('foo', 1); 62 | 63 | $collection->matching(new Criteria($expression)); 64 | 65 | lt 66 | --- 67 | 68 | .. code-block:: php 69 | $expressionBuilder = Criteria::expr(); 70 | 71 | $expression = $expressionBuilder->lt('foo', 1); 72 | 73 | $collection->matching(new Criteria($expression)); 74 | 75 | gte 76 | --- 77 | 78 | .. code-block:: php 79 | $expressionBuilder = Criteria::expr(); 80 | 81 | $expression = $expressionBuilder->gte('foo', 1); 82 | 83 | $collection->matching(new Criteria($expression)); 84 | 85 | lte 86 | --- 87 | 88 | .. code-block:: php 89 | $expressionBuilder = Criteria::expr(); 90 | 91 | $expression = $expressionBuilder->lte('foo', 1); 92 | 93 | $collection->matching(new Criteria($expression)); 94 | 95 | neq 96 | --- 97 | 98 | .. code-block:: php 99 | $expressionBuilder = Criteria::expr(); 100 | 101 | $expression = $expressionBuilder->neq('foo', 1); 102 | 103 | $collection->matching(new Criteria($expression)); 104 | 105 | isNull 106 | ------ 107 | 108 | .. code-block:: php 109 | $expressionBuilder = Criteria::expr(); 110 | 111 | $expression = $expressionBuilder->isNull('foo'); 112 | 113 | $collection->matching(new Criteria($expression)); 114 | 115 | in 116 | --- 117 | 118 | .. code-block:: php 119 | $expressionBuilder = Criteria::expr(); 120 | 121 | $expression = $expressionBuilder->in('foo', ['value1', 'value2']); 122 | 123 | $collection->matching(new Criteria($expression)); 124 | 125 | notIn 126 | ----- 127 | 128 | .. code-block:: php 129 | $expressionBuilder = Criteria::expr(); 130 | 131 | $expression = $expressionBuilder->notIn('foo', ['value1', 'value2']); 132 | 133 | $collection->matching(new Criteria($expression)); 134 | 135 | contains 136 | -------- 137 | 138 | .. code-block:: php 139 | $expressionBuilder = Criteria::expr(); 140 | 141 | $expression = $expressionBuilder->contains('foo', 'value1'); 142 | 143 | $collection->matching(new Criteria($expression)); 144 | 145 | memberOf 146 | -------- 147 | 148 | .. code-block:: php 149 | $expressionBuilder = Criteria::expr(); 150 | 151 | $expression = $expressionBuilder->memberOf('foo', ['value1', 'value2']); 152 | 153 | $collection->matching(new Criteria($expression)); 154 | 155 | startsWith 156 | ---------- 157 | 158 | .. code-block:: php 159 | $expressionBuilder = Criteria::expr(); 160 | 161 | $expression = $expressionBuilder->startsWith('foo', 'hello'); 162 | 163 | $collection->matching(new Criteria($expression)); 164 | 165 | endsWith 166 | -------- 167 | 168 | .. code-block:: php 169 | $expressionBuilder = Criteria::expr(); 170 | 171 | $expression = $expressionBuilder->endsWith('foo', 'world'); 172 | 173 | $collection->matching(new Criteria($expression)); 174 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/translations/de.php: -------------------------------------------------------------------------------- 1 | 'RRule kann nicht vollständig zu Text konvertiert werden.', 30 | 'for %count% times' => '%count% Mal', 31 | 'for one time' => 'einmal', 32 | '(~ approximate)' => '(~ ungefähr)', 33 | 'until %date%' => 'bis %date%', // e.g. every year until July 4, 2014 34 | 'day_date' => function ($str, $params) use ($days, $months) { // outputs a day date, e.g. 4. Juli, 2014 35 | return date('j. ', $params['date']) . $months[date('n', $params['date']) - 1] . date(', Y', $params['date']); 36 | }, 37 | 'day_month' => function ($str, $params) use ($days, $months) { // outputs a day month, e.g. July 4 38 | return $params['day'].'. '.$months[$params['month'] - 1]; 39 | }, 40 | 'day_names' => $days, 41 | 'month_names' => $months, 42 | 'and' => 'und', 43 | 'or' => 'oder', 44 | 'in_month' => 'im', // e.g. weekly in January, May and August 45 | 'in_week' => 'in', // e.g. yearly in week 3 46 | 'on' => 'am', // e.g. every day on Tuesday, Wednesday and Friday 47 | 'the_for_monthday' => 'dem', // e.g. monthly on Tuesday the 1st 48 | 'the_for_weekday' => '', // e.g. monthly on the 4th Monday 49 | 'on the' => 'am', // e.g. every year on the 1st and 200th day 50 | 'of_the_month' => 'des Monats', // e.g. every year on the 2nd or 3rd of the month 51 | 'every %count% years' => 'alle %count% Jahre', 52 | 'every year' => 'jährlich', 53 | 'every_month_list' => 'jeden', // e.g. every January, May and August 54 | 'every %count% months' => 'alle %count% Monate', 55 | 'every month' => 'monatlich', 56 | 'every %count% weeks' => 'alle %count% Wochen', 57 | 'every week' => 'wöchentlich', 58 | 'every %count% days' => 'alle %count% Tage', 59 | 'every day' => 'täglich', 60 | 'every %count% hours' => 'alle %count% Stunden', 61 | 'every hour' => 'stündlich', 62 | 'last' => 'letzte', // e.g. 2nd last Friday 63 | 'days' => 'Tage', 64 | 'day' => 'Tag', 65 | 'weeks' => 'Wochen', 66 | 'week' => 'Woche', 67 | 'hours' => 'Stunden', 68 | 'hour' => 'stündlich', 69 | // formats a number with a prefix e.g. every year on the 1st and 200th day 70 | // negative numbers should be handled as in '5th to the last' or 'last' 71 | // 72 | // if has_negatives is true in the params, it is good form to add 'day' after 73 | // each number, as in: 'every month on the 5th day or 2nd to the last day' or 74 | // it may be confusing like 'every month on the 5th or 2nd to the last day' 75 | 'ordinal_number' => function ($str, $params) { 76 | $number = $params['number']; 77 | 78 | $suffix = ''; 79 | $isNegative = $number < 0; 80 | 81 | if ($number == -1) { 82 | $abbreviation = 'letzten'; 83 | } elseif ($number == -2) { 84 | $abbreviation = 'vorletzten'; 85 | } elseif ($number == -3) { 86 | $abbreviation = 'drittletzten'; 87 | } elseif ($number == -4) { 88 | $abbreviation = 'viertletzten'; 89 | } elseif ($number == -5) { 90 | $abbreviation = 'fünftletzten'; 91 | } elseif ($number == -6) { 92 | $abbreviation = 'sechstletzten'; 93 | } elseif ($number == -7) { 94 | $abbreviation = 'siebtletzten'; 95 | } elseif ($number == -8) { 96 | $abbreviation = 'achtletzten'; 97 | } elseif ($number == -9) { 98 | $abbreviation = 'neuntletzten'; 99 | } elseif ($number == -10) { 100 | $abbreviation = 'zehntletzten'; 101 | } elseif ($number == -11) { 102 | $abbreviation = 'elftletzten'; 103 | } elseif ($isNegative) { 104 | $number = abs($number); 105 | $abbreviation = $number . 't letzten'; 106 | } else { 107 | $abbreviation = $number . '.'; 108 | } 109 | 110 | if (!empty($params['has_negatives']) && $isNegative) { 111 | $suffix .= ' Tag'; 112 | } 113 | 114 | return $abbreviation . $suffix; 115 | }, 116 | ); 117 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/translations/it.php: -------------------------------------------------------------------------------- 1 | 'Non è possibile convertire questo rrule in testo.', 30 | 'for %count% times' => 'per %count% volte', 31 | 'for one time' => 'per una volta', 32 | '(~ approximate)' => '(~ approssimato)', 33 | 'until %date%' => 'fino al %date%', // e.g. every year until July 4, 2014 34 | 'day_date' => function ($str, $params) use ($days, $months) { // outputs a day date, e.g. 4 luglio, 2014 35 | return date('j ', $params['date']) . $months[date('n', $params['date']) - 1] . date(', Y', $params['date']); 36 | }, 37 | 'day_month' => function ($str, $params) use ($days, $months) { // outputs a day month, e.g. July 4 38 | return $params['day'].' '.$months[$params['month'] - 1]; 39 | }, 40 | 'day_names' => $days, 41 | 'month_names' => $months, 42 | 'and' => 'e', 43 | 'or' => 'o', 44 | 'in_month' => 'in', // e.g. weekly in January, May and August 45 | 'in_week' => 'in', // e.g. yearly in week 3 46 | 'on' => 'il', // e.g. every day on Tuesday, Wednesday and Friday 47 | 'the_for_monthday' => 'il', // e.g. monthly on Tuesday the 1st 48 | 'the_for_weekday' => 'il', // e.g. monthly on the 4th Monday 49 | 'on the' => 'il', // e.g. every year on the 1st and 200th day 50 | 'of_the_month' => 'del mese', // e.g. every year on the 2nd or 3rd of the month 51 | 'every %count% years' => 'ogni %count% anni', 52 | 'every year' => 'ogni anno', 53 | 'every_month_list' => 'ogni', // e.g. every January, May and August 54 | 'every %count% months' => 'ogni %count% mesi', 55 | 'every month' => 'ogni mese', 56 | 'every %count% weeks' => 'ogni %count% settimane', 57 | 'every week' => 'ogni settimana', 58 | 'every %count% days' => 'ogni %count% giorni', 59 | 'every day' => 'ogni giorno', 60 | 'every %count% hours' => 'ogni %count% ore', 61 | 'every hour' => 'ogni ora', 62 | 'last' => 'scorso', // e.g. 2nd last Friday 63 | 'days' => 'giorni', 64 | 'day' => 'giorno', 65 | 'weeks' => 'settimane', 66 | 'week' => 'settimana', 67 | 'hours' => 'ore', 68 | 'hour' => 'ora', 69 | // formats a number with a prefix e.g. every year on the 1st and 200th day 70 | // negative numbers should be handled as in '5th to the last' or 'last' 71 | // 72 | // if has_negatives is true in the params, it is good form to add 'day' after 73 | // each number, as in: 'every month on the 5th day or 2nd to the last day' or 74 | // it may be confusing like 'every month on the 5th or 2nd to the last day' 75 | 'ordinal_number' => function ($str, $params) { 76 | $number = $params['number']; 77 | 78 | $suffix = ''; 79 | $isNegative = $number < 0; 80 | 81 | if ($number == -1) { 82 | $abbreviation = 'ultimo'; 83 | } elseif ($number == -2) { 84 | $abbreviation = 'penultimo'; 85 | } elseif ($number == -3) { 86 | $abbreviation = 'terzultimo'; 87 | } elseif ($number == -4) { 88 | $abbreviation = 'quarto ultimo'; 89 | } elseif ($number == -5) { 90 | $abbreviation = 'quinta ultimo'; 91 | } elseif ($number == -6) { 92 | $abbreviation = 'sesto ultimo'; 93 | } elseif ($number == -7) { 94 | $abbreviation = 'settimo ultimo'; 95 | } elseif ($number == -8) { 96 | $abbreviation = 'otto ultimo'; 97 | } elseif ($number == -9) { 98 | $abbreviation = 'nono ultimo'; 99 | } elseif ($number == -10) { 100 | $abbreviation = 'decimo ultimo'; 101 | } elseif ($number == -11) { 102 | $abbreviation = 'undici ultimo'; 103 | } elseif ($isNegative) { 104 | $number = abs($number); 105 | $abbreviation = $number . ' ultimo'; 106 | } else { 107 | $abbreviation = $number; 108 | } 109 | 110 | if (!empty($params['has_negatives'])) { 111 | $suffix .= ' giorno'; 112 | } 113 | 114 | return $abbreviation . $suffix; 115 | }, 116 | ); 117 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class RecurrenceCollection extends BaseCollection 19 | { 20 | /** 21 | * @param \DateTimeInterface $after 22 | * @param \DateTimeInterface $before 23 | * @param bool $inc Include $after or $before if they happen to be a recurrence. 24 | * 25 | * @return RecurrenceCollection 26 | */ 27 | public function startsBetween(\DateTimeInterface $after, \DateTimeInterface $before, $inc = false) 28 | { 29 | return $this->filter( 30 | function ($recurrence) use ($after, $before, $inc) { 31 | /** @var $recurrence Recurrence */ 32 | $start = $recurrence->getStart(); 33 | 34 | if ($inc) { 35 | return $start >= $after && $start <= $before; 36 | } 37 | 38 | return $start > $after && $start < $before; 39 | } 40 | ); 41 | } 42 | 43 | /** 44 | * @param \DateTimeInterface $before 45 | * @param bool $inc Include $before if it is a recurrence. 46 | * 47 | * @return RecurrenceCollection 48 | */ 49 | public function startsBefore(\DateTimeInterface $before, $inc = false) 50 | { 51 | return $this->filter( 52 | function ($recurrence) use ($before, $inc) { 53 | /** @var $recurrence Recurrence */ 54 | $start = $recurrence->getStart(); 55 | 56 | if ($inc) { 57 | return $start <= $before; 58 | } 59 | 60 | return $start < $before; 61 | } 62 | ); 63 | } 64 | 65 | /** 66 | * @param \DateTimeInterface $after 67 | * @param bool $inc Include $after if it a recurrence. 68 | * 69 | * @return RecurrenceCollection 70 | */ 71 | public function startsAfter(\DateTimeInterface $after, $inc = false) 72 | { 73 | return $this->filter( 74 | function ($recurrence) use ($after, $inc) { 75 | /** @var $recurrence Recurrence */ 76 | $start = $recurrence->getStart(); 77 | 78 | if ($inc) { 79 | return $start >= $after; 80 | } 81 | 82 | return $start > $after; 83 | } 84 | ); 85 | } 86 | 87 | /** 88 | * @param \DateTimeInterface $after 89 | * @param \DateTimeInterface $before 90 | * @param bool $inc Include $after or $before if they happen to be a recurrence. 91 | * 92 | * @return RecurrenceCollection 93 | */ 94 | public function endsBetween(\DateTimeInterface $after, \DateTimeInterface $before, $inc = false) 95 | { 96 | return $this->filter( 97 | function ($recurrence) use ($after, $before, $inc) { 98 | /** @var $recurrence Recurrence */ 99 | $end = $recurrence->getEnd(); 100 | 101 | if ($inc) { 102 | return $end >= $after && $end <= $before; 103 | } 104 | 105 | return $end > $after && $end < $before; 106 | } 107 | ); 108 | } 109 | 110 | /** 111 | * @param \DateTimeInterface $before 112 | * @param bool $inc Include $before if it is a recurrence. 113 | * 114 | * @return RecurrenceCollection 115 | */ 116 | public function endsBefore(\DateTimeInterface $before, $inc = false) 117 | { 118 | return $this->filter( 119 | function ($recurrence) use ($before, $inc) { 120 | /** @var $recurrence Recurrence */ 121 | $end = $recurrence->getEnd(); 122 | 123 | if ($inc) { 124 | return $end <= $before; 125 | } 126 | 127 | return $end < $before; 128 | } 129 | ); 130 | } 131 | 132 | /** 133 | * @param \DateTimeInterface $after 134 | * @param bool $inc Include $after if it a recurrence. 135 | * 136 | * @return RecurrenceCollection 137 | */ 138 | public function endsAfter(\DateTimeInterface $after, $inc = false) 139 | { 140 | return $this->filter( 141 | function ($recurrence) use ($after, $inc) { 142 | /** @var $recurrence Recurrence */ 143 | $end = $recurrence->getEnd(); 144 | 145 | if ($inc) { 146 | return $end >= $after; 147 | } 148 | 149 | return $end > $after; 150 | } 151 | ); 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /vendor/doctrine/deprecations/README.md: -------------------------------------------------------------------------------- 1 | # Doctrine Deprecations 2 | 3 | A small (side-effect free by default) layer on top of 4 | `trigger_error(E_USER_DEPRECATED)` or PSR-3 logging. 5 | 6 | - no side-effects by default, making it a perfect fit for libraries that don't know how the error handler works they operate under 7 | - options to avoid having to rely on error handlers global state by using PSR-3 logging 8 | - deduplicate deprecation messages to avoid excessive triggering and reduce overhead 9 | 10 | We recommend to collect Deprecations using a PSR logger instead of relying on 11 | the global error handler. 12 | 13 | ## Usage from consumer perspective: 14 | 15 | Enable Doctrine deprecations to be sent to a PSR3 logger: 16 | 17 | ```php 18 | \Doctrine\Deprecations\Deprecation::enableWithPsrLogger($logger); 19 | ``` 20 | 21 | Enable Doctrine deprecations to be sent as `@trigger_error($message, E_USER_DEPRECATED)` 22 | messages by setting the `DOCTRINE_DEPRECATIONS` environment variable to `trigger`. 23 | Alternatively, call: 24 | 25 | ```php 26 | \Doctrine\Deprecations\Deprecation::enableWithTriggerError(); 27 | ``` 28 | 29 | If you only want to enable deprecation tracking, without logging or calling `trigger_error` 30 | then set the `DOCTRINE_DEPRECATIONS` environment variable to `track`. 31 | Alternatively, call: 32 | 33 | ```php 34 | \Doctrine\Deprecations\Deprecation::enableTrackingDeprecations(); 35 | ``` 36 | 37 | Tracking is enabled with all three modes and provides access to all triggered 38 | deprecations and their individual count: 39 | 40 | ```php 41 | $deprecations = \Doctrine\Deprecations\Deprecation::getTriggeredDeprecations(); 42 | 43 | foreach ($deprecations as $identifier => $count) { 44 | echo $identifier . " was triggered " . $count . " times\n"; 45 | } 46 | ``` 47 | 48 | ### Suppressing Specific Deprecations 49 | 50 | Disable triggering about specific deprecations: 51 | 52 | ```php 53 | \Doctrine\Deprecations\Deprecation::ignoreDeprecations("https://link/to/deprecations-description-identifier"); 54 | ``` 55 | 56 | Disable all deprecations from a package 57 | 58 | ```php 59 | \Doctrine\Deprecations\Deprecation::ignorePackage("doctrine/orm"); 60 | ``` 61 | 62 | ### Other Operations 63 | 64 | When used within PHPUnit or other tools that could collect multiple instances of the same deprecations 65 | the deduplication can be disabled: 66 | 67 | ```php 68 | \Doctrine\Deprecations\Deprecation::withoutDeduplication(); 69 | ``` 70 | 71 | Disable deprecation tracking again: 72 | 73 | ```php 74 | \Doctrine\Deprecations\Deprecation::disable(); 75 | ``` 76 | 77 | ## Usage from a library/producer perspective: 78 | 79 | When you want to unconditionally trigger a deprecation even when called 80 | from the library itself then the `trigger` method is the way to go: 81 | 82 | ```php 83 | \Doctrine\Deprecations\Deprecation::trigger( 84 | "doctrine/orm", 85 | "https://link/to/deprecations-description", 86 | "message" 87 | ); 88 | ``` 89 | 90 | If variable arguments are provided at the end, they are used with `sprintf` on 91 | the message. 92 | 93 | ```php 94 | \Doctrine\Deprecations\Deprecation::trigger( 95 | "doctrine/orm", 96 | "https://github.com/doctrine/orm/issue/1234", 97 | "message %s %d", 98 | "foo", 99 | 1234 100 | ); 101 | ``` 102 | 103 | When you want to trigger a deprecation only when it is called by a function 104 | outside of the current package, but not trigger when the package itself is the cause, 105 | then use: 106 | 107 | ```php 108 | \Doctrine\Deprecations\Deprecation::triggerIfCalledFromOutside( 109 | "doctrine/orm", 110 | "https://link/to/deprecations-description", 111 | "message" 112 | ); 113 | ``` 114 | 115 | Based on the issue link each deprecation message is only triggered once per 116 | request. 117 | 118 | A limited stacktrace is included in the deprecation message to find the 119 | offending location. 120 | 121 | Note: A producer/library should never call `Deprecation::enableWith` methods 122 | and leave the decision how to handle deprecations to application and 123 | frameworks. 124 | 125 | ## Usage in PHPUnit tests 126 | 127 | There is a `VerifyDeprecations` trait that you can use to make assertions on 128 | the occurrence of deprecations within a test. 129 | 130 | ```php 131 | use Doctrine\Deprecations\PHPUnit\VerifyDeprecations; 132 | 133 | class MyTest extends TestCase 134 | { 135 | use VerifyDeprecations; 136 | 137 | public function testSomethingDeprecation() 138 | { 139 | $this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/issue/1234'); 140 | 141 | triggerTheCodeWithDeprecation(); 142 | } 143 | 144 | public function testSomethingDeprecationFixed() 145 | { 146 | $this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/orm/issue/1234'); 147 | 148 | triggerTheCodeWithoutDeprecation(); 149 | } 150 | } 151 | ``` 152 | 153 | ## What is a deprecation identifier? 154 | 155 | An identifier for deprecations is just a link to any resource, most often a 156 | Github Issue or Pull Request explaining the deprecation and potentially its 157 | alternative. 158 | -------------------------------------------------------------------------------- /vendor/composer/autoload_classmap.php: -------------------------------------------------------------------------------- 1 | $vendorDir . '/composer/InstalledVersions.php', 10 | 'Doctrine\\Common\\Collections\\AbstractLazyCollection' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php', 11 | 'Doctrine\\Common\\Collections\\ArrayCollection' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php', 12 | 'Doctrine\\Common\\Collections\\Collection' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Collection.php', 13 | 'Doctrine\\Common\\Collections\\Criteria' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Criteria.php', 14 | 'Doctrine\\Common\\Collections\\Expr\\ClosureExpressionVisitor' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php', 15 | 'Doctrine\\Common\\Collections\\Expr\\Comparison' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php', 16 | 'Doctrine\\Common\\Collections\\Expr\\CompositeExpression' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/CompositeExpression.php', 17 | 'Doctrine\\Common\\Collections\\Expr\\Expression' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Expression.php', 18 | 'Doctrine\\Common\\Collections\\Expr\\ExpressionVisitor' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ExpressionVisitor.php', 19 | 'Doctrine\\Common\\Collections\\Expr\\Value' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Value.php', 20 | 'Doctrine\\Common\\Collections\\ExpressionBuilder' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php', 21 | 'Doctrine\\Common\\Collections\\ReadableCollection' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/ReadableCollection.php', 22 | 'Doctrine\\Common\\Collections\\Selectable' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Selectable.php', 23 | 'Doctrine\\Deprecations\\Deprecation' => $vendorDir . '/doctrine/deprecations/lib/Doctrine/Deprecations/Deprecation.php', 24 | 'Doctrine\\Deprecations\\PHPUnit\\VerifyDeprecations' => $vendorDir . '/doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php', 25 | 'Kirby\\ComposerInstaller\\CmsInstaller' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/CmsInstaller.php', 26 | 'Kirby\\ComposerInstaller\\Installer' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/Installer.php', 27 | 'Kirby\\ComposerInstaller\\Plugin' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/Plugin.php', 28 | 'Kirby\\ComposerInstaller\\PluginInstaller' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/PluginInstaller.php', 29 | 'Recurr\\DateExclusion' => $vendorDir . '/simshaun/recurr/src/Recurr/DateExclusion.php', 30 | 'Recurr\\DateInclusion' => $vendorDir . '/simshaun/recurr/src/Recurr/DateInclusion.php', 31 | 'Recurr\\DateInfo' => $vendorDir . '/simshaun/recurr/src/Recurr/DateInfo.php', 32 | 'Recurr\\DateUtil' => $vendorDir . '/simshaun/recurr/src/Recurr/DateUtil.php', 33 | 'Recurr\\DaySet' => $vendorDir . '/simshaun/recurr/src/Recurr/DaySet.php', 34 | 'Recurr\\Exception' => $vendorDir . '/simshaun/recurr/src/Recurr/Exception.php', 35 | 'Recurr\\Exception\\InvalidArgument' => $vendorDir . '/simshaun/recurr/src/Recurr/Exception/InvalidArgument.php', 36 | 'Recurr\\Exception\\InvalidRRule' => $vendorDir . '/simshaun/recurr/src/Recurr/Exception/InvalidRRule.php', 37 | 'Recurr\\Exception\\InvalidWeekday' => $vendorDir . '/simshaun/recurr/src/Recurr/Exception/InvalidWeekday.php', 38 | 'Recurr\\Frequency' => $vendorDir . '/simshaun/recurr/src/Recurr/Frequency.php', 39 | 'Recurr\\Recurrence' => $vendorDir . '/simshaun/recurr/src/Recurr/Recurrence.php', 40 | 'Recurr\\RecurrenceCollection' => $vendorDir . '/simshaun/recurr/src/Recurr/RecurrenceCollection.php', 41 | 'Recurr\\Rule' => $vendorDir . '/simshaun/recurr/src/Recurr/Rule.php', 42 | 'Recurr\\Time' => $vendorDir . '/simshaun/recurr/src/Recurr/Time.php', 43 | 'Recurr\\Transformer\\ArrayTransformer' => $vendorDir . '/simshaun/recurr/src/Recurr/Transformer/ArrayTransformer.php', 44 | 'Recurr\\Transformer\\ArrayTransformerConfig' => $vendorDir . '/simshaun/recurr/src/Recurr/Transformer/ArrayTransformerConfig.php', 45 | 'Recurr\\Transformer\\Constraint' => $vendorDir . '/simshaun/recurr/src/Recurr/Transformer/Constraint.php', 46 | 'Recurr\\Transformer\\ConstraintInterface' => $vendorDir . '/simshaun/recurr/src/Recurr/Transformer/ConstraintInterface.php', 47 | 'Recurr\\Transformer\\Constraint\\AfterConstraint' => $vendorDir . '/simshaun/recurr/src/Recurr/Transformer/Constraint/AfterConstraint.php', 48 | 'Recurr\\Transformer\\Constraint\\BeforeConstraint' => $vendorDir . '/simshaun/recurr/src/Recurr/Transformer/Constraint/BeforeConstraint.php', 49 | 'Recurr\\Transformer\\Constraint\\BetweenConstraint' => $vendorDir . '/simshaun/recurr/src/Recurr/Transformer/Constraint/BetweenConstraint.php', 50 | 'Recurr\\Transformer\\TextTransformer' => $vendorDir . '/simshaun/recurr/src/Recurr/Transformer/TextTransformer.php', 51 | 'Recurr\\Transformer\\Translator' => $vendorDir . '/simshaun/recurr/src/Recurr/Transformer/Translator.php', 52 | 'Recurr\\Transformer\\TranslatorInterface' => $vendorDir . '/simshaun/recurr/src/Recurr/Transformer/TranslatorInterface.php', 53 | 'Recurr\\Weekday' => $vendorDir . '/simshaun/recurr/src/Recurr/Weekday.php', 54 | ); 55 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/lib/Doctrine/Common/Collections/Criteria.php: -------------------------------------------------------------------------------- 1 | expression = $expression; 73 | 74 | if ($firstResult === null && func_num_args() > 2) { 75 | Deprecation::trigger( 76 | 'doctrine/collections', 77 | 'https://github.com/doctrine/collections/pull/311', 78 | 'Passing null as $firstResult to the constructor of %s is deprecated. Pass 0 instead or omit the argument.', 79 | self::class 80 | ); 81 | } 82 | 83 | $this->setFirstResult($firstResult); 84 | $this->setMaxResults($maxResults); 85 | 86 | if ($orderings === null) { 87 | return; 88 | } 89 | 90 | $this->orderBy($orderings); 91 | } 92 | 93 | /** 94 | * Sets the where expression to evaluate when this Criteria is searched for. 95 | * 96 | * @return $this 97 | */ 98 | public function where(Expression $expression) 99 | { 100 | $this->expression = $expression; 101 | 102 | return $this; 103 | } 104 | 105 | /** 106 | * Appends the where expression to evaluate when this Criteria is searched for 107 | * using an AND with previous expression. 108 | * 109 | * @return $this 110 | */ 111 | public function andWhere(Expression $expression) 112 | { 113 | if ($this->expression === null) { 114 | return $this->where($expression); 115 | } 116 | 117 | $this->expression = new CompositeExpression( 118 | CompositeExpression::TYPE_AND, 119 | [$this->expression, $expression] 120 | ); 121 | 122 | return $this; 123 | } 124 | 125 | /** 126 | * Appends the where expression to evaluate when this Criteria is searched for 127 | * using an OR with previous expression. 128 | * 129 | * @return $this 130 | */ 131 | public function orWhere(Expression $expression) 132 | { 133 | if ($this->expression === null) { 134 | return $this->where($expression); 135 | } 136 | 137 | $this->expression = new CompositeExpression( 138 | CompositeExpression::TYPE_OR, 139 | [$this->expression, $expression] 140 | ); 141 | 142 | return $this; 143 | } 144 | 145 | /** 146 | * Gets the expression attached to this Criteria. 147 | * 148 | * @return Expression|null 149 | */ 150 | public function getWhereExpression() 151 | { 152 | return $this->expression; 153 | } 154 | 155 | /** 156 | * Gets the current orderings of this Criteria. 157 | * 158 | * @return string[] 159 | */ 160 | public function getOrderings() 161 | { 162 | return $this->orderings; 163 | } 164 | 165 | /** 166 | * Sets the ordering of the result of this Criteria. 167 | * 168 | * Keys are field and values are the order, being either ASC or DESC. 169 | * 170 | * @see Criteria::ASC 171 | * @see Criteria::DESC 172 | * 173 | * @param string[] $orderings 174 | * 175 | * @return $this 176 | */ 177 | public function orderBy(array $orderings) 178 | { 179 | $this->orderings = array_map( 180 | static function (string $ordering): string { 181 | return strtoupper($ordering) === Criteria::ASC ? Criteria::ASC : Criteria::DESC; 182 | }, 183 | $orderings 184 | ); 185 | 186 | return $this; 187 | } 188 | 189 | /** 190 | * Gets the current first result option of this Criteria. 191 | * 192 | * @return int|null 193 | */ 194 | public function getFirstResult() 195 | { 196 | return $this->firstResult; 197 | } 198 | 199 | /** 200 | * Set the number of first result that this Criteria should return. 201 | * 202 | * @param int|null $firstResult The value to set. 203 | * 204 | * @return $this 205 | */ 206 | public function setFirstResult($firstResult) 207 | { 208 | if ($firstResult === null) { 209 | Deprecation::triggerIfCalledFromOutside( 210 | 'doctrine/collections', 211 | 'https://github.com/doctrine/collections/pull/311', 212 | 'Passing null to %s() is deprecated, pass 0 instead.', 213 | __METHOD__ 214 | ); 215 | } 216 | 217 | $this->firstResult = $firstResult; 218 | 219 | return $this; 220 | } 221 | 222 | /** 223 | * Gets maxResults. 224 | * 225 | * @return int|null 226 | */ 227 | public function getMaxResults() 228 | { 229 | return $this->maxResults; 230 | } 231 | 232 | /** 233 | * Sets maxResults. 234 | * 235 | * @param int|null $maxResults The value to set. 236 | * 237 | * @return $this 238 | */ 239 | public function setMaxResults($maxResults) 240 | { 241 | $this->maxResults = $maxResults; 242 | 243 | return $this; 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /vendor/simshaun/recurr/README.md: -------------------------------------------------------------------------------- 1 | # Recurr [![Build Status](https://travis-ci.org/simshaun/recurr.png)](https://travis-ci.org/simshaun/recurr.png) [![Latest Stable Version](https://poser.pugx.org/simshaun/recurr/v/stable.svg)](https://packagist.org/packages/simshaun/recurr) [![Total Downloads](https://poser.pugx.org/simshaun/recurr/downloads.svg)](https://packagist.org/packages/simshaun/recurr) [![Latest Unstable Version](https://poser.pugx.org/simshaun/recurr/v/unstable.svg)](https://packagist.org/packages/simshaun/recurr) [![License](https://poser.pugx.org/simshaun/recurr/license.svg)](https://packagist.org/packages/simshaun/recurr) 2 | 3 | Recurr is a PHP library for working with recurrence rules ([RRULE](https://tools.ietf.org/html/rfc5545)) and converting them in to DateTime objects. 4 | 5 | Recurr was developed as a precursor for a calendar with recurring events, and is heavily inspired by [rrule.js](https://github.com/jkbr/rrule). 6 | 7 | Installing Recurr 8 | ------------ 9 | 10 | The recommended way to install Recurr is through [Composer](http://getcomposer.org). 11 | 12 | `composer require simshaun/recurr` 13 | 14 | Using Recurr 15 | ----------- 16 | 17 | ### Creating RRULE rule objects ### 18 | 19 | You can create a new Rule object by passing the ([RRULE](https://tools.ietf.org/html/rfc5545)) string or an array with the rule parts, the start date, end date (optional) and timezone. 20 | 21 | ```php 22 | $timezone = 'America/New_York'; 23 | $startDate = new \DateTime('2013-06-12 20:00:00', new \DateTimeZone($timezone)); 24 | $endDate = new \DateTime('2013-06-14 20:00:00', new \DateTimeZone($timezone)); // Optional 25 | $rule = new \Recurr\Rule('FREQ=MONTHLY;COUNT=5', $startDate, $endDate, $timezone); 26 | ``` 27 | 28 | You can also use chained methods to build your rule programmatically and get the resulting RRULE. 29 | 30 | ```php 31 | $rule = (new \Recurr\Rule) 32 | ->setStartDate($startDate) 33 | ->setTimezone($timezone) 34 | ->setFreq('DAILY') 35 | ->setByDay(['MO', 'TU']) 36 | ->setUntil(new \DateTime('2017-12-31')) 37 | ; 38 | 39 | echo $rule->getString(); //FREQ=DAILY;UNTIL=20171231T000000;BYDAY=MO,TU 40 | ``` 41 | 42 | ### RRULE to DateTime objects ### 43 | 44 | ```php 45 | $transformer = new \Recurr\Transformer\ArrayTransformer(); 46 | 47 | print_r($transformer->transform($rule)); 48 | ``` 49 | 50 | 1. `$transformer->transform(...)` returns a `RecurrenceCollection` of `Recurrence` objects. 51 | 2. Each `Recurrence` has `getStart()` and `getEnd()` methods that return a `\DateTime` object. 52 | 3. If the transformed `Rule` lacks an end date, `getEnd()` will return a `\DateTime` object equal to that of `getStart()`. 53 | 54 | > Note: The transformer has a "virtual" limit (default 732) on the number of objects it generates. 55 | > This prevents the script from crashing on an infinitely recurring rule. 56 | > You can change the virtual limit with an `ArrayTransformerConfig` object that you pass to `ArrayTransformer`. 57 | 58 | ### Transformation Constraints ### 59 | 60 | Constraints are used by the ArrayTransformer to allow or prevent certain dates from being added to a `RecurrenceCollection`. Recurr provides the following constraints: 61 | 62 | - `AfterConstraint(\DateTime $after, $inc = false)` 63 | - `BeforeConstraint(\DateTime $before, $inc = false)` 64 | - `BetweenConstraint(\DateTime $after, \DateTime $before, $inc = false)` 65 | 66 | `$inc` defines what happens if `$after` or `$before` are themselves recurrences. If `$inc = true`, they will be included in the collection. For example, 67 | 68 | ```php 69 | $startDate = new \DateTime('2014-06-17 04:00:00'); 70 | $rule = new \Recurr\Rule('FREQ=MONTHLY;COUNT=5', $startDate); 71 | $transformer = new \Recurr\Transformer\ArrayTransformer(); 72 | 73 | $constraint = new \Recurr\Transformer\Constraint\BeforeConstraint(new \DateTime('2014-08-01 00:00:00')); 74 | print_r($transformer->transform($rule, $constraint)); 75 | ``` 76 | 77 | > Note: If building your own constraint, it is important to know that dates which do not meet the constraint's requirements do **not** count toward the transformer's virtual limit. If you manually set your constraint's `$stopsTransformer` property to `false`, the transformer *might* crash via an infinite loop. See the `BetweenConstraint` for an example on how to prevent that. 78 | 79 | ### Post-Transformation `RecurrenceCollection` Filters ### 80 | 81 | `RecurrenceCollection` provides the following chainable helper methods to filter out recurrences: 82 | 83 | - `startsBetween(\DateTime $after, \DateTime $before, $inc = false)` 84 | - `startsBefore(\DateTime $before, $inc = false)` 85 | - `startsAfter(\DateTime $after, $inc = false)` 86 | - `endsBetween(\DateTime $after, \DateTime $before, $inc = false)` 87 | - `endsBefore(\DateTime $before, $inc = false)` 88 | - `endsAfter(\DateTime $after, $inc = false)` 89 | 90 | `$inc` defines what happens if `$after` or `$before` are themselves recurrences. If `$inc = true`, they will be included in the filtered collection. For example, 91 | 92 | pseudo... 93 | 2014-06-01 startsBetween(2014-06-01, 2014-06-20) // false 94 | 2014-06-01 startsBetween(2014-06-01, 2014-06-20, true) // true 95 | 96 | > Note: `RecurrenceCollection` extends the Doctrine project's [ArrayCollection](https://github.com/doctrine/collections/blob/master/lib/Doctrine/Common/Collections/ArrayCollection.php) class. 97 | 98 | RRULE to Text 99 | -------------------------- 100 | 101 | Recurr supports transforming some recurrence rules into human readable text. 102 | This feature is still in beta and only supports yearly, monthly, weekly, and daily frequencies. 103 | 104 | ```php 105 | $rule = new Rule('FREQ=YEARLY;INTERVAL=2;COUNT=3;', new \DateTime()); 106 | 107 | $textTransformer = new TextTransformer(); 108 | echo $textTransformer->transform($rule); 109 | ``` 110 | 111 | If you need more than English you can pass in a translator with one of the 112 | supported locales *(see translations folder)*. 113 | 114 | ```php 115 | $rule = new Rule('FREQ=YEARLY;INTERVAL=2;COUNT=3;', new \DateTime()); 116 | 117 | $textTransformer = new TextTransformer( 118 | new \Recurr\Transformer\Translator('de') 119 | ); 120 | echo $textTransformer->transform($rule); 121 | ``` 122 | 123 | Warnings 124 | --------------- 125 | 126 | - **Monthly recurring rules ** 127 | By default, if your start date is on the 29th, 30th, or 31st, Recurr will skip following months that don't have at least that many days. 128 | *(e.g. Jan 31 + 1 month = March)* 129 | 130 | This behavior is configurable: 131 | 132 | ```php 133 | $timezone = 'America/New_York'; 134 | $startDate = new \DateTime('2013-01-31 20:00:00', new \DateTimeZone($timezone)); 135 | $rule = new \Recurr\Rule('FREQ=MONTHLY;COUNT=5', $startDate, null, $timezone); 136 | $transformer = new \Recurr\Transformer\ArrayTransformer(); 137 | 138 | $transformerConfig = new \Recurr\Transformer\ArrayTransformerConfig(); 139 | $transformerConfig->enableLastDayOfMonthFix(); 140 | $transformer->setConfig($transformerConfig); 141 | 142 | print_r($transformer->transform($rule)); 143 | // 2013-01-31, 2013-02-28, 2013-03-31, 2013-04-30, 2013-05-31 144 | ``` 145 | 146 | 147 | Contribute 148 | ---------- 149 | 150 | Feel free to comment or make pull requests. Please include tests with PRs. 151 | 152 | 153 | License 154 | ------- 155 | 156 | Recurr is licensed under the MIT License. See the LICENSE file for details. 157 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/lib/Doctrine/Common/Collections/ReadableCollection.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | interface ReadableCollection extends Countable, IteratorAggregate 15 | { 16 | /** 17 | * Checks whether an element is contained in the collection. 18 | * This is an O(n) operation, where n is the size of the collection. 19 | * 20 | * @param mixed $element The element to search for. 21 | * @psalm-param TMaybeContained $element 22 | * 23 | * @return bool TRUE if the collection contains the element, FALSE otherwise. 24 | * @psalm-return (TMaybeContained is T ? bool : false) 25 | * 26 | * @template TMaybeContained 27 | */ 28 | public function contains($element); 29 | 30 | /** 31 | * Checks whether the collection is empty (contains no elements). 32 | * 33 | * @return bool TRUE if the collection is empty, FALSE otherwise. 34 | */ 35 | public function isEmpty(); 36 | 37 | /** 38 | * Checks whether the collection contains an element with the specified key/index. 39 | * 40 | * @param string|int $key The key/index to check for. 41 | * @psalm-param TKey $key 42 | * 43 | * @return bool TRUE if the collection contains an element with the specified key/index, 44 | * FALSE otherwise. 45 | */ 46 | public function containsKey($key); 47 | 48 | /** 49 | * Gets the element at the specified key/index. 50 | * 51 | * @param string|int $key The key/index of the element to retrieve. 52 | * @psalm-param TKey $key 53 | * 54 | * @return mixed 55 | * @psalm-return T|null 56 | */ 57 | public function get($key); 58 | 59 | /** 60 | * Gets all keys/indices of the collection. 61 | * 62 | * @return int[]|string[] The keys/indices of the collection, in the order of the corresponding 63 | * elements in the collection. 64 | * @psalm-return list 65 | */ 66 | public function getKeys(); 67 | 68 | /** 69 | * Gets all values of the collection. 70 | * 71 | * @return mixed[] The values of all elements in the collection, in the 72 | * order they appear in the collection. 73 | * @psalm-return list 74 | */ 75 | public function getValues(); 76 | 77 | /** 78 | * Gets a native PHP array representation of the collection. 79 | * 80 | * @return mixed[] 81 | * @psalm-return array 82 | */ 83 | public function toArray(); 84 | 85 | /** 86 | * Sets the internal iterator to the first element in the collection and returns this element. 87 | * 88 | * @return mixed 89 | * @psalm-return T|false 90 | */ 91 | public function first(); 92 | 93 | /** 94 | * Sets the internal iterator to the last element in the collection and returns this element. 95 | * 96 | * @return mixed 97 | * @psalm-return T|false 98 | */ 99 | public function last(); 100 | 101 | /** 102 | * Gets the key/index of the element at the current iterator position. 103 | * 104 | * @return int|string|null 105 | * @psalm-return TKey|null 106 | */ 107 | public function key(); 108 | 109 | /** 110 | * Gets the element of the collection at the current iterator position. 111 | * 112 | * @return mixed 113 | * @psalm-return T|false 114 | */ 115 | public function current(); 116 | 117 | /** 118 | * Moves the internal iterator position to the next element and returns this element. 119 | * 120 | * @return mixed 121 | * @psalm-return T|false 122 | */ 123 | public function next(); 124 | 125 | /** 126 | * Extracts a slice of $length elements starting at position $offset from the Collection. 127 | * 128 | * If $length is null it returns all elements from $offset to the end of the Collection. 129 | * Keys have to be preserved by this method. Calling this method will only return the 130 | * selected slice and NOT change the elements contained in the collection slice is called on. 131 | * 132 | * @param int $offset The offset to start from. 133 | * @param int|null $length The maximum number of elements to return, or null for no limit. 134 | * 135 | * @return mixed[] 136 | * @psalm-return array 137 | */ 138 | public function slice($offset, $length = null); 139 | 140 | /** 141 | * Tests for the existence of an element that satisfies the given predicate. 142 | * 143 | * @param Closure $p The predicate. 144 | * @psalm-param Closure(TKey, T):bool $p 145 | * 146 | * @return bool TRUE if the predicate is TRUE for at least one element, FALSE otherwise. 147 | */ 148 | public function exists(Closure $p); 149 | 150 | /** 151 | * Returns all the elements of this collection that satisfy the predicate p. 152 | * The order of the elements is preserved. 153 | * 154 | * @param Closure $p The predicate used for filtering. 155 | * @psalm-param Closure(T):bool $p 156 | * 157 | * @return ReadableCollection A collection with the results of the filter operation. 158 | * @psalm-return ReadableCollection 159 | */ 160 | public function filter(Closure $p); 161 | 162 | /** 163 | * Applies the given function to each element in the collection and returns 164 | * a new collection with the elements returned by the function. 165 | * 166 | * @psalm-param Closure(T):U $func 167 | * 168 | * @return Collection 169 | * @psalm-return Collection 170 | * 171 | * @psalm-template U 172 | */ 173 | public function map(Closure $func); 174 | 175 | /** 176 | * Partitions this collection in two collections according to a predicate. 177 | * Keys are preserved in the resulting collections. 178 | * 179 | * @param Closure $p The predicate on which to partition. 180 | * @psalm-param Closure(TKey, T):bool $p 181 | * 182 | * @return ReadableCollection[] An array with two elements. The first element contains the collection 183 | * of elements where the predicate returned TRUE, the second element 184 | * contains the collection of elements where the predicate returned FALSE. 185 | * @psalm-return array{0: ReadableCollection, 1: ReadableCollection} 186 | */ 187 | public function partition(Closure $p); 188 | 189 | /** 190 | * Tests whether the given predicate p holds for all elements of this collection. 191 | * 192 | * @param Closure $p The predicate. 193 | * @psalm-param Closure(TKey, T):bool $p 194 | * 195 | * @return bool TRUE, if the predicate yields TRUE for all elements, FALSE otherwise. 196 | */ 197 | public function forAll(Closure $p); 198 | 199 | /** 200 | * Gets the index/key of a given element. The comparison of two elements is strict, 201 | * that means not only the value but also the type must match. 202 | * For objects this means reference equality. 203 | * 204 | * @param mixed $element The element to search for. 205 | * @psalm-param TMaybeContained $element 206 | * 207 | * @return int|string|bool The key/index of the element or FALSE if the element was not found. 208 | * @psalm-return (TMaybeContained is T ? TKey|false : false) 209 | * 210 | * @template TMaybeContained 211 | */ 212 | public function indexOf($element); 213 | } 214 | -------------------------------------------------------------------------------- /vendor/composer/autoload_static.php: -------------------------------------------------------------------------------- 1 | 11 | array ( 12 | 'Recurr\\' => 7, 13 | ), 14 | 'K' => 15 | array ( 16 | 'Kirby\\' => 6, 17 | ), 18 | 'D' => 19 | array ( 20 | 'Doctrine\\Deprecations\\' => 22, 21 | 'Doctrine\\Common\\Collections\\' => 28, 22 | ), 23 | ); 24 | 25 | public static $prefixDirsPsr4 = array ( 26 | 'Recurr\\' => 27 | array ( 28 | 0 => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr', 29 | ), 30 | 'Kirby\\' => 31 | array ( 32 | 0 => __DIR__ . '/..' . '/getkirby/composer-installer/src', 33 | ), 34 | 'Doctrine\\Deprecations\\' => 35 | array ( 36 | 0 => __DIR__ . '/..' . '/doctrine/deprecations/lib/Doctrine/Deprecations', 37 | ), 38 | 'Doctrine\\Common\\Collections\\' => 39 | array ( 40 | 0 => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections', 41 | ), 42 | ); 43 | 44 | public static $classMap = array ( 45 | 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 46 | 'Doctrine\\Common\\Collections\\AbstractLazyCollection' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php', 47 | 'Doctrine\\Common\\Collections\\ArrayCollection' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php', 48 | 'Doctrine\\Common\\Collections\\Collection' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/Collection.php', 49 | 'Doctrine\\Common\\Collections\\Criteria' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/Criteria.php', 50 | 'Doctrine\\Common\\Collections\\Expr\\ClosureExpressionVisitor' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php', 51 | 'Doctrine\\Common\\Collections\\Expr\\Comparison' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php', 52 | 'Doctrine\\Common\\Collections\\Expr\\CompositeExpression' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/CompositeExpression.php', 53 | 'Doctrine\\Common\\Collections\\Expr\\Expression' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Expression.php', 54 | 'Doctrine\\Common\\Collections\\Expr\\ExpressionVisitor' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ExpressionVisitor.php', 55 | 'Doctrine\\Common\\Collections\\Expr\\Value' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Value.php', 56 | 'Doctrine\\Common\\Collections\\ExpressionBuilder' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php', 57 | 'Doctrine\\Common\\Collections\\ReadableCollection' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/ReadableCollection.php', 58 | 'Doctrine\\Common\\Collections\\Selectable' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/Selectable.php', 59 | 'Doctrine\\Deprecations\\Deprecation' => __DIR__ . '/..' . '/doctrine/deprecations/lib/Doctrine/Deprecations/Deprecation.php', 60 | 'Doctrine\\Deprecations\\PHPUnit\\VerifyDeprecations' => __DIR__ . '/..' . '/doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php', 61 | 'Kirby\\ComposerInstaller\\CmsInstaller' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/CmsInstaller.php', 62 | 'Kirby\\ComposerInstaller\\Installer' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/Installer.php', 63 | 'Kirby\\ComposerInstaller\\Plugin' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/Plugin.php', 64 | 'Kirby\\ComposerInstaller\\PluginInstaller' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/PluginInstaller.php', 65 | 'Recurr\\DateExclusion' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/DateExclusion.php', 66 | 'Recurr\\DateInclusion' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/DateInclusion.php', 67 | 'Recurr\\DateInfo' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/DateInfo.php', 68 | 'Recurr\\DateUtil' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/DateUtil.php', 69 | 'Recurr\\DaySet' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/DaySet.php', 70 | 'Recurr\\Exception' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Exception.php', 71 | 'Recurr\\Exception\\InvalidArgument' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Exception/InvalidArgument.php', 72 | 'Recurr\\Exception\\InvalidRRule' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Exception/InvalidRRule.php', 73 | 'Recurr\\Exception\\InvalidWeekday' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Exception/InvalidWeekday.php', 74 | 'Recurr\\Frequency' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Frequency.php', 75 | 'Recurr\\Recurrence' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Recurrence.php', 76 | 'Recurr\\RecurrenceCollection' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/RecurrenceCollection.php', 77 | 'Recurr\\Rule' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Rule.php', 78 | 'Recurr\\Time' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Time.php', 79 | 'Recurr\\Transformer\\ArrayTransformer' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Transformer/ArrayTransformer.php', 80 | 'Recurr\\Transformer\\ArrayTransformerConfig' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Transformer/ArrayTransformerConfig.php', 81 | 'Recurr\\Transformer\\Constraint' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Transformer/Constraint.php', 82 | 'Recurr\\Transformer\\ConstraintInterface' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Transformer/ConstraintInterface.php', 83 | 'Recurr\\Transformer\\Constraint\\AfterConstraint' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Transformer/Constraint/AfterConstraint.php', 84 | 'Recurr\\Transformer\\Constraint\\BeforeConstraint' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Transformer/Constraint/BeforeConstraint.php', 85 | 'Recurr\\Transformer\\Constraint\\BetweenConstraint' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Transformer/Constraint/BetweenConstraint.php', 86 | 'Recurr\\Transformer\\TextTransformer' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Transformer/TextTransformer.php', 87 | 'Recurr\\Transformer\\Translator' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Transformer/Translator.php', 88 | 'Recurr\\Transformer\\TranslatorInterface' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Transformer/TranslatorInterface.php', 89 | 'Recurr\\Weekday' => __DIR__ . '/..' . '/simshaun/recurr/src/Recurr/Weekday.php', 90 | ); 91 | 92 | public static function getInitializer(ClassLoader $loader) 93 | { 94 | return \Closure::bind(function () use ($loader) { 95 | $loader->prefixLengthsPsr4 = ComposerStaticInitbd2fd20cd2d671d337567db3b7cd410f::$prefixLengthsPsr4; 96 | $loader->prefixDirsPsr4 = ComposerStaticInitbd2fd20cd2d671d337567db3b7cd410f::$prefixDirsPsr4; 97 | $loader->classMap = ComposerStaticInitbd2fd20cd2d671d337567db3b7cd410f::$classMap; 98 | 99 | }, null, ClassLoader::class); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | abstract class AbstractLazyCollection implements Collection 18 | { 19 | /** 20 | * The backed collection to use 21 | * 22 | * @psalm-var Collection|null 23 | * @var Collection|null 24 | */ 25 | protected $collection; 26 | 27 | /** @var bool */ 28 | protected $initialized = false; 29 | 30 | /** 31 | * {@inheritDoc} 32 | * 33 | * @return int 34 | */ 35 | #[ReturnTypeWillChange] 36 | public function count() 37 | { 38 | $this->initialize(); 39 | 40 | return $this->collection->count(); 41 | } 42 | 43 | /** 44 | * {@inheritDoc} 45 | */ 46 | public function add($element) 47 | { 48 | $this->initialize(); 49 | 50 | return $this->collection->add($element); 51 | } 52 | 53 | /** 54 | * {@inheritDoc} 55 | */ 56 | public function clear() 57 | { 58 | $this->initialize(); 59 | $this->collection->clear(); 60 | } 61 | 62 | /** 63 | * {@inheritDoc} 64 | * 65 | * @template TMaybeContained 66 | */ 67 | public function contains($element) 68 | { 69 | $this->initialize(); 70 | 71 | return $this->collection->contains($element); 72 | } 73 | 74 | /** 75 | * {@inheritDoc} 76 | */ 77 | public function isEmpty() 78 | { 79 | $this->initialize(); 80 | 81 | return $this->collection->isEmpty(); 82 | } 83 | 84 | /** 85 | * {@inheritDoc} 86 | */ 87 | public function remove($key) 88 | { 89 | $this->initialize(); 90 | 91 | return $this->collection->remove($key); 92 | } 93 | 94 | /** 95 | * {@inheritDoc} 96 | */ 97 | public function removeElement($element) 98 | { 99 | $this->initialize(); 100 | 101 | return $this->collection->removeElement($element); 102 | } 103 | 104 | /** 105 | * {@inheritDoc} 106 | */ 107 | public function containsKey($key) 108 | { 109 | $this->initialize(); 110 | 111 | return $this->collection->containsKey($key); 112 | } 113 | 114 | /** 115 | * {@inheritDoc} 116 | */ 117 | public function get($key) 118 | { 119 | $this->initialize(); 120 | 121 | return $this->collection->get($key); 122 | } 123 | 124 | /** 125 | * {@inheritDoc} 126 | */ 127 | public function getKeys() 128 | { 129 | $this->initialize(); 130 | 131 | return $this->collection->getKeys(); 132 | } 133 | 134 | /** 135 | * {@inheritDoc} 136 | */ 137 | public function getValues() 138 | { 139 | $this->initialize(); 140 | 141 | return $this->collection->getValues(); 142 | } 143 | 144 | /** 145 | * {@inheritDoc} 146 | */ 147 | public function set($key, $value) 148 | { 149 | $this->initialize(); 150 | $this->collection->set($key, $value); 151 | } 152 | 153 | /** 154 | * {@inheritDoc} 155 | */ 156 | public function toArray() 157 | { 158 | $this->initialize(); 159 | 160 | return $this->collection->toArray(); 161 | } 162 | 163 | /** 164 | * {@inheritDoc} 165 | */ 166 | public function first() 167 | { 168 | $this->initialize(); 169 | 170 | return $this->collection->first(); 171 | } 172 | 173 | /** 174 | * {@inheritDoc} 175 | */ 176 | public function last() 177 | { 178 | $this->initialize(); 179 | 180 | return $this->collection->last(); 181 | } 182 | 183 | /** 184 | * {@inheritDoc} 185 | */ 186 | public function key() 187 | { 188 | $this->initialize(); 189 | 190 | return $this->collection->key(); 191 | } 192 | 193 | /** 194 | * {@inheritDoc} 195 | */ 196 | public function current() 197 | { 198 | $this->initialize(); 199 | 200 | return $this->collection->current(); 201 | } 202 | 203 | /** 204 | * {@inheritDoc} 205 | */ 206 | public function next() 207 | { 208 | $this->initialize(); 209 | 210 | return $this->collection->next(); 211 | } 212 | 213 | /** 214 | * {@inheritDoc} 215 | */ 216 | public function exists(Closure $p) 217 | { 218 | $this->initialize(); 219 | 220 | return $this->collection->exists($p); 221 | } 222 | 223 | /** 224 | * {@inheritDoc} 225 | */ 226 | public function filter(Closure $p) 227 | { 228 | $this->initialize(); 229 | 230 | return $this->collection->filter($p); 231 | } 232 | 233 | /** 234 | * {@inheritDoc} 235 | */ 236 | public function forAll(Closure $p) 237 | { 238 | $this->initialize(); 239 | 240 | return $this->collection->forAll($p); 241 | } 242 | 243 | /** 244 | * {@inheritDoc} 245 | */ 246 | public function map(Closure $func) 247 | { 248 | $this->initialize(); 249 | 250 | return $this->collection->map($func); 251 | } 252 | 253 | /** 254 | * {@inheritDoc} 255 | */ 256 | public function partition(Closure $p) 257 | { 258 | $this->initialize(); 259 | 260 | return $this->collection->partition($p); 261 | } 262 | 263 | /** 264 | * {@inheritDoc} 265 | * 266 | * @template TMaybeContained 267 | */ 268 | public function indexOf($element) 269 | { 270 | $this->initialize(); 271 | 272 | return $this->collection->indexOf($element); 273 | } 274 | 275 | /** 276 | * {@inheritDoc} 277 | */ 278 | public function slice($offset, $length = null) 279 | { 280 | $this->initialize(); 281 | 282 | return $this->collection->slice($offset, $length); 283 | } 284 | 285 | /** 286 | * {@inheritDoc} 287 | * 288 | * @return Traversable 289 | * @psalm-return Traversable 290 | */ 291 | #[ReturnTypeWillChange] 292 | public function getIterator() 293 | { 294 | $this->initialize(); 295 | 296 | return $this->collection->getIterator(); 297 | } 298 | 299 | /** 300 | * @param TKey $offset 301 | * 302 | * @return bool 303 | */ 304 | #[ReturnTypeWillChange] 305 | public function offsetExists($offset) 306 | { 307 | $this->initialize(); 308 | 309 | return $this->collection->offsetExists($offset); 310 | } 311 | 312 | /** 313 | * @param TKey $offset 314 | * 315 | * @return mixed 316 | */ 317 | #[ReturnTypeWillChange] 318 | public function offsetGet($offset) 319 | { 320 | $this->initialize(); 321 | 322 | return $this->collection->offsetGet($offset); 323 | } 324 | 325 | /** 326 | * @param TKey|null $offset 327 | * @param T $value 328 | * 329 | * @return void 330 | */ 331 | #[ReturnTypeWillChange] 332 | public function offsetSet($offset, $value) 333 | { 334 | $this->initialize(); 335 | $this->collection->offsetSet($offset, $value); 336 | } 337 | 338 | /** 339 | * @param TKey $offset 340 | * 341 | * @return void 342 | */ 343 | #[ReturnTypeWillChange] 344 | public function offsetUnset($offset) 345 | { 346 | $this->initialize(); 347 | $this->collection->offsetUnset($offset); 348 | } 349 | 350 | /** 351 | * Is the lazy collection already initialized? 352 | * 353 | * @return bool 354 | * 355 | * @psalm-assert-if-true Collection $this->collection 356 | */ 357 | public function isInitialized() 358 | { 359 | return $this->initialized; 360 | } 361 | 362 | /** 363 | * Initialize the collection 364 | * 365 | * @return void 366 | * 367 | * @psalm-assert Collection $this->collection 368 | */ 369 | protected function initialize() 370 | { 371 | if ($this->initialized) { 372 | return; 373 | } 374 | 375 | $this->doInitialize(); 376 | $this->initialized = true; 377 | 378 | if ($this->collection === null) { 379 | throw new LogicException('You must initialize the collection property in the doInitialize() method.'); 380 | } 381 | } 382 | 383 | /** 384 | * Do the initialization logic 385 | * 386 | * @return void 387 | */ 388 | abstract protected function doInitialize(); 389 | } 390 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php: -------------------------------------------------------------------------------- 1 | $accessor(); 60 | } 61 | } 62 | 63 | if (preg_match('/^is[A-Z]+/', $field) === 1 && method_exists($object, $field)) { 64 | return $object->$field(); 65 | } 66 | 67 | // __call should be triggered for get. 68 | $accessor = $accessors[0] . $field; 69 | 70 | if (method_exists($object, '__call')) { 71 | return $object->$accessor(); 72 | } 73 | 74 | if ($object instanceof ArrayAccess) { 75 | return $object[$field]; 76 | } 77 | 78 | if (isset($object->$field)) { 79 | return $object->$field; 80 | } 81 | 82 | // camelcase field name to support different variable naming conventions 83 | $ccField = preg_replace_callback('/_(.?)/', static function ($matches) { 84 | return strtoupper($matches[1]); 85 | }, $field); 86 | 87 | foreach ($accessors as $accessor) { 88 | $accessor .= $ccField; 89 | 90 | if (method_exists($object, $accessor)) { 91 | return $object->$accessor(); 92 | } 93 | } 94 | 95 | return $object->$field; 96 | } 97 | 98 | /** 99 | * Helper for sorting arrays of objects based on multiple fields + orientations. 100 | * 101 | * @param string $name 102 | * @param int $orientation 103 | * 104 | * @return Closure 105 | */ 106 | public static function sortByField($name, $orientation = 1, ?Closure $next = null) 107 | { 108 | if (! $next) { 109 | $next = static function (): int { 110 | return 0; 111 | }; 112 | } 113 | 114 | return static function ($a, $b) use ($name, $next, $orientation): int { 115 | $aValue = ClosureExpressionVisitor::getObjectFieldValue($a, $name); 116 | 117 | $bValue = ClosureExpressionVisitor::getObjectFieldValue($b, $name); 118 | 119 | if ($aValue === $bValue) { 120 | return $next($a, $b); 121 | } 122 | 123 | return ($aValue > $bValue ? 1 : -1) * $orientation; 124 | }; 125 | } 126 | 127 | /** 128 | * {@inheritDoc} 129 | */ 130 | public function walkComparison(Comparison $comparison) 131 | { 132 | $field = $comparison->getField(); 133 | $value = $comparison->getValue()->getValue(); // shortcut for walkValue() 134 | 135 | switch ($comparison->getOperator()) { 136 | case Comparison::EQ: 137 | return static function ($object) use ($field, $value): bool { 138 | return ClosureExpressionVisitor::getObjectFieldValue($object, $field) === $value; 139 | }; 140 | 141 | case Comparison::NEQ: 142 | return static function ($object) use ($field, $value): bool { 143 | return ClosureExpressionVisitor::getObjectFieldValue($object, $field) !== $value; 144 | }; 145 | 146 | case Comparison::LT: 147 | return static function ($object) use ($field, $value): bool { 148 | return ClosureExpressionVisitor::getObjectFieldValue($object, $field) < $value; 149 | }; 150 | 151 | case Comparison::LTE: 152 | return static function ($object) use ($field, $value): bool { 153 | return ClosureExpressionVisitor::getObjectFieldValue($object, $field) <= $value; 154 | }; 155 | 156 | case Comparison::GT: 157 | return static function ($object) use ($field, $value): bool { 158 | return ClosureExpressionVisitor::getObjectFieldValue($object, $field) > $value; 159 | }; 160 | 161 | case Comparison::GTE: 162 | return static function ($object) use ($field, $value): bool { 163 | return ClosureExpressionVisitor::getObjectFieldValue($object, $field) >= $value; 164 | }; 165 | 166 | case Comparison::IN: 167 | return static function ($object) use ($field, $value): bool { 168 | $fieldValue = ClosureExpressionVisitor::getObjectFieldValue($object, $field); 169 | 170 | return in_array($fieldValue, $value, is_scalar($fieldValue)); 171 | }; 172 | 173 | case Comparison::NIN: 174 | return static function ($object) use ($field, $value): bool { 175 | $fieldValue = ClosureExpressionVisitor::getObjectFieldValue($object, $field); 176 | 177 | return ! in_array($fieldValue, $value, is_scalar($fieldValue)); 178 | }; 179 | 180 | case Comparison::CONTAINS: 181 | return static function ($object) use ($field, $value) { 182 | return strpos(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value) !== false; 183 | }; 184 | 185 | case Comparison::MEMBER_OF: 186 | return static function ($object) use ($field, $value): bool { 187 | $fieldValues = ClosureExpressionVisitor::getObjectFieldValue($object, $field); 188 | 189 | if (! is_array($fieldValues)) { 190 | $fieldValues = iterator_to_array($fieldValues); 191 | } 192 | 193 | return in_array($value, $fieldValues, true); 194 | }; 195 | 196 | case Comparison::STARTS_WITH: 197 | return static function ($object) use ($field, $value): bool { 198 | return strpos(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value) === 0; 199 | }; 200 | 201 | case Comparison::ENDS_WITH: 202 | return static function ($object) use ($field, $value): bool { 203 | return $value === substr(ClosureExpressionVisitor::getObjectFieldValue($object, $field), -strlen($value)); 204 | }; 205 | 206 | default: 207 | throw new RuntimeException('Unknown comparison operator: ' . $comparison->getOperator()); 208 | } 209 | } 210 | 211 | /** 212 | * {@inheritDoc} 213 | */ 214 | public function walkValue(Value $value) 215 | { 216 | return $value->getValue(); 217 | } 218 | 219 | /** 220 | * {@inheritDoc} 221 | */ 222 | public function walkCompositeExpression(CompositeExpression $expr) 223 | { 224 | $expressionList = []; 225 | 226 | foreach ($expr->getExpressionList() as $child) { 227 | $expressionList[] = $this->dispatch($child); 228 | } 229 | 230 | switch ($expr->getType()) { 231 | case CompositeExpression::TYPE_AND: 232 | return $this->andExpressions($expressionList); 233 | 234 | case CompositeExpression::TYPE_OR: 235 | return $this->orExpressions($expressionList); 236 | 237 | default: 238 | throw new RuntimeException('Unknown composite ' . $expr->getType()); 239 | } 240 | } 241 | 242 | /** @param callable[] $expressions */ 243 | private function andExpressions(array $expressions): callable 244 | { 245 | return static function ($object) use ($expressions): bool { 246 | foreach ($expressions as $expression) { 247 | if (! $expression($object)) { 248 | return false; 249 | } 250 | } 251 | 252 | return true; 253 | }; 254 | } 255 | 256 | /** @param callable[] $expressions */ 257 | private function orExpressions(array $expressions): callable 258 | { 259 | return static function ($object) use ($expressions): bool { 260 | foreach ($expressions as $expression) { 261 | if ($expression($object)) { 262 | return true; 263 | } 264 | } 265 | 266 | return false; 267 | }; 268 | } 269 | } 270 | -------------------------------------------------------------------------------- /vendor/doctrine/collections/docs/en/index.rst: -------------------------------------------------------------------------------- 1 | Introduction 2 | ============ 3 | 4 | Doctrine Collections is a library that contains classes for working with 5 | arrays of data. Here is an example using the simple 6 | ``Doctrine\Common\Collections\ArrayCollection`` class: 7 | 8 | .. code-block:: php 9 | filter(function($element) { 16 | return $element > 1; 17 | }); // [2, 3] 18 | 19 | Collection Methods 20 | ================== 21 | 22 | Doctrine Collections provides an interface named ``Doctrine\Common\Collections\Collection`` 23 | that resembles the nature of a regular PHP array. That is, 24 | it is essentially an **ordered map** that can also be used 25 | like a list. 26 | 27 | A Collection has an internal iterator just like a PHP array. In addition, 28 | a Collection can be iterated with external iterators, which is preferable. 29 | To use an external iterator simply use the foreach language construct to 30 | iterate over the collection, which calls ``getIterator()`` internally, or 31 | explicitly retrieve an iterator though ``getIterator()`` which can then be 32 | used to iterate over the collection. You can not rely on the internal iterator 33 | of the collection being at a certain position unless you explicitly positioned it before. 34 | 35 | Methods that do not alter the collection or have template types 36 | appearing in invariant or contravariant positions are not directly 37 | defined in ``Doctrine\Common\Collections\Collection``, but are inherited 38 | from the ``Doctrine\Common\Collections\ReadableCollection`` interface. 39 | 40 | The methods available on the interface are: 41 | 42 | add 43 | --- 44 | 45 | Adds an element at the end of the collection. 46 | 47 | .. code-block:: php 48 | $collection->add('test'); 49 | 50 | clear 51 | ----- 52 | 53 | Clears the collection, removing all elements. 54 | 55 | .. code-block:: php 56 | $collection->clear(); 57 | 58 | contains 59 | -------- 60 | 61 | Checks whether an element is contained in the collection. This is an O(n) operation, where n is the size of the collection. 62 | 63 | .. code-block:: php 64 | $collection = new Collection(['test']); 65 | 66 | $contains = $collection->contains('test'); // true 67 | 68 | containsKey 69 | ----------- 70 | 71 | Checks whether the collection contains an element with the specified key/index. 72 | 73 | .. code-block:: php 74 | $collection = new Collection(['test' => true]); 75 | 76 | $contains = $collection->containsKey('test'); // true 77 | 78 | current 79 | ------- 80 | 81 | Gets the element of the collection at the current iterator position. 82 | 83 | .. code-block:: php 84 | $collection = new Collection(['first', 'second', 'third']); 85 | 86 | $current = $collection->current(); // first 87 | 88 | get 89 | --- 90 | 91 | Gets the element at the specified key/index. 92 | 93 | .. code-block:: php 94 | $collection = new Collection([ 95 | 'key' => 'value', 96 | ]); 97 | 98 | $value = $collection->get('key'); // value 99 | 100 | getKeys 101 | ------- 102 | 103 | Gets all keys/indices of the collection. 104 | 105 | .. code-block:: php 106 | $collection = new Collection(['a', 'b', 'c']); 107 | 108 | $keys = $collection->getKeys(); // [0, 1, 2] 109 | 110 | getValues 111 | --------- 112 | 113 | Gets all values of the collection. 114 | 115 | .. code-block:: php 116 | $collection = new Collection([ 117 | 'key1' => 'value1', 118 | 'key2' => 'value2', 119 | 'key3' => 'value3', 120 | ]); 121 | 122 | $values = $collection->getValues(); // ['value1', 'value2', 'value3'] 123 | 124 | isEmpty 125 | ------- 126 | 127 | Checks whether the collection is empty (contains no elements). 128 | 129 | .. code-block:: php 130 | $collection = new Collection(['a', 'b', 'c']); 131 | 132 | $isEmpty = $collection->isEmpty(); // false 133 | 134 | first 135 | ----- 136 | 137 | Sets the internal iterator to the first element in the collection and returns this element. 138 | 139 | .. code-block:: php 140 | $collection = new Collection(['first', 'second', 'third']); 141 | 142 | $first = $collection->first(); // first 143 | 144 | exists 145 | ------ 146 | 147 | Tests for the existence of an element that satisfies the given predicate. 148 | 149 | .. code-block:: php 150 | $collection = new Collection(['first', 'second', 'third']); 151 | 152 | $exists = $collection->exists(function($key, $value) { 153 | return $value === 'first'; 154 | }); // true 155 | 156 | filter 157 | ------ 158 | 159 | Returns all the elements of this collection for which your callback function returns `true`. 160 | The order and keys of the elements are preserved. 161 | 162 | .. code-block:: php 163 | $collection = new ArrayCollection([1, 2, 3]); 164 | 165 | $filteredCollection = $collection->filter(function($element) { 166 | return $element > 1; 167 | }); // [2, 3] 168 | 169 | forAll 170 | ------ 171 | 172 | Tests whether the given predicate holds for all elements of this collection. 173 | 174 | .. code-block:: php 175 | $collection = new ArrayCollection([1, 2, 3]); 176 | 177 | $forAll = $collection->forAll(function($key, $value) { 178 | return $value > 1; 179 | }); // false 180 | 181 | indexOf 182 | ------- 183 | 184 | Gets the index/key of a given element. The comparison of two elements is strict, that means not only the value but also the type must match. For objects this means reference equality. 185 | 186 | .. code-block:: php 187 | $collection = new ArrayCollection([1, 2, 3]); 188 | 189 | $indexOf = $collection->indexOf(3); // 2 190 | 191 | key 192 | --- 193 | 194 | Gets the key/index of the element at the current iterator position. 195 | 196 | .. code-block:: php 197 | $collection = new ArrayCollection([1, 2, 3]); 198 | 199 | $collection->next(); 200 | 201 | $key = $collection->key(); // 1 202 | 203 | last 204 | ---- 205 | 206 | Sets the internal iterator to the last element in the collection and returns this element. 207 | 208 | .. code-block:: php 209 | $collection = new ArrayCollection([1, 2, 3]); 210 | 211 | $last = $collection->last(); // 3 212 | 213 | map 214 | --- 215 | 216 | Applies the given function to each element in the collection and returns a new collection with the elements returned by the function. 217 | 218 | .. code-block:: php 219 | $collection = new ArrayCollection([1, 2, 3]); 220 | 221 | $mappedCollection = $collection->map(function($value) { 222 | return $value + 1; 223 | }); // [2, 3, 4] 224 | 225 | next 226 | ---- 227 | 228 | Moves the internal iterator position to the next element and returns this element. 229 | 230 | .. code-block:: php 231 | $collection = new ArrayCollection([1, 2, 3]); 232 | 233 | $next = $collection->next(); // 2 234 | 235 | partition 236 | --------- 237 | 238 | Partitions this collection in two collections according to a predicate. Keys are preserved in the resulting collections. 239 | 240 | .. code-block:: php 241 | $collection = new ArrayCollection([1, 2, 3]); 242 | 243 | $mappedCollection = $collection->partition(function($key, $value) { 244 | return $value > 1 245 | }); // [[2, 3], [1]] 246 | 247 | remove 248 | ------ 249 | 250 | Removes the element at the specified index from the collection. 251 | 252 | .. code-block:: php 253 | $collection = new ArrayCollection([1, 2, 3]); 254 | 255 | $collection->remove(0); // [2, 3] 256 | 257 | removeElement 258 | ------------- 259 | 260 | Removes the specified element from the collection, if it is found. 261 | 262 | .. code-block:: php 263 | $collection = new ArrayCollection([1, 2, 3]); 264 | 265 | $collection->removeElement(3); // [1, 2] 266 | 267 | set 268 | --- 269 | 270 | Sets an element in the collection at the specified key/index. 271 | 272 | .. code-block:: php 273 | $collection = new ArrayCollection(); 274 | 275 | $collection->set('name', 'jwage'); 276 | 277 | slice 278 | ----- 279 | 280 | Extracts a slice of $length elements starting at position $offset from the Collection. If $length is null it returns all elements from $offset to the end of the Collection. Keys have to be preserved by this method. Calling this method will only return the selected slice and NOT change the elements contained in the collection slice is called on. 281 | 282 | .. code-block:: php 283 | $collection = new ArrayCollection([0, 1, 2, 3, 4, 5]); 284 | 285 | $slice = $collection->slice(1, 2); // [1, 2] 286 | 287 | toArray 288 | ------- 289 | 290 | Gets a native PHP array representation of the collection. 291 | 292 | .. code-block:: php 293 | $collection = new ArrayCollection([0, 1, 2, 3, 4, 5]); 294 | 295 | $array = $collection->toArray(); // [0, 1, 2, 3, 4, 5] 296 | 297 | Selectable Methods 298 | ================== 299 | 300 | Some Doctrine Collections, like ``Doctrine\Common\Collections\ArrayCollection``, 301 | implement an interface named ``Doctrine\Common\Collections\Selectable`` 302 | that offers the usage of a powerful expressions API, where conditions 303 | can be applied to a collection to get a result with matching elements 304 | only. 305 | 306 | matching 307 | -------- 308 | 309 | Selects all elements from a selectable that match the expression and 310 | returns a new collection containing these elements. 311 | 312 | .. code-block:: php 313 | use Doctrine\Common\Collections\Criteria; 314 | use Doctrine\Common\Collections\Expr\Comparison; 315 | 316 | $collection = new ArrayCollection([ 317 | [ 318 | 'name' => 'jwage', 319 | ], 320 | [ 321 | 'name' => 'romanb', 322 | ], 323 | ]); 324 | 325 | $expr = new Comparison('name', '=', 'jwage'); 326 | 327 | $criteria = new Criteria(); 328 | 329 | $criteria->where($expr); 330 | 331 | $matched = $collection->matching($criteria); // ['jwage'] 332 | 333 | You can read more about expressions :ref:`here `. 334 | --------------------------------------------------------------------------------