From ac6a093e870e55551251c285f4e3e39fedd068d7 Mon Sep 17 00:00:00 2001 From: Ben Hillier Date: Mon, 13 May 2019 11:05:26 +0200 Subject: [PATCH 01/20] Initial Symfony Install --- .env | 21 + .gitignore | 31 +- bin/console | 42 + composer.json | 59 ++ composer.lock | 1409 +++++++++++++++++++++++++++ config/bootstrap.php | 21 + config/bundles.php | 5 + config/packages/cache.yaml | 19 + config/packages/dev/routing.yaml | 3 + config/packages/framework.yaml | 17 + config/packages/routing.yaml | 4 + config/packages/test/framework.yaml | 4 + config/packages/test/routing.yaml | 3 + config/routes.yaml | 3 + config/services.yaml | 27 + public/index.php | 27 + src/Controller/.gitignore | 0 src/Kernel.php | 53 + symfony.lock | 115 +++ 19 files changed, 1844 insertions(+), 19 deletions(-) create mode 100644 .env create mode 100755 bin/console create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 config/bootstrap.php create mode 100644 config/bundles.php create mode 100644 config/packages/cache.yaml create mode 100644 config/packages/dev/routing.yaml create mode 100644 config/packages/framework.yaml create mode 100644 config/packages/routing.yaml create mode 100644 config/packages/test/framework.yaml create mode 100644 config/packages/test/routing.yaml create mode 100644 config/routes.yaml create mode 100644 config/services.yaml create mode 100644 public/index.php create mode 100644 src/Controller/.gitignore create mode 100644 src/Kernel.php create mode 100644 symfony.lock diff --git a/.env b/.env new file mode 100644 index 0000000..357079d --- /dev/null +++ b/.env @@ -0,0 +1,21 @@ +# In all environments, the following files are loaded if they exist, +# the later taking precedence over the former: +# +# * .env contains default values for the environment variables needed by the app +# * .env.local uncommitted file with local overrides +# * .env.$APP_ENV committed environment-specific defaults +# * .env.$APP_ENV.local uncommitted environment-specific overrides +# +# Real environment variables win over .env files. +# +# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES. +# +# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2). +# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration + +###> symfony/framework-bundle ### +APP_ENV=dev +APP_SECRET=be45ec4c2dbfcb5df488a457fbe4216a +#TRUSTED_PROXIES=127.0.0.1,127.0.0.2 +#TRUSTED_HOSTS='^localhost|example\.com$' +###< symfony/framework-bundle ### diff --git a/.gitignore b/.gitignore index 3734df6..0a0f532 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,13 @@ -rsync.sh -application/configs/application.ini -.idea -cache/ -.sass-cache/ -public/data/export/* -/data/uploads/ -/data/solr/ -/public/data/icons/ + +###> symfony/framework-bundle ### +/.env.local +/.env.local.php +/.env.*.local +/public/bundles/ +/var/ /vendor/ -/nbproject/ -/node_modules/ -/public/apidoc/ -/apidoc/ -/public/oaidoc/ -/application/configs/application.ini_backup.dist -/application/configs/application_corrupted.ini -/application/configs/application_backup.ini -/application/configs/custom.ini -/data/solr/data/ +###< symfony/framework-bundle ### + +.DS_Store +.idea + diff --git a/bin/console b/bin/console new file mode 100755 index 0000000..19c2f6c --- /dev/null +++ b/bin/console @@ -0,0 +1,42 @@ +#!/usr/bin/env php +getParameterOption(['--env', '-e'], null, true)) { + putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env); +} + +if ($input->hasParameterOption('--no-debug', true)) { + putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0'); +} + +require dirname(__DIR__).'/config/bootstrap.php'; + +if ($_SERVER['APP_DEBUG']) { + umask(0000); + + if (class_exists(Debug::class)) { + Debug::enable(); + } +} + +$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']); +$application = new Application($kernel); +$application->run($input); diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..d04295b --- /dev/null +++ b/composer.json @@ -0,0 +1,59 @@ +{ + "type": "project", + "license": "proprietary", + "require": { + "php": "^7.1.3", + "ext-ctype": "*", + "ext-iconv": "*", + "symfony/console": "4.2.*", + "symfony/dotenv": "4.2.*", + "symfony/flex": "^1.1", + "symfony/framework-bundle": "4.2.*", + "symfony/yaml": "4.2.*" + }, + "config": { + "preferred-install": { + "*": "dist" + }, + "sort-packages": true + }, + "autoload": { + "psr-4": { + "App\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "App\\Tests\\": "tests/" + } + }, + "replace": { + "paragonie/random_compat": "2.*", + "symfony/polyfill-ctype": "*", + "symfony/polyfill-iconv": "*", + "symfony/polyfill-php71": "*", + "symfony/polyfill-php70": "*", + "symfony/polyfill-php56": "*" + }, + "scripts": { + "auto-scripts": { + "cache:clear": "symfony-cmd", + "assets:install %PUBLIC_DIR%": "symfony-cmd" + }, + "post-install-cmd": [ + "@auto-scripts" + ], + "post-update-cmd": [ + "@auto-scripts" + ] + }, + "conflict": { + "symfony/symfony": "*" + }, + "extra": { + "symfony": { + "allow-contrib": false, + "require": "4.2.*" + } + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..f026b7d --- /dev/null +++ b/composer.lock @@ -0,0 +1,1409 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "f143832e85df629dc1a54d892987b0d4", + "packages": [ + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "time": "2016-08-06T20:24:11+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/log", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2018-11-20T15:27:04+00:00" + }, + { + "name": "psr/simple-cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "time": "2017-10-23T01:57:42+00:00" + }, + { + "name": "symfony/cache", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "9e64db924324700e19ef4f21c2c279a35ff9bdff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/9e64db924324700e19ef4f21c2c279a35ff9bdff", + "reference": "9e64db924324700e19ef4f21c2c279a35ff9bdff", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/cache": "~1.0", + "psr/log": "~1.0", + "psr/simple-cache": "^1.0", + "symfony/contracts": "^1.0", + "symfony/var-exporter": "^4.2" + }, + "conflict": { + "doctrine/dbal": "<2.5", + "symfony/dependency-injection": "<3.4", + "symfony/var-dumper": "<3.4" + }, + "provide": { + "psr/cache-implementation": "1.0", + "psr/simple-cache-implementation": "1.0", + "symfony/cache-contracts-implementation": "1.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/cache": "~1.6", + "doctrine/dbal": "~2.5", + "predis/predis": "~1.1", + "symfony/config": "~4.2", + "symfony/dependency-injection": "~3.4|~4.1", + "symfony/var-dumper": "^4.1.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "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 Cache component with PSR-6, PSR-16, and tags", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "time": "2019-04-16T09:36:45+00:00" + }, + { + "name": "symfony/config", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "0e745ead307d5dcd4e163e94a47ec04b1428943f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/0e745ead307d5dcd4e163e94a47ec04b1428943f", + "reference": "0e745ead307d5dcd4e163e94a47ec04b1428943f", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/filesystem": "~3.4|~4.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<3.4" + }, + "require-dev": { + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/finder": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "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 Config Component", + "homepage": "https://symfony.com", + "time": "2019-04-01T14:03:25+00:00" + }, + { + "name": "symfony/console", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "e2840bb38bddad7a0feaf85931e38fdcffdb2f81" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/e2840bb38bddad7a0feaf85931e38fdcffdb2f81", + "reference": "e2840bb38bddad7a0feaf85931e38fdcffdb2f81", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/contracts": "^1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "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 Console Component", + "homepage": "https://symfony.com", + "time": "2019-04-08T14:23:48+00:00" + }, + { + "name": "symfony/contracts", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/contracts.git", + "reference": "d3636025e8253c6144358ec0a62773cae588395b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/contracts/zipball/d3636025e8253c6144358ec0a62773cae588395b", + "reference": "d3636025e8253c6144358ec0a62773cae588395b", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "psr/cache": "^1.0", + "psr/container": "^1.0", + "symfony/polyfill-intl-idn": "^1.10" + }, + "suggest": { + "psr/cache": "When using the Cache contracts", + "psr/container": "When using the Service contracts", + "symfony/cache-contracts-implementation": "", + "symfony/event-dispatcher-implementation": "", + "symfony/http-client-contracts-implementation": "", + "symfony/service-contracts-implementation": "", + "symfony/translation-contracts-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\": "" + }, + "exclude-from-classmap": [ + "**/Tests/" + ] + }, + "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": "A set of abstractions extracted out of the Symfony components", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "time": "2019-04-27T14:29:50+00:00" + }, + { + "name": "symfony/debug", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "2d279b6bb1d582dd5740d4d3251ae8c18812ed37" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/2d279b6bb1d582dd5740d4d3251ae8c18812ed37", + "reference": "2d279b6bb1d582dd5740d4d3251ae8c18812ed37", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": "<3.4" + }, + "require-dev": { + "symfony/http-kernel": "~3.4|~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "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 Debug Component", + "homepage": "https://symfony.com", + "time": "2019-04-11T11:27:41+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "d161c0c8bc77ad6fdb8f5083b9e34c3015d43eb1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/d161c0c8bc77ad6fdb8f5083b9e34c3015d43eb1", + "reference": "d161c0c8bc77ad6fdb8f5083b9e34c3015d43eb1", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/container": "^1.0", + "symfony/contracts": "^1.0" + }, + "conflict": { + "symfony/config": "<4.2", + "symfony/finder": "<3.4", + "symfony/proxy-manager-bridge": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "psr/container-implementation": "1.0", + "symfony/service-contracts-implementation": "1.0" + }, + "require-dev": { + "symfony/config": "~4.2", + "symfony/expression-language": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "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 DependencyInjection Component", + "homepage": "https://symfony.com", + "time": "2019-04-27T11:48:17+00:00" + }, + { + "name": "symfony/dotenv", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/dotenv.git", + "reference": "b541d63b83532be55a020db8ed2e50598385a583" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/b541d63b83532be55a020db8ed2e50598385a583", + "reference": "b541d63b83532be55a020db8ed2e50598385a583", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "symfony/process": "~3.4|~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Dotenv\\": "" + }, + "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": "Registers environment variables from a .env file", + "homepage": "https://symfony.com", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "time": "2019-04-01T07:32:59+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "fbce53cd74ac509cbe74b6f227622650ab759b02" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/fbce53cd74ac509cbe74b6f227622650ab759b02", + "reference": "fbce53cd74ac509cbe74b6f227622650ab759b02", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/contracts": "^1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/stopwatch": "~3.4|~4.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "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 EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2019-04-06T13:51:08+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "e16b9e471703b2c60b95f14d31c1239f68f11601" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e16b9e471703b2c60b95f14d31c1239f68f11601", + "reference": "e16b9e471703b2c60b95f14d31c1239f68f11601", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "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 Filesystem Component", + "homepage": "https://symfony.com", + "time": "2019-02-07T11:40:08+00:00" + }, + { + "name": "symfony/finder", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "e45135658bd6c14b61850bf131c4f09a55133f69" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/e45135658bd6c14b61850bf131c4f09a55133f69", + "reference": "e45135658bd6c14b61850bf131c4f09a55133f69", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "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 Finder Component", + "homepage": "https://symfony.com", + "time": "2019-04-06T13:51:08+00:00" + }, + { + "name": "symfony/flex", + "version": "v1.2.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/flex.git", + "reference": "27909122a3da4676c3dc5dc34c8f82323c610d69" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/flex/zipball/27909122a3da4676c3dc5dc34c8f82323c610d69", + "reference": "27909122a3da4676c3dc5dc34c8f82323c610d69", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0", + "php": "^7.0" + }, + "require-dev": { + "composer/composer": "^1.0.2", + "symfony/dotenv": "^3.4|^4.0", + "symfony/phpunit-bridge": "^3.4.19|^4.1.8", + "symfony/process": "^2.7|^3.0|^4.0" + }, + "type": "composer-plugin", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + }, + "class": "Symfony\\Flex\\Flex" + }, + "autoload": { + "psr-4": { + "Symfony\\Flex\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien.potencier@gmail.com" + } + ], + "description": "Composer plugin for Symfony", + "time": "2019-05-07T08:10:46+00:00" + }, + { + "name": "symfony/framework-bundle", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/framework-bundle.git", + "reference": "2748b12d8c456dbfeae149fc88b3012a333d817b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/2748b12d8c456dbfeae149fc88b3012a333d817b", + "reference": "2748b12d8c456dbfeae149fc88b3012a333d817b", + "shasum": "" + }, + "require": { + "ext-xml": "*", + "php": "^7.1.3", + "symfony/cache": "~4.2", + "symfony/config": "~4.2", + "symfony/contracts": "^1.0.2", + "symfony/dependency-injection": "^4.2.5", + "symfony/event-dispatcher": "^4.1", + "symfony/filesystem": "~3.4|~4.0", + "symfony/finder": "~3.4|~4.0", + "symfony/http-foundation": "^4.2.5", + "symfony/http-kernel": "^4.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/routing": "^4.2.8" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<3.0", + "phpdocumentor/type-resolver": "<0.2.1", + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", + "symfony/asset": "<3.4", + "symfony/console": "<3.4", + "symfony/dotenv": "<4.2", + "symfony/form": "<4.2", + "symfony/messenger": "<4.2", + "symfony/property-info": "<3.4", + "symfony/serializer": "<4.2", + "symfony/stopwatch": "<3.4", + "symfony/translation": "<4.2", + "symfony/twig-bridge": "<4.1.1", + "symfony/validator": "<4.1", + "symfony/workflow": "<4.1" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "doctrine/cache": "~1.0", + "fig/link-util": "^1.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0", + "symfony/asset": "~3.4|~4.0", + "symfony/browser-kit": "~3.4|~4.0", + "symfony/console": "~3.4|~4.0", + "symfony/css-selector": "~3.4|~4.0", + "symfony/dom-crawler": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/form": "^4.2.3", + "symfony/lock": "~3.4|~4.0", + "symfony/messenger": "^4.2", + "symfony/polyfill-intl-icu": "~1.0", + "symfony/process": "~3.4|~4.0", + "symfony/property-info": "~3.4|~4.0", + "symfony/security": "~3.4|~4.0", + "symfony/security-core": "~3.4|~4.0", + "symfony/security-csrf": "~3.4|~4.0", + "symfony/serializer": "^4.2", + "symfony/stopwatch": "~3.4|~4.0", + "symfony/templating": "~3.4|~4.0", + "symfony/translation": "~4.2", + "symfony/validator": "^4.1", + "symfony/var-dumper": "~3.4|~4.0", + "symfony/web-link": "~3.4|~4.0", + "symfony/workflow": "^4.1", + "symfony/yaml": "~3.4|~4.0", + "twig/twig": "~1.34|~2.4" + }, + "suggest": { + "ext-apcu": "For best performance of the system caches", + "symfony/console": "For using the console commands", + "symfony/form": "For using forms", + "symfony/property-info": "For using the property_info service", + "symfony/serializer": "For using the serializer service", + "symfony/validator": "For using validation", + "symfony/web-link": "For using web links, features such as preloading, prefetching or prerendering", + "symfony/yaml": "For using the debug:config and lint:yaml commands" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bundle\\FrameworkBundle\\": "" + }, + "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 FrameworkBundle", + "homepage": "https://symfony.com", + "time": "2019-05-01T08:36:31+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "1ea878bd3af18f934dedb8c0de60656a9a31a718" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/1ea878bd3af18f934dedb8c0de60656a9a31a718", + "reference": "1ea878bd3af18f934dedb8c0de60656a9a31a718", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.1" + }, + "require-dev": { + "predis/predis": "~1.0", + "symfony/expression-language": "~3.4|~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "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 HttpFoundation Component", + "homepage": "https://symfony.com", + "time": "2019-05-01T08:36:31+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "a7713bc522f1a1cdf0b39f809fa4542523fc3114" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/a7713bc522f1a1cdf0b39f809fa4542523fc3114", + "reference": "a7713bc522f1a1cdf0b39f809fa4542523fc3114", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/log": "~1.0", + "symfony/contracts": "^1.0.2", + "symfony/debug": "~3.4|~4.0", + "symfony/event-dispatcher": "~4.1", + "symfony/http-foundation": "^4.1.1", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/config": "<3.4", + "symfony/dependency-injection": "<4.2", + "symfony/translation": "<4.2", + "symfony/var-dumper": "<4.1.1", + "twig/twig": "<1.34|<2.4,>=2" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/cache": "~1.0", + "symfony/browser-kit": "~3.4|~4.0", + "symfony/config": "~3.4|~4.0", + "symfony/console": "~3.4|~4.0", + "symfony/css-selector": "~3.4|~4.0", + "symfony/dependency-injection": "^4.2", + "symfony/dom-crawler": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/finder": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0", + "symfony/routing": "~3.4|~4.0", + "symfony/stopwatch": "~3.4|~4.0", + "symfony/templating": "~3.4|~4.0", + "symfony/translation": "~4.2", + "symfony/var-dumper": "^4.1.1" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "", + "symfony/var-dumper": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "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 HttpKernel Component", + "homepage": "https://symfony.com", + "time": "2019-05-01T13:31:08+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.11.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "fe5e94c604826c35a32fa832f35bd036b6799609" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fe5e94c604826c35a32fa832f35bd036b6799609", + "reference": "fe5e94c604826c35a32fa832f35bd036b6799609", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "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 Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2019-02-06T07:57:58+00:00" + }, + { + "name": "symfony/routing", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "f4e43bb0dff56f0f62fa056c82d7eadcdb391bab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/f4e43bb0dff56f0f62fa056c82d7eadcdb391bab", + "reference": "f4e43bb0dff56f0f62fa056c82d7eadcdb391bab", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "conflict": { + "symfony/config": "<4.2", + "symfony/dependency-injection": "<3.4", + "symfony/yaml": "<3.4" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "psr/log": "~1.0", + "symfony/config": "~4.2", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/http-foundation": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation loader", + "symfony/config": "For using the all-in-one router or any loader", + "symfony/expression-language": "For using expression matching", + "symfony/http-foundation": "For using a Symfony Request object", + "symfony/yaml": "For using the YAML loader" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "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 Routing Component", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "time": "2019-04-27T09:38:08+00:00" + }, + { + "name": "symfony/var-exporter", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "57e00f3e0a3deee65b67cf971455b98afeacca46" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/57e00f3e0a3deee65b67cf971455b98afeacca46", + "reference": "57e00f3e0a3deee65b67cf971455b98afeacca46", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "symfony/var-dumper": "^4.1.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "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": "A blend of var_export() + serialize() to turn any serializable data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "serialize" + ], + "time": "2019-04-09T20:09:28+00:00" + }, + { + "name": "symfony/yaml", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "6712daf03ee25b53abb14e7e8e0ede1a770efdb1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/6712daf03ee25b53abb14e7e8e0ede1a770efdb1", + "reference": "6712daf03ee25b53abb14e7e8e0ede1a770efdb1", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "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 Yaml Component", + "homepage": "https://symfony.com", + "time": "2019-03-30T15:58:42+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^7.1.3", + "ext-ctype": "*", + "ext-iconv": "*" + }, + "platform-dev": [] +} diff --git a/config/bootstrap.php b/config/bootstrap.php new file mode 100644 index 0000000..570bb92 --- /dev/null +++ b/config/bootstrap.php @@ -0,0 +1,21 @@ +=1.2) +if (is_array($env = @include dirname(__DIR__).'/.env.local.php')) { + $_ENV += $env; +} elseif (!class_exists(Dotenv::class)) { + throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.'); +} else { + // load all the .env files + (new Dotenv(false))->loadEnv(dirname(__DIR__).'/.env'); +} + +$_SERVER += $_ENV; +$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev'; +$_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV']; +$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0'; diff --git a/config/bundles.php b/config/bundles.php new file mode 100644 index 0000000..49d3fb6 --- /dev/null +++ b/config/bundles.php @@ -0,0 +1,5 @@ + ['all' => true], +]; diff --git a/config/packages/cache.yaml b/config/packages/cache.yaml new file mode 100644 index 0000000..93e620e --- /dev/null +++ b/config/packages/cache.yaml @@ -0,0 +1,19 @@ +framework: + cache: + # Put the unique name of your app here: the prefix seed + # is used to compute stable namespaces for cache keys. + #prefix_seed: your_vendor_name/app_name + + # The app cache caches to the filesystem by default. + # Other options include: + + # Redis + #app: cache.adapter.redis + #default_redis_provider: redis://localhost + + # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues) + #app: cache.adapter.apcu + + # Namespaced pools use the above "app" backend by default + #pools: + #my.dedicated.cache: ~ diff --git a/config/packages/dev/routing.yaml b/config/packages/dev/routing.yaml new file mode 100644 index 0000000..4116679 --- /dev/null +++ b/config/packages/dev/routing.yaml @@ -0,0 +1,3 @@ +framework: + router: + strict_requirements: true diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml new file mode 100644 index 0000000..d3f884c --- /dev/null +++ b/config/packages/framework.yaml @@ -0,0 +1,17 @@ +framework: + secret: '%env(APP_SECRET)%' + #default_locale: en + #csrf_protection: true + #http_method_override: true + + # Enables session support. Note that the session will ONLY be started if you read or write from it. + # Remove or comment this section to explicitly disable session support. + session: + handler_id: ~ + cookie_secure: auto + cookie_samesite: lax + + #esi: true + #fragments: true + php_errors: + log: true diff --git a/config/packages/routing.yaml b/config/packages/routing.yaml new file mode 100644 index 0000000..a15c4ec --- /dev/null +++ b/config/packages/routing.yaml @@ -0,0 +1,4 @@ +framework: + router: + strict_requirements: ~ + utf8: true diff --git a/config/packages/test/framework.yaml b/config/packages/test/framework.yaml new file mode 100644 index 0000000..d051c84 --- /dev/null +++ b/config/packages/test/framework.yaml @@ -0,0 +1,4 @@ +framework: + test: true + session: + storage_id: session.storage.mock_file diff --git a/config/packages/test/routing.yaml b/config/packages/test/routing.yaml new file mode 100644 index 0000000..4116679 --- /dev/null +++ b/config/packages/test/routing.yaml @@ -0,0 +1,3 @@ +framework: + router: + strict_requirements: true diff --git a/config/routes.yaml b/config/routes.yaml new file mode 100644 index 0000000..c3283aa --- /dev/null +++ b/config/routes.yaml @@ -0,0 +1,3 @@ +#index: +# path: / +# controller: App\Controller\DefaultController::index diff --git a/config/services.yaml b/config/services.yaml new file mode 100644 index 0000000..5c4b417 --- /dev/null +++ b/config/services.yaml @@ -0,0 +1,27 @@ +# This file is the entry point to configure your own services. +# Files in the packages/ subdirectory configure your dependencies. + +# Put parameters here that don't need to change on each machine where the app is deployed +# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration +parameters: + +services: + # default configuration for services in *this* file + _defaults: + autowire: true # Automatically injects dependencies in your services. + autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. + + # makes classes in src/ available to be used as services + # this creates a service per class whose id is the fully-qualified class name + App\: + resource: '../src/*' + exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}' + + # controllers are imported separately to make sure services can be injected + # as action arguments even if you don't extend any base controller class + App\Controller\: + resource: '../src/Controller' + tags: ['controller.service_arguments'] + + # add more service definitions when explicit configuration is needed + # please note that last definitions always *replace* previous ones diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..e30f90c --- /dev/null +++ b/public/index.php @@ -0,0 +1,27 @@ +handle($request); +$response->send(); +$kernel->terminate($request, $response); diff --git a/src/Controller/.gitignore b/src/Controller/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/src/Kernel.php b/src/Kernel.php new file mode 100644 index 0000000..785b0be --- /dev/null +++ b/src/Kernel.php @@ -0,0 +1,53 @@ +getProjectDir().'/config/bundles.php'; + foreach ($contents as $class => $envs) { + if ($envs[$this->environment] ?? $envs['all'] ?? false) { + yield new $class(); + } + } + } + + public function getProjectDir(): string + { + return \dirname(__DIR__); + } + + protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void + { + $container->addResource(new FileResource($this->getProjectDir().'/config/bundles.php')); + $container->setParameter('container.dumper.inline_class_loader', true); + $confDir = $this->getProjectDir().'/config'; + + $loader->load($confDir.'/{packages}/*'.self::CONFIG_EXTS, 'glob'); + $loader->load($confDir.'/{packages}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob'); + $loader->load($confDir.'/{services}'.self::CONFIG_EXTS, 'glob'); + $loader->load($confDir.'/{services}_'.$this->environment.self::CONFIG_EXTS, 'glob'); + } + + protected function configureRoutes(RouteCollectionBuilder $routes): void + { + $confDir = $this->getProjectDir().'/config'; + + $routes->import($confDir.'/{routes}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob'); + $routes->import($confDir.'/{routes}/*'.self::CONFIG_EXTS, '/', 'glob'); + $routes->import($confDir.'/{routes}'.self::CONFIG_EXTS, '/', 'glob'); + } +} diff --git a/symfony.lock b/symfony.lock new file mode 100644 index 0000000..6db6169 --- /dev/null +++ b/symfony.lock @@ -0,0 +1,115 @@ +{ + "psr/cache": { + "version": "1.0.1" + }, + "psr/container": { + "version": "1.0.0" + }, + "psr/log": { + "version": "1.1.0" + }, + "psr/simple-cache": { + "version": "1.0.1" + }, + "symfony/cache": { + "version": "v4.2.8" + }, + "symfony/config": { + "version": "v4.2.8" + }, + "symfony/console": { + "version": "3.3", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "3.3", + "ref": "482d233eb8de91ebd042992077bbd5838858890c" + }, + "files": [ + "bin/console", + "config/bootstrap.php" + ] + }, + "symfony/contracts": { + "version": "v1.1.0" + }, + "symfony/debug": { + "version": "v4.2.8" + }, + "symfony/dependency-injection": { + "version": "v4.2.8" + }, + "symfony/dotenv": { + "version": "v4.2.8" + }, + "symfony/event-dispatcher": { + "version": "v4.2.8" + }, + "symfony/filesystem": { + "version": "v4.2.8" + }, + "symfony/finder": { + "version": "v4.2.8" + }, + "symfony/flex": { + "version": "1.0", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "1.0", + "ref": "dc3fc2e0334a4137c47cfd5a3ececc601fa61a0b" + }, + "files": [ + ".env" + ] + }, + "symfony/framework-bundle": { + "version": "4.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "4.2", + "ref": "f64037a414de7d861f68e9b5b5c0e4f7425e2002" + }, + "files": [ + "config/bootstrap.php", + "config/packages/cache.yaml", + "config/packages/framework.yaml", + "config/packages/test/framework.yaml", + "config/services.yaml", + "public/index.php", + "src/Controller/.gitignore", + "src/Kernel.php" + ] + }, + "symfony/http-foundation": { + "version": "v4.2.8" + }, + "symfony/http-kernel": { + "version": "v4.2.8" + }, + "symfony/polyfill-mbstring": { + "version": "v1.11.0" + }, + "symfony/routing": { + "version": "4.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "4.2", + "ref": "5374e24d508ba8fd6ba9eb15170255fdb778316a" + }, + "files": [ + "config/packages/dev/routing.yaml", + "config/packages/routing.yaml", + "config/packages/test/routing.yaml", + "config/routes.yaml" + ] + }, + "symfony/var-exporter": { + "version": "v4.2.8" + }, + "symfony/yaml": { + "version": "v4.2.8" + } +} From c5b6136467eec2e14f8ad5731693a8575a9fb020 Mon Sep 17 00:00:00 2001 From: Ben Hillier Date: Mon, 13 May 2019 11:35:44 +0200 Subject: [PATCH 02/20] Add docker configuration --- .env | 23 +- docker/docker-compose.yml | 20 + docker/fpm/Dockerfile | 20 + docker/fpm/php.ini | 366 +++++++++++++++++++ docker/fpm/symfony.env | 10 + docker/nginx/Dockerfile | 8 + docker/nginx/conf/www.d/.gitkeep | 0 docker/nginx/conf/www.d/cors.api.nginx | 17 + docker/nginx/conf/www.d/gzip.server.nginx | 5 + docker/nginx/conf/www.d/real_ip.server.nginx | 4 + docker/nginx/conf/www.tpl.nginx | 47 +++ docker/nginx/default.env | 15 + docker/nginx/entrypoint.sh | 23 ++ 13 files changed, 537 insertions(+), 21 deletions(-) create mode 100644 docker/docker-compose.yml create mode 100644 docker/fpm/Dockerfile create mode 100644 docker/fpm/php.ini create mode 100644 docker/fpm/symfony.env create mode 100644 docker/nginx/Dockerfile create mode 100644 docker/nginx/conf/www.d/.gitkeep create mode 100644 docker/nginx/conf/www.d/cors.api.nginx create mode 100644 docker/nginx/conf/www.d/gzip.server.nginx create mode 100644 docker/nginx/conf/www.d/real_ip.server.nginx create mode 100644 docker/nginx/conf/www.tpl.nginx create mode 100644 docker/nginx/default.env create mode 100644 docker/nginx/entrypoint.sh diff --git a/.env b/.env index 357079d..0a1c125 100644 --- a/.env +++ b/.env @@ -1,21 +1,2 @@ -# In all environments, the following files are loaded if they exist, -# the later taking precedence over the former: -# -# * .env contains default values for the environment variables needed by the app -# * .env.local uncommitted file with local overrides -# * .env.$APP_ENV committed environment-specific defaults -# * .env.$APP_ENV.local uncommitted environment-specific overrides -# -# Real environment variables win over .env files. -# -# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES. -# -# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2). -# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration - -###> symfony/framework-bundle ### -APP_ENV=dev -APP_SECRET=be45ec4c2dbfcb5df488a457fbe4216a -#TRUSTED_PROXIES=127.0.0.1,127.0.0.2 -#TRUSTED_HOSTS='^localhost|example\.com$' -###< symfony/framework-bundle ### +COMPOSE_PROJECT_NAME=openskosapi +COMPOSE_FILE=docker/docker-compose.yml \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..49d1cf5 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,20 @@ +version: "3.5" + +services: + fpm: + build: + context: .. + dockerfile: docker/fpm/Dockerfile + env_file: + - fpm/symfony.env + volumes: + - ../:/app + + nginx: + build: nginx + env_file: + - nginx/default.env + ports: + - 9020:80 + volumes: + - ./nginx:/app:ro diff --git a/docker/fpm/Dockerfile b/docker/fpm/Dockerfile new file mode 100644 index 0000000..cccda46 --- /dev/null +++ b/docker/fpm/Dockerfile @@ -0,0 +1,20 @@ +FROM php:7.3-fpm + +WORKDIR /app + +RUN apt update \ + && apt install -y libicu-dev \ + && docker-php-ext-install intl \ + && docker-php-ext-enable opcache \ + && rm -rf /var/lib/apt/lists/* \ + && mkdir -p /app/var + +COPY docker/fpm/php.ini /usr/local/etc/ + +COPY bin bin/ +COPY config config/ +COPY src src/ +COPY public public/ +COPY vendor vendor/ +COPY composer.* ./ + diff --git a/docker/fpm/php.ini b/docker/fpm/php.ini new file mode 100644 index 0000000..a427aa1 --- /dev/null +++ b/docker/fpm/php.ini @@ -0,0 +1,366 @@ +[global] +error_log = /proc/self/fd/2 +short_open_tag = off + +[www] +; if we send this to /proc/self/fd/1, it never appears +access.log = /proc/self/fd/2 + +clear_env = no + +; Ensure worker stdout and stderr are sent to the main error log. +catch_workers_output = yes + +;Default Configuration Below + +user = www-data +group = www-data + +listen = 127.0.0.1:9000 + +; Choose how the process manager will control the number of child processes. +; Possible Values: +; static - a fixed number (pm.max_children) of child processes; +; dynamic - the number of child processes are set dynamically based on the +; following directives. With this process management, there will be +; always at least 1 children. +; pm.max_children - the maximum number of children that can +; be alive at the same time. +; pm.start_servers - the number of children created on startup. +; pm.min_spare_servers - the minimum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is less than this +; number then some children will be created. +; pm.max_spare_servers - the maximum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is greater than this +; number then some children will be killed. +; ondemand - no children are created at startup. Children will be forked when +; new requests will connect. The following parameter are used: +; pm.max_children - the maximum number of children that +; can be alive at the same time. +; pm.process_idle_timeout - The number of seconds after which +; an idle process will be killed. +; Note: This value is mandatory. +pm = dynamic + +; The number of child processes to be created when pm is set to 'static' and the +; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. +; This value sets the limit on the number of simultaneous requests that will be +; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. +; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP +; CGI. The below defaults are based on a server without much resources. Don't +; forget to tweak pm.* to fit your needs. +; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' +; Note: This value is mandatory. +pm.max_children = 5 + +; The number of child processes created on startup. +; Note: Used only when pm is set to 'dynamic' +; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 +pm.start_servers = 2 + +; The desired minimum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.min_spare_servers = 1 + +; The desired maximum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.max_spare_servers = 3 + +; The number of seconds after which an idle process will be killed. +; Note: Used only when pm is set to 'ondemand' +; Default Value: 10s +;pm.process_idle_timeout = 10s; + +; The number of requests each child process should execute before respawning. +; This can be useful to work around memory leaks in 3rd party libraries. For +; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS. +; Default Value: 0 +;pm.max_requests = 500 + +; The URI to view the FPM status page. If this value is not set, no URI will be +; recognized as a status page. It shows the following informations: +; pool - the name of the pool; +; process manager - static, dynamic or ondemand; +; start time - the date and time FPM has started; +; start since - number of seconds since FPM has started; +; accepted conn - the number of request accepted by the pool; +; listen queue - the number of request in the queue of pending +; connections (see backlog in listen(2)); +; max listen queue - the maximum number of requests in the queue +; of pending connections since FPM has started; +; listen queue len - the size of the socket queue of pending connections; +; idle processes - the number of idle processes; +; active processes - the number of active processes; +; total processes - the number of idle + active processes; +; max active processes - the maximum number of active processes since FPM +; has started; +; max children reached - number of times, the process limit has been reached, +; when pm tries to start more children (works only for +; pm 'dynamic' and 'ondemand'); +; Value are updated in real time. +; Example output: +; pool: www +; process manager: static +; start time: 01/Jul/2011:17:53:49 +0200 +; start since: 62636 +; accepted conn: 190460 +; listen queue: 0 +; max listen queue: 1 +; listen queue len: 42 +; idle processes: 4 +; active processes: 11 +; total processes: 15 +; max active processes: 12 +; max children reached: 0 +; +; By default the status page output is formatted as text/plain. Passing either +; 'html', 'xml' or 'json' in the query string will return the corresponding +; output syntax. Example: +; http://www.foo.bar/status +; http://www.foo.bar/status?json +; http://www.foo.bar/status?html +; http://www.foo.bar/status?xml +; +; By default the status page only outputs short status. Passing 'full' in the +; query string will also return status for each pool process. +; Example: +; http://www.foo.bar/status?full +; http://www.foo.bar/status?json&full +; http://www.foo.bar/status?html&full +; http://www.foo.bar/status?xml&full +; The Full status returns for each process: +; pid - the PID of the process; +; state - the state of the process (Idle, Running, ...); +; start time - the date and time the process has started; +; start since - the number of seconds since the process has started; +; requests - the number of requests the process has served; +; request duration - the duration in µs of the requests; +; request method - the request method (GET, POST, ...); +; request URI - the request URI with the query string; +; content length - the content length of the request (only with POST); +; user - the user (PHP_AUTH_USER) (or '-' if not set); +; script - the main script called (or '-' if not set); +; last request cpu - the %cpu the last request consumed +; it's always 0 if the process is not in Idle state +; because CPU calculation is done when the request +; processing has terminated; +; last request memory - the max amount of memory the last request consumed +; it's always 0 if the process is not in Idle state +; because memory calculation is done when the request +; processing has terminated; +; If the process is in Idle state, then informations are related to the +; last request the process has served. Otherwise informations are related to +; the current request being served. +; Example output: +; ************************ +; pid: 31330 +; state: Running +; start time: 01/Jul/2011:17:53:49 +0200 +; start since: 63087 +; requests: 12808 +; request duration: 1250261 +; request method: GET +; request URI: /test_mem.php?N=10000 +; content length: 0 +; user: - +; script: /home/fat/web/docs/php/test_mem.php +; last request cpu: 0.00 +; last request memory: 0 +; +; Note: There is a real-time FPM status monitoring sample web page available +; It's available in: /usr/local/share/php/fpm/status.html +; +; Note: The value must start with a leading slash (/). The value can be +; anything, but it may not be a good idea to use the .php extension or it +; may conflict with a real PHP file. +; Default Value: not set +;pm.status_path = /status + +; The ping URI to call the monitoring page of FPM. If this value is not set, no +; URI will be recognized as a ping page. This could be used to test from outside +; that FPM is alive and responding, or to +; - create a graph of FPM availability (rrd or such); +; - remove a server from a group if it is not responding (load balancing); +; - trigger alerts for the operating team (24/7). +; Note: The value must start with a leading slash (/). The value can be +; anything, but it may not be a good idea to use the .php extension or it +; may conflict with a real PHP file. +; Default Value: not set +;ping.path = /ping + +; This directive may be used to customize the response of a ping request. The +; response is formatted as text/plain with a 200 response code. +; Default Value: pong +;ping.response = pong + +; The access log file +; Default: not set +;access.log = log/$pool.access.log + +; The access log format. +; The following syntax is allowed +; %%: the '%' character +; %C: %CPU used by the request +; it can accept the following format: +; - %{user}C for user CPU only +; - %{system}C for system CPU only +; - %{total}C for user + system CPU (default) +; %d: time taken to serve the request +; it can accept the following format: +; - %{seconds}d (default) +; - %{miliseconds}d +; - %{mili}d +; - %{microseconds}d +; - %{micro}d +; %e: an environment variable (same as $_ENV or $_SERVER) +; it must be associated with embraces to specify the name of the env +; variable. Some exemples: +; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e +; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e +; %f: script filename +; %l: content-length of the request (for POST request only) +; %m: request method +; %M: peak of memory allocated by PHP +; it can accept the following format: +; - %{bytes}M (default) +; - %{kilobytes}M +; - %{kilo}M +; - %{megabytes}M +; - %{mega}M +; %n: pool name +; %o: output header +; it must be associated with embraces to specify the name of the header: +; - %{Content-Type}o +; - %{X-Powered-By}o +; - %{Transfert-Encoding}o +; - .... +; %p: PID of the child that serviced the request +; %P: PID of the parent of the child that serviced the request +; %q: the query string +; %Q: the '?' character if query string exists +; %r: the request URI (without the query string, see %q and %Q) +; %R: remote IP address +; %s: status (response code) +; %t: server time the request was received +; it can accept a strftime(3) format: +; %d/%b/%Y:%H:%M:%S %z (default) +; The strftime(3) format must be encapsuled in a %{}t tag +; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t +; %T: time the log has been written (the request has finished) +; it can accept a strftime(3) format: +; %d/%b/%Y:%H:%M:%S %z (default) +; The strftime(3) format must be encapsuled in a %{}t tag +; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t +; %u: remote user +; +; Default: "%R - %u %t \"%m %r\" %s" +;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" + +; The log file for slow requests +; Default Value: not set +; Note: slowlog is mandatory if request_slowlog_timeout is set +;slowlog = log/$pool.log.slow + +; The timeout for serving a single request after which a PHP backtrace will be +; dumped to the 'slowlog' file. A value of '0s' means 'off'. +; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) +; Default Value: 0 +;request_slowlog_timeout = 0 + +; Depth of slow log stack trace. +; Default Value: 20 +;request_slowlog_trace_depth = 20 + +; The timeout for serving a single request after which the worker process will +; be killed. This option should be used when the 'max_execution_time' ini option +; does not stop script execution for some reason. A value of '0' means 'off'. +; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) +; Default Value: 0 +;request_terminate_timeout = 0 + +; Set open file descriptor rlimit. +; Default Value: system defined value +;rlimit_files = 1024 + +; Set max core size rlimit. +; Possible Values: 'unlimited' or an integer greater or equal to 0 +; Default Value: system defined value +;rlimit_core = 0 + +; Chroot to this directory at the start. This value must be defined as an +; absolute path. When this value is not set, chroot is not used. +; Note: you can prefix with '$prefix' to chroot to the pool prefix or one +; of its subdirectories. If the pool prefix is not set, the global prefix +; will be used instead. +; Note: chrooting is a great security feature and should be used whenever +; possible. However, all PHP paths will be relative to the chroot +; (error_log, sessions.save_path, ...). +; Default Value: not set +;chroot = + +; Chdir to this directory at the start. +; Note: relative path can be used. +; Default Value: current directory or / when chroot +;chdir = /var/www + +; Redirect worker stdout and stderr into main error log. If not set, stdout and +; stderr will be redirected to /dev/null according to FastCGI specs. +; Note: on highloaded environement, this can cause some delay in the page +; process time (several ms). +; Default Value: no +;catch_workers_output = yes + +; Clear environment in FPM workers +; Prevents arbitrary environment variables from reaching FPM worker processes +; by clearing the environment in workers before env vars specified in this +; pool configuration are added. +; Setting to "no" will make all environment variables available to PHP code +; via getenv(), $_ENV and $_SERVER. +; Default Value: yes +;clear_env = no + +; Limits the extensions of the main script FPM will allow to parse. This can +; prevent configuration mistakes on the web server side. You should only limit +; FPM to .php extensions to prevent malicious users to use other extensions to +; execute php code. +; Note: set an empty value to allow all extensions. +; Default Value: .php +;security.limit_extensions = .php .php3 .php4 .php5 .php7 + +; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from +; the current environment. +; Default Value: clean env +;env[HOSTNAME] = $HOSTNAME +;env[PATH] = /usr/local/bin:/usr/bin:/bin +;env[TMP] = /tmp +;env[TMPDIR] = /tmp +;env[TEMP] = /tmp + +; Additional php.ini defines, specific to this pool of workers. These settings +; overwrite the values previously defined in the php.ini. The directives are the +; same as the PHP SAPI: +; php_value/php_flag - you can set classic ini defines which can +; be overwritten from PHP call 'ini_set'. +; php_admin_value/php_admin_flag - these directives won't be overwritten by +; PHP call 'ini_set' +; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no. + +; Defining 'extension' will load the corresponding shared extension from +; extension_dir. Defining 'disable_functions' or 'disable_classes' will not +; overwrite previously defined php.ini values, but will append the new value +; instead. + +; Note: path INI options can be relative and will be expanded with the prefix +; (pool, global or /usr/local) + +; Default Value: nothing is defined by default except the values in php.ini and +; specified at startup with the -d argument +;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com +;php_flag[display_errors] = off +;php_admin_value[error_log] = /var/log/fpm-php.www.log +;php_admin_flag[log_errors] = on +;php_admin_value[memory_limit] = 32M diff --git a/docker/fpm/symfony.env b/docker/fpm/symfony.env new file mode 100644 index 0000000..d4f8d65 --- /dev/null +++ b/docker/fpm/symfony.env @@ -0,0 +1,10 @@ +# This file is a "template" of which env vars need to be defined for your application +# Copy this file to .env file for development, create environment variables when deploying to production +# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration + +###> symfony/framework-bundle ### +APP_ENV=dev +APP_SECRET=be45ec4c2dbfcb5df488a457fbe4216a +#TRUSTED_PROXIES=127.0.0.1,127.0.0.2 +#TRUSTED_HOSTS='^localhost|example\.com$' +###< symfony/framework-bundle ### diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile new file mode 100644 index 0000000..f3ff567 --- /dev/null +++ b/docker/nginx/Dockerfile @@ -0,0 +1,8 @@ +FROM nginx + +WORKDIR /app + +COPY conf/ ./conf +COPY entrypoint.sh ./ + +CMD [ "/bin/bash", "entrypoint.sh" ] \ No newline at end of file diff --git a/docker/nginx/conf/www.d/.gitkeep b/docker/nginx/conf/www.d/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docker/nginx/conf/www.d/cors.api.nginx b/docker/nginx/conf/www.d/cors.api.nginx new file mode 100644 index 0000000..2d16a8c --- /dev/null +++ b/docker/nginx/conf/www.d/cors.api.nginx @@ -0,0 +1,17 @@ +add_header 'Access-Control-Allow-Credentials' 'true' always; +add_header 'Access-Control-Allow-Origin' $http_origin always; +add_header 'Access-Control-Allow-Headers' $http_access_control_request_headers always; +add_header 'Access-Control-Allow-Methods' $http_access_control_request_method always; +add_header 'Access-Control-Max-Age' 1728000 always; + +if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Credentials' 'true'; + add_header 'Access-Control-Allow-Origin' $http_origin; + add_header 'Access-Control-Allow-Headers' $http_access_control_request_headers; + add_header 'Access-Control-Allow-Methods' $http_access_control_request_method; + add_header 'Access-Control-Max-Age' 1728000; + + add_header 'Content-Type' 'text/plain; charset=utf-8'; + add_header 'Content-Length' 0; + return 204; +} \ No newline at end of file diff --git a/docker/nginx/conf/www.d/gzip.server.nginx b/docker/nginx/conf/www.d/gzip.server.nginx new file mode 100644 index 0000000..e0622e3 --- /dev/null +++ b/docker/nginx/conf/www.d/gzip.server.nginx @@ -0,0 +1,5 @@ + gzip on; + gzip_comp_level 2; + gzip_min_length 1000; + gzip_proxied expired no-cache no-store private auth; + gzip_types text/plain application/x-javascript application/javascript text/xml text/css application/xml; \ No newline at end of file diff --git a/docker/nginx/conf/www.d/real_ip.server.nginx b/docker/nginx/conf/www.d/real_ip.server.nginx new file mode 100644 index 0000000..68c0748 --- /dev/null +++ b/docker/nginx/conf/www.d/real_ip.server.nginx @@ -0,0 +1,4 @@ +proxy_set_header X-Real-IP $http_x_client_ip; +# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_set_header X-Forwarded-For "$http_x_client_ip, $http_x_forwarded_for"; +#proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; diff --git a/docker/nginx/conf/www.tpl.nginx b/docker/nginx/conf/www.tpl.nginx new file mode 100644 index 0000000..f84ae1c --- /dev/null +++ b/docker/nginx/conf/www.tpl.nginx @@ -0,0 +1,47 @@ +## +# Base configuration only for HTTP connections. +# For HTTPS, you need to update this configuration in order to add +# ssl related stuff +## +# This file is TEMPLATE. All variables like $EXAMPLE or ${EXAMPLE} must be substituded +# the best tools for that kind of substitusion is envsubst https://www.gnu.org/software/gettext/manual/html_node/envsubst-Invocation.html +## +# TODO: Create production verion of that configuration. +# Remove: debug pathes (_profiler, _wdt) from location +# Add proper error redirects +## + +server { + listen $PORT; + server_name $DOMAIN; + + # Include server-related configuration + include www.d/*.server.nginx; + + # Location that forwards all request that didn't matched locations above to FPM server + # Replace location path '/' to appropriate value in other nginx configruations. + location / { + try_files $uri @fpm; + } + + # Named location to proxy HTTP request to Fast CGI server. + location @fpm { + # Include api location related configuration + include www.d/*.api.nginx; + + # General FPM Configuration + set $api_root $FPM_ROOT; + set $api_entrypoint $FPM_ENTRYPOINT; + fastcgi_pass $FPM_URL; + + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $api_root/$api_entrypoint; + fastcgi_param SCRIPT_NAME $api_entrypoint; + } + + # Restrict access to any other location. + # location / { + # return 403; + # } + +} \ No newline at end of file diff --git a/docker/nginx/default.env b/docker/nginx/default.env new file mode 100644 index 0000000..2ee4e20 --- /dev/null +++ b/docker/nginx/default.env @@ -0,0 +1,15 @@ +## +# Default Environmental Configuration for Nginx Server +## + +APP_ENV=dev + +PORT=80 +DOMAIN=http + +API_PREFIX=api + +# FPM Configuration MUST be syncronized with fpm service +FPM_ROOT=/app/public +FPM_ENTRYPOINT=index.php +FPM_URL=fpm:9000 \ No newline at end of file diff --git a/docker/nginx/entrypoint.sh b/docker/nginx/entrypoint.sh new file mode 100644 index 0000000..5713e51 --- /dev/null +++ b/docker/nginx/entrypoint.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -ex + +# Link dynamic configurations of www.conf to nginx +ln -rsf conf/www.d/ /etc/nginx/ + +# Process template file and replace default.conf of nginx +envsubst \ + '$PORT $DOMAIN $API_PREFIX + $FPM_ROOT $FPM_ENTRYPOINT $FPM_URL' \ + < conf/www.tpl.nginx \ + > /etc/nginx/conf.d/default.conf + +if [ "$APP_ENV" == "dev" ]; then + echo "Applied configuration: " + cat /etc/nginx/conf.d/default.conf + echo "" #Print End Of Line for good formatting + echo "End of Configuration." +fi + +# Run nginx +exec nginx-debug -g 'daemon off;' \ No newline at end of file From 08aa6122b534cf0bb5960568375108db7c426a02 Mon Sep 17 00:00:00 2001 From: Ben Hillier Date: Mon, 13 May 2019 11:37:26 +0200 Subject: [PATCH 03/20] Ad docker README reminder --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index a5a5b45..8e6d2b2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ # OpenSkos-API Restful API for OpenSkos + + +## Docker +TODO From 07da6b40251983b46b8233eb2dbec56d0bc2840c Mon Sep 17 00:00:00 2001 From: Ben Hillier Date: Mon, 13 May 2019 12:23:23 +0200 Subject: [PATCH 04/20] Add Annotations and Ping controller --- composer.json | 1 + composer.lock | 575 +++++++++++++++++++- config/bundles.php | 1 + config/packages/healthcheck.yaml | 9 + config/packages/sensio_framework_extra.yaml | 3 + config/routes/annotations.yaml | 5 + config/services.yaml | 18 - src/Controller/.gitignore | 0 src/Healthcheck/PingController.php | 17 + symfony.lock | 42 ++ 10 files changed, 651 insertions(+), 20 deletions(-) create mode 100644 config/packages/healthcheck.yaml create mode 100644 config/packages/sensio_framework_extra.yaml create mode 100644 config/routes/annotations.yaml delete mode 100644 src/Controller/.gitignore create mode 100644 src/Healthcheck/PingController.php diff --git a/composer.json b/composer.json index d04295b..5a98f47 100644 --- a/composer.json +++ b/composer.json @@ -5,6 +5,7 @@ "php": "^7.1.3", "ext-ctype": "*", "ext-iconv": "*", + "sensio/framework-extra-bundle": "^5.3", "symfony/console": "4.2.*", "symfony/dotenv": "4.2.*", "symfony/flex": "^1.1", diff --git a/composer.lock b/composer.lock index f026b7d..8f2289d 100644 --- a/composer.lock +++ b/composer.lock @@ -1,11 +1,509 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f143832e85df629dc1a54d892987b0d4", + "content-hash": "dd6a0b4ecbc0f68885ef6ff0c03be02e", "packages": [ + { + "name": "doctrine/annotations", + "version": "v1.6.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "53120e0eb10355388d6ccbe462f1fea34ddadb24" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/53120e0eb10355388d6ccbe462f1fea34ddadb24", + "reference": "53120e0eb10355388d6ccbe462f1fea34ddadb24", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": "^7.1" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "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" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2019-03-25T19:12:02+00:00" + }, + { + "name": "doctrine/cache", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/d768d58baee9a4862ca783840eca1b9add7a7f57", + "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57", + "shasum": "" + }, + "require": { + "php": "~7.1" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "alcaeus/mongo-php-adapter": "^1.1", + "doctrine/coding-standard": "^4.0", + "mongodb/mongodb": "^1.1", + "phpunit/phpunit": "^7.0", + "predis/predis": "~1.0" + }, + "suggest": { + "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "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" + } + ], + "description": "Caching library offering an object-oriented API for many cache backends", + "homepage": "https://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2018-08-21T18:01:43+00:00" + }, + { + "name": "doctrine/collections", + "version": "v1.6.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "d2ae4ef05e25197343b6a39bae1d3c427a2f6956" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/d2ae4ef05e25197343b6a39bae1d3c427a2f6956", + "reference": "d2ae4ef05e25197343b6a39bae1d3c427a2f6956", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "phpstan/phpstan-shim": "^0.9.2", + "phpunit/phpunit": "^7.0", + "vimeo/psalm": "^3.2.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Collections\\": "lib/Doctrine/Common/Collections" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "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" + } + ], + "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.", + "homepage": "https://www.doctrine-project.org/projects/collections.html", + "keywords": [ + "array", + "collections", + "iterators", + "php" + ], + "time": "2019-03-25T19:03:48+00:00" + }, + { + "name": "doctrine/event-manager", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/event-manager.git", + "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3", + "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "conflict": { + "doctrine/common": "<2.9@dev" + }, + "require-dev": { + "doctrine/coding-standard": "^4.0", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "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": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Doctrine Event Manager component", + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", + "keywords": [ + "event", + "eventdispatcher", + "eventmanager" + ], + "time": "2018-06-11T11:59:03+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": "doctrine/persistence", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/persistence.git", + "reference": "3da7c9d125591ca83944f477e65ed3d7b4617c48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/3da7c9d125591ca83944f477e65ed3d7b4617c48", + "reference": "3da7c9d125591ca83944f477e65ed3d7b4617c48", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.0", + "doctrine/cache": "^1.0", + "doctrine/collections": "^1.0", + "doctrine/event-manager": "^1.0", + "doctrine/reflection": "^1.0", + "php": "^7.1" + }, + "conflict": { + "doctrine/common": "<2.10@dev" + }, + "require-dev": { + "doctrine/coding-standard": "^5.0", + "phpstan/phpstan": "^0.8", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "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": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.", + "homepage": "https://doctrine-project.org/projects/persistence.html", + "keywords": [ + "mapper", + "object", + "odm", + "orm", + "persistence" + ], + "time": "2019-04-23T08:28:24+00:00" + }, + { + "name": "doctrine/reflection", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/reflection.git", + "reference": "02538d3f95e88eb397a5f86274deb2c6175c2ab6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/reflection/zipball/02538d3f95e88eb397a5f86274deb2c6175c2ab6", + "reference": "02538d3f95e88eb397a5f86274deb2c6175c2ab6", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.0", + "ext-tokenizer": "*", + "php": "^7.1" + }, + "require-dev": { + "doctrine/coding-standard": "^4.0", + "doctrine/common": "^2.8", + "phpstan/phpstan": "^0.9.2", + "phpstan/phpstan-phpunit": "^0.9.4", + "phpunit/phpunit": "^7.0", + "squizlabs/php_codesniffer": "^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "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": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Doctrine Reflection component", + "homepage": "https://www.doctrine-project.org/projects/reflection.html", + "keywords": [ + "reflection" + ], + "time": "2018-06-14T14:45:07+00:00" + }, { "name": "psr/cache", "version": "1.0.1", @@ -196,6 +694,79 @@ ], "time": "2017-10-23T01:57:42+00:00" }, + { + "name": "sensio/framework-extra-bundle", + "version": "v5.3.1", + "source": { + "type": "git", + "url": "https://github.com/sensiolabs/SensioFrameworkExtraBundle.git", + "reference": "5f75c4658b03301cba17baa15a840b57b72b4262" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/5f75c4658b03301cba17baa15a840b57b72b4262", + "reference": "5f75c4658b03301cba17baa15a840b57b72b4262", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.0", + "doctrine/persistence": "^1.0", + "php": ">=7.1.3", + "symfony/config": "^3.4|^4.2", + "symfony/dependency-injection": "^3.4|^4.2", + "symfony/framework-bundle": "^3.4|^4.2", + "symfony/http-kernel": "^3.4|^4.2" + }, + "require-dev": { + "doctrine/doctrine-bundle": "^1.6", + "doctrine/orm": "^2.5", + "nyholm/psr7": "^1.1", + "symfony/browser-kit": "^3.4|^4.2", + "symfony/dom-crawler": "^3.4|^4.2", + "symfony/expression-language": "^3.4|^4.2", + "symfony/finder": "^3.4|^4.2", + "symfony/monolog-bridge": "^3.0|^4.0", + "symfony/monolog-bundle": "^3.2", + "symfony/phpunit-bridge": "^3.4.19|^4.1.8", + "symfony/psr-http-message-bridge": "^1.1", + "symfony/security-bundle": "^3.4|^4.2", + "symfony/twig-bundle": "^3.4|^4.2", + "symfony/yaml": "^3.4|^4.2", + "twig/twig": "~1.12|~2.0" + }, + "suggest": { + "symfony/expression-language": "", + "symfony/psr-http-message-bridge": "To use the PSR-7 converters", + "symfony/security-bundle": "" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "5.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Sensio\\Bundle\\FrameworkExtraBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "This bundle provides a way to configure your controllers with annotations", + "keywords": [ + "annotations", + "controllers" + ], + "time": "2019-04-10T06:00:20+00:00" + }, { "name": "symfony/cache", "version": "v4.2.8", diff --git a/config/bundles.php b/config/bundles.php index 49d3fb6..0d71512 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -2,4 +2,5 @@ return [ Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], + Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true], ]; diff --git a/config/packages/healthcheck.yaml b/config/packages/healthcheck.yaml new file mode 100644 index 0000000..6d2701c --- /dev/null +++ b/config/packages/healthcheck.yaml @@ -0,0 +1,9 @@ +#TODO: Think about moving this configuration file into src/Healthcheck/config so it will be close to the related code +services: + # default configuration for services in *this* file + _defaults: + autowire: true # Automatically injects dependencies in your services. + autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. + + App\Healthcheck\PingController: + tags: ['controller.service_arguments'] diff --git a/config/packages/sensio_framework_extra.yaml b/config/packages/sensio_framework_extra.yaml new file mode 100644 index 0000000..1821ccc --- /dev/null +++ b/config/packages/sensio_framework_extra.yaml @@ -0,0 +1,3 @@ +sensio_framework_extra: + router: + annotations: false diff --git a/config/routes/annotations.yaml b/config/routes/annotations.yaml new file mode 100644 index 0000000..b0a6ded --- /dev/null +++ b/config/routes/annotations.yaml @@ -0,0 +1,5 @@ +#TODO: Move this configuration into package level. +#TODO: For example into config/packages/healthcheck.yaml +controllers: + resource: ../../src/Healthcheck/ + type: annotation diff --git a/config/services.yaml b/config/services.yaml index 5c4b417..0d53396 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -7,21 +7,3 @@ parameters: services: # default configuration for services in *this* file - _defaults: - autowire: true # Automatically injects dependencies in your services. - autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. - - # makes classes in src/ available to be used as services - # this creates a service per class whose id is the fully-qualified class name - App\: - resource: '../src/*' - exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}' - - # controllers are imported separately to make sure services can be injected - # as action arguments even if you don't extend any base controller class - App\Controller\: - resource: '../src/Controller' - tags: ['controller.service_arguments'] - - # add more service definitions when explicit configuration is needed - # please note that last definitions always *replace* previous ones diff --git a/src/Controller/.gitignore b/src/Controller/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/src/Healthcheck/PingController.php b/src/Healthcheck/PingController.php new file mode 100644 index 0000000..61f39d0 --- /dev/null +++ b/src/Healthcheck/PingController.php @@ -0,0 +1,17 @@ + Date: Mon, 13 May 2019 12:55:11 +0200 Subject: [PATCH 05/20] Add code validators --- .gitignore | 11 +- .php_cs.dist | 8 + composer.json | 6 + composer.lock | 1900 +++++++++++++++++++++++++++- grumphp.yml | 4 + phpcs.xml.dist | 19 + src/Healthcheck/PingController.php | 7 +- symfony.lock | 111 ++ 8 files changed, 2061 insertions(+), 5 deletions(-) create mode 100644 .php_cs.dist create mode 100644 grumphp.yml create mode 100644 phpcs.xml.dist diff --git a/.gitignore b/.gitignore index 0a0f532..3e71bfb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ - ###> symfony/framework-bundle ### /.env.local /.env.local.php @@ -11,3 +10,13 @@ .DS_Store .idea + +###> squizlabs/php_codesniffer ### +/.phpcs-cache +/phpcs.xml +###< squizlabs/php_codesniffer ### + +###> friendsofphp/php-cs-fixer ### +/.php_cs +/.php_cs.cache +###< friendsofphp/php-cs-fixer ### diff --git a/.php_cs.dist b/.php_cs.dist new file mode 100644 index 0000000..d80e5d6 --- /dev/null +++ b/.php_cs.dist @@ -0,0 +1,8 @@ +setRules([ + '@Symfony' => true, + 'array_syntax' => ['syntax' => 'short'], + ]) +; diff --git a/composer.json b/composer.json index 5a98f47..4eca2cb 100644 --- a/composer.json +++ b/composer.json @@ -56,5 +56,11 @@ "allow-contrib": false, "require": "4.2.*" } + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.15", + "phpro/grumphp": "^0.15.0", + "phpstan/phpstan": "^0.11.6", + "squizlabs/php_codesniffer": "^3.4" } } diff --git a/composer.lock b/composer.lock index 8f2289d..be08e34 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": "dd6a0b4ecbc0f68885ef6ff0c03be02e", + "content-hash": "d65df88e6b69e0f97a9ca81e10c34181", "packages": [ { "name": "doctrine/annotations", @@ -1965,7 +1965,1903 @@ "time": "2019-03-30T15:58:42+00:00" } ], - "packages-dev": [], + "packages-dev": [ + { + "name": "composer/ca-bundle", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/558f321c52faeb4828c03e7dc0cfe39a09e09a2d", + "reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5", + "psr/log": "^1.0", + "symfony/process": "^2.5 || ^3.0 || ^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "time": "2019-01-28T09:30:10+00:00" + }, + { + "name": "composer/composer", + "version": "1.8.5", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "949b116f9e7d98d8d276594fed74b580d125c0e6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/949b116f9e7d98d8d276594fed74b580d125c0e6", + "reference": "949b116f9e7d98d8d276594fed74b580d125c0e6", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "composer/semver": "^1.0", + "composer/spdx-licenses": "^1.2", + "composer/xdebug-handler": "^1.1", + "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0", + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0", + "seld/jsonlint": "^1.4", + "seld/phar-utils": "^1.0", + "symfony/console": "^2.7 || ^3.0 || ^4.0", + "symfony/filesystem": "^2.7 || ^3.0 || ^4.0", + "symfony/finder": "^2.7 || ^3.0 || ^4.0", + "symfony/process": "^2.7 || ^3.0 || ^4.0" + }, + "conflict": { + "symfony/console": "2.8.38" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7", + "phpunit/phpunit-mock-objects": "^2.3 || ^3.0" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives", + "ext-zlib": "Allow gzip compression of HTTP requests" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\": "src/Composer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects, ensuring you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "time": "2019-04-09T15:46:48+00:00" + }, + { + "name": "composer/semver", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "46d9139568ccb8d9e7cdd4539cab7347568a5e2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/46d9139568ccb8d9e7cdd4539cab7347568a5e2e", + "reference": "46d9139568ccb8d9e7cdd4539cab7347568a5e2e", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "time": "2019-03-19T17:25:45+00:00" + }, + { + "name": "composer/spdx-licenses", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "a1aa51cf3ab838b83b0867b14e56fc20fbd55b3d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/a1aa51cf3ab838b83b0867b14e56fc20fbd55b3d", + "reference": "a1aa51cf3ab838b83b0867b14e56fc20fbd55b3d", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "time": "2019-03-26T10:23:26+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "1.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "d17708133b6c276d6e42ef887a877866b909d892" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/d17708133b6c276d6e42ef887a877866b909d892", + "reference": "d17708133b6c276d6e42ef887a877866b909d892", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "time": "2019-01-28T20:25:53+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v2.15.0", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", + "reference": "adfab51ae979ee8b0fcbc55aa231ec2786cb1f91" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/adfab51ae979ee8b0fcbc55aa231ec2786cb1f91", + "reference": "adfab51ae979ee8b0fcbc55aa231ec2786cb1f91", + "shasum": "" + }, + "require": { + "composer/semver": "^1.4", + "composer/xdebug-handler": "^1.2", + "doctrine/annotations": "^1.2", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^5.6 || ^7.0", + "php-cs-fixer/diff": "^1.3", + "symfony/console": "^3.4.17 || ^4.1.6", + "symfony/event-dispatcher": "^3.0 || ^4.0", + "symfony/filesystem": "^3.0 || ^4.0", + "symfony/finder": "^3.0 || ^4.0", + "symfony/options-resolver": "^3.0 || ^4.0", + "symfony/polyfill-php70": "^1.0", + "symfony/polyfill-php72": "^1.4", + "symfony/process": "^3.0 || ^4.0", + "symfony/stopwatch": "^3.0 || ^4.0" + }, + "require-dev": { + "johnkary/phpunit-speedtrap": "^1.1 || ^2.0 || ^3.0", + "justinrainbow/json-schema": "^5.0", + "keradus/cli-executor": "^1.2", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.1", + "php-cs-fixer/accessible-object": "^1.0", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.1", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.1", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1", + "phpunitgoodpractices/traits": "^1.8", + "symfony/phpunit-bridge": "^4.0" + }, + "suggest": { + "ext-mbstring": "For handling non-UTF8 characters in cache signature.", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "For IsIdenticalString constraint.", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "For XmlMatchesXsd constraint.", + "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "extra": { + "branch-alias": { + "dev-master": "2.15-dev" + } + }, + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "classmap": [ + "tests/Test/AbstractFixerTestCase.php", + "tests/Test/AbstractIntegrationCaseFactory.php", + "tests/Test/AbstractIntegrationTestCase.php", + "tests/Test/Assert/AssertTokensTrait.php", + "tests/Test/IntegrationCase.php", + "tests/Test/IntegrationCaseFactory.php", + "tests/Test/IntegrationCaseFactoryInterface.php", + "tests/Test/InternalIntegrationCaseFactory.php", + "tests/TestCase.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "time": "2019-05-06T07:13:51+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": "jean85/pretty-package-versions", + "version": "1.2", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/75c7effcf3f77501d0e0caa75111aff4daa0dd48", + "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48", + "shasum": "" + }, + "require": { + "ocramius/package-versions": "^1.2.0", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A wrapper for ocramius/package-versions to get pretty versions strings", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "time": "2018-06-13T13:22:40+00:00" + }, + { + "name": "justinrainbow/json-schema", + "version": "5.2.8", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "dcb6e1006bb5fd1e392b4daa68932880f37550d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/dcb6e1006bb5fd1e392b4daa68932880f37550d4", + "reference": "dcb6e1006bb5fd1e392b4daa68932880f37550d4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.2.20", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.35" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "time": "2019-01-14T23:55:14+00:00" + }, + { + "name": "monolog/monolog", + "version": "1.24.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", + "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "graylog2/gelf-php": "~1.0", + "jakub-onderka/php-parallel-lint": "0.9", + "php-amqplib/php-amqplib": "~2.4", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "ruflin/elastica": ">=0.90 <3.0", + "sentry/sentry": "^0.13", + "swiftmailer/swiftmailer": "^5.3|^6.0" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server", + "sentry/sentry": "Allow sending log messages to a Sentry server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "time": "2018-11-05T09:00:11+00:00" + }, + { + "name": "nette/bootstrap", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/bootstrap.git", + "reference": "e1075af05c211915e03e0c86542f3ba5433df4a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/bootstrap/zipball/e1075af05c211915e03e0c86542f3ba5433df4a3", + "reference": "e1075af05c211915e03e0c86542f3ba5433df4a3", + "shasum": "" + }, + "require": { + "nette/di": "^3.0", + "nette/utils": "^3.0", + "php": ">=7.1" + }, + "require-dev": { + "latte/latte": "^2.2", + "nette/application": "^3.0", + "nette/caching": "^3.0", + "nette/database": "^3.0", + "nette/forms": "^3.0", + "nette/http": "^3.0", + "nette/mail": "^3.0", + "nette/robot-loader": "^3.0", + "nette/safe-stream": "^2.2", + "nette/security": "^3.0", + "nette/tester": "^2.0", + "tracy/tracy": "^2.6" + }, + "suggest": { + "nette/robot-loader": "to use Configurator::createRobotLoader()", + "tracy/tracy": "to use Configurator::enableTracy()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", + "homepage": "https://nette.org", + "keywords": [ + "bootstrapping", + "configurator", + "nette" + ], + "time": "2019-03-26T12:59:07+00:00" + }, + { + "name": "nette/di", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/di.git", + "reference": "19d83539245aaacb59470828919182411061841f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/di/zipball/19d83539245aaacb59470828919182411061841f", + "reference": "19d83539245aaacb59470828919182411061841f", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/neon": "^3.0", + "nette/php-generator": "^3.2.2", + "nette/robot-loader": "^3.2", + "nette/schema": "^1.0", + "nette/utils": "^3.0", + "php": ">=7.1" + }, + "conflict": { + "nette/bootstrap": "<3.0" + }, + "require-dev": { + "nette/tester": "^2.2", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ], + "files": [ + "src/compatibility.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP 7.1 features.", + "homepage": "https://nette.org", + "keywords": [ + "compiled", + "di", + "dic", + "factory", + "ioc", + "nette", + "static" + ], + "time": "2019-04-03T19:35:46+00:00" + }, + { + "name": "nette/finder", + "version": "v2.5.0", + "source": { + "type": "git", + "url": "https://github.com/nette/finder.git", + "reference": "6be1b83ea68ac558aff189d640abe242e0306fe2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/finder/zipball/6be1b83ea68ac558aff189d640abe242e0306fe2", + "reference": "6be1b83ea68ac558aff189d640abe242e0306fe2", + "shasum": "" + }, + "require": { + "nette/utils": "^2.4 || ~3.0.0", + "php": ">=7.1" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "? Nette Finder: find files and directories with an intuitive API.", + "homepage": "https://nette.org", + "keywords": [ + "filesystem", + "glob", + "iterator", + "nette" + ], + "time": "2019-02-28T18:13:25+00:00" + }, + { + "name": "nette/neon", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/neon.git", + "reference": "cbff32059cbdd8720deccf9e9eace6ee516f02eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/neon/zipball/cbff32059cbdd8720deccf9e9eace6ee516f02eb", + "reference": "cbff32059cbdd8720deccf9e9eace6ee516f02eb", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "ext-json": "*", + "php": ">=7.0" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "? Nette NEON: encodes and decodes NEON file format.", + "homepage": "http://ne-on.org", + "keywords": [ + "export", + "import", + "neon", + "nette", + "yaml" + ], + "time": "2019-02-05T21:30:40+00:00" + }, + { + "name": "nette/php-generator", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/nette/php-generator.git", + "reference": "acff8b136fad84b860a626d133e791f95781f9f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/php-generator/zipball/acff8b136fad84b860a626d133e791f95781f9f5", + "reference": "acff8b136fad84b860a626d133e791f95781f9f5", + "shasum": "" + }, + "require": { + "nette/utils": "^2.4.2 || ~3.0.0", + "php": ">=7.1" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 7.3 features.", + "homepage": "https://nette.org", + "keywords": [ + "code", + "nette", + "php", + "scaffolding" + ], + "time": "2019-03-15T03:41:13+00:00" + }, + { + "name": "nette/robot-loader", + "version": "v3.2.0", + "source": { + "type": "git", + "url": "https://github.com/nette/robot-loader.git", + "reference": "0712a0e39ae7956d6a94c0ab6ad41aa842544b5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/0712a0e39ae7956d6a94c0ab6ad41aa842544b5c", + "reference": "0712a0e39ae7956d6a94c0ab6ad41aa842544b5c", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/finder": "^2.5", + "nette/utils": "^3.0", + "php": ">=7.1" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "? Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", + "homepage": "https://nette.org", + "keywords": [ + "autoload", + "class", + "interface", + "nette", + "trait" + ], + "time": "2019-03-08T21:57:24+00:00" + }, + { + "name": "nette/schema", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "6241d8d4da39e825dd6cb5bfbe4242912f4d7e4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/6241d8d4da39e825dd6cb5bfbe4242912f4d7e4d", + "reference": "6241d8d4da39e825dd6cb5bfbe4242912f4d7e4d", + "shasum": "" + }, + "require": { + "nette/utils": "^3.0.1", + "php": ">=7.1" + }, + "require-dev": { + "nette/tester": "^2.2", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "time": "2019-04-03T15:53:25+00:00" + }, + { + "name": "nette/utils", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "bd961f49b211997202bda1d0fbc410905be370d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/bd961f49b211997202bda1d0fbc410905be370d4", + "reference": "bd961f49b211997202bda1d0fbc410905be370d4", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "nette/tester": "~2.0", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize() and toAscii()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "time": "2019-03-22T01:00:30+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.2.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "5221f49a608808c1e4d436df32884cbc1b821ac0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/5221f49a608808c1e4d436df32884cbc1b821ac0", + "reference": "5221f49a608808c1e4d436df32884cbc1b821ac0", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5 || ^7.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2019-02-16T20:54:15+00:00" + }, + { + "name": "ocramius/package-versions", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/PackageVersions.git", + "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", + "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0.0", + "php": "^7.1.0" + }, + "require-dev": { + "composer/composer": "^1.6.3", + "doctrine/coding-standard": "^5.0.1", + "ext-zip": "*", + "infection/infection": "^0.7.1", + "phpunit/phpunit": "^7.0.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "time": "2019-02-21T12:16:21+00:00" + }, + { + "name": "php-cs-fixer/diff", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/diff.git", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/78bb099e9c16361126c86ce82ec4405ebab8e756", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "symfony/process": "^3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "SpacePossum" + } + ], + "description": "sebastian/diff v2 backport support for PHP5.6", + "homepage": "https://github.com/PHP-CS-Fixer", + "keywords": [ + "diff" + ], + "time": "2018-02-15T16:58:55+00:00" + }, + { + "name": "phpro/grumphp", + "version": "v0.15.0", + "source": { + "type": "git", + "url": "https://github.com/phpro/grumphp.git", + "reference": "5a6fd0ab90c9f837a7c79a5f61ef1b33f1ace8c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpro/grumphp/zipball/5a6fd0ab90c9f837a7c79a5f61ef1b33f1ace8c1", + "reference": "5a6fd0ab90c9f837a7c79a5f61ef1b33f1ace8c1", + "shasum": "" + }, + "require": { + "composer-plugin-api": "~1.0", + "composer/composer": "^1.0", + "doctrine/collections": "~1.2", + "gitonomy/gitlib": "^1.0.3", + "monolog/monolog": "~1.16", + "php": ">=7.0", + "seld/jsonlint": "~1.1", + "symfony/config": "~3.0|~4.0", + "symfony/console": "~3.0|~4.0", + "symfony/dependency-injection": "~3.0|~4.0", + "symfony/event-dispatcher": "~3.0|~4.0", + "symfony/filesystem": "~3.0|~4.0", + "symfony/finder": "~3.0|~4.0", + "symfony/options-resolver": "~3.0|~4.0", + "symfony/process": "~3.2|~4.0", + "symfony/yaml": "~3.0|~4.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2", + "jakub-onderka/php-parallel-lint": "^0.9.2", + "nikic/php-parser": "~2.1", + "phpspec/phpspec": "^3.2.2", + "phpspec/prophecy": "^1.6.2", + "phpunit/phpunit": "^6.5|^7.0", + "sebastian/comparator": "^2.1", + "sebastian/diff": "^2.0", + "sebastian/exporter": "^3.1", + "sensiolabs/security-checker": "^4.0", + "squizlabs/php_codesniffer": "~2.4" + }, + "suggest": { + "atoum/atoum": "Lets GrumPHP run your unit tests.", + "behat/behat": "Lets GrumPHP validate your project features.", + "codeception/codeception": "Lets GrumPHP run your project's full stack tests", + "codegyre/robo": "Lets GrumPHP run your automated PHP tasks.", + "designsecurity/progpilot": "Lets GrumPHP be sure that there are no vulnerabilities in your code.", + "doctrine/orm": "Lets GrumPHP validate your Doctrine mapping files.", + "friendsofphp/php-cs-fixer": "Lets GrumPHP automatically fix your codestyle.", + "infection/infection": "Lets GrumPHP evaluate the quality your unit tests", + "jakub-onderka/php-parallel-lint": "Lets GrumPHP quickly lint your entire code base.", + "maglnet/composer-require-checker": "Lets GrumPHP analyze composer dependencies.", + "malukenho/kawaii-gherkin": "Lets GrumPHP lint your Gherkin files.", + "nikic/php-parser": "Lets GrumPHP run static analyses through your PHP files.", + "phan/phan": "Lets GrumPHP unleash a static analyzer on your code", + "phing/phing": "Lets GrumPHP run your automated PHP tasks.", + "phpmd/phpmd": "Lets GrumPHP sort out the mess in your code", + "phpspec/phpspec": "Lets GrumPHP spec your code.", + "phpstan/phpstan": "Lets GrumPHP discover bugs in your code without running it.", + "phpunit/phpunit": "Lets GrumPHP run your unit tests.", + "povils/phpmnd": "Lets GrumPHP help you detect magic numbers in PHP code.", + "roave/security-advisories": "Lets GrumPHP be sure that there are no known security issues.", + "sebastian/phpcpd": "Lets GrumPHP find duplicated code.", + "sensiolabs/security-checker": "Lets GrumPHP be sure that there are no known security issues.", + "squizlabs/php_codesniffer": "Lets GrumPHP sniff on your code.", + "sstalle/php7cc": "Lets GrumPHP check PHP 5.3 - 5.6 code compatibility with PHP 7.", + "symfony/phpunit-bridge": "Lets GrumPHP run your unit tests with the phpunit-bridge of Symfony.", + "vimeo/psalm": "Lets GrumPHP discover errors in your code without running it." + }, + "bin": [ + "bin/grumphp" + ], + "type": "composer-plugin", + "extra": { + "class": "GrumPHP\\Composer\\GrumPHPPlugin" + }, + "autoload": { + "psr-4": { + "GrumPHP\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Toon Verwerft", + "email": "toon.verwerft@phpro.be" + }, + { + "name": "Community", + "homepage": "https://github.com/phpro/grumphp/graphs/contributors" + } + ], + "description": "A composer plugin that enables source code quality checks.", + "time": "2019-02-22T06:02:18+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "0.3.3", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "472d3161d289f652713a5e353532fa4592663a57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/472d3161d289f652713a5e353532fa4592663a57", + "reference": "472d3161d289f652713a5e353532fa4592663a57", + "shasum": "" + }, + "require": { + "php": "~7.1" + }, + "require-dev": { + "consistence/coding-standard": "^3.5", + "jakub-onderka/php-parallel-lint": "^0.9.2", + "phing/phing": "^2.16.0", + "phpstan/phpstan": "^0.10", + "phpunit/phpunit": "^6.3", + "slevomat/coding-standard": "^4.7.2", + "squizlabs/php_codesniffer": "^3.3.2", + "symfony/process": "^3.4 || ^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.3-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "time": "2019-04-23T20:26:19+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "0.11.6", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "7af8b9d02b3ab36444dbf4e1b9ca1c1bd5044d81" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7af8b9d02b3ab36444dbf4e1b9ca1c1bd5044d81", + "reference": "7af8b9d02b3ab36444dbf4e1b9ca1c1bd5044d81", + "shasum": "" + }, + "require": { + "composer/xdebug-handler": "^1.3.0", + "jean85/pretty-package-versions": "^1.0.3", + "nette/bootstrap": "^2.4 || ^3.0", + "nette/di": "^2.4.7 || ^3.0", + "nette/robot-loader": "^3.0.1", + "nette/utils": "^2.4.5 || ^3.0", + "nikic/php-parser": "^4.0.2", + "php": "~7.1", + "phpstan/phpdoc-parser": "^0.3", + "symfony/console": "~3.2 || ~4.0", + "symfony/finder": "~3.2 || ~4.0" + }, + "conflict": { + "symfony/console": "3.4.16 || 4.1.5" + }, + "require-dev": { + "brianium/paratest": "^2.0", + "consistence/coding-standard": "^3.5", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "ext-intl": "*", + "ext-mysqli": "*", + "ext-soap": "*", + "ext-zip": "*", + "jakub-onderka/php-parallel-lint": "^1.0", + "localheinz/composer-normalize": "^1.1.0", + "phing/phing": "^2.16.0", + "phpstan/phpstan-deprecation-rules": "^0.11", + "phpstan/phpstan-php-parser": "^0.11", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-strict-rules": "^0.11", + "phpunit/phpunit": "^7.0", + "slevomat/coding-standard": "^4.7.2", + "squizlabs/php_codesniffer": "^3.3.2" + }, + "bin": [ + "bin/phpstan" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.11-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": [ + "src/", + "build/PHPStan" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "time": "2019-05-08T16:33:56+00:00" + }, + { + "name": "seld/jsonlint", + "version": "1.7.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "d15f59a67ff805a44c50ea0516d2341740f81a38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/d15f59a67ff805a44c50ea0516d2341740f81a38", + "reference": "d15f59a67ff805a44c50ea0516d2341740f81a38", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "time": "2018-01-24T12:46:19+00:00" + }, + { + "name": "seld/phar-utils", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/phar-utils.git", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/7009b5139491975ef6486545a39f3e6dad5ac30a", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\PharUtils\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "PHAR file format utilities, for when PHP phars you up", + "keywords": [ + "phra" + ], + "time": "2015-10-13T18:44:15+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.4.2", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", + "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2019-04-10T23:49:02+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "fd4a5f27b7cd085b489247b9890ebca9f3e10044" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/fd4a5f27b7cd085b489247b9890ebca9f3e10044", + "reference": "fd4a5f27b7cd085b489247b9890ebca9f3e10044", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "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 OptionsResolver Component", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "time": "2019-04-10T16:20:36+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.11.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "ab50dcf166d5f577978419edd37aa2bb8eabce0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/ab50dcf166d5f577978419edd37aa2bb8eabce0c", + "reference": "ab50dcf166d5f577978419edd37aa2bb8eabce0c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "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 backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2019-02-06T07:57:58+00:00" + }, + { + "name": "symfony/process", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "8cf39fb4ccff793340c258ee7760fd40bfe745fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/8cf39fb4ccff793340c258ee7760fd40bfe745fe", + "reference": "8cf39fb4ccff793340c258ee7760fd40bfe745fe", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "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 Process Component", + "homepage": "https://symfony.com", + "time": "2019-04-10T16:20:36+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v4.2.8", + "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" + } + ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], diff --git a/grumphp.yml b/grumphp.yml new file mode 100644 index 0000000..3755e34 --- /dev/null +++ b/grumphp.yml @@ -0,0 +1,4 @@ +parameters: + tasks: + phpstan: ~ + phpcsfixer: ~ diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..dd2a8c6 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,19 @@ + + + + + + + + + + + + bin/ + config/ + public/ + src/ + tests/ + + diff --git a/src/Healthcheck/PingController.php b/src/Healthcheck/PingController.php index 61f39d0..ad44329 100644 --- a/src/Healthcheck/PingController.php +++ b/src/Healthcheck/PingController.php @@ -1,4 +1,7 @@ Date: Mon, 13 May 2019 14:51:20 +0200 Subject: [PATCH 06/20] Add list response of Institutions --- config/packages/institution.yaml | 9 +++ config/routes/annotations.yaml | 7 +- src/Institution/Controller/Institution.php | 23 ++++++ src/Rest/ListResponse.php | 94 ++++++++++++++++++++++ 4 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 config/packages/institution.yaml create mode 100644 src/Institution/Controller/Institution.php create mode 100644 src/Rest/ListResponse.php diff --git a/config/packages/institution.yaml b/config/packages/institution.yaml new file mode 100644 index 0000000..0dc97d9 --- /dev/null +++ b/config/packages/institution.yaml @@ -0,0 +1,9 @@ +services: + # default configuration for services in *this* file + _defaults: + autowire: true # Automatically injects dependencies in your services. + autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. + + App\Institution\Controller\: + resource: '../../src/Institution/Controller/*' + tags: ['controller.service_arguments'] diff --git a/config/routes/annotations.yaml b/config/routes/annotations.yaml index b0a6ded..825fbcc 100644 --- a/config/routes/annotations.yaml +++ b/config/routes/annotations.yaml @@ -1,5 +1,10 @@ #TODO: Move this configuration into package level. #TODO: For example into config/packages/healthcheck.yaml -controllers: + +healthcheck: resource: ../../src/Healthcheck/ type: annotation + +institution: + resource: ../../src/Institution/Controller + type: annotation diff --git a/src/Institution/Controller/Institution.php b/src/Institution/Controller/Institution.php new file mode 100644 index 0000000..fe38d6d --- /dev/null +++ b/src/Institution/Controller/Institution.php @@ -0,0 +1,23 @@ + 'Test']], 10, 0); + return new JsonResponse($list->toArray()); + } +} diff --git a/src/Rest/ListResponse.php b/src/Rest/ListResponse.php new file mode 100644 index 0000000..672c371 --- /dev/null +++ b/src/Rest/ListResponse.php @@ -0,0 +1,94 @@ +docs = $docs; + $this->total = $total; + $this->offset = $offset; + } + + /** + * @return int + */ + public function getTotal(): int + { + return $this->total; + } + + /** + * @param int $total + */ + public function setTotal(int $total) + { + $this->total = $total; + } + + /** + * @return int + */ + public function getOffset(): int + { + return $this->offset; + } + + /** + * @param int $offset + */ + public function setOffset(int $offset) + { + $this->offset = $offset; + } + + /** + * @return array + */ + public function getDocs(): array + { + return $this->docs; + } + + /** + * @param array $docs + */ + public function setDocs(array $docs) + { + $this->docs = $docs; + } + + /** + * TODO: Replace with Transformers for specific formats + * TODO: Look at https://symfony.com/doc/current/components/serializer.html + * @return array + */ + public function toArray() : array { + return [ + 'docs' => $this->docs, + 'total' => $this->total, + 'offset' => $this->offset, + ]; + } +} \ No newline at end of file From d84ee52cdeaa7744815aa295bd8f3601a941b510 Mon Sep 17 00:00:00 2001 From: Ben Hillier Date: Tue, 14 May 2019 10:05:30 +0200 Subject: [PATCH 07/20] Add template Institution files --- config/packages/institution.yaml | 5 +++ src/Institution/Controller/Institution.php | 14 +++++- src/Institution/InMemoryRepository.php | 32 ++++++++++++++ src/Institution/Institution.php | 39 +++++++++++++++++ src/Institution/InstitutionRepository.php | 12 +++++ src/Rdf/Triple.php | 51 ++++++++++++++++++++++ 6 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 src/Institution/InMemoryRepository.php create mode 100644 src/Institution/Institution.php create mode 100644 src/Institution/InstitutionRepository.php create mode 100644 src/Rdf/Triple.php diff --git a/config/packages/institution.yaml b/config/packages/institution.yaml index 0dc97d9..c7a1d6b 100644 --- a/config/packages/institution.yaml +++ b/config/packages/institution.yaml @@ -7,3 +7,8 @@ services: App\Institution\Controller\: resource: '../../src/Institution/Controller/*' tags: ['controller.service_arguments'] + + App\Institution\InMemoryRepository: ~ + + App\Institution\InstitutionRepository: '@App\Institution\InMemoryRepository' + diff --git a/src/Institution/Controller/Institution.php b/src/Institution/Controller/Institution.php index fe38d6d..0cce331 100644 --- a/src/Institution/Controller/Institution.php +++ b/src/Institution/Controller/Institution.php @@ -4,9 +4,11 @@ namespace App\Institution\Controller; +use App\Institution\InstitutionRepository; use App\Rest\ListResponse; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; @@ -14,10 +16,18 @@ final class Institution { /** * @Route(path="/institutions", methods={"GET"}) + * @param InstitutionRepository $repository + * @return JsonResponse */ - public function institutions() : JsonResponse + public function institutions(InstitutionRepository $repository, Pagination $pagination) : JsonResponse { - $list = new ListResponse([['name' => 'Test']], 10, 0); + $institutions = $repository->all(); + $properties = []; + foreach ($institutions as $institution) { + $properties[] = $institution->properties(); + } + + $list = new ListResponse($properties, 0, count($properties)); return new JsonResponse($list->toArray()); } } diff --git a/src/Institution/InMemoryRepository.php b/src/Institution/InMemoryRepository.php new file mode 100644 index 0000000..dca8b71 --- /dev/null +++ b/src/Institution/InMemoryRepository.php @@ -0,0 +1,32 @@ +triples as $triple) { + $res[$triple->getPredicate()] = $triple->getObject(); + } + + return $res; + } + + /** + * @param Triple[] $triples + */ + public static function fromTriples(array $triples) : self + { + $obj = new self(); + $obj->triples = $triples; + + return $obj; + } +} \ No newline at end of file diff --git a/src/Institution/InstitutionRepository.php b/src/Institution/InstitutionRepository.php new file mode 100644 index 0000000..6cdd539 --- /dev/null +++ b/src/Institution/InstitutionRepository.php @@ -0,0 +1,12 @@ +subject = $subject; + $this->predicate = $predicate; + $this->object = $object; + } + + /** + * @return string + */ + public function getSubject(): string + { + return $this->subject; + } + + /** + * @return string + */ + public function getPredicate(): string + { + return $this->predicate; + } + + /** + * @return string + */ + public function getObject(): string + { + return $this->object; + } + + +} \ No newline at end of file From 6c55f268988257236d6e9502d915361353af8d38 Mon Sep 17 00:00:00 2001 From: Anton Lakotka Date: Mon, 20 May 2019 23:19:50 +0200 Subject: [PATCH 08/20] Implement architectural sketch of OpenSkos API Added basic Institution Domain object and its repository. Implemented Sparql Repository. Added Ontologies from old OpenSKOS. And many more... --- README.md | 27 + composer.json | 6 +- composer.lock | 1829 +++++++++++++++-- grumphp.yml | 9 +- phpspec.yml | 4 + psalm.xml | 53 + spec/EasyRdf/TripleFactorySpec.php | 62 + spec/EasyRdf/example.ttl | 12 + spec/Institution/InstitutionSpec.php | 38 + .../Sparql/SparqlRepositorySpec.php | 41 + spec/Rdf/SparqlQueryBuilderSpec.php | 24 + src/EasyRdf/EasyRdfClient.php | 50 + src/EasyRdf/TripleFactory.php | 63 + src/Institution/Controller/Institution.php | 28 +- src/Institution/InMemoryRepository.php | 32 - src/Institution/Institution.php | 120 +- src/Institution/InstitutionRepository.php | 23 +- src/Institution/Sparql/SparqlRepository.php | 60 + src/Kernel.php | 3 + src/Ontology/Dc.php | 31 + src/Ontology/DcTerms.php | 67 + src/Ontology/Dcmi.php | 9 + src/Ontology/Foaf.php | 28 + src/Ontology/OpenSkos.php | 47 + src/Ontology/Org.php | 26 + src/Ontology/Owl.php | 26 + src/Ontology/Rdf.php | 27 + src/Ontology/Rdfs.php | 27 + src/Ontology/Skos.php | 47 + src/Ontology/SkosXl.php | 37 + src/Ontology/VCard.php | 35 + src/Ontology/Xsd.php | 26 + src/Rdf/Client.php | 15 + src/Rdf/Exception/ClientException.php | 9 + src/Rdf/Exception/InvalidSparqlQuery.php | 23 + src/Rdf/Exception/InvalidUriException.php | 24 + src/Rdf/Iri.php | 41 + src/Rdf/Literal.php | 88 + src/Rdf/RdfTerm.php | 13 + src/Rdf/SparqlQuery.php | 31 + src/Rdf/SparqlQueryBuilder.php | 26 + src/Rdf/Triple.php | 58 +- src/Rest/ListResponse.php | 63 +- src/Rest/SkosResponse.php | 7 + symfony.lock | 75 + 45 files changed, 3063 insertions(+), 327 deletions(-) create mode 100644 phpspec.yml create mode 100644 psalm.xml create mode 100644 spec/EasyRdf/TripleFactorySpec.php create mode 100644 spec/EasyRdf/example.ttl create mode 100644 spec/Institution/InstitutionSpec.php create mode 100644 spec/Institution/Sparql/SparqlRepositorySpec.php create mode 100644 spec/Rdf/SparqlQueryBuilderSpec.php create mode 100644 src/EasyRdf/EasyRdfClient.php create mode 100644 src/EasyRdf/TripleFactory.php delete mode 100644 src/Institution/InMemoryRepository.php create mode 100644 src/Institution/Sparql/SparqlRepository.php create mode 100644 src/Ontology/Dc.php create mode 100644 src/Ontology/DcTerms.php create mode 100644 src/Ontology/Dcmi.php create mode 100644 src/Ontology/Foaf.php create mode 100644 src/Ontology/OpenSkos.php create mode 100644 src/Ontology/Org.php create mode 100644 src/Ontology/Owl.php create mode 100644 src/Ontology/Rdf.php create mode 100644 src/Ontology/Rdfs.php create mode 100644 src/Ontology/Skos.php create mode 100644 src/Ontology/SkosXl.php create mode 100644 src/Ontology/VCard.php create mode 100644 src/Ontology/Xsd.php create mode 100644 src/Rdf/Client.php create mode 100644 src/Rdf/Exception/ClientException.php create mode 100644 src/Rdf/Exception/InvalidSparqlQuery.php create mode 100644 src/Rdf/Exception/InvalidUriException.php create mode 100644 src/Rdf/Iri.php create mode 100644 src/Rdf/Literal.php create mode 100644 src/Rdf/RdfTerm.php create mode 100644 src/Rdf/SparqlQuery.php create mode 100644 src/Rdf/SparqlQueryBuilder.php create mode 100644 src/Rest/SkosResponse.php diff --git a/README.md b/README.md index 8e6d2b2..b98e836 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,33 @@ # OpenSkos-API Restful API for OpenSkos +## Development + +### Installation: + +* `composer install` +* `vendor/bin/grumphp git:init` -- grump will make sure that you have no mistakes before commit ;) + +### Tests + +Test are written using [PHPSpec](https://www.phpspec.net/en/stable/manual/introduction.html) +Run tests by: `vendor/bin/phpspec run` + +### Static analyser + +To have code strictly typed with nullability checks and etc. [Psalm](https://psalm.dev/) will help. +Run psalm by: `vendor/bin/psalm` + +### Development procedure: +* Pull latest master +* Create feature/bug branch `feature/code-and-short-title` +* Commit all needed changes +* Write documentation if needed under `doc/feature-name.md` +* Make sure you're code is covered by tests at least critical parts +* Submit PR to github. +* Wait for Approvals from dev-team and get ready for changes during PR discussion +* ...? +* Profit! ## Docker TODO diff --git a/composer.json b/composer.json index 4eca2cb..e19e577 100644 --- a/composer.json +++ b/composer.json @@ -5,11 +5,13 @@ "php": "^7.1.3", "ext-ctype": "*", "ext-iconv": "*", + "easyrdf/easyrdf": "^0.9.1", "sensio/framework-extra-bundle": "^5.3", "symfony/console": "4.2.*", "symfony/dotenv": "4.2.*", "symfony/flex": "^1.1", "symfony/framework-bundle": "4.2.*", + "symfony/serializer": "4.2.*", "symfony/yaml": "4.2.*" }, "config": { @@ -60,7 +62,9 @@ "require-dev": { "friendsofphp/php-cs-fixer": "^2.15", "phpro/grumphp": "^0.15.0", + "phpspec/phpspec": "^5.1", "phpstan/phpstan": "^0.11.6", - "squizlabs/php_codesniffer": "^3.4" + "squizlabs/php_codesniffer": "^3.4", + "vimeo/psalm": "^3.2" } } diff --git a/composer.lock b/composer.lock index be08e34..f959336 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": "d65df88e6b69e0f97a9ca81e10c34181", + "content-hash": "92e02b3fcb0d277e88ae985ee50e811e", "packages": [ { "name": "doctrine/annotations", @@ -504,6 +504,68 @@ ], "time": "2018-06-14T14:45:07+00:00" }, + { + "name": "easyrdf/easyrdf", + "version": "0.9.1", + "source": { + "type": "git", + "url": "https://github.com/njh/easyrdf.git", + "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/njh/easyrdf/zipball/acd09dfe0555fbcfa254291e433c45fdd4652566", + "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-pcre": "*", + "php": ">=5.2.8" + }, + "require-dev": { + "phpunit/phpunit": "~3.5", + "sami/sami": "~1.4", + "squizlabs/php_codesniffer": "~1.4.3" + }, + "suggest": { + "ml/json-ld": "~1.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "EasyRdf_": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nicholas Humfrey", + "email": "njh@aelius.com", + "homepage": "http://www.aelius.com/njh/", + "role": "Developer" + }, + { + "name": "Alexey Zakhlestin", + "email": "indeyets@gmail.com", + "role": "Developer" + } + ], + "description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.", + "homepage": "http://www.easyrdf.org/", + "keywords": [ + "Linked Data", + "RDF", + "Semantic Web", + "Turtle", + "rdfa", + "sparql" + ], + "time": "2015-02-27T09:45:49+00:00" + }, { "name": "psr/cache", "version": "1.0.1", @@ -1845,6 +1907,86 @@ ], "time": "2019-04-27T09:38:08+00:00" }, + { + "name": "symfony/serializer", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/serializer.git", + "reference": "543bf3d7d4be76e878dc78c82328e978d57dd44d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/serializer/zipball/543bf3d7d4be76e878dc78c82328e978d57dd44d", + "reference": "543bf3d7d4be76e878dc78c82328e978d57dd44d", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "phpdocumentor/type-resolver": "<0.2.1", + "symfony/dependency-injection": "<3.4", + "symfony/property-access": "<3.4", + "symfony/property-info": "<3.4", + "symfony/yaml": "<3.4" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "doctrine/cache": "~1.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0", + "symfony/cache": "~3.4|~4.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/http-foundation": "~3.4|~4.0", + "symfony/property-access": "~3.4|~4.0", + "symfony/property-info": "^3.4.13|~4.0", + "symfony/validator": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", + "doctrine/cache": "For using the default cached annotation reader and metadata cache.", + "psr/cache-implementation": "For using the metadata cache.", + "symfony/config": "For using the XML mapping loader.", + "symfony/http-foundation": "To use the DataUriNormalizer.", + "symfony/property-access": "For using the ObjectNormalizer.", + "symfony/property-info": "To deserialize relations.", + "symfony/yaml": "For using the default YAML mapping loader." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Serializer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Serializer Component", + "homepage": "https://symfony.com", + "time": "2019-04-28T07:09:27+00:00" + }, { "name": "symfony/var-exporter", "version": "v4.2.8", @@ -1966,6 +2108,141 @@ } ], "packages-dev": [ + { + "name": "amphp/amp", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/amp.git", + "reference": "7075ef7d74dbd32626bfd31c976b23055c3ade6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/amp/zipball/7075ef7d74dbd32626bfd31c976b23055c3ade6a", + "reference": "7075ef7d74dbd32626bfd31c976b23055c3ade6a", + "shasum": "" + }, + "require": { + "php": ">=7" + }, + "require-dev": { + "amphp/phpunit-util": "^1", + "friendsofphp/php-cs-fixer": "^2.3", + "phpstan/phpstan": "^0.8.5", + "phpunit/phpunit": "^6.0.9", + "react/promise": "^2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Amp\\": "lib" + }, + "files": [ + "lib/functions.php", + "lib/Internal/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "A non-blocking concurrency framework for PHP applications.", + "homepage": "http://amphp.org/amp", + "keywords": [ + "async", + "asynchronous", + "awaitable", + "concurrency", + "event", + "event-loop", + "future", + "non-blocking", + "promise" + ], + "time": "2018-12-11T10:31:37+00:00" + }, + { + "name": "amphp/byte-stream", + "version": "v1.5.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/byte-stream.git", + "reference": "6bbfcb6f47e92577e739586ba0c87e867be70a23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/6bbfcb6f47e92577e739586ba0c87e867be70a23", + "reference": "6bbfcb6f47e92577e739586ba0c87e867be70a23", + "shasum": "" + }, + "require": { + "amphp/amp": "^2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1", + "friendsofphp/php-cs-fixer": "^2.3", + "infection/infection": "^0.9.3", + "phpunit/phpunit": "^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\ByteStream\\": "lib" + }, + "files": [ + "lib/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "A stream abstraction to make working with non-blocking I/O simple.", + "homepage": "http://amphp.org/byte-stream", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "non-blocking", + "stream" + ], + "time": "2018-12-27T18:08:06+00:00" + }, { "name": "composer/ca-bundle", "version": "1.1.4", @@ -2269,80 +2546,41 @@ "time": "2019-01-28T20:25:53+00:00" }, { - "name": "friendsofphp/php-cs-fixer", - "version": "v2.15.0", + "name": "doctrine/instantiator", + "version": "1.2.0", "source": { "type": "git", - "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "adfab51ae979ee8b0fcbc55aa231ec2786cb1f91" + "url": "https://github.com/doctrine/instantiator.git", + "reference": "a2c590166b2133a4633738648b6b064edae0814a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/adfab51ae979ee8b0fcbc55aa231ec2786cb1f91", - "reference": "adfab51ae979ee8b0fcbc55aa231ec2786cb1f91", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", + "reference": "a2c590166b2133a4633738648b6b064edae0814a", "shasum": "" }, "require": { - "composer/semver": "^1.4", - "composer/xdebug-handler": "^1.2", - "doctrine/annotations": "^1.2", - "ext-json": "*", - "ext-tokenizer": "*", - "php": "^5.6 || ^7.0", - "php-cs-fixer/diff": "^1.3", - "symfony/console": "^3.4.17 || ^4.1.6", - "symfony/event-dispatcher": "^3.0 || ^4.0", - "symfony/filesystem": "^3.0 || ^4.0", - "symfony/finder": "^3.0 || ^4.0", - "symfony/options-resolver": "^3.0 || ^4.0", - "symfony/polyfill-php70": "^1.0", - "symfony/polyfill-php72": "^1.4", - "symfony/process": "^3.0 || ^4.0", - "symfony/stopwatch": "^3.0 || ^4.0" + "php": "^7.1" }, "require-dev": { - "johnkary/phpunit-speedtrap": "^1.1 || ^2.0 || ^3.0", - "justinrainbow/json-schema": "^5.0", - "keradus/cli-executor": "^1.2", - "mikey179/vfsstream": "^1.6", - "php-coveralls/php-coveralls": "^2.1", - "php-cs-fixer/accessible-object": "^1.0", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.1", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.1", - "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1", - "phpunitgoodpractices/traits": "^1.8", - "symfony/phpunit-bridge": "^4.0" - }, - "suggest": { - "ext-mbstring": "For handling non-UTF8 characters in cache signature.", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "For IsIdenticalString constraint.", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "For XmlMatchesXsd constraint.", - "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." + "doctrine/coding-standard": "^6.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" }, - "bin": [ - "php-cs-fixer" - ], - "type": "application", + "type": "library", "extra": { "branch-alias": { - "dev-master": "2.15-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { "psr-4": { - "PhpCsFixer\\": "src/" - }, - "classmap": [ - "tests/Test/AbstractFixerTestCase.php", - "tests/Test/AbstractIntegrationCaseFactory.php", - "tests/Test/AbstractIntegrationTestCase.php", - "tests/Test/Assert/AssertTokensTrait.php", - "tests/Test/IntegrationCase.php", - "tests/Test/IntegrationCaseFactory.php", - "tests/Test/IntegrationCaseFactoryInterface.php", - "tests/Test/InternalIntegrationCaseFactory.php", - "tests/TestCase.php" - ] + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2350,47 +2588,230 @@ ], "authors": [ { - "name": "Dariusz Rumiński", - "email": "dariusz.ruminski@gmail.com" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" } ], - "description": "A tool to automatically fix PHP code style", - "time": "2019-05-06T07:13:51+00:00" + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2019-03-17T17:37:11+00:00" }, { - "name": "gitonomy/gitlib", - "version": "v1.0.4", + "name": "felixfbecker/advanced-json-rpc", + "version": "v3.0.3", "source": { "type": "git", - "url": "https://github.com/gitonomy/gitlib.git", - "reference": "932a960221ae3484a3e82553b3be478e56beb68d" + "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", + "reference": "241c470695366e7b83672be04ea0e64d8085a551" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/gitonomy/gitlib/zipball/932a960221ae3484a3e82553b3be478e56beb68d", - "reference": "932a960221ae3484a3e82553b3be478e56beb68d", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/241c470695366e7b83672be04ea0e64d8085a551", + "reference": "241c470695366e7b83672be04ea0e64d8085a551", "shasum": "" }, "require": { - "php": "^5.3 || ^7.0", - "symfony/process": "^2.3|^3.0|^4.0" + "netresearch/jsonmapper": "^1.0", + "php": ">=7.0", + "phpdocumentor/reflection-docblock": "^4.0.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35|^5.7", - "psr/log": "^1.0" - }, - "suggest": { - "psr/log": "Add some log" + "phpunit/phpunit": "^6.0.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "A more advanced JSONRPC implementation", + "time": "2018-09-10T08:58:41+00:00" + }, + { + "name": "felixfbecker/language-server-protocol", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-language-server-protocol.git", + "reference": "1bdd1bcc95428edf85ec04c7b558d0886c07280f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/1bdd1bcc95428edf85ec04c7b558d0886c07280f", + "reference": "1bdd1bcc95428edf85ec04c7b558d0886c07280f", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpstan/phpstan": "*", + "phpunit/phpunit": "^6.3", + "squizlabs/php_codesniffer": "^3.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "LanguageServerProtocol\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "PHP classes for the Language Server Protocol", + "keywords": [ + "language", + "microsoft", + "php", + "server" + ], + "time": "2018-09-25T11:42:25+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v2.15.0", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", + "reference": "adfab51ae979ee8b0fcbc55aa231ec2786cb1f91" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/adfab51ae979ee8b0fcbc55aa231ec2786cb1f91", + "reference": "adfab51ae979ee8b0fcbc55aa231ec2786cb1f91", + "shasum": "" + }, + "require": { + "composer/semver": "^1.4", + "composer/xdebug-handler": "^1.2", + "doctrine/annotations": "^1.2", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^5.6 || ^7.0", + "php-cs-fixer/diff": "^1.3", + "symfony/console": "^3.4.17 || ^4.1.6", + "symfony/event-dispatcher": "^3.0 || ^4.0", + "symfony/filesystem": "^3.0 || ^4.0", + "symfony/finder": "^3.0 || ^4.0", + "symfony/options-resolver": "^3.0 || ^4.0", + "symfony/polyfill-php70": "^1.0", + "symfony/polyfill-php72": "^1.4", + "symfony/process": "^3.0 || ^4.0", + "symfony/stopwatch": "^3.0 || ^4.0" + }, + "require-dev": { + "johnkary/phpunit-speedtrap": "^1.1 || ^2.0 || ^3.0", + "justinrainbow/json-schema": "^5.0", + "keradus/cli-executor": "^1.2", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.1", + "php-cs-fixer/accessible-object": "^1.0", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.1", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.1", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1", + "phpunitgoodpractices/traits": "^1.8", + "symfony/phpunit-bridge": "^4.0" + }, + "suggest": { + "ext-mbstring": "For handling non-UTF8 characters in cache signature.", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "For IsIdenticalString constraint.", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "For XmlMatchesXsd constraint.", + "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "extra": { + "branch-alias": { + "dev-master": "2.15-dev" + } + }, + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "classmap": [ + "tests/Test/AbstractFixerTestCase.php", + "tests/Test/AbstractIntegrationCaseFactory.php", + "tests/Test/AbstractIntegrationTestCase.php", + "tests/Test/Assert/AssertTokensTrait.php", + "tests/Test/IntegrationCase.php", + "tests/Test/IntegrationCaseFactory.php", + "tests/Test/IntegrationCaseFactoryInterface.php", + "tests/Test/InternalIntegrationCaseFactory.php", + "tests/TestCase.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "time": "2019-05-06T07:13:51+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": { @@ -2612,6 +3033,104 @@ ], "time": "2018-11-05T09:00:11+00:00" }, + { + "name": "muglug/package-versions-56", + "version": "1.2.4", + "source": { + "type": "git", + "url": "https://github.com/muglug/PackageVersions.git", + "reference": "a67bed26deaaf9269a348e53063bc8d4dcc60ffd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/muglug/PackageVersions/zipball/a67bed26deaaf9269a348e53063bc8d4dcc60ffd", + "reference": "a67bed26deaaf9269a348e53063bc8d4dcc60ffd", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "composer/composer": "^1.3", + "ext-zip": "*", + "phpunit/phpunit": "^5.7.5" + }, + "type": "composer-plugin", + "extra": { + "class": "Muglug\\PackageVersions\\Installer", + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Muglug\\PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + }, + { + "name": "Abdul Malik Ikhsan", + "email": "samsonasik@gmail.com" + }, + { + "name": "Matt Brown", + "email": "github@muglug.com" + } + ], + "description": "A backport of ocramius/package-versions that supports php ^5.6. Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "time": "2018-03-26T03:22:13+00:00" + }, + { + "name": "netresearch/jsonmapper", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "3868fe1128ce1169228acdb623359dca74db5ef3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/3868fe1128ce1169228acdb623359dca74db5ef3", + "reference": "3868fe1128ce1169228acdb623359dca74db5ef3", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "~4.8.35 || ~5.7 || ~6.4", + "squizlabs/php_codesniffer": "~1.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonMapper": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@cweiske.de", + "homepage": "http://github.com/cweiske/jsonmapper/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "time": "2017-11-28T21:30:01+00:00" + }, { "name": "nette/bootstrap", "version": "v3.0.0", @@ -3237,68 +3756,330 @@ "time": "2019-02-21T12:16:21+00:00" }, { - "name": "php-cs-fixer/diff", - "version": "v1.3.0", + "name": "openlss/lib-array2xml", + "version": "0.5.1", "source": { "type": "git", - "url": "https://github.com/PHP-CS-Fixer/diff.git", - "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756" + "url": "https://github.com/nullivex/lib-array2xml.git", + "reference": "c8b5998a342d7861f2e921403f44e0a2f3ef2be0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/78bb099e9c16361126c86ce82ec4405ebab8e756", - "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756", + "url": "https://api.github.com/repos/nullivex/lib-array2xml/zipball/c8b5998a342d7861f2e921403f44e0a2f3ef2be0", + "reference": "c8b5998a342d7861f2e921403f44e0a2f3ef2be0", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7.23 || ^6.4.3", - "symfony/process": "^3.3" + "php": ">=5.3.2" }, "type": "library", "autoload": { - "classmap": [ - "src/" - ] + "psr-0": { + "LSS": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "Apache-2.0" ], "authors": [ { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Bryan Tong", + "email": "contact@nullivex.com", + "homepage": "http://bryantong.com" }, { - "name": "SpacePossum" + "name": "Tony Butler", + "email": "spudz76@gmail.com", + "homepage": "http://openlss.org" } ], - "description": "sebastian/diff v2 backport support for PHP5.6", + "description": "Array2XML conversion library credit to lalit.org", + "homepage": "http://openlss.org", + "keywords": [ + "array", + "array conversion", + "xml", + "xml conversion" + ], + "time": "2016-11-10T19:10:18+00:00" + }, + { + "name": "php-cs-fixer/diff", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/diff.git", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/78bb099e9c16361126c86ce82ec4405ebab8e756", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "symfony/process": "^3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "SpacePossum" + } + ], + "description": "sebastian/diff v2 backport support for PHP5.6", "homepage": "https://github.com/PHP-CS-Fixer", "keywords": [ "diff" ], "time": "2018-02-15T16:58:55+00:00" }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2017-09-11T18:02:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "4.3.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", + "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", + "shasum": "" + }, + "require": { + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2019-04-30T17:48:53+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpmyadmin/sql-parser", + "version": "v4.3.1", + "source": { + "type": "git", + "url": "https://github.com/phpmyadmin/sql-parser.git", + "reference": "0eb16ef5e3acacbc792be336754e42d98791a33f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/0eb16ef5e3acacbc792be336754e42d98791a33f", + "reference": "0eb16ef5e3acacbc792be336754e42d98791a33f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "symfony/polyfill-mbstring": "^1.3" + }, + "conflict": { + "phpmyadmin/motranslator": "<3.0" + }, + "require-dev": { + "phpunit/php-code-coverage": "*", + "phpunit/phpunit": "~4.8 || ~5.7 || ~6.5", + "sami/sami": "^4.0" + }, + "suggest": { + "ext-mbstring": "For best performance", + "phpmyadmin/motranslator": "Translate messages to your favorite locale" + }, + "bin": [ + "bin/highlight-query", + "bin/lint-query" + ], + "type": "library", + "autoload": { + "psr-4": { + "PhpMyAdmin\\SqlParser\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "The phpMyAdmin Team", + "email": "developers@phpmyadmin.net", + "homepage": "https://www.phpmyadmin.net/team/" + } + ], + "description": "A validating SQL lexer and parser with a focus on MySQL dialect.", + "homepage": "https://github.com/phpmyadmin/sql-parser", + "keywords": [ + "analysis", + "lexer", + "parser", + "sql" + ], + "time": "2019-01-05T13:46:38+00:00" + }, { "name": "phpro/grumphp", - "version": "v0.15.0", + "version": "v0.15.2", "source": { "type": "git", "url": "https://github.com/phpro/grumphp.git", - "reference": "5a6fd0ab90c9f837a7c79a5f61ef1b33f1ace8c1" + "reference": "c153840bead6fbed370d35cc84c63dca33de0ca4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpro/grumphp/zipball/5a6fd0ab90c9f837a7c79a5f61ef1b33f1ace8c1", - "reference": "5a6fd0ab90c9f837a7c79a5f61ef1b33f1ace8c1", + "url": "https://api.github.com/repos/phpro/grumphp/zipball/c153840bead6fbed370d35cc84c63dca33de0ca4", + "reference": "c153840bead6fbed370d35cc84c63dca33de0ca4", "shasum": "" }, "require": { @@ -3309,15 +4090,15 @@ "monolog/monolog": "~1.16", "php": ">=7.0", "seld/jsonlint": "~1.1", - "symfony/config": "~3.0|~4.0", - "symfony/console": "~3.0|~4.0", - "symfony/dependency-injection": "~3.0|~4.0", - "symfony/event-dispatcher": "~3.0|~4.0", - "symfony/filesystem": "~3.0|~4.0", - "symfony/finder": "~3.0|~4.0", - "symfony/options-resolver": "~3.0|~4.0", - "symfony/process": "~3.2|~4.0", - "symfony/yaml": "~3.0|~4.0" + "symfony/config": "~3.4|~4.0", + "symfony/console": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/filesystem": "~3.4|~4.0", + "symfony/finder": "~3.4|~4.0", + "symfony/options-resolver": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "~2", @@ -3329,12 +4110,14 @@ "sebastian/comparator": "^2.1", "sebastian/diff": "^2.0", "sebastian/exporter": "^3.1", - "sensiolabs/security-checker": "^4.0", - "squizlabs/php_codesniffer": "~2.4" + "sensiolabs/security-checker": "^5.0", + "squizlabs/php_codesniffer": "~2.9" }, "suggest": { + "allocine/twigcs": "Lets GrumPHP check Twig coding standard.", "atoum/atoum": "Lets GrumPHP run your unit tests.", "behat/behat": "Lets GrumPHP validate your project features.", + "brianium/paratest": "Lets GrumPHP run PHPUnit in parallel.", "codeception/codeception": "Lets GrumPHP run your project's full stack tests", "codegyre/robo": "Lets GrumPHP run your automated PHP tasks.", "designsecurity/progpilot": "Lets GrumPHP be sure that there are no vulnerabilities in your code.", @@ -3342,6 +4125,7 @@ "friendsofphp/php-cs-fixer": "Lets GrumPHP automatically fix your codestyle.", "infection/infection": "Lets GrumPHP evaluate the quality your unit tests", "jakub-onderka/php-parallel-lint": "Lets GrumPHP quickly lint your entire code base.", + "localheinz/composer-normalize": "Lets GrumPHP tidy and normalize your composer.json file.", "maglnet/composer-require-checker": "Lets GrumPHP analyze composer dependencies.", "malukenho/kawaii-gherkin": "Lets GrumPHP lint your Gherkin files.", "nikic/php-parser": "Lets GrumPHP run static analyses through your PHP files.", @@ -3358,6 +4142,7 @@ "squizlabs/php_codesniffer": "Lets GrumPHP sniff on your code.", "sstalle/php7cc": "Lets GrumPHP check PHP 5.3 - 5.6 code compatibility with PHP 7.", "symfony/phpunit-bridge": "Lets GrumPHP run your unit tests with the phpunit-bridge of Symfony.", + "symplify/easycodingstandard": "Lets GrumPHP check coding standard.", "vimeo/psalm": "Lets GrumPHP discover errors in your code without running it." }, "bin": [ @@ -3382,132 +4167,554 @@ "email": "toon.verwerft@phpro.be" }, { - "name": "Community", - "homepage": "https://github.com/phpro/grumphp/graphs/contributors" + "name": "Community", + "homepage": "https://github.com/phpro/grumphp/graphs/contributors" + } + ], + "description": "A composer plugin that enables source code quality checks.", + "time": "2019-05-17T11:56:59+00:00" + }, + { + "name": "phpspec/php-diff", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/php-diff.git", + "reference": "0464787bfa7cd13576c5a1e318709768798bec6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/php-diff/zipball/0464787bfa7cd13576c5a1e318709768798bec6a", + "reference": "0464787bfa7cd13576c5a1e318709768798bec6a", + "shasum": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Diff": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Chris Boulton", + "homepage": "http://github.com/chrisboulton" + } + ], + "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).", + "time": "2016-04-07T12:29:16+00:00" + }, + { + "name": "phpspec/phpspec", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/phpspec.git", + "reference": "4badea737c34a6c8e2921fca0f6a1cbe4f724f2f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/phpspec/zipball/4badea737c34a6c8e2921fca0f6a1cbe4f724f2f", + "reference": "4badea737c34a6c8e2921fca0f6a1cbe4f724f2f", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.5", + "ext-tokenizer": "*", + "php": "^7.1, <7.4", + "phpspec/php-diff": "^1.0.0", + "phpspec/prophecy": "^1.7", + "sebastian/exporter": "^1.0 || ^2.0 || ^3.0", + "symfony/console": "^3.4 || ^4.0", + "symfony/event-dispatcher": "^3.4 || ^4.0", + "symfony/finder": "^3.4 || ^4.0", + "symfony/process": "^3.4 || ^4.0", + "symfony/yaml": "^3.4 || ^4.0" + }, + "require-dev": { + "behat/behat": "^3.3", + "phpunit/phpunit": "^5.7 || ^6.0", + "symfony/filesystem": "^3.4 || ^4.0" + }, + "suggest": { + "phpspec/nyan-formatters": "Adds Nyan formatters" + }, + "bin": [ + "bin/phpspec" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1.x-dev" + } + }, + "autoload": { + "psr-0": { + "PhpSpec": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "homepage": "http://marcelloduarte.net/" + }, + { + "name": "Ciaran McNulty", + "homepage": "https://ciaranmcnulty.com/" + } + ], + "description": "Specification-oriented BDD framework for PHP 5.6+", + "homepage": "http://phpspec.net/", + "keywords": [ + "BDD", + "SpecBDD", + "TDD", + "spec", + "specification", + "testing", + "tests" + ], + "time": "2018-10-29T08:12:52+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2018-08-05T17:53:17+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "0.3.3", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "472d3161d289f652713a5e353532fa4592663a57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/472d3161d289f652713a5e353532fa4592663a57", + "reference": "472d3161d289f652713a5e353532fa4592663a57", + "shasum": "" + }, + "require": { + "php": "~7.1" + }, + "require-dev": { + "consistence/coding-standard": "^3.5", + "jakub-onderka/php-parallel-lint": "^0.9.2", + "phing/phing": "^2.16.0", + "phpstan/phpstan": "^0.10", + "phpunit/phpunit": "^6.3", + "slevomat/coding-standard": "^4.7.2", + "squizlabs/php_codesniffer": "^3.3.2", + "symfony/process": "^3.4 || ^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.3-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "time": "2019-04-23T20:26:19+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "0.11.6", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "7af8b9d02b3ab36444dbf4e1b9ca1c1bd5044d81" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7af8b9d02b3ab36444dbf4e1b9ca1c1bd5044d81", + "reference": "7af8b9d02b3ab36444dbf4e1b9ca1c1bd5044d81", + "shasum": "" + }, + "require": { + "composer/xdebug-handler": "^1.3.0", + "jean85/pretty-package-versions": "^1.0.3", + "nette/bootstrap": "^2.4 || ^3.0", + "nette/di": "^2.4.7 || ^3.0", + "nette/robot-loader": "^3.0.1", + "nette/utils": "^2.4.5 || ^3.0", + "nikic/php-parser": "^4.0.2", + "php": "~7.1", + "phpstan/phpdoc-parser": "^0.3", + "symfony/console": "~3.2 || ~4.0", + "symfony/finder": "~3.2 || ~4.0" + }, + "conflict": { + "symfony/console": "3.4.16 || 4.1.5" + }, + "require-dev": { + "brianium/paratest": "^2.0", + "consistence/coding-standard": "^3.5", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "ext-intl": "*", + "ext-mysqli": "*", + "ext-soap": "*", + "ext-zip": "*", + "jakub-onderka/php-parallel-lint": "^1.0", + "localheinz/composer-normalize": "^1.1.0", + "phing/phing": "^2.16.0", + "phpstan/phpstan-deprecation-rules": "^0.11", + "phpstan/phpstan-php-parser": "^0.11", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-strict-rules": "^0.11", + "phpunit/phpunit": "^7.0", + "slevomat/coding-standard": "^4.7.2", + "squizlabs/php_codesniffer": "^3.3.2" + }, + "bin": [ + "bin/phpstan" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.11-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": [ + "src/", + "build/PHPStan" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "time": "2019-05-08T16:33:56+00:00" + }, + { + "name": "sebastian/comparator", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "shasum": "" + }, + "require": { + "php": "^7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2018-07-12T15:12:46+00:00" + }, + { + "name": "sebastian/diff", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8.0", + "symfony/process": "^2 || ^3.3 || ^4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "A composer plugin that enables source code quality checks.", - "time": "2019-02-22T06:02:18+00:00" + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "time": "2019-02-04T06:01:07+00:00" }, { - "name": "phpstan/phpdoc-parser", - "version": "0.3.3", + "name": "sebastian/exporter", + "version": "3.1.0", "source": { "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "472d3161d289f652713a5e353532fa4592663a57" + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/472d3161d289f652713a5e353532fa4592663a57", - "reference": "472d3161d289f652713a5e353532fa4592663a57", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", "shasum": "" }, "require": { - "php": "~7.1" + "php": "^7.0", + "sebastian/recursion-context": "^3.0" }, "require-dev": { - "consistence/coding-standard": "^3.5", - "jakub-onderka/php-parallel-lint": "^0.9.2", - "phing/phing": "^2.16.0", - "phpstan/phpstan": "^0.10", - "phpunit/phpunit": "^6.3", - "slevomat/coding-standard": "^4.7.2", - "squizlabs/php_codesniffer": "^3.3.2", - "symfony/process": "^3.4 || ^4.0" + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "0.3-dev" + "dev-master": "3.1.x-dev" } }, "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "time": "2019-04-23T20:26:19+00:00" + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2017-04-03T13:19:02+00:00" }, { - "name": "phpstan/phpstan", - "version": "0.11.6", + "name": "sebastian/recursion-context", + "version": "3.0.0", "source": { "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "7af8b9d02b3ab36444dbf4e1b9ca1c1bd5044d81" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7af8b9d02b3ab36444dbf4e1b9ca1c1bd5044d81", - "reference": "7af8b9d02b3ab36444dbf4e1b9ca1c1bd5044d81", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", "shasum": "" }, "require": { - "composer/xdebug-handler": "^1.3.0", - "jean85/pretty-package-versions": "^1.0.3", - "nette/bootstrap": "^2.4 || ^3.0", - "nette/di": "^2.4.7 || ^3.0", - "nette/robot-loader": "^3.0.1", - "nette/utils": "^2.4.5 || ^3.0", - "nikic/php-parser": "^4.0.2", - "php": "~7.1", - "phpstan/phpdoc-parser": "^0.3", - "symfony/console": "~3.2 || ~4.0", - "symfony/finder": "~3.2 || ~4.0" - }, - "conflict": { - "symfony/console": "3.4.16 || 4.1.5" + "php": "^7.0" }, "require-dev": { - "brianium/paratest": "^2.0", - "consistence/coding-standard": "^3.5", - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", - "ext-intl": "*", - "ext-mysqli": "*", - "ext-soap": "*", - "ext-zip": "*", - "jakub-onderka/php-parallel-lint": "^1.0", - "localheinz/composer-normalize": "^1.1.0", - "phing/phing": "^2.16.0", - "phpstan/phpstan-deprecation-rules": "^0.11", - "phpstan/phpstan-php-parser": "^0.11", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-strict-rules": "^0.11", - "phpunit/phpunit": "^7.0", - "slevomat/coding-standard": "^4.7.2", - "squizlabs/php_codesniffer": "^3.3.2" + "phpunit/phpunit": "^6.0" }, - "bin": [ - "bin/phpstan" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "0.11-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { - "psr-4": { - "PHPStan\\": [ - "src/", - "build/PHPStan" - ] - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], - "description": "PHPStan - PHP Static Analysis Tool", - "time": "2019-05-08T16:33:56+00:00" + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2017-03-03T06:23:57+00:00" }, { "name": "seld/jsonlint", @@ -3860,6 +5067,230 @@ "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", "time": "2019-01-16T20:31:39+00:00" + }, + { + "name": "vimeo/psalm", + "version": "3.2.12", + "source": { + "type": "git", + "url": "https://github.com/vimeo/psalm.git", + "reference": "fe0f352132f798512ced19faf75cbfc84e4aabe7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/fe0f352132f798512ced19faf75cbfc84e4aabe7", + "reference": "fe0f352132f798512ced19faf75cbfc84e4aabe7", + "shasum": "" + }, + "require": { + "amphp/amp": "^2.1", + "amphp/byte-stream": "^1.5", + "composer/xdebug-handler": "^1.1", + "felixfbecker/advanced-json-rpc": "^3.0.3", + "felixfbecker/language-server-protocol": "^1.2", + "muglug/package-versions-56": "1.2.4", + "netresearch/jsonmapper": "^1.0", + "nikic/php-parser": "^4.0.2 || ^4.1", + "openlss/lib-array2xml": "^0.0.10||^0.5.1", + "php": "^7.0", + "php-cs-fixer/diff": "^1.2", + "phpmyadmin/sql-parser": "^4.0", + "symfony/console": "^3.3||^4.0", + "webmozart/glob": "^4.1", + "webmozart/path-util": "^2.3" + }, + "provide": { + "psalm/psalm": "self.version" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2", + "phpunit/phpunit": "^6.0 || ^7.0", + "psalm/plugin-phpunit": "^0.5.5", + "squizlabs/php_codesniffer": "3.4.0" + }, + "suggest": { + "ext-igbinary": "^2.0.5" + }, + "bin": [ + "psalm", + "psalter", + "psalm-language-server", + "psalm-plugin" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev", + "dev-2.x": "2.x-dev", + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psalm\\Plugin\\": "src/Psalm/Plugin", + "Psalm\\": "src/Psalm" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthew Brown" + } + ], + "description": "A static analysis tool for finding errors in PHP applications", + "keywords": [ + "code", + "inspection", + "php" + ], + "time": "2019-05-13T15:00:17+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9", + "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2018-12-25T11:19:39+00:00" + }, + { + "name": "webmozart/glob", + "version": "4.1.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/glob.git", + "reference": "3cbf63d4973cf9d780b93d2da8eec7e4a9e63bbe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/glob/zipball/3cbf63d4973cf9d780b93d2da8eec7e4a9e63bbe", + "reference": "3cbf63d4973cf9d780b93d2da8eec7e4a9e63bbe", + "shasum": "" + }, + "require": { + "php": "^5.3.3|^7.0", + "webmozart/path-util": "^2.2" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1", + "symfony/filesystem": "^2.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Glob\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "A PHP implementation of Ant's glob.", + "time": "2015-12-29T11:14:33+00:00" + }, + { + "name": "webmozart/path-util", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/path-util.git", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "webmozart/assert": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\PathUtil\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", + "time": "2015-12-17T08:42:14+00:00" } ], "aliases": [], diff --git a/grumphp.yml b/grumphp.yml index 3755e34..b18e896 100644 --- a/grumphp.yml +++ b/grumphp.yml @@ -1,4 +1,11 @@ parameters: + git_dir: . + bin_dir: vendor/bin tasks: - phpstan: ~ phpcsfixer: ~ + psalm: + ignore_patterns: + - '/spec/' #Ignore PHPSpec + phpspec: ~ + + diff --git a/phpspec.yml b/phpspec.yml new file mode 100644 index 0000000..093932b --- /dev/null +++ b/phpspec.yml @@ -0,0 +1,4 @@ +suites: + default: + namespace: App + psr4_prefix: App \ No newline at end of file diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..c94bb67 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spec/EasyRdf/TripleFactorySpec.php b/spec/EasyRdf/TripleFactorySpec.php new file mode 100644 index 0000000..e587854 --- /dev/null +++ b/spec/EasyRdf/TripleFactorySpec.php @@ -0,0 +1,62 @@ +parse($graphString, 'turtle'); + + $this::triplesFromGraph($graph)->shouldBeTriples([ + new Triple( + new Iri('http://memorix.io/skos/#russian'), + new Iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), + new Iri('http://www.w3.org/2004/02/skos/core#Concept') + ), + new Triple( + new Iri('http://memorix.io/skos/#russian'), + new Iri('http://www.w3.org/2004/02/skos/core#prefLabel'), + new Literal('Russian') + ), + new Triple( + new Iri('http://memorix.io/skos/#dutch'), + new Iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), + new Iri('http://www.w3.org/2004/02/skos/core#Concept') + ), + new Triple( + new Iri('http://memorix.io/skos/#dutch'), + new Iri('http://www.w3.org/2004/02/skos/core#prefLabel'), + new Literal('Dutch') + ), + ]); + } + + public function getMatchers(): array + { + return [ + 'beTriples' => function (array $actual, array $expected) { + foreach ($actual as $i => $triple) { + $expTriple = (string) ($expected[$i] ?? ''); + if ((string) $triple !== $expTriple) { + throw new FailureException(sprintf( + "Expected triple\n\t%s\nat index #%d but got\n\t%s", + $expTriple, $i, $triple + )); + } + } + + return true; + }, + ]; + } +} diff --git a/spec/EasyRdf/example.ttl b/spec/EasyRdf/example.ttl new file mode 100644 index 0000000..bb0f6f3 --- /dev/null +++ b/spec/EasyRdf/example.ttl @@ -0,0 +1,12 @@ +@base . +@prefix rdf: . +@prefix rdfs: . +@prefix skos: . + +<#russian> + a skos:Concept ; + skos:prefLabel "Russian"@en . + +<#dutch> + a skos:Concept ; + skos:prefLabel "Dutch"@en . \ No newline at end of file diff --git a/spec/Institution/InstitutionSpec.php b/spec/Institution/InstitutionSpec.php new file mode 100644 index 0000000..74f1050 --- /dev/null +++ b/spec/Institution/InstitutionSpec.php @@ -0,0 +1,38 @@ +beConstructedThrough('fromTriples', [$subjA, $triples]); + + $this->getSubject()->shouldBe($subjA); + $this->getCode()->__toString()->shouldBe('test'); + $this->getWebsite()->shouldBeNull(); + + $instB = $this::fromTriples($subjB, $triples); + $instB->getSubject()->shouldBe($subjB); + $instB->getWebsite()->__toString()->shouldBe('http://picturae.com'); + } +} diff --git a/spec/Institution/Sparql/SparqlRepositorySpec.php b/spec/Institution/Sparql/SparqlRepositorySpec.php new file mode 100644 index 0000000..df07284 --- /dev/null +++ b/spec/Institution/Sparql/SparqlRepositorySpec.php @@ -0,0 +1,41 @@ +beConstructedWith($rdfClient); + } + + public function it_returns_all_insitution_from_sparql(Client $rdfClient) + { + $instA = new Iri('http://test/a'); + $instB = new Iri('http://test/b'); + + $rdfClient->describe(Argument::any())->willReturn([ + new Triple($instA, new Iri(Rdf::TYPE), new Iri(Skos::CONCEPT)), + new Triple($instB, new Iri(Rdf::TYPE), new Iri(Skos::CONCEPT)), + new Triple($instA, new Iri(OpenSkos::CODE), new Literal('pic')), + new Triple($instB, new Iri(OpenSkos::CODE), new Literal('test')), + new Triple($instA, new Iri(OpenSkos::WEBPAGE), new Literal('http://picturae.com')), + ]); + + $res = $this->all(); + $res->shouldHaveCount(2); + $res[0]->getCode()->getValue()->shouldBe('pic'); + + //TODO: Find a good matcher + } +} diff --git a/spec/Rdf/SparqlQueryBuilderSpec.php b/spec/Rdf/SparqlQueryBuilderSpec.php new file mode 100644 index 0000000..02abf7c --- /dev/null +++ b/spec/Rdf/SparqlQueryBuilderSpec.php @@ -0,0 +1,24 @@ +rawSparql()->shouldBe( + 'DESCRIBE ?x WHERE ' + .'{ ?x } ' + .'LIMIT 100 OFFSET 200' + ); + } +} diff --git a/src/EasyRdf/EasyRdfClient.php b/src/EasyRdf/EasyRdfClient.php new file mode 100644 index 0000000..d8c079a --- /dev/null +++ b/src/EasyRdf/EasyRdfClient.php @@ -0,0 +1,50 @@ +easyRdfClient = $easyRdfClient; + } + + /** + * @param SparqlQuery $query + * + * @return Triple[] + */ + public function describe(SparqlQuery $query): array + { + $graph = $this->easyRdfClient->query($query->rawSparql()); + + if (!$graph instanceof EasyRdf_Graph) { + // TODO: Add to SparqlQuery object isDescribe() method for such checks. + throw InvalidSparqlQuery::causedBy($query, 'Is not a DESCRIBE query'); + } + + return TripleFactory::triplesFromGraph($graph); + } + +// public function replace($uri, $data) +// { +// $query = 'DELETE WHERE {<' . $uri . '> ?predicate ?object};'; +// $query .= PHP_EOL; +// $query .= 'INSERT DATA {' . $this->convertToTriples($data) . '}'; +// +// $this->update($query); +// } +} diff --git a/src/EasyRdf/TripleFactory.php b/src/EasyRdf/TripleFactory.php new file mode 100644 index 0000000..59c42a3 --- /dev/null +++ b/src/EasyRdf/TripleFactory.php @@ -0,0 +1,63 @@ +toRdfPhp(); + + $res = []; + foreach ($resources as $subject => $predicates) { + $subjectIri = new Iri($subject); + foreach ($predicates as $predicate => $objects) { + $predicateIri = new Iri($predicate); + foreach ($objects as $object) { + $rdfTerm = self::arrayToRdfTerm($object); + if (null === $rdfTerm) { + // TODO: Throw an exception? + continue; + } + $res[] = new Triple($subjectIri, $predicateIri, $rdfTerm); + } + } + } + + return $res; + } +} diff --git a/src/Institution/Controller/Institution.php b/src/Institution/Controller/Institution.php index 0cce331..195a9f3 100644 --- a/src/Institution/Controller/Institution.php +++ b/src/Institution/Controller/Institution.php @@ -6,28 +6,38 @@ use App\Institution\InstitutionRepository; use App\Rest\ListResponse; -use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Serializer\SerializerInterface; final class Institution { + /** + * @var SerializerInterface + */ + private $serializer; + + public function __construct( + SerializerInterface $serializer + ) { + $this->serializer = $serializer; + } + /** * @Route(path="/institutions", methods={"GET"}) + * * @param InstitutionRepository $repository + * * @return JsonResponse */ - public function institutions(InstitutionRepository $repository, Pagination $pagination) : JsonResponse + public function institutions(InstitutionRepository $repository): JsonResponse { $institutions = $repository->all(); - $properties = []; - foreach ($institutions as $institution) { - $properties[] = $institution->properties(); - } + $list = new ListResponse($institutions, 0, count($institutions)); + + $res = $this->serializer->serialize($list, 'json'); - $list = new ListResponse($properties, 0, count($properties)); - return new JsonResponse($list->toArray()); + return new JsonResponse($res, Response::HTTP_OK, [], true); } } diff --git a/src/Institution/InMemoryRepository.php b/src/Institution/InMemoryRepository.php deleted file mode 100644 index dca8b71..0000000 --- a/src/Institution/InMemoryRepository.php +++ /dev/null @@ -1,32 +0,0 @@ - OpenSkos::CODE, + self::name => OpenSkos::NAME, + self::organisationUnit => VCard::ORGUNIT, + self::email => VCard::EMAIL, + self::website => OpenSkos::WEBPAGE, + self::streetAddress => VCard::ADR, + self::locality => VCard::LOCALITY, + self::postalCode => VCard::PCODE, + self::countryName => VCard::COUNTRY, + self::enableStatusesSystem => OpenSkos::ENABLESTATUSSESSYSTEMS, + self::enableSkosXl => OpenSkos::ENABLESKOSXL, + ]; - private function __construct() {} + /** + * @var Iri + */ + private $subject; /** - * @return string[] + * @var Literal[] */ - public function properties() : array + private $literals = []; + + public function __construct(Iri $subject) { - $res = []; - foreach ($this->triples as $triple) { - $res[$triple->getPredicate()] = $triple->getObject(); - } + $this->subject = $subject; + } + + //TODO: Generate getters. - return $res; + /** + * @return Iri + */ + public function getSubject(): Iri + { + return $this->subject; } /** + * @return Literal|null + */ + public function getCode(): ?Literal + { + return $this->literals[self::code] ?? null; + } + + /** + * @return Literal|null + */ + public function getWebsite(): ?Literal + { + return $this->literals[self::website] ?? null; + } + + /** + * @param Iri $subject * @param Triple[] $triples + * + * @return Institution */ - public static function fromTriples(array $triples) : self + public static function fromTriples(Iri $subject, array $triples): Institution { - $obj = new self(); - $obj->triples = $triples; + $invMapping = array_flip(self::$mapping); + $literals = []; + foreach ($triples as $triple) { + // Skip unrelated triples + if ($triple->getSubject()->getUri() !== $subject->getUri()) { + continue; + } + + $property = $invMapping[$triple->getPredicate()->getUri()] ?? null; + // Skip unknown properties + if (null === $property) { + continue; + } + + $object = $triple->getObject(); + // Skip non-literals. TODO: throw an exception? + if (!$object instanceof Literal) { + continue; + } + $literals[$property] = $object; + + /* TODO: Add Resource when needed + if (!$object instanceof Iri) { + continue; + } + $resources[$property] = $object; + */ + } + + $obj = new self($subject); + $obj->literals = $literals; return $obj; } -} \ No newline at end of file +} diff --git a/src/Institution/InstitutionRepository.php b/src/Institution/InstitutionRepository.php index 6cdd539..275b3e2 100644 --- a/src/Institution/InstitutionRepository.php +++ b/src/Institution/InstitutionRepository.php @@ -1,12 +1,25 @@ -rdfClient = $rdfClient; + } + + /** + * @param int $offset + * @param int $limit + * + * @return Institution[] + */ + public function all(int $offset = 0, int $limit = 100): array + { + $sparql = SparqlQueryBuilder::describeAllOfType( + new Iri(Org::FORMALORG), + $offset, + $limit + ); + $triples = $this->rdfClient->describe($sparql); + + //TODO: Move to separate helper class? + $groups = []; + foreach ($triples as $triple) { + $groups[$triple->getSubject()->getUri()][] = $triple; + } + + $res = []; + foreach ($groups as $iriString => $group) { + $res[] = Institution::fromTriples(new Iri($iriString), $group); + } + + return $res; + } + + public function find(Iri $iri): ?Institution + { + throw new \RuntimeException('Not implemented'); + } +} diff --git a/src/Kernel.php b/src/Kernel.php index 785b0be..a05ddf8 100644 --- a/src/Kernel.php +++ b/src/Kernel.php @@ -17,6 +17,9 @@ class Kernel extends BaseKernel public function registerBundles(): iterable { + /** + * @psalm-suppress UnresolvableInclude + */ $contents = require $this->getProjectDir().'/config/bundles.php'; foreach ($contents as $class => $envs) { if ($envs[$this->environment] ?? $envs['all'] ?? false) { diff --git a/src/Ontology/Dc.php b/src/Ontology/Dc.php new file mode 100644 index 0000000..d388100 --- /dev/null +++ b/src/Ontology/Dc.php @@ -0,0 +1,31 @@ +query = $query; + + return $obj; + } +} diff --git a/src/Rdf/Exception/InvalidUriException.php b/src/Rdf/Exception/InvalidUriException.php new file mode 100644 index 0000000..4ff6aff --- /dev/null +++ b/src/Rdf/Exception/InvalidUriException.php @@ -0,0 +1,24 @@ +uri = $value; + } + + /** + * Output the uri as string. + * + * @return string + */ + public function __toString(): string + { + return $this->uri; + } + + /** + * @return string + */ + public function getUri(): string + { + return $this->uri; + } +} diff --git a/src/Rdf/Literal.php b/src/Rdf/Literal.php new file mode 100644 index 0000000..eb2f30f --- /dev/null +++ b/src/Rdf/Literal.php @@ -0,0 +1,88 @@ +value = $value; + $this->language = $language; + $this->type = $type; + } + + /** + * @return string + */ + public function getLanguage() + { + return $this->language; + } + + /** + * @return string + */ + public function getValue() + { + return $this->value; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * @param string $type + * + * @return self + */ + public function setType($type) + { + $this->type = $type; + + return $this; + } + + /** + * Output the literal as string. + * + * @return string + */ + public function __toString() + { + return $this->value; + } +} diff --git a/src/Rdf/RdfTerm.php b/src/Rdf/RdfTerm.php new file mode 100644 index 0000000..2462139 --- /dev/null +++ b/src/Rdf/RdfTerm.php @@ -0,0 +1,13 @@ +sparql = $sparql; + $this->variables = $variables; + } + + public function rawSparql(): string + { + //TODO: replace variables? + return $this->sparql; + } +} diff --git a/src/Rdf/SparqlQueryBuilder.php b/src/Rdf/SparqlQueryBuilder.php new file mode 100644 index 0000000..9b81859 --- /dev/null +++ b/src/Rdf/SparqlQueryBuilder.php @@ -0,0 +1,26 @@ + <%s> } LIMIT %d OFFSET %d', + Rdf::TYPE, + $type, + $limit, + $offset + ) + ); + } +} diff --git a/src/Rdf/Triple.php b/src/Rdf/Triple.php index 6379bbd..4bc14fc 100644 --- a/src/Rdf/Triple.php +++ b/src/Rdf/Triple.php @@ -1,51 +1,81 @@ -subject = $subject; $this->predicate = $predicate; $this->object = $object; + + if (!($object instanceof Iri || $object instanceof Literal)) { + throw new \InvalidArgumentException('Object must be Iri|Literal got: '.get_class($object)); + } } /** - * @return string + * @return Iri */ - public function getSubject(): string + public function getSubject(): Iri { return $this->subject; } /** - * @return string + * @return Iri */ - public function getPredicate(): string + public function getPredicate(): Iri { return $this->predicate; } /** - * @return string + * @return RdfTerm */ - public function getObject(): string + public function getObject(): RdfTerm { return $this->object; } + public function __toString(): string + { + if ($this->object instanceof Iri) { + return sprintf( + '<%s> <%s> <%s>', + $this->subject->getUri(), + $this->predicate->getUri(), + $this->object->getUri() + ); + } elseif ($this->object instanceof Literal) { + return sprintf( + '<%s> <%s> "%s"@%s', + $this->subject->getUri(), + $this->predicate->getUri(), + $this->object->getValue(), + $this->object->getLanguage() + ); + } -} \ No newline at end of file + throw new \LogicException('Object must be either Iri or Literal'); + } +} diff --git a/src/Rest/ListResponse.php b/src/Rest/ListResponse.php index 672c371..97bf2e2 100644 --- a/src/Rest/ListResponse.php +++ b/src/Rest/ListResponse.php @@ -1,10 +1,11 @@ -docs = $docs; $this->total = $total; $this->offset = $offset; } /** - * @return int + * @return array */ - public function getTotal(): int + public function getDocs(): array { - return $this->total; + return $this->docs; } /** - * @param int $total + * @return int */ - public function setTotal(int $total) + public function getTotal(): int { - $this->total = $total; + return $this->total; } /** @@ -54,41 +54,4 @@ public function getOffset(): int { return $this->offset; } - - /** - * @param int $offset - */ - public function setOffset(int $offset) - { - $this->offset = $offset; - } - - /** - * @return array - */ - public function getDocs(): array - { - return $this->docs; - } - - /** - * @param array $docs - */ - public function setDocs(array $docs) - { - $this->docs = $docs; - } - - /** - * TODO: Replace with Transformers for specific formats - * TODO: Look at https://symfony.com/doc/current/components/serializer.html - * @return array - */ - public function toArray() : array { - return [ - 'docs' => $this->docs, - 'total' => $this->total, - 'offset' => $this->offset, - ]; - } -} \ No newline at end of file +} diff --git a/src/Rest/SkosResponse.php b/src/Rest/SkosResponse.php new file mode 100644 index 0000000..685122f --- /dev/null +++ b/src/Rest/SkosResponse.php @@ -0,0 +1,7 @@ + Date: Fri, 24 May 2019 09:59:27 +0200 Subject: [PATCH 09/20] Snapshot. Completed Connection to Jena --- composer.json | 1 + composer.lock | 277 +++++++++--------- config/packages/databases.yaml | 3 + config/packages/institution.yaml | 4 +- config/packages/openskos.yaml | 20 ++ config/services.yaml | 12 + .../Sparql/SparqlRepositorySpec.php | 2 +- ...ry.php => SparqlInstitutionRepository.php} | 2 +- src/Serializer/ListResponseNormalizer.php | 62 ++++ symfony.lock | 6 + 10 files changed, 251 insertions(+), 138 deletions(-) create mode 100644 config/packages/databases.yaml create mode 100644 config/packages/openskos.yaml rename src/Institution/Sparql/{SparqlRepository.php => SparqlInstitutionRepository.php} (94%) create mode 100644 src/Serializer/ListResponseNormalizer.php diff --git a/composer.json b/composer.json index e19e577..eb7c32d 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "symfony/dotenv": "4.2.*", "symfony/flex": "^1.1", "symfony/framework-bundle": "4.2.*", + "symfony/property-access": "4.2.*", "symfony/serializer": "4.2.*", "symfony/yaml": "4.2.*" }, diff --git a/composer.lock b/composer.lock index f959336..559bb8e 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": "92e02b3fcb0d277e88ae985ee50e811e", + "content-hash": "20dbf0a069c3c3ff293773c5caa894cf", "packages": [ { "name": "doctrine/annotations", @@ -1772,6 +1772,64 @@ "homepage": "https://symfony.com", "time": "2019-05-01T13:31:08+00:00" }, + { + "name": "symfony/inflector", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/inflector.git", + "reference": "275e54941a4f17a471c68d2a00e2513fc1fd4a78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/inflector/zipball/275e54941a4f17a471c68d2a00e2513fc1fd4a78", + "reference": "275e54941a4f17a471c68d2a00e2513fc1fd4a78", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Inflector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Inflector Component", + "homepage": "https://symfony.com", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string", + "symfony", + "words" + ], + "time": "2019-01-16T20:31:39+00:00" + }, { "name": "symfony/polyfill-mbstring", "version": "v1.11.0", @@ -1831,6 +1889,73 @@ ], "time": "2019-02-06T07:57:58+00:00" }, + { + "name": "symfony/property-access", + "version": "v4.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-access.git", + "reference": "5440dd2b5373073beee051bd978b58a0f543b192" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-access/zipball/5440dd2b5373073beee051bd978b58a0f543b192", + "reference": "5440dd2b5373073beee051bd978b58a0f543b192", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/inflector": "~3.4|~4.0" + }, + "require-dev": { + "symfony/cache": "~3.4|~4.0" + }, + "suggest": { + "psr/cache-implementation": "To cache access methods." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyAccess\\": "" + }, + "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 PropertyAccess Component", + "homepage": "https://symfony.com", + "keywords": [ + "access", + "array", + "extraction", + "index", + "injection", + "object", + "property", + "property path", + "reflection" + ], + "time": "2019-03-04T09:16:25+00:00" + }, { "name": "symfony/routing", "version": "v4.2.8", @@ -3033,62 +3158,6 @@ ], "time": "2018-11-05T09:00:11+00:00" }, - { - "name": "muglug/package-versions-56", - "version": "1.2.4", - "source": { - "type": "git", - "url": "https://github.com/muglug/PackageVersions.git", - "reference": "a67bed26deaaf9269a348e53063bc8d4dcc60ffd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/muglug/PackageVersions/zipball/a67bed26deaaf9269a348e53063bc8d4dcc60ffd", - "reference": "a67bed26deaaf9269a348e53063bc8d4dcc60ffd", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0", - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "composer/composer": "^1.3", - "ext-zip": "*", - "phpunit/phpunit": "^5.7.5" - }, - "type": "composer-plugin", - "extra": { - "class": "Muglug\\PackageVersions\\Installer", - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Muglug\\PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - }, - { - "name": "Abdul Malik Ikhsan", - "email": "samsonasik@gmail.com" - }, - { - "name": "Matt Brown", - "email": "github@muglug.com" - } - ], - "description": "A backport of ocramius/package-versions that supports php ^5.6. Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "time": "2018-03-26T03:22:13+00:00" - }, { "name": "netresearch/jsonmapper", "version": "v1.4.0", @@ -4007,67 +4076,6 @@ ], "time": "2017-07-14T14:27:02+00:00" }, - { - "name": "phpmyadmin/sql-parser", - "version": "v4.3.1", - "source": { - "type": "git", - "url": "https://github.com/phpmyadmin/sql-parser.git", - "reference": "0eb16ef5e3acacbc792be336754e42d98791a33f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/0eb16ef5e3acacbc792be336754e42d98791a33f", - "reference": "0eb16ef5e3acacbc792be336754e42d98791a33f", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "symfony/polyfill-mbstring": "^1.3" - }, - "conflict": { - "phpmyadmin/motranslator": "<3.0" - }, - "require-dev": { - "phpunit/php-code-coverage": "*", - "phpunit/phpunit": "~4.8 || ~5.7 || ~6.5", - "sami/sami": "^4.0" - }, - "suggest": { - "ext-mbstring": "For best performance", - "phpmyadmin/motranslator": "Translate messages to your favorite locale" - }, - "bin": [ - "bin/highlight-query", - "bin/lint-query" - ], - "type": "library", - "autoload": { - "psr-4": { - "PhpMyAdmin\\SqlParser\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-2.0-or-later" - ], - "authors": [ - { - "name": "The phpMyAdmin Team", - "email": "developers@phpmyadmin.net", - "homepage": "https://www.phpmyadmin.net/team/" - } - ], - "description": "A validating SQL lexer and parser with a focus on MySQL dialect.", - "homepage": "https://github.com/phpmyadmin/sql-parser", - "keywords": [ - "analysis", - "lexer", - "parser", - "sql" - ], - "time": "2019-01-05T13:46:38+00:00" - }, { "name": "phpro/grumphp", "version": "v0.15.2", @@ -4405,16 +4413,16 @@ }, { "name": "phpstan/phpstan", - "version": "0.11.6", + "version": "0.11.7", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "7af8b9d02b3ab36444dbf4e1b9ca1c1bd5044d81" + "reference": "32d87d746c70785f78d239855782d27cde0eb6ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7af8b9d02b3ab36444dbf4e1b9ca1c1bd5044d81", - "reference": "7af8b9d02b3ab36444dbf4e1b9ca1c1bd5044d81", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/32d87d746c70785f78d239855782d27cde0eb6ee", + "reference": "32d87d746c70785f78d239855782d27cde0eb6ee", "shasum": "" }, "require": { @@ -4423,6 +4431,7 @@ "nette/bootstrap": "^2.4 || ^3.0", "nette/di": "^2.4.7 || ^3.0", "nette/robot-loader": "^3.0.1", + "nette/schema": "^1.0", "nette/utils": "^2.4.5 || ^3.0", "nikic/php-parser": "^4.0.2", "php": "~7.1", @@ -4474,7 +4483,7 @@ "MIT" ], "description": "PHPStan - PHP Static Analysis Tool", - "time": "2019-05-08T16:33:56+00:00" + "time": "2019-05-19T17:36:42+00:00" }, { "name": "sebastian/comparator", @@ -5070,16 +5079,16 @@ }, { "name": "vimeo/psalm", - "version": "3.2.12", + "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", - "reference": "fe0f352132f798512ced19faf75cbfc84e4aabe7" + "reference": "a1eb191f57cd6ac1963ce7818d010f981564bb74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/fe0f352132f798512ced19faf75cbfc84e4aabe7", - "reference": "fe0f352132f798512ced19faf75cbfc84e4aabe7", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/a1eb191f57cd6ac1963ce7818d010f981564bb74", + "reference": "a1eb191f57cd6ac1963ce7818d010f981564bb74", "shasum": "" }, "require": { @@ -5088,13 +5097,12 @@ "composer/xdebug-handler": "^1.1", "felixfbecker/advanced-json-rpc": "^3.0.3", "felixfbecker/language-server-protocol": "^1.2", - "muglug/package-versions-56": "1.2.4", "netresearch/jsonmapper": "^1.0", "nikic/php-parser": "^4.0.2 || ^4.1", + "ocramius/package-versions": "^1.2", "openlss/lib-array2xml": "^0.0.10||^0.5.1", - "php": "^7.0", - "php-cs-fixer/diff": "^1.2", - "phpmyadmin/sql-parser": "^4.0", + "php": "^7.1", + "sebastian/diff": "^3.0", "symfony/console": "^3.3||^4.0", "webmozart/glob": "^4.1", "webmozart/path-util": "^2.3" @@ -5104,8 +5112,9 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.2", - "phpunit/phpunit": "^6.0 || ^7.0", - "psalm/plugin-phpunit": "^0.5.5", + "phpmyadmin/sql-parser": "^5.0", + "phpunit/phpunit": "^7.5 || ^8.0", + "psalm/plugin-phpunit": "^0.6", "squizlabs/php_codesniffer": "3.4.0" }, "suggest": { @@ -5146,7 +5155,7 @@ "inspection", "php" ], - "time": "2019-05-13T15:00:17+00:00" + "time": "2019-05-21T03:14:41+00:00" }, { "name": "webmozart/assert", diff --git a/config/packages/databases.yaml b/config/packages/databases.yaml new file mode 100644 index 0000000..a4d6f9c --- /dev/null +++ b/config/packages/databases.yaml @@ -0,0 +1,3 @@ +parameters: + query_uri: 'http://192.168.56.10:3030/beg-openskos-production/query' + update_uri: 'http://192.168.56.10:3030/beg-openskos-production/update' diff --git a/config/packages/institution.yaml b/config/packages/institution.yaml index c7a1d6b..dd974b3 100644 --- a/config/packages/institution.yaml +++ b/config/packages/institution.yaml @@ -8,7 +8,7 @@ services: resource: '../../src/Institution/Controller/*' tags: ['controller.service_arguments'] - App\Institution\InMemoryRepository: ~ + App\Institution\Sparql\SparqlInstitutionRepository: ~ - App\Institution\InstitutionRepository: '@App\Institution\InMemoryRepository' + App\Institution\InstitutionRepository: '@App\Institution\Sparql\SparqlInstitutionRepository' diff --git a/config/packages/openskos.yaml b/config/packages/openskos.yaml new file mode 100644 index 0000000..ceed2d7 --- /dev/null +++ b/config/packages/openskos.yaml @@ -0,0 +1,20 @@ +services: + # default configuration for services in *this* file + _defaults: + autowire: true # Automatically injects dependencies in your services. + autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. + + + EasyRdf_Sparql_Client: + class: EasyRdf_Sparql_Client + arguments: + $queryUri: '%query_uri%' + $updateUri: '%update_uri%' + + + MyEasyRdfClient: + class: App\EasyRdf\EasyRdfClient + arguments: ['@EasyRdf_Sparql_Client'] + + App\Institution\Sparql\SparqlInstitutionRepository: + arguments: ['@MyEasyRdfClient'] diff --git a/config/services.yaml b/config/services.yaml index 0d53396..f13bd6a 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -5,5 +5,17 @@ # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration parameters: + +imports: + - { resource: './packages/databases.yaml' } + services: # default configuration for services in *this* file + + \App\Rdf\RdfClient: '@App\Institution\Sparql\SparqlInstitutionRepository' + + + \App\Serialize\ListResponseNormalizer: + class: App\Serializer\ListResponseNormalizer + tags: ['serializer.normalizer'] + arguments: ['@Symfony\Component\Serializer\Normalizer\ObjectNormalizer'] diff --git a/spec/Institution/Sparql/SparqlRepositorySpec.php b/spec/Institution/Sparql/SparqlRepositorySpec.php index df07284..ce16303 100644 --- a/spec/Institution/Sparql/SparqlRepositorySpec.php +++ b/spec/Institution/Sparql/SparqlRepositorySpec.php @@ -12,7 +12,7 @@ use PhpSpec\ObjectBehavior; use Prophecy\Argument; -class SparqlRepositorySpec extends ObjectBehavior +class SparqlInstitutionRepositorySpec extends ObjectBehavior { public function let(Client $rdfClient) { diff --git a/src/Institution/Sparql/SparqlRepository.php b/src/Institution/Sparql/SparqlInstitutionRepository.php similarity index 94% rename from src/Institution/Sparql/SparqlRepository.php rename to src/Institution/Sparql/SparqlInstitutionRepository.php index 586f2ea..29ed87d 100644 --- a/src/Institution/Sparql/SparqlRepository.php +++ b/src/Institution/Sparql/SparqlInstitutionRepository.php @@ -11,7 +11,7 @@ use App\Rdf\Iri; use App\Rdf\SparqlQueryBuilder; -final class SparqlRepository implements InstitutionRepository +final class SparqlInstitutionRepository implements InstitutionRepository { /** * @var Client diff --git a/src/Serializer/ListResponseNormalizer.php b/src/Serializer/ListResponseNormalizer.php new file mode 100644 index 0000000..6b79ebd --- /dev/null +++ b/src/Serializer/ListResponseNormalizer.php @@ -0,0 +1,62 @@ +normalizer = $normalizer; + } + + /** + * {@inheritdoc} + */ + public function normalize($list_object, $format = null, array $context = []) + { + //$objectNormalizer = new ObjectNormalizer(); + + $data = $this->normalizer->normalize($list_object, $format, $context); + + /* + // Here, add, edit, or delete some data: + $data['href']['self'] = $this->router->generate('topic_show', [ + 'id' => $topic->getId(), + ], UrlGeneratorInterface::ABSOLUTE_URL); + + return $data; + */ + return $data; + + /* + return json_encode($data); + + return var_export($list_object); + */ + } + + /** + * {@inheritdoc} + */ + public function supportsNormalization($data, $format = null, array $context = []) + { + return $data instanceof ListResponse; + } +} diff --git a/symfony.lock b/symfony.lock index 7297f4b..132c8cf 100644 --- a/symfony.lock +++ b/symfony.lock @@ -289,6 +289,9 @@ "symfony/http-kernel": { "version": "v4.2.8" }, + "symfony/inflector": { + "version": "v4.2.8" + }, "symfony/options-resolver": { "version": "v4.2.8" }, @@ -301,6 +304,9 @@ "symfony/process": { "version": "v4.2.8" }, + "symfony/property-access": { + "version": "v4.2.8" + }, "symfony/routing": { "version": "4.2", "recipe": { From a1802745dbaf6b8092bb949a2c2fa6abd3d15fe8 Mon Sep 17 00:00:00 2001 From: Ben Hillier Date: Mon, 27 May 2019 12:59:41 +0200 Subject: [PATCH 10/20] Added Pagination classes and testing --- config/services.yaml | 6 +- spec/OpenSkos/PaginationSpec.php | 24 +++++++ .../PaginationResolverSpec.php | 43 ++++++++++++ src/Institution/Controller/Institution.php | 5 +- src/OpenSkos/InvalidPaginationLevel.php | 13 ++++ src/OpenSkos/Pagination.php | 66 +++++++++++++++++++ .../ArgumentResolver/PaginationResolver.php | 27 ++++++++ 7 files changed, 181 insertions(+), 3 deletions(-) create mode 100644 spec/OpenSkos/PaginationSpec.php create mode 100644 spec/Rest/ArgumentResolver/PaginationResolverSpec.php create mode 100644 src/OpenSkos/InvalidPaginationLevel.php create mode 100644 src/OpenSkos/Pagination.php create mode 100644 src/Rest/ArgumentResolver/PaginationResolver.php diff --git a/config/services.yaml b/config/services.yaml index f13bd6a..ce97af5 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -15,7 +15,9 @@ services: \App\Rdf\RdfClient: '@App\Institution\Sparql\SparqlInstitutionRepository' - \App\Serialize\ListResponseNormalizer: - class: App\Serializer\ListResponseNormalizer + App\Serializer\ListResponseNormalizer: tags: ['serializer.normalizer'] arguments: ['@Symfony\Component\Serializer\Normalizer\ObjectNormalizer'] + + App\Rest\ArgumentResolver\PaginationResolver: + tags: ['controller.argument_value_resolver'] \ No newline at end of file diff --git a/spec/OpenSkos/PaginationSpec.php b/spec/OpenSkos/PaginationSpec.php new file mode 100644 index 0000000..9a437e0 --- /dev/null +++ b/spec/OpenSkos/PaginationSpec.php @@ -0,0 +1,24 @@ +beConstructedWith(5); + $this->shouldThrow(InvalidPaginationLevel::class)->duringInstantiation(); + + $this->beConstructedWith(0); + $this->shouldThrow(InvalidPaginationLevel::class)->duringInstantiation(); + } + + public function it_throws_exception_for_negative_paging() + { + $this->beConstructedWith(1, -1, -42); + $this->shouldThrow(\InvalidArgumentException::class)->duringInstantiation(); + } +} diff --git a/spec/Rest/ArgumentResolver/PaginationResolverSpec.php b/spec/Rest/ArgumentResolver/PaginationResolverSpec.php new file mode 100644 index 0000000..c2a8aa5 --- /dev/null +++ b/spec/Rest/ArgumentResolver/PaginationResolverSpec.php @@ -0,0 +1,43 @@ + '123', + 'offset' => '12', + 'level' => '1', + ] + ); + + /** @var Pagination $pagination */ + $pagination = $this->resolve($request, $argumentMetadata)->current(); + + $pagination->getLevel()->shouldBe(1); + $pagination->getLimit()->shouldBe(123); + $pagination->getOffset()->shouldBe(12); + } + + public function it_returns_correct_default_values( + ArgumentMetadata $argumentMetadata + ) { + $request = new Request(); + + /** @var Pagination $pagination */ + $pagination = $this->resolve($request, $argumentMetadata)->current(); + + $pagination->getLevel()->shouldBe(1); + $pagination->getLimit()->shouldBe(100); + $pagination->getOffset()->shouldBe(0); + } +} diff --git a/src/Institution/Controller/Institution.php b/src/Institution/Controller/Institution.php index 195a9f3..e86841a 100644 --- a/src/Institution/Controller/Institution.php +++ b/src/Institution/Controller/Institution.php @@ -5,9 +5,11 @@ namespace App\Institution\Controller; use App\Institution\InstitutionRepository; +use App\OpenSkos\Pagination; use App\Rest\ListResponse; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Serializer\SerializerInterface; @@ -27,11 +29,12 @@ public function __construct( /** * @Route(path="/institutions", methods={"GET"}) * + * @param Request $request * @param InstitutionRepository $repository * * @return JsonResponse */ - public function institutions(InstitutionRepository $repository): JsonResponse + public function institutions(Pagination $pagination, InstitutionRepository $repository): JsonResponse { $institutions = $repository->all(); $list = new ListResponse($institutions, 0, count($institutions)); diff --git a/src/OpenSkos/InvalidPaginationLevel.php b/src/OpenSkos/InvalidPaginationLevel.php new file mode 100644 index 0000000..48ecd50 --- /dev/null +++ b/src/OpenSkos/InvalidPaginationLevel.php @@ -0,0 +1,13 @@ +level = $level; + $this->offset = $offset; + $this->limit = $limit; + + if ($level < 1 || $level > 4) { + throw new InvalidPaginationLevel($level); + } + if ($limit < 0 || $offset < 0) { + throw new \InvalidArgumentException( + "Limit and offset must be zero or higher. $limit and $offset passed" + ); + } + } + + /** + * @return int + */ + public function getLevel(): int + { + return $this->level; + } + + /** + * @return int + */ + public function getOffset(): int + { + return $this->offset; + } + + /** + * @return int + */ + public function getLimit(): int + { + return $this->limit; + } +} diff --git a/src/Rest/ArgumentResolver/PaginationResolver.php b/src/Rest/ArgumentResolver/PaginationResolver.php new file mode 100644 index 0000000..3b9f100 --- /dev/null +++ b/src/Rest/ArgumentResolver/PaginationResolver.php @@ -0,0 +1,27 @@ +getType(); + } + + public function resolve(Request $request, ArgumentMetadata $argument) + { + yield new Pagination( + $request->query->getInt('level', 1), + $request->query->getInt('limit', 100), + $request->query->getInt('offset', 0) + ); + } +} From 251e350318da13e130ef6f3adcf9bb80b4e16da0 Mon Sep 17 00:00:00 2001 From: Ben Hillier Date: Mon, 27 May 2019 14:29:48 +0200 Subject: [PATCH 11/20] Added format to 'Pagination', and refactored it to 'ApiRequest' --- config/services.yaml | 2 +- spec/OpenSkos/ApiRequestSpec.php | 24 +++++++++++++++++++ spec/OpenSkos/PaginationSpec.php | 24 ------------------- ...verSpec.php => ApiRequestResolverSpec.php} | 11 +++++---- src/Institution/Controller/Institution.php | 4 ++-- .../{Pagination.php => ApiRequest.php} | 22 +++++++++++++++-- ...onLevel.php => InvalidApiRequestLevel.php} | 2 +- ...ionResolver.php => ApiRequestResolver.php} | 9 +++---- 8 files changed, 60 insertions(+), 38 deletions(-) create mode 100644 spec/OpenSkos/ApiRequestSpec.php delete mode 100644 spec/OpenSkos/PaginationSpec.php rename spec/Rest/ArgumentResolver/{PaginationResolverSpec.php => ApiRequestResolverSpec.php} (77%) rename src/OpenSkos/{Pagination.php => ApiRequest.php} (73%) rename src/OpenSkos/{InvalidPaginationLevel.php => InvalidApiRequestLevel.php} (75%) rename src/Rest/ArgumentResolver/{PaginationResolver.php => ApiRequestResolver.php} (72%) diff --git a/config/services.yaml b/config/services.yaml index ce97af5..080c274 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -19,5 +19,5 @@ services: tags: ['serializer.normalizer'] arguments: ['@Symfony\Component\Serializer\Normalizer\ObjectNormalizer'] - App\Rest\ArgumentResolver\PaginationResolver: + App\Rest\ArgumentResolver\ApiRequestResolver: tags: ['controller.argument_value_resolver'] \ No newline at end of file diff --git a/spec/OpenSkos/ApiRequestSpec.php b/spec/OpenSkos/ApiRequestSpec.php new file mode 100644 index 0000000..fbb71c2 --- /dev/null +++ b/spec/OpenSkos/ApiRequestSpec.php @@ -0,0 +1,24 @@ +beConstructedWith('json-ld', 5); + $this->shouldThrow(InvalidApiRequestLevel::class)->duringInstantiation(); + + $this->beConstructedWith('json-ld', 0); + $this->shouldThrow(InvalidApiRequestLevel::class)->duringInstantiation(); + } + + public function it_throws_exception_for_negative_paging() + { + $this->beConstructedWith('json-ld', 1, -1, -42); + $this->shouldThrow(\InvalidArgumentException::class)->duringInstantiation(); + } +} diff --git a/spec/OpenSkos/PaginationSpec.php b/spec/OpenSkos/PaginationSpec.php deleted file mode 100644 index 9a437e0..0000000 --- a/spec/OpenSkos/PaginationSpec.php +++ /dev/null @@ -1,24 +0,0 @@ -beConstructedWith(5); - $this->shouldThrow(InvalidPaginationLevel::class)->duringInstantiation(); - - $this->beConstructedWith(0); - $this->shouldThrow(InvalidPaginationLevel::class)->duringInstantiation(); - } - - public function it_throws_exception_for_negative_paging() - { - $this->beConstructedWith(1, -1, -42); - $this->shouldThrow(\InvalidArgumentException::class)->duringInstantiation(); - } -} diff --git a/spec/Rest/ArgumentResolver/PaginationResolverSpec.php b/spec/Rest/ArgumentResolver/ApiRequestResolverSpec.php similarity index 77% rename from spec/Rest/ArgumentResolver/PaginationResolverSpec.php rename to spec/Rest/ArgumentResolver/ApiRequestResolverSpec.php index c2a8aa5..bb5687b 100644 --- a/spec/Rest/ArgumentResolver/PaginationResolverSpec.php +++ b/spec/Rest/ArgumentResolver/ApiRequestResolverSpec.php @@ -2,27 +2,29 @@ namespace spec\App\Rest\ArgumentResolver; -use App\OpenSkos\Pagination; +use App\OpenSkos\ApiRequest; use PhpSpec\ObjectBehavior; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; -class PaginationResolverSpec extends ObjectBehavior +class ApiRequestResolverSpec extends ObjectBehavior { public function it_resolves_pagination_from_symfony_request( ArgumentMetadata $argumentMetadata ) { $request = new Request( [ + 'format' => 'json-ld', 'limit' => '123', 'offset' => '12', 'level' => '1', ] ); - /** @var Pagination $pagination */ + /** @var ApiRequest $pagination */ $pagination = $this->resolve($request, $argumentMetadata)->current(); + $pagination->getFormat()->shouldBe('json-ld'); $pagination->getLevel()->shouldBe(1); $pagination->getLimit()->shouldBe(123); $pagination->getOffset()->shouldBe(12); @@ -33,9 +35,10 @@ public function it_returns_correct_default_values( ) { $request = new Request(); - /** @var Pagination $pagination */ + /** @var ApiRequest $pagination */ $pagination = $this->resolve($request, $argumentMetadata)->current(); + $pagination->getFormat()->shouldBe('json-ld'); $pagination->getLevel()->shouldBe(1); $pagination->getLimit()->shouldBe(100); $pagination->getOffset()->shouldBe(0); diff --git a/src/Institution/Controller/Institution.php b/src/Institution/Controller/Institution.php index e86841a..280c9a6 100644 --- a/src/Institution/Controller/Institution.php +++ b/src/Institution/Controller/Institution.php @@ -5,7 +5,7 @@ namespace App\Institution\Controller; use App\Institution\InstitutionRepository; -use App\OpenSkos\Pagination; +use App\OpenSkos\ApiRequest; use App\Rest\ListResponse; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; @@ -34,7 +34,7 @@ public function __construct( * * @return JsonResponse */ - public function institutions(Pagination $pagination, InstitutionRepository $repository): JsonResponse + public function institutions(ApiRequest $apiRequest, InstitutionRepository $repository): JsonResponse { $institutions = $repository->all(); $list = new ListResponse($institutions, 0, count($institutions)); diff --git a/src/OpenSkos/Pagination.php b/src/OpenSkos/ApiRequest.php similarity index 73% rename from src/OpenSkos/Pagination.php rename to src/OpenSkos/ApiRequest.php index 55e7dd2..862ddaf 100644 --- a/src/OpenSkos/Pagination.php +++ b/src/OpenSkos/ApiRequest.php @@ -4,8 +4,19 @@ namespace App\OpenSkos; -final class Pagination +final class ApiRequest { + /* + * Supported Formats + */ + const FORMAT_JSONLD = 'json-ld'; + + + /** + * @var string + */ + private $format; + /** * @var int */ @@ -22,16 +33,18 @@ final class Pagination private $limit; public function __construct( + string $format = self::FORMAT_JSONLD, int $level = 1, int $limit = 100, int $offset = 0 ) { + $this->format = $format; $this->level = $level; $this->offset = $offset; $this->limit = $limit; if ($level < 1 || $level > 4) { - throw new InvalidPaginationLevel($level); + throw new InvalidApiRequestLevel($level); } if ($limit < 0 || $offset < 0) { throw new \InvalidArgumentException( @@ -63,4 +76,9 @@ public function getLimit(): int { return $this->limit; } + + public function getFormat() + { + return $this->format; + } } diff --git a/src/OpenSkos/InvalidPaginationLevel.php b/src/OpenSkos/InvalidApiRequestLevel.php similarity index 75% rename from src/OpenSkos/InvalidPaginationLevel.php rename to src/OpenSkos/InvalidApiRequestLevel.php index 48ecd50..04b6a1a 100644 --- a/src/OpenSkos/InvalidPaginationLevel.php +++ b/src/OpenSkos/InvalidApiRequestLevel.php @@ -4,7 +4,7 @@ namespace App\OpenSkos; -final class InvalidPaginationLevel extends \InvalidArgumentException +final class InvalidApiRequestLevel extends \InvalidArgumentException { public function __construct($level = '') { diff --git a/src/Rest/ArgumentResolver/PaginationResolver.php b/src/Rest/ArgumentResolver/ApiRequestResolver.php similarity index 72% rename from src/Rest/ArgumentResolver/PaginationResolver.php rename to src/Rest/ArgumentResolver/ApiRequestResolver.php index 3b9f100..3b3fdb8 100644 --- a/src/Rest/ArgumentResolver/PaginationResolver.php +++ b/src/Rest/ArgumentResolver/ApiRequestResolver.php @@ -4,21 +4,22 @@ namespace App\Rest\ArgumentResolver; -use App\OpenSkos\Pagination; +use App\OpenSkos\ApiRequest; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; -final class PaginationResolver implements ArgumentValueResolverInterface +final class ApiRequestResolver implements ArgumentValueResolverInterface { public function supports(Request $request, ArgumentMetadata $argument) { - return Pagination::class === $argument->getType(); + return ApiRequest::class === $argument->getType(); } public function resolve(Request $request, ArgumentMetadata $argument) { - yield new Pagination( + yield new ApiRequest( + $request->query->get('format', 'json-ld'), $request->query->getInt('level', 1), $request->query->getInt('limit', 100), $request->query->getInt('offset', 0) From 7a605e0f234f02ee36e8ca2c9d98bcbab555b6b6 Mon Sep 17 00:00:00 2001 From: Ben Hillier Date: Mon, 27 May 2019 14:30:43 +0200 Subject: [PATCH 12/20] Formatting --- src/OpenSkos/ApiRequest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/OpenSkos/ApiRequest.php b/src/OpenSkos/ApiRequest.php index 862ddaf..2d526f0 100644 --- a/src/OpenSkos/ApiRequest.php +++ b/src/OpenSkos/ApiRequest.php @@ -11,7 +11,6 @@ final class ApiRequest */ const FORMAT_JSONLD = 'json-ld'; - /** * @var string */ From 76c8fa286b3e2c663b39692e28380ae8e67ae033 Mon Sep 17 00:00:00 2001 From: Ben Hillier Date: Tue, 28 May 2019 15:52:22 +0200 Subject: [PATCH 13/20] Added Encoders/Decoders for EasyRDF. Implemented some Content Types --- composer.json | 1 + composer.lock | 98 +++++++++++++++++++++- config/services.yaml | 7 ++ spec/OpenSkos/ApiRequestSpec.php | 7 ++ src/Institution/Controller/Institution.php | 22 +++-- src/Institution/Institution.php | 21 +++++ src/OpenSkos/ApiRequest.php | 49 +++++++++-- src/Rdf/RdfHeaders.php | 35 ++++++++ src/Serializer/JsonLdEncoder.php | 58 +++++++++++++ src/Serializer/ListResponseNormalizer.php | 37 ++++---- src/Serializer/RdfXmlEncoder.php | 66 +++++++++++++++ symfony.lock | 6 ++ 12 files changed, 375 insertions(+), 32 deletions(-) create mode 100644 src/Rdf/RdfHeaders.php create mode 100644 src/Serializer/JsonLdEncoder.php create mode 100644 src/Serializer/RdfXmlEncoder.php diff --git a/composer.json b/composer.json index eb7c32d..29e3d51 100644 --- a/composer.json +++ b/composer.json @@ -6,6 +6,7 @@ "ext-ctype": "*", "ext-iconv": "*", "easyrdf/easyrdf": "^0.9.1", + "ml/json-ld": "^1.1", "sensio/framework-extra-bundle": "^5.3", "symfony/console": "4.2.*", "symfony/dotenv": "4.2.*", diff --git a/composer.lock b/composer.lock index 559bb8e..8a8f020 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": "20dbf0a069c3c3ff293773c5caa894cf", + "content-hash": "c488b9f138f0af69b914f0a0d8c032ee", "packages": [ { "name": "doctrine/annotations", @@ -566,6 +566,102 @@ ], "time": "2015-02-27T09:45:49+00:00" }, + { + "name": "ml/iri", + "version": "1.1.4", + "target-dir": "ML/IRI", + "source": { + "type": "git", + "url": "https://github.com/lanthaler/IRI.git", + "reference": "cbd44fa913e00ea624241b38cefaa99da8d71341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lanthaler/IRI/zipball/cbd44fa913e00ea624241b38cefaa99da8d71341", + "reference": "cbd44fa913e00ea624241b38cefaa99da8d71341", + "shasum": "" + }, + "require": { + "lib-pcre": ">=4.0", + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "ML\\IRI": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Markus Lanthaler", + "email": "mail@markus-lanthaler.com", + "homepage": "http://www.markus-lanthaler.com", + "role": "Developer" + } + ], + "description": "IRI handling for PHP", + "homepage": "http://www.markus-lanthaler.com", + "keywords": [ + "URN", + "iri", + "uri", + "url" + ], + "time": "2014-01-21T13:43:39+00:00" + }, + { + "name": "ml/json-ld", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/lanthaler/JsonLD.git", + "reference": "b5f82820c255cb64067b1c7adbb819cad4afa70a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lanthaler/JsonLD/zipball/b5f82820c255cb64067b1c7adbb819cad4afa70a", + "reference": "b5f82820c255cb64067b1c7adbb819cad4afa70a", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ml/iri": "^1.1.1", + "php": ">=5.3.0" + }, + "require-dev": { + "json-ld/tests": "1.0", + "phpunit/phpunit": "^4" + }, + "type": "library", + "autoload": { + "psr-4": { + "ML\\JsonLD\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Markus Lanthaler", + "email": "mail@markus-lanthaler.com", + "homepage": "http://www.markus-lanthaler.com", + "role": "Developer" + } + ], + "description": "JSON-LD Processor for PHP", + "homepage": "http://www.markus-lanthaler.com", + "keywords": [ + "JSON-LD", + "jsonld" + ], + "time": "2018-11-18T20:26:18+00:00" + }, { "name": "psr/cache", "version": "1.0.1", diff --git a/config/services.yaml b/config/services.yaml index 080c274..0a1a9b0 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -19,5 +19,12 @@ services: tags: ['serializer.normalizer'] arguments: ['@Symfony\Component\Serializer\Normalizer\ObjectNormalizer'] + + App\Serializer\JsonLdEncoder: + tags: ['serializer.encoder'] + + App\Serializer\RdfXmlEncoder: + tags: ['serializer.encoder'] + App\Rest\ArgumentResolver\ApiRequestResolver: tags: ['controller.argument_value_resolver'] \ No newline at end of file diff --git a/spec/OpenSkos/ApiRequestSpec.php b/spec/OpenSkos/ApiRequestSpec.php index fbb71c2..7fe127e 100644 --- a/spec/OpenSkos/ApiRequestSpec.php +++ b/spec/OpenSkos/ApiRequestSpec.php @@ -4,6 +4,7 @@ use App\OpenSkos\InvalidApiRequestLevel; use PhpSpec\ObjectBehavior; +use Symfony\Component\HttpKernel\Exception\HttpException; class ApiRequestSpec extends ObjectBehavior { @@ -21,4 +22,10 @@ public function it_throws_exception_for_negative_paging() $this->beConstructedWith('json-ld', 1, -1, -42); $this->shouldThrow(\InvalidArgumentException::class)->duringInstantiation(); } + + public function it_throws_a_wobbly_with_invalid_formats() + { + $this->beConstructedWith('something-i-just-made-up'); + $this->shouldThrow(HttpException::class)->duringInstantiation(); + } } diff --git a/src/Institution/Controller/Institution.php b/src/Institution/Controller/Institution.php index 280c9a6..a27b55c 100644 --- a/src/Institution/Controller/Institution.php +++ b/src/Institution/Controller/Institution.php @@ -7,9 +7,7 @@ use App\Institution\InstitutionRepository; use App\OpenSkos\ApiRequest; use App\Rest\ListResponse; -use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Serializer\SerializerInterface; @@ -29,18 +27,24 @@ public function __construct( /** * @Route(path="/institutions", methods={"GET"}) * - * @param Request $request + * @param ApiRequest $apiRequest * @param InstitutionRepository $repository * - * @return JsonResponse + * @return Response */ - public function institutions(ApiRequest $apiRequest, InstitutionRepository $repository): JsonResponse + public function institutions(ApiRequest $apiRequest, InstitutionRepository $repository): Response { - $institutions = $repository->all(); - $list = new ListResponse($institutions, 0, count($institutions)); + $institutions = $repository->all($apiRequest->getOffset(), $apiRequest->getLimit()); - $res = $this->serializer->serialize($list, 'json'); + $list = new ListResponse($institutions, count($institutions), $apiRequest->getOffset()); - return new JsonResponse($res, Response::HTTP_OK, [], true); + $res = $this->serializer->serialize($list, $apiRequest->getFormat()); + + $formatOut = $apiRequest->getReturnContentType(); + + $response = new Response($res, Response::HTTP_OK, []); + $response->headers->set('Content-Type', $formatOut); + + return $response; } } diff --git a/src/Institution/Institution.php b/src/Institution/Institution.php index 8474d93..3ba7de6 100644 --- a/src/Institution/Institution.php +++ b/src/Institution/Institution.php @@ -56,6 +56,14 @@ public function __construct(Iri $subject) $this->subject = $subject; } + /** + * @return string[] + */ + public static function getMapping(): array + { + return self::$mapping; + } + //TODO: Generate getters. /** @@ -82,6 +90,11 @@ public function getWebsite(): ?Literal return $this->literals[self::website] ?? null; } + public function count(): int + { + return count($this->literals); + } + /** * @param Iri $subject * @param Triple[] $triples @@ -124,4 +137,12 @@ public static function fromTriples(Iri $subject, array $triples): Institution return $obj; } + + /** + * @return Literal[] + */ + public function getLiterals(): array + { + return $this->literals; + } } diff --git a/src/OpenSkos/ApiRequest.php b/src/OpenSkos/ApiRequest.php index 2d526f0..4204736 100644 --- a/src/OpenSkos/ApiRequest.php +++ b/src/OpenSkos/ApiRequest.php @@ -4,13 +4,11 @@ namespace App\OpenSkos; +use App\Rdf\RdfHeaders; +use Symfony\Component\HttpKernel\Exception\HttpException; + final class ApiRequest { - /* - * Supported Formats - */ - const FORMAT_JSONLD = 'json-ld'; - /** * @var string */ @@ -31,8 +29,16 @@ final class ApiRequest */ private $limit; + /** + * ApiRequest constructor. + * + * @param string $format + * @param int $level + * @param int $limit + * @param int $offset + */ public function __construct( - string $format = self::FORMAT_JSONLD, + string $format = RdfHeaders::FORMAT_JSON_LD, int $level = 1, int $limit = 100, int $offset = 0 @@ -42,6 +48,13 @@ public function __construct( $this->offset = $offset; $this->limit = $limit; + if (!in_array($format, [RdfHeaders::FORMAT_JSON_LD, RdfHeaders::FORMAT_RDF_XML])) { + throw new HttpException( + 406, + "'$format' is not an accepted format" + ); + } + if ($level < 1 || $level > 4) { throw new InvalidApiRequestLevel($level); } @@ -76,8 +89,30 @@ public function getLimit(): int return $this->limit; } - public function getFormat() + /** + * @return string + */ + public function getFormat(): string { return $this->format; } + + /** + * @return string + */ + public function getReturnContentType(): string + { + $formatOut = RdfHeaders::CONTENT_TYPE_HEADER_HTML; + + switch ($this->format) { + case RdfHeaders::FORMAT_JSON_LD: + $formatOut = RdfHeaders::CONTENT_TYPE_HEADER_JSON_LD; + break; + case RdfHeaders::FORMAT_RDF_XML: + $formatOut = RdfHeaders::CONTENT_TYPE_HEADER_RDF_XML; + break; + } + + return $formatOut; + } } diff --git a/src/Rdf/RdfHeaders.php b/src/Rdf/RdfHeaders.php new file mode 100644 index 0000000..458f067 --- /dev/null +++ b/src/Rdf/RdfHeaders.php @@ -0,0 +1,35 @@ +serialise('jsonld'); + } + + /** + * @param string $format + * + * @return bool + */ + public function supportsEncoding($format) + { + return RdfHeaders::FORMAT_JSON_LD === $format; + } + + /** + * @param string $data + * @param string $format + * @param array $context + * + * @return EasyRdf_Graph|mixed + * + * @throws \EasyRdf_Exception + */ + public function decode($data, $format, array $context = []) + { + $graph = new EasyRdf_Graph($_REQUEST['uri']); + $graph->parse($_REQUEST['data'], 'jsonld', 'http://openskos.org'); + + return $graph; + } + + /** + * @param string $format + * + * @return bool + */ + public function supportsDecoding($format) + { + return RdfHeaders::FORMAT_JSON_LD === $format; + } +} diff --git a/src/Serializer/ListResponseNormalizer.php b/src/Serializer/ListResponseNormalizer.php index 6b79ebd..145d531 100644 --- a/src/Serializer/ListResponseNormalizer.php +++ b/src/Serializer/ListResponseNormalizer.php @@ -5,12 +5,16 @@ namespace App\Serializer; use App\Rest\ListResponse; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use EasyRdf_Graph; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; class ListResponseNormalizer implements NormalizerInterface { + /** + * EasyRdf is used an an intermediate format between the TripleStore and its serialised formats. + */ + /** * @var ObjectNormalizer */ @@ -31,25 +35,28 @@ public function __construct(ObjectNormalizer $normalizer) */ public function normalize($list_object, $format = null, array $context = []) { - //$objectNormalizer = new ObjectNormalizer(); + // A listing of artist + //$uri = sprintf("%s%s", self::RKD_RECORDSEARCH, $searchQuery); + + $graph = new EasyRdf_Graph('http://openskos.org'); - $data = $this->normalizer->normalize($list_object, $format, $context); + $OSEntityCollection = $list_object->getDocs(); - /* - // Here, add, edit, or delete some data: - $data['href']['self'] = $this->router->generate('topic_show', [ - 'id' => $topic->getId(), - ], UrlGeneratorInterface::ABSOLUTE_URL); + foreach ($OSEntityCollection as $osEntity) { + $subject = $osEntity->getSubject()->getUri(); - return $data; - */ - return $data; + $entity = $graph->resource($subject, 'rdf:Description'); - /* - return json_encode($data); + $mapping = $osEntity->getMapping(); + $literals = $osEntity->getLiterals(); + foreach ($mapping as $key => $property) { + if (isset($literals[$key])) { + $entity->addLiteral($property, $literals[$key]->getValue(), $literals[$key]->getLanguage()); + } + } + } - return var_export($list_object); - */ + return $graph; } /** diff --git a/src/Serializer/RdfXmlEncoder.php b/src/Serializer/RdfXmlEncoder.php new file mode 100644 index 0000000..88bdbd1 --- /dev/null +++ b/src/Serializer/RdfXmlEncoder.php @@ -0,0 +1,66 @@ +serialise('rdf'); + } + + /** + * @param string $format + * + * @return bool + */ + public function supportsEncoding($format) + { + return RdfHeaders::FORMAT_RDF_XML === $format; + } + + /** + * @param string $data + * @param string $format + * @param array $context + * + * @return EasyRdf_Graph|mixed + * + * @throws \EasyRdf_Exception + */ + public function decode($data, $format, array $context = []) + { + $graph = new EasyRdf_Graph($_REQUEST['uri']); + $graph->parse($_REQUEST['data'], 'jsonld', 'http://openskos.org'); + + return $graph; + } + + /** + * @param string $format + * + * @return bool + */ + public function supportsDecoding($format) + { + return RdfHeaders::FORMAT_RDF_XML === $format; + } +} diff --git a/symfony.lock b/symfony.lock index 132c8cf..880161c 100644 --- a/symfony.lock +++ b/symfony.lock @@ -83,6 +83,12 @@ "justinrainbow/json-schema": { "version": "5.2.8" }, + "ml/iri": { + "version": "1.1.4" + }, + "ml/json-ld": { + "version": "1.1.0" + }, "monolog/monolog": { "version": "1.24.0" }, From 8fc059ed6eced84ea07e33a28058a4a1660edfe9 Mon Sep 17 00:00:00 2001 From: Ben Hillier Date: Wed, 29 May 2019 15:26:19 +0200 Subject: [PATCH 14/20] Updated Encoders. Added Unittest of RDF Types --- config/services.yaml | 5 +- spec/EasyRdf/TripleFactorySpec.php | 25 ++-- spec/EasyRdf/example.ttl | 33 ++++-- src/EasyRdf/EasyRdfClient.php | 8 -- src/EasyRdf/TripleFactory.php | 10 +- src/Institution/Institution.php | 50 +++++--- src/Rdf/Literal.php | 8 +- src/Rdf/Triple.php | 40 +++++-- src/Rdf/TripleSet.php | 3 + src/Serializer/JsonLdEncoder.php | 58 ---------- src/Serializer/ListResponseNormalizer.php | 30 ++--- src/Serializer/RdfEncoder.php | 134 ++++++++++++++++++++++ src/Serializer/RdfXmlEncoder.php | 66 ----------- src/Serializer/TripleNormalizer.php | 98 ++++++++++++++++ src/Serializer/TripleSetNormalizer.php | 97 ++++++++++++++++ 15 files changed, 452 insertions(+), 213 deletions(-) create mode 100644 src/Rdf/TripleSet.php delete mode 100644 src/Serializer/JsonLdEncoder.php create mode 100644 src/Serializer/RdfEncoder.php delete mode 100644 src/Serializer/RdfXmlEncoder.php create mode 100644 src/Serializer/TripleNormalizer.php create mode 100644 src/Serializer/TripleSetNormalizer.php diff --git a/config/services.yaml b/config/services.yaml index 0a1a9b0..a7f5a9f 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -20,10 +20,7 @@ services: arguments: ['@Symfony\Component\Serializer\Normalizer\ObjectNormalizer'] - App\Serializer\JsonLdEncoder: - tags: ['serializer.encoder'] - - App\Serializer\RdfXmlEncoder: + App\Serializer\RdfEncoder: tags: ['serializer.encoder'] App\Rest\ArgumentResolver\ApiRequestResolver: diff --git a/spec/EasyRdf/TripleFactorySpec.php b/spec/EasyRdf/TripleFactorySpec.php index e587854..63395c6 100644 --- a/spec/EasyRdf/TripleFactorySpec.php +++ b/spec/EasyRdf/TripleFactorySpec.php @@ -19,24 +19,29 @@ public function it_can_transform_easy_rdf_graph_to_triples() $this::triplesFromGraph($graph)->shouldBeTriples([ new Triple( - new Iri('http://memorix.io/skos/#russian'), + new Iri('http://tenant/0e2a9a87-ea19-4704-90e6-a75b3baba80a'), new Iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), - new Iri('http://www.w3.org/2004/02/skos/core#Concept') + new Iri('http://www.w3.org/ns/org#FormalOrganization') ), new Triple( - new Iri('http://memorix.io/skos/#russian'), + new Iri('http://tenant/0e2a9a87-ea19-4704-90e6-a75b3baba80a'), + new Iri('http://openskos.org/xmlns#code'), + new Literal('pic') + ), + new Triple( + new Iri('http://tenant/0e2a9a87-ea19-4704-90e6-a75b3baba80a'), new Iri('http://www.w3.org/2004/02/skos/core#prefLabel'), - new Literal('Russian') + new Literal('Doe, John', 'nl') ), new Triple( - new Iri('http://memorix.io/skos/#dutch'), - new Iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), - new Iri('http://www.w3.org/2004/02/skos/core#Concept') + new Iri('http://tenant/0e2a9a87-ea19-4704-90e6-a75b3baba80a'), + new Iri('http://openskos.org/xmlns#disableSearchInOtherTenants'), + new Literal('false', null, Literal::TYPE_BOOL) ), new Triple( - new Iri('http://memorix.io/skos/#dutch'), - new Iri('http://www.w3.org/2004/02/skos/core#prefLabel'), - new Literal('Dutch') + new Iri('http://tenant/0e2a9a87-ea19-4704-90e6-a75b3baba80a'), + new Iri('http://purl.org/dc/terms/dateSubmitted'), + new Literal('2019-02-05T15:25:05+00:00', null, Literal::TYPE_DATETIME) ), ]); } diff --git a/spec/EasyRdf/example.ttl b/spec/EasyRdf/example.ttl index bb0f6f3..6b36bb9 100644 --- a/spec/EasyRdf/example.ttl +++ b/spec/EasyRdf/example.ttl @@ -1,12 +1,21 @@ -@base . -@prefix rdf: . -@prefix rdfs: . -@prefix skos: . - -<#russian> - a skos:Concept ; - skos:prefLabel "Russian"@en . - -<#dutch> - a skos:Concept ; - skos:prefLabel "Dutch"@en . \ No newline at end of file + + + #Resource + a ; + + #Language independent string + + "pic" ; + + #Language dependent string + + "Doe, John"@nl ; + + #Boolean + + "false"^^ ; + + + #DateTime + + "2019-02-05T15:25:05+00:00"^^ . diff --git a/src/EasyRdf/EasyRdfClient.php b/src/EasyRdf/EasyRdfClient.php index d8c079a..6922d6e 100644 --- a/src/EasyRdf/EasyRdfClient.php +++ b/src/EasyRdf/EasyRdfClient.php @@ -39,12 +39,4 @@ public function describe(SparqlQuery $query): array return TripleFactory::triplesFromGraph($graph); } -// public function replace($uri, $data) -// { -// $query = 'DELETE WHERE {<' . $uri . '> ?predicate ?object};'; -// $query .= PHP_EOL; -// $query .= 'INSERT DATA {' . $this->convertToTriples($data) . '}'; -// -// $this->update($query); -// } } diff --git a/src/EasyRdf/TripleFactory.php b/src/EasyRdf/TripleFactory.php index 59c42a3..807a05b 100644 --- a/src/EasyRdf/TripleFactory.php +++ b/src/EasyRdf/TripleFactory.php @@ -26,8 +26,14 @@ private static function arrayToRdfTerm(array $arr): ?RdfTerm } switch ($type) { - case 'uri': return new Iri($value); - case 'literal': return new Literal($value, $arr['lang'] ?? 'en'); + case 'uri': + return new Iri($value); + case 'literal': + return new Literal( + $value, + $arr['lang'] ?? null, + $arr['datatype'] ?? null + ); } return null; diff --git a/src/Institution/Institution.php b/src/Institution/Institution.php index 3ba7de6..2bfbd0f 100644 --- a/src/Institution/Institution.php +++ b/src/Institution/Institution.php @@ -5,12 +5,14 @@ namespace App\Institution; use App\Ontology\OpenSkos; +use App\Ontology\Rdf; use App\Ontology\VCard; use App\Rdf\Iri; use App\Rdf\Literal; use App\Rdf\Triple; +use App\Rdf\TripleSet; -final class Institution +final class Institution implements TripleSet { const code = 'code'; const name = 'name'; @@ -23,6 +25,8 @@ final class Institution const countryName = 'countryName'; const enableStatusesSystem = 'enableStatusesSystem'; const enableSkosXl = 'enableSkosXl'; + const type = 'type'; + const disableSearchInOtherTenants = 'disableSearchInOtherTenants'; /** * @var string[] @@ -30,6 +34,7 @@ final class Institution private static $mapping = [ self::code => OpenSkos::CODE, self::name => OpenSkos::NAME, + self::disableSearchInOtherTenants => OpenSkos::DISABLESEARCHINOTERTENANTS, self::organisationUnit => VCard::ORGUNIT, self::email => VCard::EMAIL, self::website => OpenSkos::WEBPAGE, @@ -39,6 +44,7 @@ final class Institution self::countryName => VCard::COUNTRY, self::enableStatusesSystem => OpenSkos::ENABLESTATUSSESSYSTEMS, self::enableSkosXl => OpenSkos::ENABLESKOSXL, + self::type => Rdf::TYPE, ]; /** @@ -46,10 +52,15 @@ final class Institution */ private $subject; + /** + * @var Triple[] + */ + private $triples = []; + /** * @var Literal[] */ - private $literals = []; + private $properties = []; public function __construct(Iri $subject) { @@ -79,7 +90,7 @@ public function getSubject(): Iri */ public function getCode(): ?Literal { - return $this->literals[self::code] ?? null; + return $this->properties[self::code] ?? null; } /** @@ -87,12 +98,12 @@ public function getCode(): ?Literal */ public function getWebsite(): ?Literal { - return $this->literals[self::website] ?? null; + return $this->properties[self::website] ?? null; } public function count(): int { - return count($this->literals); + return count($this->properties); } /** @@ -104,7 +115,7 @@ public function count(): int public static function fromTriples(Iri $subject, array $triples): Institution { $invMapping = array_flip(self::$mapping); - $literals = []; + $properties = []; foreach ($triples as $triple) { // Skip unrelated triples if ($triple->getSubject()->getUri() !== $subject->getUri()) { @@ -118,22 +129,17 @@ public static function fromTriples(Iri $subject, array $triples): Institution } $object = $triple->getObject(); - // Skip non-literals. TODO: throw an exception? + /* + // Skip non-properties. TODO: throw an exception? if (!$object instanceof Literal) { continue; } - $literals[$property] = $object; - - /* TODO: Add Resource when needed - if (!$object instanceof Iri) { - continue; - } - $resources[$property] = $object; - */ + */ + $properties[$property] = $object; } $obj = new self($subject); - $obj->literals = $literals; + $obj->properties = $properties; return $obj; } @@ -141,8 +147,16 @@ public static function fromTriples(Iri $subject, array $triples): Institution /** * @return Literal[] */ - public function getLiterals(): array + public function getProperties(): array + { + return $this->properties; + } + + /** + * @return Triple[] + */ + public function triples(): array { - return $this->literals; + return $this->triples; } } diff --git a/src/Rdf/Literal.php b/src/Rdf/Literal.php index eb2f30f..95373d4 100644 --- a/src/Rdf/Literal.php +++ b/src/Rdf/Literal.php @@ -5,7 +5,7 @@ class Literal implements RdfTerm { const TYPE_DATETIME = 'http://www.w3.org/2001/XMLSchema#dateTime'; - const TYPE_BOOL = 'http://www.w3.org/2001/XMLSchema#boolean'; + const TYPE_BOOL = 'http://www.w3.org/2001/XMLSchema#bool'; const TYPE_STRING = 'http://www.w3.org/2001/XMLSchema#string'; /** @@ -30,10 +30,10 @@ class Literal implements RdfTerm * TODO: Or make Typed Literals. Such as StringLiteral, DateTypeLiteral * * @param string $value - * @param string $language - * @param string $type + * @param mixed $language + * @param mixed $type */ - public function __construct(string $value, string $language = 'en', string $type = self::TYPE_STRING) + public function __construct(string $value, $language = null, $type = null) { $this->value = $value; $this->language = $language; diff --git a/src/Rdf/Triple.php b/src/Rdf/Triple.php index 4bc14fc..c82343b 100644 --- a/src/Rdf/Triple.php +++ b/src/Rdf/Triple.php @@ -60,20 +60,44 @@ public function getObject(): RdfTerm public function __toString(): string { if ($this->object instanceof Iri) { - return sprintf( + $retVal = sprintf( '<%s> <%s> <%s>', $this->subject->getUri(), $this->predicate->getUri(), $this->object->getUri() ); + + return $retVal; } elseif ($this->object instanceof Literal) { - return sprintf( - '<%s> <%s> "%s"@%s', - $this->subject->getUri(), - $this->predicate->getUri(), - $this->object->getValue(), - $this->object->getLanguage() - ); + $type = $this->object->getType(); + $lang = $this->object->getLanguage(); + + if (isset($type)) { + $retVal = sprintf( + '<%s> <%s> "%s"^^<%s>', + $this->subject->getUri(), + $this->predicate->getUri(), + $this->object->getValue(), + $type + ); + } elseif (isset($lang)) { + $retVal = sprintf( + '<%s> <%s> "%s"@%s', + $this->subject->getUri(), + $this->predicate->getUri(), + $this->object->getValue(), + $lang + ); + } else { + $retVal = sprintf( + '<%s> <%s> "%s"', + $this->subject->getUri(), + $this->predicate->getUri(), + $this->object->getValue() + ); + } + + return $retVal; } throw new \LogicException('Object must be either Iri or Literal'); diff --git a/src/Rdf/TripleSet.php b/src/Rdf/TripleSet.php new file mode 100644 index 0000000..174d7fd --- /dev/null +++ b/src/Rdf/TripleSet.php @@ -0,0 +1,3 @@ +serialise('jsonld'); - } - - /** - * @param string $format - * - * @return bool - */ - public function supportsEncoding($format) - { - return RdfHeaders::FORMAT_JSON_LD === $format; - } - - /** - * @param string $data - * @param string $format - * @param array $context - * - * @return EasyRdf_Graph|mixed - * - * @throws \EasyRdf_Exception - */ - public function decode($data, $format, array $context = []) - { - $graph = new EasyRdf_Graph($_REQUEST['uri']); - $graph->parse($_REQUEST['data'], 'jsonld', 'http://openskos.org'); - - return $graph; - } - - /** - * @param string $format - * - * @return bool - */ - public function supportsDecoding($format) - { - return RdfHeaders::FORMAT_JSON_LD === $format; - } -} diff --git a/src/Serializer/ListResponseNormalizer.php b/src/Serializer/ListResponseNormalizer.php index 145d531..fe14b81 100644 --- a/src/Serializer/ListResponseNormalizer.php +++ b/src/Serializer/ListResponseNormalizer.php @@ -4,8 +4,12 @@ namespace App\Serializer; +use App\Ontology\OpenSkos; +use App\Rdf\Literal; +use App\Rdf\Iri; use App\Rest\ListResponse; use EasyRdf_Graph; +use EasyRdf_Literal_Boolean; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; @@ -32,31 +36,11 @@ public function __construct(ObjectNormalizer $normalizer) /** * {@inheritdoc} + * @param ListResponse $object */ - public function normalize($list_object, $format = null, array $context = []) + public function normalize($object, $format = null, array $context = []) { - // A listing of artist - //$uri = sprintf("%s%s", self::RKD_RECORDSEARCH, $searchQuery); - - $graph = new EasyRdf_Graph('http://openskos.org'); - - $OSEntityCollection = $list_object->getDocs(); - - foreach ($OSEntityCollection as $osEntity) { - $subject = $osEntity->getSubject()->getUri(); - - $entity = $graph->resource($subject, 'rdf:Description'); - - $mapping = $osEntity->getMapping(); - $literals = $osEntity->getLiterals(); - foreach ($mapping as $key => $property) { - if (isset($literals[$key])) { - $entity->addLiteral($property, $literals[$key]->getValue(), $literals[$key]->getLanguage()); - } - } - } - - return $graph; + return $object->getDocs(); } /** diff --git a/src/Serializer/RdfEncoder.php b/src/Serializer/RdfEncoder.php new file mode 100644 index 0000000..dfa1dd1 --- /dev/null +++ b/src/Serializer/RdfEncoder.php @@ -0,0 +1,134 @@ +format2EasyRdfFormat($format); + + $graph = $this->arrayToEasyRdfGraph($data); + + return $graph->serialise($easyRdfFormat); + } + + /** + * @param string $format + * + * @return bool + */ + public function supportsEncoding($format) + { + return in_array($format, [RdfHeaders::FORMAT_JSON_LD, RdfHeaders::FORMAT_RDF_XML]); + } + + /** + * @param string $data + * @param string $format + * @param array $context + * + * @return EasyRdf_Graph|mixed + * + * @throws \EasyRdf_Exception + */ + public function decode($data, $format, array $context = []) + { + $easyRdfFormat = $this->format2EasyRdfFormat($format); + $graph = new EasyRdf_Graph($_REQUEST['uri']); + $graph->parse($_REQUEST['data'], $easyRdfFormat, 'http://openskos.org'); + + return $graph; + } + + /** + * @param string $format + * + * @return bool + */ + public function supportsDecoding($format) + { + return in_array($format, [RdfHeaders::FORMAT_JSON_LD, RdfHeaders::FORMAT_RDF_XML]); + } + + private function arrayToEasyRdfGraph($data) + { + $graph = new EasyRdf_Graph('http://openskos.org'); + \EasyRdf_Namespace::set('openskos', OpenSkos::NAME_SPACE); + + $OSEntityCollection = $data; + + foreach ($OSEntityCollection as $osEntity) { + $subject = $osEntity->getSubject()->getUri(); + + $entity = $graph->resource($subject, 'rdf:Description'); + + $mapping = $osEntity->getMapping(); + $properties = $osEntity->getProperties(); + foreach ($mapping as $key => $property) { + if (isset($properties[$key])) { + if ($properties[$key] instanceof Literal) { + if (null === $properties[$key]->getType()) { + $entity->addLiteral( + $property, + $properties[$key]->getValue(), + $properties[$key]->getLanguage(), + ); + } elseif (\App\Rdf\Literal::TYPE_BOOL === $properties[$key]->getType()) { + $res = new EasyRdf_Literal_Boolean($properties[$key]->getValue()); + $entity->add($property, $res); + } else { + $entity->addLiteral( + $property, + $properties[$key]->getValue(), + $properties[$key]->getLanguage(), + ); + } + } elseif ($properties[$key] instanceof Iri) { + $entity->addResource($property, $properties[$key]->getUri()); + } + } + } + } + + return $graph; + } +} diff --git a/src/Serializer/RdfXmlEncoder.php b/src/Serializer/RdfXmlEncoder.php deleted file mode 100644 index 88bdbd1..0000000 --- a/src/Serializer/RdfXmlEncoder.php +++ /dev/null @@ -1,66 +0,0 @@ -serialise('rdf'); - } - - /** - * @param string $format - * - * @return bool - */ - public function supportsEncoding($format) - { - return RdfHeaders::FORMAT_RDF_XML === $format; - } - - /** - * @param string $data - * @param string $format - * @param array $context - * - * @return EasyRdf_Graph|mixed - * - * @throws \EasyRdf_Exception - */ - public function decode($data, $format, array $context = []) - { - $graph = new EasyRdf_Graph($_REQUEST['uri']); - $graph->parse($_REQUEST['data'], 'jsonld', 'http://openskos.org'); - - return $graph; - } - - /** - * @param string $format - * - * @return bool - */ - public function supportsDecoding($format) - { - return RdfHeaders::FORMAT_RDF_XML === $format; - } -} diff --git a/src/Serializer/TripleNormalizer.php b/src/Serializer/TripleNormalizer.php new file mode 100644 index 0000000..14fc5b9 --- /dev/null +++ b/src/Serializer/TripleNormalizer.php @@ -0,0 +1,98 @@ +normalizer = $normalizer; + } + + /** + * {@inheritdoc} + * @param TripleSet $object + */ + public function normalize($object, $format = null, array $context = []) + { + return $object->triples(); + + // A listing of artist + //$uri = sprintf("%s%s", self::RKD_RECORDSEARCH, $searchQuery); + +// $graph = new EasyRdf_Graph('http://openskos.org'); +// \EasyRdf_Namespace::set('openskos', OpenSkos::NAME_SPACE); +// +// $OSEntityCollection = $listObject->getDocs(); +// +// foreach ($OSEntityCollection as $osEntity) { +// $subject = $osEntity->getSubject()->getUri(); +// +// $entity = $graph->resource($subject, 'rdf:Description'); +// +// $mapping = $osEntity->getMapping(); +// $properties = $osEntity->getProperties(); +// foreach ($mapping as $key => $property) { +// if (isset($properties[$key])) { +// if ($properties[$key] instanceof Literal) { +// if (null === $properties[$key]->getType()) { +// $entity->addLiteral( +// $property, +// $properties[$key]->getValue(), +// $properties[$key]->getLanguage(), +// ); +// } elseif (\App\Rdf\Literal::TYPE_BOOL === $properties[$key]->getType()) { +// $res = new EasyRdf_Literal_Boolean($properties[$key]->getValue()); +// $entity->add($property, $res); +// } else { +// $entity->addLiteral( +// $property, +// $properties[$key]->getValue(), +// $properties[$key]->getLanguage(), +// ); +// } +// } elseif ($properties[$key] instanceof Iri) { +// $entity->addResource($property, $properties[$key]->getUri()); +// } +// } +// } +// } +// +// return $graph; + } + + /** + * {@inheritdoc} + */ + public function supportsNormalization($data, $format = null, array $context = []) + { + return $data instanceof TripleSet; + } +} diff --git a/src/Serializer/TripleSetNormalizer.php b/src/Serializer/TripleSetNormalizer.php new file mode 100644 index 0000000..30dacda --- /dev/null +++ b/src/Serializer/TripleSetNormalizer.php @@ -0,0 +1,97 @@ +normalizer = $normalizer; + } + + /** + * {@inheritdoc} + * @param ListResponse $object + */ + public function normalize($object, $format = null, array $context = []) + { + return $object->getDocs(); + + // A listing of artist + //$uri = sprintf("%s%s", self::RKD_RECORDSEARCH, $searchQuery); + +// $graph = new EasyRdf_Graph('http://openskos.org'); +// \EasyRdf_Namespace::set('openskos', OpenSkos::NAME_SPACE); +// +// $OSEntityCollection = $listObject->getDocs(); +// +// foreach ($OSEntityCollection as $osEntity) { +// $subject = $osEntity->getSubject()->getUri(); +// +// $entity = $graph->resource($subject, 'rdf:Description'); +// +// $mapping = $osEntity->getMapping(); +// $properties = $osEntity->getProperties(); +// foreach ($mapping as $key => $property) { +// if (isset($properties[$key])) { +// if ($properties[$key] instanceof Literal) { +// if (null === $properties[$key]->getType()) { +// $entity->addLiteral( +// $property, +// $properties[$key]->getValue(), +// $properties[$key]->getLanguage(), +// ); +// } elseif (\App\Rdf\Literal::TYPE_BOOL === $properties[$key]->getType()) { +// $res = new EasyRdf_Literal_Boolean($properties[$key]->getValue()); +// $entity->add($property, $res); +// } else { +// $entity->addLiteral( +// $property, +// $properties[$key]->getValue(), +// $properties[$key]->getLanguage(), +// ); +// } +// } elseif ($properties[$key] instanceof Iri) { +// $entity->addResource($property, $properties[$key]->getUri()); +// } +// } +// } +// } +// +// return $graph; + } + + /** + * {@inheritdoc} + */ + public function supportsNormalization($data, $format = null, array $context = []) + { + return $data instanceof ListResponse; + } +} From 7a424c2d4545afe43bac884e2ccde353b1db29fd Mon Sep 17 00:00:00 2001 From: Ben Hillier Date: Mon, 3 Jun 2019 18:03:27 +0200 Subject: [PATCH 15/20] #39331. Refactored Institution collection to TripleSets --- config/packages/databases.yaml | 6 +- spec/EasyRdf/TripleFactorySpec.php | 4 +- spec/Serializer/RdfEncoderSpec.php | 39 +++++++++ spec/Serializer/RdfTestEncoderSpec.php | 15 ++++ src/Institution/Institution.php | 81 +----------------- src/Rdf/TripleSet.php | 100 ++++++++++++++++++++++ src/Serializer/ListResponseNormalizer.php | 1 - src/Serializer/RdfTestEncoder.php | 7 ++ src/Serializer/TripleNormalizer.php | 12 +-- src/Serializer/TripleSetNormalizer.php | 9 +- 10 files changed, 180 insertions(+), 94 deletions(-) create mode 100644 spec/Serializer/RdfEncoderSpec.php create mode 100644 spec/Serializer/RdfTestEncoderSpec.php create mode 100644 src/Serializer/RdfTestEncoder.php diff --git a/config/packages/databases.yaml b/config/packages/databases.yaml index a4d6f9c..bc69147 100644 --- a/config/packages/databases.yaml +++ b/config/packages/databases.yaml @@ -1,3 +1,5 @@ parameters: - query_uri: 'http://192.168.56.10:3030/beg-openskos-production/query' - update_uri: 'http://192.168.56.10:3030/beg-openskos-production/update' + #query_uri: 'http://192.168.56.10:3030/beg-openskos-production/query' + #update_uri: 'http://192.168.56.10:3030/beg-openskos-production/update' + query_uri: 'http://jena-01.pictura-hosting.nl:3030/openskos-beg-test/query' + update_uri: 'http://jena-01.pictura-hosting.nl:3030/openskos-beg-test/update' diff --git a/spec/EasyRdf/TripleFactorySpec.php b/spec/EasyRdf/TripleFactorySpec.php index 63395c6..ad86639 100644 --- a/spec/EasyRdf/TripleFactorySpec.php +++ b/spec/EasyRdf/TripleFactorySpec.php @@ -17,7 +17,9 @@ public function it_can_transform_easy_rdf_graph_to_triples() $graph = new EasyRdf_Graph(); $graph->parse($graphString, 'turtle'); - $this::triplesFromGraph($graph)->shouldBeTriples([ + $testData = $this::triplesFromGraph($graph); + + $testData->shouldBeTriples([ new Triple( new Iri('http://tenant/0e2a9a87-ea19-4704-90e6-a75b3baba80a'), new Iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), diff --git a/spec/Serializer/RdfEncoderSpec.php b/spec/Serializer/RdfEncoderSpec.php new file mode 100644 index 0000000..67c1335 --- /dev/null +++ b/spec/Serializer/RdfEncoderSpec.php @@ -0,0 +1,39 @@ +shouldHaveType(RdfEncoder::class); + } + + public function it_can_serialise_triple_stores() + { + $graphString = file_get_contents(__DIR__.'/../EasyRdf/example.ttl'); + $graph = new EasyRdf_Graph(); + $graph->parse($graphString, 'turtle'); + + + $testData = TripleFactory::triplesFromGraph($graph); + + $graphUri = $testData[0]->getSubject()->getUri(); + + $institutions = Institution::fromTriples(new Iri($graphUri), $testData); + $list = new ListResponse($institutions, count($testData), 0); + + //$res = $serializer->serialize($list->getDocs(), 'json', []); + + $output = $this->encode($list->getDocs(), 'rdf', []); + } +} diff --git a/spec/Serializer/RdfTestEncoderSpec.php b/spec/Serializer/RdfTestEncoderSpec.php new file mode 100644 index 0000000..80b0473 --- /dev/null +++ b/spec/Serializer/RdfTestEncoderSpec.php @@ -0,0 +1,15 @@ +shouldHaveType(RdfTestEncoder::class); + } +} diff --git a/src/Institution/Institution.php b/src/Institution/Institution.php index 2bfbd0f..eef9d95 100644 --- a/src/Institution/Institution.php +++ b/src/Institution/Institution.php @@ -12,7 +12,7 @@ use App\Rdf\Triple; use App\Rdf\TripleSet; -final class Institution implements TripleSet +final class Institution extends TripleSet { const code = 'code'; const name = 'name'; @@ -47,20 +47,6 @@ final class Institution implements TripleSet self::type => Rdf::TYPE, ]; - /** - * @var Iri - */ - private $subject; - - /** - * @var Triple[] - */ - private $triples = []; - - /** - * @var Literal[] - */ - private $properties = []; public function __construct(Iri $subject) { @@ -75,15 +61,7 @@ public static function getMapping(): array return self::$mapping; } - //TODO: Generate getters. - /** - * @return Iri - */ - public function getSubject(): Iri - { - return $this->subject; - } /** * @return Literal|null @@ -101,62 +79,5 @@ public function getWebsite(): ?Literal return $this->properties[self::website] ?? null; } - public function count(): int - { - return count($this->properties); - } - - /** - * @param Iri $subject - * @param Triple[] $triples - * - * @return Institution - */ - public static function fromTriples(Iri $subject, array $triples): Institution - { - $invMapping = array_flip(self::$mapping); - $properties = []; - foreach ($triples as $triple) { - // Skip unrelated triples - if ($triple->getSubject()->getUri() !== $subject->getUri()) { - continue; - } - - $property = $invMapping[$triple->getPredicate()->getUri()] ?? null; - // Skip unknown properties - if (null === $property) { - continue; - } - - $object = $triple->getObject(); - /* - // Skip non-properties. TODO: throw an exception? - if (!$object instanceof Literal) { - continue; - } - */ - $properties[$property] = $object; - } - - $obj = new self($subject); - $obj->properties = $properties; - - return $obj; - } - - /** - * @return Literal[] - */ - public function getProperties(): array - { - return $this->properties; - } - /** - * @return Triple[] - */ - public function triples(): array - { - return $this->triples; - } } diff --git a/src/Rdf/TripleSet.php b/src/Rdf/TripleSet.php index 174d7fd..13b499f 100644 --- a/src/Rdf/TripleSet.php +++ b/src/Rdf/TripleSet.php @@ -1,3 +1,103 @@ subject; + } + + public function count(): int + { + return count($this->properties); + } + + /** + * @return Triple[] + */ + abstract public static function getMapping(): array; + + /** + * @param Iri $subject + * @param Triple[] $triples + * + * @return Institution + */ + public static function fromTriples(Iri $subject, array $triples): TripleSet + { + + $class = get_called_class(); + + $invMapping = array_flip($class::getMapping()); + + /** + * var Literal[]. + */ + $properties = []; + + foreach ($triples as $triple) { + // Skip unrelated triples + if ($triple->getSubject()->getUri() !== $subject->getUri()) { + continue; + } + + $property = $invMapping[$triple->getPredicate()->getUri()] ?? null; + // Skip unknown properties + if (null === $property) { + continue; + } + + $object = $triple->getObject(); + $properties[$property] = $object; + } + + $obj = new $class($subject); + $obj->properties = $properties; + + return $obj; + } + + + /** + * @return Literal[] + */ + public function getProperties(): array + { + return $this->properties; + } + + /** + * @return Triple[] + */ + public function triples(): array + { + return $this->triples; + } + +} diff --git a/src/Serializer/ListResponseNormalizer.php b/src/Serializer/ListResponseNormalizer.php index fe14b81..46d3e98 100644 --- a/src/Serializer/ListResponseNormalizer.php +++ b/src/Serializer/ListResponseNormalizer.php @@ -36,7 +36,6 @@ public function __construct(ObjectNormalizer $normalizer) /** * {@inheritdoc} - * @param ListResponse $object */ public function normalize($object, $format = null, array $context = []) { diff --git a/src/Serializer/RdfTestEncoder.php b/src/Serializer/RdfTestEncoder.php new file mode 100644 index 0000000..f96e8d6 --- /dev/null +++ b/src/Serializer/RdfTestEncoder.php @@ -0,0 +1,7 @@ +triples(); + return [$object->getSubject()->getUri(), $object->getPredicate()->getUri(), (string) $object->getObject()]; // A listing of artist //$uri = sprintf("%s%s", self::RKD_RECORDSEARCH, $searchQuery); @@ -93,6 +93,6 @@ public function normalize($object, $format = null, array $context = []) */ public function supportsNormalization($data, $format = null, array $context = []) { - return $data instanceof TripleSet; + return $data instanceof Triple; } } diff --git a/src/Serializer/TripleSetNormalizer.php b/src/Serializer/TripleSetNormalizer.php index 30dacda..14fc5b9 100644 --- a/src/Serializer/TripleSetNormalizer.php +++ b/src/Serializer/TripleSetNormalizer.php @@ -8,13 +8,14 @@ use App\Ontology\Rdf; use App\Rdf\Literal; use App\Rdf\Iri; +use App\Rdf\TripleSet; use App\Rest\ListResponse; use EasyRdf_Graph; use EasyRdf_Literal_Boolean; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; -class ListResponseNormalizer implements NormalizerInterface +class TripleSetNormalizer implements NormalizerInterface { /** * EasyRdf is used an an intermediate format between the TripleStore and its serialised formats. @@ -37,11 +38,11 @@ public function __construct(ObjectNormalizer $normalizer) /** * {@inheritdoc} - * @param ListResponse $object + * @param TripleSet $object */ public function normalize($object, $format = null, array $context = []) { - return $object->getDocs(); + return $object->triples(); // A listing of artist //$uri = sprintf("%s%s", self::RKD_RECORDSEARCH, $searchQuery); @@ -92,6 +93,6 @@ public function normalize($object, $format = null, array $context = []) */ public function supportsNormalization($data, $format = null, array $context = []) { - return $data instanceof ListResponse; + return $data instanceof TripleSet; } } From b9ce9fe9b4361604e6cfa0d8b18c96679930f9e5 Mon Sep 17 00:00:00 2001 From: Ben Hillier Date: Mon, 3 Jun 2019 18:16:01 +0200 Subject: [PATCH 16/20] Removed unwanted class I should not have commited --- spec/Serializer/RdfTestEncoderSpec.php | 15 --------------- src/Serializer/RdfTestEncoder.php | 7 ------- 2 files changed, 22 deletions(-) delete mode 100644 spec/Serializer/RdfTestEncoderSpec.php delete mode 100644 src/Serializer/RdfTestEncoder.php diff --git a/spec/Serializer/RdfTestEncoderSpec.php b/spec/Serializer/RdfTestEncoderSpec.php deleted file mode 100644 index 80b0473..0000000 --- a/spec/Serializer/RdfTestEncoderSpec.php +++ /dev/null @@ -1,15 +0,0 @@ -shouldHaveType(RdfTestEncoder::class); - } -} diff --git a/src/Serializer/RdfTestEncoder.php b/src/Serializer/RdfTestEncoder.php deleted file mode 100644 index f96e8d6..0000000 --- a/src/Serializer/RdfTestEncoder.php +++ /dev/null @@ -1,7 +0,0 @@ - Date: Tue, 4 Jun 2019 10:07:29 +0200 Subject: [PATCH 17/20] Removed unit test I would never be able to get right --- spec/Serializer/RdfEncoderSpec.php | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/spec/Serializer/RdfEncoderSpec.php b/spec/Serializer/RdfEncoderSpec.php index 67c1335..81ab506 100644 --- a/spec/Serializer/RdfEncoderSpec.php +++ b/spec/Serializer/RdfEncoderSpec.php @@ -2,14 +2,8 @@ namespace spec\App\Serializer; -use App\Institution\Institution; -use App\Rdf\Iri; use App\Serializer\RdfEncoder; -use App\Rest\ListResponse; -use Symfony\Component\Serializer\Serializer; use PhpSpec\ObjectBehavior; -use App\EasyRdf\TripleFactory; -use EasyRdf_Graph; class RdfEncoderSpec extends ObjectBehavior { @@ -17,23 +11,4 @@ public function it_is_initializable() { $this->shouldHaveType(RdfEncoder::class); } - - public function it_can_serialise_triple_stores() - { - $graphString = file_get_contents(__DIR__.'/../EasyRdf/example.ttl'); - $graph = new EasyRdf_Graph(); - $graph->parse($graphString, 'turtle'); - - - $testData = TripleFactory::triplesFromGraph($graph); - - $graphUri = $testData[0]->getSubject()->getUri(); - - $institutions = Institution::fromTriples(new Iri($graphUri), $testData); - $list = new ListResponse($institutions, count($testData), 0); - - //$res = $serializer->serialize($list->getDocs(), 'json', []); - - $output = $this->encode($list->getDocs(), 'rdf', []); - } } From 58b6c952bbd1dfcd630e843b2a5bc45aa318aa3d Mon Sep 17 00:00:00 2001 From: Ben Hillier Date: Tue, 4 Jun 2019 11:15:28 +0200 Subject: [PATCH 18/20] Split up serialiser unit tests to individual types --- spec/Serializer/RdfEncoderSpec.php | 142 +++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/spec/Serializer/RdfEncoderSpec.php b/spec/Serializer/RdfEncoderSpec.php index 81ab506..8bbbe66 100644 --- a/spec/Serializer/RdfEncoderSpec.php +++ b/spec/Serializer/RdfEncoderSpec.php @@ -2,8 +2,13 @@ namespace spec\App\Serializer; +use App\Institution\Institution; +use App\Rdf\Iri; use App\Serializer\RdfEncoder; +use App\Rest\ListResponse; use PhpSpec\ObjectBehavior; +use App\EasyRdf\TripleFactory; +use EasyRdf_Graph; class RdfEncoderSpec extends ObjectBehavior { @@ -11,4 +16,141 @@ public function it_is_initializable() { $this->shouldHaveType(RdfEncoder::class); } + + public function it_can_serialise_strings() + { + $graphString = << "pic". +GRAPH_STRING; + $graph = new EasyRdf_Graph(); + $graph->parse($graphString, 'turtle'); + + $testData = TripleFactory::triplesFromGraph($graph); + + $graphUri = $testData[0]->getSubject()->getUri(); + + $institutions = [Institution::fromTriples(new Iri($graphUri), $testData)]; + $list = new ListResponse($institutions, count($testData), 0); + + $output = ($this->encode($list->getDocs(), 'rdf', [])); + + $expectedOutput = << + + + + + pic + + + + +RDF_BLOCK; + + $output->shouldBe($expectedOutput); + } + + /* + *This will fail until we build concepts, which do support language independen strings. So I've left it out for now + public function it_can_serialise_language_dependent_strings() + { + $graphString = << "Doe, John"@nl . +GRAPH_STRING; + $graph = new EasyRdf_Graph(); + $graph->parse($graphString, 'turtle'); + + $testData = TripleFactory::triplesFromGraph($graph); + + $graphUri = $testData[0]->getSubject()->getUri(); + + $institutions = [Institution::fromTriples(new Iri($graphUri), $testData)]; + $list = new ListResponse($institutions, count($testData), 0); + + $output = ($this->encode($list->getDocs(), 'rdf', [])); + + $expectedOutput = << + + + + + Doe, John + + + + +RDF_BLOCK; + + $output->shouldBe($expectedOutput); + } + */ + + public function it_can_serialise_resources() + { + $graphString = << a . +GRAPH_STRING; + $graph = new EasyRdf_Graph(); + $graph->parse($graphString, 'turtle'); + + $testData = TripleFactory::triplesFromGraph($graph); + + $graphUri = $testData[0]->getSubject()->getUri(); + + $institutions = [Institution::fromTriples(new Iri($graphUri), $testData)]; + $list = new ListResponse($institutions, count($testData), 0); + + $output = ($this->encode($list->getDocs(), 'rdf', [])); + + $expectedOutput = << + + + + + + + + + +RDF_BLOCK; + + $output->shouldBe($expectedOutput); + } + + public function it_can_serialise_booleans() + { + $graphString = << "false"^^ . +GRAPH_STRING; + $graph = new EasyRdf_Graph(); + $graph->parse($graphString, 'turtle'); + + $testData = TripleFactory::triplesFromGraph($graph); + + $graphUri = $testData[0]->getSubject()->getUri(); + + $institutions = [Institution::fromTriples(new Iri($graphUri), $testData)]; + $list = new ListResponse($institutions, count($testData), 0); + + $output = ($this->encode($list->getDocs(), 'rdf', [])); + + $expectedOutput = << + + + + + false + + + + +RDF_BLOCK; + + $output->shouldBe($expectedOutput); + } } From 8b633586f1e86534f28d3dc62187b243eb9b4fd5 Mon Sep 17 00:00:00 2001 From: Ben Hillier Date: Thu, 13 Jun 2019 15:48:05 +0200 Subject: [PATCH 19/20] #39335 Sets Level 1 and All sets --- config/packages/institution.yaml | 2 - config/packages/openskos.yaml | 3 + config/packages/set.yaml | 13 +++ config/routes/annotations.yaml | 4 + config/services.yaml | 5 +- src/Institution/Controller/Institution.php | 35 ++++++++ src/Institution/InstitutionRepository.php | 7 ++ .../Sparql/SparqlInstitutionRepository.php | 23 +++++ src/Rdf/SparqlQueryBuilder.php | 20 +++++ src/Rest/ScalarResponse.php | 35 ++++++++ src/Serializer/ScalarResponseNormalizer.php | 47 ++++++++++ src/Set/Controller/Set.php | 85 +++++++++++++++++++ src/Set/Set.php | 71 ++++++++++++++++ src/Set/SetRepository.php | 32 +++++++ src/Set/Sparql/SparqlSetRepository.php | 83 ++++++++++++++++++ 15 files changed, 461 insertions(+), 4 deletions(-) create mode 100644 config/packages/set.yaml create mode 100644 src/Rest/ScalarResponse.php create mode 100644 src/Serializer/ScalarResponseNormalizer.php create mode 100644 src/Set/Controller/Set.php create mode 100644 src/Set/Set.php create mode 100644 src/Set/SetRepository.php create mode 100644 src/Set/Sparql/SparqlSetRepository.php diff --git a/config/packages/institution.yaml b/config/packages/institution.yaml index dd974b3..5ac4aad 100644 --- a/config/packages/institution.yaml +++ b/config/packages/institution.yaml @@ -8,7 +8,5 @@ services: resource: '../../src/Institution/Controller/*' tags: ['controller.service_arguments'] - App\Institution\Sparql\SparqlInstitutionRepository: ~ - App\Institution\InstitutionRepository: '@App\Institution\Sparql\SparqlInstitutionRepository' diff --git a/config/packages/openskos.yaml b/config/packages/openskos.yaml index ceed2d7..09cce7a 100644 --- a/config/packages/openskos.yaml +++ b/config/packages/openskos.yaml @@ -18,3 +18,6 @@ services: App\Institution\Sparql\SparqlInstitutionRepository: arguments: ['@MyEasyRdfClient'] + + App\Set\Sparql\SparqlSetRepository: + arguments: ['@MyEasyRdfClient'] diff --git a/config/packages/set.yaml b/config/packages/set.yaml new file mode 100644 index 0000000..c79f72c --- /dev/null +++ b/config/packages/set.yaml @@ -0,0 +1,13 @@ +services: + # default configuration for services in *this* file + _defaults: + autowire: true # Automatically injects dependencies in your services. + autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. + + App\Set\Controller\: + resource: '../../src/Set/Controller/*' + tags: ['controller.service_arguments'] + + App\Set\SetRepository: '@App\Set\Sparql\SparqlSetRepository' + + diff --git a/config/routes/annotations.yaml b/config/routes/annotations.yaml index 825fbcc..399cfdb 100644 --- a/config/routes/annotations.yaml +++ b/config/routes/annotations.yaml @@ -8,3 +8,7 @@ healthcheck: institution: resource: ../../src/Institution/Controller type: annotation + +set: + resource: ../../src/Set/Controller + type: annotation diff --git a/config/services.yaml b/config/services.yaml index a7f5a9f..c75dd66 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -12,13 +12,14 @@ imports: services: # default configuration for services in *this* file - \App\Rdf\RdfClient: '@App\Institution\Sparql\SparqlInstitutionRepository' - App\Serializer\ListResponseNormalizer: tags: ['serializer.normalizer'] arguments: ['@Symfony\Component\Serializer\Normalizer\ObjectNormalizer'] + App\Serializer\ScalarResponseNormalizer: + tags: ['serializer.normalizer'] + arguments: ['@Symfony\Component\Serializer\Normalizer\ObjectNormalizer'] App\Serializer\RdfEncoder: tags: ['serializer.encoder'] diff --git a/src/Institution/Controller/Institution.php b/src/Institution/Controller/Institution.php index a27b55c..97d6a77 100644 --- a/src/Institution/Controller/Institution.php +++ b/src/Institution/Controller/Institution.php @@ -5,8 +5,13 @@ namespace App\Institution\Controller; use App\Institution\InstitutionRepository; +use App\Ontology\OpenSkos; +use App\Ontology\Org; use App\OpenSkos\ApiRequest; +use App\Rdf\Iri; use App\Rest\ListResponse; +use App\Rest\ScalarResponse; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Serializer\SerializerInterface; @@ -47,4 +52,34 @@ public function institutions(ApiRequest $apiRequest, InstitutionRepository $repo return $response; } + + /** + * @Route(path="/institution/{id}", methods={"GET"}) + * + * @param ApiRequest $apiRequest + * @param InstitutionRepository $repository + * + * @return Response + */ + public function institution(Request $request, ApiRequest $apiRequest, InstitutionRepository $repository): Response + { + $id = $request->get('id'); + + $institution = $repository->findBy( + new Iri(Org::FORMALORG), + new Iri(OpenSkos::CODE), + $id + ); + + $list = new ScalarResponse($institution); + + $res = $this->serializer->serialize($list, $apiRequest->getFormat()); + + $formatOut = $apiRequest->getReturnContentType(); + + $response = new Response($res, Response::HTTP_OK, []); + $response->headers->set('Content-Type', $formatOut); + + return $response; + } } diff --git a/src/Institution/InstitutionRepository.php b/src/Institution/InstitutionRepository.php index 275b3e2..9ff89d4 100644 --- a/src/Institution/InstitutionRepository.php +++ b/src/Institution/InstitutionRepository.php @@ -22,4 +22,11 @@ public function all(int $offset = 0, int $limit = 100): array; * @return Institution|null */ public function find(Iri $iri): ?Institution; + + /** + * @param Iri $iri + * + * @return Institution|null + */ + public function findBy(Iri $rdfType, Iri $predicate, string $object): array; } diff --git a/src/Institution/Sparql/SparqlInstitutionRepository.php b/src/Institution/Sparql/SparqlInstitutionRepository.php index 29ed87d..d6408dc 100644 --- a/src/Institution/Sparql/SparqlInstitutionRepository.php +++ b/src/Institution/Sparql/SparqlInstitutionRepository.php @@ -57,4 +57,27 @@ public function find(Iri $iri): ?Institution { throw new \RuntimeException('Not implemented'); } + + public function findBy(Iri $rdfType, Iri $predicate, string $object): array + { + $sparql = SparqlQueryBuilder::describeByTypeAndPredicate( + $rdfType, + $predicate, + $object + ); + $triples = $this->rdfClient->describe($sparql); + + //TODO: Move to separate helper class? + $groups = []; + foreach ($triples as $triple) { + $groups[$triple->getSubject()->getUri()][] = $triple; + } + + $res = []; + foreach ($groups as $iriString => $group) { + $res[] = Institution::fromTriples(new Iri($iriString), $group); + } + + return $res; + } } diff --git a/src/Rdf/SparqlQueryBuilder.php b/src/Rdf/SparqlQueryBuilder.php index 9b81859..329da78 100644 --- a/src/Rdf/SparqlQueryBuilder.php +++ b/src/Rdf/SparqlQueryBuilder.php @@ -23,4 +23,24 @@ public static function describeAllOfType( ) ); } + + public static function describeByTypeAndPredicate( + Iri $rdfType, + Iri $predicate, + string $object + ): SparqlQuery { + $queryString = << <%s>; + <%s> "%s" + } +QUERY_BY_TYPE_AND_PREDICATE; + + $queryString = sprintf($queryString, Rdf::TYPE, $rdfType, $predicate, $object); + + $retVal = new SparqlQuery($queryString); + + return $retVal; + } } diff --git a/src/Rest/ScalarResponse.php b/src/Rest/ScalarResponse.php new file mode 100644 index 0000000..e09ffb4 --- /dev/null +++ b/src/Rest/ScalarResponse.php @@ -0,0 +1,35 @@ +docs = $docs; + } + + /** + * @return array + */ + public function getDocs(): array + { + return $this->docs; + } +} diff --git a/src/Serializer/ScalarResponseNormalizer.php b/src/Serializer/ScalarResponseNormalizer.php new file mode 100644 index 0000000..d8b767e --- /dev/null +++ b/src/Serializer/ScalarResponseNormalizer.php @@ -0,0 +1,47 @@ +normalizer = $normalizer; + } + + /** + * {@inheritdoc} + */ + public function normalize($object, $format = null, array $context = []) + { + return $object->getDocs(); + } + + /** + * {@inheritdoc} + */ + public function supportsNormalization($data, $format = null, array $context = []) + { + return $data instanceof ScalarResponse; + } +} diff --git a/src/Set/Controller/Set.php b/src/Set/Controller/Set.php new file mode 100644 index 0000000..5d534de --- /dev/null +++ b/src/Set/Controller/Set.php @@ -0,0 +1,85 @@ +serializer = $serializer; + } + + /** + * @Route(path="/sets", methods={"GET"}) + * + * @param ApiRequest $apiRequest + * @param SetRepository $repository + * + * @return Response + */ + public function sets(ApiRequest $apiRequest, SetRepository $repository): Response + { + $sets = $repository->all($apiRequest->getOffset(), $apiRequest->getLimit()); + + $list = new ListResponse($sets, count($sets), $apiRequest->getOffset()); + + $res = $this->serializer->serialize($list, $apiRequest->getFormat()); + + $formatOut = $apiRequest->getReturnContentType(); + + $response = new Response($res, Response::HTTP_OK, []); + $response->headers->set('Content-Type', $formatOut); + + return $response; + } + + /** + * @Route(path="/set/{id}", methods={"GET"}) + * + * @param ApiRequest $apiRequest + * @param SetRepository $repository + * + * @return Response + */ + public function set(Request $request, ApiRequest $apiRequest, SetRepository $repository): Response + { + $id = $request->get('id'); + + $set = $repository->findBy( + new Iri(Org::FORMALORG), + new Iri(OpenSkos::CODE), + $id + ); + + $list = new ScalarResponse($set); + + $res = $this->serializer->serialize($list, $apiRequest->getFormat()); + + $formatOut = $apiRequest->getReturnContentType(); + + $response = new Response($res, Response::HTTP_OK, []); + $response->headers->set('Content-Type', $formatOut); + + return $response; + } +} diff --git a/src/Set/Set.php b/src/Set/Set.php new file mode 100644 index 0000000..52b8166 --- /dev/null +++ b/src/Set/Set.php @@ -0,0 +1,71 @@ + OpenSkos::ALLOW_OAI, + self::code => OpenSkos::CODE, + self::conceptBaseUri => OpenSkos::CONCEPTBASEURI, + self::oai_baseURL => OpenSkos::OAI_BASEURL, + self::tenant => OpenSkos::TENANT, + self::webpage => OpenSkos::WEBPAGE, + self::description => DcTerms::DESCRIPTION, + self::license => DcTerms::LICENSE, + self::publisher => DcTerms::PUBLISHER, + self::title => DC::TITLE, + ]; + + public function __construct(Iri $subject) + { + $this->subject = $subject; + } + + /** + * @return string[] + */ + public static function getMapping(): array + { + return self::$mapping; + } + + /** + * @return Literal|null + */ + public function getCode(): ?Literal + { + return $this->properties[self::code] ?? null; + } + + /** + * @return Literal|null + */ + public function getWebsite(): ?Literal + { + return $this->properties[self::website] ?? null; + } +} diff --git a/src/Set/SetRepository.php b/src/Set/SetRepository.php new file mode 100644 index 0000000..395a870 --- /dev/null +++ b/src/Set/SetRepository.php @@ -0,0 +1,32 @@ +rdfClient = $rdfClient; + } + + /** + * @param int $offset + * @param int $limit + * + * @return Set[] + */ + public function all(int $offset = 0, int $limit = 100): array + { + $sparql = SparqlQueryBuilder::describeAllOfType( + new Iri(Openskos::SET), + $offset, + $limit + ); + $triples = $this->rdfClient->describe($sparql); + + //TODO: Move to separate helper class? + $groups = []; + foreach ($triples as $triple) { + $groups[$triple->getSubject()->getUri()][] = $triple; + } + + $res = []; + foreach ($groups as $iriString => $group) { + $res[] = Set::fromTriples(new Iri($iriString), $group); + } + + return $res; + } + + public function find(Iri $iri): ?Set + { + throw new \RuntimeException('Not implemented'); + } + + public function findBy(Iri $rdfType, Iri $predicate, string $object): array + { + $sparql = SparqlQueryBuilder::describeByTypeAndPredicate( + $rdfType, + $predicate, + $object + ); + $triples = $this->rdfClient->describe($sparql); + + //TODO: Move to separate helper class? + $groups = []; + foreach ($triples as $triple) { + $groups[$triple->getSubject()->getUri()][] = $triple; + } + + $res = []; + foreach ($groups as $iriString => $group) { + $res[] = Set::fromTriples(new Iri($iriString), $group); + } + + return $res; + } +} From c6fc84b8f8ed18218578131278d7503d599951f1 Mon Sep 17 00:00:00 2001 From: Ben Hillier Date: Thu, 13 Jun 2019 17:05:23 +0200 Subject: [PATCH 20/20] #39336 Sets Level 2 --- src/Institution/Controller/Institution.php | 8 +++++++- src/Institution/Institution.php | 8 ++++++++ .../Sparql/SparqlInstitutionRepository.php | 17 ++++++++++++++++ src/Rdf/TripleSet.php | 20 ++++++++++++------- src/Rest/ScalarResponse.php | 6 +++--- src/Set/Controller/Set.php | 11 +++++++--- src/Set/Set.php | 13 ++++++++++-- src/Set/SetRepository.php | 10 +++++++++- src/Set/Sparql/SparqlSetRepository.php | 16 +++++++++++++++ 9 files changed, 92 insertions(+), 17 deletions(-) diff --git a/src/Institution/Controller/Institution.php b/src/Institution/Controller/Institution.php index 97d6a77..cf9b781 100644 --- a/src/Institution/Controller/Institution.php +++ b/src/Institution/Controller/Institution.php @@ -13,6 +13,7 @@ use App\Rest\ScalarResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Serializer\SerializerInterface; @@ -65,12 +66,17 @@ public function institution(Request $request, ApiRequest $apiRequest, Institutio { $id = $request->get('id'); - $institution = $repository->findBy( + $institution = $repository->findOneBy( new Iri(Org::FORMALORG), new Iri(OpenSkos::CODE), $id ); + + if (!$institution) { + throw new NotFoundHttpException("The institution $id could not be retreived."); + } + $list = new ScalarResponse($institution); $res = $this->serializer->serialize($list, $apiRequest->getFormat()); diff --git a/src/Institution/Institution.php b/src/Institution/Institution.php index eef9d95..5f1a683 100644 --- a/src/Institution/Institution.php +++ b/src/Institution/Institution.php @@ -62,6 +62,14 @@ public static function getMapping(): array } + /** + * @return string[] + */ + public function getLevel2Predicate() + { + //Institutions have no level 2 + return ''; + } /** * @return Literal|null diff --git a/src/Institution/Sparql/SparqlInstitutionRepository.php b/src/Institution/Sparql/SparqlInstitutionRepository.php index d6408dc..484fef5 100644 --- a/src/Institution/Sparql/SparqlInstitutionRepository.php +++ b/src/Institution/Sparql/SparqlInstitutionRepository.php @@ -80,4 +80,21 @@ public function findBy(Iri $rdfType, Iri $predicate, string $object): array return $res; } + + /** + * @param Iri $rdfType + * @param Iri $predicate + * @param string $object + * @return Institution|null + */ + public function findOneBy(Iri $rdfType, Iri $predicate, string $object): ?Institution + { + $objects = $this->findBy($rdfType, $predicate, $object); + if ($objects) { + return $objects[0]; + } + + return null; + } + } diff --git a/src/Rdf/TripleSet.php b/src/Rdf/TripleSet.php index 13b499f..3949441 100644 --- a/src/Rdf/TripleSet.php +++ b/src/Rdf/TripleSet.php @@ -6,7 +6,6 @@ abstract class TripleSet { - /** * @var Iri */ @@ -22,9 +21,6 @@ abstract class TripleSet */ protected $properties = []; - - - /** * @return Iri */ @@ -38,11 +34,24 @@ public function count(): int return count($this->properties); } + abstract public function getLevel2Predicate(); + /** * @return Triple[] */ abstract public static function getMapping(): array; + public function getLevel2Object(): ?Literal + { + $object = null; + $mappingKey = $this->getLevel2Predicate(); + if ($mappingKey) { + $object = $this->properties[$mappingKey]; + } + + return $object; + } + /** * @param Iri $subject * @param Triple[] $triples @@ -51,7 +60,6 @@ abstract public static function getMapping(): array; */ public static function fromTriples(Iri $subject, array $triples): TripleSet { - $class = get_called_class(); $invMapping = array_flip($class::getMapping()); @@ -83,7 +91,6 @@ public static function fromTriples(Iri $subject, array $triples): TripleSet return $obj; } - /** * @return Literal[] */ @@ -99,5 +106,4 @@ public function triples(): array { return $this->triples; } - } diff --git a/src/Rest/ScalarResponse.php b/src/Rest/ScalarResponse.php index e09ffb4..5e36e5a 100644 --- a/src/Rest/ScalarResponse.php +++ b/src/Rest/ScalarResponse.php @@ -17,12 +17,12 @@ final class ScalarResponse /** * ScalarResponse constructor. * - * @param array $docs + * @param $doc */ public function __construct( - array $docs + $doc ) { - $this->docs = $docs; + $this->docs = [$doc]; } /** diff --git a/src/Set/Controller/Set.php b/src/Set/Controller/Set.php index 5d534de..ba5d1aa 100644 --- a/src/Set/Controller/Set.php +++ b/src/Set/Controller/Set.php @@ -6,7 +6,6 @@ use App\Set\SetRepository; use App\Ontology\OpenSkos; -use App\Ontology\Org; use App\OpenSkos\ApiRequest; use App\Rdf\Iri; use App\Rest\ListResponse; @@ -15,6 +14,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Serializer\SerializerInterface; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; final class Set { @@ -65,12 +65,17 @@ public function set(Request $request, ApiRequest $apiRequest, SetRepository $rep { $id = $request->get('id'); - $set = $repository->findBy( - new Iri(Org::FORMALORG), + $set = $repository->findOneBy( + new Iri(OpenSkos::SET), new Iri(OpenSkos::CODE), $id ); + if (!$set) { + throw new NotFoundHttpException("The set $id could not be retreived."); + } + $l2Object = $set->getLevel2Object(); + $list = new ScalarResponse($set); $res = $this->serializer->serialize($list, $apiRequest->getFormat()); diff --git a/src/Set/Set.php b/src/Set/Set.php index 52b8166..d026813 100644 --- a/src/Set/Set.php +++ b/src/Set/Set.php @@ -28,11 +28,11 @@ final class Set extends TripleSet * @var string[] */ private static $mapping = [ - self::allow_oai => OpenSkos::ALLOW_OAI, + self::tenant => OpenSkos::TENANT, self::code => OpenSkos::CODE, + self::allow_oai => OpenSkos::ALLOW_OAI, self::conceptBaseUri => OpenSkos::CONCEPTBASEURI, self::oai_baseURL => OpenSkos::OAI_BASEURL, - self::tenant => OpenSkos::TENANT, self::webpage => OpenSkos::WEBPAGE, self::description => DcTerms::DESCRIPTION, self::license => DcTerms::LICENSE, @@ -53,6 +53,15 @@ public static function getMapping(): array return self::$mapping; } + /** + * @return string + */ + public function getLevel2Predicate() + { + return self::tenant; + } + + /** * @return Literal|null */ diff --git a/src/Set/SetRepository.php b/src/Set/SetRepository.php index 395a870..a37d00d 100644 --- a/src/Set/SetRepository.php +++ b/src/Set/SetRepository.php @@ -26,7 +26,15 @@ public function find(Iri $iri): ?Set; /** * @param Iri $iri * - * @return Set|null + * @return array */ public function findBy(Iri $rdfType, Iri $predicate, string $object): array; + + + /** + * @param Iri $iri + * + * @return Set|null + */ + public function findOneBy(Iri $rdfType, Iri $predicate, string $object): ?Set; } diff --git a/src/Set/Sparql/SparqlSetRepository.php b/src/Set/Sparql/SparqlSetRepository.php index 8b3bcc0..7c611c3 100644 --- a/src/Set/Sparql/SparqlSetRepository.php +++ b/src/Set/Sparql/SparqlSetRepository.php @@ -80,4 +80,20 @@ public function findBy(Iri $rdfType, Iri $predicate, string $object): array return $res; } + + /** + * @param Iri $rdfType + * @param Iri $predicate + * @param string $object + * @return Set|null + */ + public function findOneBy(Iri $rdfType, Iri $predicate, string $object): ?Set + { + $objects = $this->findBy($rdfType, $predicate, $object); + if ($objects) { + return $objects[0]; + } + + return null; + } }