diff --git a/.env b/.env new file mode 100644 index 0000000..0a1c125 --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +COMPOSE_PROJECT_NAME=openskosapi +COMPOSE_FILE=docker/docker-compose.yml \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3734df6..3e71bfb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,22 @@ -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 + + +###> 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/README.md b/README.md index a5a5b45..b98e836 100644 --- a/README.md +++ b/README.md @@ -1,2 +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/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..29e3d51 --- /dev/null +++ b/composer.json @@ -0,0 +1,72 @@ +{ + "type": "project", + "license": "proprietary", + "require": { + "php": "^7.1.3", + "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.*", + "symfony/flex": "^1.1", + "symfony/framework-bundle": "4.2.*", + "symfony/property-access": "4.2.*", + "symfony/serializer": "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.*" + } + }, + "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", + "vimeo/psalm": "^3.2" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..8a8f020 --- /dev/null +++ b/composer.lock @@ -0,0 +1,5412 @@ +{ + "_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#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "c488b9f138f0af69b914f0a0d8c032ee", + "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": "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": "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", + "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": "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", + "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/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", + "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/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", + "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/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", + "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": [ + { + "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", + "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": "doctrine/instantiator", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "a2c590166b2133a4633738648b6b064edae0814a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", + "reference": "a2c590166b2133a4633738648b6b064edae0814a", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2019-03-17T17:37:11+00:00" + }, + { + "name": "felixfbecker/advanced-json-rpc", + "version": "v3.0.3", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", + "reference": "241c470695366e7b83672be04ea0e64d8085a551" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/241c470695366e7b83672be04ea0e64d8085a551", + "reference": "241c470695366e7b83672be04ea0e64d8085a551", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^1.0", + "php": ">=7.0", + "phpdocumentor/reflection-docblock": "^4.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0.0" + }, + "type": "library", + "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": { + "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": "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", + "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": "openlss/lib-array2xml", + "version": "0.5.1", + "source": { + "type": "git", + "url": "https://github.com/nullivex/lib-array2xml.git", + "reference": "c8b5998a342d7861f2e921403f44e0a2f3ef2be0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nullivex/lib-array2xml/zipball/c8b5998a342d7861f2e921403f44e0a2f3ef2be0", + "reference": "c8b5998a342d7861f2e921403f44e0a2f3ef2be0", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "autoload": { + "psr-0": { + "LSS": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Bryan Tong", + "email": "contact@nullivex.com", + "homepage": "http://bryantong.com" + }, + { + "name": "Tony Butler", + "email": "spudz76@gmail.com", + "homepage": "http://openlss.org" + } + ], + "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": "phpro/grumphp", + "version": "v0.15.2", + "source": { + "type": "git", + "url": "https://github.com/phpro/grumphp.git", + "reference": "c153840bead6fbed370d35cc84c63dca33de0ca4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpro/grumphp/zipball/c153840bead6fbed370d35cc84c63dca33de0ca4", + "reference": "c153840bead6fbed370d35cc84c63dca33de0ca4", + "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.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", + "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": "^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.", + "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.", + "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.", + "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.", + "symplify/easycodingstandard": "Lets GrumPHP check coding standard.", + "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-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.7", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "32d87d746c70785f78d239855782d27cde0eb6ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/32d87d746c70785f78d239855782d27cde0eb6ee", + "reference": "32d87d746c70785f78d239855782d27cde0eb6ee", + "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/schema": "^1.0", + "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-19T17:36:42+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": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "time": "2019-02-04T06:01:07+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-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" + }, + { + "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": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "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", + "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" + }, + { + "name": "vimeo/psalm", + "version": "3.3.0", + "source": { + "type": "git", + "url": "https://github.com/vimeo/psalm.git", + "reference": "a1eb191f57cd6ac1963ce7818d010f981564bb74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/a1eb191f57cd6ac1963ce7818d010f981564bb74", + "reference": "a1eb191f57cd6ac1963ce7818d010f981564bb74", + "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", + "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.1", + "sebastian/diff": "^3.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", + "phpmyadmin/sql-parser": "^5.0", + "phpunit/phpunit": "^7.5 || ^8.0", + "psalm/plugin-phpunit": "^0.6", + "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-21T03:14:41+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": [], + "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..0d71512 --- /dev/null +++ b/config/bundles.php @@ -0,0 +1,6 @@ + ['all' => true], + Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['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/databases.yaml b/config/packages/databases.yaml new file mode 100644 index 0000000..bc69147 --- /dev/null +++ b/config/packages/databases.yaml @@ -0,0 +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://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/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/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/institution.yaml b/config/packages/institution.yaml new file mode 100644 index 0000000..5ac4aad --- /dev/null +++ b/config/packages/institution.yaml @@ -0,0 +1,12 @@ +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'] + + 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..09cce7a --- /dev/null +++ b/config/packages/openskos.yaml @@ -0,0 +1,23 @@ +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'] + + App\Set\Sparql\SparqlSetRepository: + arguments: ['@MyEasyRdfClient'] 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/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/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/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/routes/annotations.yaml b/config/routes/annotations.yaml new file mode 100644 index 0000000..399cfdb --- /dev/null +++ b/config/routes/annotations.yaml @@ -0,0 +1,14 @@ +#TODO: Move this configuration into package level. +#TODO: For example into config/packages/healthcheck.yaml + +healthcheck: + resource: ../../src/Healthcheck/ + type: annotation + +institution: + resource: ../../src/Institution/Controller + type: annotation + +set: + resource: ../../src/Set/Controller + type: annotation diff --git a/config/services.yaml b/config/services.yaml new file mode 100644 index 0000000..c75dd66 --- /dev/null +++ b/config/services.yaml @@ -0,0 +1,28 @@ +# 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: + + +imports: + - { resource: './packages/databases.yaml' } + +services: + # default configuration for services in *this* file + + + 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'] + + App\Rest\ArgumentResolver\ApiRequestResolver: + tags: ['controller.argument_value_resolver'] \ 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 diff --git a/grumphp.yml b/grumphp.yml new file mode 100644 index 0000000..b18e896 --- /dev/null +++ b/grumphp.yml @@ -0,0 +1,11 @@ +parameters: + git_dir: . + bin_dir: vendor/bin + tasks: + phpcsfixer: ~ + psalm: + ignore_patterns: + - '/spec/' #Ignore PHPSpec + phpspec: ~ + + 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/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/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/spec/EasyRdf/TripleFactorySpec.php b/spec/EasyRdf/TripleFactorySpec.php new file mode 100644 index 0000000..ad86639 --- /dev/null +++ b/spec/EasyRdf/TripleFactorySpec.php @@ -0,0 +1,69 @@ +parse($graphString, 'turtle'); + + $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'), + new Iri('http://www.w3.org/ns/org#FormalOrganization') + ), + new Triple( + 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('Doe, John', 'nl') + ), + new Triple( + 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://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) + ), + ]); + } + + 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..6b36bb9 --- /dev/null +++ b/spec/EasyRdf/example.ttl @@ -0,0 +1,21 @@ + + + #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/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..ce16303 --- /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/OpenSkos/ApiRequestSpec.php b/spec/OpenSkos/ApiRequestSpec.php new file mode 100644 index 0000000..7fe127e --- /dev/null +++ b/spec/OpenSkos/ApiRequestSpec.php @@ -0,0 +1,31 @@ +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(); + } + + public function it_throws_a_wobbly_with_invalid_formats() + { + $this->beConstructedWith('something-i-just-made-up'); + $this->shouldThrow(HttpException::class)->duringInstantiation(); + } +} 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/spec/Rest/ArgumentResolver/ApiRequestResolverSpec.php b/spec/Rest/ArgumentResolver/ApiRequestResolverSpec.php new file mode 100644 index 0000000..bb5687b --- /dev/null +++ b/spec/Rest/ArgumentResolver/ApiRequestResolverSpec.php @@ -0,0 +1,46 @@ + 'json-ld', + 'limit' => '123', + 'offset' => '12', + 'level' => '1', + ] + ); + + /** @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); + } + + public function it_returns_correct_default_values( + ArgumentMetadata $argumentMetadata + ) { + $request = new Request(); + + /** @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/spec/Serializer/RdfEncoderSpec.php b/spec/Serializer/RdfEncoderSpec.php new file mode 100644 index 0000000..8bbbe66 --- /dev/null +++ b/spec/Serializer/RdfEncoderSpec.php @@ -0,0 +1,156 @@ +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); + } +} diff --git a/src/EasyRdf/EasyRdfClient.php b/src/EasyRdf/EasyRdfClient.php new file mode 100644 index 0000000..6922d6e --- /dev/null +++ b/src/EasyRdf/EasyRdfClient.php @@ -0,0 +1,42 @@ +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); + } + +} diff --git a/src/EasyRdf/TripleFactory.php b/src/EasyRdf/TripleFactory.php new file mode 100644 index 0000000..807a05b --- /dev/null +++ b/src/EasyRdf/TripleFactory.php @@ -0,0 +1,69 @@ +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/Healthcheck/PingController.php b/src/Healthcheck/PingController.php new file mode 100644 index 0000000..ad44329 --- /dev/null +++ b/src/Healthcheck/PingController.php @@ -0,0 +1,20 @@ +serializer = $serializer; + } + + /** + * @Route(path="/institutions", methods={"GET"}) + * + * @param ApiRequest $apiRequest + * @param InstitutionRepository $repository + * + * @return Response + */ + public function institutions(ApiRequest $apiRequest, InstitutionRepository $repository): Response + { + $institutions = $repository->all($apiRequest->getOffset(), $apiRequest->getLimit()); + + $list = new ListResponse($institutions, count($institutions), $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="/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->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()); + + $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 new file mode 100644 index 0000000..5f1a683 --- /dev/null +++ b/src/Institution/Institution.php @@ -0,0 +1,91 @@ + OpenSkos::CODE, + self::name => OpenSkos::NAME, + self::disableSearchInOtherTenants => OpenSkos::DISABLESEARCHINOTERTENANTS, + 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, + self::type => Rdf::TYPE, + ]; + + + public function __construct(Iri $subject) + { + $this->subject = $subject; + } + + /** + * @return string[] + */ + public static function getMapping(): array + { + return self::$mapping; + } + + + /** + * @return string[] + */ + public function getLevel2Predicate() + { + //Institutions have no level 2 + return ''; + } + + /** + * @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/Institution/InstitutionRepository.php b/src/Institution/InstitutionRepository.php new file mode 100644 index 0000000..9ff89d4 --- /dev/null +++ b/src/Institution/InstitutionRepository.php @@ -0,0 +1,32 @@ +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'); + } + + 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; + } + + /** + * @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/Kernel.php b/src/Kernel.php new file mode 100644 index 0000000..a05ddf8 --- /dev/null +++ b/src/Kernel.php @@ -0,0 +1,56 @@ +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/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 @@ +format = $format; + $this->level = $level; + $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); + } + 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; + } + + /** + * @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/OpenSkos/InvalidApiRequestLevel.php b/src/OpenSkos/InvalidApiRequestLevel.php new file mode 100644 index 0000000..04b6a1a --- /dev/null +++ b/src/OpenSkos/InvalidApiRequestLevel.php @@ -0,0 +1,13 @@ +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..95373d4 --- /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/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 @@ +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..329da78 --- /dev/null +++ b/src/Rdf/SparqlQueryBuilder.php @@ -0,0 +1,46 @@ + <%s> } LIMIT %d OFFSET %d', + Rdf::TYPE, + $type, + $limit, + $offset + ) + ); + } + + 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/Rdf/Triple.php b/src/Rdf/Triple.php new file mode 100644 index 0000000..c82343b --- /dev/null +++ b/src/Rdf/Triple.php @@ -0,0 +1,105 @@ +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 Iri + */ + public function getSubject(): Iri + { + return $this->subject; + } + + /** + * @return Iri + */ + public function getPredicate(): Iri + { + return $this->predicate; + } + + /** + * @return RdfTerm + */ + public function getObject(): RdfTerm + { + return $this->object; + } + + public function __toString(): string + { + if ($this->object instanceof Iri) { + $retVal = sprintf( + '<%s> <%s> <%s>', + $this->subject->getUri(), + $this->predicate->getUri(), + $this->object->getUri() + ); + + return $retVal; + } elseif ($this->object instanceof Literal) { + $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..3949441 --- /dev/null +++ b/src/Rdf/TripleSet.php @@ -0,0 +1,109 @@ +subject; + } + + 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 + * + * @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/Rest/ArgumentResolver/ApiRequestResolver.php b/src/Rest/ArgumentResolver/ApiRequestResolver.php new file mode 100644 index 0000000..3b3fdb8 --- /dev/null +++ b/src/Rest/ArgumentResolver/ApiRequestResolver.php @@ -0,0 +1,28 @@ +getType(); + } + + public function resolve(Request $request, ArgumentMetadata $argument) + { + yield new ApiRequest( + $request->query->get('format', 'json-ld'), + $request->query->getInt('level', 1), + $request->query->getInt('limit', 100), + $request->query->getInt('offset', 0) + ); + } +} diff --git a/src/Rest/ListResponse.php b/src/Rest/ListResponse.php new file mode 100644 index 0000000..97bf2e2 --- /dev/null +++ b/src/Rest/ListResponse.php @@ -0,0 +1,57 @@ +docs = $docs; + $this->total = $total; + $this->offset = $offset; + } + + /** + * @return array + */ + public function getDocs(): array + { + return $this->docs; + } + + /** + * @return int + */ + public function getTotal(): int + { + return $this->total; + } + + /** + * @return int + */ + public function getOffset(): int + { + return $this->offset; + } +} diff --git a/src/Rest/ScalarResponse.php b/src/Rest/ScalarResponse.php new file mode 100644 index 0000000..5e36e5a --- /dev/null +++ b/src/Rest/ScalarResponse.php @@ -0,0 +1,35 @@ +docs = [$doc]; + } + + /** + * @return array + */ + public function getDocs(): array + { + return $this->docs; + } +} 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 @@ +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 ListResponse; + } +} 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/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/Serializer/TripleNormalizer.php b/src/Serializer/TripleNormalizer.php new file mode 100644 index 0000000..82b7470 --- /dev/null +++ b/src/Serializer/TripleNormalizer.php @@ -0,0 +1,98 @@ +normalizer = $normalizer; + } + + /** + * {@inheritdoc} + * + * @param Triple $object + */ + public function normalize($object, $format = null, array $context = []) + { + return [$object->getSubject()->getUri(), $object->getPredicate()->getUri(), (string) $object->getObject()]; + + // 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 Triple; + } +} diff --git a/src/Serializer/TripleSetNormalizer.php b/src/Serializer/TripleSetNormalizer.php new file mode 100644 index 0000000..14fc5b9 --- /dev/null +++ b/src/Serializer/TripleSetNormalizer.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/Set/Controller/Set.php b/src/Set/Controller/Set.php new file mode 100644 index 0000000..ba5d1aa --- /dev/null +++ b/src/Set/Controller/Set.php @@ -0,0 +1,90 @@ +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->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()); + + $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..d026813 --- /dev/null +++ b/src/Set/Set.php @@ -0,0 +1,80 @@ + OpenSkos::TENANT, + self::code => OpenSkos::CODE, + self::allow_oai => OpenSkos::ALLOW_OAI, + self::conceptBaseUri => OpenSkos::CONCEPTBASEURI, + self::oai_baseURL => OpenSkos::OAI_BASEURL, + 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 string + */ + public function getLevel2Predicate() + { + return self::tenant; + } + + + /** + * @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..a37d00d --- /dev/null +++ b/src/Set/SetRepository.php @@ -0,0 +1,40 @@ +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; + } + + /** + * @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; + } +} diff --git a/symfony.lock b/symfony.lock new file mode 100644 index 0000000..880161c --- /dev/null +++ b/symfony.lock @@ -0,0 +1,355 @@ +{ + "amphp/amp": { + "version": "v2.1.1" + }, + "amphp/byte-stream": { + "version": "v1.5.1" + }, + "composer/ca-bundle": { + "version": "1.1.4" + }, + "composer/composer": { + "version": "1.8.5" + }, + "composer/semver": { + "version": "1.5.0" + }, + "composer/spdx-licenses": { + "version": "1.5.1" + }, + "composer/xdebug-handler": { + "version": "1.3.2" + }, + "doctrine/annotations": { + "version": "1.0", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "1.0", + "ref": "cb4152ebcadbe620ea2261da1a1c5a9b8cea7672" + }, + "files": [ + "config/routes/annotations.yaml" + ] + }, + "doctrine/cache": { + "version": "v1.8.0" + }, + "doctrine/collections": { + "version": "v1.6.1" + }, + "doctrine/event-manager": { + "version": "v1.0.0" + }, + "doctrine/instantiator": { + "version": "1.2.0" + }, + "doctrine/lexer": { + "version": "v1.0.1" + }, + "doctrine/persistence": { + "version": "1.1.1" + }, + "doctrine/reflection": { + "version": "v1.0.0" + }, + "easyrdf/easyrdf": { + "version": "0.9.1" + }, + "felixfbecker/advanced-json-rpc": { + "version": "v3.0.3" + }, + "felixfbecker/language-server-protocol": { + "version": "v1.2.0" + }, + "friendsofphp/php-cs-fixer": { + "version": "2.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "2.2", + "ref": "81dee417d2cc60cd1c9d6208dff2ec22a1103e93" + }, + "files": [ + ".php_cs.dist" + ] + }, + "gitonomy/gitlib": { + "version": "v1.0.4" + }, + "jean85/pretty-package-versions": { + "version": "1.2" + }, + "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" + }, + "muglug/package-versions-56": { + "version": "1.2.4" + }, + "netresearch/jsonmapper": { + "version": "v1.4.0" + }, + "nette/bootstrap": { + "version": "v3.0.0" + }, + "nette/di": { + "version": "v3.0.0" + }, + "nette/finder": { + "version": "v2.5.0" + }, + "nette/neon": { + "version": "v3.0.0" + }, + "nette/php-generator": { + "version": "v3.2.2" + }, + "nette/robot-loader": { + "version": "v3.2.0" + }, + "nette/schema": { + "version": "v1.0.0" + }, + "nette/utils": { + "version": "v3.0.1" + }, + "nikic/php-parser": { + "version": "v4.2.1" + }, + "ocramius/package-versions": { + "version": "1.4.0" + }, + "openlss/lib-array2xml": { + "version": "0.5.1" + }, + "php-cs-fixer/diff": { + "version": "v1.3.0" + }, + "phpdocumentor/reflection-common": { + "version": "1.0.1" + }, + "phpdocumentor/reflection-docblock": { + "version": "4.3.1" + }, + "phpdocumentor/type-resolver": { + "version": "0.4.0" + }, + "phpmyadmin/sql-parser": { + "version": "v4.3.1" + }, + "phpro/grumphp": { + "version": "v0.15.0" + }, + "phpspec/php-diff": { + "version": "v1.1.0" + }, + "phpspec/phpspec": { + "version": "5.1.0" + }, + "phpspec/prophecy": { + "version": "1.8.0" + }, + "phpstan/phpdoc-parser": { + "version": "0.3.3" + }, + "phpstan/phpstan": { + "version": "0.11.6" + }, + "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" + }, + "sebastian/comparator": { + "version": "3.0.2" + }, + "sebastian/diff": { + "version": "3.0.2" + }, + "sebastian/exporter": { + "version": "3.1.0" + }, + "sebastian/recursion-context": { + "version": "3.0.0" + }, + "seld/jsonlint": { + "version": "1.7.1" + }, + "seld/phar-utils": { + "version": "1.0.1" + }, + "sensio/framework-extra-bundle": { + "version": "5.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "5.2", + "ref": "fb7e19da7f013d0d422fa9bce16f5c510e27609b" + }, + "files": [ + "config/packages/sensio_framework_extra.yaml" + ] + }, + "squizlabs/php_codesniffer": { + "version": "3.0", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "master", + "version": "3.0", + "ref": "0dc9cceda799fd3a08b96987e176a261028a3709" + }, + "files": [ + "phpcs.xml.dist" + ] + }, + "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/inflector": { + "version": "v4.2.8" + }, + "symfony/options-resolver": { + "version": "v4.2.8" + }, + "symfony/polyfill-mbstring": { + "version": "v1.11.0" + }, + "symfony/polyfill-php72": { + "version": "v1.11.0" + }, + "symfony/process": { + "version": "v4.2.8" + }, + "symfony/property-access": { + "version": "v4.2.8" + }, + "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/serializer": { + "version": "v4.2.8" + }, + "symfony/stopwatch": { + "version": "v4.2.8" + }, + "symfony/var-exporter": { + "version": "v4.2.8" + }, + "symfony/yaml": { + "version": "v4.2.8" + }, + "vimeo/psalm": { + "version": "3.2.12" + }, + "webmozart/assert": { + "version": "1.4.0" + }, + "webmozart/glob": { + "version": "4.1.0" + }, + "webmozart/path-util": { + "version": "2.3.0" + } +}