From dc1949ba4c425db970e2f93d885bca189de6b8be Mon Sep 17 00:00:00 2001 From: Daniel Waxweiler Date: Fri, 5 Apr 2024 23:26:11 +0200 Subject: [PATCH] move requests to backend (#18) --- .gitignore | 3 + README.md | 1 + composer.json | 11 +- composer.lock | 1738 ++++++++++++++++- gulpfile.cjs | 3 +- package.json | 2 +- phpunit.xml | 27 + source/changelog.txt | 3 + source/connector-mobilizon.php | 32 +- source/front/blocks/events-list/edit.js | 108 +- source/front/events-displayer-test.js | 29 +- source/front/events-displayer.js | 6 +- source/front/events-loader.js | 38 - source/includes/Api.php | 53 + .../includes/{constants.php => Constants.php} | 5 - source/includes/DateTimeWrapper.php | 34 + source/includes/EventsCache.php | 19 + ...nts-list-block.php => EventsListBlock.php} | 26 +- ...st-shortcut.php => EventsListShortcut.php} | 26 +- ...s-list-widget.php => EventsListWidget.php} | 26 +- source/includes/Formatter.php | 42 + source/includes/GraphQlClient.php | 113 ++ .../includes/{settings.php => Settings.php} | 5 - .../includes/exceptions/GeneralException.php | 12 + .../exceptions/GroupNotFoundException.php | 12 + source/readme.txt | 2 +- source/uninstall.php | 4 +- source/view/events-list-group-not-found.php | 11 + source/view/events-list-not-loaded.php | 11 + source/view/events-list-widget/form.php | 2 + source/view/events-list.php | 23 +- .../is-short-offset-name-shown-field.php | 2 + source/view/settings/page.php | 2 + source/view/settings/url-field.php | 2 + tests/DateTimeWrapperTest.php | 47 + tests/FormatterTest.php | 52 + webpack.config.cjs | 1 - 37 files changed, 2369 insertions(+), 164 deletions(-) create mode 100644 phpunit.xml delete mode 100644 source/front/events-loader.js create mode 100644 source/includes/Api.php rename source/includes/{constants.php => Constants.php} (64%) create mode 100644 source/includes/DateTimeWrapper.php create mode 100644 source/includes/EventsCache.php rename source/includes/{events-list-block.php => EventsListBlock.php} (64%) rename source/includes/{events-list-shortcut.php => EventsListShortcut.php} (52%) rename source/includes/{events-list-widget.php => EventsListWidget.php} (69%) create mode 100644 source/includes/Formatter.php create mode 100644 source/includes/GraphQlClient.php rename source/includes/{settings.php => Settings.php} (98%) create mode 100644 source/includes/exceptions/GeneralException.php create mode 100644 source/includes/exceptions/GroupNotFoundException.php create mode 100644 source/view/events-list-group-not-found.php create mode 100644 source/view/events-list-not-loaded.php create mode 100644 tests/DateTimeWrapperTest.php create mode 100644 tests/FormatterTest.php diff --git a/.gitignore b/.gitignore index 615015c..569ac1a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ build/ coverage/ node_modules/ vendor/ + +.phpunit.cache +.phpunit.result.cache diff --git a/README.md b/README.md index 2b9b088..8de6309 100644 --- a/README.md +++ b/README.md @@ -47,3 +47,4 @@ The current changelog can be found under [source/changelog.txt](source/changelog - Update PHP dependencies: `composer update` - Check for direct PHP dependency updates: `composer outdated --direct` - Format code with prettier: `npm run format` +- Generate `vendor/autoload.php` file after creating new class: `composer dump-autoload` diff --git a/composer.json b/composer.json index 0967ef4..69806a6 100644 --- a/composer.json +++ b/composer.json @@ -1 +1,10 @@ -{} +{ + "autoload": { + "psr-4": { + "MobilizonConnector\\": "source/includes/" + } + }, + "require-dev": { + "phpunit/phpunit": "^9.6" + } +} diff --git a/composer.lock b/composer.lock index fd0bcbc..7814239 100644 --- a/composer.lock +++ b/composer.lock @@ -4,9 +4,1741 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d751713988987e9331980363e24189ce", + "content-hash": "6c23f37f66ceb05fd480caba8880c601", "packages": [], - "packages-dev": [], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^11", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:23:10+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.15.5", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/11e2663a5bc9db5d714eedb4277ee300403b4a9e", + "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.5" + }, + "time": "2023-05-19T20:20:00+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.26", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", + "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.15", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.26" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-03-06T12:58:08+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.6.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "17d621b3aff84d0c8b62539e269e87d8d5baa76e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/17d621b3aff84d0c8b62539e269e87d8d5baa76e", + "reference": "17d621b3aff84d0c8b62539e269e87d8d5baa76e", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1 || ^2", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.8", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.5", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.2", + "sebastian/version": "^3.0.2" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.6-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.8" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2023-05-11T05:14:45+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T12:41:17+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-05-07T05:35:17+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:03:51+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T06:03:37+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-02-14T08:28:10+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:07:39+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:13:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + } + ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], @@ -14,5 +1746,5 @@ "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.3.0" } diff --git a/gulpfile.cjs b/gulpfile.cjs index ced7188..3ef0479 100644 --- a/gulpfile.cjs +++ b/gulpfile.cjs @@ -11,9 +11,8 @@ function injectMetadata() { return src( [ FOLDER_BUILD + '/front/block-events-loader.js', - FOLDER_BUILD + '/front/events-loader.js', FOLDER_BUILD + '/' + PACKAGE.name + '.php', - FOLDER_BUILD + '/includes/constants.php', + FOLDER_BUILD + '/includes/Constants.php', FOLDER_BUILD + '/readme.txt', ], { base: './' }, diff --git a/package.json b/package.json index 7f8dc33..4833bf9 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "eslint": "npx eslint source/**/*.js", "format": "npx prettier --write .", "prepare": "husky install", - "test": "ava" + "test": "ava && ./vendor/bin/phpunit" }, "author": { "name": "Daniel Waxweiler", diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..5a15cdb --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,27 @@ + + + + + tests + + + + + + source/includes + + + diff --git a/source/changelog.txt b/source/changelog.txt index 22a9c77..f897478 100644 --- a/source/changelog.txt +++ b/source/changelog.txt @@ -1,9 +1,12 @@ ### [Unreleased] #### Added +- Display name of group when it cannot be found #### Changed +- Let backend do requests to API of Mobilizon instance for increased privacy #### Deprecated #### Removed #### Fixed +- Fix displaying more than one block in the editor #### Security ### [0.11.5] diff --git a/source/connector-mobilizon.php b/source/connector-mobilizon.php index da173d9..c90a4d0 100644 --- a/source/connector-mobilizon.php +++ b/source/connector-mobilizon.php @@ -10,11 +10,18 @@ * License: */ -require_once __DIR__ . '/includes/constants.php'; -require_once __DIR__ . '/includes/settings.php'; -require_once __DIR__ . '/includes/events-list-block.php'; -require_once __DIR__ . '/includes/events-list-shortcut.php'; -require_once __DIR__ . '/includes/events-list-widget.php'; +require_once __DIR__ . '/includes/exceptions/GeneralException.php'; +require_once __DIR__ . '/includes/exceptions/GroupNotFoundException.php'; +require_once __DIR__ . '/includes/Constants.php'; +require_once __DIR__ . '/includes/Api.php'; +require_once __DIR__ . '/includes/EventsCache.php'; +require_once __DIR__ . '/includes/Settings.php'; +require_once __DIR__ . '/includes/DateTimeWrapper.php'; +require_once __DIR__ . '/includes/Formatter.php'; +require_once __DIR__ . '/includes/GraphQlClient.php'; +require_once __DIR__ . '/includes/EventsListBlock.php'; +require_once __DIR__ . '/includes/EventsListShortcut.php'; +require_once __DIR__ . '/includes/EventsListWidget.php'; // Exit if this file is called directly. if (!defined('ABSPATH')) { @@ -24,11 +31,11 @@ if (!defined('ABSPATH')) { final class Mobilizon_Connector { private function __construct() { + add_action('init', [$this, 'register_api']); add_action('init', [$this, 'register_blocks']); add_action('init', [$this, 'register_settings'], 1); // required for register_blocks add_action('init', [$this, 'register_shortcut']); add_action('widgets_init', [$this, 'register_widget']); - add_action('wp_enqueue_scripts', [$this, 'register_scripts']); register_activation_hook(__FILE__, [$this, 'enable_activation']); } @@ -49,12 +56,15 @@ final class Mobilizon_Connector { $settings = array( 'isShortOffsetNameShown' => MobilizonConnector\Settings::isShortOffsetNameShown(), 'locale' => str_replace('_', '-', get_locale()), - 'timeZone' => wp_timezone_string(), - 'url' => MobilizonConnector\Settings::getUrl() + 'timeZone' => wp_timezone_string() ); wp_add_inline_script($scriptName, 'var MOBILIZON_CONNECTOR = ' . json_encode($settings), 'before'); } + public function register_api() { + MobilizonConnector\Api::init(); + } + public function register_blocks() { $scriptName = MobilizonConnector\EventsListBlock::initAndReturnScriptName(); $this->load_settings_globally_before_script($scriptName); @@ -64,12 +74,6 @@ final class Mobilizon_Connector { MobilizonConnector\Settings::init(); } - public function register_scripts() { - $name = MobilizonConnector\NAME . '-js'; - wp_enqueue_script($name, plugins_url('front/events-loader.js', __FILE__ )); - $this->load_settings_globally_before_script($name); - } - public function register_shortcut() { MobilizonConnector\EventsListShortcut::init(); } diff --git a/source/front/blocks/events-list/edit.js b/source/front/blocks/events-list/edit.js index d1da0bf..f8de8a3 100644 --- a/source/front/blocks/events-list/edit.js +++ b/source/front/blocks/events-list/edit.js @@ -1,75 +1,101 @@ /* eslint-disable @wordpress/i18n-ellipsis */ -import { loadEventList } from '../../events-loader.js' +import { + clearEventsList, + displayErrorMessage, + displayEvents, + hideErrorMessages, + showLoadingIndicator, +} from '../../events-displayer.js' const { InspectorControls, useBlockProps } = wp.blockEditor -const { PanelBody } = wp.components +const { Panel, PanelBody } = wp.components const { useEffect } = wp.element const { __ } = wp.i18n const NAME = '' -let timer - export default ({ attributes, setAttributes }) => { + let timer const blockProps = useBlockProps({ className: NAME + '_events-list', - 'data-maximum': attributes.eventsCount, - 'data-group-name': attributes.groupName, }) - function reloadEventList() { + function reloadEventList(eventsCount, groupName) { if (timer) { clearTimeout(timer) } - timer = setTimeout(() => { + timer = setTimeout(async () => { const container = document.getElementById(blockProps.id) if (container) { - loadEventList(container) + hideErrorMessages(container) + clearEventsList(container) + showLoadingIndicator(container) + let url = `/wp-json/connector-mobilizon/v1/events?eventsCount=${eventsCount}` + if (groupName) { + url += `&groupName=${groupName}` + } + await fetch(url) + .then((response) => response.text()) + .then((data) => { + const events = JSON.parse(data) + displayEvents({ + events, + document, + container, + maxEventsCount: eventsCount, + }) + }) + .catch((data) => { + displayErrorMessage({ data, container }) + }) } }, 500) } useEffect(() => { - reloadEventList() + reloadEventList(attributes.eventsCount, attributes.groupName) }, []) function updateEventsCount(event) { let newValue = Number(event.target.value) if (newValue < 1) newValue = 1 setAttributes({ eventsCount: newValue }) - reloadEventList() + reloadEventList(newValue, attributes.groupName) } function updateGroupName(event) { - setAttributes({ groupName: event.target.value }) - reloadEventList() + const newValue = event.target.value + setAttributes({ groupName: newValue }) + reloadEventList(attributes.eventsCount, newValue) } return [ - ')}> - - - - - + + ')}> + + + + + + ,
diff --git a/source/front/events-displayer-test.js b/source/front/events-displayer-test.js index 6feb578..93b55e9 100644 --- a/source/front/events-displayer-test.js +++ b/source/front/events-displayer-test.js @@ -18,7 +18,6 @@ test.before(() => { test.beforeEach((t) => { t.context.container = document.createElement('div') - t.context.container.setAttribute('data-maximum', '2') const errorMessageGeneral = document.createElement('div') errorMessageGeneral.setAttribute('class', 'general-error') @@ -40,24 +39,20 @@ test.beforeEach((t) => { }) test('#displayEvents one event', (t) => { - const data = { - events: { - elements: [ - { - title: 'a', - url: 'b', - beginsOn: '2021-04-15T10:30:00Z', - endsOn: '2021-04-15T15:30:00Z', - physicalAddress: { - description: 'c', - locality: 'd', - }, - }, - ], + const events = [ + { + title: 'a', + url: 'b', + beginsOn: '2021-04-15T10:30:00Z', + endsOn: '2021-04-15T15:30:00Z', + physicalAddress: { + description: 'c', + locality: 'd', + }, }, - } + ] const container = t.context.container - displayEvents({ data, document, container }) + displayEvents({ events, document, container, maxEventsCount: 2 }) const list = container.querySelector('ul') t.is(list.children[0].childNodes[0].tagName, 'A') t.is(list.children[0].childNodes[0].getAttribute('href'), 'b') diff --git a/source/front/events-displayer.js b/source/front/events-displayer.js index 96abf20..6eec340 100644 --- a/source/front/events-displayer.js +++ b/source/front/events-displayer.js @@ -6,18 +6,14 @@ export function clearEventsList(container) { list.replaceChildren() } -export function displayEvents({ data, document, container }) { +export function displayEvents({ events, document, container, maxEventsCount }) { hideLoadingIndicator(container) const isShortOffsetNameShown = window.MOBILIZON_CONNECTOR.isShortOffsetNameShown const locale = window.MOBILIZON_CONNECTOR.locale - const maxEventsCount = container.getAttribute('data-maximum') const timeZone = window.MOBILIZON_CONNECTOR.timeZone - const events = data.events - ? data.events.elements - : data.group.organizedEvents.elements const eventsCount = Math.min(maxEventsCount, events.length) const list = container.querySelector('ul') for (let i = 0; i < eventsCount; i++) { diff --git a/source/front/events-loader.js b/source/front/events-loader.js deleted file mode 100644 index b88a2f5..0000000 --- a/source/front/events-loader.js +++ /dev/null @@ -1,38 +0,0 @@ -import { - clearEventsList, - displayEvents, - displayErrorMessage, - hideErrorMessages, - showLoadingIndicator, -} from './events-displayer.js' -import * as GraphqlWrapper from './graphql-wrapper.js' - -const NAME = '' -const URL_SUFFIX = '/api' - -document.addEventListener('DOMContentLoaded', loadEventLists) - -function loadEventLists() { - const eventLists = document.getElementsByClassName(NAME + '_events-list') - for (const list of eventLists) { - loadEventList(list) - } -} - -export function loadEventList(container) { - const url = MOBILIZON_CONNECTOR.url + URL_SUFFIX - const limit = parseInt(container.getAttribute('data-maximum')) - const groupName = container.getAttribute('data-group-name') - hideErrorMessages(container) - clearEventsList(container) - showLoadingIndicator(container) - if (groupName) { - GraphqlWrapper.getUpcomingEventsByGroupName({ url, limit, groupName }) - .then((data) => displayEvents({ data, document, container })) - .catch((data) => displayErrorMessage({ data, container })) - } else { - GraphqlWrapper.getUpcomingEvents({ url, limit }) - .then((data) => displayEvents({ data, document, container })) - .catch((data) => displayErrorMessage({ data, container })) - } -} diff --git a/source/includes/Api.php b/source/includes/Api.php new file mode 100644 index 0000000..b3d1bb1 --- /dev/null +++ b/source/includes/Api.php @@ -0,0 +1,53 @@ + 'GET', + 'callback' => 'MobilizonConnector\Api::get_events', + 'args' => [ + 'eventsCount' => [ + 'required' => true, + 'validate_callback' => function($param, $request, $key) { + return is_numeric($param) && $param > 0; + } + ], + 'groupName' => [ + 'validate_callback' => function($param, $request, $key) { + return !is_numeric($param); + } + ] + ], + 'permission_callback' => '__return_true', + ] + ); + } + + public static function get_events($request) { + $eventsCount = $request['eventsCount']; + $groupName = isset($request['groupName']) ? $request['groupName'] : ''; + + $url = Settings::getUrl(); + + try { + if ($groupName) { + $events = GraphQlClient::get_upcoming_events_by_group_name($url, (int) $eventsCount, $groupName); + } else { + $events = GraphQlClient::get_upcoming_events($url, (int) $eventsCount); + } + return $events; + } catch (GeneralException $e) { + return new \WP_Error('events_not_loading', 'The events could not be loaded!', array('status' => 500)); + } catch (GroupNotFoundException $e) { + return new \WP_Error('group_not_found', sprintf('The group "%s" could not be found!', $groupName), array('status' => 404)); + } + } +} diff --git a/source/includes/constants.php b/source/includes/Constants.php similarity index 64% rename from source/includes/constants.php rename to source/includes/Constants.php index 159460e..b48e68c 100644 --- a/source/includes/constants.php +++ b/source/includes/Constants.php @@ -1,11 +1,6 @@ '; const NICE_NAME = ''; diff --git a/source/includes/DateTimeWrapper.php b/source/includes/DateTimeWrapper.php new file mode 100644 index 0000000..9c5a578 --- /dev/null +++ b/source/includes/DateTimeWrapper.php @@ -0,0 +1,34 @@ +dateTime = new \DateTime($text); + $this->locale = $locale; + $this->timeZone = new \DateTimeZone($timeZone); + } + + public function get24Time(): string { + $formatter = \IntlDateFormatter::create($this->locale, \IntlDateFormatter::NONE, \IntlDateFormatter::SHORT, $this->timeZone); + return $formatter->format($this->dateTime); + } + + public function getShortDate(): string { + $formatter = \IntlDateFormatter::create($this->locale, \IntlDateFormatter::SHORT, \IntlDateFormatter::NONE, $this->timeZone); + return $formatter->format($this->dateTime); + } + + public function getTimeZoneName(): string { + return $this->timeZone->getName(); + } +} diff --git a/source/includes/EventsCache.php b/source/includes/EventsCache.php new file mode 100644 index 0000000..ac0027c --- /dev/null +++ b/source/includes/EventsCache.php @@ -0,0 +1,19 @@ +getShortDate(); + $dateText .= ' ' . $startDateTime->get24Time(); + if (!$end && $isShortOffsetNameShown) { + $dateText .= ' (' . $startDateTime->getTimeZoneName() . ')'; + } + if ($end) { + $endDateTime = new DateTimeWrapper($end, $locale, $timeZone); + if ($startDateTime->getShortDate() != $endDateTime->getShortDate()) { + $dateText .= ' - '; + $dateText .= $endDateTime->getShortDate() . ' '; + } else { + $dateText .= ' - '; + } + $dateText .= $endDateTime->get24Time(); + if ($isShortOffsetNameShown) { + $dateText .= ' (' . $endDateTime->getTimeZoneName() . ')'; + } + } + return $dateText; + } + + public static function format_location(string $description, string $locality): string { + $location = ''; + if ($description && trim($description)) { + $location .= trim($description); + } + if ($location && $locality) { + $location .= ', '; + } + if ($locality) { + $location .= $locality; + } + return $location; + } +} diff --git a/source/includes/GraphQlClient.php b/source/includes/GraphQlClient.php new file mode 100644 index 0000000..b87dc88 --- /dev/null +++ b/source/includes/GraphQlClient.php @@ -0,0 +1,113 @@ + [ + 'method' => 'POST', + 'header' => $headers, + 'content' => json_encode(['query' => $query, 'variables' => $variables]), + ] + ]); + $data = @file_get_contents($endpoint, false, $context); + + if ($data === false) { + $error = error_get_last(); + throw new \ErrorException($error['message'], $error['type']); + } + + return json_decode($data, true); + } + + public static function get_upcoming_events(string $url, int $limit): array { + $query = <<<'GRAPHQL' + query ($limit: Int) { + events(limit: $limit) { + elements { + id, + title, + url, + beginsOn, + endsOn, + physicalAddress { + description, + locality + } + }, + total + } + } + GRAPHQL; + + $cachedEvents = EventsCache::get(['url' => $url, 'query' => $query, 'limit' => $limit]); + if ($cachedEvents !== false) { + return $cachedEvents; + } + + $endpoint = $url . '/api'; + $data = self::query($endpoint, $query, ['limit' => $limit]); + self::checkData($data); + + $events = $data['data']['events']['elements']; + EventsCache::set(['url' => $url, 'query' => $query, 'limit' => $limit], $events); + return $events; + } + + public static function get_upcoming_events_by_group_name(string $url, int $limit, string $groupName): array { + $query = <<<'GRAPHQL' + query ($afterDatetime: DateTime, $groupName: String!, $limit: Int) { + group(preferredUsername: $groupName) { + organizedEvents(afterDatetime: $afterDatetime, limit: $limit) { + elements { + id, + title, + url, + beginsOn, + endsOn, + physicalAddress { + description, + locality + } + }, + total + } + } + } + GRAPHQL; + + $afterDatetime = date(\DateTime::ISO8601); + + $cachedEvents = EventsCache::get(['url' => $url, 'query' => $query, 'afterDatetime' => $afterDatetime, 'groupName' => $groupName, 'limit' => $limit]); + if ($cachedEvents !== false) { + return $cachedEvents; + } + + $endpoint = $url . '/api'; + $data = self::query($endpoint, $query, ['afterDatetime' => $afterDatetime, 'groupName' => $groupName, 'limit' => $limit]); + self::checkData($data); + + $events = $data['data']['group']['organizedEvents']['elements']; + EventsCache::set(['url' => $url, 'query' => $query, 'afterDatetime' => $afterDatetime, 'groupName' => $groupName, 'limit' => $limit], $events); + return $events; + } + + private static function checkData($data) { + if (isset($data['errors'])) { + if (count($data['errors']) > 0 && + isset($data['errors'][0]['code']) && + $data['errors'][0]['code'] === 'group_not_found') { + throw new GroupNotFoundException(serialize($data['errors'][0])); + } else { + throw new GeneralException(serialize($data['errors'])); + } + } + } +} diff --git a/source/includes/settings.php b/source/includes/Settings.php similarity index 98% rename from source/includes/settings.php rename to source/includes/Settings.php index a7b0e2b..9b5feac 100644 --- a/source/includes/settings.php +++ b/source/includes/Settings.php @@ -1,11 +1,6 @@ code}]: {$this->message}\n"; +} +} diff --git a/source/includes/exceptions/GroupNotFoundException.php b/source/includes/exceptions/GroupNotFoundException.php new file mode 100644 index 0000000..6fabb41 --- /dev/null +++ b/source/includes/exceptions/GroupNotFoundException.php @@ -0,0 +1,12 @@ +code}]: {$this->message}\n"; +} +} diff --git a/source/readme.txt b/source/readme.txt index 75b4580..201a3e9 100644 --- a/source/readme.txt +++ b/source/readme.txt @@ -17,7 +17,7 @@ License: Features - Display events as Gutenberg block, as widget and as shortcut - Display events' title, date, and location, if available -- Cache requests' responses for 2 minutes in the browser's `sessionStorage` +- Cache requests' responses for 2 minutes in the database - Configure number of events to show per block, per widget and per shortcut - Optionally filter events by a specific group per block, per widget and per shortcut - Set the URL of the Mobilizon instance in the settings diff --git a/source/uninstall.php b/source/uninstall.php index 4342684..67e868f 100644 --- a/source/uninstall.php +++ b/source/uninstall.php @@ -1,6 +1,6 @@ +
+ +
diff --git a/source/view/events-list-not-loaded.php b/source/view/events-list-not-loaded.php new file mode 100644 index 0000000..5bf43d5 --- /dev/null +++ b/source/view/events-list-not-loaded.php @@ -0,0 +1,11 @@ + +
+ +
diff --git a/source/view/events-list-widget/form.php b/source/view/events-list-widget/form.php index db614d4..1e7b1e9 100644 --- a/source/view/events-list-widget/form.php +++ b/source/view/events-list-widget/form.php @@ -1,4 +1,6 @@ -
- - - -
    +
    +
      + +
    • + +
      + + +
      + + +
    • + +
    diff --git a/source/view/settings/is-short-offset-name-shown-field.php b/source/view/settings/is-short-offset-name-shown-field.php index f05f9bb..424a011 100644 --- a/source/view/settings/is-short-offset-name-shown-field.php +++ b/source/view/settings/is-short-offset-name-shown-field.php @@ -1,4 +1,6 @@ assertSame('16:45', $d->get24Time()); + } + + public function testCanGetShortDateForUsualDate(): void { + $d = new DateTimeWrapper('2020-12-24T16:45:00Z'); + $this->assertSame('24/12/2020', $d->getShortDate()); + } + + public function testCanGetShortDateForUsualDateWithLocaleWithUnderscore(): void { + $d = new DateTimeWrapper('2020-12-24T16:45:00Z'); + $this->assertSame('24/12/2020', $d->getShortDate(), 'en_GB'); + } + + public function testCanGetShortDateForUsualDateWithTimezoneString(): void { + $d = new DateTimeWrapper('2020-12-24T16:45:00Z', 'en-GB', 'Europe/Rome'); + $this->assertSame('24/12/2020', $d->getShortDate()); + } + + public function testCanGetShortDateForUsualDateWithNamedOffset(): void { + $d = new DateTimeWrapper('2020-12-24T16:45:00Z', 'en-GB', 'UTC'); + $this->assertSame('24/12/2020', $d->getShortDate()); + } + + public function testCanGetShortDateForUsualDateWithOffset(): void { + $d = new DateTimeWrapper('2020-12-24T16:45:00Z', 'en-GB', '+02:00'); + $this->assertSame('24/12/2020', $d->getShortDate()); + } + + public function testCanGetShortDateForUsualDateWithEmptyTimezone(): void { + $d = new DateTimeWrapper('2020-12-24T16:45:00Z', 'en-GB', ''); + $this->assertSame('24/12/2020', $d->getShortDate()); + } + + public function testCanGetShortOffsetNameForUsualTime(): void { + $d = new DateTimeWrapper('2020-12-24T16:45:00Z'); + $this->assertSame('UTC', $d->getTimeZoneName()); + } +} diff --git a/tests/FormatterTest.php b/tests/FormatterTest.php new file mode 100644 index 0000000..56ed230 --- /dev/null +++ b/tests/FormatterTest.php @@ -0,0 +1,52 @@ +assertSame('15/04/2021 10:30 - 15:30', Formatter::format_date('en-GB', 'UTC', '2021-04-15T10:30:00Z', '2021-04-15T15:30:00Z', false)); + } + + public function testCanDateFormatOneDateWithOffset(): void { + $this->assertSame('15/04/2021 10:30 - 15:30 (UTC)', Formatter::format_date('en-GB', 'UTC', '2021-04-15T10:30:00Z', '2021-04-15T15:30:00Z', true)); + } + + public function testCanDateFormatOneDateWithTimeZoneOffset(): void { + $this->assertSame('15/04/2021 11:30 - 16:30', Formatter::format_date('en-GB', '+01:00', '2021-04-15T10:30:00Z', '2021-04-15T15:30:00Z', false)); + } + + public function testCanDateFormatTwoDates(): void { + $this->assertSame('15/04/2021 10:30 - 16/04/2021 15:30', Formatter::format_date('en-GB', 'UTC', '2021-04-15T10:30:00Z', '2021-04-16T15:30:00Z', false)); + } + + public function testCanDateFormatTwoDatesWithOffset(): void { + $this->assertSame('15/04/2021 10:30 - 16/04/2021 15:30 (UTC)', Formatter::format_date('en-GB', 'UTC', '2021-04-15T10:30:00Z', '2021-04-16T15:30:00Z', true)); + } + + public function testCanDateFormatWhenSecondDateIsNull(): void { + $this->assertSame('15/04/2021 10:30', Formatter::format_date('en-GB', 'UTC', '2021-04-15T10:30:00Z', null, false)); + } + + public function testCanDateFormatWhenSecondDateIsNullWithOffset(): void { + $this->assertSame('15/04/2021 10:30 (UTC)', Formatter::format_date('en-GB', 'UTC', '2021-04-15T10:30:00Z', null, true)); + } + + public function testCanLocationFormatBothParameters(): void { + $this->assertSame('a, b', Formatter::format_location('a', 'b')); + } + + public function testLocationFormatDescriptionOnly(): void { + $this->assertSame('a', Formatter::format_location('a', '')); + } + + public function testLocationFormatDescriptionWithSpaceOnly(): void { + $this->assertSame('', Formatter::format_location(' ', '')); + } + + public function testLocationFormatLocalityOnly(): void { + $this->assertSame('a', Formatter::format_location('', 'a')); + } +} diff --git a/webpack.config.cjs b/webpack.config.cjs index c3ff736..c61fe98 100644 --- a/webpack.config.cjs +++ b/webpack.config.cjs @@ -8,7 +8,6 @@ const FOLDER_SOURCE = './source' module.exports = { entry: { 'block-events-loader': FOLDER_SOURCE + '/front/block-events-loader.js', - 'events-loader': FOLDER_SOURCE + '/front/events-loader.js', }, output: { filename: '[name].js',