diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 00000000..8ca00ef3 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,50 @@ +kind: pipeline +type: docker +name: unit-tests + +steps: + - name: check-pr-branch-name + image: alpine + commands: + - ./bin/check-branch-name.sh + when: + event: + include: + - pull_request + - name: install + image: composer + commands: + - composer install --ignore-platform-reqs + - name: test + image: php:7 + environment: + CC_TEST_REPORTER_ID: + from_secret: cc_test_reporter_id + commands: + - apt-get update && apt-get install -y zlib1g-dev libicu-dev g++ git + - docker-php-ext-configure intl + - docker-php-ext-install intl + - ./vendor/bin/phpunit -c phpunit-checks.xml --no-coverage + - pecl install xdebug + - docker-php-ext-enable xdebug + - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter + - chmod +x ./cc-test-reporter + - ./cc-test-reporter before-build + - XDEBUG_MODE=coverage ./vendor/bin/phpunit -c phpunit.xml + - ./bin/report-code-coverage.sh + - name: slack + image: plugins/slack + settings: + webhook: + from_secret: slack_hook + when: + status: + - failure + event: + exclude: + - pull_request + +trigger: + branch: + exclude: + - feature/* diff --git a/.idea/Einsatzverwaltung.iml b/.idea/Einsatzverwaltung.iml index aad2a029..3541ed5d 100644 --- a/.idea/Einsatzverwaltung.iml +++ b/.idea/Einsatzverwaltung.iml @@ -6,74 +6,79 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/.idea/misc.xml b/.idea/misc.xml index 213af641..7faf8a41 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -10,6 +10,6 @@ - \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml index 1872c689..9307c1bc 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -19,74 +19,79 @@ - - - - - - - - + + + + + - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 65c4c9ca..00000000 --- a/.travis.yml +++ /dev/null @@ -1,68 +0,0 @@ -os: linux -dist: xenial -language: php - -notifications: - email: - on_success: never - on_failure: always - slack: - secure: i6jy0Y/EiplpnJVw47cJuB3isSh19qI5F9bj299/jGb+4IBXkZh6k8jjn13Amg3P59ydOowPtI+tyYw9vu84rTQ03giddcyyPK7qxZziyJ+y5/fhsA8gHPgexA0pxA/wt6Hp6QzDC+jmPVSXSZ6ImYTDz6dk+arfQd5oGVHcfgRB+o6enw6J3Q+yt6YugyJoVpETO71aj7u/LE44yVk49SJTnQBaqXGLrWPT1uBaINzheAvPO0oICHCoqUK3XKR3b5UCvILywBkbyc01gyPO0CpT3TPPyfXR8nburkzEG+b2bKbrMD9kWnIXxNiue+zOB0jLKK2yJw7AHOewUek9J93mvzk7204CNeu5uA8xAEO2BiiRky+KhL+HHhnUHe7YlvL1xHZMlw/u0BzAgUsoELnFZb5FawiQ2lw8CuNTxCL91sQqvpMCTYAmJqZpWjZRaj8wSUm/3jiMjgIrhWv5rDnmeQJEPN+v5ZGs91yyXwEMVnsXePNx+13/3HrCFYpCawfb8S+1UljR+kZ4YJuX0+zE86x8pCGl4AOHGafvUY3T014ma0CWTvvW264fvS9NmJirRkTVsilvQACuL2RW3yl7gXqhCaTWRAm4P3F5V2K5+SKqaHVz4+Hd/jSXTr5Q0UKfdW9EuDU9YId+89JkDRq+nRwNMgv4wrrD6T7mo6E= -branches: - except: - - /^feature\/[-\w]+$/ - -php: - - '7.3' - -env: - - WP_VERSION=latest WP_MULTISITE=0 - - WP_VERSION=5.1.8 WP_MULTISITE=0 - - WP_VERSION=5.2.9 WP_MULTISITE=0 - - WP_VERSION=5.3.6 WP_MULTISITE=0 - - WP_VERSION=5.4.4 WP_MULTISITE=0 - - WP_VERSION=5.5.3 WP_MULTISITE=0 - - WP_VERSION=nightly WP_MULTISITE=0 - -services: - - mysql - -stages: - - validate - - test - -jobs: - include: - - stage: validate - name: "Basic Checks" - before_script: skip - script: ./vendor/bin/phpunit -c phpunit-checks.xml --no-coverage - - stage: validate - name: 'Minimum requirement' - php: '7.1' - before_script: skip - script: ./vendor/bin/phpunit -c phpunit.xml --no-coverage - - stage: validate - name: 'Latest versions' - before_install: skip - before_script: - - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter - - chmod +x ./cc-test-reporter - - ./cc-test-reporter before-build - script: XDEBUG_MODE=coverage ./vendor/bin/phpunit -c phpunit.xml - after_script: - - ./cc-test-reporter after-build --coverage-input-type clover --exit-code $TRAVIS_TEST_RESULT - - stage: test - name: 'Latest versions, pretty permalinks' - env: WP_VERSION=latest WP_MULTISITE=0 WP_TESTS_PERMALINK=PRETTY - - stage: test - name: 'Latest versions, PATHINFO permalinks' - env: WP_VERSION=latest WP_MULTISITE=0 WP_TESTS_PERMALINK=PATHINFO - allow_failures: - - env: WP_VERSION=nightly WP_MULTISITE=0 - fast_finish: true - -before_install: phpenv config-rm xdebug.ini -install: composer install --prefer-source -before_script: bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION -script: ./vendor/bin/phpunit -c phpunit-integration.xml --no-coverage diff --git a/README.md b/README.md index f1e5e5ea..e3c73393 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,7 @@ ![Wordpress Plugin: Tested WP Version](https://img.shields.io/wordpress/plugin/tested/einsatzverwaltung.svg) ![Wordpress Plugin Active Installs](https://img.shields.io/wordpress/plugin/installs/einsatzverwaltung.svg) [![Wordpress Plugin Rating](https://img.shields.io/wordpress/plugin/rating/einsatzverwaltung.svg)](https://wordpress.org/support/plugin/einsatzverwaltung/reviews/) -[![Build Status](https://travis-ci.org/abrain/einsatzverwaltung.svg)](https://travis-ci.org/abrain/einsatzverwaltung) -[![Liberapay receiving](https://img.shields.io/liberapay/receives/abrain.svg)](https://liberapay.com/abrain) +[![Build Status](https://drone.abrain.dev/api/badges/abrain/einsatzverwaltung/status.svg?ref=refs/heads/develop)](https://drone.abrain.dev/abrain/einsatzverwaltung) Dieses Plugin fügt WordPress eine neue Beitragsart "Einsatzbericht" hinzu. Diese Einsatzberichte werden wie gewöhnliche WordPress-Beiträge erstellt, es können aber zusätzliche Informationen wie Alarmzeit, Art des Einsatzes, eingesetzte Fahrzeuge und vieles mehr angegeben werden. Zudem stellt das Plugin verschiedene Möglichkeiten zur Darstellung der Einsatzberichte zur Verfügung. @@ -19,7 +18,9 @@ Uses Font Awesome by Dave Gandy - http://fontawesome.io ### Hinweise für Entwickler Dieses Projekt arbeitet mit [git-flow](http://nvie.com/posts/a-successful-git-branching-model/). Die Entwicklung findet im Branch [develop](https://github.com/abrain/einsatzverwaltung/tree/develop) statt, im Branch [master](https://github.com/abrain/einsatzverwaltung/tree/master) befindet sich immer der Stand der zuletzt veröffentlichten Version. -Pull Requests werden nur im Branch `develop` angenommen. + +Pull Requests können nur gegen `develop` gestellt werden. +Die Änderungen im Fork müssen auf einem eigenen Branch (also nicht `develop`) vorgenommen werden, da sonst die Code Coverage nicht korrekt bestimmt wird. Das Plugin an sich liegt im Ordner `src`, alles andere dient der Unterstützung bei der Entwicklung. Code aus einem anderen Branch als `master` sollte nicht für Produktivsysteme verwendet werden. diff --git a/bin/check-branch-name.sh b/bin/check-branch-name.sh new file mode 100755 index 00000000..2d05ec79 --- /dev/null +++ b/bin/check-branch-name.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env sh + +if [ "$DRONE_BUILD_EVENT" == "pull_request" ]; then + case "$DRONE_SOURCE_BRANCH" in + develop|master|main) echo "!!! Please make your changes in a branch other than develop, master, or main !!!"; + exit 1; + ;; + *) echo "Branch name OK" + ;; + esac +else + echo "This script is only meant to be run on a Pull Requests" + exit 2 +fi diff --git a/bin/report-code-coverage.sh b/bin/report-code-coverage.sh new file mode 100755 index 00000000..3461ef6a --- /dev/null +++ b/bin/report-code-coverage.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# The root directory of the project is one up +cd "$(dirname "$0")/.." + +# Set the environment variable GIT_BRANCH for the Code Climate test-reporter, so it does not report the coverage for the +# target branch of pull requests but for the source branch +if [ "$DRONE_BUILD_EVENT" == "pull_request" ]; then + export GIT_BRANCH="$DRONE_SOURCE_BRANCH" +else + export GIT_BRANCH="$DRONE_COMMIT_BRANCH" +fi + +./cc-test-reporter after-build --debug --coverage-input-type clover \ No newline at end of file diff --git a/composer.json b/composer.json index e18eb663..5d880928 100644 --- a/composer.json +++ b/composer.json @@ -21,21 +21,21 @@ }, "config": { "platform": { - "php": "7.1" + "php": "7.1.27" } }, "require": { "php": ">=7.1.0" }, "require-dev": { - "phpunit/phpunit": "^7", - "bartlett/php-compatinfo": "5.2.0", - "phpmd/phpmd": "2.7.0", - "squizlabs/php_codesniffer": "3.4.2", - "brain/monkey": "^2.3", - "friendsofphp/php-cs-fixer": "^2.15", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.1", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.1", + "phpunit/phpunit": "^7.5", + "bartlett/php-compatinfo": "^5.2", + "phpmd/phpmd": "^2.9", + "squizlabs/php_codesniffer": "^3.5", + "brain/monkey": "^2.6", + "friendsofphp/php-cs-fixer": "^2.18", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2", "sebastian/comparator": "^3.0" } } diff --git a/composer.lock b/composer.lock index 9f312412..bf4cdb2c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "222d531c0c66d5e857c5e3aa11f0d986", + "content-hash": "1fd8078ffcbc6ccca0757fbdcd31c73f", "packages": [], "packages-dev": [ { @@ -49,46 +49,50 @@ "runkit", "testing" ], + "support": { + "issues": "https://github.com/antecedent/patchwork/issues", + "source": "https://github.com/antecedent/patchwork/tree/2.1.12" + }, "time": "2019-12-22T17:52:09+00:00" }, { "name": "bartlett/php-compatinfo", - "version": "5.2.0", + "version": "5.4.2", "source": { "type": "git", "url": "https://github.com/llaville/php-compat-info.git", - "reference": "b54d10946b0f10d67be0faffb5dee24d687effd3" + "reference": "456308cc09f2c78903195bbbf09886314950a083" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/llaville/php-compat-info/zipball/b54d10946b0f10d67be0faffb5dee24d687effd3", - "reference": "b54d10946b0f10d67be0faffb5dee24d687effd3", + "url": "https://api.github.com/repos/llaville/php-compat-info/zipball/456308cc09f2c78903195bbbf09886314950a083", + "reference": "456308cc09f2c78903195bbbf09886314950a083", "shasum": "" }, "require": { - "bartlett/php-compatinfo-db": "^1.23|^2.0", - "bartlett/php-reflect": "^4.3", + "bartlett/php-compatinfo-db": "^2.0", + "bartlett/php-reflect": "^4.4", + "composer/package-versions-deprecated": "^1.8", + "doctrine/collections": "^1.4", "ext-json": "*", "ext-libxml": "*", "ext-pcre": "*", "ext-pdo": "*", "ext-pdo_sqlite": "*", "ext-spl": "*", - "nikic/php-parser": "^3.1", - "php": "^5.5|^7.0", - "psr/log": "^1.0" + "php": "^7.1.3|^8.0", + "psr/log": "^1.0", + "ramsey/uuid": "^3.9|^4.0", + "symfony/config": "^4.4|^5.0", + "symfony/console": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/event-dispatcher": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/serializer": "^4.4|^5.0", + "symfony/stopwatch": "^4.4|^5.0" }, "require-dev": { - "doctrine/cache": "^1.3", - "monolog/monolog": "^1.10" - }, - "suggest": { - "bartlett/monolog-callbackfilterhandler": "Advanced filtering strategies for Monolog", - "bartlett/monolog-growlhandler": "Sends notifications to Growl for Monolog", - "bartlett/phpunit-loggertestlistener": "Allow logging unit tests to your favorite PSR-3 logger interface", - "bartlett/umlwriter": "Allow writing UML class diagrams (Graphviz or PlantUML)", - "doctrine/cache": "Allow caching results, since bartlett/php-reflect 2.2", - "monolog/monolog": "Allow logging events with the LogPlugin" + "humbug/box": "^3.7" }, "bin": [ "bin/phpcompatinfo" @@ -122,24 +126,29 @@ "compatibility", "version" ], - "time": "2019-06-01T08:19:06+00:00" + "support": { + "issues": "https://github.com/llaville/php-compat-info/issues", + "source": "https://github.com/llaville/php-compat-info" + }, + "time": "2020-11-20T12:00:53+00:00" }, { "name": "bartlett/php-compatinfo-db", - "version": "2.12.0", + "version": "2.19.0", "source": { "type": "git", "url": "https://github.com/llaville/php-compatinfo-db.git", - "reference": "9ee4ff81bd2093741e056d25e4b7735113439fcc" + "reference": "4bc78f3103014c65f598162055838a1abee939fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/llaville/php-compatinfo-db/zipball/9ee4ff81bd2093741e056d25e4b7735113439fcc", - "reference": "9ee4ff81bd2093741e056d25e4b7735113439fcc", + "url": "https://api.github.com/repos/llaville/php-compatinfo-db/zipball/4bc78f3103014c65f598162055838a1abee939fe", + "reference": "4bc78f3103014c65f598162055838a1abee939fe", "shasum": "" }, "require": { - "composer/semver": "^1.0", + "composer/package-versions-deprecated": "^1.8", + "composer/semver": "^1.0|^2.0|^3.0", "ext-curl": "*", "ext-intl": "*", "ext-json": "*", @@ -148,23 +157,13 @@ "ext-pcre": "*", "ext-pdo_sqlite": "*", "ext-spl": "*", - "jean85/pretty-package-versions": "^1.2", "laminas/laminas-diagnostics": "^1.3", "league/tactician": "^1.0", - "php": "^7.1", - "symfony/console": "^3.0||^4.0" + "php": "^7.1|^8.0", + "symfony/console": "^4.4|^5.0" }, "require-dev": { - "bartlett/phpunit-loggertestlistener": "^2.0", - "monolog/monolog": "^1.10", - "phpunit/php-timer": "^2.0", - "psr/log": "^1.0" - }, - "suggest": { - "bartlett/phpunit-loggertestlistener": "Allow logging unit tests to your favorite PSR-3 logger interface", - "monolog/monolog": "Allow logging events with the LogPlugin", - "psr/log": "Allow logging events with the LogPlugin", - "symfony/console": "Allow to rebuild the Reference CompatInfo Database" + "phpunit/php-timer": "^2.0" }, "type": "library", "autoload": { @@ -196,20 +195,24 @@ "compatibility", "database" ], - "time": "2020-03-21T07:51:18+00:00" + "support": { + "issues": "https://github.com/llaville/php-compatinfo-db/issues", + "source": "https://github.com/llaville/php-compatinfo-db" + }, + "time": "2020-10-03T15:02:17+00:00" }, { "name": "bartlett/php-reflect", - "version": "4.3.1", + "version": "4.4.1", "source": { "type": "git", "url": "https://github.com/llaville/php-reflect.git", - "reference": "5010b4de0540a711f329a26c72bd48280a3d755a" + "reference": "2e890a43cab0a2c92806d1eaf45fa1b4edd3b887" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/llaville/php-reflect/zipball/5010b4de0540a711f329a26c72bd48280a3d755a", - "reference": "5010b4de0540a711f329a26c72bd48280a3d755a", + "url": "https://api.github.com/repos/llaville/php-reflect/zipball/2e890a43cab0a2c92806d1eaf45fa1b4edd3b887", + "reference": "2e890a43cab0a2c92806d1eaf45fa1b4edd3b887", "shasum": "" }, "require": { @@ -221,18 +224,19 @@ "ext-reflection": "*", "ext-spl": "*", "ext-tokenizer": "*", - "justinrainbow/json-schema": "^1.3", - "nikic/php-parser": "^3.1", - "php": "^5.5|^7.0", - "phpdocumentor/reflection-docblock": "^3.0", + "justinrainbow/json-schema": "^5.2", + "nikic/php-parser": "^4.5", + "php": "^7.1.3|^8.0", + "phpdocumentor/reflection-docblock": "^4.3|^5.2", + "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", "psr/log": "^1.0", - "sebastian/version": "^1.0|^2.0", - "seld/jsonlint": "^1.1", - "symfony/console": "^2.5|^3.0|^4.0", - "symfony/dependency-injection": "^2.5|^3.0|^4.0", - "symfony/event-dispatcher": "^2.5|^3.0|^4.0", - "symfony/finder": "^2.5|^3.0|^4.0", - "symfony/stopwatch": "^2.5|^3.0|^4.0" + "sebastian/version": "^2.0", + "seld/jsonlint": "^1.4", + "symfony/console": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/event-dispatcher": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/stopwatch": "^4.4|^5.0" }, "require-dev": { "monolog/monolog": "^1.10" @@ -271,7 +275,11 @@ "reflection", "reverse-engineer" ], - "time": "2020-02-26T10:11:10+00:00" + "support": { + "issues": "https://github.com/llaville/php-reflect/issues", + "source": "https://github.com/llaville/php-reflect" + }, + "time": "2020-10-06T15:55:25+00:00" }, { "name": "brain/monkey", @@ -345,16 +353,16 @@ }, { "name": "composer/package-versions-deprecated", - "version": "1.11.99", + "version": "1.11.99.1", "source": { "type": "git", "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "c8c9aa8a14cc3d3bec86d0a8c3fa52ea79936855" + "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/c8c9aa8a14cc3d3bec86d0a8c3fa52ea79936855", - "reference": "c8c9aa8a14cc3d3bec86d0a8c3fa52ea79936855", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/7413f0b55a051e89485c5cb9f765fe24bb02a7b6", + "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6", "shasum": "" }, "require": { @@ -396,6 +404,10 @@ } ], "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "support": { + "issues": "https://github.com/composer/package-versions-deprecated/issues", + "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.1" + }, "funding": [ { "url": "https://packagist.com", @@ -410,32 +422,33 @@ "type": "tidelift" } ], - "time": "2020-08-25T05:50:16+00:00" + "time": "2020-11-11T10:22:58+00:00" }, { "name": "composer/semver", - "version": "1.7.1", + "version": "3.2.4", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "38276325bd896f90dfcfe30029aa5db40df387a7" + "reference": "a02fdf930a3c1c3ed3a49b5f63859c0c20e10464" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/38276325bd896f90dfcfe30029aa5db40df387a7", - "reference": "38276325bd896f90dfcfe30029aa5db40df387a7", + "url": "https://api.github.com/repos/composer/semver/zipball/a02fdf930a3c1c3ed3a49b5f63859c0c20e10464", + "reference": "a02fdf930a3c1c3ed3a49b5f63859c0c20e10464", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0" + "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^4.5 || ^5.0.5" + "phpstan/phpstan": "^0.12.54", + "symfony/phpunit-bridge": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-main": "3.x-dev" } }, "autoload": { @@ -471,6 +484,11 @@ "validation", "versioning" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.2.4" + }, "funding": [ { "url": "https://packagist.com", @@ -485,20 +503,20 @@ "type": "tidelift" } ], - "time": "2020-09-27T13:13:07+00:00" + "time": "2020-11-13T08:59:24+00:00" }, { "name": "composer/xdebug-handler", - "version": "1.4.4", + "version": "1.4.5", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "6e076a124f7ee146f2487554a94b6a19a74887ba" + "reference": "f28d44c286812c714741478d968104c5e604a1d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6e076a124f7ee146f2487554a94b6a19a74887ba", - "reference": "6e076a124f7ee146f2487554a94b6a19a74887ba", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f28d44c286812c714741478d968104c5e604a1d4", + "reference": "f28d44c286812c714741478d968104c5e604a1d4", "shasum": "" }, "require": { @@ -529,6 +547,11 @@ "Xdebug", "performance" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/1.4.5" + }, "funding": [ { "url": "https://packagist.com", @@ -543,7 +566,7 @@ "type": "tidelift" } ], - "time": "2020-10-24T12:39:10+00:00" + "time": "2020-11-13T08:04:11+00:00" }, { "name": "doctrine/annotations", @@ -614,38 +637,39 @@ "docblock", "parser" ], + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/1.11.1" + }, "time": "2020-10-26T10:28:16+00:00" }, { "name": "doctrine/collections", - "version": "v1.5.0", + "version": "1.6.7", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "a01ee38fcd999f34d9bfbcee59dbda5105449cbf" + "reference": "55f8b799269a1a472457bd1a41b4f379d4cfba4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/a01ee38fcd999f34d9bfbcee59dbda5105449cbf", - "reference": "a01ee38fcd999f34d9bfbcee59dbda5105449cbf", + "url": "https://api.github.com/repos/doctrine/collections/zipball/55f8b799269a1a472457bd1a41b4f379d4cfba4a", + "reference": "55f8b799269a1a472457bd1a41b4f379d4cfba4a", "shasum": "" }, "require": { - "php": "^7.1" + "php": "^7.1.3 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "~0.1@dev", - "phpunit/phpunit": "^5.7" + "doctrine/coding-standard": "^6.0", + "phpstan/phpstan-shim": "^0.9.2", + "phpunit/phpunit": "^7.0", + "vimeo/psalm": "^3.8.1" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, "autoload": { - "psr-0": { - "Doctrine\\Common\\Collections\\": "lib/" + "psr-4": { + "Doctrine\\Common\\Collections\\": "lib/Doctrine/Common/Collections" } }, "notification-url": "https://packagist.org/downloads/", @@ -653,6 +677,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -661,10 +689,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -674,47 +698,47 @@ "email": "schmittjoh@gmail.com" } ], - "description": "Collections Abstraction library", - "homepage": "http://www.doctrine-project.org", + "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.", + "homepage": "https://www.doctrine-project.org/projects/collections.html", "keywords": [ "array", "collections", - "iterator" + "iterators", + "php" ], - "time": "2017-07-22T10:37:32+00:00" + "support": { + "issues": "https://github.com/doctrine/collections/issues", + "source": "https://github.com/doctrine/collections/tree/1.6.7" + }, + "time": "2020-07-27T17:53:49+00:00" }, { "name": "doctrine/instantiator", - "version": "1.3.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea" + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^6.0", + "doctrine/coding-standard": "^8.0", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" + "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" @@ -728,7 +752,7 @@ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "homepage": "https://ocramius.github.io/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", @@ -737,6 +761,10 @@ "constructor", "instantiate" ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -751,7 +779,7 @@ "type": "tidelift" } ], - "time": "2020-05-29T17:27:14+00:00" + "time": "2020-11-10T18:47:58+00:00" }, { "name": "doctrine/lexer", @@ -811,20 +839,24 @@ "parser", "php" ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/1.0.2" + }, "time": "2019-06-08T11:03:04+00:00" }, { "name": "friendsofphp/php-cs-fixer", - "version": "v2.16.7", + "version": "v2.18.2", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "4e35806a6d7d8510d6842ae932e8832363d22c87" + "reference": "18f8c9d184ba777380794a389fabc179896ba913" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/4e35806a6d7d8510d6842ae932e8832363d22c87", - "reference": "4e35806a6d7d8510d6842ae932e8832363d22c87", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/18f8c9d184ba777380794a389fabc179896ba913", + "reference": "18f8c9d184ba777380794a389fabc179896ba913", "shasum": "" }, "require": { @@ -833,7 +865,7 @@ "doctrine/annotations": "^1.2", "ext-json": "*", "ext-tokenizer": "*", - "php": "^7.1", + "php": "^5.6 || ^7.0 || ^8.0", "php-cs-fixer/diff": "^1.3", "symfony/console": "^3.4.43 || ^4.1.6 || ^5.0", "symfony/event-dispatcher": "^3.0 || ^4.0 || ^5.0", @@ -846,17 +878,19 @@ "symfony/stopwatch": "^3.0 || ^4.0 || ^5.0" }, "require-dev": { - "johnkary/phpunit-speedtrap": "^1.1 || ^2.0 || ^3.0", "justinrainbow/json-schema": "^5.0", "keradus/cli-executor": "^1.4", "mikey179/vfsstream": "^1.6", - "php-coveralls/php-coveralls": "^2.4.1", + "php-coveralls/php-coveralls": "^2.4.2", "php-cs-fixer/accessible-object": "^1.0", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.1", + "phpspec/prophecy-phpunit": "^1.1 || ^2.0", + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.13 || ^9.5", + "phpunitgoodpractices/polyfill": "^1.5", "phpunitgoodpractices/traits": "^1.9.1", - "symfony/phpunit-bridge": "^5.1", + "sanmai/phpunit-legacy-adapter": "^6.4 || ^8.2.1", + "symfony/phpunit-bridge": "^5.2.1", "symfony/yaml": "^3.0 || ^4.0 || ^5.0" }, "suggest": { @@ -902,13 +936,17 @@ } ], "description": "A tool to automatically fix PHP code style", + "support": { + "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", + "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v2.18.2" + }, "funding": [ { "url": "https://github.com/keradus", "type": "github" } ], - "time": "2020-10-27T22:44:27+00:00" + "time": "2021-01-26T00:22:21+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -955,80 +993,33 @@ "keywords": [ "test" ], - "time": "2020-07-09T08:09:16+00:00" - }, - { - "name": "jean85/pretty-package-versions", - "version": "1.5.1", - "source": { - "type": "git", - "url": "https://github.com/Jean85/pretty-package-versions.git", - "reference": "a917488320c20057da87f67d0d40543dd9427f7a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/a917488320c20057da87f67d0d40543dd9427f7a", - "reference": "a917488320c20057da87f67d0d40543dd9427f7a", - "shasum": "" - }, - "require": { - "composer/package-versions-deprecated": "^1.8.0", - "php": "^7.0|^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0|^8.5|^9.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Jean85\\": "src/" - } + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alessandro Lai", - "email": "alessandro.lai85@gmail.com" - } - ], - "description": "A wrapper for ocramius/package-versions to get pretty versions strings", - "keywords": [ - "composer", - "package", - "release", - "versions" - ], - "time": "2020-09-14T08:43:34+00:00" + "time": "2020-07-09T08:09:16+00:00" }, { "name": "justinrainbow/json-schema", - "version": "1.6.1", + "version": "5.2.10", "source": { "type": "git", "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "cc84765fb7317f6b07bd8ac78364747f95b86341" + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/cc84765fb7317f6b07bd8ac78364747f95b86341", - "reference": "cc84765fb7317f6b07bd8ac78364747f95b86341", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", "shasum": "" }, "require": { - "php": ">=5.3.29" + "php": ">=5.3.3" }, "require-dev": { - "json-schema/json-schema-test-suite": "1.1.0", - "phpdocumentor/phpdocumentor": "~2", - "phpunit/phpunit": "~3.7" + "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.35" }, "bin": [ "bin/validate-json" @@ -1036,7 +1027,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6.x-dev" + "dev-master": "5.0.x-dev" } }, "autoload": { @@ -1046,7 +1037,7 @@ }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { @@ -1072,7 +1063,11 @@ "json", "schema" ], - "time": "2016-01-25T15:43:01+00:00" + "support": { + "issues": "https://github.com/justinrainbow/json-schema/issues", + "source": "https://github.com/justinrainbow/json-schema/tree/5.2.10" + }, + "time": "2020-05-27T16:41:55+00:00" }, { "name": "laminas/laminas-diagnostics", @@ -1146,6 +1141,14 @@ "php", "test" ], + "support": { + "chat": "https://laminas.dev/chat", + "docs": "https://docs.laminas.dev/laminas-diagnostics/", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-diagnostics/issues", + "rss": "https://github.com/laminas/laminas-diagnostics/releases.atom", + "source": "https://github.com/laminas/laminas-diagnostics" + }, "time": "2019-12-31T16:42:23+00:00" }, { @@ -1194,6 +1197,12 @@ "laminas", "zf" ], + "support": { + "forum": "https://discourse.laminas.dev/", + "issues": "https://github.com/laminas/laminas-zendframework-bridge/issues", + "rss": "https://github.com/laminas/laminas-zendframework-bridge/releases.atom", + "source": "https://github.com/laminas/laminas-zendframework-bridge" + }, "funding": [ { "url": "https://funding.communitybridge.org/projects/laminas-project", @@ -1251,6 +1260,10 @@ "command bus", "service layer" ], + "support": { + "issues": "https://github.com/thephpleague/tactician/issues", + "source": "https://github.com/thephpleague/tactician/tree/master" + }, "time": "2017-11-30T09:17:20+00:00" }, { @@ -1316,20 +1329,24 @@ "test double", "testing" ], + "support": { + "issues": "https://github.com/mockery/mockery/issues", + "source": "https://github.com/mockery/mockery/tree/1.3.3" + }, "time": "2020-08-11T18:10:21+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.10.1", + "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", "shasum": "" }, "require": { @@ -1364,34 +1381,39 @@ "object", "object graph" ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + }, "funding": [ { "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", "type": "tidelift" } ], - "time": "2020-06-29T13:22:24+00:00" + "time": "2020-11-13T09:40:50+00:00" }, { "name": "nikic/php-parser", - "version": "v3.1.5", + "version": "v4.10.4", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce" + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bb87e28e7d7b8d9a7fda231d37457c9210faf6ce", - "reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=5.5" + "php": ">=7.0" }, "require-dev": { - "phpunit/phpunit": "~4.0|~5.0" + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/php-parse" @@ -1399,7 +1421,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "4.9-dev" } }, "autoload": { @@ -1421,7 +1443,61 @@ "parser", "php" ], - "time": "2018-02-28T20:30:58+00:00" + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.4" + }, + "time": "2020-12-20T10:01:03+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.99", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "shasum": "" + }, + "require": { + "php": "^7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2018-07-02T15:55:56+00:00" }, { "name": "pdepend/pdepend", @@ -1468,6 +1544,10 @@ "BSD-3-Clause" ], "description": "Official version of pdepend to be handled with Composer", + "support": { + "issues": "https://github.com/pdepend/pdepend/issues", + "source": "https://github.com/pdepend/pdepend/tree/master" + }, "funding": [ { "url": "https://tidelift.com/funding/github/packagist/pdepend/pdepend", @@ -1529,6 +1609,10 @@ } ], "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/master" + }, "time": "2018-07-08T19:23:20+00:00" }, { @@ -1576,6 +1660,10 @@ } ], "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/master" + }, "time": "2018-07-08T19:19:57+00:00" }, { @@ -1627,6 +1715,10 @@ "keywords": [ "diff" ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/diff/issues", + "source": "https://github.com/PHP-CS-Fixer/diff/tree/v1.3.1" + }, "time": "2020-10-14T08:39:05+00:00" }, { @@ -1672,6 +1764,10 @@ } ], "description": "Constraint for testing strings considering not-same line endings.", + "support": { + "issues": "https://github.com/PHP-CS-Fixer/phpunit-constraint-isidenticalstring/issues", + "source": "https://github.com/PHP-CS-Fixer/phpunit-constraint-isidenticalstring/tree/v1.2.0" + }, "time": "2020-10-20T01:38:06+00:00" }, { @@ -1722,39 +1818,38 @@ } ], "description": "Constraint for testing XML against XSD.", + "support": { + "issues": "https://github.com/PHP-CS-Fixer/phpunit-constraint-xmlmatchesxsd/issues", + "source": "https://github.com/PHP-CS-Fixer/phpunit-constraint-xmlmatchesxsd/tree/v1.2.1" + }, "time": "2020-10-19T23:46:42+00:00" }, { "name": "phpdocumentor/reflection-common", - "version": "1.0.1", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/6568f4687e5b41b054365f9ae03fcb1ed5f2069b", + "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b", "shasum": "" }, "require": { - "php": ">=5.5" - }, - "require-dev": { - "phpunit/phpunit": "^4.6" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] + "phpDocumentor\\Reflection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1776,33 +1871,44 @@ "reflection", "static analysis" ], - "time": "2017-09-11T18:02:19+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/master" + }, + "time": "2020-04-27T09:25:28+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "3.3.2", + "version": "4.3.4", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2" + "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2", - "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/da3fd972d6bafd628114f7e7e036f45944b62e9c", + "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", + "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", "webmozart/assert": "^1.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^4.4" + "doctrine/instantiator": "^1.0.5", + "mockery/mockery": "^1.0", + "phpdocumentor/type-resolver": "0.4.*", + "phpunit/phpunit": "^6.4" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": [ @@ -1821,41 +1927,44 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-10T14:09:06+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/4.x" + }, + "time": "2019-12-28T18:55:12+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "0.4.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" + "php": "^7.1", + "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" + "ext-tokenizer": "^7.1", + "mockery/mockery": "~1", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1868,28 +1977,37 @@ "email": "me@mikevanriel.com" } ], - "time": "2017-07-14T14:27:02+00:00" + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/0.7.2" + }, + "time": "2019-08-22T18:11:29+00:00" }, { "name": "phpmd/phpmd", - "version": "2.7.0", + "version": "2.9.1", "source": { "type": "git", "url": "https://github.com/phpmd/phpmd.git", - "reference": "a05a999c644f4bc9a204846017db7bb7809fbe4c" + "reference": "ce10831d4ddc2686c1348a98069771dd314534a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpmd/phpmd/zipball/a05a999c644f4bc9a204846017db7bb7809fbe4c", - "reference": "a05a999c644f4bc9a204846017db7bb7809fbe4c", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/ce10831d4ddc2686c1348a98069771dd314534a8", + "reference": "ce10831d4ddc2686c1348a98069771dd314534a8", "shasum": "" }, "require": { + "composer/xdebug-handler": "^1.0", "ext-xml": "*", - "pdepend/pdepend": "^2.5", + "pdepend/pdepend": "^2.7.1", "php": ">=5.3.9" }, "require-dev": { + "easy-doc/easy-doc": "0.0.0 || ^1.3.2", + "ext-json": "*", + "ext-simplexml": "*", "gregwar/rst": "^1.0", "mikey179/vfsstream": "^1.6.4", "phpunit/phpunit": "^4.8.36 || ^5.7.27", @@ -1936,7 +2054,18 @@ "phpmd", "pmd" ], - "time": "2019-07-30T21:13:32+00:00" + "support": { + "irc": "irc://irc.freenode.org/phpmd", + "issues": "https://github.com/phpmd/phpmd/issues", + "source": "https://github.com/phpmd/phpmd/tree/2.9.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/phpmd/phpmd", + "type": "tidelift" + } + ], + "time": "2020-09-23T22:06:32+00:00" }, { "name": "phpspec/prophecy", @@ -1999,6 +2128,10 @@ "spy", "stub" ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.10.3" + }, "time": "2020-03-05T15:02:03+00:00" }, { @@ -2062,27 +2195,31 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/master" + }, "time": "2018-10-31T16:06:48+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "050bedf145a257b1ff02746c31894800e5122946" + "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", - "reference": "050bedf145a257b1ff02746c31894800e5122946", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4b49fb70f067272b659ef0174ff9ca40fdaa6357", + "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^7.1" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -2112,7 +2249,17 @@ "filesystem", "iterator" ], - "time": "2018-09-13T20:33:42+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:25:21+00:00" }, { "name": "phpunit/php-text-template", @@ -2153,27 +2300,31 @@ "keywords": [ "template" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" + }, "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", - "version": "2.1.2", + "version": "2.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" + "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", - "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", + "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -2202,25 +2353,35 @@ "keywords": [ "timer" ], - "time": "2019-06-07T04:22:29+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:20:02+00:00" }, { "name": "phpunit/php-token-stream", - "version": "3.1.1", + "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff" + "reference": "472b687829041c24b25f475e14c2f38a09edf1c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff", - "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/472b687829041c24b25f475e14c2f38a09edf1c2", + "reference": "472b687829041c24b25f475e14c2f38a09edf1c2", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "^7.0" @@ -2251,8 +2412,18 @@ "keywords": [ "tokenizer" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", + "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "abandoned": true, - "time": "2019-09-17T06:23:10+00:00" + "time": "2020-11-30T08:38:46+00:00" }, { "name": "phpunit/phpunit", @@ -2336,31 +2507,33 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/7.5.20" + }, "time": "2020-01-08T08:45:45+00:00" }, { "name": "phpunitgoodpractices/polyfill", - "version": "v1.4.0", + "version": "v1.5.0", "source": { "type": "git", "url": "https://github.com/PHPUnitGoodPractices/polyfill.git", - "reference": "0e3754f1e31b0051eeb5a7223f9b45ba6442af0d" + "reference": "b87c59f0d3df764d0dcf8154e18be69fe6cb5cba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPUnitGoodPractices/polyfill/zipball/0e3754f1e31b0051eeb5a7223f9b45ba6442af0d", - "reference": "0e3754f1e31b0051eeb5a7223f9b45ba6442af0d", + "url": "https://api.github.com/repos/PHPUnitGoodPractices/polyfill/zipball/b87c59f0d3df764d0dcf8154e18be69fe6cb5cba", + "reference": "b87c59f0d3df764d0dcf8154e18be69fe6cb5cba", "shasum": "" }, "require": { "php": "^5.5 || ^7.0 || ^8.0", "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.0 || ^9.0" }, - "conflict": { - "hhvm": "*" - }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.16" + "friendsofphp/php-cs-fixer": "^2", + "php-coveralls/php-coveralls": "^2.4" }, "type": "library", "autoload": { @@ -2382,7 +2555,11 @@ } ], "description": "Lacking future-compat polyfills for PHPUnit.", - "time": "2020-10-19T23:33:46+00:00" + "support": { + "issues": "https://github.com/PHPUnitGoodPractices/polyfill/issues", + "source": "https://github.com/PHPUnitGoodPractices/polyfill/tree/v1.5.0" + }, + "time": "2020-11-22T18:47:33+00:00" }, { "name": "psr/container", @@ -2431,6 +2608,10 @@ "container-interop", "psr" ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/master" + }, "time": "2017-02-14T16:28:37+00:00" }, { @@ -2478,27 +2659,123 @@ "psr", "psr-3" ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.3" + }, "time": "2020-03-23T09:12:05+00:00" }, { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", + "name": "ramsey/uuid", + "version": "3.9.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + "url": "https://github.com/ramsey/uuid.git", + "reference": "7e1633a6964b48589b142d60542f9ed31bd37a92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/7e1633a6964b48589b142d60542f9ed31bd37a92", + "reference": "7e1633a6964b48589b142d60542f9ed31bd37a92", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "ext-json": "*", + "paragonie/random_compat": "^1 | ^2 | 9.99.99", + "php": "^5.4 | ^7 | ^8", + "symfony/polyfill-ctype": "^1.8" }, - "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "codeception/aspect-mock": "^1 | ^2", + "doctrine/annotations": "^1.2", + "goaop/framework": "1.0.0-alpha.2 | ^1 | ^2.1", + "jakub-onderka/php-parallel-lint": "^1", + "mockery/mockery": "^0.9.11 | ^1", + "moontoast/math": "^1.1", + "paragonie/random-lib": "^2", + "php-mock/php-mock-phpunit": "^0.3 | ^1.1", + "phpunit/phpunit": "^4.8 | ^5.4 | ^6.5", + "squizlabs/php_codesniffer": "^3.5" + }, + "suggest": { + "ext-ctype": "Provides support for PHP Ctype functions", + "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator", + "ext-openssl": "Provides the OpenSSL extension for use with the OpenSslGenerator", + "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator", + "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-console": "A console application for generating UUIDs with ramsey/uuid", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Uuid\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + }, + { + "name": "Marijn Huizendveld", + "email": "marijn.huizendveld@gmail.com" + }, + { + "name": "Thibaud Fabre", + "email": "thibaud@aztech.io" + } + ], + "description": "Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", + "homepage": "https://github.com/ramsey/uuid", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "rss": "https://github.com/ramsey/uuid/releases.atom", + "source": "https://github.com/ramsey/uuid", + "wiki": "https://github.com/ramsey/uuid/wiki" + }, + "time": "2020-02-21T04:36:14+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -2523,7 +2800,17 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:15:22+00:00" }, { "name": "sebastian/comparator", @@ -2601,20 +2888,20 @@ }, { "name": "sebastian/diff", - "version": "3.0.2", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" + "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", - "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211", + "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "^7.5 || ^8.0", @@ -2636,13 +2923,13 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" } ], "description": "Diff implementation", @@ -2653,24 +2940,34 @@ "unidiff", "unified diff" ], - "time": "2019-02-04T06:01:07+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:59:04+00:00" }, { "name": "sebastian/environment", - "version": "4.2.3", + "version": "4.2.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368" + "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368", - "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", + "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "^7.5" @@ -2706,24 +3003,34 @@ "environment", "hhvm" ], - "time": "2019-11-20T08:46:58+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:53:42+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.2", + "version": "3.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" + "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e", + "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e", "shasum": "" }, "require": { - "php": "^7.0", + "php": ">=7.0", "sebastian/recursion-context": "^3.0" }, "require-dev": { @@ -2773,7 +3080,17 @@ "export", "exporter" ], - "time": "2019-09-14T09:02:43+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:47:53+00:00" }, { "name": "sebastian/global-state", @@ -2824,24 +3141,28 @@ "keywords": [ "global state" ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0" + }, "time": "2017-04-27T15:39:26+00:00" }, { "name": "sebastian/object-enumerator", - "version": "3.0.3", + "version": "3.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", + "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", "shasum": "" }, "require": { - "php": "^7.0", + "php": ">=7.0", "sebastian/object-reflector": "^1.1.1", "sebastian/recursion-context": "^3.0" }, @@ -2871,24 +3192,34 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:40:27+00:00" }, { "name": "sebastian/object-reflector", - "version": "1.1.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" + "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", + "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" @@ -2916,24 +3247,34 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:37:18+00:00" }, { "name": "sebastian/recursion-context", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", + "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" @@ -2954,14 +3295,14 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, { "name": "Adam Harvey", "email": "aharvey@php.net" @@ -2969,24 +3310,34 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:34:24+00:00" }, { "name": "sebastian/resource-operations", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" + "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", + "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "type": "library", "extra": { @@ -3011,7 +3362,17 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2018-10-04T04:07:39+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:30:19+00:00" }, { "name": "sebastian/version", @@ -3054,20 +3415,24 @@ ], "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/master" + }, "time": "2016-10-03T07:35:21+00:00" }, { "name": "seld/jsonlint", - "version": "1.8.2", + "version": "1.8.3", "source": { "type": "git", "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "590cfec960b77fd55e39b7d9246659e95dd6d337" + "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/590cfec960b77fd55e39b7d9246659e95dd6d337", - "reference": "590cfec960b77fd55e39b7d9246659e95dd6d337", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/9ad6ce79c342fbd44df10ea95511a1b24dee5b57", + "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57", "shasum": "" }, "require": { @@ -3103,6 +3468,10 @@ "parser", "validator" ], + "support": { + "issues": "https://github.com/Seldaek/jsonlint/issues", + "source": "https://github.com/Seldaek/jsonlint/tree/1.8.3" + }, "funding": [ { "url": "https://github.com/Seldaek", @@ -3113,20 +3482,20 @@ "type": "tidelift" } ], - "time": "2020-08-25T06:56:57+00:00" + "time": "2020-11-11T09:19:24+00:00" }, { "name": "squizlabs/php_codesniffer", - "version": "3.4.2", + "version": "3.5.8", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8" + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", - "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/9d583721a7157ee997f235f327de038e7ea6dac4", + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4", "shasum": "" }, "require": { @@ -3164,36 +3533,41 @@ "phpcs", "standards" ], - "time": "2019-04-10T23:49:02+00:00" + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2020-10-23T02:01:07+00:00" }, { "name": "symfony/config", - "version": "v3.4.46", + "version": "v4.4.19", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "bc6b3fd3930d4b53a60b42fe2ed6fc466b75f03f" + "reference": "2c4c7827a7e143f5cf375666641b0f448eab8802" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/bc6b3fd3930d4b53a60b42fe2ed6fc466b75f03f", - "reference": "bc6b3fd3930d4b53a60b42fe2ed6fc466b75f03f", + "url": "https://api.github.com/repos/symfony/config/zipball/2c4c7827a7e143f5cf375666641b0f448eab8802", + "reference": "2c4c7827a7e143f5cf375666641b0f448eab8802", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/filesystem": "~2.8|~3.0|~4.0", + "php": ">=7.1.3", + "symfony/filesystem": "^3.4|^4.0|^5.0", "symfony/polyfill-ctype": "~1.8" }, "conflict": { - "symfony/dependency-injection": "<3.3", - "symfony/finder": "<3.3" + "symfony/finder": "<3.4" }, "require-dev": { - "symfony/dependency-injection": "~3.3|~4.0", - "symfony/event-dispatcher": "~3.3|~4.0", - "symfony/finder": "~3.3|~4.0", - "symfony/yaml": "~3.0|~4.0" + "symfony/event-dispatcher": "^3.4|^4.0|^5.0", + "symfony/finder": "^3.4|^4.0|^5.0", + "symfony/messenger": "^4.1|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/yaml": "To use the yaml reference dumper" @@ -3221,8 +3595,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Config Component", + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v4.4.19" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3237,29 +3614,33 @@ "type": "tidelift" } ], - "time": "2020-10-24T10:57:07+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { "name": "symfony/console", - "version": "v3.4.46", + "version": "v4.4.19", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "a10b1da6fc93080c180bba7219b5ff5b7518fe81" + "reference": "24026c44fc37099fa145707fecd43672831b837a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a10b1da6fc93080c180bba7219b5ff5b7518fe81", - "reference": "a10b1da6fc93080c180bba7219b5ff5b7518fe81", + "url": "https://api.github.com/repos/symfony/console/zipball/24026c44fc37099fa145707fecd43672831b837a", + "reference": "24026c44fc37099fa145707fecd43672831b837a", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/debug": "~2.8|~3.0|~4.0", - "symfony/polyfill-mbstring": "~1.0" + "php": ">=7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.8", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1|^2" }, "conflict": { "symfony/dependency-injection": "<3.4", + "symfony/event-dispatcher": "<4.3|>=5", + "symfony/lock": "<4.4", "symfony/process": "<3.3" }, "provide": { @@ -3267,11 +3648,12 @@ }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~3.3|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/event-dispatcher": "~2.8|~3.0|~4.0", - "symfony/lock": "~3.4|~4.0", - "symfony/process": "~3.3|~4.0" + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/event-dispatcher": "^4.3", + "symfony/lock": "^4.4|^5.0", + "symfony/process": "^3.4|^4.0|^5.0", + "symfony/var-dumper": "^4.3|^5.0" }, "suggest": { "psr/log": "For using the console logger", @@ -3302,8 +3684,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Console Component", + "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/console/tree/v4.4.19" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3318,36 +3703,53 @@ "type": "tidelift" } ], - "time": "2020-10-24T10:57:07+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { - "name": "symfony/debug", - "version": "v3.4.46", + "name": "symfony/dependency-injection", + "version": "v4.4.19", "source": { "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "ab42889de57fdfcfcc0759ab102e2fd4ea72dcae" + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "2468b95d869c872c6fb1b93b395a7fcd5331f2b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/ab42889de57fdfcfcc0759ab102e2fd4ea72dcae", - "reference": "ab42889de57fdfcfcc0759ab102e2fd4ea72dcae", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2468b95d869c872c6fb1b93b395a7fcd5331f2b9", + "reference": "2468b95d869c872c6fb1b93b395a7fcd5331f2b9", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", - "psr/log": "~1.0" + "php": ">=7.1.3", + "psr/container": "^1.0", + "symfony/service-contracts": "^1.1.6|^2" }, "conflict": { - "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + "symfony/config": "<4.3|>=5.0", + "symfony/finder": "<3.4", + "symfony/proxy-manager-bridge": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "psr/container-implementation": "1.0", + "symfony/service-implementation": "1.0" }, "require-dev": { - "symfony/http-kernel": "~2.8|~3.0|~4.0" + "symfony/config": "^4.3", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Debug\\": "" + "Symfony\\Component\\DependencyInjection\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -3367,8 +3769,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Debug Component", + "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v4.4.19" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3383,51 +3788,51 @@ "type": "tidelift" } ], - "time": "2020-10-24T10:57:07+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { - "name": "symfony/dependency-injection", - "version": "v3.4.46", + "name": "symfony/event-dispatcher", + "version": "v4.4.19", "source": { "type": "git", - "url": "https://github.com/symfony/dependency-injection.git", - "reference": "51d2a2708c6ceadad84393f8581df1dcf9e5e84b" + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "c352647244bd376bf7d31efbd5401f13f50dad0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/51d2a2708c6ceadad84393f8581df1dcf9e5e84b", - "reference": "51d2a2708c6ceadad84393f8581df1dcf9e5e84b", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c352647244bd376bf7d31efbd5401f13f50dad0c", + "reference": "c352647244bd376bf7d31efbd5401f13f50dad0c", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", - "psr/container": "^1.0" + "php": ">=7.1.3", + "symfony/event-dispatcher-contracts": "^1.1" }, "conflict": { - "symfony/config": "<3.3.7", - "symfony/finder": "<3.3", - "symfony/proxy-manager-bridge": "<3.4", - "symfony/yaml": "<3.4" + "symfony/dependency-injection": "<3.4" }, "provide": { - "psr/container-implementation": "1.0" + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "1.1" }, "require-dev": { - "symfony/config": "~3.3|~4.0", - "symfony/expression-language": "~2.8|~3.0|~4.0", - "symfony/yaml": "~3.4|~4.0" + "psr/log": "~1.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/error-handler": "~3.4|~4.4", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/stopwatch": "^3.4|^4.0|^5.0" }, "suggest": { - "symfony/config": "", - "symfony/expression-language": "For using expressions in service container configuration", - "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", - "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", - "symfony/yaml": "" + "symfony/dependency-injection": "", + "symfony/http-kernel": "" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\DependencyInjection\\": "" + "Symfony\\Component\\EventDispatcher\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -3447,8 +3852,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony DependencyInjection Component", + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v4.4.19" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3463,48 +3871,43 @@ "type": "tidelift" } ], - "time": "2020-10-24T10:57:07+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { - "name": "symfony/event-dispatcher", - "version": "v3.4.46", + "name": "symfony/event-dispatcher-contracts", + "version": "v1.1.9", "source": { "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "31fde73757b6bad247c54597beef974919ec6860" + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/31fde73757b6bad247c54597beef974919ec6860", - "reference": "31fde73757b6bad247c54597beef974919ec6860", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/84e23fdcd2517bf37aecbd16967e83f0caee25a7", + "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" - }, - "conflict": { - "symfony/dependency-injection": "<3.3" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~2.8|~3.0|~4.0", - "symfony/debug": "~3.4|~4.4", - "symfony/dependency-injection": "~3.3|~4.0", - "symfony/expression-language": "~2.8|~3.0|~4.0", - "symfony/stopwatch": "~2.8|~3.0|~4.0" + "php": ">=7.1.3" }, "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" + "psr/event-dispatcher": "", + "symfony/event-dispatcher-implementation": "" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, "autoload": { "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Symfony\\Contracts\\EventDispatcher\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3512,16 +3915,27 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony EventDispatcher Component", + "description": "Generic abstractions related to dispatching event", "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v1.1.9" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3536,24 +3950,24 @@ "type": "tidelift" } ], - "time": "2020-10-24T10:57:07+00:00" + "time": "2020-07-06T13:19:58+00:00" }, { "name": "symfony/filesystem", - "version": "v3.4.46", + "version": "v4.4.19", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "e58d7841cddfed6e846829040dca2cca0ebbbbb3" + "reference": "83a6feed14846d2d9f3916adbaf838819e4e3380" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/e58d7841cddfed6e846829040dca2cca0ebbbbb3", - "reference": "e58d7841cddfed6e846829040dca2cca0ebbbbb3", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/83a6feed14846d2d9f3916adbaf838819e4e3380", + "reference": "83a6feed14846d2d9f3916adbaf838819e4e3380", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", + "php": ">=7.1.3", "symfony/polyfill-ctype": "~1.8" }, "type": "library", @@ -3579,8 +3993,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Filesystem Component", + "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v4.4.19" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3595,24 +4012,24 @@ "type": "tidelift" } ], - "time": "2020-10-24T10:57:07+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { "name": "symfony/finder", - "version": "v3.4.46", + "version": "v4.4.19", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "4e1da3c110c52d868f8a9153b7de3ebc381fba78" + "reference": "25d79cfccfc12e84e7a63a248c3f0720fdd92db6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/4e1da3c110c52d868f8a9153b7de3ebc381fba78", - "reference": "4e1da3c110c52d868f8a9153b7de3ebc381fba78", + "url": "https://api.github.com/repos/symfony/finder/zipball/25d79cfccfc12e84e7a63a248c3f0720fdd92db6", + "reference": "25d79cfccfc12e84e7a63a248c3f0720fdd92db6", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": ">=7.1.3" }, "type": "library", "autoload": { @@ -3637,8 +4054,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Finder Component", + "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v4.4.19" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3653,24 +4073,24 @@ "type": "tidelift" } ], - "time": "2020-10-24T10:57:07+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { "name": "symfony/options-resolver", - "version": "v3.4.46", + "version": "v4.4.19", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "c7efc97a47b2ebaabc19d5b6c6b50f5c37c92744" + "reference": "cd8c6a2778d5f8b5e8fc4b7abdf126790b5d5095" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/c7efc97a47b2ebaabc19d5b6c6b50f5c37c92744", - "reference": "c7efc97a47b2ebaabc19d5b6c6b50f5c37c92744", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/cd8c6a2778d5f8b5e8fc4b7abdf126790b5d5095", + "reference": "cd8c6a2778d5f8b5e8fc4b7abdf126790b5d5095", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": ">=7.1.3" }, "type": "library", "autoload": { @@ -3695,13 +4115,16 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony OptionsResolver Component", + "description": "Provides an improved replacement for the array_replace PHP function", "homepage": "https://symfony.com", "keywords": [ "config", "configuration", "options" ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v4.4.19" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3716,20 +4139,20 @@ "type": "tidelift" } ], - "time": "2020-10-24T10:57:07+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.20.0", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", "shasum": "" }, "require": { @@ -3741,7 +4164,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3778,6 +4201,9 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3792,20 +4218,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.20.0", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" + "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", + "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", "shasum": "" }, "require": { @@ -3817,7 +4243,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3855,6 +4281,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3869,7 +4298,7 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-php70", @@ -3920,6 +4349,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php70/tree/v1.20.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3938,16 +4370,16 @@ }, { "name": "symfony/polyfill-php72", - "version": "v1.20.0", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930" + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cede45fcdfabdd6043b3592e83678e42ec69e930", - "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", "shasum": "" }, "require": { @@ -3956,7 +4388,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3993,6 +4425,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.22.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4007,24 +4442,186 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-07T16:49:33+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.22.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", + "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-07T16:49:33+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.22.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91", + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/process", - "version": "v3.4.46", + "version": "v4.4.19", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "b8648cf1d5af12a44a51d07ef9bf980921f15fca" + "reference": "7e950b6366d4da90292c2e7fa820b3c1842b965a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/b8648cf1d5af12a44a51d07ef9bf980921f15fca", - "reference": "b8648cf1d5af12a44a51d07ef9bf980921f15fca", + "url": "https://api.github.com/repos/symfony/process/zipball/7e950b6366d4da90292c2e7fa820b3c1842b965a", + "reference": "7e950b6366d4da90292c2e7fa820b3c1842b965a", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": ">=7.1.3" }, "type": "library", "autoload": { @@ -4049,8 +4646,106 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Process Component", + "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v4.4.19" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-27T09:09:26+00:00" + }, + { + "name": "symfony/serializer", + "version": "v4.4.19", + "source": { + "type": "git", + "url": "https://github.com/symfony/serializer.git", + "reference": "6b383bc45777d14857b634e9f8fa2b8a2e69b66d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/serializer/zipball/6b383bc45777d14857b634e9f8fa2b8a2e69b66d", + "reference": "6b383bc45777d14857b634e9f8fa2b8a2e69b66d", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<3.0|>=3.2.0,<3.2.2", + "phpdocumentor/type-resolver": "<0.3.0|1.3.*", + "symfony/dependency-injection": "<3.4", + "symfony/property-access": "<3.4", + "symfony/property-info": "<3.4", + "symfony/yaml": "<3.4" + }, + "require-dev": { + "doctrine/annotations": "^1.10.4", + "doctrine/cache": "~1.0", + "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", + "symfony/cache": "^3.4|^4.0|^5.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/error-handler": "^4.4|^5.0", + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/mime": "^4.4|^5.0", + "symfony/property-access": "^3.4.41|^4.4.9|^5.0.9", + "symfony/property-info": "^3.4.13|~4.0|^5.0", + "symfony/validator": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", + "doctrine/cache": "For using the default cached annotation reader and metadata cache.", + "psr/cache-implementation": "For using the metadata cache.", + "symfony/config": "For using the XML mapping loader.", + "symfony/http-foundation": "For using a MIME type guesser within the DataUriNormalizer.", + "symfony/property-access": "For using the ObjectNormalizer.", + "symfony/property-info": "To deserialize relations.", + "symfony/yaml": "For using the default YAML mapping loader." + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Serializer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/serializer/tree/v4.4.19" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4065,24 +4760,104 @@ "type": "tidelift" } ], - "time": "2020-10-24T10:57:07+00:00" + "time": "2021-01-27T09:09:26+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v1.1.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "b776d18b303a39f56c63747bcb977ad4b27aca26" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b776d18b303a39f56c63747bcb977ad4b27aca26", + "reference": "b776d18b303a39f56c63747bcb977ad4b27aca26", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "psr/container": "^1.0" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v1.1.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-07-06T13:19:58+00:00" }, { "name": "symfony/stopwatch", - "version": "v3.4.46", + "version": "v4.4.19", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "298b81faad4ce60e94466226b2abbb8c9bca7462" + "reference": "c5572f6494fc20668a73b77684d8dc77e534d8cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/298b81faad4ce60e94466226b2abbb8c9bca7462", - "reference": "298b81faad4ce60e94466226b2abbb8c9bca7462", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/c5572f6494fc20668a73b77684d8dc77e534d8cf", + "reference": "c5572f6494fc20668a73b77684d8dc77e534d8cf", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": ">=7.1.3", + "symfony/service-contracts": "^1.0|^2" }, "type": "library", "autoload": { @@ -4107,8 +4882,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Stopwatch Component", + "description": "Provides a way to profile code", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v4.4.19" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4123,7 +4901,7 @@ "type": "tidelift" } ], - "time": "2020-10-24T10:57:07+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { "name": "theseer/tokenizer", @@ -4163,6 +4941,10 @@ } ], "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/master" + }, "time": "2019-06-13T22:48:21+00:00" }, { @@ -4170,12 +4952,12 @@ "version": "1.9.1", "source": { "type": "git", - "url": "https://github.com/webmozart/assert.git", + "url": "https://github.com/webmozarts/assert.git", "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", "shasum": "" }, @@ -4212,6 +4994,10 @@ "check", "validate" ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.9.1" + }, "time": "2020-07-08T17:02:28+00:00" } ], @@ -4225,7 +5011,7 @@ }, "platform-dev": [], "platform-overrides": { - "php": "7.1" + "php": "7.1.27" }, "plugin-api-version": "2.0.0" } diff --git a/src/Admin/EditScreen.php b/src/Admin/EditScreen.php index 0d6a3802..e459ec65 100644 --- a/src/Admin/EditScreen.php +++ b/src/Admin/EditScreen.php @@ -2,6 +2,14 @@ namespace abrain\Einsatzverwaltung\Admin; use WP_Screen; +use WP_Taxonomy; +use WP_Term; +use function checked; +use function esc_attr; +use function esc_html; +use function in_array; +use function printf; +use function str_replace; /** * Base class for the edit screen customizations of custom post types @@ -15,13 +23,74 @@ abstract class EditScreen */ protected $customTypeSlug; + /** + * Gibt eine Checkbox für die Metabox aus + * + * @param string $label Beschriftung + * @param string $name Feld-ID + * @param bool $state Zustandswert + */ + protected function echoInputCheckbox(string $label, string $name, bool $state) + { + printf( + '', + esc_attr($name), + checked($state, '1', false), + $label + ); + } + + /** + * Gibt ein Eingabefeld für die Metabox aus + * + * @param string $label Beschriftung + * @param string $name Feld-ID + * @param string $value Feldwert + * @param string $placeholder Platzhalter + * @param int $size Größe des Eingabefelds + */ + protected function echoInputText(string $label, string $name, string $value, $placeholder = '', $size = 20) + { + printf('', esc_attr($name), esc_html($label)); + printf( + '', + esc_attr($name), + esc_attr($value), + esc_attr($size), + esc_attr($placeholder) + ); + } + + /** + * @param WP_Term[] $terms + * @param WP_Taxonomy $taxonomy + * @param int[] $assignedIds + */ + protected function echoTermCheckboxes(array $terms, WP_Taxonomy $taxonomy, array $assignedIds) + { + $format = '
  • '; + if ($taxonomy->hierarchical) { + $format = str_replace('%2$s', '%2$d', $format); + } + foreach ($terms as $term) { + $assigned = in_array($term->term_id, $assignedIds); + printf( + $format, + $taxonomy->name, + ($taxonomy->hierarchical ? esc_attr($term->term_id) : esc_attr($term->name)), + checked($assigned, true, false), + esc_html($term->name) + ); + } + } + /** * @param string[] $hidden * @param WP_Screen $screen * * @return string[] */ - public function filterDefaultHiddenMetaboxes($hidden, WP_Screen $screen) + public function filterDefaultHiddenMetaboxes(array $hidden, WP_Screen $screen): array { if ($screen->post_type !== $this->customTypeSlug) { return $hidden; diff --git a/src/Admin/Initializer.php b/src/Admin/Initializer.php index f1aaaba5..5a398f30 100644 --- a/src/Admin/Initializer.php +++ b/src/Admin/Initializer.php @@ -93,9 +93,10 @@ public function enqueueEditScripts($hook) wp_enqueue_script( 'einsatzverwaltung-edit-script', Core::$scriptUrl . 'einsatzverwaltung-edit.js', - array('jquery', 'jquery-ui-autocomplete'), + array('jquery', 'jquery-ui-autocomplete', 'wp-i18n'), Core::VERSION ); + wp_set_script_translations('einsatzverwaltung-edit-script', 'einsatzverwaltung'); wp_enqueue_style( 'einsatzverwaltung-edit', Core::$styleUrl . 'style-edit.css', @@ -139,7 +140,7 @@ public function enqueueEditScripts($hook) * * @return array */ - public function addReportsToDashboard($items) + public function addReportsToDashboard($items): array { $postType = 'einsatz'; if (post_type_exists($postType)) { @@ -172,7 +173,7 @@ public function addReportsToDashboard($items) * @param string $file Name der Plugindatei * @return array Vervollständigte Liste mit Links */ - public function pluginMetaLinks($links, $file) + public function pluginMetaLinks($links, $file): array { if (Core::$pluginBasename === $file) { $links[] = sprintf( @@ -192,7 +193,7 @@ public function pluginMetaLinks($links, $file) * * @return array */ - public function addActionLinks($links) + public function addActionLinks($links): array { $settingsPage = 'options-general.php?page=' . MainPage::EVW_SETTINGS_SLUG; $actionLinks = [ @@ -233,7 +234,7 @@ public function displayAdminNotices() * * @return bool */ - public function useBlockEditorForReports($useBlockEditor, $postType) + public function useBlockEditorForReports($useBlockEditor, $postType): bool { if ($postType === Report::getSlug() && get_option('einsatz_disable_blockeditor', '0') === '1') { return false; diff --git a/src/Admin/ReportEditScreen.php b/src/Admin/ReportEditScreen.php index a9623ecf..6868a306 100644 --- a/src/Admin/ReportEditScreen.php +++ b/src/Admin/ReportEditScreen.php @@ -6,6 +6,7 @@ use abrain\Einsatzverwaltung\Types\Report; use abrain\Einsatzverwaltung\Types\Unit; use abrain\Einsatzverwaltung\Types\Vehicle; +use abrain\Einsatzverwaltung\Utilities; use WP_Post; use WP_Taxonomy; use WP_Term; @@ -21,9 +22,9 @@ use function esc_html; use function esc_html__; use function get_taxonomy; +use function get_term; use function get_term_meta; use function get_terms; -use function get_the_terms; use function in_array; use function is_wp_error; use function join; @@ -32,8 +33,8 @@ use function preg_match_all; use function printf; use function sprintf; -use function str_replace; use function usort; +use function wp_dropdown_categories; use const PREG_GREP_INVERT; /** @@ -83,19 +84,7 @@ public function addMetaBoxes() add_meta_box( 'einsatzartdiv', __('Incident Category', 'einsatzverwaltung'), - array('abrain\Einsatzverwaltung\Admin\ReportEditScreen', 'displayMetaBoxEinsatzart'), - 'einsatz', - 'side', - 'default', - array( - '__block_editor_compatible_meta_box' => true, - '__back_compat_meta_box' => false - ) - ); - add_meta_box( - 'einsatzverwaltung_units', - __('Units', 'einsatzverwaltung'), - array($this, 'displayMetaBoxUnits'), + array($this, 'displayMetaBoxEinsatzart'), 'einsatz', 'side', 'default', @@ -123,7 +112,7 @@ public function addMetaBoxes() * * @param WP_Post $post Das Post-Objekt des aktuell bearbeiteten Einsatzberichts */ - public function displayMetaBoxAnnotations($post) + public function displayMetaBoxAnnotations(WP_Post $post) { $report = new IncidentReport($post); @@ -153,7 +142,7 @@ public function displayMetaBoxAnnotations($post) * * @param WP_Post $post Das Post-Objekt des aktuell bearbeiteten Einsatzberichts */ - public function displayMetaBoxEinsatzdetails($post) + public function displayMetaBoxEinsatzdetails(WP_Post $post) { // Use nonce for verification wp_nonce_field('save_einsatz_details', 'einsatzverwaltung_nonce'); @@ -170,7 +159,7 @@ public function displayMetaBoxEinsatzdetails($post) $names = $this->getEinsatzleiterNamen(); printf('', esc_attr(implode(',', $names))); - echo '
    '; + echo '
    '; if (get_option('einsatzverwaltung_incidentnumbers_auto', '0') === '1') { $numberText = $report->isDraft() ? __('Will be generated upon publication', 'einsatzverwaltung') : $nummer; @@ -193,14 +182,14 @@ public function displayMetaBoxEinsatzdetails($post) __('Alarm time', 'einsatzverwaltung'), 'einsatzverwaltung_alarmzeit', esc_attr($alarmzeit->format('Y-m-d H:i')), - 'JJJJ-MM-TT hh:mm' + 'YYYY-MM-DD hh:mm' ); $this->echoInputText( __('End time', 'einsatzverwaltung'), 'einsatz_einsatzende', esc_attr($einsatzende), - 'JJJJ-MM-TT hh:mm' + 'YYYY-MM-DD hh:mm' ); echo '
    '; @@ -246,42 +235,24 @@ public function displayMetaBoxEinsatzdetails($post) * * @param WP_Post $post Post-Object */ - public static function displayMetaBoxEinsatzart($post) + public function displayMetaBoxEinsatzart(WP_Post $post) { $report = new IncidentReport($post); $typeOfIncident = $report->getTypeOfIncident(); - self::dropdownEinsatzart($typeOfIncident ? $typeOfIncident->term_id : 0); - } - - /** - * @param WP_Post $post - */ - public function displayMetaBoxUnits(WP_Post $post) - { - $units = get_terms(array( - 'taxonomy' => Unit::getSlug(), - 'hide_empty' => false + wp_dropdown_categories(array( + 'show_option_all' => '', + 'show_option_none' => _x('- none -', 'incident category dropdown', 'einsatzverwaltung'), + 'orderby' => 'NAME', + 'order' => 'ASC', + 'show_count' => false, + 'hide_empty' => false, + 'echo' => true, + 'selected' => $typeOfIncident ? $typeOfIncident->term_id : 0, + 'hierarchical' => true, + 'name' => 'tax_input[einsatzart]', + 'taxonomy' => 'einsatzart', + 'hide_if_empty' => false )); - - if (is_wp_error($units)) { - printf("
    %s
    ", $units->get_error_message()); - return; - } - - $taxonomyObject = get_taxonomy(Unit::getSlug()); - if (empty($units)) { - printf("
    %s
    ", esc_html($taxonomyObject->labels->no_terms)); - return; - } - - $report = new IncidentReport($post); - $assignedUnits = array_map(function (WP_Term $unit) { - return $unit->term_id; - }, $report->getUnits()); - - echo '
      '; - $this->echoTermCheckboxes($units, $taxonomyObject, $assignedUnits); - echo '
    '; } /** @@ -291,8 +262,8 @@ public function displayMetaBoxUnits(WP_Post $post) */ public function displayMetaBoxVehicles(WP_Post $post) { - $taxonomyObject = get_taxonomy(Vehicle::getSlug()); - if (empty($taxonomyObject)) { + $vehicleTaxonomy = get_taxonomy(Vehicle::getSlug()); + if (empty($vehicleTaxonomy)) { return; } @@ -301,7 +272,7 @@ public function displayMetaBoxVehicles(WP_Post $post) 'hide_empty' => false )); if (empty($allVehicles)) { - printf("
    %s
    ", esc_html($taxonomyObject->labels->no_terms)); + printf("
    %s
    ", esc_html($vehicleTaxonomy->labels->no_terms)); return; } @@ -313,25 +284,31 @@ public function displayMetaBoxVehicles(WP_Post $post) return get_term_meta($vehicle->term_id, 'out_of_service', true) !== '1'; }); - // Sort the vehicles according to the custom order numbers - usort($inServiceVehicles, array(Vehicle::class, 'compareVehicles')); - usort($outOfServiceVehicles, array(Vehicle::class, 'compareVehicles')); - // Determine vehicles assigned to the current report - $terms = get_the_terms($post, Vehicle::getSlug()); - if (is_wp_error($terms) || $terms === false) { - $terms = array(); + $assignedVehicleIds = get_terms([ + 'taxonomy' => Vehicle::getSlug(), + 'object_ids' => $post->ID, + 'fields' => 'ids' + ]); + if (is_wp_error($assignedVehicleIds)) { + $assignedVehicleIds = []; } - $assignedVehicleIds = array_map(function (WP_Term $vehicle) { - return $vehicle->term_id; - }, $terms); - // Output the checkboxes - echo '
      '; - $this->echoTermCheckboxes($inServiceVehicles, $taxonomyObject, $assignedVehicleIds); + echo '
      '; + if (Unit::isActivelyUsed()) { + $this->echoVehiclesByUnit($post, $vehicleTaxonomy, $inServiceVehicles, $assignedVehicleIds); + } else { + // Sort the vehicles according to the custom order numbers + usort($inServiceVehicles, array(Vehicle::class, 'compareVehicles')); + + echo '
        '; + $this->echoTermCheckboxes($inServiceVehicles, $vehicleTaxonomy, $assignedVehicleIds); + echo '
      '; + } if (!empty($outOfServiceVehicles)) { echo '
      '; + usort($outOfServiceVehicles, array(Vehicle::class, 'compareVehicles')); // Automatically expand the details tag, if vehicles in there are assigned to the current report $outOfServiceIds = array_map(function (WP_Term $vehicle) { @@ -340,33 +317,55 @@ public function displayMetaBoxVehicles(WP_Post $post) echo empty(array_intersect($assignedVehicleIds, $outOfServiceIds)) ? '
      ' : '
      '; echo sprintf("%s", esc_html__('Out of service', 'einsatzverwaltung')); - $this->echoTermCheckboxes($outOfServiceVehicles, $taxonomyObject, $assignedVehicleIds); + echo '
        '; + $this->echoTermCheckboxes($outOfServiceVehicles, $vehicleTaxonomy, $assignedVehicleIds); + echo '
      '; echo '
      '; } - echo '
    '; + echo ''; } /** - * Zeigt Dropdown mit Hierarchie für die Einsatzart + * Echoes the checkboxes for vehicles and units, grouped by unit. * - * @param string $selected Slug der ausgewählten Einsatzart + * @param WP_Post $post + * @param WP_Taxonomy $vehicleTaxonomy + * @param array $vehicles + * @param array $assignedVehicleIds */ - public static function dropdownEinsatzart(string $selected) + private function echoVehiclesByUnit(WP_Post $post, WP_Taxonomy $vehicleTaxonomy, array $vehicles, array $assignedVehicleIds) { - wp_dropdown_categories(array( - 'show_option_all' => '', - 'show_option_none' => _x('- none -', 'incident category dropdown', 'einsatzverwaltung'), - 'orderby' => 'NAME', - 'order' => 'ASC', - 'show_count' => false, - 'hide_empty' => false, - 'echo' => true, - 'selected' => $selected, - 'hierarchical' => true, - 'name' => 'tax_input[einsatzart]', - 'taxonomy' => 'einsatzart', - 'hide_if_empty' => false - )); + $unitTaxObj = get_taxonomy(Unit::getSlug()); + if (empty($unitTaxObj)) { + return; + } + + $assignedUnitIds = get_terms([ + 'taxonomy' => Unit::getSlug(), + 'object_ids' => $post->ID, + 'fields' => 'ids' + ]); + if (is_wp_error($assignedVehicleIds)) { + $assignedVehicleIds = []; + } + + foreach (Utilities::groupVehiclesByUnit($vehicles) as $unitId => $unitVehicles) { + if ($unitId === -1) { + printf('

    %s

    ', esc_html__('Without Unit', 'einsatzverwaltung')); + } else { + $unit = get_term($unitId, Unit::getSlug()); + printf( + '', + $unitTaxObj->name, + esc_attr($unit->name), + checked(in_array($unit->term_id, $assignedUnitIds), true, false), + esc_html($unit->name) + ); + } + echo '
      '; + $this->echoTermCheckboxes($unitVehicles, $vehicleTaxonomy, $assignedVehicleIds); + echo '
    '; + } } /** @@ -422,75 +421,13 @@ public function filterIncidentCategoryDropdown(string $output, array $parsedArgs return $newOutput; } - /** - * Gibt ein Eingabefeld für die Metabox aus - * - * @param string $label Beschriftung - * @param string $name Feld-ID - * @param string $value Feldwert - * @param string $placeholder Platzhalter - * @param int $size Größe des Eingabefelds - */ - private function echoInputText($label, $name, $value, $placeholder = '', $size = 20) - { - printf('', esc_attr($name), esc_html($label)); - printf( - '', - esc_attr($name), - esc_attr($value), - esc_attr($size), - esc_attr($placeholder) - ); - } - - /** - * Gibt eine Checkbox für die Metabox aus - * - * @param string $label Beschriftung - * @param string $name Feld-ID - * @param bool $state Zustandswert - */ - private function echoInputCheckbox($label, $name, $state) - { - printf( - '', - esc_attr($name), - checked($state, '1', false), - $label - ); - } - - /** - * @param WP_Term[] $terms - * @param WP_Taxonomy $taxonomy - * @param int[] $assignedIds - */ - private function echoTermCheckboxes($terms, $taxonomy, $assignedIds) - { - $format = '
  • '; - if ($taxonomy->hierarchical) { - $format = str_replace('%2$s', '%2$d', $format); - } - foreach ($terms as $term) { - $assigned = in_array($term->term_id, $assignedIds); - printf( - $format, - $taxonomy->name, - ($taxonomy->hierarchical ? esc_attr($term->term_id) : esc_attr($term->name)), - checked($assigned, true, false), - esc_html($term->name) - ); - } - } - /** * Gibt die Namen aller bisher verwendeten Einsatzleiter zurück * * @return array */ - public function getEinsatzleiterNamen() + public function getEinsatzleiterNamen(): array { - /** @var wpdb $wpdb */ global $wpdb; $names = array(); diff --git a/src/Admin/ReportListTable.php b/src/Admin/ReportListTable.php index 1fa61376..47ba77f2 100644 --- a/src/Admin/ReportListTable.php +++ b/src/Admin/ReportListTable.php @@ -21,7 +21,7 @@ class ReportListTable * * @var array */ - private $customColumns = array(); + private $customColumns; /** * ReportListTable constructor. @@ -72,7 +72,7 @@ public function __construct() * * @return array */ - public function filterColumnsEinsatz($columns) + public function filterColumnsEinsatz($columns): array { unset($columns['author']); unset($columns['date']); @@ -96,7 +96,7 @@ public function filterColumnContentEinsatz($column, $postId) { $report = new IncidentReport($postId); $content = $this->getColumnContent($column, $report); - echo (empty($content) ? '-' : $content); + echo empty($content) ? '-' : $content; } /** @@ -105,7 +105,7 @@ public function filterColumnContentEinsatz($column, $postId) * * @return string */ - public function getColumnContent($columnId, IncidentReport $report) + public function getColumnContent($columnId, IncidentReport $report): string { switch ($columnId) { case 'e_nummer': @@ -136,7 +136,7 @@ public function getColumnContent($columnId, IncidentReport $report) $vehicleLinks = array_map(array($this, 'getTermFilterLink'), $vehicles); return join(', ', $vehicleLinks); case 'einsatzverwaltung_annotations': - return AnnotationIconBar::getInstance()->render($report); + return AnnotationIconBar::getInstance()->render($report->getPostId()); case 'einsatzverwaltung_units': $units = $report->getUnits(); $unitLinks = array_map(array($this, 'getTermFilterLink'), $units); @@ -150,7 +150,7 @@ public function getColumnContent($columnId, IncidentReport $report) * @param WP_Term|null $term * @return string An HTML anchor to filter this list table for occurrences of a certain term */ - private function getTermFilterLink(WP_Term $term = null) + private function getTermFilterLink(WP_Term $term = null): string { if (empty($term)) { return ''; @@ -220,7 +220,7 @@ private function echoEditCustomBox($columnName) * * @return bool */ - private function columnHasCustomBox($columnName) + private function columnHasCustomBox($columnName): bool { return array_key_exists($columnName, $this->customColumns) && $this->customColumns[$columnName]['quickedit']; } @@ -232,7 +232,7 @@ private function columnHasCustomBox($columnName) * * @return string */ - private function getColumnLabel($columnName) + private function getColumnLabel($columnName): string { if (!array_key_exists($columnName, $this->customColumns)) { return ''; diff --git a/src/Admin/TasksPage.php b/src/Admin/TasksPage.php index 15d91782..749b1ad0 100644 --- a/src/Admin/TasksPage.php +++ b/src/Admin/TasksPage.php @@ -79,8 +79,8 @@ public function renderPage() echo '

    Permalinks von ' . count($posts) . ' Einsatzberichten werden angepasst...

    '; // Da nur die Titelform geändert wird, muss keine Aktualisierung der laufenden Nummern etc. anlaufen - remove_action('private_einsatz', array($this->data, 'onPublish'), 10); - remove_action('publish_einsatz', array($this->data, 'onPublish'), 10); + remove_action('private_einsatz', array($this->data, 'onPublish')); + remove_action('publish_einsatz', array($this->data, 'onPublish')); $processed = 0; foreach ($posts as $post) { diff --git a/src/Core.php b/src/Core.php index 5ff12e27..b00a6831 100644 --- a/src/Core.php +++ b/src/Core.php @@ -11,7 +11,7 @@ */ class Core { - const VERSION = '1.8.0'; + const VERSION = '1.9.0'; const DB_VERSION = 60; /** @@ -197,7 +197,7 @@ private function maybeUpdate() /** * @return Data */ - public function getData() + public function getData(): Data { return $this->data; } @@ -208,7 +208,7 @@ public function getData() * * @return Core */ - public static function getInstance() + public static function getInstance(): ?Core { if (null === self::$instance) { self::$instance = new Core(); diff --git a/src/CustomFields/Checkbox.php b/src/CustomFields/Checkbox.php index 6a93123d..94bd4351 100644 --- a/src/CustomFields/Checkbox.php +++ b/src/CustomFields/Checkbox.php @@ -29,7 +29,7 @@ public function __construct($key, $label, $checkboxLabel, $description, $default /** * @inheritDoc */ - public function getAddTermInput() + public function getAddTermInput(): string { return sprintf( '', @@ -41,7 +41,7 @@ public function getAddTermInput() /** * @inheritDoc */ - public function getAddTermMarkup() + public function getAddTermMarkup(): string { return sprintf( '
    %2$s%4$s

    %5$s

    ', @@ -56,7 +56,7 @@ public function getAddTermMarkup() /** * @inheritDoc */ - public function getColumnContent($termId) + public function getColumnContent($termId): string { $value = $this->getValue($termId); return ($value === '1' ? __('Yes', 'einsatzverwaltung') : __('No', 'einsatzverwaltung')); @@ -65,7 +65,7 @@ public function getColumnContent($termId) /** * @inheritDoc */ - public function getEditPostInput(WP_Post $post) + public function getEditPostInput(WP_Post $post): string { return sprintf( '', @@ -77,7 +77,7 @@ public function getEditPostInput(WP_Post $post) /** * @inheritDoc */ - public function getEditTermInput($tag) + public function getEditTermInput($tag): string { return sprintf( '', @@ -89,7 +89,7 @@ public function getEditTermInput($tag) /** * @inheritDoc */ - public function getEditTermMarkup($tag) + public function getEditTermMarkup($tag): string { return sprintf( '', diff --git a/src/CustomFields/ColorPicker.php b/src/CustomFields/ColorPicker.php index e9dca70c..f22ad9c3 100644 --- a/src/CustomFields/ColorPicker.php +++ b/src/CustomFields/ColorPicker.php @@ -21,7 +21,7 @@ public function __construct($key, $label, $description, $defaultValue = '') /** * @inheritdoc */ - public function getAddTermInput() + public function getAddTermInput(): string { return sprintf( '', @@ -32,7 +32,7 @@ public function getAddTermInput() /** * @inheritdoc */ - public function getEditTermInput($tag) + public function getEditTermInput($tag): string { return sprintf( '', @@ -44,7 +44,7 @@ public function getEditTermInput($tag) /** * @inheritdoc */ - public function getColumnContent($termId) + public function getColumnContent($termId): string { $value = $this->getValue($termId); if (empty($value)) { @@ -60,7 +60,7 @@ public function getColumnContent($termId) /** * @inheritDoc */ - public function getEditPostInput(WP_Post $post) + public function getEditPostInput(WP_Post $post): string { return sprintf( '', diff --git a/src/CustomFields/CustomField.php b/src/CustomFields/CustomField.php index 4844468a..f28e7f82 100644 --- a/src/CustomFields/CustomField.php +++ b/src/CustomFields/CustomField.php @@ -34,7 +34,7 @@ public function __construct($key, $label, $description, $defaultValue = false) /** * @return string The markup for the form field shown when adding a new term. */ - public function getAddTermMarkup() + public function getAddTermMarkup(): string { return sprintf( '
    %4$s

    %3$s

    ', @@ -49,7 +49,7 @@ public function getAddTermMarkup() * @param WP_Term $tag Current taxonomy term object. * @return string The markup for the form field shown when editing an existing term. */ - public function getEditTermMarkup($tag) + public function getEditTermMarkup($tag): string { return sprintf( '', @@ -80,23 +80,23 @@ public function getValue($objectId) /** * @return string The markup for the input shown when adding a new term. */ - abstract public function getAddTermInput(); + abstract public function getAddTermInput(): string; /** * @param int $termId * @return string */ - abstract public function getColumnContent($termId); + abstract public function getColumnContent($termId): string; /** * @param WP_Post $post Currently edited post object * @return string HTML markup for the input */ - abstract public function getEditPostInput(WP_Post $post); + abstract public function getEditPostInput(WP_Post $post): string; /** * @param WP_Term $tag Current taxonomy term object. * @return string The markup for the input shown when editing an existing term. */ - abstract public function getEditTermInput($tag); + abstract public function getEditTermInput($tag): string; } diff --git a/src/CustomFields/NumberInput.php b/src/CustomFields/NumberInput.php index b1a424a4..532db70e 100644 --- a/src/CustomFields/NumberInput.php +++ b/src/CustomFields/NumberInput.php @@ -21,7 +21,7 @@ public function __construct($key, $label, $description, $defaultValue = 0) /** * @inheritdoc */ - public function getAddTermInput() + public function getAddTermInput(): string { return sprintf( '', @@ -33,7 +33,7 @@ public function getAddTermInput() /** * @inheritdoc */ - public function getEditTermInput($tag) + public function getEditTermInput($tag): string { return sprintf( '', @@ -45,7 +45,7 @@ public function getEditTermInput($tag) /** * @inheritdoc */ - public function getColumnContent($termId) + public function getColumnContent($termId): string { return esc_html($this->getValue($termId)); } @@ -53,7 +53,7 @@ public function getColumnContent($termId) /** * @inheritDoc */ - public function getEditPostInput(WP_Post $post) + public function getEditPostInput(WP_Post $post): string { return sprintf( '', diff --git a/src/CustomFields/PostSelector.php b/src/CustomFields/PostSelector.php index 4618dc45..4979d2b1 100644 --- a/src/CustomFields/PostSelector.php +++ b/src/CustomFields/PostSelector.php @@ -44,7 +44,7 @@ public function __construct($key, $label, $description, $postTypes = array('post * } * @return string HTML-Code für Auswahlfeld */ - public function dropdownPosts($args) + public function dropdownPosts($args): string { $defaults = array( 'echo' => true, @@ -108,7 +108,7 @@ public function dropdownPosts($args) /** * @inheritdoc */ - public function getAddTermInput() + public function getAddTermInput(): string { return $this->dropdownPosts(array( 'echo' => false, @@ -120,7 +120,7 @@ public function getAddTermInput() /** * @inheritdoc */ - public function getEditTermInput($tag) + public function getEditTermInput($tag): string { return $this->dropdownPosts(array( 'echo' => false, @@ -133,7 +133,7 @@ public function getEditTermInput($tag) /** * @inheritdoc */ - public function getColumnContent($termId) + public function getColumnContent($termId): string { $postId = $this->getValue($termId); @@ -154,7 +154,7 @@ public function getColumnContent($termId) /** * @inheritDoc */ - public function getEditPostInput(WP_Post $post) + public function getEditPostInput(WP_Post $post): string { return $this->dropdownPosts(array( 'echo' => false, diff --git a/src/CustomFields/TextInput.php b/src/CustomFields/TextInput.php index d1749498..0c52abda 100644 --- a/src/CustomFields/TextInput.php +++ b/src/CustomFields/TextInput.php @@ -21,7 +21,7 @@ public function __construct($key, $label, $description, $defaultValue = '') /** * @inheritdoc */ - public function getAddTermInput() + public function getAddTermInput(): string { return sprintf( '', @@ -32,7 +32,7 @@ public function getAddTermInput() /** * @inheritdoc */ - public function getEditTermInput($tag) + public function getEditTermInput($tag): string { return sprintf( '', @@ -44,7 +44,7 @@ public function getEditTermInput($tag) /** * @inheritdoc */ - public function getColumnContent($termId) + public function getColumnContent($termId): string { return esc_html($this->getValue($termId)); } @@ -52,7 +52,7 @@ public function getColumnContent($termId) /** * @inheritDoc */ - public function getEditPostInput(WP_Post $post) + public function getEditPostInput(WP_Post $post): string { return sprintf( '', diff --git a/src/CustomFields/UnitSelector.php b/src/CustomFields/UnitSelector.php new file mode 100644 index 00000000..0664cccc --- /dev/null +++ b/src/CustomFields/UnitSelector.php @@ -0,0 +1,84 @@ + _x('- none -', 'unit dropdown', 'einsatzverwaltung'), + 'orderby' => 'NAME', + 'order' => 'ASC', + 'hide_empty' => false, + 'echo' => false, + 'name' => $this->key, + 'taxonomy' => Unit::getSlug(), + )); + } + + /** + * @inheritdoc + */ + public function getEditTermInput($tag): string + { + return wp_dropdown_categories(array( + 'show_option_none' => _x('- none -', 'unit dropdown', 'einsatzverwaltung'), + 'orderby' => 'NAME', + 'order' => 'ASC', + 'hide_empty' => false, + 'echo' => false, + 'name' => $this->key, + 'taxonomy' => Unit::getSlug(), + 'selected' => $this->getValue($tag->term_id), + )); + } + + /** + * @inheritdoc + */ + public function getColumnContent($termId): string + { + $unitTermId = $this->getValue($termId); + + $unit = get_term($unitTermId, Unit::getSlug()); + if (empty($unit) || is_wp_error($unit)) { + return ''; + } + + return esc_html($unit->name); + } + + /** + * @inheritDoc + * @throws Exception + */ + public function getEditPostInput(WP_Post $post): string + { + throw new Exception('Not yet implemented'); + } +} diff --git a/src/CustomFields/UrlInput.php b/src/CustomFields/UrlInput.php index c98d807b..76003dd7 100644 --- a/src/CustomFields/UrlInput.php +++ b/src/CustomFields/UrlInput.php @@ -23,7 +23,7 @@ public function __construct($key, $label, $description, $defaultValue = '') /** * @inheritDoc */ - public function getAddTermInput() + public function getAddTermInput(): string { return sprintf( '', @@ -35,7 +35,7 @@ public function getAddTermInput() /** * @inheritDoc */ - public function getColumnContent($termId) + public function getColumnContent($termId): string { $url = $this->getValue($termId); if (empty($url)) { @@ -52,7 +52,7 @@ public function getColumnContent($termId) /** * @inheritDoc */ - public function getEditPostInput(WP_Post $post) + public function getEditPostInput(WP_Post $post): string { return sprintf( '', @@ -64,7 +64,7 @@ public function getEditPostInput(WP_Post $post) /** * @inheritDoc */ - public function getEditTermInput($tag) + public function getEditTermInput($tag): string { return sprintf( '', diff --git a/src/CustomFieldsRepository.php b/src/CustomFieldsRepository.php index 2fe8280a..5ce16f24 100644 --- a/src/CustomFieldsRepository.php +++ b/src/CustomFieldsRepository.php @@ -76,7 +76,7 @@ public function add(CustomType $customType, CustomField $customField) * * @return CustomField[] */ - public function getFieldsForType($slug) + public function getFieldsForType($slug): array { if ($this->hasPostType($slug)) { return $this->postTypeFields[$slug]; @@ -94,7 +94,7 @@ public function getFieldsForType($slug) * * @return bool */ - private function hasPostType($postType) + private function hasPostType($postType): bool { return array_key_exists($postType, $this->postTypeFields) && is_array($this->postTypeFields[$postType]); } @@ -106,7 +106,7 @@ private function hasPostType($postType) * * @return bool */ - private function hasTaxonomy($taxonomy) + private function hasTaxonomy($taxonomy): bool { return array_key_exists($taxonomy, $this->taxonomyFields) && is_array($this->taxonomyFields[$taxonomy]); } @@ -148,7 +148,7 @@ public function onEditFormFields($tag, $taxonomy) * @param array $columns * @return array */ - public function onCustomColumns($columns) + public function onCustomColumns($columns): array { $screen = get_current_screen(); @@ -220,7 +220,7 @@ public function onPostColumnContent($columnId, $postId) * * @return string Inhalt der Spalte */ - public function onTaxonomyColumnContent($string, $columnName, $termId) + public function onTaxonomyColumnContent($string, $columnName, $termId): string { $term = get_term($termId); if (empty($term) || is_wp_error($term)) { diff --git a/src/Data.php b/src/Data.php index ffc9fcd5..a42db22b 100644 --- a/src/Data.php +++ b/src/Data.php @@ -46,7 +46,7 @@ class Data * * @param Options $options */ - public function __construct($options) + public function __construct(Options $options) { $this->options = $options; } @@ -56,9 +56,8 @@ public function __construct($options) * * @return int[] */ - public function getYearsWithReports() + public function getYearsWithReports(): array { - /** @var wpdb $wpdb */ global $wpdb; $yearStrings = $wpdb->get_col($wpdb->prepare( @@ -75,7 +74,7 @@ public function getYearsWithReports() * @param int $postId ID des Posts * @param WP_Post $post Das Post-Objekt */ - public function savePostdata($postId, $post) + public function savePostdata(int $postId, WP_Post $post) { // Schreibrechte prüfen if (!current_user_can('edit_einsatzbericht', $postId)) { @@ -212,7 +211,7 @@ public function updateSequenceNumbers($yearToUpdate = null) * @param int $postId Die ID des Einsatzberichts * @param WP_Post $post Das Post-Objekt des Einsatzberichts */ - public function onPublish($postId, $post) + public function onPublish(int $postId, WP_Post $post) { $report = new IncidentReport($post); @@ -238,7 +237,7 @@ public function onPublish($postId, $post) * @param string $oldStatus * @param WP_Post $post */ - public function onTransitionPostStatus($newStatus, $oldStatus, WP_Post $post) + public function onTransitionPostStatus(string $newStatus, string $oldStatus, WP_Post $post) { if (get_post_type($post) !== Report::getSlug()) { return; @@ -282,7 +281,7 @@ private function adjustPostDate(WP_Post $post) * @param int $postId Die ID des Einsatzberichts * @param WP_Post $post Das Post-Objekt des Einsatzberichts */ - public function onTrash($postId, $post) + public function onTrash(int $postId, WP_Post $post) { // Laufende Nummern aktualisieren if (true === $this->assignSequenceNumbers) { @@ -314,7 +313,7 @@ public function resumeAutoSequenceNumbers() * @param int $postId ID des Einsatzberichts * @param string $seqNum Zu setzende laufende Nummer */ - public function setSequenceNumber($postId, $seqNum) + public function setSequenceNumber(int $postId, string $seqNum) { if (empty($postId) || empty($seqNum)) { return; @@ -326,7 +325,7 @@ public function setSequenceNumber($postId, $seqNum) /** * @return bool */ - private function isBulkEdit() + private function isBulkEdit(): bool { if (isset($_REQUEST['filter_action']) && ! empty($_REQUEST['filter_action'])) { return false; diff --git a/src/Export/Formats/AbstractFormat.php b/src/Export/Formats/AbstractFormat.php index 74f71300..a78e168a 100644 --- a/src/Export/Formats/AbstractFormat.php +++ b/src/Export/Formats/AbstractFormat.php @@ -25,7 +25,7 @@ abstract class AbstractFormat implements Format /** * @inheritDoc */ - public function setFilters($startDate, $endDate) + public function setFilters(string $startDate, string $endDate) { $this->startDate = $startDate; $this->endDate = $endDate; @@ -37,7 +37,7 @@ public function setFilters($startDate, $endDate) * * @return WP_Query */ - protected function getQuery() + protected function getQuery(): WP_Query { // Wähle nur veröffentlichte Einsatzberichte aus $args = array( @@ -67,7 +67,7 @@ protected function getQuery() * * @return array */ - protected function getColumnNames() + protected function getColumnNames(): array { return array( 'Einsatznummer', @@ -93,7 +93,7 @@ protected function getColumnNames() * @param WP_Post $post * @return array */ - protected function getValuesForReport(WP_Post $post) + protected function getValuesForReport(WP_Post $post): array { $report = new IncidentReport($post); @@ -127,7 +127,7 @@ protected function getValuesForReport(WP_Post $post) * @param WP_Post|WP_Term $object * @return string */ - private function getName($object) + private function getName($object): string { if ($object instanceof WP_Term) { return $object->name; @@ -140,13 +140,15 @@ private function getName($object) /** * @param array $array + * * @return mixed */ - abstract protected function getArrayRepresentation($array); + abstract protected function getArrayRepresentation(array $array); /** * @param bool $bool + * * @return mixed */ - abstract protected function getBooleanRepresentation($bool); + abstract protected function getBooleanRepresentation(bool $bool); } diff --git a/src/Export/Formats/Csv.php b/src/Export/Formats/Csv.php index 85de3076..8dcdd035 100644 --- a/src/Export/Formats/Csv.php +++ b/src/Export/Formats/Csv.php @@ -32,7 +32,7 @@ class Csv extends AbstractFormat /** * @inheritDoc */ - public function getTitle() + public function getTitle(): string { return 'CSV'; } @@ -91,7 +91,7 @@ public function setOptions(array $options) /** * @inheritDoc */ - public function getFilename() + public function getFilename(): string { return 'Einsatzberichte.csv'; } @@ -125,18 +125,20 @@ public function export() /** * @param bool $bool + * * @return mixed */ - protected function getBooleanRepresentation($bool) + protected function getBooleanRepresentation(bool $bool): string { return ($bool === true ? 'Ja' : 'Nein'); } /** * @param array $array + * * @return mixed */ - protected function getArrayRepresentation($array) + protected function getArrayRepresentation(array $array) { return join(',', $array); } diff --git a/src/Export/Formats/Excel.php b/src/Export/Formats/Excel.php index adeb3281..7c384056 100644 --- a/src/Export/Formats/Excel.php +++ b/src/Export/Formats/Excel.php @@ -12,7 +12,7 @@ class Excel extends Csv /** * @inheritDoc */ - public function getTitle() + public function getTitle(): string { return 'CSV für Microsoft Excel'; } diff --git a/src/Export/Formats/Format.php b/src/Export/Formats/Format.php index 4a5e3f5b..8149d9b4 100644 --- a/src/Export/Formats/Format.php +++ b/src/Export/Formats/Format.php @@ -11,7 +11,7 @@ interface Format * * @return string */ - public function getTitle(); + public function getTitle(): string; /** * Gibt die Optionen im HTML-Format für dieses Exportformat aus. @@ -25,11 +25,12 @@ public function renderOptions(); * Die Inhalte im Array müssen überprüft werden, da es sich um Eingaben vom * Benutzer handelt. * - * @param string $startDate Jahr und Monat im Format YYYY-MM oder 0 - * @param string $endDate Jahr und Monat im Format YYYY-MM oder 0 + * @param string $startDate Jahr und Monat im Format YYYY-MM oder 0 + * @param string $endDate Jahr und Monat im Format YYYY-MM oder 0 + * * @return void */ - public function setFilters($startDate, $endDate); + public function setFilters(string $startDate, string $endDate); /** * Erwartet ein Array mit Optionen zum Konfigurieren des Exportformats. @@ -46,7 +47,7 @@ public function setOptions(array $options); * * @return string */ - public function getFilename(); + public function getFilename(): string; /** * Gibt den Inhalt der Datei, die beim Export erstellt wird, aus. diff --git a/src/Export/Formats/Json.php b/src/Export/Formats/Json.php index 9946c10f..481be27a 100644 --- a/src/Export/Formats/Json.php +++ b/src/Export/Formats/Json.php @@ -17,7 +17,7 @@ class Json extends AbstractFormat /** * @inheritDoc */ - public function getTitle() + public function getTitle(): string { return 'JSON'; } @@ -40,7 +40,7 @@ public function renderOptions() /** * @inheritDoc */ - public function getFilename() + public function getFilename(): string { return 'Einsatzberichte.json'; } @@ -107,18 +107,20 @@ public function export() /** * @param bool $bool + * * @return mixed */ - protected function getBooleanRepresentation($bool) + protected function getBooleanRepresentation(bool $bool): bool { return $bool; } /** * @param array $array + * * @return mixed */ - protected function getArrayRepresentation($array) + protected function getArrayRepresentation(array $array): array { return $array; } diff --git a/src/Export/Tool.php b/src/Export/Tool.php index 38d156ac..eb1f0213 100644 --- a/src/Export/Tool.php +++ b/src/Export/Tool.php @@ -137,7 +137,8 @@ public function renderToolPage() - + diff --git a/src/Frontend.php b/src/Frontend.php index 4541c80c..48ff6f07 100644 --- a/src/Frontend.php +++ b/src/Frontend.php @@ -3,9 +3,14 @@ use abrain\Einsatzverwaltung\Frontend\ReportList\Renderer as ReportListRenderer; use abrain\Einsatzverwaltung\Model\IncidentReport; +use abrain\Einsatzverwaltung\Types\Report; +use abrain\Einsatzverwaltung\Types\Unit; use abrain\Einsatzverwaltung\Util\Formatter; use WP_Post; use WP_Query; +use function date_i18n; +use function sprintf; +use function wp_kses; /** * Generiert alle Inhalte für das Frontend, mit Ausnahme der Shortcodes und des Widgets @@ -28,7 +33,7 @@ class Frontend * @param Options $options * @param Formatter $formatter */ - public function __construct($options, $formatter) + public function __construct(Options $options, Formatter $formatter) { $this->formatter = $formatter; $this->options = $options; @@ -81,52 +86,58 @@ public function enqueueStyleAndScripts() * * @return string Auflistung der Einsatzdetails */ - public function getEinsatzberichtHeader($post, $mayContainLinks = true, $showArchiveLinks = true) + public function getEinsatzberichtHeader(WP_Post $post, bool $mayContainLinks = true, bool $showArchiveLinks = true): string { - if (get_post_type($post) == "einsatz") { - $report = new IncidentReport($post); + if (get_post_type($post) !== Report::getSlug()) { + return ''; + } - $typesOfAlerting = $this->formatter->getTypesOfAlerting($report); + $report = new IncidentReport($post); - $duration = $report->getDuration(); - $durationString = ($duration === false ? '' : $this->formatter->getDurationString($duration)); + $duration = $report->getDuration(); + $durationString = ($duration === false ? '' : $this->formatter->getDurationString($duration)); - $showEinsatzartArchiveLink = $showArchiveLinks && $this->options->isShowEinsatzartArchive(); - $art = $this->formatter->getTypeOfIncident($report, $mayContainLinks, $showEinsatzartArchiveLink); + $showTypeArchiveLink = $showArchiveLinks && $this->options->isShowEinsatzartArchive(); + $art = $this->formatter->getTypeOfIncident($report, $mayContainLinks, $showTypeArchiveLink); - if ($report->isFalseAlarm()) { - $art = (empty($art) ? 'Fehlalarm' : $art.' (Fehlalarm)'); - } + if ($report->isFalseAlarm()) { + $art = (empty($art) ? 'Fehlalarm' : $art . ' (Fehlalarm)'); + } - $einsatzort = $report->getLocation(); - $einsatzleiter = $report->getIncidentCommander(); - $mannschaft = $report->getWorkforce(); - - $vehicles = $this->formatter->getVehicles($report, $mayContainLinks, $showArchiveLinks); - $units = $this->formatter->getUnits($report); - $additionalForces = $this->formatter->getAdditionalForces($report, $mayContainLinks, $showArchiveLinks); - - $timeOfAlerting = $report->getTimeOfAlerting(); - $datumsformat = get_option('date_format', 'd.m.Y'); - $zeitformat = get_option('time_format', 'H:i'); - $einsatz_datum = ($timeOfAlerting ? date_i18n($datumsformat, $timeOfAlerting->getTimestamp()) : '-'); - $einsatz_zeit = ($timeOfAlerting ? date_i18n($zeitformat, $timeOfAlerting->getTimestamp()).' Uhr' : '-'); - - $headerstring = "Datum: ".$einsatz_datum." 
    "; - $headerstring .= "Alarmzeit: ".$einsatz_zeit." 
    "; - $headerstring .= $this->getDetailString('Alarmierungsart:', $typesOfAlerting); - $headerstring .= $this->getDetailString('Dauer:', $durationString); - $headerstring .= $this->getDetailString('Art:', $art); - $headerstring .= $this->getDetailString('Einsatzort:', $einsatzort); - $headerstring .= $this->getDetailString('Einsatzleiter:', $einsatzleiter); - $headerstring .= $this->getDetailString('Mannschaftsstärke:', $mannschaft); - $headerstring .= $this->getDetailString('Fahrzeuge:', $vehicles); - $headerstring .= $this->getDetailString('Einheiten:', $units); - $headerstring .= $this->getDetailString('Weitere Kräfte:', $additionalForces); - - return "

    $headerstring

    "; + $timeOfAlerting = $report->getTimeOfAlerting(); + $dateAndTime = empty($timeOfAlerting) ? '-' : sprintf( + /* translators: 1: Date, 2: Time. */ + __('%1$s at %2$s', 'einsatzverwaltung'), + date_i18n(get_option('date_format'), $timeOfAlerting->getTimestamp()), + date_i18n(get_option('time_format'), $timeOfAlerting->getTimestamp()) + ); + $headerstring = $this->getDetailString(__('Date', 'einsatzverwaltung'), $dateAndTime); + + $headerstring .= $this->getDetailString('Alarmierungsart', $this->formatter->getTypesOfAlerting($report)); + $headerstring .= $this->getDetailString(__('Duration', 'einsatzverwaltung'), $durationString); + $headerstring .= $this->getDetailString(__('Incident Category', 'einsatzverwaltung'), $art); + $headerstring .= $this->getDetailString(__('Location', 'einsatzverwaltung'), $report->getLocation()); + $headerstring .= $this->getDetailString('Einsatzleiter', $report->getIncidentCommander()); + $headerstring .= $this->getDetailString('Mannschaftsstärke', $report->getWorkforce()); + + // If at least one unit has been assigned to any report, show the vehicles grouped by unit + if (Unit::isActivelyUsed()) { + $headerstring .= $this->getDetailString( + __('Vehicles', 'einsatzverwaltung'), + $this->formatter->getVehiclesByUnitString($report->getVehiclesByUnit()), + false + ); + } else { + $headerstring .= $this->getDetailString( + __('Vehicles', 'einsatzverwaltung'), + $this->formatter->getVehicleString($report->getVehicles(), $mayContainLinks, $showArchiveLinks) + ); } - return ""; + + $additionalForces = $this->formatter->getAdditionalForces($report, $mayContainLinks, $showArchiveLinks); + $headerstring .= $this->getDetailString('Weitere Kräfte', $additionalForces); + + return "

    $headerstring

    "; } @@ -139,13 +150,20 @@ public function getEinsatzberichtHeader($post, $mayContainLinks = true, $showArc * * @return string Formatiertes Einsatzdetail */ - private function getDetailString($title, $value, $newline = true) + private function getDetailString(string $title, string $value, bool $newline = true): string { if ($this->options->isHideEmptyDetails() && (!isset($value) || $value === '')) { return ''; } - return ''.$title.' '.$value.($newline ? ' 
    ' : ' '); + /* translators: Single incident detail, 1: Label, 2: Value */ + $format = __('%1$s: %2$s', 'einsatzverwaltung'); + $filteredFormat = wp_kses($format, ['b' => []]); + if ($newline) { + $filteredFormat .= '
    '; + } + + return sprintf($filteredFormat, $title, $value); } @@ -156,7 +174,7 @@ private function getDetailString($title, $value, $newline = true) * * @return string Mit Einsatzdetails angereicherter Beitragstext */ - public function renderContent($content) + public function renderContent(string $content): string { global $post; @@ -177,7 +195,7 @@ public function renderContent($content) $content = sprintf('

    %s

    ', esc_html($replacementText)); } - $templateWithData = $this->formatter->formatIncidentData($template, array(), $post, 'post'); + $templateWithData = $this->formatter->formatIncidentData($template, array(), $post); $templateWithContent = str_replace('%content%', $content, $templateWithData); return stripslashes(wp_filter_post_kses(addslashes($templateWithContent))); } @@ -187,7 +205,7 @@ public function renderContent($content) } // Fallback auf das klassische Layout - $header = $this->getEinsatzberichtHeader($post, true, true); + $header = $this->getEinsatzberichtHeader($post); $content = $this->prepareContent($content); return $header . '
    ' . $content; @@ -198,7 +216,7 @@ public function renderContent($content) * * @return bool */ - private function useReportTemplate() + private function useReportTemplate(): bool { $useTemplate = get_option('einsatzverwaltung_use_reporttemplate', 'no'); @@ -229,7 +247,7 @@ private function useReportTemplate() * @return string Der Beitragstext mit einer vorangestellten Überschrift. Wenn der Beitragstext leer ist, wird ein * Ersatztext zurückgegeben */ - private function prepareContent($content) + private function prepareContent(string $content): string { $replacementText = get_option('einsatzverwaltung_report_contentifempty', ''); if (!empty($replacementText)) { @@ -249,7 +267,7 @@ private function prepareContent($content) * * @return string Der Auszug */ - public function filterEinsatzExcerpt($excerpt) + public function filterEinsatzExcerpt(string $excerpt): string { global $post; if (get_post_type() !== 'einsatz') { @@ -275,7 +293,7 @@ public function filterEinsatzExcerpt($excerpt) * * @param WP_Query $query */ - public function addReportsToQuery($query) + public function addReportsToQuery(WP_Query $query) { // Nur, wenn Filter erlaubt sind, soll weitergemacht werden if (!empty($query->query_vars['suppress_filters'])) { diff --git a/src/Frontend/AnnotationIconBar.php b/src/Frontend/AnnotationIconBar.php index 8bd3b4a1..e1ecec9e 100644 --- a/src/Frontend/AnnotationIconBar.php +++ b/src/Frontend/AnnotationIconBar.php @@ -1,7 +1,6 @@ getAnnotationIcon( $icon, array($annotation->getLabelWhenInactive(), $annotation->getLabelWhenActive()), - $annotation->getStateForReport($report) + $annotation->getStateForReport($postId) ); } return $string; @@ -105,7 +104,7 @@ public function render($report, $annotationIds = array()) * * @return string */ - private function getAnnotationIcon($icon, $titles, $state) + private function getAnnotationIcon($icon, $titles, $state): string { return sprintf( '', @@ -118,7 +117,7 @@ private function getAnnotationIcon($icon, $titles, $state) /** * @return string */ - private function getAnnotationColorOff() + private function getAnnotationColorOff(): string { if (is_admin()) { return self::DEFAULT_COLOR_OFF; diff --git a/src/Frontend/ReportList/Column.php b/src/Frontend/ReportList/Column.php index b0843da5..c34f1127 100644 --- a/src/Frontend/ReportList/Column.php +++ b/src/Frontend/ReportList/Column.php @@ -54,7 +54,7 @@ public function __construct($identifier, $name, $longName = '', $noWrap = false) /** * @return string */ - public function getIdentifier() + public function getIdentifier(): string { return $this->identifier; } @@ -62,7 +62,7 @@ public function getIdentifier() /** * @return string */ - public function getName() + public function getName(): string { return $this->name; } @@ -70,7 +70,7 @@ public function getName() /** * @return string */ - public function getNameForSettings() + public function getNameForSettings(): string { if (empty($this->longName)) { return $this->name; @@ -82,7 +82,7 @@ public function getNameForSettings() /** * @return bool */ - public function isNoWrap() + public function isNoWrap(): bool { return $this->noWrap; } diff --git a/src/Frontend/ReportList/ColumnRepository.php b/src/Frontend/ReportList/ColumnRepository.php index b454ca39..20f3b901 100644 --- a/src/Frontend/ReportList/ColumnRepository.php +++ b/src/Frontend/ReportList/ColumnRepository.php @@ -59,7 +59,7 @@ private function addColumn(Column $column) /** * @return Column[] */ - public function getAvailableColumns() + public function getAvailableColumns(): array { return $this->columns; } @@ -69,7 +69,7 @@ public function getAvailableColumns() * * @return Column|null */ - public function getColumn($identifier) + public function getColumn($identifier): ?Column { if (!$this->hasColumn($identifier)) { return null; @@ -83,7 +83,7 @@ public function getColumn($identifier) * * @return Column[] */ - public function getColumnsByIdentifier($identifiers) + public function getColumnsByIdentifier($identifiers): array { $columns = array(); foreach ($identifiers as $identifier) { @@ -97,7 +97,7 @@ public function getColumnsByIdentifier($identifiers) /** * @return Column[] */ - public function getDefaultColumns() + public function getDefaultColumns(): array { return $this->getColumnsByIdentifier(explode(',', self::DEFAULT_COLUMNS)); } @@ -107,7 +107,7 @@ public function getDefaultColumns() * * @return string */ - public function getIdentifiers($columns) + public function getIdentifiers($columns): string { $columnIds = array_map(function (Column $column) { return $column->getIdentifier(); @@ -119,7 +119,7 @@ public function getIdentifiers($columns) /** * @return ColumnRepository */ - public static function getInstance() + public static function getInstance(): ColumnRepository { if (empty(self::$instance)) { self::$instance = new self(); @@ -133,7 +133,7 @@ public static function getInstance() * * @return bool */ - public function hasColumn($identifier) + public function hasColumn($identifier): bool { return array_key_exists($identifier, $this->columns); } @@ -146,7 +146,7 @@ public function hasColumn($identifier) * @return string Der Eingabestring ohne ungültige Spalten-Ids, bei Problemen werden die Standardspalten * zurückgegeben */ - public static function sanitizeColumns($input) + public static function sanitizeColumns($input): string { if (empty($input)) { return self::DEFAULT_COLUMNS; @@ -166,7 +166,7 @@ public static function sanitizeColumns($input) * * @return string[] */ - public static function sanitizeColumnsArray($inputArray) + public static function sanitizeColumnsArray($inputArray): array { $validColumnIds = self::sanitizeColumnsArrayNoDefault($inputArray); @@ -184,7 +184,7 @@ public static function sanitizeColumnsArray($inputArray) * * @return string[] */ - public static function sanitizeColumnsArrayNoDefault($inputArray) + public static function sanitizeColumnsArrayNoDefault($inputArray): array { $columnRepository = self::getInstance(); diff --git a/src/Frontend/ReportList/Renderer.php b/src/Frontend/ReportList/Renderer.php index c8bf6a15..64ddada9 100644 --- a/src/Frontend/ReportList/Renderer.php +++ b/src/Frontend/ReportList/Renderer.php @@ -143,7 +143,7 @@ private function constructList($reports, Parameters $parameters) * * @return string HTML-Code der Liste */ - public function getList($reports, Parameters $parameters) + public function getList($reports, Parameters $parameters): string { $this->string = ''; $this->constructList($reports, $parameters); @@ -232,7 +232,7 @@ private function insertRow($report, Parameters $parameters) * * @return string HTML markup for the table cell only visible on devices with a small screen (e.g. smartphones) */ - private function getSmallScreenCell(IncidentReport $report, Parameters $parameters) + private function getSmallScreenCell(IncidentReport $report, Parameters $parameters): string { $content = ''; $annotations = ''; @@ -273,7 +273,7 @@ private function getSmallScreenCell(IncidentReport $report, Parameters $paramete * * @return string */ - private function getCellMarkup(IncidentReport $report, Parameters $parameters, $columnId) + private function getCellMarkup(IncidentReport $report, Parameters $parameters, $columnId): string { $cellContent = $this->getCellContent($report, $columnId, $parameters); @@ -297,7 +297,7 @@ private function getCellMarkup(IncidentReport $report, Parameters $parameters, $ * * @return bool */ - private function isCellLinkToReport(IncidentReport $report, $columnId, Parameters $parameters) + private function isCellLinkToReport(IncidentReport $report, $columnId, Parameters $parameters): bool { $linkToReport = $parameters->linkEmptyReports || $report->hasContent(); $columnsLinkingReport = $parameters->getColumnsLinkingReport(); @@ -325,7 +325,7 @@ private function insertZebraCorrection($numberOfColumns) * * @return string */ - private function getCellContent($report, $colId, Parameters $parameters) + private function getCellContent($report, $colId, Parameters $parameters): string { if (empty($report)) { return ' '; @@ -364,7 +364,7 @@ private function getCellContent($report, $colId, Parameters $parameters) $cellContent = $this->formatter->getDurationString($minutes, true); break; case 'vehicles': - $cellContent = $this->formatter->getVehicles($report, $parameters->linkVehicles, false); + $cellContent = $this->formatter->getVehicleString($report->getVehicles(), $parameters->linkVehicles, false); break; case 'alarmType': $cellContent = $this->formatter->getTypesOfAlerting($report); @@ -388,10 +388,10 @@ private function getCellContent($report, $colId, Parameters $parameters) } break; case 'annotationImages': - $cellContent = AnnotationIconBar::getInstance()->render($report, array('images')); + $cellContent = AnnotationIconBar::getInstance()->render($report->getPostId(), array('images')); break; case 'annotationSpecial': - $cellContent = AnnotationIconBar::getInstance()->render($report, array('special')); + $cellContent = AnnotationIconBar::getInstance()->render($report->getPostId(), array('special')); break; default: $cellContent = ''; @@ -477,7 +477,7 @@ private function insertSplit(Parameters $parameters, $class, $heading) * * @return string */ - public static function getDynamicCss() + public static function getDynamicCss(): string { if (empty(self::$settings)) { self::$settings = new Settings(); diff --git a/src/Frontend/ReportList/Settings.php b/src/Frontend/ReportList/Settings.php index 67baa159..3373827a 100644 --- a/src/Frontend/ReportList/Settings.php +++ b/src/Frontend/ReportList/Settings.php @@ -17,7 +17,7 @@ class Settings * * @return string */ - public function getZebraColor() + public function getZebraColor(): string { $option = get_option('einsatzvw_list_zebracolor', self::DEFAULT_ZEBRACOLOR); $sanitized = sanitize_hex_color($option); @@ -33,7 +33,7 @@ public function getZebraColor() * * @return string */ - public function getZebraNthChildArg() + public function getZebraNthChildArg(): string { $option = get_option('einsatzvw_list_zebra_nth', self::DEFAULT_NTHCHILD); return $this->sanitizeZebraNthChildArg($option); @@ -44,7 +44,7 @@ public function getZebraNthChildArg() * * @return boolean */ - public function isZebraTable() + public function isZebraTable(): bool { return (get_option('einsatzvw_list_zebra', '1') !== '0'); } @@ -56,7 +56,7 @@ public function isZebraTable() * * @return string */ - public function sanitizeZebraNthChildArg($input) + public function sanitizeZebraNthChildArg($input): string { if (!in_array($input, array('odd', 'even'))) { return self::DEFAULT_NTHCHILD; diff --git a/src/Loader.php b/src/Loader.php index 048036a4..528226b8 100644 --- a/src/Loader.php +++ b/src/Loader.php @@ -19,7 +19,7 @@ class Loader * * @param string $class The fully-qualified name of the class to load */ - public static function load($class) + public static function load(string $class) { // Do not load classes from other namespaces if (strpos($class, 'abrain\\Einsatzverwaltung') === false) { diff --git a/src/Model/IncidentReport.php b/src/Model/IncidentReport.php index 37c778da..54fba3d7 100644 --- a/src/Model/IncidentReport.php +++ b/src/Model/IncidentReport.php @@ -4,14 +4,20 @@ use abrain\Einsatzverwaltung\Types\Unit; use abrain\Einsatzverwaltung\Types\Vehicle; +use abrain\Einsatzverwaltung\Utilities; use DateTime; use WP_Post; use WP_Term; +use function array_key_exists; +use function array_keys; use function get_post; use function get_post_type; use function error_log; +use function get_the_terms; use function intval; use function is_numeric; +use function is_wp_error; +use function usort; /** * Datenmodellklasse für Einsatzberichte @@ -53,7 +59,7 @@ public function __construct($post = null) * * @return string Die Beschriftung oder $field, wenn es das Feld nicht gibt */ - public static function getFieldLabel($field) + public static function getFieldLabel($field): string { $fields = self::getFields(); return (array_key_exists($field, $fields) ? $fields[$field]['label'] : $field); @@ -63,7 +69,7 @@ public static function getFieldLabel($field) * Gibt ein Array aller Felder und deren Namen zurück, * Hauptverwendungszweck ist das Mapping beim Import */ - public static function getFields() + public static function getFields(): array { return array_merge(self::getMetaFields(), self::getTerms(), self::getPostFields()); } @@ -73,7 +79,7 @@ public static function getFields() * * @return array */ - public static function getMetaFields() + public static function getMetaFields(): array { return array( 'einsatz_einsatzort' => array( @@ -134,7 +140,7 @@ public function getDuration() * * @return array */ - public static function getTerms() + public static function getTerms(): array { return array( 'alarmierungsart' => array( @@ -157,7 +163,7 @@ public static function getTerms() * * @return array */ - public static function getPostFields() + public static function getPostFields(): array { return array( 'post_date' => array( @@ -175,7 +181,7 @@ public static function getPostFields() /** * @return array */ - public function getAdditionalForces() + public function getAdditionalForces(): array { return $this->getTheTerms('exteinsatzmittel'); } @@ -185,7 +191,7 @@ public function getAdditionalForces() * * @return string */ - public function getIncidentCommander() + public function getIncidentCommander(): string { return $this->getPostMeta('einsatz_einsatzleiter'); } @@ -195,7 +201,7 @@ public function getIncidentCommander() * * @return string */ - public function getLocation() + public function getLocation(): string { return $this->getPostMeta('einsatz_einsatzort'); } @@ -205,7 +211,7 @@ public function getLocation() * * @return string */ - public function getNumber() + public function getNumber(): string { return $this->getPostMeta('einsatz_incidentNumber'); } @@ -223,7 +229,7 @@ public function getPostId() * * @return string */ - private function getPostMeta($key) + private function getPostMeta($key): string { if (empty($this->post)) { return ''; @@ -241,9 +247,9 @@ private function getPostMeta($key) /** * Gibt die laufende Nummer des Einsatzberichts bezogen auf das Kalenderjahr zurück * - * @return mixed + * @return string */ - public function getSequentialNumber() + public function getSequentialNumber(): string { return $this->getPostMeta('einsatz_seqNum'); } @@ -290,7 +296,7 @@ private function getPostDate() * * @return string */ - public function getTimeOfEnding() + public function getTimeOfEnding(): string { return $this->getPostMeta('einsatz_einsatzende'); } @@ -298,9 +304,9 @@ public function getTimeOfEnding() /** * Gibt das Term-Objekt der Alarmierungsart zurück * - * @return array + * @return WP_Term[] */ - public function getTypesOfAlerting() + public function getTypesOfAlerting(): array { return $this->getTheTerms('alarmierungsart'); } @@ -313,7 +319,7 @@ public function getTypesOfAlerting() * * @return WP_Term[] Die Terms oder ein leeres Array */ - private function getTheTerms($taxonomy) + private function getTheTerms(string $taxonomy): array { if (empty($this->post)) { return array(); @@ -334,7 +340,7 @@ private function getTheTerms($taxonomy) * * @return WP_Term */ - public function getTypeOfIncident() + public function getTypeOfIncident(): ?WP_Term { $terms = $this->getTheTerms('einsatzart'); @@ -351,7 +357,9 @@ public function getTypeOfIncident() */ public function getUnits(): array { - return $this->getTheTerms(Unit::getSlug()); + $units = $this->getTheTerms(Unit::getSlug()); + usort($units, array(Unit::class, 'compare')); + return $units; } /** @@ -359,9 +367,9 @@ public function getUnits(): array * * @return WP_Term[] */ - public function getVehicles() + public function getVehicles(): array { - $vehicles = $this->getTheTerms('fahrzeug'); + $vehicles = $this->getTheTerms(Vehicle::getSlug()); if (empty($vehicles)) { return array(); @@ -372,10 +380,20 @@ public function getVehicles() return $vehicles; } + public function getVehiclesByUnit(): array + { + $vehicles = $this->getTheTerms(Vehicle::getSlug()); + if (empty($vehicles)) { + return []; + } + + return Utilities::groupVehiclesByUnit($vehicles); + } + /** * @return int The weight of the report (i. e. how many reports it represents) */ - public function getWeight() + public function getWeight(): int { $weight = $this->getPostMeta('einsatz_weight'); if (empty($weight) || !is_numeric($weight)) { @@ -390,7 +408,7 @@ public function getWeight() * * @return string */ - public function getWorkforce() + public function getWorkforce(): string { return $this->getPostMeta('einsatz_mannschaft'); } @@ -400,7 +418,7 @@ public function getWorkforce() * * @return bool */ - public function hasContent() + public function hasContent(): bool { return !empty($this->post->post_content); } @@ -410,7 +428,7 @@ public function hasContent() * * @return bool */ - public function hasImages() + public function hasImages(): bool { return ($this->getPostMeta('einsatz_hasimages') == 1); } @@ -420,7 +438,7 @@ public function hasImages() * * @return bool */ - public function isDraft() + public function isDraft(): bool { return in_array($this->post->post_status, array('draft', 'pending', 'auto-draft')); } @@ -430,7 +448,7 @@ public function isDraft() * * @return bool */ - public function isFalseAlarm() + public function isFalseAlarm(): bool { return ($this->getPostMeta('einsatz_fehlalarm') == 1); } @@ -440,7 +458,7 @@ public function isFalseAlarm() * * @return bool */ - public function isSpecial() + public function isSpecial(): bool { return ($this->getPostMeta('einsatz_special') == 1); } @@ -450,7 +468,7 @@ public function isSpecial() * * @return bool */ - private function isFuture() + private function isFuture(): bool { return $this->post->post_status === 'future'; } @@ -460,7 +478,7 @@ private function isFuture() * * @param int $category Die ID der Kategorie */ - public function addToCategory($category) + public function addToCategory(int $category) { wp_set_post_categories($this->getPostId(), $category, true); } diff --git a/src/Model/ReportAnnotation.php b/src/Model/ReportAnnotation.php index 1117cfe1..72250597 100644 --- a/src/Model/ReportAnnotation.php +++ b/src/Model/ReportAnnotation.php @@ -69,7 +69,7 @@ public function __construct($identifier, $name, $metaKey, $icon, $labelWhenActiv /** * @return string */ - public function getIcon() + public function getIcon(): string { return $this->icon; } @@ -77,7 +77,7 @@ public function getIcon() /** * @return string */ - public function getIdentifier() + public function getIdentifier(): string { return $this->identifier; } @@ -85,7 +85,7 @@ public function getIdentifier() /** * @return string */ - public function getLabelWhenActive() + public function getLabelWhenActive(): string { return $this->labelWhenActive; } @@ -93,7 +93,7 @@ public function getLabelWhenActive() /** * @return string */ - public function getLabelWhenInactive() + public function getLabelWhenInactive(): string { return $this->labelWhenInactive; } @@ -101,19 +101,19 @@ public function getLabelWhenInactive() /** * @return string */ - public function getName() + public function getName(): string { return $this->name; } /** - * @param IncidentReport $report + * @param int $postId * * @return bool */ - public function getStateForReport($report) + public function getStateForReport(int $postId): bool { - $get_post_meta = get_post_meta($report->getPostId(), $this->metaKey, true); + $get_post_meta = get_post_meta($postId, $this->metaKey, true); return 1 == $get_post_meta; } } diff --git a/src/Options.php b/src/Options.php index edc383f5..b6001147 100644 --- a/src/Options.php +++ b/src/Options.php @@ -27,7 +27,7 @@ class Options * * @return mixed */ - public function getOption($key) + public function getOption(string $key) { if (array_key_exists($key, $this->defaults)) { return get_option($key, $this->defaults[$key]); @@ -46,7 +46,7 @@ public function getOption($key) * * @return bool */ - public function getBoolOption($key) + public function getBoolOption(string $key): bool { $option = $this->getOption($key); return $this->toBoolean($option); @@ -59,7 +59,7 @@ public function getBoolOption($key) * * @return int Die ID der Kategorie oder -1, wenn nicht gesetzt */ - public function getEinsatzberichteCategory() + public function getEinsatzberichteCategory(): int { $categoryId = $this->getOption('einsatzvw_category'); return (false === $categoryId ? -1 : intval($categoryId)); @@ -70,7 +70,7 @@ public function getEinsatzberichteCategory() * * @return bool */ - public function isFlushRewriteRules() + public function isFlushRewriteRules(): bool { return $this->getBoolOption('einsatzvw_flush_rewrite_rules'); } @@ -80,7 +80,7 @@ public function isFlushRewriteRules() * * @return bool */ - public function isHideEmptyDetails() + public function isHideEmptyDetails(): bool { $option = $this->getOption('einsatzvw_einsatz_hideemptydetails'); return $this->toBoolean($option); @@ -92,7 +92,7 @@ public function isHideEmptyDetails() * * @return bool */ - public function isOnlySpecialInLoop() + public function isOnlySpecialInLoop(): bool { return $this->getBoolOption('einsatzvw_loop_only_special'); } @@ -101,7 +101,7 @@ public function isOnlySpecialInLoop() /** * @return bool */ - public function isOpenExtEinsatzmittelNewWindow() + public function isOpenExtEinsatzmittelNewWindow(): bool { $option = $this->getOption('einsatzvw_open_ext_in_new'); return $this->toBoolean($option); @@ -110,7 +110,7 @@ public function isOpenExtEinsatzmittelNewWindow() /** * @return bool */ - public function isShowEinsatzartArchive() + public function isShowEinsatzartArchive(): bool { $option = $this->getOption('einsatzvw_show_einsatzart_archive'); return $this->toBoolean($option); @@ -119,7 +119,7 @@ public function isShowEinsatzartArchive() /** * @return bool */ - public function isShowReportsInLoop() + public function isShowReportsInLoop(): bool { $option = $this->getOption('einsatzvw_show_einsatzberichte_mainloop'); return $this->toBoolean($option); @@ -128,7 +128,7 @@ public function isShowReportsInLoop() /** * @return bool */ - public function isShowExtEinsatzmittelArchive() + public function isShowExtEinsatzmittelArchive(): bool { $option = $this->getOption('einsatzvw_show_exteinsatzmittel_archive'); return $this->toBoolean($option); @@ -137,18 +137,19 @@ public function isShowExtEinsatzmittelArchive() /** * @return bool */ - public function isShowFahrzeugArchive() + public function isShowFahrzeugArchive(): bool { $option = $this->getOption('einsatzvw_show_fahrzeug_archive'); return $this->toBoolean($option); } /** + * @param bool $value + * * @since 1.0.0 * - * @param bool $value */ - public function setFlushRewriteRules($value) + public function setFlushRewriteRules(bool $value) { update_option('einsatzvw_flush_rewrite_rules', $value ? 1 : 0); } @@ -158,7 +159,7 @@ public function setFlushRewriteRules($value) * * @return bool */ - private function toBoolean($value) + private function toBoolean($value): bool { return in_array($value, array(1, true, '1', 'yes', 'on'), true); } diff --git a/src/PermalinkController.php b/src/PermalinkController.php index 13712aa0..d7ac5487 100644 --- a/src/PermalinkController.php +++ b/src/PermalinkController.php @@ -67,7 +67,7 @@ public function addRewriteRules(Report $report) * * @return string */ - public function buildSelector(WP_Post $post, $structure) + public function buildSelector(WP_Post $post, string $structure): string { $tagReplacements = array( $post->post_name, @@ -80,7 +80,7 @@ public function buildSelector(WP_Post $post, $structure) /** * @param WP_Query $query */ - public function einsatznummerMetaQuery($query) + public function einsatznummerMetaQuery(WP_Query $query) { $enr = $query->get('einsatznummer'); if (!empty($enr)) { @@ -98,7 +98,7 @@ public function einsatznummerMetaQuery($query) * * @return string */ - public function filterPostTypeLink($postLink, WP_Post $post, $leavename, $sample) + public function filterPostTypeLink(string $postLink, WP_Post $post, bool $leavename, bool $sample): string { global $wp_rewrite; @@ -126,9 +126,9 @@ public function filterPostTypeLink($postLink, WP_Post $post, $leavename, $sample * * @param array $queryvars * - * @return mixed + * @return array */ - public function filterRequest($queryvars) + public function filterRequest(array $queryvars): array { global $wp_rewrite; @@ -143,7 +143,7 @@ public function filterRequest($queryvars) /** * @return string */ - public function getRewriteBase() + private function getRewriteBase(): string { global $wp_rewrite; return ltrim($wp_rewrite->front, '/') . $this->reportRewriteSlug; @@ -156,7 +156,7 @@ public function getRewriteBase() * * @return string */ - public function getSelectorRegEx($permalink) + public function getSelectorRegEx(string $permalink): string { $regex = str_replace($this->rewriteTags, $this->rewriteTagRegEx, $permalink); return '/^' . str_replace('/', '\/', $regex) . '$/'; @@ -167,7 +167,7 @@ public function getSelectorRegEx($permalink) * * @return string */ - public function getPermalink($selector) + public function getPermalink(string $selector): string { $path = sprintf('%s/%s', $this->getRewriteBase(), $selector); return home_url(user_trailingslashit($path)); @@ -180,7 +180,7 @@ public function getPermalink($selector) * * @return string */ - public function getYearArchiveLink($year) + public function getYearArchiveLink(string $year): string { global $wp_rewrite; $link = get_post_type_archive_link(Report::getSlug()); @@ -196,7 +196,7 @@ public function getYearArchiveLink($year) * * @return array */ - public function modifyQueryVars($queryVars, $reportPermalink) + public function modifyQueryVars(array $queryVars, string $reportPermalink): array { // Do nothing, if the request is not about reports if (!array_key_exists('einsatz', $queryVars)) { @@ -235,7 +235,7 @@ public function modifyQueryVars($queryVars, $reportPermalink) * * @return string */ - public static function sanitizePermalink($permalink) + public static function sanitizePermalink(string $permalink): string { preg_match('/^(%[a-z_]+%)(-(%[a-z_]+%))*$/', $permalink, $matches); if (empty($matches)) { diff --git a/src/ReportAnnotationRepository.php b/src/ReportAnnotationRepository.php index 5b3f2179..7ffaef90 100644 --- a/src/ReportAnnotationRepository.php +++ b/src/ReportAnnotationRepository.php @@ -35,7 +35,7 @@ private function __construct() * * @return ReportAnnotationRepository */ - public static function getInstance() + public static function getInstance(): ReportAnnotationRepository { if (null === self::$instance) { self::$instance = new ReportAnnotationRepository(); @@ -55,7 +55,7 @@ public function addAnnotation(ReportAnnotation $annotation) /** * @return ReportAnnotation[] */ - public function getAnnotations() + public function getAnnotations(): array { return $this->annotations; } @@ -63,7 +63,7 @@ public function getAnnotations() /** * @return string[] */ - public function getAnnotationIdentifiers() + public function getAnnotationIdentifiers(): array { return array_keys($this->annotations); } diff --git a/src/ReportNumberController.php b/src/ReportNumberController.php index 66738b09..dff0e2eb 100644 --- a/src/ReportNumberController.php +++ b/src/ReportNumberController.php @@ -21,6 +21,7 @@ class ReportNumberController { const DEFAULT_SEQNUM_DIGITS = 3; + const DEFAULT_SEPARATOR = 'none'; /** * @var Data @@ -45,7 +46,7 @@ public function __construct(Data $data) * @param string $metaKey Der Key des postmeta-Eintrags * @param string $metaValue Der Wert des postmeta-Eintrags */ - public function onPostMetaChanged($metaId, $objectId, $metaKey, $metaValue) + public function onPostMetaChanged(int $metaId, int $objectId, string $metaKey, string $metaValue) { // Bail, if this is not about reports if (get_post_type($objectId) !== 'einsatz') { @@ -53,15 +54,15 @@ public function onPostMetaChanged($metaId, $objectId, $metaKey, $metaValue) } if ($metaKey === 'einsatz_seqNum' && self::isAutoIncidentNumbers()) { - $this->adjustIncidentNumber($objectId, $metaValue); + $this->adjustIncidentNumber($objectId, (int)$metaValue); } } /** * @param int $postId - * @param string $sequenceNumber + * @param int $sequenceNumber */ - private function adjustIncidentNumber($postId, $sequenceNumber) + private function adjustIncidentNumber(int $postId, int $sequenceNumber) { $date = date_create(get_post_field('post_date', $postId)); $newIncidentNumber = $this->formatEinsatznummer(date_format($date, 'Y'), $sequenceNumber); @@ -76,18 +77,35 @@ private function adjustIncidentNumber($postId, $sequenceNumber) * * @return string Formatierte Einsatznummer */ - private function formatEinsatznummer($jahr, $nummer) + public function formatEinsatznummer(string $jahr, int $nummer): string { - $stellen = self::sanitizeEinsatznummerStellen(get_option('einsatzvw_einsatznummer_stellen')); - $lfdvorne = (get_option('einsatzvw_einsatznummer_lfdvorne', false) == '1'); - $format = $lfdvorne ? '%2$s%1$s' : '%1$s%2$s'; - return sprintf($format, $jahr, str_pad($nummer, $stellen, "0", STR_PAD_LEFT)); + $stellen = self::sanitizeNumberOfDigits(get_option('einsatzvw_einsatznummer_stellen')); + $sequentialFirst = (get_option('einsatzvw_einsatznummer_lfdvorne', false) == '1'); + + // Determine the separator + switch (self::sanitizeSeparator(get_option('einsatzvw_numbers_separator', self::DEFAULT_SEPARATOR))) { + case 'slash': + $separator = '/'; + break; + case 'hyphen': + $separator = '-'; + break; + default: + $separator = ''; + } + + return sprintf( + $sequentialFirst ? '%2$s%3$s%1$s' : '%1$s%3$s%2$s', + $jahr, + str_pad($nummer, $stellen, "0", STR_PAD_LEFT), + $separator + ); } /** * @return bool */ - public static function isAutoIncidentNumbers() + public static function isAutoIncidentNumbers(): bool { return (get_option('einsatzverwaltung_incidentnumbers_auto', '0') === '1'); } @@ -96,7 +114,7 @@ public static function isAutoIncidentNumbers() * @param string $option Name of the added option * @param mixed $value Value of the added option */ - public function onOptionAdded($option, $value) + public function onOptionAdded(string $option, $value) { if ($option === 'einsatzverwaltung_incidentnumbers_auto') { $this->maybeAutoIncidentNumbersChanged($option, '', $value); @@ -110,7 +128,7 @@ public function onOptionAdded($option, $value) * * @return int */ - public static function sanitizeEinsatznummerStellen($input) + public static function sanitizeNumberOfDigits($input): int { if (!is_numeric($input)) { return self::DEFAULT_SEQNUM_DIGITS; @@ -124,6 +142,22 @@ public static function sanitizeEinsatznummerStellen($input) return $val; } + /** + * Sanitizes the option value for the separator between year and sequential number. + * + * @param string $input + * + * @return string + */ + public static function sanitizeSeparator(string $input): string + { + if (in_array($input, ['none', 'slash', 'hyphen'])) { + return $input; + } + + return self::DEFAULT_SEPARATOR; + } + /** * Generiert für alle Einsatzberichte eine Einsatznummer gemäß dem aktuell konfigurierten Format. */ @@ -138,7 +172,7 @@ private function updateAllIncidentNumbers() $reports = $reportQuery->getReports(); foreach ($reports as $report) { - $newIncidentNumber = $this->formatEinsatznummer($year, $report->getSequentialNumber()); + $newIncidentNumber = $this->formatEinsatznummer($year, (int)$report->getSequentialNumber()); update_post_meta($report->getPostId(), 'einsatz_incidentNumber', $newIncidentNumber); } } @@ -149,10 +183,10 @@ private function updateAllIncidentNumbers() * aktualisiert werden müssen * * @param string $option Name der Option - * @param string $oldValue Der alte Wert - * @param string $newValue Der neue Wert + * @param mixed $oldValue Der alte Wert + * @param mixed $newValue Der neue Wert */ - public function maybeAutoIncidentNumbersChanged($option, $oldValue, $newValue) + public function maybeAutoIncidentNumbersChanged(string $option, $oldValue, $newValue) { // Wir sind nur an einer bestimmten Option interessiert if ('einsatzverwaltung_incidentnumbers_auto' != $option) { @@ -175,13 +209,18 @@ public function maybeAutoIncidentNumbersChanged($option, $oldValue, $newValue) * müssen * * @param string $option Name der Option - * @param string $oldValue Der alte Wert - * @param string $newValue Der neue Wert + * @param mixed $oldValue Der alte Wert + * @param mixed $newValue Der neue Wert */ - public function maybeIncidentNumberFormatChanged($option, $oldValue, $newValue) + public function maybeIncidentNumberFormatChanged(string $option, $oldValue, $newValue) { // Wir sind nur an bestimmten Optionen interessiert - if (!in_array($option, array('einsatzvw_einsatznummer_stellen', 'einsatzvw_einsatznummer_lfdvorne'))) { + $formatOptions = array( + 'einsatzvw_einsatznummer_stellen', + 'einsatzvw_einsatznummer_lfdvorne', + 'einsatzvw_numbers_separator' + ); + if (!in_array($option, $formatOptions)) { return; } diff --git a/src/Settings/MainPage.php b/src/Settings/MainPage.php index c8d0130b..4a375b4d 100644 --- a/src/Settings/MainPage.php +++ b/src/Settings/MainPage.php @@ -93,7 +93,7 @@ public function echoSettingsPage() } echo '
    '; - echo '

    Einstellungen › Einsatzverwaltung

    '; + echo sprintf('

    %s › Einsatzverwaltung

    ', __('Settings', 'einsatzverwaltung')); // Check if any page uses the same permalink as the archive $conflictingPage = $this->getConflictingPage(); @@ -154,7 +154,7 @@ public function echoSettingsPage() * * @return WP_Post|null */ - private function getConflictingPage() + private function getConflictingPage(): ?WP_Post { $reportArchiveUrl = get_post_type_archive_link(ReportType::getSlug()); @@ -171,7 +171,7 @@ private function getConflictingPage() /** * @return SubPage */ - private function getCurrentSubPage() + private function getCurrentSubPage(): SubPage { $flags = FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH; $tab = filter_input(INPUT_GET, 'tab', FILTER_SANITIZE_STRING, $flags); @@ -189,7 +189,7 @@ private function getCurrentSubPage() * * @return bool Returns true if the supplied sub page matches the currently displayed sub page */ - private function isCurrentSubPage(SubPage $subPage) + private function isCurrentSubPage(SubPage $subPage): bool { return $subPage === $this->getCurrentSubPage(); } diff --git a/src/Settings/Pages/About.php b/src/Settings/Pages/About.php index ce094422..541ae62e 100644 --- a/src/Settings/Pages/About.php +++ b/src/Settings/Pages/About.php @@ -18,12 +18,10 @@ public function __construct() public function addSettingsFields() { - return; } public function addSettingsSections() { - return; } /** @@ -64,13 +62,12 @@ public function echoStaticContent() /** * @inheritDoc */ - public function hasForm() + public function hasForm(): bool { return false; } public function registerSettings() { - return; } } diff --git a/src/Settings/Pages/Advanced.php b/src/Settings/Pages/Advanced.php index 60a32f6b..0305ec18 100644 --- a/src/Settings/Pages/Advanced.php +++ b/src/Settings/Pages/Advanced.php @@ -1,9 +1,11 @@ array( - 'label' => 'Beitragstitel mit angehängtem Zähler (Standard)' - ), - '%post_id%-%postname_nosuffix%' => array( - 'label' => 'Beitragsnummer und Beitragstitel ohne angehängten Zähler' - ) - ); + /** + * @var array[] + */ + private $permalinkOptions; + /** * @var PermalinkController */ @@ -35,6 +34,15 @@ public function __construct(PermalinkController $permalinkController) parent::__construct('advanced', __('Advanced', 'einsatzverwaltung')); $this->permalinkController = $permalinkController; + $this->permalinkOptions = [ + PermalinkController::DEFAULT_REPORT_PERMALINK => [ + 'label' => __('Title with counter', 'einsatzverwaltung') + ], + '%post_id%-%postname_nosuffix%' => [ + 'label' => __('ID + title without counter', 'einsatzverwaltung') + ] + ]; + add_filter('pre_update_option_einsatzvw_rewrite_slug', array($this, 'maybeRewriteSlugChanged'), 10, 2); } @@ -42,28 +50,28 @@ public function addSettingsFields() { add_settings_field( 'einsatzvw_permalinks_base', - 'Basis', + __('Base', 'einsatzverwaltung'), array($this, 'echoFieldBase'), $this->settingsApiPage, 'einsatzvw_settings_permalinks' ); add_settings_field( 'einsatzvw_permalinks_struct', - 'URL-Struktur für Einsatzberichte', + __('URL structure for reports', 'einsatzverwaltung'), array($this, 'echoFieldUrlStructure'), $this->settingsApiPage, 'einsatzvw_settings_permalinks' ); add_settings_field( 'einsatzvw_advreport_corefeatures', - 'Beitragsfunktionen', + __('Post features', 'einsatzverwaltung'), array($this, 'echoFieldCoreFeatures'), $this->settingsApiPage, 'einsatzvw_settings_advreport' ); add_settings_field( 'einsatzvw_advreport_gutenberg', - 'Gutenberg', + __('Block editor', 'einsatzverwaltung'), array($this, 'echoFieldGutenberg'), $this->settingsApiPage, 'einsatzvw_settings_advreport' @@ -91,7 +99,10 @@ function () { ); echo '

    '; } - echo '

    Eine Änderung der Permalinkstruktur hat zur Folge, dass bisherige Links auf Einsatzberichte nicht mehr funktionieren. Dem solltest du als Seitenbetreiber mit Weiterleitungen entgegenwirken.

    '; + printf( + "

    %s

    ", + esc_html__('Changing the permalink structure breaks existing links to reports and archives. In case you are setting up the plugin for the first time, this is not a problem. If you have been using the plugin for some time, you should redirect the broken URLs to the working ones.', 'einsatzverwaltung') + ); }, $this->settingsApiPage ); @@ -128,9 +139,18 @@ public function echoFieldBase() ); echo '

    '; printf( - 'Basis für Links zu Einsatzberichten, zum %s und zum %s.', - sprintf('%s', get_post_type_archive_link('einsatz'), 'Archiv'), - sprintf('%s', get_post_type_archive_feed_link('einsatz'), 'Feed') + /* translators: 1: archive, 2: feed */ + __('Base for links to single reports, the %s, and the %s.', 'einsatzverwaltung'), + sprintf( + '%s', + get_post_type_archive_link(\abrain\Einsatzverwaltung\Types\Report::getSlug()), + esc_html__('archive', 'einsatzverwaltung') + ), + sprintf( + '%s', + get_post_type_archive_feed_link(\abrain\Einsatzverwaltung\Types\Report::getSlug()), + esc_html__('feed', 'einsatzverwaltung') + ) ); echo '

    '; } @@ -147,7 +167,10 @@ public function echoFieldCoreFeatures() 'einsatz_support_posttag', __('Tags', 'einsatzverwaltung') ); - echo '

    Diese Funktionen, die du von Beiträgen kennst, können auch für Einsatzberichte aktiviert werden.

    '; + printf( + '

    %s

    ', + __('You can activate these features of Posts also for Incident Reports.', 'einsatzverwaltung') + ); echo ''; } @@ -178,29 +201,20 @@ public function echoFieldUrlStructure() ); printf( __('By default, WordPress uses the post name to build the URL. To ensure uniqueness across posts, the post name can have a number appended if there are other posts with the same title (e.g. %1$s, %2$s, %3$s, ...).', 'einsatzverwaltung'), - $sampleSlug, - "$sampleSlug-2", - "$sampleSlug-3" + esc_html($sampleSlug), + esc_html("$sampleSlug-2"), + esc_html("$sampleSlug-3") ); echo '

    '; } - /** - * @inheritDoc - */ - public function echoStaticContent() - { - echo '

    Die erweiterten Einstellungen können weitreichende Konsequenzen haben und sollten entsprechend nicht leichtfertig geändert werden.

    '; - return; - } - /** * @param WP_Post $post * @param string $permalinkStructure * * @return string */ - private function getSampleUrl(WP_Post $post, $permalinkStructure) + private function getSampleUrl(WP_Post $post, $permalinkStructure): string { $selector = $this->permalinkController->buildSelector($post, $permalinkStructure); return $this->permalinkController->getPermalink($selector); @@ -214,7 +228,7 @@ private function getSampleUrl(WP_Post $post, $permalinkStructure) * @param string $oldValue Der alte Wert * @return string Der zu speichernde Wert */ - public function maybeRewriteSlugChanged($newValue, $oldValue) + public function maybeRewriteSlugChanged($newValue, $oldValue): string { if ($newValue != $oldValue) { self::$options->setFlushRewriteRules(true); @@ -233,22 +247,22 @@ public function registerSettings() register_setting( 'einsatzvw_settings_advanced', 'einsatz_permalink', - array('\abrain\Einsatzverwaltung\PermalinkController', 'sanitizePermalink') + array(PermalinkController::class, 'sanitizePermalink') ); register_setting( 'einsatzvw_settings_advanced', 'einsatz_support_excerpt', - array('\abrain\Einsatzverwaltung\Utilities', 'sanitizeCheckbox') + array(Utilities::class, 'sanitizeCheckbox') ); register_setting( 'einsatzvw_settings_advanced', 'einsatz_support_posttag', - array('\abrain\Einsatzverwaltung\Utilities', 'sanitizeCheckbox') + array(Utilities::class, 'sanitizeCheckbox') ); register_setting( 'einsatzvw_settings_advanced', 'einsatz_disable_blockeditor', - array('\abrain\Einsatzverwaltung\Utilities', 'sanitizeCheckbox') + array(Utilities::class, 'sanitizeCheckbox') ); } } diff --git a/src/Settings/Pages/Capabilities.php b/src/Settings/Pages/Capabilities.php index ed2a45d7..12861d0b 100644 --- a/src/Settings/Pages/Capabilities.php +++ b/src/Settings/Pages/Capabilities.php @@ -1,7 +1,8 @@ isOnlySpecialInLoop(); foreach ($reports as $report) { if (!$onlySpecialInCategory || $report->isSpecial()) { - $report->addToCategory($newValue); + $report->addToCategory((int)$newValue); } } } @@ -143,7 +142,7 @@ public function maybeCategoryChanged($newValue, $oldValue) * * @return string Der zu speichernde Wert */ - public function maybeCategorySpecialChanged($newValue, $oldValue) + public function maybeCategorySpecialChanged(string $newValue, string $oldValue): string { // Nur Änderungen sind interessant if ($newValue == $oldValue) { @@ -187,7 +186,7 @@ public function registerSettings() register_setting( 'einsatzvw_settings_general', 'einsatzvw_show_einsatzberichte_mainloop', - array('\abrain\Einsatzverwaltung\Utilities', 'sanitizeCheckbox') + array(Utilities::class, 'sanitizeCheckbox') ); register_setting( 'einsatzvw_settings_general', @@ -197,7 +196,7 @@ public function registerSettings() register_setting( 'einsatzvw_settings_general', 'einsatzvw_loop_only_special', - array('\abrain\Einsatzverwaltung\Utilities', 'sanitizeCheckbox') + array(Utilities::class, 'sanitizeCheckbox') ); register_setting( 'einsatzvw_settings_general', diff --git a/src/Settings/Pages/Numbers.php b/src/Settings/Pages/Numbers.php index 9a131f27..e9493744 100644 --- a/src/Settings/Pages/Numbers.php +++ b/src/Settings/Pages/Numbers.php @@ -1,8 +1,11 @@ settingsApiPage, 'einsatzvw_settings_numbers' ); add_settings_field( - 'einsatzvw_einsatznummer_stellen', - 'Format der Einsatznummer', - array($this, 'echoFieldFormat'), + 'einsatzvw_einsatznummer_order', + __('Order', 'einsatzverwaltung'), + array($this, 'echoFieldOrder'), + $this->settingsApiPage, + 'einsatzvw_settings_numbers' + ); + add_settings_field( + 'einsatzvw_einsatznummer_digits', + __('Number of digits', 'einsatzverwaltung'), + array($this, 'echoFieldDigits'), + $this->settingsApiPage, + 'einsatzvw_settings_numbers' + ); + add_settings_field( + 'einsatzvw_einsatznummer_separator', + __('Separator', 'einsatzverwaltung'), + array($this, 'echoFieldSeparator'), $this->settingsApiPage, 'einsatzvw_settings_numbers' ); @@ -48,27 +65,54 @@ public function echoFieldAuto() { $this->echoSettingsCheckbox( 'einsatzverwaltung_incidentnumbers_auto', - 'Einsatznummern automatisch verwalten' + __('Generate incident numbers automatically', 'einsatzverwaltung') + ); + printf( + '

    %s

    ', + __('If deactivated, incident numbers can be maintained manually.', 'einsatzverwaltung') ); - echo '

    Ist diese Option aktiv, kann die Einsatznummer nicht mehr manuell geändert werden. Sie wird automatisch gemäß den nachfolgenden Regeln generiert und aktualisiert.

    '; } - /** - * - */ - public function echoFieldFormat() + public function echoFieldDigits() { echo '
    '; printf( - 'Jahreszahl + jahresbezogene, fortlaufende Nummer mit Stellen', + '', 'einsatzvw_einsatznummer_stellen', - ReportNumberController::sanitizeEinsatznummerStellen(get_option('einsatzvw_einsatznummer_stellen')) + esc_attr(ReportNumberController::sanitizeNumberOfDigits(get_option('einsatzvw_einsatznummer_stellen'))) + ); + echo '
    '; + printf( + '

    %s

    ', + __('The sequential number gets padded with leading zeros until it has this length.', 'einsatzverwaltung') + ); + } + + public function echoFieldOrder() + { + $this->echoSettingsCheckbox( + 'einsatzvw_einsatznummer_lfdvorne', + __('Put the sequential number first', 'einsatzverwaltung') + ); + printf( + '

    %s

    ', + __('By default, the year comes before the sequential number. Activate this option to reverse the order.', 'einsatzverwaltung') ); - echo '

    Beispiel für den fünften Einsatz in 2014:
    bei 2 Stellen: 201405
    bei 4 Stellen: 20140005


    '; - $this->echoSettingsCheckbox('einsatzvw_einsatznummer_lfdvorne', 'Laufende Nummer vor das Jahr stellen'); - - echo '

    Hinweis: Nach einer Änderung des Formats erhalten die bestehenden Einsatzberichte nur dann automatisch aktualisierte Nummern, wenn die Option Einsatznummern automatisch verwalten aktiviert ist.

    '; + } + + public function echoFieldSeparator() + { + echo '
    '; + $this->echoRadioButtons('einsatzvw_numbers_separator', [ + 'none' => ['label' => _x('None', 'number separator selection', 'einsatzverwaltung')], + 'slash' => ['label' => __('Slash', 'einsatzverwaltung'), 'code' => '/'], + 'hyphen' => ['label' => __('Hyphen', 'einsatzverwaltung'), 'code' => '-'], + ], ReportNumberController::DEFAULT_SEPARATOR); echo '
    '; + printf( + '

    %s

    ', + __('This character separates the year and the sequential number.', 'einsatzverwaltung') + ); } public function registerSettings() @@ -76,17 +120,22 @@ public function registerSettings() register_setting( 'einsatzvw_settings_numbers', 'einsatzverwaltung_incidentnumbers_auto', - array('\abrain\Einsatzverwaltung\Utilities', 'sanitizeCheckbox') + array(Utilities::class, 'sanitizeCheckbox') ); register_setting( 'einsatzvw_settings_numbers', 'einsatzvw_einsatznummer_stellen', - array('\abrain\Einsatzverwaltung\ReportNumberController', 'sanitizeEinsatznummerStellen') + array(ReportNumberController::class, 'sanitizeEinsatznummerStellen') ); register_setting( 'einsatzvw_settings_numbers', 'einsatzvw_einsatznummer_lfdvorne', - array('\abrain\Einsatzverwaltung\Utilities', 'sanitizeCheckbox') + array(Utilities::class, 'sanitizeCheckbox') + ); + register_setting( + 'einsatzvw_settings_numbers', + 'einsatzvw_numbers_separator', + array(ReportNumberController::class, 'sanitizeSeparator') ); } } diff --git a/src/Settings/Pages/Report.php b/src/Settings/Pages/Report.php index edda2009..23dc8b38 100644 --- a/src/Settings/Pages/Report.php +++ b/src/Settings/Pages/Report.php @@ -1,7 +1,8 @@ useReportTemplateOptions))) { return 'no'; @@ -262,7 +263,7 @@ public function sanitizeReportTemplateUsage($input) * @param string $input * @return string */ - public function sanitizeTemplate($input) + public function sanitizeTemplate($input): string { return stripslashes(wp_filter_post_kses(addslashes($input))); } diff --git a/src/Settings/Pages/ReportList.php b/src/Settings/Pages/ReportList.php index 34254767..01239da1 100644 --- a/src/Settings/Pages/ReportList.php +++ b/src/Settings/Pages/ReportList.php @@ -1,10 +1,11 @@ reportListSettings, 'sanitizeZebraNthChildArg') + [$this->reportListSettings, 'sanitizeZebraNthChildArg'] ); } } diff --git a/src/Settings/Pages/SubPage.php b/src/Settings/Pages/SubPage.php index 097dd466..77480c1f 100644 --- a/src/Settings/Pages/SubPage.php +++ b/src/Settings/Pages/SubPage.php @@ -4,6 +4,8 @@ use abrain\Einsatzverwaltung\Options; use abrain\Einsatzverwaltung\Settings\MainPage; +use function esc_html; +use function sprintf; /** * Base class for a sub page of the plugin settings @@ -54,7 +56,6 @@ abstract public function registerSettings(); */ public function beforeContent() { - return; } /** @@ -105,7 +106,11 @@ protected function echoRadioButtons($name, $options, $defaultValue) { $currentValue = get_option($name, $defaultValue); foreach ($options as $value => $option) { - $label = esc_html($option['label']); + if ($value === $defaultValue) { + $label = esc_html(sprintf(__('%s (default)', 'einsatzverwaltung'), $option['label'])); + } else { + $label = esc_html($option['label']); + } if (array_key_exists('code', $option) && !empty($option['code'])) { $label .= sprintf('%s', esc_html($option['code'])); } @@ -179,7 +184,6 @@ protected function echoSettingsInput($name, $value, $size = 20) */ public function echoStaticContent() { - return; } /** @@ -188,7 +192,7 @@ public function echoStaticContent() * * @return bool */ - public function hasForm() + public function hasForm(): bool { return true; } diff --git a/src/TypeRegistry.php b/src/TypeRegistry.php index 816a2f64..382b29bb 100644 --- a/src/TypeRegistry.php +++ b/src/TypeRegistry.php @@ -95,7 +95,7 @@ private function registerPostType(CustomPostType $customPostType) * * @throws TypeRegistrationException */ - private function registerTaxonomy(CustomTaxonomy $customTaxonomy, $postType) + private function registerTaxonomy(CustomTaxonomy $customTaxonomy, string $postType) { $slug = $customTaxonomy::getSlug(); if (get_taxonomy($slug) !== false) { diff --git a/src/Types/Report.php b/src/Types/Report.php index 96bc0870..51bb2e4a 100644 --- a/src/Types/Report.php +++ b/src/Types/Report.php @@ -4,6 +4,7 @@ use abrain\Einsatzverwaltung\CustomFieldsRepository; use abrain\Einsatzverwaltung\Model\ReportAnnotation; use abrain\Einsatzverwaltung\ReportAnnotationRepository; +use abrain\Einsatzverwaltung\Utilities; use function register_meta; /** @@ -221,7 +222,7 @@ private function registerPostMeta() 'type' => 'boolean', 'description' => 'Vermerk, ob es sich um einen Fehlalarm handelte.', 'single' => true, - 'sanitize_callback' => array('Utilities', 'sanitizeCheckbox'), + 'sanitize_callback' => array(Utilities::class, 'sanitizeCheckbox'), 'show_in_rest' => false )); @@ -230,7 +231,7 @@ private function registerPostMeta() 'type' => 'boolean', 'description' => 'Vermerk, ob der Einsatzbericht Bilder enthält.', 'single' => true, - 'sanitize_callback' => array('Utilities', 'sanitizeCheckbox'), + 'sanitize_callback' => array(Utilities::class, 'sanitizeCheckbox'), 'show_in_rest' => false )); @@ -257,7 +258,7 @@ private function registerPostMeta() 'type' => 'boolean', 'description' => 'Vermerk, ob es sich um einen besonderen Einsatzbericht handelt.', 'single' => true, - 'sanitize_callback' => array('Utilities', 'sanitizeCheckbox'), + 'sanitize_callback' => array(Utilities::class, 'sanitizeCheckbox'), 'show_in_rest' => false )); diff --git a/src/Types/Unit.php b/src/Types/Unit.php index 6bc8e410..1d49cadd 100644 --- a/src/Types/Unit.php +++ b/src/Types/Unit.php @@ -1,6 +1,7 @@ term_id, 'unit_order', true); + $order2 = get_term_meta($unit2->term_id, 'unit_order', true); + + if (empty($order1) && !empty($order2)) { + return 1; + } + + if (!empty($order1) && empty($order2)) { + return -1; + } + + // If no order is set on both or if they are equal, sort by name + if (empty($order1) && empty($order2) || $order1 == $order2) { + return strcasecmp($unit1->name, $unit2->name); + } + + return ($order1 < $order2) ? -1 : 1; + } + /** * Retrieve the URL to more info about a given Unit. This can be a permalink to an internal page or an external URL. * @@ -118,6 +151,12 @@ public static function getSlug(): string return 'evw_unit'; } + public static function isActivelyUsed(): bool + { + $unitCount = get_terms(['taxonomy' => self::getSlug(), 'fields' => 'count']); + return is_numeric($unitCount) && $unitCount > 0; + } + /** * @inheritDoc */ @@ -134,6 +173,11 @@ public function registerCustomFields(CustomFieldsRepository $customFields) __('External URL', 'einsatzverwaltung'), __('You can specify a URL that points to more information about this unit. If set, this takes precedence over the page selected above.', 'einsatzverwaltung') )); + $customFields->add($this, new NumberInput( + 'unit_order', + 'Reihenfolge', + 'Optionale Angabe, mit der die Anzeigereihenfolge der Einheiten beeinflusst werden kann. Einheiten mit der kleineren Zahl werden zuerst angezeigt, anschließend diejenigen ohne Angabe bzw. dem Wert 0. Haben mehrere Einheiten den gleichen Wert, werden sie in alphabetischer Reihenfolge ausgegeben.' + )); } /** diff --git a/src/Types/Vehicle.php b/src/Types/Vehicle.php index f684cb52..7c8eb9c9 100644 --- a/src/Types/Vehicle.php +++ b/src/Types/Vehicle.php @@ -4,6 +4,7 @@ use abrain\Einsatzverwaltung\CustomFields\Checkbox; use abrain\Einsatzverwaltung\CustomFields\NumberInput; use abrain\Einsatzverwaltung\CustomFields\PostSelector; +use abrain\Einsatzverwaltung\CustomFields\UnitSelector; use abrain\Einsatzverwaltung\CustomFields\UrlInput; use WP_REST_Response; use WP_Term; @@ -113,6 +114,11 @@ public function getRewriteSlug(): string */ public function registerCustomFields(CustomFieldsRepository $customFields) { + $customFields->add($this, new UnitSelector( + 'vehicle_unit', + _x('Unit', 'taxonomy singular name', 'einsatzverwaltung'), + 'Falls du auf dieser Seite mehrere Einheiten (Abteilungen o.ä.) unterscheidest, kannst du hier das Fahrzeug einer davon zuordnen.' + )); $customFields->add($this, new PostSelector( 'fahrzeugpid', __('Page with further information', 'einsatzverwaltung'), diff --git a/src/Util/Formatter.php b/src/Util/Formatter.php index e1a923da..d2270bf5 100644 --- a/src/Util/Formatter.php +++ b/src/Util/Formatter.php @@ -16,6 +16,7 @@ use function esc_html; use function esc_url; use function get_permalink; +use function get_term; use function get_term_link; use function get_term_meta; use function get_the_post_thumbnail; @@ -53,6 +54,7 @@ class Formatter '%seqNum%' => 'Laufende Nummer', '%annotations%' => 'Vermerke', '%vehicles%' => 'Fahrzeuge', + '%vehiclesByUnit%' => 'Fahrzeuge, gruppiert nach Einheiten', '%additionalForces%' => 'Weitere Kräfte', '%typesOfAlerting%' => 'Alarmierungsarten', '%content%' => 'Berichtstext', @@ -95,12 +97,12 @@ public function __construct(Options $options, PermalinkController $permalinkCont /** * @param string $pattern * @param array $allowedTags - * @param WP_Post $post + * @param WP_Post|null $post * @param string $context * * @return mixed */ - public function formatIncidentData($pattern, $allowedTags = array(), $post = null, $context = 'post') + public function formatIncidentData(string $pattern, $allowedTags = array(), ?WP_Post $post = null, $context = 'post'): string { if (empty($allowedTags)) { $allowedTags = array_keys($this->availableTags); @@ -119,13 +121,14 @@ public function formatIncidentData($pattern, $allowedTags = array(), $post = nul } /** - * @param WP_Post $post + * @param WP_Post|null $post * @param string $pattern * @param string $tag * @param string $context + * * @return mixed|string */ - private function format($post, $pattern, $tag, $context = 'post') + private function format(?WP_Post $post, string $pattern, string $tag, $context = 'post'): string { if ($post == null && !in_array($tag, $this->tagsNotNeedingPost)) { return $pattern; @@ -166,7 +169,7 @@ private function format($post, $pattern, $tag, $context = 'post') $replace = $incidentReport->getIncidentCommander(); break; case '%incidentType%': - $replace = $this->getTypeOfIncidentString($incidentReport, $context, false); + $replace = $this->getTypeOfIncidentString($incidentReport, $context); break; case '%incidentTypeHierarchical%': $replace = $this->getTypeOfIncidentString($incidentReport, $context, true); @@ -195,10 +198,13 @@ private function format($post, $pattern, $tag, $context = 'post') } break; case '%annotations%': - $replace = $this->annotationIconBar->render($incidentReport); + $replace = $this->annotationIconBar->render($incidentReport->getPostId()); break; case '%vehicles%': - $replace = $this->getVehicles($incidentReport, ($context === 'post'), ($context === 'post')); + $replace = $this->getVehicleString($incidentReport->getVehicles(), ($context === 'post'), ($context === 'post')); + break; + case '%vehiclesByUnit%': + $replace = $this->getVehiclesByUnitString($incidentReport->getVehiclesByUnit()); break; case '%additionalForces%': $replace = $this->getAdditionalForces($incidentReport, ($context === 'post'), ($context === 'post')); @@ -237,7 +243,7 @@ private function format($post, $pattern, $tag, $context = 'post') * @param WP_Term|false $typeOfIncident * @return string */ - public function getColorOfTypeOfIncident($typeOfIncident) + public function getColorOfTypeOfIncident($typeOfIncident): string { if (empty($typeOfIncident)) { return 'inherit'; @@ -263,7 +269,7 @@ public function getColorOfTypeOfIncident($typeOfIncident) * * @return string */ - public function getTypesOfAlerting($report) + public function getTypesOfAlerting(IncidentReport $report): string { if (empty($report)) { return ''; @@ -292,7 +298,7 @@ public function getTypesOfAlerting($report) * * @return string */ - public static function getTypeOfIncident($report, $makeLinks, $showArchiveLinks, $showHierarchy = true) + public static function getTypeOfIncident(IncidentReport $report, bool $makeLinks, bool $showArchiveLinks, $showHierarchy = true): string { if (empty($report)) { return ''; @@ -331,7 +337,7 @@ public static function getTypeOfIncident($report, $makeLinks, $showArchiveLinks, * * @return string */ - private function getTypeOfIncidentString(IncidentReport $incidentReport, $context, $showHierarchy = false) + private function getTypeOfIncidentString(IncidentReport $incidentReport, string $context, $showHierarchy = false): string { $showTypeArchive = get_option('einsatzvw_show_einsatzart_archive') === '1'; return $this->getTypeOfIncident($incidentReport, ($context === 'post'), $showTypeArchive, $showHierarchy); @@ -347,49 +353,52 @@ public function getUnits(IncidentReport $report, $addLinks = false): string { $units = $report->getUnits(); - if (!$addLinks) { - // Only return the names - $unitNames = array_map(function (WP_Term $unit) { - return esc_html($unit->name); - }, $units); - return join(', ', $unitNames); + if ($addLinks) { + $linkedUnitNames = array_map([$this, 'getUnitNameWithLink'], $units); + return join(', ', $linkedUnitNames); } - // Return the names, linked to the respective info page if URL has been set - $linkedUnitNames = array_map(function (WP_Term $unit) { - $name = $unit->name; - - $infoUrl = Unit::getInfoUrl($unit); - if (empty($infoUrl)) { - return esc_html($name); - } - - return sprintf( - '%s', - esc_url($infoUrl), - esc_attr($name), - esc_html($name) - ); + // Only return the names + $unitNames = array_map(function (WP_Term $unit) { + return esc_html($unit->name); }, $units); - return join(', ', $linkedUnitNames); + return join(', ', $unitNames); } /** - * @param IncidentReport $report - * @param bool $makeLinks Fahrzeugname als Link zur Fahrzeugseite angeben, wenn diese eingetragen wurde - * @param bool $showArchiveLinks Generiere zusätzlichen Link zur Archivseite des Fahrzeugs + * Returns the name of a Unit, linked to the respective info page if URL has been set. + * + * @param WP_Term $unit * * @return string */ - public function getVehicles($report, $makeLinks, $showArchiveLinks) + private function getUnitNameWithLink(WP_Term $unit): string { - if (empty($report)) { - return ''; + $name = $unit->name; + + $infoUrl = Unit::getInfoUrl($unit); + if (empty($infoUrl)) { + return esc_html($name); } - $vehicles = $report->getVehicles(); + return sprintf( + '%s', + esc_url($infoUrl), + esc_attr($name), + esc_html($name) + ); + } + /** + * @param WP_Term[] $vehicles + * @param bool $makeLinks Fahrzeugname als Link zur Fahrzeugseite angeben, wenn diese eingetragen wurde + * @param bool $showArchiveLinks Generiere zusätzlichen Link zur Archivseite des Fahrzeugs + * + * @return string + */ + public function getVehicleString(array $vehicles, bool $makeLinks, bool $showArchiveLinks): string + { if (empty($vehicles)) { return ''; } @@ -411,11 +420,38 @@ public function getVehicles($report, $makeLinks, $showArchiveLinks) return join(", ", $names); } + public function getVehiclesByUnitString(array $vehiclesByUnitId): string + { + if (empty($vehiclesByUnitId)) { + return ''; + } + + $string = '
      '; + foreach ($vehiclesByUnitId as $unitId => $vehicles) { + if ($unitId === -1) { + $string .= sprintf( + '
    • %s
    • ', + $this->getVehicleString($vehicles, true, true) + ); + continue; + } + + $unit = get_term($unitId, Unit::getSlug()); + $string .= sprintf( + '
    • %s: %s
    • ', + $this->getUnitNameWithLink($unit), + $this->getVehicleString($vehicles, true, true) + ); + } + $string .= '
    '; + return $string; + } + /** * @param WP_Term $vehicle * @return string A link to the page associated with the vehicle (if any), otherwise the name without a link */ - private function addVehicleLink($vehicle) + private function addVehicleLink(WP_Term $vehicle): string { $url = $this->getUrlForVehicle($vehicle); if (empty($url)) { @@ -435,7 +471,7 @@ private function addVehicleLink($vehicle) * * @return string */ - private function getUrlForVehicle(WP_Term $vehicle) + private function getUrlForVehicle(WP_Term $vehicle): string { // The external URL takes precedence over an internal page $extUrl = get_term_meta($vehicle->term_id, 'vehicle_exturl', true); @@ -465,7 +501,7 @@ private function getUrlForVehicle(WP_Term $vehicle) * * @return string */ - public function getAdditionalForces($report, $makeLinks, $showArchiveLinks) + public function getAdditionalForces(IncidentReport $report, bool $makeLinks, bool $showArchiveLinks): string { if (empty($report)) { return ''; @@ -496,9 +532,10 @@ public function getAdditionalForces($report, $makeLinks, $showArchiveLinks) /** * @param WP_Term $additionalForce + * * @return string */ - private function getAdditionalForceLink($additionalForce) + private function getAdditionalForceLink(WP_Term $additionalForce): string { $url = get_term_meta($additionalForce->term_id, 'url', true); if (empty($url)) { @@ -517,9 +554,10 @@ private function getAdditionalForceLink($additionalForce) /** * @param WP_Term $term + * * @return string */ - private function getFilterLink(WP_Term $term) + private function getFilterLink(WP_Term $term): string { return sprintf( '', @@ -536,7 +574,7 @@ private function getFilterLink(WP_Term $term) * * @return string */ - public static function getDurationString($minutes, $abbreviated = false) + public static function getDurationString(int $minutes, $abbreviated = false): string { if (!is_numeric($minutes) || $minutes < 0) { return ''; @@ -560,9 +598,10 @@ public static function getDurationString($minutes, $abbreviated = false) /** * @param string $tag + * * @return string */ - public function getLabelForTag($tag) + public function getLabelForTag(string $tag): string { if (!array_key_exists($tag, $this->availableTags)) { return ''; diff --git a/src/Util/ProgressTracker.php b/src/Util/ProgressTracker.php index d6865740..265a7cfb 100644 --- a/src/Util/ProgressTracker.php +++ b/src/Util/ProgressTracker.php @@ -82,7 +82,7 @@ public function finish($message = '') /** * @return int */ - public function getPercentage() + public function getPercentage(): int { if ($this->totalSteps === 0) { return 0; diff --git a/src/Utilities.php b/src/Utilities.php index 48c1f016..1ed5964a 100644 --- a/src/Utilities.php +++ b/src/Utilities.php @@ -1,6 +1,16 @@ term_id, 'vehicle_unit', true); + if (empty($unitId)) { + $unitId = -1; + } + if (!array_key_exists($unitId, $grouped)) { + $grouped[$unitId] = []; + } + $grouped[$unitId][] = $vehicle; + } + + // Sort the units + $unitIds = array_keys($grouped); + /** @var WP_Term[] $units */ + $units = array_map('get_term', array_filter($unitIds, function ($unitId) { + return $unitId > 0; + })); + usort($units, array(Unit::class, 'compare')); + $groupedAndSorted = []; + foreach ($units as $unit) { + $groupedAndSorted[$unit->term_id] = $grouped[$unit->term_id]; + } + if (array_key_exists(-1, $grouped)) { + $groupedAndSorted[-1] = $grouped[-1]; + } + + // Sort the vehicles per unit + foreach ($unitIds as $unitId) { + usort($groupedAndSorted[$unitId], array(Vehicle::class, 'compareVehicles')); + } + + return $groupedAndSorted; + } + /** * Gibt eine Fehlermeldung aus * * @param string $message Meldung, die ausgegeben werden soll */ - public function printError($message) + public function printError(string $message) { echo '

    ' . $message . '

    '; } @@ -36,7 +90,7 @@ public function printError($message) * * @param string $message Meldung, die ausgegeben werden soll */ - public function printWarning($message) + public function printWarning(string $message) { echo '

    ' . $message . '

    '; } @@ -47,7 +101,7 @@ public function printWarning($message) * * @param string $message Meldung, die ausgegeben werden soll */ - public function printSuccess($message) + public function printSuccess(string $message) { echo '

    ' . $message . '

    '; } @@ -58,7 +112,7 @@ public function printSuccess($message) * * @param string $message Meldung, die ausgegeben werden soll */ - public function printInfo($message) + public function printInfo(string $message) { echo '

    ' . $message . '

    '; } @@ -69,7 +123,7 @@ public function printInfo($message) * @param int $postId Die ID des Einsatzberichts * @param int $category Die ID der Kategorie */ - public static function removePostFromCategory($postId, $category) + public static function removePostFromCategory(int $postId, int $category) { $categories = wp_get_post_categories($postId); $key = array_search($category, $categories); @@ -86,7 +140,7 @@ public static function removePostFromCategory($postId, $category) * * @return int 0 für false, 1 für true */ - public static function sanitizeCheckbox($value) + public static function sanitizeCheckbox($value): int { if (isset($value) && $value == "1") { return 1; diff --git a/src/Widgets/AbstractWidget.php b/src/Widgets/AbstractWidget.php index d83709a9..92a639f9 100644 --- a/src/Widgets/AbstractWidget.php +++ b/src/Widgets/AbstractWidget.php @@ -11,6 +11,22 @@ */ abstract class AbstractWidget extends WP_Widget { + /** + * @param array $instance + * @param string $fieldName + * @param string $label + */ + protected function echoCheckbox(array $instance, string $fieldName, string $label) + { + printf( + ' ', + esc_attr($this->get_field_id($fieldName)), + esc_attr($this->get_field_name($fieldName)), + checked($instance[$fieldName], 'on', false), + esc_html($label) + ); + } + /** * @param WP_Taxonomy $taxonomyObject * @param string $fieldName diff --git a/src/Widgets/RecentIncidents.php b/src/Widgets/RecentIncidents.php index c77f472d..67f43044 100644 --- a/src/Widgets/RecentIncidents.php +++ b/src/Widgets/RecentIncidents.php @@ -7,8 +7,13 @@ use abrain\Einsatzverwaltung\Types\Unit; use abrain\Einsatzverwaltung\Util\Formatter; use abrain\Einsatzverwaltung\Utilities; +use function array_merge; +use function checked; +use function esc_html; +use function esc_html__; use function get_queried_object_id; use function get_taxonomy; +use function printf; /** * WordPress-Widget für die letzten X Einsätze @@ -22,6 +27,11 @@ class RecentIncidents extends AbstractWidget */ private $formatter; + /** + * @var array + */ + private $defaults; + /** * Register widget with WordPress. * @@ -30,25 +40,19 @@ class RecentIncidents extends AbstractWidget public function __construct(Formatter $formatter) { parent::__construct( - 'einsatzverwaltung_widget', // Base ID - 'Letzte Einsätze', // Name - array( - 'description' => 'Zeigt die neuesten Einsätze an.', + 'einsatzverwaltung_widget', + __('Recent Incident Reports', 'einsatzverwaltung'), + [ + 'description' => __('The the most recent Incident Reports.', 'einsatzverwaltung'), 'customize_selective_refresh' => true, - ) // Args + ] ); $this->formatter = $formatter; - } - /** - * @inheritDoc - */ - public function widget($args, $instance) - { - $defaults = array( - 'title' => 'Letzte Einsätze', + $this->defaults = [ + 'title' => '', 'anzahl' => 3, - 'units' => array(), + 'units' => [], 'zeigeDatum' => false, 'zeigeZeit' => false, 'zeigeFeedlink' => false, @@ -56,14 +60,20 @@ public function widget($args, $instance) 'zeigeArt' => false, 'zeigeArtHierarchie' => false, 'showAnnotations' => false - ); - $instance = wp_parse_args($instance, $defaults); + ]; + } - $title = apply_filters('widget_title', $instance['title']); + /** + * @inheritDoc + */ + public function widget($args, $instance) + { + $instance = array_merge($this->defaults, $instance); + $title = empty($instance['title']) ? __('Recent incidents', 'einsatzverwaltung') : $instance['title']; echo $args['before_widget']; echo $args['before_title']; - echo esc_html($title); + echo esc_html(apply_filters('widget_title', $title)); echo $args['after_title']; $this->echoReports($instance); @@ -72,7 +82,7 @@ public function widget($args, $instance) printf( '

     %s

    ', get_post_type_archive_feed_link('einsatz'), - 'Einsatzberichte (Feed)' + esc_html__('Incident Reports feed', 'einsatzverwaltung') ); } echo $args['after_widget']; @@ -81,7 +91,7 @@ public function widget($args, $instance) /** * @param array $instance */ - private function echoReports($instance) + private function echoReports(array $instance) { $reportQuery = new ReportQuery(); $reportQuery->setOrderAsc(false); @@ -90,7 +100,7 @@ private function echoReports($instance) $reports = $reportQuery->getReports(); if (empty($reports)) { - echo '

    Keine Einsätze

    '; + echo sprintf("

    %s

    ", esc_html__('No reports', 'einsatzverwaltung')); return; } @@ -111,7 +121,7 @@ private function echoSingleReport(IncidentReport $report, $instance) { if (true === ($instance['showAnnotations'])) { $annotationIconBar = AnnotationIconBar::getInstance(); - printf('
    %s
    ', $annotationIconBar->render($report)); + printf('
    %s
    ', $annotationIconBar->render($report->getPostId())); } if (get_queried_object_id() === $report->getPostId()) { @@ -134,7 +144,7 @@ private function echoSingleReport(IncidentReport $report, $instance) ); if ($instance['zeigeZeit']) { printf( - ' | %s Uhr', + ' | %s', esc_html(date_i18n(get_option('time_format', 'H:i'), $timestamp)) ); } @@ -155,7 +165,11 @@ private function echoSingleReport(IncidentReport $report, $instance) if ($instance['zeigeOrt']) { $location = $report->getLocation(); if (!empty($location)) { - printf('
    Ort: %s', $location); + $locationFormat = sprintf( + '
    %s', + esc_html__('Location: %s', 'einsatzverwaltung') + ); + printf($locationFormat, esc_html($location)); } } } @@ -163,7 +177,7 @@ private function echoSingleReport(IncidentReport $report, $instance) /** * @inheritDoc */ - public function update($newInstance, $oldInstance) + public function update($newInstance, $oldInstance): array { $instance = array(); $instance['title'] = strip_tags($newInstance['title']); @@ -190,99 +204,58 @@ public function update($newInstance, $oldInstance) /** * @inheritDoc */ - public function form($instance) + public function form($instance): string { - $title = Utilities::getArrayValueIfKey($instance, 'title', 'Letzte Einsätze'); - $anzahl = Utilities::getArrayValueIfKey($instance, 'anzahl', 3); - $selectedUnits = Utilities::getArrayValueIfKey($instance, 'units', array()); - $zeigeDatum = Utilities::getArrayValueIfKey($instance, 'zeigeDatum', false); - $zeigeZeit = Utilities::getArrayValueIfKey($instance, 'zeigeZeit', false); - $zeigeFeedlink = Utilities::getArrayValueIfKey($instance, 'zeigeFeedlink', false); - $zeigeOrt = Utilities::getArrayValueIfKey($instance, 'zeigeOrt', false); - $zeigeArt = Utilities::getArrayValueIfKey($instance, 'zeigeArt', false); - $zeigeArtHierarchie = Utilities::getArrayValueIfKey($instance, 'zeigeArtHierarchie', false); - $showAnnotations = Utilities::getArrayValueIfKey($instance, 'showAnnotations', false); + $instance = array_merge($this->defaults, $instance); printf( '

    ', $this->get_field_id('title'), - 'Titel:', + esc_html__('Title:', 'einsatzverwaltung'), $this->get_field_name('title'), - esc_attr($title) + esc_attr($instance['title']) ); printf( '

     

    ', $this->get_field_id('anzahl'), - 'Anzahl der Einsatzberichte, die angezeigt werden:', + esc_html__('Number of reports to show:', 'einsatzverwaltung'), $this->get_field_name('anzahl'), - esc_attr($anzahl) + esc_attr($instance['anzahl']) ); $this->echoChecklistBox( get_taxonomy(Unit::getSlug()), 'units', __('Only show reports for these units:', 'einsatzverwaltung'), - $selectedUnits, + $instance['units'], __('Select no unit to show all reports', 'einsatzverwaltung') ); - printf( - '

     

    ', - esc_attr($this->get_field_id('zeigeFeedlink')), - esc_attr($this->get_field_name('zeigeFeedlink')), - checked($zeigeFeedlink, 'on', false), - 'Link zum Feed anzeigen' - ); - - echo '

    Einsatzdaten:

    '; - - printf( - '

     

    ', - esc_attr($this->get_field_id('zeigeDatum')), - esc_attr($this->get_field_name('zeigeDatum')), - checked($zeigeDatum, 'on', false), - 'Datum anzeigen' - ); - - printf( - '

     

    ', - esc_attr($this->get_field_id('zeigeZeit')), - esc_attr($this->get_field_name('zeigeZeit')), - checked($zeigeZeit, 'on', false), - 'Zeit anzeigen (nur in Kombination mit Datum)' - ); - - printf( - '

     

    ', - esc_attr($this->get_field_id('zeigeArt')), - esc_attr($this->get_field_name('zeigeArt')), - checked($zeigeArt, 'on', false), - 'Einsatzart anzeigen' - ); + echo '

    '; + $this->echoCheckbox($instance, 'zeigeFeedlink', __('Show link to RSS feed', 'einsatzverwaltung')); + echo '

    '; - printf( - '

     

    ', - esc_attr($this->get_field_id('zeigeArtHierarchie')), - esc_attr($this->get_field_name('zeigeArtHierarchie')), - checked($zeigeArtHierarchie, 'on', false), - 'Hierarchie der Einsatzart anzeigen' - ); + echo sprintf("

    %s

    ", __('Incident details', 'einsatzverwaltung')); - printf( - '

     

    ', - esc_attr($this->get_field_id('zeigeOrt')), - esc_attr($this->get_field_name('zeigeOrt')), - checked($zeigeOrt, 'on', false), - 'Ort anzeigen' - ); + echo '

    '; + $this->echoCheckbox($instance, 'zeigeDatum', __('Show date', 'einsatzverwaltung')); + echo '

    '; + $this->echoCheckbox($instance, 'zeigeZeit', __('Show time', 'einsatzverwaltung')); + echo '

    '; + $this->echoCheckbox($instance, 'zeigeArt', __('Show Incident Category', 'einsatzverwaltung')); + echo '

    '; + $this->echoCheckbox($instance, 'zeigeArtHierarchie', __('Show parent Incident Categories', 'einsatzverwaltung')); + echo '

    '; + $this->echoCheckbox($instance, 'zeigeOrt', __('Show location', 'einsatzverwaltung')); + echo '

    '; printf( '

     

    ', esc_attr($this->get_field_id('showAnnotations')), esc_attr($this->get_field_name('showAnnotations')), - checked($showAnnotations, '1', false), - 'Vermerke anzeigen' + checked($instance['showAnnotations'], '1', false), + esc_html__('Show annotations', 'einsatzverwaltung') ); return ''; diff --git a/src/Widgets/RecentIncidentsFormatted.php b/src/Widgets/RecentIncidentsFormatted.php index c28b9619..464541d5 100644 --- a/src/Widgets/RecentIncidentsFormatted.php +++ b/src/Widgets/RecentIncidentsFormatted.php @@ -4,6 +4,8 @@ use abrain\Einsatzverwaltung\ReportQuery; use abrain\Einsatzverwaltung\Types\Unit; use abrain\Einsatzverwaltung\Util\Formatter; +use function esc_html__; +use function esc_html_e; use function get_taxonomy; /** @@ -140,8 +142,8 @@ class RecentIncidentsFormatted extends AbstractWidget ); private $allowedTagsPattern = array('%title%', '%date%', '%time%', '%endTime%', '%location%', '%duration%', '%incidentCommander%', '%incidentType%', '%incidentTypeHierarchical%', '%incidentTypeColor%', '%url%', - '%number%', '%seqNum%', '%annotations%', '%vehicles%', '%units%', '%additionalForces%', '%typesOfAlerting%', - '%featuredImage%', '%featuredImageThumbnail%', '%workforce%'); + '%number%', '%seqNum%', '%annotations%', '%vehicles%', '%vehiclesByUnit%', '%units%', '%additionalForces%', + '%typesOfAlerting%', '%featuredImage%', '%featuredImageThumbnail%', '%workforce%'); private $allowedTagsAfter = array('%feedUrl%', '%yearArchive%'); /** @@ -152,9 +154,9 @@ public function __construct(Formatter $formatter) { parent::__construct( 'recent-incidents-formatted', - 'Letzte Einsätze (eigenes Format)', + __('Recent Incident Reports (Templates)', 'einsatzverwaltung'), array( - 'description' => 'Zeigt die neuesten Einsätze an. Das Aussehen kann vollständig mit eigenem HTML bestimmt werden.', + 'description' => __('The the most recent Incident Reports. Layout can be customized with HTML and placeholders.', 'einsatzverwaltung'), 'customize_selective_refresh' => true, ) ); @@ -170,17 +172,14 @@ public function __construct(Formatter $formatter) public function widget($args, $instance) { $settings = wp_parse_args($instance, $this->defaults); - - if (empty($settings['title'])) { - $settings['title'] = 'Letzte Einsätze'; - } + $title = empty($settings['title']) ? __('Recent incidents', 'einsatzverwaltung') : $settings['title']; if (empty($settings['numIncidents'])) { $settings['numIncidents'] = $this->defaults['numIncidents']; } echo $args['before_widget']; - echo $args['before_title'] . apply_filters('widget_title', $settings['title']) . $args['after_title']; + echo $args['before_title'] . apply_filters('widget_title', $title) . $args['after_title']; $reportQuery = new ReportQuery(); $reportQuery->setOrderAsc(false); @@ -209,7 +208,7 @@ public function widget($args, $instance) * * @return array Die zu speichernden Einstellungen oder false um das Speichern abzubrechen */ - public function update($newInstance, $oldInstance) + public function update($newInstance, $oldInstance): array { $instance = array(); $instance['title'] = strip_tags($newInstance['title']); @@ -236,7 +235,7 @@ public function update($newInstance, $oldInstance) * * @return string HTML-Code für das Formular */ - public function form($instance) + public function form($instance): string { $values = wp_parse_args($instance, $this->defaults); @@ -244,7 +243,7 @@ public function form($instance) printf( '', $this->get_field_id('title'), - 'Titel:', + esc_html__('Title:', 'einsatzverwaltung'), $this->get_field_name('title'), esc_attr($values['title']) ); @@ -254,7 +253,7 @@ public function form($instance) printf( ' ', $this->get_field_id('numIncidents'), - 'Anzahl der Einsatzberichte, die angezeigt werden:', + esc_html__('Number of reports to show:', 'einsatzverwaltung'), $this->get_field_name('numIncidents'), esc_attr($values['numIncidents']) ); @@ -272,7 +271,7 @@ public function form($instance) printf( '', $this->get_field_id('beforeContent'), - 'HTML-Code vor den Einsatzberichten:', + esc_html__('HTML code before the reports:', 'einsatzverwaltung'), $this->get_field_name('beforeContent'), esc_textarea($values['beforeContent']) ); @@ -282,7 +281,7 @@ public function form($instance) printf( '', $this->get_field_id('pattern'), - 'HTML-Template pro Einsatzbericht:', + esc_html__('HTML template per report:', 'einsatzverwaltung'), $this->get_field_name('pattern'), esc_textarea($values['pattern']) ); @@ -293,7 +292,7 @@ public function form($instance) printf( '', $this->get_field_id('afterContent'), - 'HTML-Code nach den Einsatzberichten:', + esc_html__('HTML code after the reports:', 'einsatzverwaltung'), $this->get_field_name('afterContent'), esc_textarea($values['afterContent']) ); @@ -309,7 +308,7 @@ public function form($instance) private function printTagReplacementInfo($allowedTags) { echo '
    '; - _e('The following tags will be replaced:', 'einsatzverwaltung'); + esc_html_e('The following tags will be replaced:', 'einsatzverwaltung'); foreach ($allowedTags as $tag) { printf('
    %s (%s)', esc_html($tag), esc_html($this->formatter->getLabelForTag($tag))); } diff --git a/src/changelog.txt b/src/changelog.txt index 19ed12cc..ea88a1dc 100644 --- a/src/changelog.txt +++ b/src/changelog.txt @@ -1,3 +1,24 @@ += 1.7.2 = +* Report list and Templates: Show sequential numbers as range if the report represents more than one incident +* Fix: Shortcode `reportcount` did not take into account if reports represented more than one incident +* Fix: Incident numbers would not have been correctly updated when changing the format +* Accessibility: Add aria-current attribute to links to the currently displayed page + += 1.7.1 = +* Fix: Associations with reports were not removed when a Unit got deleted +* Adjust numbering automatically, if reports represent more than one incident + += 1.7.0 = +* Vehicles: Can be marked as out of service so they are initially hidden when composing reports +* Vehicles: Custom sort order is respected when composing or editing reports +* Vehicles: Can now be linked with a page from the same site or an arbitrary URL +* Units: Can now be linked with a page from the same site or an arbitrary URL +* Templates: Added placeholder for end date and time of an incident +* Templates: Placeholder for yearly archive permalink can be used in widget footer +* Report list: Made the entire row clickable on mobile devices +* Improved compatibility with Essential Addons for Elementor +* Requires PHP 5.6 or newer + = 1.6.7 = * Fix: Calculation of the duration could fail, if the time zone was specified as offset from UTC diff --git a/src/css/style-admin.css b/src/css/style-admin.css index eaf19587..4c1c2c88 100644 --- a/src/css/style-admin.css +++ b/src/css/style-admin.css @@ -123,15 +123,6 @@ li.dropzone { display: unset; } -#fahrzeugdiv summary { - margin-bottom: 0.5em; -} - -#einsatzverwaltung_meta_box .incidentnumber { - line-height: 2; - min-height: 30px; -} - /* Hides the selector for the parent term when creating a term for the fahrzeug taxonomy, hierarchy will be removed */ body.edit-tags-php.post-type-einsatz.taxonomy-fahrzeug .form-wrap div.form-field.term-parent-wrap { display: none; diff --git a/src/css/style-edit.css b/src/css/style-edit.css index 24c7c6ca..6a38315c 100644 --- a/src/css/style-edit.css +++ b/src/css/style-edit.css @@ -1,3 +1,18 @@ .einsatzverwaltung_hint { color: #FF8800; -} \ No newline at end of file +} + +#fahrzeugdiv summary { + margin-bottom: 0.5em; +} + +#einsatzverwaltung_meta_box .incidentnumber { + line-height: 2; + min-height: 30px; +} + +@media (max-width: 400px) { + #einsatz_einsatzort, #einsatz_einsatzleiter, #einsatz_mannschaft { + max-width: 12em; + } +} diff --git a/src/einsatzverwaltung.php b/src/einsatzverwaltung.php index ec5cc6eb..e6295005 100644 --- a/src/einsatzverwaltung.php +++ b/src/einsatzverwaltung.php @@ -3,7 +3,7 @@ Plugin Name: Einsatzverwaltung Plugin URI: https://einsatzverwaltung.abrain.de Description: Public incident reports for fire brigades and other rescue services -Version: 1.8.0 +Version: 1.9.0 Author: Andreas Brain Author URI: https://www.abrain.de License: GPLv2 diff --git a/src/js/einsatzverwaltung-edit.js b/src/js/einsatzverwaltung-edit.js index f76281b9..a73921ea 100644 --- a/src/js/einsatzverwaltung-edit.js +++ b/src/js/einsatzverwaltung-edit.js @@ -1,12 +1,14 @@ +const { __ } = wp.i18n; + jQuery(document).ready(function() { var datumsregex = /^(19|20)\d{2}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]) ([01][0-9]|2[0-3]):([0-5][0-9])$/; - var hinweistext = 'Bitte das folgende Format einhalten: JJJJ-MM-TT hh:mm, z.B. 2014-01-31 13:37'; + const hinweistext = __('Please use the following format: YYYY-MM-DD hh:mm', 'einsatzverwaltung'); jQuery('#einsatzverwaltung_alarmzeit').after(' '); jQuery('#einsatz_einsatzende').after(' '); - einsatzverwaltung_register_and_execute('keyup', 'einsatzverwaltung_alarmzeit', datumsregex, hinweistext, false); - einsatzverwaltung_register_and_execute('keyup', 'einsatz_einsatzende', datumsregex, hinweistext, true); + einsatzverwaltung_register_and_execute('blur', 'einsatzverwaltung_alarmzeit', datumsregex, hinweistext, false); + einsatzverwaltung_register_and_execute('blur', 'einsatz_einsatzende', datumsregex, hinweistext, true); var used_values = jQuery("#einsatzleiter_used_values"); if (used_values.val() !== undefined) { diff --git a/src/readme.txt b/src/readme.txt index 9027cecd..8b667d0e 100644 --- a/src/readme.txt +++ b/src/readme.txt @@ -3,9 +3,9 @@ Contributors: abrain Donate link: https://einsatzverwaltung.abrain.de/unterstuetzen/ Tags: Feuerwehr, fire department, EMS Requires at least: 5.1.0 -Tested up to: 5.6 +Tested up to: 5.7 Requires PHP: 7.1.0 -Stable tag: 1.8.0 +Stable tag: 1.9.0 License: GPLv2 License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -52,6 +52,17 @@ Yes, you can find them on [our website](https://einsatzverwaltung.abrain.de/faq/ == Changelog == += 1.9.0 = +* Vehicles can be associated with a unit +* Incident numbers can have a separator between the year the and sequential number +* Classic singular view of reports shows vehicles grouped by unit, if units are used +* Templates: Added placeholder for vehicles grouped by unit +* Units: Display order can be customized +* Editor: Vehicles appear grouped by unit +* Editor: Meta box for incident details is now mobile friendly +* Editor: Notice about wrong date format only appears after leaving the field +* Internationalized more labels + = 1.8.0 = * Fix: Not all vehicles could be removed from an existing Incident Report * Shortcode `reportcount` can be filtered by status (actual or false alarm) @@ -62,26 +73,5 @@ Yes, you can find them on [our website](https://einsatzverwaltung.abrain.de/faq/ * Requires PHP 7.1 or newer * Requires WordPress 5.1 or newer -= 1.7.2 = -* Report list and Templates: Show sequential numbers as range if the report represents more than one incident -* Fix: Shortcode `reportcount` did not take into account if reports represented more than one incident -* Fix: Incident numbers would not have been correctly updated when changing the format -* Accessibility: Add aria-current attribute to links to the currently displayed page - -= 1.7.1 = -* Fix: Associations with reports were not removed when a Unit got deleted -* Adjust numbering automatically, if reports represent more than one incident - -= 1.7.0 = -* Vehicles: Can be marked as out of service so they are initially hidden when composing reports -* Vehicles: Custom sort order is respected when composing or editing reports -* Vehicles: Can now be linked with a page from the same site or an arbitrary URL -* Units: Can now be linked with a page from the same site or an arbitrary URL -* Templates: Added placeholder for end date and time of an incident -* Templates: Placeholder for yearly archive permalink can be used in widget footer -* Report list: Made the entire row clickable on mobile devices -* Improved compatibility with Essential Addons for Elementor -* Requires PHP 5.6 or newer - == Upgrade Notice == diff --git a/tests/integration/DataTest.php b/tests/integration/DataTest.php index 767fd34e..96c43e63 100644 --- a/tests/integration/DataTest.php +++ b/tests/integration/DataTest.php @@ -14,8 +14,7 @@ class DataTest extends WP_UnitTestCase */ public function testGetYearsWithReports() { - $options = $this->createMock('abrain\Einsatzverwaltung\Options'); - $data = new Data($options); + $data = new Data(new Options()); $this->assertEquals(array(), $data->getYearsWithReports()); $reportFactory = new ReportFactory(); diff --git a/tests/Model/IncidentReportTest.php b/tests/integration/Model/IncidentReportTest.php similarity index 96% rename from tests/Model/IncidentReportTest.php rename to tests/integration/Model/IncidentReportTest.php index 20ed5cd5..c1a66de1 100644 --- a/tests/Model/IncidentReportTest.php +++ b/tests/integration/Model/IncidentReportTest.php @@ -4,6 +4,10 @@ use abrain\Einsatzverwaltung\ReportFactory; use WP_UnitTestCase; +/** + * Class IncidentReportTest + * @package abrain\Einsatzverwaltung\Model + */ class IncidentReportTest extends WP_UnitTestCase { public function testGetDuration() diff --git a/tests/integration/PermalinkControllerTest.php b/tests/integration/PermalinkControllerTest.php index 8b9dea9b..2e18cc98 100644 --- a/tests/integration/PermalinkControllerTest.php +++ b/tests/integration/PermalinkControllerTest.php @@ -24,45 +24,6 @@ public function testBuildSelector() $this->assertEquals("prefix/$report->post_name/suffix", $controller->buildSelector($report, 'prefix/%postname%/suffix')); } - public function testGetPermalink() - { - $controller = new PermalinkController(); - $report = $this->createMock('abrain\Einsatzverwaltung\Types\Report'); - $report->method('getRewriteSlug')->willReturn('customrewriteslug'); - $controller->addRewriteRules($report); - - if (getenv('WP_TESTS_PERMALINK') === 'PRETTY') { - $this->assertEquals( - 'http://example.org/customrewriteslug/some-unique-selector/', - $controller->getPermalink('some-unique-selector') - ); - } elseif (getenv('WP_TESTS_PERMALINK') === 'PATHINFO') { - $this->assertEquals( - 'http://example.org/index.php/customrewriteslug/some-unique-selector/', - $controller->getPermalink('some-unique-selector') - ); - } - } - - /** - * @group unittests - */ - public function testGetRewriteBase() - { - $controller = new PermalinkController(); - $report = $this->createMock('abrain\Einsatzverwaltung\Types\Report'); - $report->method('getRewriteSlug')->willReturn('customrewriteslug'); - $controller->addRewriteRules($report); - - if (getenv('WP_TESTS_PERMALINK') === 'PRETTY') { - $this->assertEquals('customrewriteslug', $controller->getRewriteBase()); - } elseif (getenv('WP_TESTS_PERMALINK') === 'PATHINFO') { - $this->assertEquals('index.php/customrewriteslug', $controller->getRewriteBase()); - } else { - $this->assertEquals('', $controller->getRewriteBase()); - } - } - /** * @dataProvider queryVarTests * @param string $input @@ -154,22 +115,4 @@ public function testModifyQueryVarsBail() ); $this->assertEquals($queryVarsWrongFormat, $controller->modifyQueryVars($queryVarsWrongFormat, 'wontmatch')); } - - public function testSanitizePermalink() - { - $this->assertEquals('%postname%', PermalinkController::sanitizePermalink('%postname%')); - $this->assertEquals('%post_id%-%postname_nosuffix%', PermalinkController::sanitizePermalink('%post_id%-%postname_nosuffix%')); - $this->assertEquals('%postname_nosuffix%-%post_id%', PermalinkController::sanitizePermalink('%postname_nosuffix%-%post_id%')); - $this->assertEquals('%post_id%-%postname%', PermalinkController::sanitizePermalink('%post_id%-%postname%')); - - // invalid permalinks should return the default permalink - $this->assertEquals('%postname%', PermalinkController::sanitizePermalink('%post_id%_%postname_nosuffix%')); - $this->assertEquals('%postname%', PermalinkController::sanitizePermalink('%post_id%/%postname_nosuffix%')); - $this->assertEquals('%postname%', PermalinkController::sanitizePermalink('%post_id%--%postname_nosuffix%')); - $this->assertEquals('%postname%', PermalinkController::sanitizePermalink('')); - $this->assertEquals('%postname%', PermalinkController::sanitizePermalink('something')); - - // permalinks that do not contain a unique identifier should return the default permalink - $this->assertEquals('%postname%', PermalinkController::sanitizePermalink('%postname_nosuffix%')); - } } diff --git a/tests/integration/bootstrap.php b/tests/integration/bootstrap.php index 3dde82ad..f429de7d 100644 --- a/tests/integration/bootstrap.php +++ b/tests/integration/bootstrap.php @@ -16,12 +16,6 @@ // Zeitzone setzen update_option('timezone_string', 'Europe/Berlin'); - - if (getenv('WP_TESTS_PERMALINK') === 'PRETTY') { - update_option('permalink_structure', '/%year%/%monthnum%/%postname%/'); - } elseif (getenv('WP_TESTS_PERMALINK') === 'PATHINFO') { - update_option('permalink_structure', '/index.php/%year%/%monthnum%/%postname%/'); - } }); require $_tests_dir . '/includes/bootstrap.php'; diff --git a/tests/unit/PermalinkControllerTest.php b/tests/unit/PermalinkControllerTest.php new file mode 100644 index 00000000..f1e6eb9a --- /dev/null +++ b/tests/unit/PermalinkControllerTest.php @@ -0,0 +1,86 @@ +expects('using_permalinks')->once()->andReturnTrue(); + $wp_rewrite->front = '/'; + + $controller = new PermalinkController(); + $report = $this->createMock(Report::class); + $report->method('getRewriteSlug')->willReturn('customrewriteslug'); + expect('get_option')->once()->with('einsatz_permalink', Mockery::type('string'))->andReturn(''); + when('add_rewrite_rule')->justReturn(); + when('add_rewrite_tag')->justReturn(); + $controller->addRewriteRules($report); + + expect('home_url')->once()->with('customrewriteslug/some-unique-selector/')->andReturn('url184'); + $this->assertEquals('url184', $controller->getPermalink('some-unique-selector')); + } + + /** + * @covers \abrain\Einsatzverwaltung\PermalinkController::getPermalink + * @covers \abrain\Einsatzverwaltung\PermalinkController::getRewriteBase + * @uses \abrain\Einsatzverwaltung\PermalinkController::addRewriteRules + * @throws ExpectationArgsRequired + */ + public function testGetPathinfoPermalink() + { + global $wp_rewrite; + $wp_rewrite = Mockery::mock('\WP_Rewrite'); + $wp_rewrite->expects('using_permalinks')->once()->andReturnTrue(); + $wp_rewrite->front = '/index.php/'; + + $controller = new PermalinkController(); + $report = $this->createMock(Report::class); + $report->method('getRewriteSlug')->willReturn('another-rewriteslug'); + expect('get_option')->once()->with('einsatz_permalink', Mockery::type('string'))->andReturn(''); + when('add_rewrite_rule')->justReturn(); + when('add_rewrite_tag')->justReturn(); + $controller->addRewriteRules($report); + + expect('home_url')->once()->with('index.php/another-rewriteslug/random-selector/')->andReturn('url4613'); + $this->assertEquals('url4613', $controller->getPermalink('random-selector')); + } + + /** + * @covers \abrain\Einsatzverwaltung\PermalinkController::sanitizePermalink + */ + public function testSanitizePermalink() + { + $this->assertEquals('%postname%', PermalinkController::sanitizePermalink('%postname%')); + $this->assertEquals('%post_id%-%postname_nosuffix%', PermalinkController::sanitizePermalink('%post_id%-%postname_nosuffix%')); + $this->assertEquals('%postname_nosuffix%-%post_id%', PermalinkController::sanitizePermalink('%postname_nosuffix%-%post_id%')); + $this->assertEquals('%post_id%-%postname%', PermalinkController::sanitizePermalink('%post_id%-%postname%')); + + // invalid permalinks should return the default permalink + $this->assertEquals('%postname%', PermalinkController::sanitizePermalink('%post_id%_%postname_nosuffix%')); + $this->assertEquals('%postname%', PermalinkController::sanitizePermalink('%post_id%/%postname_nosuffix%')); + $this->assertEquals('%postname%', PermalinkController::sanitizePermalink('%post_id%--%postname_nosuffix%')); + $this->assertEquals('%postname%', PermalinkController::sanitizePermalink('')); + $this->assertEquals('%postname%', PermalinkController::sanitizePermalink('something')); + + // permalinks that do not contain a unique identifier should return the default permalink + $this->assertEquals('%postname%', PermalinkController::sanitizePermalink('%postname_nosuffix%')); + } +} diff --git a/tests/unit/ReportNumberControllerTest.php b/tests/unit/ReportNumberControllerTest.php index 24679e63..e5804ec0 100644 --- a/tests/unit/ReportNumberControllerTest.php +++ b/tests/unit/ReportNumberControllerTest.php @@ -1,6 +1,7 @@ assertEquals(2, ReportNumberController::sanitizeEinsatznummerStellen(2)); - $this->assertEquals(5, ReportNumberController::sanitizeEinsatznummerStellen('5')); - $this->assertEquals($fallback, ReportNumberController::sanitizeEinsatznummerStellen(0)); - $this->assertEquals($fallback, ReportNumberController::sanitizeEinsatznummerStellen(-1)); - $this->assertEquals($fallback, ReportNumberController::sanitizeEinsatznummerStellen('-2')); - $this->assertEquals($fallback, ReportNumberController::sanitizeEinsatznummerStellen('string')); - $this->assertEquals($fallback, ReportNumberController::sanitizeEinsatznummerStellen('')); - $this->assertEquals($fallback, ReportNumberController::sanitizeEinsatznummerStellen(false)); + $this->assertEquals(2, ReportNumberController::sanitizeNumberOfDigits(2)); + $this->assertEquals(5, ReportNumberController::sanitizeNumberOfDigits('5')); + $this->assertEquals($fallback, ReportNumberController::sanitizeNumberOfDigits(0)); + $this->assertEquals($fallback, ReportNumberController::sanitizeNumberOfDigits(-1)); + $this->assertEquals($fallback, ReportNumberController::sanitizeNumberOfDigits('-2')); + $this->assertEquals($fallback, ReportNumberController::sanitizeNumberOfDigits('string')); + $this->assertEquals($fallback, ReportNumberController::sanitizeNumberOfDigits('')); + $this->assertEquals($fallback, ReportNumberController::sanitizeNumberOfDigits(false)); } + public function testSanitizeSeparator() + { + $fallback = ReportNumberController::DEFAULT_SEPARATOR; + self::assertEquals('none', ReportNumberController::sanitizeSeparator('none')); + self::assertEquals('slash', ReportNumberController::sanitizeSeparator('slash')); + self::assertEquals('hyphen', ReportNumberController::sanitizeSeparator('hyphen')); + self::assertEquals($fallback, ReportNumberController::sanitizeSeparator('')); + self::assertEquals($fallback, ReportNumberController::sanitizeSeparator('something')); + } + + + /** + * @throws ExpectationArgsRequired + */ public function testChangeOfSequenceNumber() { $data = Mockery::mock('\abrain\Einsatzverwaltung\Data'); @@ -34,10 +49,14 @@ public function testChangeOfSequenceNumber() expect('get_post_field')->once()->with('post_date', $postId)->andReturn('2018-03-24 00:00:00'); expect('get_option')->once()->with('einsatzvw_einsatznummer_stellen')->andReturn('4'); expect('get_option')->once()->with('einsatzvw_einsatznummer_lfdvorne', false)->andReturn('0'); + expect('get_option')->once()->with('einsatzvw_numbers_separator', 'none')->andReturn('none'); expect('update_post_meta')->once()->with($postId, 'einsatz_incidentNumber', '20180017'); $controller->onPostMetaChanged(0, $postId, 'einsatz_seqNum', '17'); } + /** + * @throws ExpectationArgsRequired + */ public function testChangeOfForeignPostMeta() { $data = Mockery::mock('\abrain\Einsatzverwaltung\Data'); @@ -48,6 +67,9 @@ public function testChangeOfForeignPostMeta() $controller->onPostMetaChanged(0, $postId, 'some_other_key', '941'); } + /** + * @throws ExpectationArgsRequired + */ public function testChangeOfPostMetaOfForeignPostType() { $data = Mockery::mock('\abrain\Einsatzverwaltung\Data'); @@ -57,4 +79,23 @@ public function testChangeOfPostMetaOfForeignPostType() expect('update_post_meta')->never(); $controller->onPostMetaChanged(0, $postId, 'einsatz_seqNum', '89'); } + + /** + * @throws ExpectationArgsRequired + */ + public function testFormatEinsatznummer() + { + $data = Mockery::mock(Data::class); + $controller = new ReportNumberController($data); + + expect('get_option')->once()->with('einsatzvw_einsatznummer_stellen')->andReturn('3'); + expect('get_option')->once()->with('einsatzvw_einsatznummer_lfdvorne', false)->andReturn('1'); + expect('get_option')->once()->with('einsatzvw_numbers_separator', 'none')->andReturn('slash'); + self::assertEquals('012/2020', $controller->formatEinsatznummer('2020', 12)); + + expect('get_option')->once()->with('einsatzvw_einsatznummer_stellen')->andReturn('2'); + expect('get_option')->once()->with('einsatzvw_einsatznummer_lfdvorne', false)->andReturn('0'); + expect('get_option')->once()->with('einsatzvw_numbers_separator', 'none')->andReturn('hyphen'); + self::assertEquals('2019-623', $controller->formatEinsatznummer('2019', 623)); + } } diff --git a/tests/unit/Util/FormatterTest.php b/tests/unit/Util/FormatterTest.php index 544ee029..fa89d59a 100644 --- a/tests/unit/Util/FormatterTest.php +++ b/tests/unit/Util/FormatterTest.php @@ -26,9 +26,7 @@ public function testGetDurationString() $this->assertEquals('1 h 1 min', Formatter::getDurationString(61, true)); $this->assertEquals('2 h 2 min', Formatter::getDurationString(122, true)); - $this->assertEquals('', Formatter::getDurationString('asdf', true)); - $this->assertEquals('', Formatter::getDurationString('asdf', false)); $this->assertEquals('', Formatter::getDurationString(-1)); - $this->assertEquals('9 minutes', Formatter::getDurationString('9', false)); + $this->assertEquals('9 minutes', Formatter::getDurationString('9')); } } diff --git a/tests/unit/UtilitiesTest.php b/tests/unit/UtilitiesTest.php index a911e644..7ea89a6e 100644 --- a/tests/unit/UtilitiesTest.php +++ b/tests/unit/UtilitiesTest.php @@ -1,6 +1,8 @@ term_id = 124; + $vehicle1->name = 'A'; + expect('get_term_meta')->once()->with(124, 'vehicle_unit', true)->andReturn(53); + expect('get_term_meta')->once()->with(124, 'vehicleorder', true)->andReturn(3); + + $vehicle2 = Mockery::mock('\WP_Term'); + $vehicle2->term_id = 6232; + $vehicle2->name = 'B'; + expect('get_term_meta')->once()->with(6232, 'vehicle_unit', true)->andReturn(-1); + + $vehicle3 = Mockery::mock('\WP_Term'); + $vehicle3->term_id = 7632; + $vehicle3->name = 'C'; + expect('get_term_meta')->once()->with(7632, 'vehicle_unit', true)->andReturn(53); + expect('get_term_meta')->once()->with(7632, 'vehicleorder', true)->andReturn(2); + + $vehicle4 = Mockery::mock('\WP_Term'); + $vehicle4->term_id = 523; + $vehicle4->name = 'D'; + expect('get_term_meta')->once()->with(523, 'vehicle_unit', true)->andReturn(991); + + $vehicle5 = Mockery::mock('\WP_Term'); + $vehicle5->term_id = 1928; + $vehicle5->name = 'E'; + expect('get_term_meta')->once()->with(1928, 'vehicle_unit', true)->andReturn(false); + + $unit1 = Mockery::mock('\WP_Term'); + $unit1->term_id = 991; + expect('get_term')->once()->with(991)->andReturn($unit1); + expect('get_term_meta')->once()->with(991, 'unit_order', true)->andReturn(2); + + $unit2 = Mockery::mock('\WP_Term'); + $unit2->term_id = 53; + expect('get_term')->once()->with(53)->andReturn($unit2); + expect('get_term_meta')->once()->with(53, 'unit_order', true)->andReturn(1); + + self::assertEquals([ + 53 => [$vehicle3, $vehicle1], + 991 => [$vehicle4], + -1 => [$vehicle2, $vehicle5] + ], Utilities::groupVehiclesByUnit([$vehicle1, $vehicle2, $vehicle3, $vehicle4, $vehicle5])); + } + public function testPrintError() { $utilities = new Utilities(); @@ -64,6 +117,9 @@ public function testPrintWarning() $utilities->printWarning('Some random string'); } + /** + * @throws ExpectationArgsRequired + */ public function testRemovePostFromCategory() { $postId = 24; @@ -74,6 +130,7 @@ public function testRemovePostFromCategory() /** * If we want to remove a category that is not even set, nothing should be changed. + * @throws ExpectationArgsRequired */ public function testRemovePostFromCategoryBail() {
    %2$s%3$s

    %5$s

    %4$s

    %3$s