From 0414c82b0c5605578f0695e3c9b2e2a73796d7b7 Mon Sep 17 00:00:00 2001
From: rbairwell
Date: Tue, 19 Mar 2019 14:47:16 +0000
Subject: [PATCH 1/2] Change to Doctrine based coding standards
---
.circleci/config.yml | 4 +
.idea/PublicWhipV2.iml | 16 +-
.idea/codeStyles/Project.xml | 3 +-
.../includes/PHP Class Doc Comment.php | 2 +-
.../includes/PHP Interface Doc Comment.php | 2 +-
.../includes/PHP Trait Doc Comment.php | 2 +-
.idea/fileTemplates/internal/PHP Class.php | 1 -
.idea/fileTemplates/internal/PHP Trait.php | 1 -
.idea/fileTemplates/internal/PHPUnit Test.php | 1 -
.idea/inspectionProfiles/Project_Default.xml | 4 +-
.idea/php.xml | 207 ++--
README.md | 1 -
composer.json | 64 +-
composer.lock | 922 +++++++++---------
composerRequireChecker.json | 5 +-
config/develop.php | 6 +-
config/docker.php | 9 +-
config/production.php | 6 +-
docker/php/Dockerfile | 8 +-
docs/CODE_OF_CONDUCT.md | 3 +-
docs/ChangeLog.md | 6 +-
phpcs.xml | 316 ++----
phpstan.neon | 3 +-
src/Config.php | 56 +-
src/Entities/DivisionEntity.php | 75 +-
src/Exceptions/AbstractException.php | 6 +-
.../Factories/AbstractFactoryException.php | 6 +-
.../Factories/BadDateTimeException.php | 5 +-
...ntityFactoryUnrecognisedFieldException.php | 6 +-
.../EntityFieldWrongTypeException.php | 6 +-
.../EntityMissingRequiredFieldException.php | 6 +-
.../MissingConfigurationException.php | 5 +-
.../Providers/AbstractProviderException.php | 6 +-
src/Exceptions/Providers/WikiFailedRegExp.php | 6 +-
.../Services/AbstractServicesException.php | 6 +-
.../Services/BadDatabaseReturnException.php | 6 +-
src/Factories/DateTimeFactory.php | 14 +-
src/Factories/DateTimeFactoryInterface.php | 8 +-
src/Factories/EntityFactory.php | 204 ++--
src/Factories/EntityFactoryInterface.php | 10 +-
src/Providers/CallableResolverProvider.php | 16 +-
.../CallableResolverProviderInterface.php | 14 +-
src/Providers/ControllerInvokerProvider.php | 17 +-
src/Providers/DatabaseProvider.php | 42 +-
src/Providers/DatabaseProviderInterface.php | 32 +-
src/Providers/DebuggerProvider.php | 91 +-
src/Providers/DebuggerProviderInterface.php | 20 +-
src/Providers/DebuggerTwigExtension.php | 22 +-
src/Providers/MailerProvider.php | 140 ++-
src/Providers/MailerProviderInterface.php | 27 +-
src/Providers/MailerTransportProvider.php | 98 ++
.../MailerTransportProviderInterface.php | 19 +
src/Providers/TemplateProvider.php | 17 +-
src/Providers/TemplateProviderInterface.php | 11 +-
src/Providers/WikiParserProvider.php | 144 +--
src/Providers/WikiParserProviderInterface.php | 16 +-
src/Services/DivisionService.php | 54 +-
src/Services/DivisionServiceInterface.php | 14 +-
src/Web.php | 61 +-
src/Web/Controllers/DebugBarController.php | 2 +-
src/Web/Controllers/DivisionController.php | 2 +-
src/Web/Controllers/DocsController.php | 4 +-
src/Web/Controllers/IndexController.php | 2 +-
src/Web/Controllers/PingController.php | 23 +-
src/Web/ErrorHandlers/ErrorHandler.php | 74 +-
src/Web/ErrorHandlers/NotFoundHandler.php | 2 +-
src/Web/ErrorHandlers/PhpErrorHandler.php | 77 +-
src/Web/Routing.php | 91 +-
.../Unit/Providers/WikiParserProviderTest.php | 36 +-
.../Web/Controllers/PingControllerTest.php | 54 +
tests/bootstrap.php | 2 +-
v1migrationUtils/compare.php | 28 +-
v1migrationUtils/divisionExtractorToTests.php | 48 +-
v1migrationUtils/htmlMarkupToTests.php | 6 +-
74 files changed, 1799 insertions(+), 1530 deletions(-)
create mode 100644 src/Providers/MailerTransportProvider.php
create mode 100644 src/Providers/MailerTransportProviderInterface.php
create mode 100644 tests/Unit/Web/Controllers/PingControllerTest.php
diff --git a/.circleci/config.yml b/.circleci/config.yml
index bdbef8f..80a6ed4 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -24,6 +24,10 @@ jobs:
- run: sudo apt update
- run: sudo docker-php-ext-install pdo_mysql
+ # check composer is in sync
+ - run:
+ name: Checking composer.lock
+ command: composer validate --no-check-all --strict
# Download and cache dependencies
- restore_cache:
keys:
diff --git a/.idea/PublicWhipV2.iml b/.idea/PublicWhipV2.iml
index 4ba10b3..a4bcbe9 100644
--- a/.idea/PublicWhipV2.iml
+++ b/.idea/PublicWhipV2.iml
@@ -2,8 +2,9 @@
+
-
+
@@ -14,14 +15,14 @@
+
+
+
-
-
-
@@ -49,10 +50,10 @@
+
-
@@ -64,6 +65,7 @@
+
@@ -76,7 +78,6 @@
-
@@ -111,12 +112,13 @@
+
+
-
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index d6fc450..546edc7 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -3,13 +3,14 @@
-
+
+
diff --git a/.idea/fileTemplates/includes/PHP Class Doc Comment.php b/.idea/fileTemplates/includes/PHP Class Doc Comment.php
index 9d97f4d..85333ee 100644
--- a/.idea/fileTemplates/includes/PHP Class Doc Comment.php
+++ b/.idea/fileTemplates/includes/PHP Class Doc Comment.php
@@ -1,3 +1,3 @@
/**
- * Class ${NAME}.
+ * ${NAME}.
*/
diff --git a/.idea/fileTemplates/includes/PHP Interface Doc Comment.php b/.idea/fileTemplates/includes/PHP Interface Doc Comment.php
index cb387af..85333ee 100644
--- a/.idea/fileTemplates/includes/PHP Interface Doc Comment.php
+++ b/.idea/fileTemplates/includes/PHP Interface Doc Comment.php
@@ -1,3 +1,3 @@
/**
- * Interface ${NAME}.
+ * ${NAME}.
*/
diff --git a/.idea/fileTemplates/includes/PHP Trait Doc Comment.php b/.idea/fileTemplates/includes/PHP Trait Doc Comment.php
index 118cf16..85333ee 100644
--- a/.idea/fileTemplates/includes/PHP Trait Doc Comment.php
+++ b/.idea/fileTemplates/includes/PHP Trait Doc Comment.php
@@ -1,3 +1,3 @@
/**
- * Trait ${NAME}.
+ * ${NAME}.
*/
diff --git a/.idea/fileTemplates/internal/PHP Class.php b/.idea/fileTemplates/internal/PHP Class.php
index 860cba4..1bfdf19 100644
--- a/.idea/fileTemplates/internal/PHP Class.php
+++ b/.idea/fileTemplates/internal/PHP Class.php
@@ -3,7 +3,6 @@
#if (${NAMESPACE})
namespace ${NAMESPACE};
#end
-
class ${NAME} {
}
\ No newline at end of file
diff --git a/.idea/fileTemplates/internal/PHP Trait.php b/.idea/fileTemplates/internal/PHP Trait.php
index b3f31ce..945692f 100644
--- a/.idea/fileTemplates/internal/PHP Trait.php
+++ b/.idea/fileTemplates/internal/PHP Trait.php
@@ -3,7 +3,6 @@
#if (${NAMESPACE})
namespace ${NAMESPACE};
#end
-
trait ${NAME} {
}
\ No newline at end of file
diff --git a/.idea/fileTemplates/internal/PHPUnit Test.php b/.idea/fileTemplates/internal/PHPUnit Test.php
index 84e5a27..c946dbe 100644
--- a/.idea/fileTemplates/internal/PHPUnit Test.php
+++ b/.idea/fileTemplates/internal/PHPUnit Test.php
@@ -3,7 +3,6 @@
#if (${NAMESPACE})
namespace ${NAMESPACE};
#end
-
#if (${TESTED_NAME} && ${NAMESPACE} && !${TESTED_NAMESPACE})
use ${TESTED_NAME};
#elseif (${TESTED_NAME} && ${TESTED_NAMESPACE} && ${NAMESPACE} != ${TESTED_NAMESPACE})
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index a2afae2..4d4d7e6 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -121,9 +121,10 @@
-
+
+
@@ -151,7 +152,6 @@
-
diff --git a/.idea/php.xml b/.idea/php.xml
index 2e728e6..417fb62 100644
--- a/.idea/php.xml
+++ b/.idea/php.xml
@@ -18,121 +18,122 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/README.md b/README.md
index 17a2d82..d5080c4 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,6 @@ If you are considering [Contributing](docs/CONTRIBUTING.md) to the development o
read the [Code of Conduct](docs/CODE_OF_CONDUCT.md) first. All contributions to PublicWhip v2 must be licensed under
the [MIT](LICENSE.txt) license allowing free usage of the code in any form without restriction.
-[![Coverage Status](https://coveralls.io/repos/github/publicwhip/publicwhipv2/badge.svg?branch=master)](https://coveralls.io/github/publicwhip/publicwhipv2?branch=master)
[![CircleCI](https://circleci.com/gh/publicwhip/publicwhipv2/tree/master.svg?style=svg)](https://circleci.com/gh/publicwhip/publicwhipv2/tree/master)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Slack Join Chat](https://img.shields.io/badge/Slack-Join_Chat-blue.svg)](https://join.slack.com/t/publicwhip/shared_invite/enQtNTczMTg1MTc1Mzc3LTAxMjkyYzNhNWY0NDdmY2EzYjYwNTZjNjQ1YTNiOTQwZWYzM2Q0ZDJjOWU5MTVjNzZmNGFjMzljY2U0ZjA0YjM)
\ No newline at end of file
diff --git a/composer.json b/composer.json
index a262f23..5e974b6 100644
--- a/composer.json
+++ b/composer.json
@@ -5,46 +5,48 @@
"homepage": "https://www.publicwhip.org.uk/",
"require": {
"php": ">=7.2",
+ "ext-json": "*",
"ext-pdo": "*",
- "ext-json" : "*",
- "slim/slim": "^3",
- "psr/log": "^1",
- "twig/twig": "^2",
- "slim/twig-view": "^2",
- "monolog/monolog": "^1.24",
- "php-di/php-di": "^6.0",
- "php-di/invoker": "^2.0.0",
- "psr/http-message": "^1.0",
- "psr/container": "^1",
- "slim/csrf": "^0.5",
- "slim/flash": "^0.1",
- "maximebf/debugbar": "^1.15",
- "swiftmailer/swiftmailer": "^5.4",
+ "ext-sodium": "*",
+ "erusev/parsedown": "^1.7",
+ "illuminate/container": "^5.8",
+ "illuminate/contracts": "^5.8",
"illuminate/database": "^5.1",
"illuminate/events": "^5.1",
- "illuminate/container": "^5.8",
"illuminate/support": "^5.8",
- "illuminate/contracts": "^5.8",
+ "maximebf/debugbar": "^1.15",
+ "monolog/monolog": "^1.24",
+ "php-di/invoker": "^2.0.0",
+ "php-di/php-di": "^6.0",
+ "psr/container": "^1",
+ "psr/http-message": "^1.0",
+ "psr/log": "^1",
+ "slim/csrf": "^0.8",
+ "slim/flash": "^0.4",
"slim/http-cache": "^0.4.0",
- "erusev/parsedown": "^1.7"
+ "slim/slim": "^3",
+ "slim/twig-view": "^2",
+ "swiftmailer/swiftmailer": "^6.2",
+ "twig/twig": "^2"
},
"require-dev": {
- "phpunit/phpunit": "^8",
- "roave/security-advisories": "dev-master",
- "phpstan/phpstan-strict-rules": "^0.11",
- "phpmd/phpmd": "^2",
+ "ext-xdebug": "*",
+ "doctrine/coding-standard": "^6.0",
+ "infection/infection": "^0.12",
+ "jakub-onderka/php-parallel-lint": "^1.0",
"maglnet/composer-require-checker": "^1",
+ "phpmd/phpmd": "^2",
"phpro/grumphp": "^0.15",
"phpstan/phpstan": "^0.11",
- "sensiolabs/security-checker": "^5",
- "squizlabs/php_codesniffer": "^3",
- "infection/infection": "^0.12",
+ "phpstan/phpstan-phpunit": "^0.11.0",
+ "phpstan/phpstan-strict-rules": "^0.11",
+ "phpunit/phpunit": "^8",
+ "roave/security-advisories": "dev-master",
"sebastian/phpcpd": "^4",
- "jakub-onderka/php-parallel-lint": "^1.0",
- "slevomat/coding-standard": "^5.0",
+ "sensiolabs/security-checker": "^5",
"sirbrillig/phpcs-variable-analysis": "^2.6",
- "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0",
- "php-coveralls/php-coveralls": "^2.1"
+ "slevomat/coding-standard": "^5.0",
+ "squizlabs/php_codesniffer": "^3"
},
"scripts": {
"phpcs": "phpcs --standard=./phpcs.xml -s",
@@ -67,6 +69,9 @@
"docs": "https://github.com/publicwhip/publicwhip/tree/master/docs",
"email": "team@publicwhip.org.uk"
},
+ "config": {
+ "sort-packages": true
+ },
"autoload": {
"psr-4": {
"PublicWhip\\": "src/"
@@ -74,7 +79,8 @@
},
"autoload-dev": {
"psr-4": {
- "PublicWhip\\Tests\\": "tests/"
+ "PublicWhip\\Tests\\": "tests/",
+ "PublicWhip\\v1migrationUtils\\": "v1migrationUtils/"
}
},
"minimum-stability": "stable"
diff --git a/composer.lock b/composer.lock
index 7bcd58d..8f47647 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": "4d0e36cba4e3f267227ff38589951ede",
+ "content-hash": "b1800fc7d8bb4f60acab32960305fa8d",
"packages": [
{
"name": "container-interop/container-interop",
@@ -104,6 +104,117 @@
],
"time": "2018-01-09T20:05:19+00:00"
},
+ {
+ "name": "doctrine/lexer",
+ "version": "v1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/lexer.git",
+ "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c",
+ "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Doctrine\\Common\\Lexer\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
+ "homepage": "http://www.doctrine-project.org",
+ "keywords": [
+ "lexer",
+ "parser"
+ ],
+ "time": "2014-09-09T13:34:57+00:00"
+ },
+ {
+ "name": "egulias/email-validator",
+ "version": "2.1.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/egulias/EmailValidator.git",
+ "reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/709f21f92707308cdf8f9bcfa1af4cb26586521e",
+ "reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/lexer": "^1.0.1",
+ "php": ">= 5.5"
+ },
+ "require-dev": {
+ "dominicsayers/isemail": "dev-master",
+ "phpunit/phpunit": "^4.8.35||^5.7||^6.0",
+ "satooshi/php-coveralls": "^1.0.1"
+ },
+ "suggest": {
+ "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Egulias\\EmailValidator\\": "EmailValidator"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Eduardo Gulias Davis"
+ }
+ ],
+ "description": "A library for validating emails against several RFCs",
+ "homepage": "https://github.com/egulias/EmailValidator",
+ "keywords": [
+ "email",
+ "emailvalidation",
+ "emailvalidator",
+ "validation",
+ "validator"
+ ],
+ "time": "2018-12-04T22:38:24+00:00"
+ },
{
"name": "erusev/parsedown",
"version": "v1.7.2",
@@ -759,6 +870,51 @@
],
"time": "2019-02-16T20:54:15+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"
+ ],
+ "time": "2018-07-02T15:55:56+00:00"
+ },
{
"name": "php-di/invoker",
"version": "2.0.0",
@@ -1148,25 +1304,26 @@
},
{
"name": "slim/csrf",
- "version": "0.5.0",
+ "version": "0.8.3",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim-Csrf.git",
- "reference": "fd713fe28c73c70edcdda95afcf5ad30b21d2d9b"
+ "reference": "5f2bcf5d89adf86dc0455a32bea84d912ab466a7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/slimphp/Slim-Csrf/zipball/fd713fe28c73c70edcdda95afcf5ad30b21d2d9b",
- "reference": "fd713fe28c73c70edcdda95afcf5ad30b21d2d9b",
+ "url": "https://api.github.com/repos/slimphp/Slim-Csrf/zipball/5f2bcf5d89adf86dc0455a32bea84d912ab466a7",
+ "reference": "5f2bcf5d89adf86dc0455a32bea84d912ab466a7",
"shasum": ""
},
"require": {
+ "paragonie/random_compat": "^1.1|^2.0|^9.99",
"php": ">=5.5.0",
"psr/http-message": "^1.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0",
- "slim/slim": "3.x-dev"
+ "slim/slim": "~3.0"
},
"type": "library",
"autoload": {
@@ -1193,25 +1350,28 @@
"middleware",
"slim"
],
- "time": "2015-11-09T10:34:12+00:00"
+ "time": "2018-08-22T16:12:18+00:00"
},
{
"name": "slim/flash",
- "version": "0.1.0",
+ "version": "0.4.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim-Flash.git",
- "reference": "1995ed53b77b8eeb67adf032de93c319f76aa5cd"
+ "reference": "9aaff5fded3b54f4e519ec3d4ac74d3d1f2cbbbc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/slimphp/Slim-Flash/zipball/1995ed53b77b8eeb67adf032de93c319f76aa5cd",
- "reference": "1995ed53b77b8eeb67adf032de93c319f76aa5cd",
+ "url": "https://api.github.com/repos/slimphp/Slim-Flash/zipball/9aaff5fded3b54f4e519ec3d4ac74d3d1f2cbbbc",
+ "reference": "9aaff5fded3b54f4e519ec3d4ac74d3d1f2cbbbc",
"shasum": ""
},
"require": {
"php": ">=5.5.0"
},
+ "require-dev": {
+ "phpunit/phpunit": "^4.0"
+ },
"type": "library",
"autoload": {
"psr-4": {
@@ -1238,7 +1398,7 @@
"provider",
"slim"
],
- "time": "2015-08-16T22:49:06+00:00"
+ "time": "2017-10-22T10:35:05+00:00"
},
{
"name": "slim/http-cache",
@@ -1413,29 +1573,37 @@
},
{
"name": "swiftmailer/swiftmailer",
- "version": "v5.4.12",
+ "version": "v6.2.0",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
- "reference": "181b89f18a90f8925ef805f950d47a7190e9b950"
+ "reference": "6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/181b89f18a90f8925ef805f950d47a7190e9b950",
- "reference": "181b89f18a90f8925ef805f950d47a7190e9b950",
+ "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707",
+ "reference": "6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "egulias/email-validator": "~2.0",
+ "php": ">=7.0.0",
+ "symfony/polyfill-iconv": "^1.0",
+ "symfony/polyfill-intl-idn": "^1.10",
+ "symfony/polyfill-mbstring": "^1.0"
},
"require-dev": {
"mockery/mockery": "~0.9.1",
- "symfony/phpunit-bridge": "~3.2"
+ "symfony/phpunit-bridge": "^3.4.19|^4.1.8"
+ },
+ "suggest": {
+ "ext-intl": "Needed to support internationalized email addresses",
+ "true/punycode": "Needed to support internationalized email addresses, if ext-intl is not installed"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "5.4-dev"
+ "dev-master": "6.2-dev"
}
},
"autoload": {
@@ -1463,7 +1631,7 @@
"mail",
"mailer"
],
- "time": "2018-07-31T09:26:32+00:00"
+ "time": "2019-03-10T07:52:41+00:00"
},
{
"name": "symfony/contracts",
@@ -1591,6 +1759,127 @@
],
"time": "2018-08-06T14:22:27+00:00"
},
+ {
+ "name": "symfony/polyfill-iconv",
+ "version": "v1.10.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-iconv.git",
+ "reference": "97001cfc283484c9691769f51cdf25259037eba2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/97001cfc283484c9691769f51cdf25259037eba2",
+ "reference": "97001cfc283484c9691769f51cdf25259037eba2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-iconv": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Iconv\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "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 for the Iconv extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "iconv",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "time": "2018-09-21T06:26:08+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-idn",
+ "version": "v1.10.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-idn.git",
+ "reference": "89de1d44f2c059b266f22c9cc9124ddc4cd0987a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/89de1d44f2c059b266f22c9cc9124ddc4cd0987a",
+ "reference": "89de1d44f2c059b266f22c9cc9124ddc4cd0987a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "symfony/polyfill-mbstring": "^1.3",
+ "symfony/polyfill-php72": "^1.9"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Idn\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ },
+ {
+ "name": "Laurent Bassin",
+ "email": "laurent@bassin.info"
+ }
+ ],
+ "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "idn",
+ "intl",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "time": "2018-09-30T16:36:12+00:00"
+ },
{
"name": "symfony/polyfill-mbstring",
"version": "v1.10.0",
@@ -2401,35 +2690,34 @@
"time": "2018-10-26T13:21:45+00:00"
},
{
- "name": "doctrine/collections",
- "version": "v1.5.0",
+ "name": "doctrine/coding-standard",
+ "version": "6.0.0",
"source": {
"type": "git",
- "url": "https://github.com/doctrine/collections.git",
- "reference": "a01ee38fcd999f34d9bfbcee59dbda5105449cbf"
+ "url": "https://github.com/doctrine/coding-standard.git",
+ "reference": "d33f69eb98b25aa51ffe3a909f0ec77000af4701"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/collections/zipball/a01ee38fcd999f34d9bfbcee59dbda5105449cbf",
- "reference": "a01ee38fcd999f34d9bfbcee59dbda5105449cbf",
+ "url": "https://api.github.com/repos/doctrine/coding-standard/zipball/d33f69eb98b25aa51ffe3a909f0ec77000af4701",
+ "reference": "d33f69eb98b25aa51ffe3a909f0ec77000af4701",
"shasum": ""
},
"require": {
- "php": "^7.1"
- },
- "require-dev": {
- "doctrine/coding-standard": "~0.1@dev",
- "phpunit/phpunit": "^5.7"
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0",
+ "php": "^7.1",
+ "slevomat/coding-standard": "^5.0",
+ "squizlabs/php_codesniffer": "^3.4.0"
},
- "type": "library",
+ "type": "phpcodesniffer-standard",
"extra": {
"branch-alias": {
- "dev-master": "1.3.x-dev"
+ "dev-master": "6.0.x-dev"
}
},
"autoload": {
- "psr-0": {
- "Doctrine\\Common\\Collections\\": "lib/"
+ "psr-4": {
+ "Doctrine\\Sniffs\\": "lib/Doctrine/Sniffs"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2437,185 +2725,61 @@
"MIT"
],
"authors": [
- {
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
- {
- "name": "Jonathan Wage",
- "email": "jonwage@gmail.com"
- },
- {
- "name": "Johannes Schmitt",
- "email": "schmittjoh@gmail.com"
+ "name": "Steve Müller",
+ "email": "st.mueller@dzh-online.de"
}
],
- "description": "Collections Abstraction library",
- "homepage": "http://www.doctrine-project.org",
+ "description": "The Doctrine Coding Standard is a set of PHPCS rules applied to all Doctrine projects.",
+ "homepage": "https://www.doctrine-project.org/projects/coding-standard.html",
"keywords": [
- "array",
- "collections",
- "iterator"
+ "checks",
+ "code",
+ "coding",
+ "cs",
+ "doctrine",
+ "rules",
+ "sniffer",
+ "sniffs",
+ "standard",
+ "style"
],
- "time": "2017-07-22T10:37:32+00:00"
+ "time": "2019-03-15T12:45:47+00:00"
},
{
- "name": "doctrine/instantiator",
- "version": "1.1.0",
+ "name": "doctrine/collections",
+ "version": "v1.5.0",
"source": {
"type": "git",
- "url": "https://github.com/doctrine/instantiator.git",
- "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda"
+ "url": "https://github.com/doctrine/collections.git",
+ "reference": "a01ee38fcd999f34d9bfbcee59dbda5105449cbf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
- "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
+ "url": "https://api.github.com/repos/doctrine/collections/zipball/a01ee38fcd999f34d9bfbcee59dbda5105449cbf",
+ "reference": "a01ee38fcd999f34d9bfbcee59dbda5105449cbf",
"shasum": ""
},
"require": {
"php": "^7.1"
},
"require-dev": {
- "athletic/athletic": "~0.1.8",
- "ext-pdo": "*",
- "ext-phar": "*",
- "phpunit/phpunit": "^6.2.3",
- "squizlabs/php_codesniffer": "^3.0.2"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.2.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Marco Pivetta",
- "email": "ocramius@gmail.com",
- "homepage": "http://ocramius.github.com/"
- }
- ],
- "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
- "homepage": "https://github.com/doctrine/instantiator",
- "keywords": [
- "constructor",
- "instantiate"
- ],
- "time": "2017-07-22T11:58:36+00:00"
- },
- {
- "name": "gitonomy/gitlib",
- "version": "v1.0.4",
- "source": {
- "type": "git",
- "url": "https://github.com/gitonomy/gitlib.git",
- "reference": "932a960221ae3484a3e82553b3be478e56beb68d"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/gitonomy/gitlib/zipball/932a960221ae3484a3e82553b3be478e56beb68d",
- "reference": "932a960221ae3484a3e82553b3be478e56beb68d",
- "shasum": ""
- },
- "require": {
- "php": "^5.3 || ^7.0",
- "symfony/process": "^2.3|^3.0|^4.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.8.35|^5.7",
- "psr/log": "^1.0"
- },
- "suggest": {
- "psr/log": "Add some log"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Gitonomy\\Git\\": "src/Gitonomy/Git/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Alexandre Salomé",
- "email": "alexandre.salome@gmail.com",
- "homepage": "http://alexandre-salome.fr"
- },
- {
- "name": "Julien DIDIER",
- "email": "genzo.wm@gmail.com",
- "homepage": "http://www.jdidier.net"
- }
- ],
- "description": "Library for accessing git",
- "homepage": "http://gitonomy.com",
- "time": "2018-04-22T19:55:36+00:00"
- },
- {
- "name": "guzzlehttp/guzzle",
- "version": "6.3.3",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/guzzle.git",
- "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba",
- "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba",
- "shasum": ""
- },
- "require": {
- "guzzlehttp/promises": "^1.0",
- "guzzlehttp/psr7": "^1.4",
- "php": ">=5.5"
- },
- "require-dev": {
- "ext-curl": "*",
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
- "psr/log": "^1.0"
- },
- "suggest": {
- "psr/log": "Required for using the Log middleware"
+ "doctrine/coding-standard": "~0.1@dev",
+ "phpunit/phpunit": "^5.7"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "6.3-dev"
+ "dev-master": "1.3.x-dev"
}
},
- "autoload": {
- "files": [
- "src/functions_include.php"
- ],
- "psr-4": {
- "GuzzleHttp\\": "src/"
+ "autoload": {
+ "psr-0": {
+ "Doctrine\\Common\\Collections\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2624,57 +2788,69 @@
],
"authors": [
{
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
}
],
- "description": "Guzzle is a PHP HTTP client library",
- "homepage": "http://guzzlephp.org/",
+ "description": "Collections Abstraction library",
+ "homepage": "http://www.doctrine-project.org",
"keywords": [
- "client",
- "curl",
- "framework",
- "http",
- "http client",
- "rest",
- "web service"
+ "array",
+ "collections",
+ "iterator"
],
- "time": "2018-04-22T15:46:56+00:00"
+ "time": "2017-07-22T10:37:32+00:00"
},
{
- "name": "guzzlehttp/promises",
- "version": "v1.3.1",
+ "name": "doctrine/instantiator",
+ "version": "1.1.0",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/promises.git",
- "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
- "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
"shasum": ""
},
"require": {
- "php": ">=5.5.0"
+ "php": "^7.1"
},
"require-dev": {
- "phpunit/phpunit": "^4.0"
+ "athletic/athletic": "~0.1.8",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpunit/phpunit": "^6.2.3",
+ "squizlabs/php_codesniffer": "^3.0.2"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.4-dev"
+ "dev-master": "1.2.x-dev"
}
},
"autoload": {
"psr-4": {
- "GuzzleHttp\\Promise\\": "src/"
- },
- "files": [
- "src/functions_include.php"
- ]
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2682,55 +2858,54 @@
],
"authors": [
{
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "http://ocramius.github.com/"
}
],
- "description": "Guzzle promises library",
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://github.com/doctrine/instantiator",
"keywords": [
- "promise"
+ "constructor",
+ "instantiate"
],
- "time": "2016-12-20T10:07:11+00:00"
+ "time": "2017-07-22T11:58:36+00:00"
},
{
- "name": "guzzlehttp/psr7",
- "version": "1.5.2",
+ "name": "gitonomy/gitlib",
+ "version": "v1.0.4",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/psr7.git",
- "reference": "9f83dded91781a01c63574e387eaa769be769115"
+ "url": "https://github.com/gitonomy/gitlib.git",
+ "reference": "932a960221ae3484a3e82553b3be478e56beb68d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115",
- "reference": "9f83dded91781a01c63574e387eaa769be769115",
+ "url": "https://api.github.com/repos/gitonomy/gitlib/zipball/932a960221ae3484a3e82553b3be478e56beb68d",
+ "reference": "932a960221ae3484a3e82553b3be478e56beb68d",
"shasum": ""
},
"require": {
- "php": ">=5.4.0",
- "psr/http-message": "~1.0",
- "ralouphie/getallheaders": "^2.0.5"
- },
- "provide": {
- "psr/http-message-implementation": "1.0"
+ "php": "^5.3 || ^7.0",
+ "symfony/process": "^2.3|^3.0|^4.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
+ "phpunit/phpunit": "^4.8.35|^5.7",
+ "psr/log": "^1.0"
+ },
+ "suggest": {
+ "psr/log": "Add some log"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.5-dev"
+ "dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
- "GuzzleHttp\\Psr7\\": "src/"
- },
- "files": [
- "src/functions_include.php"
- ]
+ "Gitonomy\\Git\\": "src/Gitonomy/Git/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2738,27 +2913,19 @@
],
"authors": [
{
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
+ "name": "Alexandre Salomé",
+ "email": "alexandre.salome@gmail.com",
+ "homepage": "http://alexandre-salome.fr"
},
{
- "name": "Tobias Schultze",
- "homepage": "https://github.com/Tobion"
+ "name": "Julien DIDIER",
+ "email": "genzo.wm@gmail.com",
+ "homepage": "http://www.jdidier.net"
}
],
- "description": "PSR-7 message implementation that also provides common utility methods",
- "keywords": [
- "http",
- "message",
- "psr-7",
- "request",
- "response",
- "stream",
- "uri",
- "url"
- ],
- "time": "2018-12-04T20:46:45+00:00"
+ "description": "Library for accessing git",
+ "homepage": "http://gitonomy.com",
+ "time": "2018-04-22T19:55:36+00:00"
},
{
"name": "infection/infection",
@@ -3711,7 +3878,7 @@
"homepage": "http://blog.astrumfutura.com"
},
{
- "name": "Théo FIDRY",
+ "name": "Théo Fidry",
"email": "theo.fidry@gmail.com"
}
],
@@ -3921,89 +4088,6 @@
"description": "Library for handling version information and constraints",
"time": "2018-07-08T19:19:57+00:00"
},
- {
- "name": "php-coveralls/php-coveralls",
- "version": "v2.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/php-coveralls/php-coveralls.git",
- "reference": "3b00c229726f892bfdadeaf01ea430ffd04a939d"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-coveralls/php-coveralls/zipball/3b00c229726f892bfdadeaf01ea430ffd04a939d",
- "reference": "3b00c229726f892bfdadeaf01ea430ffd04a939d",
- "shasum": ""
- },
- "require": {
- "ext-json": "*",
- "ext-simplexml": "*",
- "guzzlehttp/guzzle": "^6.0",
- "php": "^5.5 || ^7.0",
- "psr/log": "^1.0",
- "symfony/config": "^2.1 || ^3.0 || ^4.0",
- "symfony/console": "^2.1 || ^3.0 || ^4.0",
- "symfony/stopwatch": "^2.0 || ^3.0 || ^4.0",
- "symfony/yaml": "^2.0 || ^3.0 || ^4.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.8.35 || ^5.4.3 || ^6.0"
- },
- "suggest": {
- "symfony/http-kernel": "Allows Symfony integration"
- },
- "bin": [
- "bin/php-coveralls"
- ],
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.1-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "PhpCoveralls\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Kitamura Satoshi",
- "email": "with.no.parachute@gmail.com",
- "homepage": "https://www.facebook.com/satooshi.jp",
- "role": "Original creator"
- },
- {
- "name": "Takashi Matsuo",
- "email": "tmatsuo@google.com"
- },
- {
- "name": "Google Inc"
- },
- {
- "name": "Dariusz Ruminski",
- "email": "dariusz.ruminski@gmail.com",
- "homepage": "https://github.com/keradus"
- },
- {
- "name": "Contributors",
- "homepage": "https://github.com/php-coveralls/php-coveralls/graphs/contributors"
- }
- ],
- "description": "PHP client library for Coveralls API",
- "homepage": "https://github.com/php-coveralls/php-coveralls",
- "keywords": [
- "ci",
- "coverage",
- "github",
- "test"
- ],
- "time": "2018-05-22T23:11:08+00:00"
- },
{
"name": "phpdocumentor/reflection-common",
"version": "1.0.1",
@@ -4506,6 +4590,57 @@
"description": "PHPStan - PHP Static Analysis Tool",
"time": "2019-03-14T14:46:15+00:00"
},
+ {
+ "name": "phpstan/phpstan-phpunit",
+ "version": "0.11",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpstan-phpunit.git",
+ "reference": "70c22d44b96a21a4952fc13021a5a63cc83f5c81"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/70c22d44b96a21a4952fc13021a5a63cc83f5c81",
+ "reference": "70c22d44b96a21a4952fc13021a5a63cc83f5c81",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.0",
+ "php": "~7.1",
+ "phpstan/phpdoc-parser": "^0.3",
+ "phpstan/phpstan": "^0.11"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<7.0"
+ },
+ "require-dev": {
+ "consistence/coding-standard": "^3.0.1",
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
+ "jakub-onderka/php-parallel-lint": "^1.0",
+ "phing/phing": "^2.16.0",
+ "phpstan/phpstan-strict-rules": "^0.11",
+ "phpunit/phpunit": "^7.0",
+ "satooshi/php-coveralls": "^1.0",
+ "slevomat/coding-standard": "^4.5.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.11-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PHPStan\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "PHPUnit extensions and rules for PHPStan",
+ "time": "2018-12-22T14:05:04+00:00"
+ },
{
"name": "phpstan/phpstan-strict-rules",
"version": "0.11",
@@ -4886,46 +5021,6 @@
],
"time": "2019-03-16T07:33:46+00:00"
},
- {
- "name": "ralouphie/getallheaders",
- "version": "2.0.5",
- "source": {
- "type": "git",
- "url": "https://github.com/ralouphie/getallheaders.git",
- "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
- "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3"
- },
- "require-dev": {
- "phpunit/phpunit": "~3.7.0",
- "satooshi/php-coveralls": ">=1.0"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/getallheaders.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Ralph Khattar",
- "email": "ralph.khattar@gmail.com"
- }
- ],
- "description": "A polyfill for getallheaders.",
- "time": "2016-02-11T07:05:27+00:00"
- },
{
"name": "roave/security-advisories",
"version": "dev-master",
@@ -6017,16 +6112,16 @@
},
{
"name": "squizlabs/php_codesniffer",
- "version": "3.4.0",
+ "version": "3.4.1",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "379deb987e26c7cd103a7b387aea178baec96e48"
+ "reference": "5b4333b4010625d29580eb4a41f1e53251be6baa"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/379deb987e26c7cd103a7b387aea178baec96e48",
- "reference": "379deb987e26c7cd103a7b387aea178baec96e48",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/5b4333b4010625d29580eb4a41f1e53251be6baa",
+ "reference": "5b4333b4010625d29580eb4a41f1e53251be6baa",
"shasum": ""
},
"require": {
@@ -6059,12 +6154,12 @@
}
],
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
- "homepage": "http://www.squizlabs.com/php-codesniffer",
+ "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
"keywords": [
"phpcs",
"standards"
],
- "time": "2018-12-19T23:57:18+00:00"
+ "time": "2019-03-19T03:22:27+00:00"
},
{
"name": "symfony/config",
@@ -6540,56 +6635,6 @@
"homepage": "https://symfony.com",
"time": "2019-01-24T22:05:03+00:00"
},
- {
- "name": "symfony/stopwatch",
- "version": "v4.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/stopwatch.git",
- "reference": "b1a5f646d56a3290230dbc8edf2a0d62cda23f67"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b1a5f646d56a3290230dbc8edf2a0d62cda23f67",
- "reference": "b1a5f646d56a3290230dbc8edf2a0d62cda23f67",
- "shasum": ""
- },
- "require": {
- "php": "^7.1.3",
- "symfony/contracts": "^1.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Stopwatch\\": ""
- },
- "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": "Symfony Stopwatch Component",
- "homepage": "https://symfony.com",
- "time": "2019-01-16T20:31:39+00:00"
- },
{
"name": "symfony/yaml",
"version": "v4.2.4",
@@ -6883,8 +6928,11 @@
"prefer-lowest": false,
"platform": {
"php": ">=7.2",
+ "ext-json": "*",
"ext-pdo": "*",
- "ext-json": "*"
+ "ext-sodium": "*"
},
- "platform-dev": []
+ "platform-dev": {
+ "ext-xdebug": "*"
+ }
}
diff --git a/composerRequireChecker.json b/composerRequireChecker.json
index 73b54c6..2719d1f 100644
--- a/composerRequireChecker.json
+++ b/composerRequireChecker.json
@@ -7,7 +7,10 @@
"Swift_SmtpTransport",
"Swift_Mailer",
"Swift_Message",
- "Swift_SendmailTransport"
+ "Swift_SendmailTransport",
+ "Swift_Plugins_LoggerPlugin",
+ "Swift_Transport",
+ "Swift_Plugins_Logger"
],
"php-core-extensions" : [
"Core",
diff --git a/config/develop.php b/config/develop.php
index 3c05175..cb10887 100644
--- a/config/develop.php
+++ b/config/develop.php
@@ -1,5 +1,5 @@
__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR . 'app.log'
],
'settings.mail' => [
- 'transport' => 'null'
+ 'transport' => 'null',
+ 'fromname' => 'PublicWhip Development',
+ 'fromaddress' => 'null@publicwhip.localdomain'
],
'settings.debug' => true,
'settings.templates.cache' => false
diff --git a/config/docker.php b/config/docker.php
index 4346c0a..c4426be 100644
--- a/config/docker.php
+++ b/config/docker.php
@@ -1,7 +1,8 @@
''
],
'settings.mail' => [
- 'transport' => 'sendmail',
+ 'transport' => 'smtp',
'host' => 'mailhog',
'port' => 1025,
'username' => '',
- 'password' => ''
+ 'password' => '',
+ 'fromname' => 'PublicWhip Development',
+ 'fromaddress' => 'null@publicwhip.org.uk'
]
]
);
diff --git a/config/production.php b/config/production.php
index b69e186..8047ba0 100644
--- a/config/production.php
+++ b/config/production.php
@@ -1,5 +1,5 @@
[
@@ -20,7 +20,9 @@
'host' => 'mailhog',
'port' => 1025,
'username' => '',
- 'password' => ''
+ 'password' => '',
+ 'fromname' => 'PublicWhip Development',
+ 'fromaddress' => 'null@publicwhip.org.uk'
],
'settings.debug' => false,
'settings.templates.cache' => __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'cache'
diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile
index 1b060d0..76303de 100644
--- a/docker/php/Dockerfile
+++ b/docker/php/Dockerfile
@@ -1,7 +1,13 @@
FROM php:7.3-fpm-alpine
-RUN docker-php-ext-install pdo_mysql
+
+# Add packages
RUN apk update && apk upgrade && \
apk add --no-cache bash git openssh
+
+# Add pdo_mysql
+RUN docker-php-ext-install pdo_mysql
+
+# Add xDebug
RUN apk add --no-cache $PHPIZE_DEPS \
&& pecl install xdebug-2.7.0 \
&& docker-php-ext-enable xdebug
diff --git a/docs/CODE_OF_CONDUCT.md b/docs/CODE_OF_CONDUCT.md
index 0a40a2f..dd83c3c 100644
--- a/docs/CODE_OF_CONDUCT.md
+++ b/docs/CODE_OF_CONDUCT.md
@@ -4,7 +4,8 @@ The PublicWhip code of conduct is derived from the Ruby code of conduct.
This document provides community guidelines for a safe, respectful, productive, and collaborative place for any
person who is willing to contribute to the PublicWhip community. It applies to all “collaborative space”, which is
-defined as community communications channels (such as mailing lists, IRC, Slack, forums, submitted patches, commit comments, etc.).
+defined as community communications channels (such as mailing lists, IRC, Slack, forums, submitted patches,
+commit comments, etc.).
Any violations of the code of conduct may be reported by contacting one or more of the project maintainers either
directly or via email to team@publicwhip.org.uk .
diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md
index 70e6092..6b82129 100644
--- a/docs/ChangeLog.md
+++ b/docs/ChangeLog.md
@@ -3,6 +3,10 @@
These are items that have been done and released. To see what's planned, have a look at the
[Milestones](Milestones.md).
+* 0.4.3 - Move over to the Doctrine coding standard.
+
+ Add more code quality checks.
+
* 0.4.2 - Ensure division data from v1 is processed correctly: Estimate 1 day. DONE - 2019-03-17
Added code from `originalPublicWhipCode` and associated data extractors (in `v1migrationUtils`)
@@ -14,8 +18,6 @@ These are items that have been done and released. To see what's planned, have a
Standardise on the spelling/format of `PublicWhip`.
- Add coveralls coverage.
-
* 0.4.1 - Improved coding style and fixes. DONE - 2019-03-16
* 0.4 - Get accurate information about Divisions showing: Estimate 1-2 days. DONE - 2019-03-15
diff --git a/phpcs.xml b/phpcs.xml
index a893876..753e60b 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -1,6 +1,15 @@
PublicWhip Ruleset.
+
+
+
+
+
+
+
+
+
src
tests
v1migrationUtils
@@ -9,287 +18,108 @@
./.idea/
./originalPublicWhipCode/
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
+
+
+
+
-
-
+
+
-
-
+
+
+
+
+
-
-
-
-
+
+
-
-
+
+
-
-
-
-
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- error
- The "goto" language construct should not be used.
-
-
-
-
-
-
-
-
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
-
- warning
-
-
- warning
-
-
- warning
-
-
-
-
-
- 0
-
-
-
-
-
-
-
-
-
-
- 0
-
-
-
-
-
-
-
-
-
-
-
-
-
- error
- eval() is a security risk so not allowed.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/phpstan.neon b/phpstan.neon
index ee30dfb..f0791b8 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,5 +1,6 @@
includes:
- vendor/phpstan/phpstan-strict-rules/rules.neon
+ - vendor/phpstan/phpstan-phpunit/extension.neon
parameters:
level: 7
paths:
@@ -13,6 +14,6 @@ parameters:
message: '#Variable property access on object.#'
path: %currentWorkingDirectory%/src/Factories/EntityFactory.php
-
- message: '#Parameter \#4 \$routeArguments \(array\\) of method#'
+ message: '#Parameter \#4 \$routeArguments \(array\
+ * @return array
*/
public function getWebConfig(): array
{
@@ -91,6 +92,7 @@ public function getWebConfig(): array
TwigExtension::class => static function (ContainerInterface $container): TwigExtension {
$router = $container->get('router');
$uri = $container->get('request')->getUri();
+
return new TwigExtension($router, $uri);
},
TemplateProviderInterface::class => autowire(TemplateProvider::class),
@@ -126,6 +128,7 @@ public function getWebConfig(): array
// setup parsedown for markdown formatting.
Parsedown::class => create()
];
+
return array_merge($this->generalSlimSetup(), $return);
}
@@ -133,9 +136,9 @@ public function getWebConfig(): array
* Get the general Slim settings.
* /**
* Disable this PHPMD warning for simplicity when building the environment using Request::.
- * @SuppressWarnings(PHPMD.StaticAccess)
*
- * @return array):
+ * @SuppressWarnings(PHPMD.StaticAccess)
+ * @return array
*/
private function generalSlimSetup(): array
{
@@ -173,15 +176,16 @@ private function generalSlimSetup(): array
return new Environment($_SERVER);
},
-
'request' => static function (ContainerInterface $container) {
return Request::createFromEnvironment($container->get('environment'));
},
'response' => static function (ContainerInterface $container) {
$headers = new Headers(['Content-Type' => 'text/html; charset=UTF-8']);
+
return (new Response(200, $headers))->withProtocolVersion($container->get('settings')['httpVersion']);
},
+
'foundHandler' => create(ControllerInvokerProvider::class)
->constructor(get('foundHandler.invoker')),
'foundHandler.invoker' => static function (ContainerInterface $container) {
@@ -193,6 +197,7 @@ private function generalSlimSetup(): array
// Then fall back on parameters default values for optional route parameters
new DefaultValueResolver()
];
+
return new Invoker(new ResolverChain($resolvers), $container);
},
@@ -203,7 +208,7 @@ private function generalSlimSetup(): array
/**
* The general configurations needed to run the system (no matter what environment).
*
- * @return array
+ * @return array
*/
public function getGeneralConfig(): array
{
@@ -224,9 +229,11 @@ public function getGeneralConfig(): array
$logger->pushProcessor(new MemoryUsageProcessor());
$logger->pushHandler(new StreamHandler($settings['path'], Logger::DEBUG));
$logger->pushProcessor(new IntrospectionProcessor());
+
if ($container->get('settings.isWeb') && $container->has('environment')) {
$logger->pushProcessor(new WebProcessor($container->get('environment')));
}
+
// add it to the debugger
$debugger = $container->get(DebuggerProviderInterface::class);
$debugger->addDataCollector(new MonologCollector($logger));
@@ -252,16 +259,36 @@ public function getGeneralConfig(): array
DatabaseProviderInterface::class => create(DatabaseProvider::class)
->constructor(get('settings.db'))
->method('addToDebugger', get(DebuggerProviderInterface::class)),
- MailerProviderInterface::class => create(MailerProvider::class)
- ->constructor(get('settings.mail'))
- ->method('addToDebugger', get(DebuggerProviderInterface::class)),
+
+ MailerProviderInterface::class => static function (ContainerInterface $container): MailerProviderInterface {
+ /** @var array|null $settings */
+ $settings = $container->get('settings.mail');
+ if (!is_array($settings)) {
+ throw new RuntimeException('Missing settings.mail');
+ }
+ if (!isset($settings['fromname']) || !is_string($settings['fromname'])) {
+ throw new RuntimeException('Missing settings.mail.fromname');
+ }
+ if (!isset($settings['fromaddress']) || !is_string($settings['fromaddress'])) {
+ throw new RuntimeException('Missing settings.mail.fromaddress');
+ }
+ $provider = new MailerProvider(
+ $container->get(MailerTransportProviderInterface::class),
+ $settings['fromname'],
+ $settings['fromaddress']
+ );
+ $provider->addToDebugger($container->get(DebuggerProviderInterface::class));
+
+ return $provider;
+ },
+ MailerTransportProviderInterface::class => create(MailerTransportProvider::class)
+ ->constructor(get('settings.mail')),
DebuggerProviderInterface::class => create(DebuggerProvider::class)
->constructor(get('settings.debug')),
WikiParserProviderInterface::class => autowire(WikiParserProvider::class)
->constructorParameter('logger', get('logger.providers'))
-
];
/**
* Factories
@@ -279,6 +306,7 @@ public function getGeneralConfig(): array
DivisionServiceInterface::class => autowire(DivisionService::class)
->constructorParameter('logger', get('logger.services'))
];
+
return array_merge($defaultSettings, $loggers, $providers, $factories, $services);
}
}
diff --git a/src/Entities/DivisionEntity.php b/src/Entities/DivisionEntity.php
index 052f3eb..eb31999 100644
--- a/src/Entities/DivisionEntity.php
+++ b/src/Entities/DivisionEntity.php
@@ -1,88 +1,118 @@
logger->info('Creating dateTimeImmutable from {ymd} in yyyy-mm-dd format', ['ymd' => $ymd]);
$date = DateTimeImmutable::createFromFormat('!Y-m-d', $ymd);
+
if (!$date instanceof DateTimeImmutable) {
$errors = DateTimeImmutable::getLastErrors();
$encoded = json_encode($errors);
@@ -54,8 +50,10 @@ public function dateTimeImmutableFromYyyyMmDd(string $ymd): DateTimeImmutable
$encoded ?: '[failed]'
);
$this->logger->warning($message);
+
throw new BadDateTimeException($message);
}
+
return $date;
}
}
diff --git a/src/Factories/DateTimeFactoryInterface.php b/src/Factories/DateTimeFactoryInterface.php
index 56eca5f..838d925 100644
--- a/src/Factories/DateTimeFactoryInterface.php
+++ b/src/Factories/DateTimeFactoryInterface.php
@@ -1,5 +1,5 @@
logger = $logger;
}
+ /**
+ * Build a division.
+ *
+ * @param array $data Data to build the entity with.
+ * @return DivisionEntity
+ */
+ public function division(array $data): DivisionEntity
+ {
+ /** @var DivisionEntity $entity */
+ $entity = $this->buildFromArray(
+ $data,
+ DivisionEntity::class,
+ [
+ 'divisionId' => 'int',
+ 'date' => DateTimeImmutable::class,
+ 'number' => 'int',
+ 'sourceUrl' => 'string',
+ 'debateUrl' => 'string',
+ 'motionText' => 'string',
+ 'house' => 'string',
+ 'motionTitle' => 'string',
+ 'originalMotionText' => 'string',
+ 'originalMotionTitle' => 'string'
+ ],
+ [
+ 'rebellions' => 'int',
+ 'turnout' => 'int',
+ 'possibleTurnout' => 'int',
+ 'ayeMajority' => 'int'
+ ]
+ );
+
+ return $entity;
+ }
+
/**
* Build an entity from an array.
*
- * @param array $data The data to build from.
+ * @param array $data The data to build from.
* @param string $entityName Name of the entity to build.
- * @param array $required The required data configuration.
- * @param array $optional The optional data configuration.
- *
+ * @param array $required The required data configuration.
+ * @param array $optional The optional data configuration.
* @return object
*/
private function buildFromArray(array $data, string $entityName, array $required, array $optional): object
{
$this->logger->debug('Building ' . $entityName);
$new = new $entityName();
+
/**
* Handles hydration without having to use reflection.
*
* @param object $object Object we are modifying.
* @param string $property Name of the property.
- * @param mixed $newValue New value.
+ * @param string|bool|int|float $newValue New value.
*/
$hydrate = function (object $object, string $property, $newValue): void {
Closure::bind(function () use ($property, $newValue): void {
$this->$property = $newValue;
}, $object, $object)->__invoke();
};
+
$fieldsMapped = $this->fillRequiredFields($new, $required, $data, $hydrate, $entityName);
$fieldsMapped = $this->fillOptionalFields($new, $optional, $data, $hydrate, $entityName, $fieldsMapped);
@@ -71,6 +104,7 @@ private function buildFromArray(array $data, string $entityName, array $required
* Check that all fields were loaded.
*/
$difference = array_diff(array_keys($data), $fieldsMapped);
+
if (count($difference) > 0) {
$this->logger->warning(
'The entity {entityName} was passed the following field(s) which it does ' .
@@ -82,8 +116,10 @@ private function buildFromArray(array $data, string $entityName, array $required
$entityName,
implode(', ', $difference)
);
+
throw new EntityFactoryUnrecognisedFieldException($message);
}
+
return $new;
}
@@ -91,11 +127,10 @@ private function buildFromArray(array $data, string $entityName, array $required
* Fill required fields fields.
*
* @param object $new The object we are hydrating.
- * @param array $required The configuration for the required fields.
- * @param array $data The provided data.
+ * @param array $required Name of field as key, type of field as value.
+ * @param array $data The provided data.
* @param callable $hydrate Our hydrator.
* @param string $entityName Name of the entity
- *
* @return array Mapped fields
*/
private function fillRequiredFields(
@@ -104,9 +139,9 @@ private function fillRequiredFields(
array $data,
callable $hydrate,
string $entityName
- ): array
- {
+ ): array {
$fieldsMapped = [];
+
foreach ($required as $name => $type) {
if (!isset($data[$name])) {
$this->logger->error(
@@ -118,8 +153,10 @@ private function fillRequiredFields(
$name,
$entityName
);
+
throw new EntityMissingRequiredFieldException($message);
}
+
if (!self::checkType($name, $type, $data[$name])) {
$actualType = is_object($data[$name]) ? get_class($data[$name]) : gettype($data[$name]);
$this->logger->error(
@@ -139,24 +176,70 @@ private function fillRequiredFields(
$actualType,
$entityName
);
+
throw new EntityFieldWrongTypeException($message);
}
+
$hydrate($new, $name, $data[$name]);
$fieldsMapped[] = $name;
}
+
return $fieldsMapped;
}
+ /**
+ * Checks that the field is of the expected type.
+ *
+ * @param string $fieldName Name of the field (for error reporting).
+ * @param string $expectedType String of the expected type.
+ * @param string|int|float|object|bool $value The value to check.
+ * @return bool
+ */
+ private static function checkType(string $fieldName, string $expectedType, $value): bool
+ {
+ $correctType = true;
+
+ switch ($expectedType) {
+ case 'int':
+ if (!is_int($value)) {
+ $correctType = false;
+ }
+
+ break;
+ case 'string':
+ if (!is_string($value)) {
+ $correctType = false;
+ }
+
+ break;
+ case DateTimeImmutable::class:
+ if (!$value instanceof DateTimeImmutable) {
+ $correctType = false;
+ }
+
+ break;
+ default:
+ throw new EntityFieldWrongTypeException(
+ sprintf(
+ 'Bad definition found for field %s in %s',
+ $fieldName,
+ self::class
+ )
+ );
+ }
+
+ return $correctType;
+ }
+
/**
* Fill optional fields.
*
* @param object $new The object we are hydrating.
- * @param array $optional The configuration for the optional fields.
- * @param array $data The provided data.
+ * @param array $optional Name of field as key, type of field as value.
+ * @param array $data The provided data.
* @param callable $hydrate Our hydrator.
* @param string $entityName Name of the entity
* @param array $fieldsMapped List of fields already mapped.
- *
* @return array Mapped fields
*/
private function fillOptionalFields(
@@ -166,11 +249,11 @@ private function fillOptionalFields(
callable $hydrate,
string $entityName,
array $fieldsMapped
- ): array
- {
+ ): array {
foreach ($optional as $name => $type) {
if (isset($data[$name])) {
$hydrate($new, $name, null);
+
if (!self::checkType($name, $type, $data[$name])) {
$actualType = is_object($data[$name]) ? get_class($data[$name]) : gettype($data[$name]);
$this->logger->error(
@@ -190,87 +273,16 @@ private function fillOptionalFields(
$actualType,
$entityName
);
+
throw new EntityFieldWrongTypeException($message);
}
+
$hydrate($new, $name, $data[$name]);
}
- $fieldsMapped[] = $name;
- }
- return $fieldsMapped;
- }
- /**
- * Checks that the field is of the expected type.
- *
- * @param string $fieldName Name of the field (for error reporting).
- * @param string $expectedType String of the expected type.
- * @param mixed $value The value to check.
- *
- * @return bool
- */
- private static function checkType(string $fieldName, string $expectedType, $value): bool
- {
- $correctType = true;
- switch ($expectedType) {
- case 'int':
- if (!is_int($value)) {
- $correctType = false;
- }
- break;
- case 'string':
- if (!is_string($value)) {
- $correctType = false;
- }
- break;
- case DateTimeImmutable::class:
- if (!$value instanceof DateTimeImmutable) {
- $correctType = false;
- }
- break;
- default:
- throw new EntityFieldWrongTypeException(
- sprintf(
- 'Bad definition found for field %s in %s',
- $fieldName,
- self::class
- )
- );
+ $fieldsMapped[] = $name;
}
- return $correctType;
- }
- /**
- * Build a division.
- *
- * @param array $data Data to build the entity with.
- *
- * @return DivisionEntity
- */
- public function division(array $data): DivisionEntity
- {
- /** @var DivisionEntity $entity */
- $entity = $this->buildFromArray(
- $data,
- DivisionEntity::class,
- [
- 'divisionId' => 'int',
- 'date' => DateTimeImmutable::class,
- 'number' => 'int',
- 'sourceUrl' => 'string',
- 'debateUrl' => 'string',
- 'motionText' => 'string',
- 'house' => 'string',
- 'motionTitle' => 'string',
- 'originalMotionText' => 'string',
- 'originalMotionTitle' => 'string'
- ],
- [
- 'rebellions' => 'int',
- 'turnout' => 'int',
- 'possibleTurnout' => 'int',
- 'ayeMajority' => 'int'
- ]
- );
- return $entity;
+ return $fieldsMapped;
}
}
diff --git a/src/Factories/EntityFactoryInterface.php b/src/Factories/EntityFactoryInterface.php
index 6c7bb18..ebc7e37 100644
--- a/src/Factories/EntityFactoryInterface.php
+++ b/src/Factories/EntityFactoryInterface.php
@@ -1,5 +1,5 @@
$data Data to build the entity with.
- *
+ * @param array$data Data to build the entity with.
* @return DivisionEntity
*/
public function division(array $data): DivisionEntity;
diff --git a/src/Providers/CallableResolverProvider.php b/src/Providers/CallableResolverProvider.php
index 5e6e9d2..df3f3da 100644
--- a/src/Providers/CallableResolverProvider.php
+++ b/src/Providers/CallableResolverProvider.php
@@ -1,26 +1,27 @@
$routeArguments The route's placeholder arguments
* @return ResponseInterface|string The response from the callable.
* @throws InvocationException
* @throws NotCallableException
@@ -52,8 +48,7 @@ public function __invoke(
ServerRequestInterface $request,
ResponseInterface $response,
array $routeArguments
- )
- {
+ ) {
// Inject the request and response by parameter name
$parameters = [
'request' => $request,
diff --git a/src/Providers/DatabaseProvider.php b/src/Providers/DatabaseProvider.php
index d0b9927..5d3adbd 100644
--- a/src/Providers/DatabaseProvider.php
+++ b/src/Providers/DatabaseProvider.php
@@ -1,5 +1,5 @@
$config Configuration settings.
*/
public function __construct(array $config)
{
@@ -76,6 +74,7 @@ public function __construct(array $config)
$this->setEventDispatcher(new Dispatcher($this->container));
Model::setConnectionResolver($this->manager);
$dispatcher = $this->getEventDispatcher();
+
if (null === $dispatcher) {
return;
}
@@ -86,9 +85,9 @@ public function __construct(array $config)
/**
* Add a new connection.
*
- * @param string[] $config Configuration settings.
+ * @param array $config Configuration settings.
* @param string|null $name Name of the configuration.
- * */
+ */
public function addConnection(array $config, ?string $name = null): void
{
$name = $name ?: self::DEFAULT_CONNECTION_NAME;
@@ -101,7 +100,7 @@ public function addConnection(array $config, ?string $name = null): void
* Set the event dispatcher.
*
* @param Dispatcher $dispatcher Dispatcher.
- * */
+ */
public function setEventDispatcher(Dispatcher $dispatcher): void
{
$this->container->instance('events', $dispatcher);
@@ -117,6 +116,7 @@ public function getEventDispatcher(): ?Dispatcher
if ($this->container->bound('events')) {
return $this->container['events'];
}
+
return null;
}
@@ -125,12 +125,12 @@ public function getEventDispatcher(): ?Dispatcher
*
* @param string $table Name of the table.
* @param Connection|null $connection Connection to use.
- *
* @return QueryBuilder
*/
public function table(string $table, ?Connection $connection = null): QueryBuilder
{
$connectionName = $connection ? $connection->getName() : self::DEFAULT_CONNECTION_NAME;
+
return $this->getConnection($connectionName)->table($table);
}
@@ -138,7 +138,6 @@ public function table(string $table, ?Connection $connection = null): QueryBuild
* Get a named connection.
*
* @param string|null $name Name of the connection (or null for default)
- *
* @return Connection
*/
public function getConnection(?string $name = null): Connection
@@ -150,12 +149,12 @@ public function getConnection(?string $name = null): Connection
* Get the schema builder.
*
* @param Connection|null $connection Connection to use.
- *
* @return SchemaBuilder
*/
public function schema(?Connection $connection = null): SchemaBuilder
{
$connectionName = $connection ? $connection->getName() : self::DEFAULT_CONNECTION_NAME;
+
return $this->getConnection($connectionName)->getSchemaBuilder();
}
@@ -163,14 +162,14 @@ public function schema(?Connection $connection = null): SchemaBuilder
* Get an eloquent model.
*
* @param string $model Name of the model.
- *
- * @return mixed
+ * @return EloquentBuilder
*/
- public function query(string $model)
+ public function query(string $model): EloquentBuilder
{
$entity = str_replace(':', '\\Model\\', '\\' . $model);
/** @var Model $entity */
$entity = new $entity();
+
return $entity->newQuery();
}
@@ -188,7 +187,7 @@ public function getContainer(): Container
* Set the container.
*
* @param Container $container Set the eloquent container.
- * */
+ */
public function setContainer(Container $container): void
{
$this->container = $container;
@@ -198,12 +197,12 @@ public function setContainer(Container $container): void
* Set the fetch mode.
*
* @param string $fetchMode Fetch mode.
- *
* @return DatabaseProviderInterface
*/
public function setFetchMode(string $fetchMode): DatabaseProviderInterface
{
$this->container['config']['database.fetch'] = $fetchMode;
+
return $this;
}
@@ -221,7 +220,6 @@ public function getDatabaseManager(): DatabaseManager
* Addable to a debugger.
*
* @param DebuggerProviderInterface $debugger Debugger to add.
- * *
* @throws DebugBarException
*/
public function addToDebugger(DebuggerProviderInterface $debugger): void
diff --git a/src/Providers/DatabaseProviderInterface.php b/src/Providers/DatabaseProviderInterface.php
index 1d6c5ae..edb387f 100644
--- a/src/Providers/DatabaseProviderInterface.php
+++ b/src/Providers/DatabaseProviderInterface.php
@@ -1,5 +1,5 @@
$config
*/
public function __construct(array $config);
/**
* Add a new connection.
*
- * @param string[] $config Configuration settings.
+ * @param array $config Configuration settings.
* @param string|null $name Name of the configuration.
- * */
+ */
public function addConnection(array $config, ?string $name = null): void;
/**
* Set the event dispatcher.
*
* @param Dispatcher $dispatcher Dispatcher.
- * */
+ */
public function setEventDispatcher(Dispatcher $dispatcher): void;
/**
@@ -51,7 +52,6 @@ public function getEventDispatcher(): ?Dispatcher;
*
* @param string $table Name of the table.
* @param Connection|null $connection Connection to use.
- *
* @return QueryBuilder
*/
public function table(string $table, ?Connection $connection = null): QueryBuilder;
@@ -60,7 +60,6 @@ public function table(string $table, ?Connection $connection = null): QueryBuild
* Get a named connection.
*
* @param string|null $name Name of the connection (or null for default)
- *
* @return Connection
*/
public function getConnection(?string $name = null): Connection;
@@ -69,7 +68,6 @@ public function getConnection(?string $name = null): Connection;
* Get the schema builder.
*
* @param Connection|null $connection Connection to use.
- *
* @return SchemaBuilder
*/
public function schema(?Connection $connection = null): SchemaBuilder;
@@ -78,10 +76,9 @@ public function schema(?Connection $connection = null): SchemaBuilder;
* Get an eloquent model.
*
* @param string $model Name of the model.
- *
- * @return mixed
+ * @return EloquentBuilder
*/
- public function query(string $model);
+ public function query(string $model): EloquentBuilder;
/**
* Get the eloquent container.
@@ -94,15 +91,13 @@ public function getContainer(): Container;
* Set the container.
*
* @param Container $container Set the eloquent container.
- * */
+ */
public function setContainer(Container $container): void;
/**
* Set the fetch mode.
*
* @param string $fetchMode Fetch mode.
- *
- *
* @return DatabaseProviderInterface
*/
public function setFetchMode(string $fetchMode): DatabaseProviderInterface;
@@ -118,7 +113,6 @@ public function getDatabaseManager(): DatabaseManager;
* Addable to a debugger.
*
* @param DebuggerProviderInterface $debugger Debugger to add.
- * *
* @throws DebugBarException
*/
public function addToDebugger(DebuggerProviderInterface $debugger): void;
diff --git a/src/Providers/DebuggerProvider.php b/src/Providers/DebuggerProvider.php
index 6ef487d..51fdcd5 100644
--- a/src/Providers/DebuggerProvider.php
+++ b/src/Providers/DebuggerProvider.php
@@ -1,5 +1,5 @@
debugbar = new StandardDebugBar();
- $this->renderer = $this->debugbar->getJavascriptRenderer();
- $this->setBaseUrl('/debugbar');
+ if (!$active) {
+ return;
}
+
+ $this->debugbar = new StandardDebugBar();
+ $this->renderer = $this->debugbar->getJavascriptRenderer();
+ $this->setBaseUrl('/debugbar');
}
/**
* Set the base url for output rendering.
*
* @param string $url Base Url.
- * */
+ */
public function setBaseUrl(string $url): void
{
- if (null !== $this->renderer) {
- $this->renderer->setBaseUrl($url);
+ if (null === $this->renderer) {
+ return;
}
+
+ $this->renderer->setBaseUrl($url);
}
/**
* Add a new data collector to the debugger.
*
* @param DataCollectorInterface $collector The data collector we are adding.
- * *
* @throws DebugBarException
*/
public function addDataCollector(DataCollectorInterface $collector): void
{
- if (null !== $this->debugbar) {
- $this->debugbar->addCollector($collector);
+ if (null === $this->debugbar) {
+ return;
}
+
+ $this->debugbar->addCollector($collector);
}
/**
* Add a new messages collector.
*
* @param MessagesAggregateInterface $collector The collector we are adding.
- * */
+ */
public function addMessagesAggregateCollector(MessagesAggregateInterface $collector): void
{
- if (null !== $this->debugbar) {
- $this->debugbar['message']->aggregate($collector);
+ if (null === $this->debugbar) {
+ return;
}
+
+ $this->debugbar['messages']->aggregate($collector);
}
/**
@@ -84,25 +93,29 @@ public function addMessagesAggregateCollector(MessagesAggregateInterface $collec
*
* @param string $msg The message we are logging.
* @param string|null $level The severity level we are logging.
- * */
+ */
public function addMessage(string $msg, ?string $level = null): void
{
- if (null !== $this->debugbar) {
- $level = $level ?: 'info';
- $this->debugbar['messages']->log($level, $msg);
+ if (null === $this->debugbar) {
+ return;
}
+
+ $level = $level ?: 'info';
+ $this->debugbar['messages']->log($level, $msg);
}
/**
* Add an exception.
*
* @param Throwable $throwable The throwable we are handling.
- * */
+ */
public function addThrowable(Throwable $throwable): void
{
- if (null !== $this->debugbar) {
- $this->debugbar['exceptions']->addException($throwable);
+ if (null === $this->debugbar) {
+ return;
}
+
+ $this->debugbar['exceptions']->addException($throwable);
}
/**
@@ -112,10 +125,11 @@ public function addThrowable(Throwable $throwable): void
*/
public function getBaseUrl(): string
{
- if (null !== $this->renderer) {
- return $this->renderer->getBaseUrl();
+ if (null === $this->renderer) {
+ return '';
}
- return '';
+
+ return $this->renderer->getBaseUrl();
}
/**
@@ -125,10 +139,11 @@ public function getBaseUrl(): string
*/
public function getBasePath(): string
{
- if (null !== $this->renderer) {
- return $this->renderer->getBasePath();
+ if (null === $this->renderer) {
+ return '';
}
- return '';
+
+ return $this->renderer->getBasePath();
}
/**
@@ -138,10 +153,11 @@ public function getBasePath(): string
*/
public function renderHead(): string
{
- if (null !== $this->renderer) {
- return $this->renderer->renderHead();
+ if (null === $this->renderer) {
+ return '';
}
- return '';
+
+ return $this->renderer->renderHead();
}
/**
@@ -151,9 +167,10 @@ public function renderHead(): string
*/
public function renderBar(): string
{
- if (null !== $this->renderer) {
- return $this->renderer->render();
+ if (null === $this->renderer) {
+ return '';
}
- return '';
+
+ return $this->renderer->render();
}
}
diff --git a/src/Providers/DebuggerProviderInterface.php b/src/Providers/DebuggerProviderInterface.php
index 758d3e4..edbe07b 100644
--- a/src/Providers/DebuggerProviderInterface.php
+++ b/src/Providers/DebuggerProviderInterface.php
@@ -1,22 +1,20 @@
uri, 'getBaseUrl')) {
return $this->uri->getBaseUrl();
}
+
return '';
}
/**
* Get the twig functions
- * @return TwigFunction[]
+ *
+ * @return array
*/
public function getFunctions(): array
{
@@ -65,6 +67,7 @@ public function getFunctions(): array
/**
* Get the debug header.
+ *
* @return string
*/
public function debugHeadFunction(): string
@@ -74,6 +77,7 @@ public function debugHeadFunction(): string
/**
* Get the debug bar main body.
+ *
* @return string
*/
public function debugBarFunction(): string
diff --git a/src/Providers/MailerProvider.php b/src/Providers/MailerProvider.php
index 59cf38d..b4e8549 100644
--- a/src/Providers/MailerProvider.php
+++ b/src/Providers/MailerProvider.php
@@ -1,55 +1,57 @@
setUsername($options['username'])
- ->setPassword($options['password']);
- break;
- case 'sendmail':
- $transport = new Swift_SendmailTransport($options['command']);
- break;
- default:
- throw new RuntimeException('Unrecognised mail transport');
- }
- $this->mailer = new Swift_Mailer($transport);
+ private $fromName;
+
+ /**
+ * Default from address.
+ *
+ * @var string
+ */
+ private $fromAddress;
+
+ /**
+ * Setup the mailer.
+ *
+ * @param MailerTransportProviderInterface $mailerTransport Built transport.
+ * @param string $fromName Default from name.
+ * @param string $fromAddress Default from address.
+ */
+ public function __construct(
+ MailerTransportProviderInterface $mailerTransport,
+ string $fromName,
+ string $fromAddress
+ ) {
+ $this->mailer = new Swift_Mailer($mailerTransport->getTransport());
+ $this->fromName = $fromName;
+ $this->fromAddress = $fromAddress;
}
/**
@@ -58,8 +60,7 @@ public function __construct(array $options)
* @param string $subject The subject of the email.
* @param string $toAddress Who it is going to.
* @param string $toName The name of the person it is going to.
- * @param string[] $body What the body of the email is.
- *
+ * @param array $body What the body of the email is.
* @return int The number of successful recipients. Can be 0 which indicates failure
*/
public function sendMultipartMail(string $subject, string $toAddress, string $toName, array $body): int
@@ -67,12 +68,16 @@ public function sendMultipartMail(string $subject, string $toAddress, string $to
if (0 === count($body)) {
return 0;
}
- $message = Swift_Message::newInstance($subject)->setTo($toAddress, $toName);
+
+ $message = (new Swift_Message($subject))->setTo([$toAddress => $toName]);
+ $message->setFrom([$this->fromAddress => $this->fromName]);
$message->addPart($body[0]);
next($body);
+
foreach ($body as $part) {
$message->addPart($part);
}
+
return $this->mailer->send($message);
}
@@ -83,13 +88,15 @@ public function sendMultipartMail(string $subject, string $toAddress, string $to
* @param string $toAddress Who it is going to.
* @param string $toName The name of the person it is going to.
* @param string $body What the body of the email is.
- *
* @return int The number of successful recipients. Can be 0 which indicates failure
*/
public function sendMail(string $subject, string $toAddress, string $toName, string $body): int
{
- $message = (new Swift_Message($subject))->setTo($toAddress, $toName);
+ $message = (new Swift_Message($subject))->setTo([$toAddress => $toName]);
+ $message->setFrom([$this->fromAddress => $this->fromName]);
+
$message->setBody($body);
+
return $this->mailer->send($message);
}
@@ -97,12 +104,63 @@ public function sendMail(string $subject, string $toAddress, string $toName, str
* Add a debugger.
*
* @param DebuggerProviderInterface $debugger The debugger to add.
- *
- * @throws DebugBarException
*/
public function addToDebugger(DebuggerProviderInterface $debugger): void
{
- $debugger->addMessagesAggregateCollector(new SwiftLogCollector($this->mailer));
+ // the SwiftLogCollector with Debugbar is outdated.
+ $logCollector = new class($this->mailer) extends MessagesCollector implements Swift_Plugins_Logger
+ {
+ /**
+ * Registers our plugin.
+ *
+ * @param Swift_Mailer $mailer The mailer object.
+ */
+ public function __construct(Swift_Mailer $mailer)
+ {
+ $mailer->registerPlugin(new Swift_Plugins_LoggerPlugin($this));
+ parent::__construct($this->getName());
+ }
+
+ /**
+ * Adds an entry
+ *
+ * Coding standard disabled for Swift compatibility.
+ * phpcs:disable SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint
+ * @param string $entry Details of message we are adding.
+ */
+ public function add($entry): void
+ {
+ $this->addMessage($entry);
+ }
+
+ // phpcs:enable SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint
+
+ /**
+ * Diagnostics.
+ *
+ * @return string
+ */
+ public function dump(): string
+ {
+ $text = json_encode($this->messages);
+ if (!is_string($text)) {
+ $text = '[Failed to encode]';
+ }
+
+ return $text;
+ }
+
+ /**
+ * Get the name.
+ *
+ * @return string
+ */
+ public function getName(): string
+ {
+ return 'mailerProviderSwift';
+ }
+ };
+ $debugger->addMessagesAggregateCollector($logCollector);
$debugger->addDataCollector(new SwiftMailCollector($this->mailer));
}
}
diff --git a/src/Providers/MailerProviderInterface.php b/src/Providers/MailerProviderInterface.php
index 07d3f73..e9cd57d 100644
--- a/src/Providers/MailerProviderInterface.php
+++ b/src/Providers/MailerProviderInterface.php
@@ -1,24 +1,25 @@
$body What the body of the email is.
* @return int The number of successful recipients. Can be 0 which indicates failure
*/
public function sendMultipartMail(string $subject, string $toAddress, string $toName, array $body): int;
@@ -39,7 +39,6 @@ public function sendMultipartMail(string $subject, string $toAddress, string $to
* @param string $toAddress Who it is going to.
* @param string $toName The name of the person it is going to.
* @param string $body What the body of the email is.
- *
* @return int The number of successful recipients. Can be 0 which indicates failure
*/
public function sendMail(string $subject, string $toAddress, string $toName, string $body): int;
@@ -48,8 +47,6 @@ public function sendMail(string $subject, string $toAddress, string $toName, str
* Add a debugger.
*
* @param DebuggerProviderInterface $debugger The debugger to add.
- *
- * @throws DebugBarException
*/
public function addToDebugger(DebuggerProviderInterface $debugger): void;
}
diff --git a/src/Providers/MailerTransportProvider.php b/src/Providers/MailerTransportProvider.php
new file mode 100644
index 0000000..a680145
--- /dev/null
+++ b/src/Providers/MailerTransportProvider.php
@@ -0,0 +1,98 @@
+ $options Configuration options.
+ */
+ public function __construct(array $options)
+ {
+ $transport = $options['transport'] ?: '';
+
+ switch ($transport) {
+ case 'null':
+ $this->transport = new Swift_NullTransport();
+
+ break;
+ case 'smtp':
+ $this->buildSmtp($options);
+
+ break;
+ case 'sendmail':
+ $this->buildSendmail($options);
+
+ break;
+ default:
+ throw new RuntimeException('Unrecognised mail transport');
+ }
+ }
+
+ /**
+ * Build SMTP transport.
+ *
+ * @param array $options Configuration options
+ */
+ private function buildSmtp(array $options): void
+ {
+ if (!isset($options['host'])) {
+ throw new InvalidArgumentException('Missing host for smtp transport');
+ }
+ if (!isset($options['port'])) {
+ throw new InvalidArgumentException('Missing port for smtp transport');
+ }
+ if (!isset($options['username'])) {
+ throw new InvalidArgumentException('Missing username for smtp transport');
+ }
+ if (!isset($options['password'])) {
+ throw new InvalidArgumentException('Missing password for smtp transport');
+ }
+ $this->transport = (new Swift_SmtpTransport($options['host'], (int)$options['port']))
+ ->setUsername($options['username'])
+ ->setPassword($options['password']);
+ }
+
+ /**
+ * Build sendmail.
+ *
+ * @param array $options Configuration options.
+ */
+ private function buildSendmail(array $options): void
+ {
+ if (!isset($options['command'])) {
+ throw new InvalidArgumentException('Missing command for sendmail transport');
+ }
+ $this->transport = new Swift_SendmailTransport($options['command']);
+ }
+
+ /**
+ * Get the configured transport.
+ *
+ * @return Swift_Transport
+ */
+ public function getTransport(): Swift_Transport
+ {
+ return $this->transport;
+ }
+}
diff --git a/src/Providers/MailerTransportProviderInterface.php b/src/Providers/MailerTransportProviderInterface.php
new file mode 100644
index 0000000..38a1f3c
--- /dev/null
+++ b/src/Providers/MailerTransportProviderInterface.php
@@ -0,0 +1,19 @@
+|null $data Associative array of template variables
- *
+ * @param array|null $data Associative array of template variables
* @return ResponseInterface
*/
public function render(ResponseInterface $response, string $template, ?array $data = null): ResponseInterface
@@ -41,6 +41,7 @@ public function render(ResponseInterface $response, string $template, ?array $da
if (!$data) {
$data = [];
}
+
return $this->twig->render($response, $template, $data);
}
}
diff --git a/src/Providers/TemplateProviderInterface.php b/src/Providers/TemplateProviderInterface.php
index 878e38c..2ec8b92 100644
--- a/src/Providers/TemplateProviderInterface.php
+++ b/src/Providers/TemplateProviderInterface.php
@@ -1,5 +1,5 @@
|null $data Associative array of template variables
- *
+ * @param array|null $data Associative array of template variables
* @return ResponseInterface
*/
public function render(ResponseInterface $response, string $template, ?array $data = null): ResponseInterface;
diff --git a/src/Providers/WikiParserProvider.php b/src/Providers/WikiParserProvider.php
index b8db87f..0da547c 100644
--- a/src/Providers/WikiParserProvider.php
+++ b/src/Providers/WikiParserProvider.php
@@ -1,22 +1,18 @@
logger->debug('Extracted wiki title {wikiTitle}', ['wikiTitle' => $newTitle]);
} else {
$this->logger->debug('No wiki text found, using default title: {title}', ['default' => $default]);
}
+
$newTitle = trim(strip_tags($newTitle));
$newTitle = str_replace(' - ', ' — ', $newTitle);
+
return $newTitle;
}
@@ -73,22 +71,22 @@ public function parseDivisionTitle(string $wiki, string $default): string
* Parse the motion text suitable for display.
*
* @see https://github.com/publicwhip/publicwhip/blob/a4899135b6957abae85da3fc93c4cc3cf9e4fbc1/website/wiki.inc#L112
- *
* @param string $wiki The text to parse.
* @param string $default The text to return if it's not a valid wiki text.
- *
* @return string
*/
public function parseMotionText(string $wiki, string $default): string
{
$this->logger->debug('Going to parse motion text');
$motion = $this->parseMotionTextForEdit($wiki, $default);
+
if (!preg_match('/<\/.*?>/', $motion)) {
$motionLines = explode("\n", $motion);
$binUL = 0;
$res = [];
$matches = [];
$footerNumber = 0;
+
foreach ($motionLines as $motionLine) {
$motionLine = $this->replaceUsingRegExpStrings("/''(.*?)''/", '\\1', $motionLine);
$motionLine = $this->replaceUsingRegExpStrings(
@@ -104,18 +102,23 @@ public function parseMotionText(string $wiki, string $default): string
'',
$motionLine
);
+
if (preg_match('/^\s\s*$/', $motionLine)) {
continue;
}
+
// skip comment lines we lift up for the short sentences
if (preg_match('/^@/', $motionLine)) {
continue;
}
+
if (preg_match('/^([\*|:])/', $motionLine)) {
if (!$binUL) {
$res[] = '
' : '';
+ $res[] = 0 === $binUL ? '' : '';
}
+
if ($binUL) {
$res[] = '';
}
+
$motion = implode("\n", $res);
}
+
$this->logger->debug(
'Making safe motion text: {motion}',
['motion' => htmlspecialchars($motion, ENT_QUOTES)]
@@ -179,56 +189,26 @@ public function parseMotionText(string $wiki, string $default): string
return $motion;
}
- /**
- * Replace text using a regular expression, logging/raising error if appropriate.
- *
- * @param string $pattern Search pattern
- * @param string $replacement Replacement text
- * @param string $inputString Input string.
- *
- * @return string
- *
- * @throws WikiFailedRegExp
- */
- private function replaceUsingRegExpStrings(string $pattern, string $replacement, string $inputString): string
- {
- $output = preg_replace($pattern, $replacement, $inputString);
- if (null === $output) {
- $error = array_flip(get_defined_constants(true)['pcre'])[preg_last_error()];
- $this->logger->error(
- 'Failed to replace using regular expression ({error}) using pattern {pattern} on {input}',
- [
- 'pattern' => $pattern,
- 'replacement' => $replacement,
- 'error' => $error,
- 'input' => $inputString
- ]
- );
- throw new WikiFailedRegExp(sprintf('Failed with %s', $error));
- }
- return $output;
- }
-
/**
* Get the motion text from the wiki - suitable for editing.
- *
* PublicWhip v1 function extract_motion_text_from_wiki_text_for_edit
*
* @param string $wiki Wiki text to parse.
* @param string $default If the wiki text was not valid, the text to be returned instead.
- *
* @return string
*/
public function parseMotionTextForEdit(string $wiki, string $default): string
{
$text = $default;
+
if ('' !== $wiki && preg_match('/--- MOTION EFFECT ---(.*)--- COMMENT/s', $wiki, $matches)) {
$text = $matches[1];
$this->logger->debug('Will be using extracted text from wiki');
}
+
$this->logger->debug('Parsing text {text}', ['text' => htmlspecialchars($text, ENT_QUOTES)]);
// strip empty items.
- $text = str_replace(['—',' class=""', ' pwmotiontext="yes"'], ['-','',''], trim($text));
+ $text = str_replace(['—', ' class=""', ' pwmotiontext="yes"'], ['-', '', ''], trim($text));
$text = $this->replaceUsingRegExpStrings(
"/(.*)<\/p>/",
'
\\1
',
@@ -245,16 +225,46 @@ public function parseMotionTextForEdit(string $wiki, string $default): string
'editText' => htmlspecialchars($text, ENT_QUOTES)
]
);
+
return trim($text);
}
+ /**
+ * Replace text using a regular expression, logging/raising error if appropriate.
+ *
+ * @param string $pattern Search pattern
+ * @param string $replacement Replacement text
+ * @param string $inputString Input string.
+ * @return string
+ * @throws WikiFailedRegExp
+ */
+ private function replaceUsingRegExpStrings(string $pattern, string $replacement, string $inputString): string
+ {
+ $output = preg_replace($pattern, $replacement, $inputString);
+
+ if (null === $output) {
+ $error = array_flip(get_defined_constants(true)['pcre'])[preg_last_error()];
+ $this->logger->error(
+ 'Failed to replace using regular expression ({error}) using pattern {pattern} on {input}',
+ [
+ 'pattern' => $pattern,
+ 'replacement' => $replacement,
+ 'error' => $error,
+ 'input' => $inputString
+ ]
+ );
+
+ throw new WikiFailedRegExp(sprintf('Failed with %s', $error));
+ }
+
+ return $output;
+ }
+
/**
* Takes our safe html and converts it to normal html.
*
* @see https://github.com/publicwhip/publicwhip/blob/a4899135b6957abae85da3fc93c4cc3cf9e4fbc1/website/pretty.inc#L418
- *
* @param string $html The 'safe' html to convert back to normal html.
- *
* @return string
*/
public function safeHtmlToNormalHtml(string $html): string
@@ -267,6 +277,7 @@ public function safeHtmlToNormalHtml(string $html): string
];
$replace = ['&\\1', '<', '>', '"'];
$return = preg_replace($patterns, $replace, $html);
+
if (null === $return) {
throw new WikiFailedRegExp(
sprintf(
@@ -275,6 +286,7 @@ public function safeHtmlToNormalHtml(string $html): string
)
);
}
+
return $return;
}
@@ -282,9 +294,7 @@ public function safeHtmlToNormalHtml(string $html): string
* Strips bad html.
*
* @see https://github.com/publicwhip/publicwhip/blob/a4899135b6957abae85da3fc93c4cc3cf9e4fbc1/website/pretty.inc#L313
- *
* @param string $text Text to strip unwanted html from.
- *
* @return string
*/
public function htmlToSafeHtml(string $text): string
@@ -299,11 +309,12 @@ public function htmlToSafeHtml(string $text): string
$checkedText = strip_tags($text, $htmlAllowedStripTags);
$checkedText = preg_replace_callback(
'/<(' . $htmlRegExp . ')\b(.*?)>/si',
- function (array $data): string {
+ static function (array $data): string {
return self::filterHtmlAttributes($data);
},
$checkedText
);
+
if (null === $checkedText) {
throw new WikiFailedRegExp(
sprintf(
@@ -312,6 +323,7 @@ function (array $data): string {
)
);
}
+
$checkedText = $this->replaceUsingRegExpStrings(
'/<\/([^ ' . "\n" . '>]+)[^>]*>/i',
self::SAFE_LESS_THAN . '/$1' . self::SAFE_GREATER_THAN,
@@ -331,9 +343,7 @@ function (array $data): string {
* Only keeps approved attributes of HTML.
*
* @see https://github.com/publicwhip/publicwhip/blob/a4899135b6957abae85da3fc93c4cc3cf9e4fbc1/website/pretty.inc#L334
- *
- * @param string[] $arr Html element and items to strip away.
- *
+ * @param array $arr Html element and items to strip away.
* @return string
*/
private static function filterHtmlAttributes(array $arr): string
@@ -347,59 +357,71 @@ private static function filterHtmlAttributes(array $arr): string
switch ($element) {
case 'a':
$noSpecial = 'href|hreflang|name|lang';
+
break;
case 'img':
$noSpecial = 'longdesc|src|align';
$special .= '|class|alt';
+
if (false !== stripos($attributes, 'alt')) {
$prepared = ['alt=' . self::SAFE_QUOTE . self::SAFE_QUOTE];
}
+
break;
case 'ins':
case 'del':
$noSpecial = 'cite|datetime|lang';
+
break;
case 'blockquote':
case 'q':
$noSpecial = 'cite|lang';
+
break;
case 'br':
case 'news':
case 'column':
$special = '';
+
break;
case 'span':
$special .= '|class';
$noSpecial = 'lang';
+
break;
case 'form':
$special = '';
$noSpecial = 'level';
+
break;
case 'ol':
$noSpecial = 'type';
+
break;
default:
$noSpecial = 'lang';
}
if ($noSpecial) {
- preg_match_all("/(?:$noSpecial)\s*=\s*\"[^\s\">]+\"/is", $attributes, $matches);
+ preg_match_all('/(?:' . $noSpecial . ')\s*=\s*"[^\s">]+"/is', $attributes, $matches);
$prepared = array_merge($prepared, str_replace('"', self::SAFE_QUOTE, $matches[0]));
- preg_match_all("/(?:$noSpecial)\s*=\s*'[^\s'>]+'/is", $attributes, $matches);
+ preg_match_all('/(?:' . $noSpecial . ')\s*=\s*\'[^\s\'>]+\'/is', $attributes, $matches);
$prepared = array_merge($prepared, $matches[0]);
- preg_match_all("/(?:$noSpecial)\s*=\s*[^\s>'\"][^\s>]*/is", $attributes, $matches);
+ preg_match_all('/(?:' . $noSpecial . ')\s*=\s*[^\s>\'"][^\s>]*/is', $attributes, $matches);
$prepared = array_merge($prepared, $matches[0]);
}
+
if ($special) {
- preg_match_all("/(?:$special)\s*=\s*\"[^\"]*\"/is", $attributes, $matches);
+ preg_match_all('/(?:' . $special . ')\s*=\s*"[^"]*"/is', $attributes, $matches);
$prepared = array_merge($prepared, str_replace('"', self::SAFE_QUOTE, $matches[0]));
- preg_match_all("/(?:$special)\s*=\s*'[^']*'/is", $attributes, $matches);
+ preg_match_all('/(?:' . $special . ')\s*=\s*\'[^\']*\'/is', $attributes, $matches);
$prepared = array_merge($prepared, $matches[0]);
- preg_match_all("/(?:$special)\s*=\s*[^\s>'\"][^\s>]*/is", $attributes, $matches);
+ preg_match_all('/(?:' . $special . ')\s*=\s*[^\s>\'"][^\s>]*/is', $attributes, $matches);
$prepared = array_merge($prepared, $matches[0]);
}
+
$outText = implode(' ', $prepared);
+
return self::SAFE_LESS_THAN . $element . ($outText ? ' ' . $outText : '') . self::SAFE_GREATER_THAN;
}
}
diff --git a/src/Providers/WikiParserProviderInterface.php b/src/Providers/WikiParserProviderInterface.php
index d18007f..3b1006d 100644
--- a/src/Providers/WikiParserProviderInterface.php
+++ b/src/Providers/WikiParserProviderInterface.php
@@ -1,19 +1,17 @@
databaseProvider = $databaseProvider;
$this->entityFactory = $entityFactory;
$this->dateTimeFactory = $dateTimeFactory;
@@ -72,7 +77,7 @@ public function __construct(
/**
* Get the latest division date (usually used to ensure data is up to date).
*
- * @return string
+ * @return string In YYYY-MM-DD format.
*/
public function getNewestDivisionDate(): string
{
@@ -83,8 +88,7 @@ public function getNewestDivisionDate(): string
* Find a division by its numerical id.
*
* @param int $divisionId Numerical id of the division.
- *
- * @return DivisionEntity|null
+ * @return DivisionEntity|null Null if not found.
*/
public function findByDivisionId(int $divisionId): ?DivisionEntity
{
@@ -96,6 +100,7 @@ public function findByDivisionId(int $divisionId): ?DivisionEntity
$basicDivision = $this->databaseProvider->table('pw_division')
->where('division_id', '=', $divisionId)
->first();
+
if (null === $basicDivision) {
$this->logger->debug(
__METHOD__ . ': Did not find by id {id}',
@@ -103,8 +108,10 @@ public function findByDivisionId(int $divisionId): ?DivisionEntity
'id' => $divisionId
]
);
+
return null;
}
+
return $this->buildDivisionEntityFromDivisionTable($basicDivision);
}
@@ -115,11 +122,8 @@ public function findByDivisionId(int $divisionId): ?DivisionEntity
* has done in the database.
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
- *
* @param object $basicDivision A division object as returned from the database.
- *
- * @return DivisionEntity
- *
+ * @return DivisionEntity The generated entity.
* @throws BadDatabaseReturnException
*/
private function buildDivisionEntityFromDivisionTable(object $basicDivision): DivisionEntity
@@ -158,6 +162,7 @@ private function buildDivisionEntityFromDivisionTable(object $basicDivision): Di
$voteInformation = $this->databaseProvider->table('pw_cache_divinfo')
->where('division_id', '=', $basicDivision->division_id)
->first();
+
if ($voteInformation) {
if (!property_exists($voteInformation, 'rebellions')
|| !property_exists($voteInformation, 'turnout')
@@ -166,6 +171,7 @@ private function buildDivisionEntityFromDivisionTable(object $basicDivision): Di
) {
throw new BadDatabaseReturnException('Not a divinfo');
}
+
$builtData['rebellions'] = (int)$voteInformation->rebellions;
$builtData['turnout'] = (int)$voteInformation->turnout;
$builtData['possibleTurnout'] = (int)$voteInformation->possible_turnout;
@@ -187,12 +193,15 @@ private function buildDivisionEntityFromDivisionTable(object $basicDivision): Di
->orderBy('wiki_id', 'DESC')
->first();
$wikiTextBody = '';
+
if ($descriptionData) {
if (!property_exists($descriptionData, 'text_body')) {
throw new BadDatabaseReturnException('Not a wiki_motion');
}
+
$wikiTextBody = $descriptionData->text_body;
}
+
/**
* Now to extract the additional fields.
*/
@@ -204,6 +213,7 @@ private function buildDivisionEntityFromDivisionTable(object $basicDivision): Di
$wikiTextBody,
(string)$basicDivision->motion
);
+
return $this->entityFactory->division($builtData);
}
@@ -213,7 +223,6 @@ private function buildDivisionEntityFromDivisionTable(object $basicDivision): Di
* @param string $house Name of the house - probably 'commons','lords' or 'scotland'
* @param string $date Date in YYYY-MM-DD of the division.
* @param int $divisionNumber Number of the division.
- *
* @return DivisionEntity|null Entity if found.
*/
public function findByHouseDateAndNumber(string $house, string $date, int $divisionNumber): ?DivisionEntity
@@ -228,6 +237,7 @@ public function findByHouseDateAndNumber(string $house, string $date, int $divis
->where('division_number', '=', $divisionNumber)
->where('house', '=', $house)
->first();
+
if (null === $basicDivision) {
$this->logger->debug(
__METHOD__ . ': Did not find in {house} date {date} {divisionNumber}',
@@ -237,8 +247,10 @@ public function findByHouseDateAndNumber(string $house, string $date, int $divis
'divisionNumber' => $divisionNumber
]
);
+
return null;
}
+
return $this->buildDivisionEntityFromDivisionTable($basicDivision);
}
}
diff --git a/src/Services/DivisionServiceInterface.php b/src/Services/DivisionServiceInterface.php
index 3203688..118112c 100644
--- a/src/Services/DivisionServiceInterface.php
+++ b/src/Services/DivisionServiceInterface.php
@@ -1,5 +1,5 @@
environment = $environment;
+
if (null === $app) {
$containerBuilder = new ContainerBuilder();
$this->configureContainer($containerBuilder);
$container = $containerBuilder->build();
$app = new App($container);
}
- $this->app = $app;
- }
- /**
- * Main runner.
- **
- *
- * @return ResponseInterface The response interface.
- *
- * @throws MethodNotAllowedException
- * @throws NotFoundException
- */
- public function run(): ResponseInterface
- {
- $routing = new Routing();
- $routing->getRouting($this->app);
- $routing->setupTrailingSlash($this->app);
- return $this->app->run();
+ $this->app = $app;
}
/**
* Configure the dependency injector container.
*
* @TODO Add caching if appropriate on production.
- *
* @param ContainerBuilder $builder The container we we populating.
- *
* @throws MissingConfigurationException
*/
protected function configureContainer(ContainerBuilder $builder): void
@@ -89,6 +71,7 @@ protected function configureContainer(ContainerBuilder $builder): void
DIRECTORY_SEPARATOR . '..' .
DIRECTORY_SEPARATOR . 'config' .
DIRECTORY_SEPARATOR . $this->environment . '.php';
+
if (!file_exists($settingsFile) && is_readable($settingsFile)) {
throw new MissingConfigurationException(
sprintf(
@@ -97,6 +80,24 @@ protected function configureContainer(ContainerBuilder $builder): void
)
);
}
+
$builder->addDefinitions($settingsFile);
}
+
+ /**
+ * Main runner.
+ **
+ *
+ * @return ResponseInterface The response interface.
+ * @throws MethodNotAllowedException
+ * @throws NotFoundException
+ */
+ public function run(): ResponseInterface
+ {
+ $routing = new Routing();
+ $routing->getRouting($this->app);
+ $routing->setupTrailingSlash($this->app);
+
+ return $this->app->run();
+ }
}
diff --git a/src/Web/Controllers/DebugBarController.php b/src/Web/Controllers/DebugBarController.php
index 7594f33..e974362 100644
--- a/src/Web/Controllers/DebugBarController.php
+++ b/src/Web/Controllers/DebugBarController.php
@@ -1,5 +1,5 @@
write($divisionService->getNewestDivisionDate());
return $response;
}
+
+ /**
+ * Send a test mail.
+ *
+ * @param MailerProviderInterface $mailer
+ * @param ResponseInterface $response
+ * @return ResponseInterface
+ */
+ public function testMailAction(MailerProviderInterface $mailer, ResponseInterface $response): ResponseInterface
+ {
+ $count = $mailer->sendMail(
+ 'Test subject',
+ 'test@example.com',
+ 'Testing name',
+ 'Generated at '.time()
+ );
+ $body = $response->getBody();
+ $body->write('Sent ' . $count . ' test mails');
+ return $response;
+ }
}
diff --git a/src/Web/ErrorHandlers/ErrorHandler.php b/src/Web/ErrorHandlers/ErrorHandler.php
index 6095f94..00cbb3d 100644
--- a/src/Web/ErrorHandlers/ErrorHandler.php
+++ b/src/Web/ErrorHandlers/ErrorHandler.php
@@ -1,5 +1,5 @@
withBody($body);
}
+ /**
+ * Render JSON error
+ *
+ * @param Throwable $throwable The thrown item.
+ *
+ * @return string
+ */
+ private function renderJsonErrorMessage(Throwable $throwable): string
+ {
+ $error = [
+ 'message' => 'PublicWhip Application Error'
+ ];
+
+ if ($this->displayErrorDetails) {
+ $error['exception'] = [];
+
+ do {
+ $error['exception'][] = [
+ 'type' => get_class($throwable),
+ 'code' => $throwable->getCode(),
+ 'message' => $throwable->getMessage(),
+ 'file' => $throwable->getFile(),
+ 'line' => $throwable->getLine(),
+ 'trace' => explode("\n", $throwable->getTraceAsString())
+ ];
+ $throwable = $throwable->getPrevious();
+ } while ($throwable);
+ }
+
+ $encoded = json_encode($error, JSON_PRETTY_PRINT);
+ if (!is_string($encoded)) {
+ $encoded = '[]';
+ }
+ return $encoded;
+ }
+
/**
* Render HTML error page
*
@@ -163,40 +199,4 @@ private function renderHtmlExceptionOrError(Throwable $throwable): string
return $html;
}
-
- /**
- * Render JSON error
- *
- * @param Throwable $throwable The thrown item.
- *
- * @return string
- */
- private function renderJsonErrorMessage(Throwable $throwable): string
- {
- $error = [
- 'message' => 'PublicWhip Application Error'
- ];
-
- if ($this->displayErrorDetails) {
- $error['exception'] = [];
-
- do {
- $error['exception'][] = [
- 'type' => get_class($throwable),
- 'code' => $throwable->getCode(),
- 'message' => $throwable->getMessage(),
- 'file' => $throwable->getFile(),
- 'line' => $throwable->getLine(),
- 'trace' => explode("\n", $throwable->getTraceAsString())
- ];
- $throwable = $throwable->getPrevious();
- } while ($throwable);
- }
-
- $encoded = json_encode($error, JSON_PRETTY_PRINT);
- if (!is_string($encoded)) {
- $encoded = '[]';
- }
- return $encoded;
- }
}
diff --git a/src/Web/ErrorHandlers/NotFoundHandler.php b/src/Web/ErrorHandlers/NotFoundHandler.php
index d743a96..c7e75ba 100644
--- a/src/Web/ErrorHandlers/NotFoundHandler.php
+++ b/src/Web/ErrorHandlers/NotFoundHandler.php
@@ -1,5 +1,5 @@
withBody($body);
}
+ /**
+ * Render JSON error
+ *
+ * @param Throwable $error
+ *
+ * @return string
+ */
+ private function renderJsonErrorMessage(Throwable $error): string
+ {
+ $json = [
+ 'message' => 'PublicWhip Application Error'
+ ];
+
+ if ($this->displayErrorDetails) {
+ $json['error'] = [];
+
+ $error = $error->getPrevious();
+ while ($error) {
+ $json['error'][] = [
+ 'type' => get_class($error),
+ 'code' => $error->getCode(),
+ 'message' => $error->getMessage(),
+ 'file' => $error->getFile(),
+ 'line' => $error->getLine(),
+ 'trace' => explode("\n", $error->getTraceAsString())
+ ];
+ $error = $error->getPrevious();
+ }
+ }
+
+ $encoded = json_encode($json, JSON_PRETTY_PRINT);
+ if (false === $encoded) {
+ return '{"message":"Unrecoverable server error"}';
+ }
+ return $encoded;
+ }
+
/**
* Render HTML error page
*
@@ -116,7 +153,6 @@ private function renderHtmlErrorMessage(Throwable $error): string
return $output;
}
-
/**
* Render error as HTML.
*
@@ -153,41 +189,4 @@ private function renderHtmlError(Throwable $error): string
return $html;
}
-
- /**
- * Render JSON error
- *
- * @param Throwable $error
- *
- * @return string
- */
- private function renderJsonErrorMessage(Throwable $error): string
- {
- $json = [
- 'message' => 'PublicWhip Application Error'
- ];
-
- if ($this->displayErrorDetails) {
- $json['error'] = [];
-
- $error = $error->getPrevious();
- while ($error) {
- $json['error'][] = [
- 'type' => get_class($error),
- 'code' => $error->getCode(),
- 'message' => $error->getMessage(),
- 'file' => $error->getFile(),
- 'line' => $error->getLine(),
- 'trace' => explode("\n", $error->getTraceAsString())
- ];
- $error = $error->getPrevious();
- }
- }
-
- $encoded = json_encode($json, JSON_PRETTY_PRINT);
- if (false === $encoded) {
- return '{"message":"Unrecoverable server error"}';
- }
- return $encoded;
- }
}
diff --git a/src/Web/Routing.php b/src/Web/Routing.php
index 8be14ee..e8537c2 100644
--- a/src/Web/Routing.php
+++ b/src/Web/Routing.php
@@ -1,5 +1,5 @@
get('/debugbar/[{filePath:.*}]', [DebugBarController::class, 'staticFileAction']);
}
+ /**
+ * Setup all the routes starting /divisions .
+ *
+ * @param App $app Slim App
+ */
+ private function setupDivisions(App $app): void
+ {
+ $app->group(
+ '/divisions',
+ function (App $app): void {
+ $app->get('/', [DivisionController::class, 'indexAction']);
+ $app->get(
+ '/{divisionId:[0-9]+}/',
+ [DivisionController::class, 'showDivisionById']
+ )->setName('divisionById');
+ $app->get(
+ '/' .
+ '{house:commons|lords|scotland}/' .
+ '{date:18|19|20[0-9][0-9]\-[0-1][0-9]\-[0-3][0-9]}/' .
+ '{divisionNumber:[0-9]+}/',
+ [DivisionController::class, 'showDivisionByDateAndNumberAction']
+ )->setName('divisionByHouseDateNumber');
+ }
+ );
+ }
+
+ /**
+ * Sets up all the routes starting /ping - mainly our uptime monitoring ones.
+ *
+ * @param App $app Slim app.
+ */
+ private function setupPingRoutes(App $app): void
+ {
+ $app->group(
+ '/ping',
+ function (App $app): void {
+ $app->get('/', [PingController::class, 'indexAction']);
+ $app->get('/lastDivisionParsed/', [PingController::class, 'lastDivisionParsedAction']);
+ $app->get('/testmail/', [PingController::class, 'testMailAction']);
+
+ }
+ );
+ }
+
/**
* Handle optional trailing slashes on GET requests.
*
- * @param App $app Slim App. */
+ * @param App $app Slim App.
+ */
public function setupTrailingSlash(App $app): void
{
$container = $app->getContainer();
@@ -77,46 +122,4 @@ function (RequestInterface $request, Response $response, callable $next) use ($c
}
);
}
-
- /**
- * Sets up all the routes starting /ping - mainly our uptime monitoring ones.
- *
- * @param App $app Slim app.
- * */
- private function setupPingRoutes(App $app): void
- {
- $app->group(
- '/ping',
- function (App $app): void {
- $app->get('/', [PingController::class, 'indexAction']);
- $app->get('/lastDivisionParsed/', [PingController::class, 'lastDivisionParsedAction']);
- }
- );
- }
-
- /**
- * Setup all the routes starting /divisions .
- *
- * @param App $app Slim App
- * */
- private function setupDivisions(App $app): void
- {
- $app->group(
- '/divisions',
- function (App $app): void {
- $app->get('/', [DivisionController::class, 'indexAction']);
- $app->get(
- '/{divisionId:[0-9]+}/',
- [DivisionController::class, 'showDivisionById']
- )->setName('divisionById');
- $app->get(
- '/' .
- '{house:commons|lords|scotland}/' .
- '{date:18|19|20[0-9][0-9]\-[0-1][0-9]\-[0-3][0-9]}/' .
- '{divisionNumber:[0-9]+}/',
- [DivisionController::class, 'showDivisionByDateAndNumberAction']
- )->setName('divisionByHouseDateNumber');
- }
- );
- }
}
\ No newline at end of file
diff --git a/tests/Unit/Providers/WikiParserProviderTest.php b/tests/Unit/Providers/WikiParserProviderTest.php
index 027f04a..7d1644b 100644
--- a/tests/Unit/Providers/WikiParserProviderTest.php
+++ b/tests/Unit/Providers/WikiParserProviderTest.php
@@ -1,5 +1,5 @@
*/
final class WikiParserProviderTest extends TestCase
{
-
/**
* Cached division test data.
*
- * @var array>|null $cachedDivisionTestData
+ * @var array>>|null $cachedDivisionTestData
*/
private $cachedDivisionTestData;
@@ -43,39 +42,49 @@ private function getHtmlMarkupTestData(): array
if (is_array($this->cachedHtmlMarkupTestData)) {
return $this->cachedHtmlMarkupTestData;
}
+
$contents = file_get_contents(
__DIR__ . DIRECTORY_SEPARATOR . 'WikiParserProvider' . DIRECTORY_SEPARATOR . 'html.json'
);
+
if (!$contents) {
throw new RuntimeException('Unable to load test data html.json');
}
+
$this->cachedHtmlMarkupTestData = json_decode($contents, true);
+
if (!$this->cachedHtmlMarkupTestData) {
throw new RuntimeException('Unable to parse test data html.json: ' . json_last_error_msg());
}
+
return $this->cachedHtmlMarkupTestData;
}
/**
* Get the mock divisions.
*
- * @return array>
+ * @return array>>
*/
private function getMockDivisions(): array
{
if (is_array($this->cachedDivisionTestData)) {
return $this->cachedDivisionTestData;
}
+
$contents = file_get_contents(
__DIR__ . DIRECTORY_SEPARATOR . 'WikiParserProvider' . DIRECTORY_SEPARATOR . 'mockDivisions.json'
);
+
if (!$contents) {
throw new RuntimeException('Unable to load test data mockDivisions.json');
}
+
$this->cachedDivisionTestData = json_decode($contents, true);
+
if (!$this->cachedDivisionTestData) {
throw new RuntimeException('Unable to parse test data mockDivisions.json: ' . json_last_error_msg());
}
+
return $this->cachedDivisionTestData;
}
@@ -83,7 +92,6 @@ private function getMockDivisions(): array
* Check we render all division titles the same as v1.
*
* @covers ::parseDivisionTitle
- * @return void
* @throws ReflectionException
*/
public function testParseDivisionTitle(): void
@@ -91,6 +99,7 @@ public function testParseDivisionTitle(): void
/** @var LoggerInterface $logger */
$logger = $this->createMock(LoggerInterface::class);
$sut = new WikiParserProvider($logger);
+
foreach ($this->getMockDivisions() as $divisionId => $divisionEntry) {
$lastWiki = last($divisionEntry['wiki']);
$newTitle = $sut->parseDivisionTitle(
@@ -108,16 +117,17 @@ public function testParseDivisionTitle(): void
/**
* Check we render all division texts the same as v1.
*
+ * @throws ReflectionException
+ *
* @covers ::parseMotionText
* @covers ::parseMotionTextForEdit
- * @return void
- * @throws ReflectionException
*/
public function testParseMotionText(): void
{
/** @var LoggerInterface $logger */
$logger = $this->createMock(LoggerInterface::class);
$sut = new WikiParserProvider($logger);
+
foreach ($this->getMockDivisions() as $divisionId => $divisionEntry) {
// we are comparing the last entry.
$lastWiki = last($divisionEntry['wiki']);
@@ -137,8 +147,9 @@ public function testParseMotionText(): void
/**
* Checks we can convert back from safe html to normal html.
*
- * @covers ::safeHtmlToNormalHtml
* @throws ReflectionException
+ *
+ * @covers ::safeHtmlToNormalHtml
*/
public function testSafeHtmlToNormalHtml(): void
{
@@ -146,6 +157,7 @@ public function testSafeHtmlToNormalHtml(): void
/** @var LoggerInterface $logger */
$logger = $this->createMock(LoggerInterface::class);
$sut = new WikiParserProvider($logger);
+
foreach ($testData as $entry) {
$output = $sut->safeHtmlToNormalHtml($entry['safeHtml']);
self::assertSame($entry['normalHtml'], $output);
@@ -155,8 +167,9 @@ public function testSafeHtmlToNormalHtml(): void
/**
* Checks we convert html to the expected safe format.
*
- * @covers ::htmlToSafeHtml
* @throws ReflectionException
+ *
+ * @covers ::htmlToSafeHtml
*/
public function testHtmlToSafeHtml(): void
{
@@ -164,9 +177,10 @@ public function testHtmlToSafeHtml(): void
/** @var LoggerInterface $logger */
$logger = $this->createMock(LoggerInterface::class);
$sut = new WikiParserProvider($logger);
+
foreach ($testData as $entry) {
$output = $sut->htmlToSafeHtml($entry['input']);
self::assertSame($entry['safeHtml'], $output);
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/Unit/Web/Controllers/PingControllerTest.php b/tests/Unit/Web/Controllers/PingControllerTest.php
new file mode 100644
index 0000000..bde6a02
--- /dev/null
+++ b/tests/Unit/Web/Controllers/PingControllerTest.php
@@ -0,0 +1,54 @@
+indexAction($mockResponse);
+ self::assertSame($response, $mockResponse);
+ $body = $response->getBody();
+ $body->rewind();
+ self::assertSame('ready', $body->getContents());
+ }
+
+ /**
+ * @covers ::lastDivisionParsedAction
+ * @throws ReflectionException
+ */
+ public function testLastDivisionParseAction(): void
+ {
+ $sut = new PingController();
+ $mockResponse = new Response(200);
+
+ /** @var DivisionServiceInterface|MockObject $mockDivisionService */
+ $mockDivisionService = $this->createMock(DivisionServiceInterface::class);
+ $mockDivisionService->method('getNewestDivisionDate')->willReturn('2018-01-23');
+
+ $response = $sut->lastDivisionParsedAction($mockDivisionService, $mockResponse);
+ self::assertSame($response, $mockResponse);
+ $body = $response->getBody();
+ $body->rewind();
+ self::assertSame('2018-01-23', $body->getContents());
+ }
+}
\ No newline at end of file
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index e38fb27..63caa81 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -1,4 +1,4 @@
parseMotionText($wikiTextBody, $default);
checkSameness('Standard', $theirs, $ours);
}
+
print 'COMPLETED';
/**
@@ -64,35 +72,45 @@
* @param string $reasonForCheck What are we checking.
* @param string $theirs The original text.
* @param string $ours The output text.
- *
- * @return bool
+ * @return bool Are they the same?
*/
function checkSameness(string $reasonForCheck, string $theirs, string $ours): bool
{
if ($theirs === $ours) {
print $reasonForCheck . ': PASSED';
+
return true;
}
+
print $reasonForCheck . ': FAILED' . PHP_EOL;
$len = strlen($theirs);
$ourLen = strlen(trim($ours));
+
if ($len !== $ourLen) {
print 'Difference in length: expected ' . $len . ' got ' . $ourLen . PHP_EOL;
}
+
$max = max($len, $ourLen);
+
for ($position = 0; $position < $max; $position++) {
if ($position > $ourLen) {
print 'Exceeded length of ours';
+
break;
}
+
if ($position > $len) {
print 'Exceeded length of v1';
+
break;
}
+
if ($theirs[$position] === $ours[$position]) {
print $theirs[$position];
+
continue;
}
+
print PHP_EOL;
print '[expected character: ' . $theirs[$position] . ' (' . ord($theirs[$position]) . '):';
print 'got: ' . $ours[$position] . ' (' . ord($ours[$position]) . ')';
@@ -101,7 +119,9 @@ function checkSameness(string $reasonForCheck, string $theirs, string $ours): bo
print $theirs . PHP_EOL;
print '------------------- Ours -----------' . PHP_EOL;
print $ours . PHP_EOL;
+
break;
}
+
return false;
}
diff --git a/v1migrationUtils/divisionExtractorToTests.php b/v1migrationUtils/divisionExtractorToTests.php
index 8034e2f..db8c126 100644
--- a/v1migrationUtils/divisionExtractorToTests.php
+++ b/v1migrationUtils/divisionExtractorToTests.php
@@ -1,17 +1,24 @@
-execute();
$migrationRow = $extractStatement->fetch(PDO::FETCH_ASSOC);
+
while ($migrationRow) {
print PHP_EOL . 'Processing division ' . $migrationRow['division_id'];
$getWikiStatement->execute([
@@ -101,6 +109,7 @@
$wikiLinesCovered = array_keys($codeCoverage[$wikiParserFilename]);
$newLines = array_diff($wikiLinesCovered, $wikiLinesAlreadyCovered);
// have we got a division we want to include?
+
if (count($newLines) > 0 || in_array((int)$migrationRow['division_id'], $alwaysIncludeDivisionIds, true)) {
$wikiLinesAlreadyCovered = array_unique(array_merge($wikiLinesAlreadyCovered, $wikiLinesCovered));
$extractedDivisions[$migrationRow['division_id']] = [
@@ -109,8 +118,10 @@
'v1' => getResultsFromV1($migrationRow)
];
}
+
$migrationRow = $extractStatement->fetch(PDO::FETCH_ASSOC);
}
+
file_put_contents(
__DIR__ .
DIRECTORY_SEPARATOR . '..' .
@@ -126,7 +137,6 @@
* Pass it through version 1 to extract how it would handle it.
*
* @param array $migrationRow Data from the database.
- *
* @return array Extracted Data.
*/
function getResultsFromV1(array $migrationRow): array
@@ -137,9 +147,11 @@ function getResultsFromV1(array $migrationRow): array
$_GET['house'] = $migrationRow['house'];
// let v1 handle it as it does in divisions.php
$divattr = get_division_attr_decode();
+
if ('none' === $divattr) {
throw new RuntimeException('Failed when fetching division ' . $migrationRow['division_id']);
}
+
$motionData = get_wiki_current_value(
'motion',
[$divattr['division_date'], $divattr['division_number'], $divattr['house']]
@@ -147,17 +159,21 @@ function getResultsFromV1(array $migrationRow): array
$name = extract_title_from_wiki_text($motionData['text_body']);
$debateGid = $divattr['debate_gid'];
-
$ldalink = null;
if (('lords' === $divattr['house']) && ($divattr['division_date'] >= '2009-01-21')) {
$ldasess = '2008_09';
$ldadate = str_replace('-', '', $divattr['division_date']);
$ldanum = '/number/' . $divattr['division_number'];
- $ldalink = "http://services.parliament.uk/LordsDivisionsAnalysis/session/$ldasess/division/$ldadate$ldanum";
+ $ldalink = 'http://services.parliament.uk/LordsDivisionsAnalysis/session/' .
+ $ldasess .
+ '/division/' .
+ $ldadate .
+ $ldanum;
}
$theyWorkForYouLink = null;
+
if ('' !== $debateGid) {
if ('lords' === $divattr['house']) {
$debateGid = 'lords/?id=' . str_replace('uk.org.publicwhip/lords/', '', $debateGid);
@@ -166,11 +182,13 @@ function getResultsFromV1(array $migrationRow): array
} else {
$debateGid = 'debates/?id=' . str_replace('uk.org.publicwhip/debate/', '', $debateGid);
}
+
$theyWorkForYouLink = 'http://www.theyworkforyou.com/' . $debateGid;
}
// hansard
$historicalHansard = null;
+
if ($divattr['division_date'] <= '2005-03-17') {
$millbankurl = $divattr['house']
. '/' .
@@ -195,14 +213,18 @@ function getResultsFromV1(array $migrationRow): array
'description' => extract_motion_text_from_wiki_text($motionData['text_body']),
'actionText' => extract_action_text_from_wiki_text($motionData['text_body'])
];
+
if ($ldalink) {
$output['ldaLink'] = $ldalink;
}
+
if ($theyWorkForYouLink) {
$output['theyWorkForYouLink'] = $theyWorkForYouLink;
}
+
if ($historicalHansard) {
$output['historicalHansard'] = $historicalHansard;
}
+
return $output;
}
diff --git a/v1migrationUtils/htmlMarkupToTests.php b/v1migrationUtils/htmlMarkupToTests.php
index 14da059..4a9224b 100644
--- a/v1migrationUtils/htmlMarkupToTests.php
+++ b/v1migrationUtils/htmlMarkupToTests.php
@@ -1,5 +1,7 @@
guy2html($guyed)
];
}
+
file_put_contents(
__DIR__ .
DIRECTORY_SEPARATOR . '..' .
From 8cc22aaf246cfb41e4fa03634da9dd2abe809dff Mon Sep 17 00:00:00 2001
From: rbairwell
Date: Tue, 19 Mar 2019 14:55:45 +0000
Subject: [PATCH 2/2] Fix typo in circleci configuration
---
.circleci/config.yml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 80a6ed4..e7e0ba5 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -26,8 +26,9 @@ jobs:
# check composer is in sync
- run:
- name: Checking composer.lock
- command: composer validate --no-check-all --strict
+ name: Checking composer.lock
+ command: composer validate --no-check-all --strict
+
# Download and cache dependencies
- restore_cache:
keys: