commit 17ec066110e4ec6201e647cabb2188964c81d904 Author: Danyi Dávid Date: Sun Nov 11 12:01:18 2018 +0100 * initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4da80f1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.idea +composer.phar + +clover.xml +coveralls-upload.json +phpunit.xml +vendor/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..dfb1a34 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Webnaplo Gül-Baba diff --git a/bin/clear-config-cache.php b/bin/clear-config-cache.php new file mode 100644 index 0000000..50a14ce --- /dev/null +++ b/bin/clear-config-cache.php @@ -0,0 +1,46 @@ +get('config')['console']['commands']; +foreach ($commands as $command) { + $application->add($container->get($command)); +} + +$application->run(); diff --git a/cli-config.php b/cli-config.php new file mode 100644 index 0000000..b555030 --- /dev/null +++ b/cli-config.php @@ -0,0 +1,9 @@ + new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper( + $container->get('doctrine.entity_manager.orm_default') + ), +]); \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..ea5e333 --- /dev/null +++ b/composer.json @@ -0,0 +1,76 @@ +{ + "name": "zendframework/zend-expressive-skeleton", + "description": "Zend expressive skeleton. Begin developing PSR-7 middleware applications in seconds!", + "type": "project", + "homepage": "https://github.com/zendframework/zend-expressive-skeleton", + "license": "BSD-3-Clause", + "config": { + "sort-packages": true + }, + "minimum-stability": "dev", + "prefer-stable": true, + "require": { + "php": "^7.1", + "dasprid/container-interop-doctrine": "^1.0", + "doctrine/data-fixtures": "^1.2", + "gedmo/doctrine-extensions": "^2.4", + "imagine/imagine": "^0.7.1", + "lcobucci/jwt": "^3.2", + "monolog/monolog": "^1.23", + "oro/doctrine-extensions": "^1.2", + "phpoffice/phpexcel": "1.8.1", + "psliwa/php-pdf": "^1.2", + "roave/security-advisories": "dev-master", + "symfony/yaml": "^3.3", + "tuupola/cors-middleware": "^0.5.2", + "tuupola/slim-jwt-auth": "^2.3", + "zendframework/zend-component-installer": "^1.0", + "zendframework/zend-config": "^3.1", + "zendframework/zend-config-aggregator": "^1.0", + "zendframework/zend-crypt": "^3.2", + "zendframework/zend-expressive": "^2.0.2", + "zendframework/zend-expressive-fastroute": "^2.0", + "zendframework/zend-expressive-helpers": "^4.0", + "zendframework/zend-hydrator": "^2.2", + "zendframework/zend-json": "^3.0", + "zendframework/zend-mail": "^2.8", + "zendframework/zend-permissions-rbac": "^2.5", + "zendframework/zend-servicemanager": "^3.3", + "zendframework/zend-stdlib": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.0.8 || ^5.7.15", + "squizlabs/php_codesniffer": "^2.8.1", + "zfcampus/zf-development-mode": "^3.1", + "filp/whoops": "^2.1.7" + }, + "autoload": { + "psr-4": { + "App\\": "src/App/" + } + }, + "autoload-dev": { + "psr-4": { + "AppTest\\": "test/AppTest/" + } + }, + "scripts": { + "post-create-project-cmd": [ + "@development-enable" + ], + "development-disable": "zf-development-mode disable", + "development-enable": "zf-development-mode enable", + "development-status": "zf-development-mode status", + "check": [ + "@cs-check", + "@test" + ], + "clear-config-cache": "php bin/clear-config-cache.php", + "cs-check": "phpcs", + "cs-fix": "phpcbf", + "serve": "php -S 0.0.0.0:8888 -t public public/index.php", + "test": "phpunit --colors=always", + "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", + "upload-coverage": "coveralls -v" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..8af2144 --- /dev/null +++ b/composer.lock @@ -0,0 +1,5243 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "d56bfbdbd812dad68abdf21910e4ed01", + "packages": [ + { + "name": "behat/transliterator", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/Behat/Transliterator.git", + "reference": "826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Transliterator/zipball/826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c", + "reference": "826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "chuyskywalker/rolling-curl": "^3.1", + "php-yaoi/php-yaoi": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\Transliterator": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Artistic-1.0" + ], + "description": "String transliterator", + "keywords": [ + "i18n", + "slug", + "transliterator" + ], + "time": "2017-04-04T11:38:05+00:00" + }, + { + "name": "container-interop/container-interop", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/container-interop/container-interop.git", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "shasum": "" + }, + "require": { + "psr/container": "^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Interop\\Container\\": "src/Interop/Container/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", + "homepage": "https://github.com/container-interop/container-interop", + "time": "2017-02-14T19:40:03+00:00" + }, + { + "name": "dasprid/container-interop-doctrine", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/DASPRiD/container-interop-doctrine.git", + "reference": "b9f3afc00ce997e469d7fdd6fed7b8d400763290" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DASPRiD/container-interop-doctrine/zipball/b9f3afc00ce997e469d7fdd6fed7b8d400763290", + "reference": "b9f3afc00ce997e469d7fdd6fed7b8d400763290", + "shasum": "" + }, + "require": { + "doctrine/common": "^2.6", + "doctrine/dbal": "^2.5", + "doctrine/orm": "^2.5", + "php": "^5.5|^7.0", + "psr/container": "^1.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8", + "squizlabs/php_codesniffer": "^2.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "ContainerInteropDoctrine\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "description": "Doctrine factories for container-interop", + "homepage": "https://github.com/DASPRiD/container-interop-doctrine", + "time": "2018-01-24T23:25:49+00:00" + }, + { + "name": "doctrine/annotations", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", + "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", + "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": "2017-12-06T07:11:42+00:00" + }, + { + "name": "doctrine/cache", + "version": "v1.7.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "b3217d58609e9c8e661cd41357a54d926c4a2a1a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/b3217d58609e9c8e661cd41357a54d926c4a2a1a", + "reference": "b3217d58609e9c8e661cd41357a54d926c4a2a1a", + "shasum": "" + }, + "require": { + "php": "~7.1" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "alcaeus/mongo-php-adapter": "^1.1", + "mongodb/mongodb": "^1.1", + "phpunit/phpunit": "^5.7", + "predis/predis": "~1.0" + }, + "suggest": { + "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7.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": "http://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2017-08-25T07:02:50+00:00" + }, + { + "name": "doctrine/collections", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "a01ee38fcd999f34d9bfbcee59dbda5105449cbf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/a01ee38fcd999f34d9bfbcee59dbda5105449cbf", + "reference": "a01ee38fcd999f34d9bfbcee59dbda5105449cbf", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "doctrine/coding-standard": "~0.1@dev", + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Collections\\": "lib/" + } + }, + "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": "Collections Abstraction library", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "array", + "collections", + "iterator" + ], + "time": "2017-07-22T10:37:32+00:00" + }, + { + "name": "doctrine/common", + "version": "v2.8.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common.git", + "reference": "f68c297ce6455e8fd794aa8ffaf9fa458f6ade66" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/f68c297ce6455e8fd794aa8ffaf9fa458f6ade66", + "reference": "f68c297ce6455e8fd794aa8ffaf9fa458f6ade66", + "shasum": "" + }, + "require": { + "doctrine/annotations": "1.*", + "doctrine/cache": "1.*", + "doctrine/collections": "1.*", + "doctrine/inflector": "1.*", + "doctrine/lexer": "1.*", + "php": "~7.1" + }, + "require-dev": { + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8.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" + } + ], + "description": "Common Library for Doctrine projects", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "collections", + "eventmanager", + "persistence", + "spl" + ], + "time": "2017-08-31T08:43:38+00:00" + }, + { + "name": "doctrine/data-fixtures", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/data-fixtures.git", + "reference": "7b76ccc8e648c4502aad7f61347326c8a072bd3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/7b76ccc8e648c4502aad7f61347326c8a072bd3b", + "reference": "7b76ccc8e648c4502aad7f61347326c8a072bd3b", + "shasum": "" + }, + "require": { + "doctrine/common": "~2.2", + "php": "^7.1" + }, + "require-dev": { + "doctrine/dbal": "^2.5.4", + "doctrine/orm": "^2.5.4", + "phpunit/phpunit": "^6.3" + }, + "suggest": { + "alcaeus/mongo-php-adapter": "For using MongoDB ODM with PHP 7", + "doctrine/mongodb-odm": "For loading MongoDB ODM fixtures", + "doctrine/orm": "For loading ORM fixtures", + "doctrine/phpcr-odm": "For loading PHPCR ODM fixtures" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\DataFixtures\\": "lib/Doctrine/Common/DataFixtures" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Data Fixtures for all Doctrine Object Managers", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database" + ], + "time": "2017-11-27T18:48:06+00:00" + }, + { + "name": "doctrine/dbal", + "version": "v2.6.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "e3eed9b1facbb0ced3a0995244843a189e7d1b13" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/e3eed9b1facbb0ced3a0995244843a189e7d1b13", + "reference": "e3eed9b1facbb0ced3a0995244843a189e7d1b13", + "shasum": "" + }, + "require": { + "doctrine/common": "^2.7.1", + "ext-pdo": "*", + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^5.4.6", + "phpunit/phpunit-mock-objects": "!=3.2.4,!=3.2.5", + "symfony/console": "2.*||^3.0" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\DBAL\\": "lib/" + } + }, + "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" + } + ], + "description": "Database Abstraction Layer", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "dbal", + "persistence", + "queryobject" + ], + "time": "2017-11-19T13:38:54+00:00" + }, + { + "name": "doctrine/inflector", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "5527a48b7313d15261292c149e55e26eae771b0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/5527a48b7313d15261292c149e55e26eae771b0a", + "reference": "5527a48b7313d15261292c149e55e26eae771b0a", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector" + } + }, + "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": "Common String Manipulations with regard to casing and singular/plural rules.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string" + ], + "time": "2018-01-09T20:05:19+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "^6.2.3", + "squizlabs/php_codesniffer": "^3.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2017-07-22T11:58:36+00:00" + }, + { + "name": "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/orm", + "version": "v2.6.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/doctrine2.git", + "reference": "374e7ace49d864dad8cddbc55346447c8a6a2083" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/374e7ace49d864dad8cddbc55346447c8a6a2083", + "reference": "374e7ace49d864dad8cddbc55346447c8a6a2083", + "shasum": "" + }, + "require": { + "doctrine/annotations": "~1.5", + "doctrine/cache": "~1.6", + "doctrine/collections": "^1.4", + "doctrine/common": "^2.7.1", + "doctrine/dbal": "^2.6", + "doctrine/instantiator": "~1.1", + "ext-pdo": "*", + "php": "^7.1", + "symfony/console": "~3.0|~4.0" + }, + "require-dev": { + "doctrine/coding-standard": "^1.0", + "phpunit/phpunit": "^6.5", + "squizlabs/php_codesniffer": "^3.2", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" + }, + "bin": [ + "bin/doctrine" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\ORM\\": "lib/Doctrine/ORM" + } + }, + "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": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Object-Relational-Mapper for PHP", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "orm" + ], + "time": "2017-12-20T00:38:15+00:00" + }, + { + "name": "fig/http-message-util", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message-util.git", + "reference": "20b2c280cb6914b7b83089720df44e490f4b42f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message-util/zipball/20b2c280cb6914b7b83089720df44e490f4b42f0", + "reference": "20b2c280cb6914b7b83089720df44e490f4b42f0", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Fig\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Utility classes and constants for use with PSR-7 (psr/http-message)", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2017-02-09T16:10:21+00:00" + }, + { + "name": "firebase/php-jwt", + "version": "v5.0.0", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "9984a4d3a32ae7673d6971ea00bae9d0a1abba0e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/9984a4d3a32ae7673d6971ea00bae9d0a1abba0e", + "reference": "9984a4d3a32ae7673d6971ea00bae9d0a1abba0e", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": " 4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "time": "2017-06-27T22:17:23+00:00" + }, + { + "name": "gedmo/doctrine-extensions", + "version": "v2.4.33", + "source": { + "type": "git", + "url": "https://github.com/Atlantic18/DoctrineExtensions.git", + "reference": "d5fdc573b6a2ecfa29c070ecb3db8397ac55ed78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Atlantic18/DoctrineExtensions/zipball/d5fdc573b6a2ecfa29c070ecb3db8397ac55ed78", + "reference": "d5fdc573b6a2ecfa29c070ecb3db8397ac55ed78", + "shasum": "" + }, + "require": { + "behat/transliterator": "~1.2", + "doctrine/common": "~2.4", + "php": ">=5.3.2" + }, + "require-dev": { + "doctrine/common": ">=2.5.0", + "doctrine/mongodb-odm": ">=1.0.2", + "doctrine/orm": ">=2.5.0", + "phpunit/phpunit": "*", + "symfony/yaml": "~2.6|~3.0|~4.0" + }, + "suggest": { + "doctrine/mongodb-odm": "to use the extensions with the MongoDB ODM", + "doctrine/orm": "to use the extensions with the ORM" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Gedmo\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "David Buchmann", + "email": "david@liip.ch" + }, + { + "name": "Gediminas Morkevicius", + "email": "gediminas.morkevicius@gmail.com" + }, + { + "name": "Gustavo Falco", + "email": "comfortablynumb84@gmail.com" + } + ], + "description": "Doctrine2 behavioral extensions", + "homepage": "http://gediminasm.org/", + "keywords": [ + "Blameable", + "behaviors", + "doctrine2", + "extensions", + "gedmo", + "loggable", + "nestedset", + "sluggable", + "sortable", + "timestampable", + "translatable", + "tree", + "uploadable" + ], + "time": "2018-01-08T14:13:45+00:00" + }, + { + "name": "http-interop/http-middleware", + "version": "0.4.1", + "source": { + "type": "git", + "url": "https://github.com/http-interop/http-middleware.git", + "reference": "9a801fe60e70d5d608b61d56b2dcde29516c81b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/http-interop/http-middleware/zipball/9a801fe60e70d5d608b61d56b2dcde29516c81b9", + "reference": "9a801fe60e70d5d608b61d56b2dcde29516c81b9", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Interop\\Http\\ServerMiddleware\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side middleware", + "keywords": [ + "factory", + "http", + "middleware", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "abandoned": "http-interop/http-server-middleware", + "time": "2017-01-14T15:23:42+00:00" + }, + { + "name": "imagine/imagine", + "version": "v0.7.1", + "source": { + "type": "git", + "url": "https://github.com/avalanche123/Imagine.git", + "reference": "a9a702a946073cbca166718f1b02a1e72d742daa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/avalanche123/Imagine/zipball/a9a702a946073cbca166718f1b02a1e72d742daa", + "reference": "a9a702a946073cbca166718f1b02a1e72d742daa", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "sami/sami": "^3.3", + "symfony/phpunit-bridge": "^3.2" + }, + "suggest": { + "ext-gd": "to use the GD implementation", + "ext-gmagick": "to use the Gmagick implementation", + "ext-imagick": "to use the Imagick implementation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "0.7-dev" + } + }, + "autoload": { + "psr-0": { + "Imagine": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bulat Shakirzyanov", + "email": "mallluhuct@gmail.com", + "homepage": "http://avalanche123.com" + } + ], + "description": "Image processing for PHP 5.3", + "homepage": "http://imagine.readthedocs.org/", + "keywords": [ + "drawing", + "graphics", + "image manipulation", + "image processing" + ], + "time": "2017-05-16T10:31:22+00:00" + }, + { + "name": "lcobucci/jwt", + "version": "3.2.2", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/jwt.git", + "reference": "0b5930be73582369e10c4d4bb7a12bac927a203c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/0b5930be73582369e10c4d4bb7a12bac927a203c", + "reference": "0b5930be73582369e10c4d4bb7a12bac927a203c", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "php": ">=5.5" + }, + "require-dev": { + "mdanter/ecc": "~0.3.1", + "mikey179/vfsstream": "~1.5", + "phpmd/phpmd": "~2.2", + "phpunit/php-invoker": "~1.1", + "phpunit/phpunit": "~4.5", + "squizlabs/php_codesniffer": "~2.3" + }, + "suggest": { + "mdanter/ecc": "Required to use Elliptic Curves based algorithms." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Lcobucci\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Luís Otávio Cobucci Oblonczyk", + "email": "lcobucci@gmail.com", + "role": "Developer" + } + ], + "description": "A simple library to work with JSON Web Token and JSON Web Signature", + "keywords": [ + "JWS", + "jwt" + ], + "time": "2017-09-01T08:23:26+00:00" + }, + { + "name": "monolog/monolog", + "version": "1.23.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "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": "2017-06-19T01:22:40+00:00" + }, + { + "name": "neomerx/cors-psr7", + "version": "v1.0.12", + "source": { + "type": "git", + "url": "https://github.com/neomerx/cors-psr7.git", + "reference": "24944f39483d1a89f66ae9d58cca9f82b8815b35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/neomerx/cors-psr7/zipball/24944f39483d1a89f66ae9d58cca9f82b8815b35", + "reference": "24944f39483d1a89f66ae9d58cca9f82b8815b35", + "shasum": "" + }, + "require": { + "php": ">=5.6.0", + "psr/http-message": "^1.0", + "psr/log": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.9", + "phpunit/phpunit": "^5.7", + "scrutinizer/ocular": "^1.1", + "squizlabs/php_codesniffer": "^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Neomerx\\Cors\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "neomerx", + "email": "info@neomerx.com" + } + ], + "description": "Framework agnostic (PSR-7) CORS implementation (www.w3.org/TR/cors/)", + "homepage": "https://github.com/neomerx/cors-psr7", + "keywords": [ + "Cross Origin Resource Sharing", + "Cross-Origin Resource Sharing", + "cors", + "neomerx", + "psr-7", + "psr7", + "w3.org", + "www.w3.org" + ], + "time": "2017-09-03T22:31:57+00:00" + }, + { + "name": "nikic/fast-route", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/FastRoute.git", + "reference": "b5f95749071c82a8e0f58586987627054400cdf6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/FastRoute/zipball/b5f95749071c82a8e0f58586987627054400cdf6", + "reference": "b5f95749071c82a8e0f58586987627054400cdf6", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "FastRoute\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov", + "email": "nikic@php.net" + } + ], + "description": "Fast request router for PHP", + "keywords": [ + "router", + "routing" + ], + "time": "2017-01-19T11:35:12+00:00" + }, + { + "name": "oro/doctrine-extensions", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/orocrm/doctrine-extensions.git", + "reference": "26f38a2065d36d308331ccecb0b5ef31d61541d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orocrm/doctrine-extensions/zipball/26f38a2065d36d308331ccecb0b5ef31d61541d2", + "reference": "26f38a2065d36d308331ccecb0b5ef31d61541d2", + "shasum": "" + }, + "require": { + "doctrine/orm": ">=2.2.3", + "php": ">=5.3.0" + }, + "require-dev": { + "doctrine/data-fixtures": "^1.0", + "doctrine/orm": "<2.5.0", + "phpunit/phpunit": "4.*", + "squizlabs/php_codesniffer": "2.8.*", + "symfony/yaml": "2.*" + }, + "type": "library", + "autoload": { + "psr-0": { + "Oro\\DBAL": "src/", + "Oro\\ORM": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oro, Inc", + "homepage": "http://www.orocrm.com" + } + ], + "description": "Doctrine Extensions for MySQL and PostgreSQL.", + "homepage": "https://github.com/orocrm/doctrine-extensions/", + "keywords": [ + "database", + "doctrine", + "dql", + "function", + "mysql", + "postgresql", + "type" + ], + "time": "2017-07-17T10:33:16+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v2.0.11", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8", + "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "pseudorandom", + "random" + ], + "time": "2017-09-27T21:40:39+00:00" + }, + { + "name": "phpoffice/phpexcel", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/PHPOffice/PHPExcel.git", + "reference": "372c7cbb695a6f6f1e62649381aeaa37e7e70b32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPOffice/PHPExcel/zipball/372c7cbb695a6f6f1e62649381aeaa37e7e70b32", + "reference": "372c7cbb695a6f6f1e62649381aeaa37e7e70b32", + "shasum": "" + }, + "require": { + "ext-xml": "*", + "ext-xmlwriter": "*", + "php": ">=5.2.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "PHPExcel": "Classes/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL" + ], + "authors": [ + { + "name": "Maarten Balliauw", + "homepage": "http://blog.maartenballiauw.be" + }, + { + "name": "Mark Baker" + }, + { + "name": "Franck Lefevre", + "homepage": "http://blog.rootslabs.net" + }, + { + "name": "Erik Tilt" + } + ], + "description": "PHPExcel - OpenXML - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", + "homepage": "http://phpexcel.codeplex.com", + "keywords": [ + "OpenXML", + "excel", + "php", + "spreadsheet", + "xls", + "xlsx" + ], + "abandoned": "phpoffice/phpspreadsheet", + "time": "2015-05-01T07:00:55+00:00" + }, + { + "name": "psliwa/php-pdf", + "version": "1.2.10", + "source": { + "type": "git", + "url": "https://github.com/psliwa/PHPPdf.git", + "reference": "7055c857a34003b8bf2af6200d5fad18360a67a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/psliwa/PHPPdf/zipball/7055c857a34003b8bf2af6200d5fad18360a67a6", + "reference": "7055c857a34003b8bf2af6200d5fad18360a67a6", + "shasum": "" + }, + "require": { + "zendframework/zend-cache": "^2.0", + "zendframework/zendpdf": "~2.0.0" + }, + "require-dev": { + "imagine/imagine": ">=0.2.0,<0.6.0", + "phpunit/phpunit": ">=4,<5.4.0", + "zendframework/zend-barcode": "^2.0", + "zendframework/zend-validator": "^2.0" + }, + "suggest": { + "imagine/Imagine": "If you want to use image generating (required version: >=v0.2.6)", + "zendframework/zend-barcode": "If you want to use barcodes", + "zendframework/zend-validator": "If you want to use barcodes (required by zend-barcode)" + }, + "type": "library", + "autoload": { + "psr-0": { + "PHPPdf": "lib/", + "Imagine": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Piotr Śliwa", + "email": "peter.pl7@gmail.com", + "homepage": "http://ohey.pl" + } + ], + "description": "Pdf and graphic files generator library for PHP.", + "keywords": [ + "PHPPdf", + "pdf" + ], + "time": "2016-08-14T22:50:47+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/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "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": "2016-10-10T12:19:37+00:00" + }, + { + "name": "roave/security-advisories", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/Roave/SecurityAdvisories.git", + "reference": "3df94834c80037130b533703df4672785b6ea112" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/3df94834c80037130b533703df4672785b6ea112", + "reference": "3df94834c80037130b533703df4672785b6ea112", + "shasum": "" + }, + "conflict": { + "adodb/adodb-php": "<5.20.6", + "amphp/artax": "<1.0.6|>=2,<2.0.6", + "aws/aws-sdk-php": ">=3,<3.2.1", + "bugsnag/bugsnag-laravel": ">=2,<2.0.2", + "cakephp/cakephp": ">=1.3,<1.3.18|>=2,<2.4.99|>=2.5,<2.5.99|>=2.6,<2.6.12|>=2.7,<2.7.6|>=3,<3.0.15|>=3.1,<3.1.4", + "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4", + "cartalyst/sentry": "<=2.1.6", + "codeigniter/framework": "<=3.0.6", + "composer/composer": "<=1.0.0-alpha11", + "contao-components/mediaelement": ">=2.14.2,<2.21.1", + "contao/core": ">=2,<3.5.32", + "contao/core-bundle": ">=4,<4.4.8", + "contao/listing-bundle": ">=4,<4.4.8", + "contao/newsletter-bundle": ">=4,<4.1", + "doctrine/annotations": ">=1,<1.2.7", + "doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2", + "doctrine/common": ">=2,<2.4.3|>=2.5,<2.5.1", + "doctrine/dbal": ">=2,<2.0.8|>=2.1,<2.1.2", + "doctrine/doctrine-bundle": "<1.5.2", + "doctrine/doctrine-module": "<=0.7.1", + "doctrine/mongodb-odm": ">=1,<1.0.2", + "doctrine/mongodb-odm-bundle": ">=2,<3.0.1", + "doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1", + "dompdf/dompdf": ">=0.6,<0.6.2", + "drupal/core": ">=8,<8.3.7", + "drupal/drupal": ">=8,<8.3.7", + "ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.2|>=5.4,<5.4.10.1|>=2017.8,<2017.8.1.1", + "firebase/php-jwt": "<2", + "friendsofsymfony/rest-bundle": ">=1.2,<1.2.2", + "friendsofsymfony/user-bundle": ">=1.2,<1.3.5", + "gree/jose": "<=2.2", + "gregwar/rst": "<1.0.3", + "guzzlehttp/guzzle": ">=6,<6.2.1|>=4.0.0-rc2,<4.2.4|>=5,<5.3.1", + "illuminate/auth": ">=4,<4.0.99|>=4.1,<4.1.26", + "illuminate/database": ">=4,<4.0.99|>=4.1,<4.1.29", + "joomla/session": "<1.3.1", + "laravel/framework": ">=4,<4.0.99|>=4.1,<4.1.29", + "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10", + "magento/magento1ce": ">=1.5.0.1,<1.9.3.2", + "magento/magento1ee": ">=1.9,<1.14.3.2", + "magento/magento2ce": ">=2,<2.2", + "monolog/monolog": ">=1.8,<1.12", + "namshi/jose": "<2.2", + "onelogin/php-saml": "<2.10.4", + "oro/crm": ">=1.7,<1.7.4", + "oro/platform": ">=1.7,<1.7.4", + "phpmailer/phpmailer": ">=5,<5.2.24", + "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3", + "phpxmlrpc/extras": "<0.6.1", + "pusher/pusher-php-server": "<2.2.1", + "sabre/dav": ">=1.6,<1.6.99|>=1.7,<1.7.11|>=1.8,<1.8.9", + "shopware/shopware": "<5.3.7", + "silverstripe/cms": ">=3,<=3.0.11|>=3.1,<3.1.11", + "silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3", + "silverstripe/framework": ">=3,<3.3", + "silverstripe/userforms": "<3", + "simplesamlphp/saml2": "<1.10.4|>=2,<2.3.5|>=3,<3.1.1", + "simplesamlphp/simplesamlphp": "<1.15.2", + "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1", + "socalnick/scn-social-auth": "<1.15.2", + "squizlabs/php_codesniffer": ">=1,<2.8.1", + "swiftmailer/swiftmailer": ">=4,<5.4.5", + "symfony/dependency-injection": ">=2,<2.0.17", + "symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2", + "symfony/http-foundation": ">=2,<2.3.27|>=2.4,<2.5.11|>=2.6,<2.6.6", + "symfony/http-kernel": ">=2,<2.3.29|>=2.4,<2.5.12|>=2.6,<2.6.8", + "symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/routing": ">=2,<2.0.19", + "symfony/security": ">=2,<2.0.25|>=2.1,<2.1.13|>=2.2,<2.2.9|>=2.3,<2.3.37|>=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8.23,<2.8.25|>=3.2.10,<3.2.12|>=3.3.3,<3.3.5", + "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<2.8.6|>=2.8.23,<2.8.25|>=3,<3.0.6|>=3.2.10,<3.2.12|>=3.3.3,<3.3.5", + "symfony/security-csrf": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/serializer": ">=2,<2.0.11", + "symfony/symfony": ">=2,<2.3.41|>=2.4,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/translation": ">=2,<2.0.17", + "symfony/validator": ">=2,<2.0.24|>=2.1,<2.1.12|>=2.2,<2.2.5|>=2.3,<2.3.3", + "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4", + "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7", + "thelia/backoffice-default-template": ">=2.1,<2.1.2", + "thelia/thelia": ">=2.1.0-beta1,<2.1.3|>=2.1,<2.1.2", + "twig/twig": "<1.20", + "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.22|>=8,<8.7.5", + "typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.10|>=3.1,<3.1.7|>=3.2,<3.2.7|>=3.3,<3.3.5", + "typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4", + "willdurand/js-translation-bundle": "<2.1.1", + "yiisoft/yii": ">=1.1.14,<1.1.15", + "yiisoft/yii2": "<2.0.5", + "yiisoft/yii2-bootstrap": "<2.0.4", + "yiisoft/yii2-dev": "<2.0.4", + "yiisoft/yii2-gii": "<2.0.4", + "yiisoft/yii2-jui": "<2.0.4", + "zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3", + "zendframework/zend-captcha": ">=2,<2.4.9|>=2.5,<2.5.2", + "zendframework/zend-crypt": ">=2,<2.4.9|>=2.5,<2.5.2", + "zendframework/zend-db": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.10|>=2.3,<2.3.5", + "zendframework/zend-diactoros": ">=1,<1.0.4", + "zendframework/zend-form": ">=2,<2.2.7|>=2.3,<2.3.1", + "zendframework/zend-http": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.3,<2.3.8|>=2.4,<2.4.1", + "zendframework/zend-json": ">=2.1,<2.1.6|>=2.2,<2.2.6", + "zendframework/zend-ldap": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.8|>=2.3,<2.3.3", + "zendframework/zend-mail": ">=2,<2.4.11|>=2.5,<2.7.2", + "zendframework/zend-navigation": ">=2,<2.2.7|>=2.3,<2.3.1", + "zendframework/zend-session": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.9|>=2.3,<2.3.4", + "zendframework/zend-validator": ">=2.3,<2.3.6", + "zendframework/zend-view": ">=2,<2.2.7|>=2.3,<2.3.1", + "zendframework/zend-xmlrpc": ">=2.1,<2.1.6|>=2.2,<2.2.6", + "zendframework/zendframework": ">=2,<2.4.11|>=2.5,<2.5.1", + "zendframework/zendframework1": "<1.12.20", + "zendframework/zendopenid": ">=2,<2.0.2", + "zendframework/zendxml": ">=1,<1.0.1", + "zetacomponents/mail": "<1.8.2", + "zf-commons/zfc-user": "<1.2.2", + "zfcampus/zf-apigility-doctrine": ">=1,<1.0.3", + "zfr/zfr-oauth2-server-module": "<0.1.2" + }, + "type": "metapackage", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "role": "maintainer" + } + ], + "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", + "time": "2018-02-04T22:09:50+00:00" + }, + { + "name": "symfony/console", + "version": "v4.0.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "36d5b41e7d4e1ccf0370f6babe966c08ef0a1488" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/36d5b41e7d4e1ccf0370f6babe966c08ef0a1488", + "reference": "36d5b41e7d4e1ccf0370f6babe966c08ef0a1488", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "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.0-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": "2018-01-29T09:06:29+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b", + "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-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": "2018-01-30T19:27:44+00:00" + }, + { + "name": "symfony/yaml", + "version": "v3.4.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "eab73b6c21d27ae4cd037c417618dfd4befb0bfe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/eab73b6c21d27ae4cd037c417618dfd4befb0bfe", + "reference": "eab73b6c21d27ae4cd037c417618dfd4befb0bfe", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.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": "3.4-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": "2018-01-21T19:05:02+00:00" + }, + { + "name": "tuupola/cors-middleware", + "version": "0.5.2", + "source": { + "type": "git", + "url": "https://github.com/tuupola/cors-middleware.git", + "reference": "db69d8e67b99570b16e8cd5f78c423ed1167cb21" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tuupola/cors-middleware/zipball/db69d8e67b99570b16e8cd5f78c423ed1167cb21", + "reference": "db69d8e67b99570b16e8cd5f78c423ed1167cb21", + "shasum": "" + }, + "require": { + "neomerx/cors-psr7": "^1.0", + "php": "^5.5 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8", + "squizlabs/php_codesniffer": "^2.5", + "zendframework/zend-diactoros": "^1.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Tuupola\\Middleware\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mika Tuupola", + "email": "tuupola@appelsiini.net", + "homepage": "http://www.appelsiini.net/", + "role": "Developer" + } + ], + "description": "PSR-7 CORS Middleware", + "homepage": "https://github.com/tuupola/cors-middleware", + "keywords": [ + "cors", + "middleware", + "slim" + ], + "time": "2016-08-12T13:12:58+00:00" + }, + { + "name": "tuupola/slim-jwt-auth", + "version": "2.3.3", + "source": { + "type": "git", + "url": "https://github.com/tuupola/slim-jwt-auth.git", + "reference": "1f9fb673e4f5bb9ca4104e328aabfc2e4af38c32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tuupola/slim-jwt-auth/zipball/1f9fb673e4f5bb9ca4104e328aabfc2e4af38c32", + "reference": "1f9fb673e4f5bb9ca4104e328aabfc2e4af38c32", + "shasum": "" + }, + "require": { + "firebase/php-jwt": "^3.0 || ^4.0 || ^5.0", + "php": "^5.5 || ^7.0", + "psr/http-message": "^1.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "squizlabs/php_codesniffer": "^2.3", + "zendframework/zend-diactoros": "^1.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Slim\\Middleware\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mika Tuupola", + "email": "tuupola@appelsiini.net", + "homepage": "http://www.appelsiini.net/", + "role": "Developer" + } + ], + "description": "PSR-7 JWT Authentication Middleware", + "homepage": "https://github.com/tuupola/slim-jwt-auth", + "keywords": [ + "auth", + "json", + "jwt", + "middleware", + "psr-7" + ], + "time": "2017-07-12T09:57:35+00:00" + }, + { + "name": "webimpress/composer-extra-dependency", + "version": "0.2.2", + "source": { + "type": "git", + "url": "https://github.com/webimpress/composer-extra-dependency.git", + "reference": "31fa56391d30f03b1180c87610cbe22254780ad9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webimpress/composer-extra-dependency/zipball/31fa56391d30f03b1180c87610cbe22254780ad9", + "reference": "31fa56391d30f03b1180c87610cbe22254780ad9", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "composer/composer": "^1.5.2", + "mikey179/vfsstream": "^1.6.5", + "phpunit/phpunit": "^5.7.22 || ^6.4.1", + "zendframework/zend-coding-standard": "~1.0.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Webimpress\\ComposerExtraDependency\\Plugin" + }, + "autoload": { + "psr-4": { + "Webimpress\\ComposerExtraDependency\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "description": "Composer plugin to require extra dependencies", + "homepage": "https://github.com/webimpress/composer-extra-dependency", + "keywords": [ + "composer", + "dependency", + "webimpress" + ], + "time": "2017-10-17T17:15:14+00:00" + }, + { + "name": "webimpress/http-middleware-compatibility", + "version": "0.1.4", + "source": { + "type": "git", + "url": "https://github.com/webimpress/http-middleware-compatibility.git", + "reference": "8ed1c2c7523dce0035b98bc4f3a73ca9cd1d3717" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webimpress/http-middleware-compatibility/zipball/8ed1c2c7523dce0035b98bc4f3a73ca9cd1d3717", + "reference": "8ed1c2c7523dce0035b98bc4f3a73ca9cd1d3717", + "shasum": "" + }, + "require": { + "http-interop/http-middleware": "^0.1.1 || ^0.2 || ^0.3 || ^0.4.1 || ^0.5", + "php": "^5.6 || ^7.0", + "webimpress/composer-extra-dependency": "^0.2.2" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.23 || ^6.4.3" + }, + "type": "library", + "extra": { + "dependency": [ + "http-interop/http-middleware" + ] + }, + "autoload": { + "files": [ + "autoload/http-middleware.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "description": "Compatibility library for Draft PSR-15 HTTP Middleware", + "homepage": "https://github.com/webimpress/http-middleware-compatibility", + "keywords": [ + "middleware", + "psr-15", + "webimpress" + ], + "abandoned": "psr/http-server-middleware", + "time": "2017-10-17T17:31:10+00:00" + }, + { + "name": "zendframework/zend-cache", + "version": "2.7.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-cache.git", + "reference": "c98331b96d3b9d9b24cf32d02660602edb34d039" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-cache/zipball/c98331b96d3b9d9b24cf32d02660602edb34d039", + "reference": "c98331b96d3b9d9b24cf32d02660602edb34d039", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "phpbench/phpbench": "^0.10.0", + "phpunit/phpunit": "^4.8", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-serializer": "^2.6", + "zendframework/zend-session": "^2.6.2" + }, + "suggest": { + "ext-apc": "APC or compatible extension, to use the APC storage adapter", + "ext-apcu": "APCU >= 5.1.0, to use the APCu storage adapter", + "ext-dba": "DBA, to use the DBA storage adapter", + "ext-memcache": "Memcache >= 2.0.0 to use the Memcache storage adapter", + "ext-memcached": "Memcached >= 1.0.0 to use the Memcached storage adapter", + "ext-mongo": "Mongo, to use MongoDb storage adapter", + "ext-redis": "Redis, to use Redis storage adapter", + "ext-wincache": "WinCache, to use the WinCache storage adapter", + "ext-xcache": "XCache, to use the XCache storage adapter", + "mongofill/mongofill": "Alternative to ext-mongo - a pure PHP implementation designed as a drop in replacement", + "zendframework/zend-serializer": "Zend\\Serializer component", + "zendframework/zend-session": "Zend\\Session component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev", + "dev-develop": "2.8-dev" + }, + "zf": { + "component": "Zend\\Cache", + "config-provider": "Zend\\Cache\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Zend\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides a generic way to cache any data", + "homepage": "https://github.com/zendframework/zend-cache", + "keywords": [ + "cache", + "zf2" + ], + "time": "2016-12-16T11:35:47+00:00" + }, + { + "name": "zendframework/zend-component-installer", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-component-installer.git", + "reference": "5e9beda3b81d29d4d080b110d67f8c8c44d93605" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-component-installer/zipball/5e9beda3b81d29d4d080b110d67f8c8c44d93605", + "reference": "5e9beda3b81d29d4d080b110d67f8c8c44d93605", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "composer/composer": "^1.5.2", + "malukenho/docheader": "^0.1.6", + "mikey179/vfsstream": "^1.6.5", + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "zendframework/zend-coding-standard": "~1.0.0" + }, + "type": "composer-plugin", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev", + "dev-develop": "1.2-dev" + }, + "class": "Zend\\ComponentInstaller\\ComponentInstaller" + }, + "autoload": { + "psr-4": { + "Zend\\ComponentInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Composer plugin for automating component registration in zend-mvc and Expressive applications", + "keywords": [ + "ZendFramework", + "component installer", + "composer", + "plugin", + "zf" + ], + "time": "2018-01-11T15:03:06+00:00" + }, + { + "name": "zendframework/zend-config", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-config.git", + "reference": "a12e4a592bf66d9629b84960e268f3752e53abe4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-config/zipball/a12e4a592bf66d9629b84960e268f3752e53abe4", + "reference": "a12e4a592bf66d9629b84960e268f3752e53abe4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^5.6 || ^7.0", + "psr/container": "^1.0", + "zendframework/zend-stdlib": "^2.7.7 || ^3.1" + }, + "conflict": { + "container-interop/container-interop": "<1.2.0" + }, + "require-dev": { + "malukenho/docheader": "^0.1.5", + "phpunit/phpunit": "^5.7 || ^6.0", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-filter": "^2.7.1", + "zendframework/zend-i18n": "^2.7.3", + "zendframework/zend-servicemanager": "^2.7.8 || ^3.2.1" + }, + "suggest": { + "zendframework/zend-filter": "^2.7.1; install if you want to use the Filter processor", + "zendframework/zend-i18n": "^2.7.3; install if you want to use the Translator processor", + "zendframework/zend-servicemanager": "^2.7.8 || ^3.2.1; if you need an extensible plugin manager for use with the Config Factory" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev", + "dev-develop": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Config\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides a nested object property based user interface for accessing this configuration data within application code", + "homepage": "https://github.com/zendframework/zend-config", + "keywords": [ + "config", + "zf2" + ], + "time": "2017-02-22T14:31:10+00:00" + }, + { + "name": "zendframework/zend-config-aggregator", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-config-aggregator.git", + "reference": "2762abefdb1df1517be7e77a6717540557dca1bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-config-aggregator/zipball/2762abefdb1df1517be7e77a6717540557dca1bb", + "reference": "2762abefdb1df1517be7e77a6717540557dca1bb", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "zendframework/zend-stdlib": "^2.7.7 || ^3.1.0" + }, + "require-dev": { + "malukenho/docheader": "^0.1.5", + "mikey179/vfsstream": "^1.6", + "phpunit/phpunit": "^5.7.21 || ^6.3", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-config": "^2.6 || ^3.0", + "zendframework/zend-servicemanager": "^2.7.7 || ^3.1.1" + }, + "suggest": { + "zendframework/zend-config": "Allows loading configuration from XML, INI, YAML, and JSON files" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev", + "dev-develop": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\ConfigAggregator\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD 3-Clause" + ], + "authors": [ + { + "name": "Mateusz Tymek", + "email": "mtymek@gmail.com" + } + ], + "description": "Lightweight library for merging and caching application config", + "time": "2017-11-06T14:55:00+00:00" + }, + { + "name": "zendframework/zend-crypt", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-crypt.git", + "reference": "514cef5556bac069e36c2cbded40e529b86bb3f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-crypt/zipball/514cef5556bac069e36c2cbded40e529b86bb3f2", + "reference": "514cef5556bac069e36c2cbded40e529b86bb3f2", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "~1.0", + "ext-mbstring": "*", + "php": "^5.6 || ^7.0", + "zendframework/zend-math": "^3.0", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.6.7", + "squizlabs/php_codesniffer": "^2.3.1" + }, + "suggest": { + "ext-openssl": "Required for most features of Zend\\Crypt" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev", + "dev-develop": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Crypt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-crypt", + "keywords": [ + "crypt", + "zf2" + ], + "time": "2017-07-17T15:46:00+00:00" + }, + { + "name": "zendframework/zend-diactoros", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-diactoros.git", + "reference": "ed6ce7e2105c400ca10277643a8327957c0384b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/ed6ce7e2105c400ca10277643a8327957c0384b7", + "reference": "ed6ce7e2105c400ca10277643a8327957c0384b7", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "psr/http-message": "^1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-dom": "*", + "ext-libxml": "*", + "phpunit/phpunit": "^5.7.16 || ^6.0.8", + "zendframework/zend-coding-standard": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7.x-dev", + "dev-develop": "1.8.x-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Diactoros\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "description": "PSR HTTP Message implementations", + "homepage": "https://github.com/zendframework/zend-diactoros", + "keywords": [ + "http", + "psr", + "psr-7" + ], + "time": "2018-01-04T18:21:48+00:00" + }, + { + "name": "zendframework/zend-escaper", + "version": "2.5.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-escaper.git", + "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/2dcd14b61a72d8b8e27d579c6344e12c26141d4e", + "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Escaper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-escaper", + "keywords": [ + "escaper", + "zf2" + ], + "time": "2016-06-30T19:48:38+00:00" + }, + { + "name": "zendframework/zend-eventmanager", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-eventmanager.git", + "reference": "9d72db10ceb6e42fb92350c0cb54460da61bd79c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/9d72db10ceb6e42fb92350c0cb54460da61bd79c", + "reference": "9d72db10ceb6e42fb92350c0cb54460da61bd79c", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "athletic/athletic": "^0.1", + "container-interop/container-interop": "^1.1.0", + "phpunit/phpunit": "^6.0.7 || ^5.7.14", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-stdlib": "^2.7.3 || ^3.0" + }, + "suggest": { + "container-interop/container-interop": "^1.1.0, to use the lazy listeners feature", + "zendframework/zend-stdlib": "^2.7.3 || ^3.0, to use the FilterChain feature" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev", + "dev-develop": "3.3-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\EventManager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Trigger and listen to events within a PHP application", + "homepage": "https://github.com/zendframework/zend-eventmanager", + "keywords": [ + "event", + "eventmanager", + "events", + "zf2" + ], + "time": "2017-07-11T19:17:22+00:00" + }, + { + "name": "zendframework/zend-expressive", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-expressive.git", + "reference": "05c82075d486fc7818f4c69e218fcad4d43e2cb4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-expressive/zipball/05c82075d486fc7818f4c69e218fcad4d43e2cb4", + "reference": "05c82075d486fc7818f4c69e218fcad4d43e2cb4", + "shasum": "" + }, + "require": { + "fig/http-message-util": "^1.1.2", + "http-interop/http-middleware": "^0.4.1", + "php": "^5.6 || ^7.0", + "psr/container": "^1.0", + "psr/http-message": "^1.0.1", + "zendframework/zend-diactoros": "^1.3.10", + "zendframework/zend-expressive-router": "^2.1", + "zendframework/zend-expressive-template": "^1.0.4", + "zendframework/zend-stratigility": "^2.0.1" + }, + "conflict": { + "container-interop/container-interop": "<1.2.0" + }, + "require-dev": { + "filp/whoops": "^2.1.6 || ^1.1.10", + "malukenho/docheader": "^0.1.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-expressive-aurarouter": "^2.0", + "zendframework/zend-expressive-fastroute": "^2.0", + "zendframework/zend-expressive-zendrouter": "^2.0.1", + "zendframework/zend-servicemanager": "^3.3 || ^2.7.8" + }, + "suggest": { + "aura/di": "^3.2 to make use of Aura.Di dependency injection container", + "filp/whoops": "^2.1 to use the Whoops error handler", + "xtreamwayz/pimple-container-interop": "^1.0 to use Pimple for dependency injection", + "zendframework/zend-expressive-helpers": "^3.0 for its UrlHelper, ServerUrlHelper, and BodyParseMiddleware", + "zendframework/zend-expressive-tooling": "For migration and development tools; require it with the --dev flag", + "zendframework/zend-servicemanager": "^3.3 to use zend-servicemanager for dependency injection" + }, + "bin": [ + "bin/expressive-tooling" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev", + "dev-develop": "2.2.x-dev", + "dev-release-3.0.0": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Expressive\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "PSR-7 Middleware Microframework based on Stratigility", + "keywords": [ + "PSR-11", + "ZendFramework", + "http", + "middleware", + "psr", + "psr-7", + "zend-expressive", + "zf" + ], + "time": "2017-12-11T21:41:17+00:00" + }, + { + "name": "zendframework/zend-expressive-fastroute", + "version": "2.1.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-expressive-fastroute.git", + "reference": "8ba998e5f5de883d2753031338029cb4e545e963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-expressive-fastroute/zipball/8ba998e5f5de883d2753031338029cb4e545e963", + "reference": "8ba998e5f5de883d2753031338029cb4e545e963", + "shasum": "" + }, + "require": { + "fig/http-message-util": "^1.1.2", + "nikic/fast-route": "^1.2", + "php": "^5.6 || ^7.0", + "psr/container": "^1.0", + "psr/http-message": "^1.0.1", + "zendframework/zend-expressive-router": "^2.0.1", + "zendframework/zend-stdlib": "^3.1 || 2.*" + }, + "conflict": { + "container-interop/container-interop": "<1.2.0" + }, + "require-dev": { + "malukenho/docheader": "^0.1.5", + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "zendframework/zend-coding-standard": "~1.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev", + "dev-develop": "2.2-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Expressive\\Router\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "FastRoute integration for Expressive", + "keywords": [ + "FastRoute", + "ZendFramework", + "expressive", + "http", + "middleware", + "psr", + "psr-7", + "zend-expressive", + "zf" + ], + "time": "2017-12-06T21:35:57+00:00" + }, + { + "name": "zendframework/zend-expressive-helpers", + "version": "4.2.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-expressive-helpers.git", + "reference": "137d863d4741210d05297b4bb1c30264f100ba8f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-expressive-helpers/zipball/137d863d4741210d05297b4bb1c30264f100ba8f", + "reference": "137d863d4741210d05297b4bb1c30264f100ba8f", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "psr/container": "^1.0", + "psr/http-message": "^1.0.1", + "webimpress/http-middleware-compatibility": "^0.1.1", + "zendframework/zend-expressive-router": "^2.2" + }, + "require-dev": { + "malukenho/docheader": "^0.1.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^5.7.22 || ^6.4.1", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-diactoros": "^1.3.10" + }, + "suggest": { + "aura/di": "^3.2 to make use of Aura.Di dependency injection container", + "mouf/pimple-interop": "^1.0 to use Pimple for dependency injection", + "zendframework/zend-servicemanager": "^3.3 to use zend-servicemanager for dependency injection" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev", + "dev-develop": "4.3-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Expressive\\Helper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Helper/Utility classes for Expressive", + "keywords": [ + "expressive", + "http", + "middleware", + "psr", + "psr-7" + ], + "time": "2017-10-09T19:03:01+00:00" + }, + { + "name": "zendframework/zend-expressive-router", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-expressive-router.git", + "reference": "eb71000aa7970ad67f252076200bcc1593714f8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-expressive-router/zipball/eb71000aa7970ad67f252076200bcc1593714f8d", + "reference": "eb71000aa7970ad67f252076200bcc1593714f8d", + "shasum": "" + }, + "require": { + "fig/http-message-util": "^1.1.2", + "php": "^5.6 || ^7.0", + "psr/http-message": "^1.0.1", + "webimpress/http-middleware-compatibility": "^0.1.1" + }, + "require-dev": { + "malukenho/docheader": "^0.1.5", + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "zendframework/zend-coding-standard": "~1.0.0" + }, + "suggest": { + "zendframework/zend-expressive-aurarouter": "^1.0 to use the Aura.Router routing adapter", + "zendframework/zend-expressive-fastroute": "^1.2 to use the FastRoute routing adapter", + "zendframework/zend-expressive-zendrouter": "^1.2 to use the zend-router routing adapter" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev", + "dev-develop": "2.4.x-dev", + "dev-release-3.0.0": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Expressive\\Router\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Router subcomponent for Expressive", + "keywords": [ + "ZendFramework", + "expressive", + "http", + "middleware", + "psr", + "psr-7", + "zend-expressive", + "zf" + ], + "time": "2018-02-01T19:49:45+00:00" + }, + { + "name": "zendframework/zend-expressive-template", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-expressive-template.git", + "reference": "23922f96b32ab6e64fc551ec06b81fd047828765" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-expressive-template/zipball/23922f96b32ab6e64fc551ec06b81fd047828765", + "reference": "23922f96b32ab6e64fc551ec06b81fd047828765", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.7", + "zendframework/zend-coding-standard": "~1.0.0" + }, + "suggest": { + "zendframework/zend-expressive-platesrenderer": "^0.1 to use the Plates template renderer", + "zendframework/zend-expressive-twigrenderer": "^0.1 to use the Twig template renderer", + "zendframework/zend-expressive-zendviewrenderer": "^0.1 to use the zend-view PhpRenderer template renderer" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev", + "dev-develop": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Expressive\\Template\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Template subcomponent for Expressive", + "keywords": [ + "expressive", + "template" + ], + "time": "2017-01-11T18:42:34+00:00" + }, + { + "name": "zendframework/zend-hydrator", + "version": "2.3.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-hydrator.git", + "reference": "de0d6465fbc4b7ca345fddc148834c321c4b361f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-hydrator/zipball/de0d6465fbc4b7ca345fddc148834c321c4b361f", + "reference": "de0d6465fbc4b7ca345fddc148834c321c4b361f", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "zendframework/zend-stdlib": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.21 || ^6.3", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-eventmanager": "^3.0", + "zendframework/zend-filter": "^2.6", + "zendframework/zend-inputfilter": "^2.6", + "zendframework/zend-serializer": "^2.6.1", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3" + }, + "suggest": { + "zendframework/zend-eventmanager": "^2.6.2 || ^3.0, to support aggregate hydrator usage", + "zendframework/zend-filter": "^2.6, to support naming strategy hydrator usage", + "zendframework/zend-serializer": "^2.6.1, to use the SerializableStrategy", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3, to support hydrator plugin manager usage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-release-1.0": "1.0-dev", + "dev-release-1.1": "1.1-dev", + "dev-master": "2.3-dev", + "dev-develop": "2.4-dev" + }, + "zf": { + "component": "Zend\\Hydrator", + "config-provider": "Zend\\Hydrator\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Zend\\Hydrator\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-hydrator", + "keywords": [ + "hydrator", + "zf2" + ], + "time": "2017-10-02T15:01:27+00:00" + }, + { + "name": "zendframework/zend-json", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-json.git", + "reference": "4dd940e8e6f32f1d36ea6b0677ea57c540c7c19c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-json/zipball/4dd940e8e6f32f1d36ea6b0677ea57c540c7c19c", + "reference": "4dd940e8e6f32f1d36ea6b0677ea57c540c7c19c", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-stdlib": "^2.7.7 || ^3.1" + }, + "suggest": { + "zendframework/zend-json-server": "For implementing JSON-RPC servers", + "zendframework/zend-xml2json": "For converting XML documents to JSON" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev", + "dev-develop": "3.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Json\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides convenience methods for serializing native PHP to JSON and decoding JSON to native PHP", + "keywords": [ + "ZendFramework", + "json", + "zf" + ], + "time": "2018-01-04T17:51:34+00:00" + }, + { + "name": "zendframework/zend-loader", + "version": "2.5.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-loader.git", + "reference": "c5fd2f071bde071f4363def7dea8dec7393e135c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-loader/zipball/c5fd2f071bde071f4363def7dea8dec7393e135c", + "reference": "c5fd2f071bde071f4363def7dea8dec7393e135c", + "shasum": "" + }, + "require": { + "php": ">=5.3.23" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Loader\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-loader", + "keywords": [ + "loader", + "zf2" + ], + "time": "2015-06-03T14:05:47+00:00" + }, + { + "name": "zendframework/zend-mail", + "version": "2.8.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-mail.git", + "reference": "248230940ab1453b2a532a8fde76c5a6470d7aad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-mail/zipball/248230940ab1453b2a532a8fde76c5a6470d7aad", + "reference": "248230940ab1453b2a532a8fde76c5a6470d7aad", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": "^7.0 || ^5.6", + "zendframework/zend-loader": "^2.5", + "zendframework/zend-mime": "^2.5", + "zendframework/zend-stdlib": "^2.7 || ^3.0", + "zendframework/zend-validator": "^2.6" + }, + "require-dev": { + "phpunit/phpunit": "^6.0.8 || ^5.7.15", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-config": "^2.6", + "zendframework/zend-crypt": "^2.6", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3" + }, + "suggest": { + "ext-intl": "Handle IDN in AddressList hostnames", + "zendframework/zend-crypt": "Crammd5 support in SMTP Auth", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3 when using SMTP to deliver messages" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev", + "dev-develop": "2.9-dev" + }, + "zf": { + "component": "Zend\\Mail", + "config-provider": "Zend\\Mail\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Zend\\Mail\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides generalized functionality to compose and send both text and MIME-compliant multipart e-mail messages", + "homepage": "https://github.com/zendframework/zend-mail", + "keywords": [ + "mail", + "zf2" + ], + "time": "2017-06-08T20:03:58+00:00" + }, + { + "name": "zendframework/zend-math", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-math.git", + "reference": "fda3b4e6c3bb15c35adc6db38b2eacabaa243e65" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-math/zipball/fda3b4e6c3bb15c35adc6db38b2eacabaa243e65", + "reference": "fda3b4e6c3bb15c35adc6db38b2eacabaa243e65", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "paragonie/random_compat": "^2.0.2", + "php": "^5.5 || ^7.0" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "ext-bcmath": "If using the bcmath functionality", + "ext-gmp": "If using the gmp functionality" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev", + "dev-develop": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-math", + "keywords": [ + "math", + "zf2" + ], + "time": "2016-04-28T17:37:42+00:00" + }, + { + "name": "zendframework/zend-memory", + "version": "2.5.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-memory.git", + "reference": "bbf8b9509660b2a97f2d6ccfefabffac3cca6a5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-memory/zipball/bbf8b9509660b2a97f2d6ccfefabffac3cca6a5c", + "reference": "bbf8b9509660b2a97f2d6ccfefabffac3cca6a5c", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8", + "squizlabs/php_codesniffer": "^2.3.1", + "zendframework/zend-cache": "^2.7" + }, + "suggest": { + "zendframework/zend-cache": "To support swapping memory objects into and out of non-memory cache storage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Memory\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-memory", + "keywords": [ + "memory", + "zf2" + ], + "time": "2016-05-11T14:49:42+00:00" + }, + { + "name": "zendframework/zend-mime", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-mime.git", + "reference": "5db38e92f8a6c7c5e25c8afce6e2d0bd49340c5f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-mime/zipball/5db38e92f8a6c7c5e25c8afce6e2d0bd49340c5f", + "reference": "5db38e92f8a6c7c5e25c8afce6e2d0bd49340c5f", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.21 || ^6.3", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-mail": "^2.6" + }, + "suggest": { + "zendframework/zend-mail": "Zend\\Mail component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev", + "dev-develop": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Mime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Create and parse MIME messages and parts", + "homepage": "https://github.com/zendframework/zend-mime", + "keywords": [ + "ZendFramework", + "mime", + "zf" + ], + "time": "2017-11-28T15:02:22+00:00" + }, + { + "name": "zendframework/zend-permissions-rbac", + "version": "2.6.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-permissions-rbac.git", + "reference": "c10ad55e50f402bf14eb2eb9bc424dd9a44dfc78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-permissions-rbac/zipball/c10ad55e50f402bf14eb2eb9bc424dd9a44dfc78", + "reference": "c10ad55e50f402bf14eb2eb9bc424dd9a44dfc78", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.15|| ^6.2.1", + "zendframework/zend-coding-standard": "~1.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev", + "dev-develop": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Permissions\\Rbac\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides a role-based access control management", + "homepage": "https://github.com/zendframework/zend-permissions-rbac", + "keywords": [ + "rbac", + "zf2" + ], + "time": "2018-02-01T09:55:50+00:00" + }, + { + "name": "zendframework/zend-servicemanager", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-servicemanager.git", + "reference": "9f35a104b8d4d3b32da5f4a3b6efc0dd62e5af42" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-servicemanager/zipball/9f35a104b8d4d3b32da5f4a3b6efc0dd62e5af42", + "reference": "9f35a104b8d4d3b32da5f4a3b6efc0dd62e5af42", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "^1.2", + "php": "^5.6 || ^7.0", + "psr/container": "^1.0", + "zendframework/zend-stdlib": "^3.1" + }, + "provide": { + "container-interop/container-interop-implementation": "^1.2", + "psr/container-implementation": "^1.0" + }, + "require-dev": { + "mikey179/vfsstream": "^1.6.5", + "ocramius/proxy-manager": "^1.0 || ^2.0", + "phpbench/phpbench": "^0.13.0", + "phpunit/phpunit": "^5.7.25 || ^6.4.4", + "zendframework/zend-coding-standard": "~1.0.0" + }, + "suggest": { + "ocramius/proxy-manager": "ProxyManager 1.* to handle lazy initialization of services", + "zendframework/zend-stdlib": "zend-stdlib ^2.5 if you wish to use the MergeReplaceKey or MergeRemoveKey features in Config instances" + }, + "bin": [ + "bin/generate-deps-for-config-factory", + "bin/generate-factory-for-class" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev", + "dev-develop": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\ServiceManager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Factory-Driven Dependency Injection Container", + "keywords": [ + "PSR-11", + "ZendFramework", + "dependency-injection", + "di", + "dic", + "service-manager", + "servicemanager", + "zf" + ], + "time": "2018-01-29T16:48:37+00:00" + }, + { + "name": "zendframework/zend-stdlib", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-stdlib.git", + "reference": "debedcfc373a293f9250cc9aa03cf121428c8e78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/debedcfc373a293f9250cc9aa03cf121428c8e78", + "reference": "debedcfc373a293f9250cc9aa03cf121428c8e78", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "athletic/athletic": "~0.1", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "^2.6.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev", + "dev-develop": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Stdlib\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-stdlib", + "keywords": [ + "stdlib", + "zf2" + ], + "time": "2016-09-13T14:38:50+00:00" + }, + { + "name": "zendframework/zend-stratigility", + "version": "2.1.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-stratigility.git", + "reference": "7dfec8dee92dad0d01e68365015f2848c250fe9f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-stratigility/zipball/7dfec8dee92dad0d01e68365015f2848c250fe9f", + "reference": "7dfec8dee92dad0d01e68365015f2848c250fe9f", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "psr/http-message": "^1.0", + "webimpress/http-middleware-compatibility": "^0.1.3", + "zendframework/zend-escaper": "^2.3" + }, + "require-dev": { + "malukenho/docheader": "^0.1.5", + "phpunit/phpunit": "^6.0.8 || ^5.7.15", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-diactoros": "^1.0" + }, + "suggest": { + "psr/http-message-implementation": "Please install a psr/http-message-implementation to consume Stratigility; e.g., zendframework/zend-diactoros" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1.0-dev", + "dev-develop": "2.2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Stratigility\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Middleware for PHP", + "homepage": "https://github.com/zendframework/zend-stratigility", + "keywords": [ + "http", + "middleware", + "psr-7" + ], + "time": "2017-10-12T13:14:14+00:00" + }, + { + "name": "zendframework/zend-validator", + "version": "2.10.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-validator.git", + "reference": "38109ed7d8e46cfa71bccbe7e6ca80cdd035f8c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-validator/zipball/38109ed7d8e46cfa71bccbe7e6ca80cdd035f8c9", + "reference": "38109ed7d8e46cfa71bccbe7e6ca80cdd035f8c9", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "^1.1", + "php": "^5.6 || ^7.0", + "zendframework/zend-stdlib": "^2.7.6 || ^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.0.8 || ^5.7.15", + "zendframework/zend-cache": "^2.6.1", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-config": "^2.6", + "zendframework/zend-db": "^2.7", + "zendframework/zend-filter": "^2.6", + "zendframework/zend-http": "^2.5.4", + "zendframework/zend-i18n": "^2.6", + "zendframework/zend-math": "^2.6", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-session": "^2.8", + "zendframework/zend-uri": "^2.5" + }, + "suggest": { + "zendframework/zend-db": "Zend\\Db component, required by the (No)RecordExists validator", + "zendframework/zend-filter": "Zend\\Filter component, required by the Digits validator", + "zendframework/zend-i18n": "Zend\\I18n component to allow translation of validation error messages", + "zendframework/zend-i18n-resources": "Translations of validator messages", + "zendframework/zend-math": "Zend\\Math component, required by the Csrf validator", + "zendframework/zend-servicemanager": "Zend\\ServiceManager component to allow using the ValidatorPluginManager and validator chains", + "zendframework/zend-session": "Zend\\Session component, ^2.8; required by the Csrf validator", + "zendframework/zend-uri": "Zend\\Uri component, required by the Uri and Sitemap\\Loc validators" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.10.x-dev", + "dev-develop": "2.11.x-dev" + }, + "zf": { + "component": "Zend\\Validator", + "config-provider": "Zend\\Validator\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Zend\\Validator\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides a set of commonly needed validators", + "homepage": "https://github.com/zendframework/zend-validator", + "keywords": [ + "validator", + "zf2" + ], + "time": "2018-02-01T17:05:33+00:00" + }, + { + "name": "zendframework/zendpdf", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/ZendPdf.git", + "reference": "041f90c339cff63a3c4d03a28ef1ea5188059793" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/ZendPdf/zipball/041f90c339cff63a3c4d03a28ef1ea5188059793", + "reference": "041f90c339cff63a3c4d03a28ef1ea5188059793", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "zendframework/zend-memory": ">=2.0.0", + "zendframework/zend-stdlib": ">=2.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "ZendPdf\\": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Zend Pdf Component", + "homepage": "http://packages.zendframework.com/", + "keywords": [ + "pdf", + "zf2" + ], + "abandoned": true, + "time": "2012-11-16T11:16:01+00:00" + } + ], + "packages-dev": [ + { + "name": "filp/whoops", + "version": "2.1.14", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "c6081b8838686aa04f1e83ba7e91f78b7b2a23e6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/c6081b8838686aa04f1e83ba7e91f78b7b2a23e6", + "reference": "c6081b8838686aa04f1e83ba7e91f78b7b2a23e6", + "shasum": "" + }, + "require": { + "php": "^5.5.9 || ^7.0", + "psr/log": "^1.0.1" + }, + "require-dev": { + "mockery/mockery": "0.9.*", + "phpunit/phpunit": "^4.8.35 || ^5.7", + "symfony/var-dumper": "^2.6 || ^3.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Whoops\\": "src/Whoops/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" + } + ], + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], + "time": "2017-11-23T18:22:44+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2017-10-19T19:58:43+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2017-03-05T18:14:27+00:00" + }, + { + "name": "phar-io/version", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2017-03-05T17:38:23+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.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "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": "2017-11-30T07:14:17+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": "phpspec/prophecy", + "version": "1.7.3", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", + "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", + "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", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7.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": "2017-11-24T13:59:53+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/661f34d0bd3f1a7225ef491a70a020ad23a057a1", + "reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.0", + "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^2.0.1", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.0", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-xdebug": "^2.5.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2017-12-06T09:29:45+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2017-11-27T13:52:08+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2017-02-26T11:10:40+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "791198a2c6254db10131eecfe8c06670700904db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", + "reference": "791198a2c6254db10131eecfe8c06670700904db", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.2.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2017-11-27T05:48:46+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "6.5.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "3330ef26ade05359d006041316ed0fa9e8e3cefe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3330ef26ade05359d006041316ed0fa9e8e3cefe", + "reference": "3330ef26ade05359d006041316ed0fa9e8e3cefe", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.6.1", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.0", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^5.3", + "phpunit/php-file-iterator": "^1.4.3", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^1.0.9", + "phpunit/phpunit-mock-objects": "^5.0.5", + "sebastian/comparator": "^2.1", + "sebastian/diff": "^2.0", + "sebastian/environment": "^3.1", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0.1" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2", + "phpunit/dbunit": "<3.0" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "^1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2018-02-01T05:57:37+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "5.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "33fd41a76e746b8fa96d00b49a23dadfa8334cdf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/33fd41a76e746b8fa96d00b49a23dadfa8334cdf", + "reference": "33fd41a76e746b8fa96d00b49a23dadfa8334cdf", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.5", + "php": "^7.0", + "phpunit/php-text-template": "^1.2.1", + "sebastian/exporter": "^3.1" + }, + "conflict": { + "phpunit/phpunit": "<6.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2018-01-06T05:45:45+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "2.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/diff": "^2.0 || ^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2018-02-01T13:46:46+00:00" + }, + { + "name": "sebastian/diff", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "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" + ], + "time": "2017-08-03T08:09:46+00:00" + }, + { + "name": "sebastian/environment", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.1" + }, + "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": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2017-07-01T08:51:00+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/global-state", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.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": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-08-03T12:35:26+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2017-03-29T09:07:27+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": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "2.9.1", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/dcbed1074f8244661eecddfc2a675430d8d33f62", + "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "bin": [ + "scripts/phpcs", + "scripts/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "classmap": [ + "CodeSniffer.php", + "CodeSniffer/CLI.php", + "CodeSniffer/Exception.php", + "CodeSniffer/File.php", + "CodeSniffer/Fixer.php", + "CodeSniffer/Report.php", + "CodeSniffer/Reporting.php", + "CodeSniffer/Sniff.php", + "CodeSniffer/Tokens.php", + "CodeSniffer/Reports/", + "CodeSniffer/Tokenizers/", + "CodeSniffer/DocGenerators/", + "CodeSniffer/Standards/AbstractPatternSniff.php", + "CodeSniffer/Standards/AbstractScopeSniff.php", + "CodeSniffer/Standards/AbstractVariableSniff.php", + "CodeSniffer/Standards/IncorrectPatternException.php", + "CodeSniffer/Standards/Generic/Sniffs/", + "CodeSniffer/Standards/MySource/Sniffs/", + "CodeSniffer/Standards/PEAR/Sniffs/", + "CodeSniffer/Standards/PSR1/Sniffs/", + "CodeSniffer/Standards/PSR2/Sniffs/", + "CodeSniffer/Standards/Squiz/Sniffs/", + "CodeSniffer/Standards/Zend/Sniffs/" + ] + }, + "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": "http://www.squizlabs.com/php-codesniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2017-05-22T02:43:20+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2017-04-07T12:08:54+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "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-01-29T19:49:41+00:00" + }, + { + "name": "zfcampus/zf-development-mode", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/zfcampus/zf-development-mode.git", + "reference": "ffef6ab8cf84ee1d1a77a2b51ba2240d2707c05d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zfcampus/zf-development-mode/zipball/ffef6ab8cf84ee1d1a77a2b51ba2240d2707c05d", + "reference": "ffef6ab8cf84ee1d1a77a2b51ba2240d2707c05d", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "mikey179/vfsstream": "^1.6", + "phpunit/phpunit": "^5.4", + "squizlabs/php_codesniffer": "^2.3.1" + }, + "bin": [ + "bin/zf-development-mode" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev", + "dev-develop": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "ZF\\DevelopmentMode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Zend Framework development mode script", + "homepage": "http://github.com/zfcampus/zf-development-mode", + "keywords": [ + "framework", + "zf2" + ], + "time": "2017-01-09T23:34:49+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": { + "roave/security-advisories": 20 + }, + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": "^7.1" + }, + "platform-dev": [] +} diff --git a/config/.gitignore b/config/.gitignore new file mode 100644 index 0000000..9604301 --- /dev/null +++ b/config/.gitignore @@ -0,0 +1 @@ +development.config.php diff --git a/config/autoload/.gitignore b/config/autoload/.gitignore new file mode 100644 index 0000000..1a83fda --- /dev/null +++ b/config/autoload/.gitignore @@ -0,0 +1,2 @@ +local.php +*.local.php diff --git a/config/autoload/authx2.global.php b/config/autoload/authx2.global.php new file mode 100644 index 0000000..20f7863 --- /dev/null +++ b/config/autoload/authx2.global.php @@ -0,0 +1,93 @@ + [ + 'unguarded_routes' => [ + 'api.auth.login', + 'api.ping', + 'api.xlsx', + 'show-attachment', + 'hibajegy-pdf', + 'karbantartasjegy-pdf', + 'havi-riport-pdf', + ], + + 'route_guard' => [ + 'roles' => [ + /** + * child role => parents[] + * parentrole has all child roles permissions + * order of roles DO matter, referenced parents MUST exist, so should be defined first + */ + // karbantartó oldal + 'uzemeltetesi_vezeto' => [ + 'ufo', + ], + 'betekinto' => [ + 'uzemeltetesi_vezeto', + ], + // ügyfél oldal + 'karbantarto' => [ + 'projektvezeto' + ], + 'user' => [ + 'betekinto', + 'karbantarto', + ], + ], + 'permissions' => [ + // 'admin' role has full access + 'uzemeltetesi_vezeto' => [ + 'api.fault.post', + 'api.fault.put', + 'api.report.post', + 'api.fault-attachment.post', + 'api.fault-comment.post', + 'api.fault-reject.post', + 'api.maintenance', + 'api.maintenance.upcoming' + ], + 'ufo' => [ + 'api.fault.put', + 'api.fault-attachment.post', + 'api.fault-comment.post', + 'api.fault-reject.post', + ], +// 'betekinto' => [ +// 'api.fault.get', +// ], + + 'projektvezeto' => [ + 'api.fault.put', + 'api.report.post', + 'api.fault-attachment.post', + 'api.fault-comment.post', + 'api.maintenance', + 'api.maintenance.put', + 'api.maintenance.upcoming', + ], + 'karbantarto' => [ + ], + // anybody logged in has the 'user' meta role, its not assignable otherwise + // api endpoints defined here are accessible to all authenticated users + 'user' => [ + 'api.auth.renew', + 'api.user.list', + 'api.user.profile', + 'api.user.password', +// 'api.settings.post', + 'api.error-category.get', + 'api.error-origin.get', + 'api.facility-location.get', + 'api.solution-time-interval.get', + 'api.fault.get', + 'show-attachment', + ], + ], + ], + ], +]; diff --git a/config/autoload/cli.global.php b/config/autoload/cli.global.php new file mode 100644 index 0000000..9c5bba5 --- /dev/null +++ b/config/autoload/cli.global.php @@ -0,0 +1,19 @@ + [ + 'invokables' => [], + 'factories' => [ + App\Command\InitializeFixtureCommand::class => App\Command\InitializeFixtureCommandFactory::class, +// App\Command\ConvertMaintenanceHashCommand::class => App\Command\ConvertMaintenanceHashCommandFactory::class, +// App\Command\MailTestCommand::class => App\Command\MailTestCommandFactory::class, + ], + ], + 'console' => [ + 'commands' => [ + App\Command\InitializeFixtureCommand::class, +// App\Command\ConvertMaintenanceHashCommand::class, +// App\Command\MailTestCommand::class, + ], + ], +]; diff --git a/config/autoload/dependencies.global.php b/config/autoload/dependencies.global.php new file mode 100644 index 0000000..8f27cf2 --- /dev/null +++ b/config/autoload/dependencies.global.php @@ -0,0 +1,43 @@ + [ + // Use 'aliases' to alias a service name to another service. The + // key is the alias name, the value is the service to which it points. + 'aliases' => [ + 'Zend\Expressive\Delegate\DefaultDelegate' => Delegate\NotFoundDelegate::class, + ], + // Use 'invokables' for constructor-less services, or services that do + // not require arguments to the constructor. Map a service name to the + // class name. + 'invokables' => [ + // Fully\Qualified\InterfaceName::class => Fully\Qualified\ClassName::class, + Helper\ServerUrlHelper::class => Helper\ServerUrlHelper::class, + ], + // Use 'factories' for services provided by callbacks/factory classes. + 'factories' => [ + Application::class => Container\ApplicationFactory::class, + Delegate\NotFoundDelegate::class => Container\NotFoundDelegateFactory::class, + Helper\ServerUrlMiddleware::class => Helper\ServerUrlMiddlewareFactory::class, + Helper\UrlHelper::class => Helper\UrlHelperFactory::class, + Helper\UrlHelperMiddleware::class => Helper\UrlHelperMiddlewareFactory::class, + + Zend\Stratigility\Middleware\ErrorHandler::class => Container\ErrorHandlerFactory::class, + Middleware\ErrorResponseGenerator::class => Container\ErrorResponseGeneratorFactory::class, + Middleware\NotFoundHandler::class => Container\NotFoundHandlerFactory::class, + + Slim\Middleware\JwtAuthentication::class => App\Middleware\JwtAuthenticationFactory::class, + Tuupola\Middleware\Cors::class => App\Middleware\CorsMiddlewareFactory::class, + App\Middleware\RouteAuthorization::class => App\Middleware\RouteAuthorizationFactory::class, + ], + ], +]; diff --git a/config/autoload/development.local.php.dist b/config/autoload/development.local.php.dist new file mode 100644 index 0000000..9c8aa17 --- /dev/null +++ b/config/autoload/development.local.php.dist @@ -0,0 +1,34 @@ + [ + 'invokables' => [ + ], + 'factories' => [ + ErrorResponseGenerator::class => Container\WhoopsErrorResponseGeneratorFactory::class, + 'Zend\Expressive\Whoops' => Container\WhoopsFactory::class, + 'Zend\Expressive\WhoopsPageHandler' => Container\WhoopsPageHandlerFactory::class, + ], + ], + + 'whoops' => [ + 'json_exceptions' => [ + 'display' => true, + 'show_trace' => true, + 'ajax_only' => true, + ], + ], +]; diff --git a/config/autoload/doctrine.global.php b/config/autoload/doctrine.global.php new file mode 100644 index 0000000..de7e314 --- /dev/null +++ b/config/autoload/doctrine.global.php @@ -0,0 +1,74 @@ + [ + 'factories' => [ + 'doctrine.entity_manager.orm_default' => ContainerInteropDoctrine\EntityManagerFactory::class, + 'doctrine.hydrator' => App\Hydrator\DoctrineObjectFactory::class, + ], + ], + 'doctrine' => [ + 'driver' => [ + 'orm_default' => [ + 'class' => Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain::class, + 'drivers' => [ + 'App\Entity' => 'app_entity', + ], + ], + 'app_entity' => [ + 'class' => Doctrine\ORM\Mapping\Driver\AnnotationDriver::class, + 'cache' => 'array', + 'paths' => __DIR__ . '/../../src/App/Entity', + ], + ], + 'configuration' => [ + 'orm_default' => [ +// 'datetime_functions' => [ +// 'date' => Oro\ORM\Query\AST\Functions\SimpleFunction::class, +// 'time' => Oro\ORM\Query\AST\Functions\SimpleFunction::class, +// 'timestamp' => Oro\ORM\Query\AST\Functions\SimpleFunction::class, +// 'convert_tz' => Oro\ORM\Query\AST\Functions\DateTime\ConvertTz::class, +// ], + 'numeric_functions' => [ +// 'timestampdiff' => Oro\ORM\Query\AST\Functions\Numeric\TimestampDiff::class, +// 'dayofyear' => Oro\ORM\Query\AST\Functions\SimpleFunction::class, +// 'dayofmonth' => Oro\ORM\Query\AST\Functions\SimpleFunction::class, +// 'dayofweek' => Oro\ORM\Query\AST\Functions\SimpleFunction::class, +// 'week' => Oro\ORM\Query\AST\Functions\SimpleFunction::class, +// 'day' => Oro\ORM\Query\AST\Functions\SimpleFunction::class, +// 'hour' => Oro\ORM\Query\AST\Functions\SimpleFunction::class, +// 'minute' => Oro\ORM\Query\AST\Functions\SimpleFunction::class, + 'month' => Oro\ORM\Query\AST\Functions\SimpleFunction::class, +// 'quarter' => Oro\ORM\Query\AST\Functions\SimpleFunction::class, +// 'second' => Oro\ORM\Query\AST\Functions\SimpleFunction::class, + 'year' => Oro\ORM\Query\AST\Functions\SimpleFunction::class, +// 'sign' => Oro\ORM\Query\AST\Functions\Numeric\Sign::class, +// 'pow' => Oro\ORM\Query\AST\Functions\Numeric\Pow::class, + ], +// 'string_functions' => [ +// 'md5' => Oro\ORM\Query\AST\Functions\SimpleFunction::class, +// 'group_concat' => Oro\ORM\Query\AST\Functions\String\GroupConcat::class, +// 'cast' => Oro\ORM\Query\AST\Functions\Cast::class, +// 'concat_ws' => Oro\ORM\Query\AST\Functions\String\ConcatWs::class +// ] +// 'filters' => [ +// 'soft-deleteable' => Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter::class, +// ], + ], + ], + 'event_manager' => [ + 'orm_default' => [ + 'subscribers' => [ + Gedmo\Timestampable\TimestampableListener::class, + Gedmo\Tree\TreeListener::class, + // Gedmo\SoftDeleteable\SoftDeleteableListener::class, + // Gedmo\Translatable\TranslatableListener::class, + // Gedmo\Blameable\BlameableListener::class, + // Gedmo\Loggable\LoggableListener::class, + // Gedmo\Sortable\SortableListener::class, + // Gedmo\Sluggable\SluggableListener::class, + ], + ], + ], + ], +]; diff --git a/config/autoload/doctrine.local.dist.php b/config/autoload/doctrine.local.dist.php new file mode 100644 index 0000000..a3f3324 --- /dev/null +++ b/config/autoload/doctrine.local.dist.php @@ -0,0 +1,14 @@ + [ + 'connection' => [ + 'orm_default' => [ + 'params' => [ + 'url' => 'sqlite:///data/app.db', + 'charset' => 'UTF8', + ], + ], + ], + ], +]; diff --git a/config/autoload/local.php.dist b/config/autoload/local.php.dist new file mode 100644 index 0000000..0869f79 --- /dev/null +++ b/config/autoload/local.php.dist @@ -0,0 +1,27 @@ + [ + 'name' => 'Laterex Üzemeltető Kft.', + 'address' => '1095 Budapest, Hídépítő utca 1-12.', + 'tax_number' => '25398791-2-43', + 'sender' => 'nobody@localhost', + 'site-uri' => 'localhost', + ], + 'client' => [ + 'short' => 'XXII. kerület', + 'name' => 'Budafok-Tétény, Budapest, XXII. kerületi Önkormányzat', + 'address' => '1221 Budapest, Városház tér 11.', + 'tax_number' => '15735856-2-43', + ], + 'acl_config' => [ + 'hmac_key' => '', + ], +]; diff --git a/config/autoload/mail.local.dist.php b/config/autoload/mail.local.dist.php new file mode 100644 index 0000000..692fc9b --- /dev/null +++ b/config/autoload/mail.local.dist.php @@ -0,0 +1,29 @@ + [ +// 'transportClass' => Smtp::class, +// 'optionsClass' => SmtpOptions::class, +// 'options' => [ +// 'name' => 'localhost', +// 'host' => '127.0.0.1', +// 'port' => 25, +// 'connection_class' => 'plain', +// 'connection_config' => [ +// 'username' => 'user', +// 'password' => 'pass', +// ], +// ], + 'transportClass' => File::class, + 'optionsClass' => FileOptions::class, + 'options' => [ + 'path' => 'data/mail/', + ], + ] +]; diff --git a/config/autoload/router.global.php b/config/autoload/router.global.php new file mode 100644 index 0000000..0505bee --- /dev/null +++ b/config/autoload/router.global.php @@ -0,0 +1,12 @@ + [ + 'invokables' => [ + RouterInterface::class => FastRouteRouter::class, + ], + ], +]; diff --git a/config/autoload/zend-expressive.global.php b/config/autoload/zend-expressive.global.php new file mode 100644 index 0000000..dd4acd1 --- /dev/null +++ b/config/autoload/zend-expressive.global.php @@ -0,0 +1,27 @@ + true, + + // Enable debugging; typically used to provide debugging information within templates. + 'debug' => false, + + 'zend-expressive' => [ + // Enable programmatic pipeline: Any `middleware_pipeline` or `routes` + // configuration will be ignored when creating the `Application` instance. + 'programmatic_pipeline' => true, + + // Provide templates for the error handling middleware to use when + // generating responses. + 'error_handler' => [ + 'template_404' => 'error::404', + 'template_error' => 'error::error', + ], + ], +]; diff --git a/config/config.php b/config/config.php new file mode 100644 index 0000000..d07c342 --- /dev/null +++ b/config/config.php @@ -0,0 +1,36 @@ + 'data/config-cache.php', +]; + +$aggregator = new ConfigAggregator([ + \Zend\Mail\ConfigProvider::class, + \Zend\Validator\ConfigProvider::class, + \Zend\Cache\ConfigProvider::class, + \Zend\Hydrator\ConfigProvider::class, + // Include cache configuration + new ArrayProvider($cacheConfig), + + // Default App module config + App\ConfigProvider::class, + + // Load application config in a pre-defined order in such a way that local settings + // overwrite global settings. (Loaded as first to last): + // - `global.php` + // - `*.global.php` + // - `local.php` + // - `*.local.php` + new PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'), + + // Load development config if it exists + new PhpFileProvider('config/development.config.php'), +], $cacheConfig['config_cache_path']); + +return $aggregator->getMergedConfig(); diff --git a/config/container.php b/config/container.php new file mode 100644 index 0000000..e565faa --- /dev/null +++ b/config/container.php @@ -0,0 +1,16 @@ +configureServiceManager($container); + +// Inject config +$container->setService('config', $config); + +return $container; diff --git a/config/development.config.php.dist b/config/development.config.php.dist new file mode 100644 index 0000000..f9e594a --- /dev/null +++ b/config/development.config.php.dist @@ -0,0 +1,29 @@ + true, + ConfigAggregator::ENABLE_CACHE => false, +]; diff --git a/config/pipeline.php b/config/pipeline.php new file mode 100644 index 0000000..312fdf1 --- /dev/null +++ b/config/pipeline.php @@ -0,0 +1,58 @@ +pipe(Tuupola\Middleware\Cors::class); +$app->pipe(ErrorHandler::class); +$app->pipe(ServerUrlMiddleware::class); + +// Pipe more middleware here that you want to execute on every request: +// - bootstrapping +// - pre-conditions +// - modifications to outgoing responses +// +// Piped Middleware may be either callables or service names. Middleware may +// also be passed as an array; each item in the array must resolve to +// middleware eventually (i.e., callable or service name). +// +// Middleware can be attached to specific paths, allowing you to mix and match +// applications under a common domain. The handlers in each middleware +// attached this way will see a URI with the MATCHED PATH SEGMENT REMOVED!!! +// +// - $app->pipe('/api', $apiMiddleware); +// - $app->pipe('/docs', $apiDocMiddleware); +// - $app->pipe('/files', $filesMiddleware); + +// Register the routing middleware in the middleware pipeline +$app->pipeRoutingMiddleware(); +$app->pipe(ImplicitHeadMiddleware::class); +$app->pipe(ImplicitOptionsMiddleware::class); +$app->pipe(UrlHelperMiddleware::class); + +// Add more middleware here that needs to introspect the routing results; this +// might include: +// +// - route-based authentication +// - route-based validation +// - etc. +$app->pipe(Slim\Middleware\JwtAuthentication::class); +$app->pipe(App\Middleware\RouteAuthorization::class); + +// Register the dispatch middleware in the middleware pipeline +$app->pipeDispatchMiddleware(); + +// At this point, if no Response is return by any middleware, the +// NotFoundHandler kicks in; alternately, you can provide other fallback +// middleware to execute. +$app->pipe(NotFoundHandler::class); diff --git a/config/routes.php b/config/routes.php new file mode 100644 index 0000000..31fc92b --- /dev/null +++ b/config/routes.php @@ -0,0 +1,60 @@ +get('/', App\Action\HomePageAction::class, 'home'); + * $app->post('/album', App\Action\AlbumCreateAction::class, 'album.create'); + * $app->put('/album/:id', App\Action\AlbumUpdateAction::class, 'album.put'); + * $app->patch('/album/:id', App\Action\AlbumUpdateAction::class, 'album.patch'); + * $app->delete('/album/:id', App\Action\AlbumDeleteAction::class, 'album.delete'); + * + * Or with multiple request methods: + * + * $app->route('/contact', App\Action\ContactAction::class, ['GET', 'POST', ...], 'contact'); + * + * Or handling all request methods: + * + * $app->route('/contact', App\Action\ContactAction::class)->setName('contact'); + * + * or: + * + * $app->route( + * '/contact', + * App\Action\ContactAction::class, + * Zend\Expressive\Router\Route::HTTP_METHOD_ANY, + * 'contact' + * ); + */ + +$app->get('/', App\Action\PingAction::class, 'home'); +$app->get('/api/ping', App\Action\PingAction::class, 'api.ping'); + +$app->get('/api/maintenance/upcoming', App\Action\MaintenanceUpcomingAction::class, 'api.maintenance.upcoming'); +$app->route('/api/maintenance[/{id:\w+}]', App\Action\MaintenanceAction::class, ['GET', 'OPTIONS'], 'api.maintenance'); +$app->route('/api/maintenance/{id:\w+}', App\Action\MaintenanceAction::class, ['PUT'], 'api.maintenance.put'); + +// authentication and user management +$app->route('/api/auth/login', App\Action\Auth\AuthAction::class, ['POST', 'OPTIONS'], 'api.auth.login'); +$app->route('/api/auth/renew', App\Action\Auth\AuthAction::class, ['GET', 'OPTIONS'], 'api.auth.renew'); +$app->route('/api/user[/{id:\d+}]', App\Action\User\UserAction::class, ['GET', 'PUT', 'OPTIONS'], 'api.user.profile'); +$app->route('/api/user/password', App\Action\User\PasswordAction::class, ['POST', 'OPTIONS'], 'api.user.password'); + +// fault management +$app->route('/api/fault[/{id:\d+}]', App\Action\Fault\FaultAction::class, ['GET', 'OPTIONS'], 'api.fault.get'); // list/show +$app->post('/api/fault', App\Action\Fault\FaultAction::class, 'api.fault.post'); // create +$app->put('/api/fault/{id:\d+}', App\Action\Fault\FaultAction::class, 'api.fault.put'); // update +$app->delete('/api/fault/{id:\d+}', App\Action\Fault\FaultAction::class, 'api.fault.delete'); + +$app->route('/api/fault-reject/{id:\d+}', App\Action\Fault\FaultRejectAction::class, ['POST', 'OPTIONS'], 'api.fault-reject.post'); +$app->route('/api/fault-comment/{id:\d+}', App\Action\Fault\FaultCommentAction::class, ['POST', 'OPTIONS'], 'api.fault-comment.post'); +$app->route('/api/fault-attachment/{id:\d+}/{type}', App\Action\Fault\FaultAttachmentAction::class, ['POST', 'OPTIONS'], 'api.fault-attachment.post'); +$app->route('/show-attachment/{id:\d+}', App\Action\Fault\FaultAttachmentAction::class, ['GET', 'OPTIONS'], 'show-attachment'); + +$app->route('/hibajegy-pdf/{id:\d+}[/{filename}]', App\Action\Pdf\GenerateWorksheetAction::class, ['GET', 'OPTIONS'], 'hibajegy-pdf'); +$app->route('/karbantartasjegy-pdf/{id:\w+}[/{filename}]', App\Action\Pdf\GenerateMaintenanceSheetAction::class, ['GET', 'OPTIONS'], 'karbantartasjegy-pdf'); + +// core data +$app->route('/api/error-category', App\Action\ErrorCategoryAction::class, ['GET', 'OPTIONS'], 'api.error-category.get'); // list/show +$app->route('/api/error-origin', App\Action\ErrorOriginAction::class, ['GET', 'OPTIONS'], 'api.error-origin.get'); // list/show +$app->route('/api/facility-location', App\Action\FacilityLocationAction::class, ['GET', 'OPTIONS'], 'api.facility-location.get'); // list/show +$app->route('/api/solution-time-interval', App\Action\SolutionTimeIntervalAction::class, ['GET', 'OPTIONS'], 'api.solution-time-interval.get'); // list/show diff --git a/data/.gitignore b/data/.gitignore new file mode 100644 index 0000000..213a62f --- /dev/null +++ b/data/.gitignore @@ -0,0 +1,6 @@ +attachments +tmp +temp +cache +passwords-generated.txt +user-upload \ No newline at end of file diff --git a/data/fixture/error-category.yml b/data/fixture/error-category.yml new file mode 100644 index 0000000..43668c6 --- /dev/null +++ b/data/fixture/error-category.yml @@ -0,0 +1,86 @@ +ErrorCategories: + ErrorCategory_1: + id: 1 + name: "víz-, és szennyvízrendszer" + type: "machinery" + active: true + ErrorCategory_2: + id: 2 + name: "hideg-, és melegvizes végberendezés, szerelvény, stb." + type: "machinery" + active: true + ErrorCategory_3: + id: 3 + name: "fűtési rendszer és melegvíz szolgáltatás" + type: "machinery" + active: true + ErrorCategory_4: + id: 4 + name: "fűtési végberendezés, szabályozó, stb." + type: "machinery" + active: true + ErrorCategory_5: + id: 5 + name: "légtechnikai gépészeti rendszer" + type: "machinery" + active: true + ErrorCategory_6: + id: 6 + name: "légtecnikai gépészeti berendezés, szabályozó, stb." + type: "machinery" + active: true + ErrorCategory_7: + id: 7 + name: "elektromos rendszer" + type: "electric" + active: true + ErrorCategory_8: + id: 8 + name: "végelem: kapcsoló, dugaszolóaljzat, biztosíték, stb." + type: "electric" + active: true + ErrorCategory_9: + id: 9 + name: "kommunikációs hálózat" + type: "electric" + active: true + ErrorCategory_10: + id: 10 + name: "kommunikációs végberendezés (telefon, kamera , stb.)" + type: "electric" + active: true + ErrorCategory_11: + id: 11 + name: "tartószerkezetek, fal, mennyezet, válaszfal szerkezete" + type: "building" + active: true + ErrorCategory_12: + id: 12 + name: "tetők, falak, padozatok szigetelése" + type: "building" + active: true + ErrorCategory_13: + id: 13 + name: "álmennyezetek és padlófelületek " + type: "building" + active: true + ErrorCategory_14: + id: 14 + name: "falak és mennyezetek felületképzése" + type: "building" + active: true + ErrorCategory_15: + id: 15 + name: "ajtók, ablakok szerkezetei és szerelvényei" + type: "building" + active: true + ErrorCategory_16: + id: 16 + name: "egyéb felületképzések" + type: "building" + active: true + ErrorCategory_17: + id: 17 + name: "egyéb épületszerkezetek" + type: "building" + active: true diff --git a/data/fixture/error-origin.yml b/data/fixture/error-origin.yml new file mode 100644 index 0000000..bf28fe9 --- /dev/null +++ b/data/fixture/error-origin.yml @@ -0,0 +1,31 @@ +ErrorOrigins: + ErrorOrigin_1: + id: 1 + code: "ü" + name: "rendeltetésszerű használat" + active: true + ErrorOrigin_2: + id: 2 + code: "k" + name: "karbantartás" + active: true + ErrorOrigin_3: + id: 3 + code: "e" + name: "külső elhárítatlan ok" + active: true + ErrorOrigin_4: + id: 4 + code: "r" + name: "rongálás-károkozás" + active: true + ErrorOrigin_5: + id: 5 + code: "hn" + name: "rend. haszn. nem befolyásol" + active: true + ErrorOrigin_6: + id: 6 + code: "m" + name: "megrendelés" + active: true diff --git a/data/fixture/facility-location.yml b/data/fixture/facility-location.yml new file mode 100644 index 0000000..ea3807c --- /dev/null +++ b/data/fixture/facility-location.yml @@ -0,0 +1,2555 @@ +FacilityLocations: +# root node and floors + FacilityLocation_ROOT: + roomNumber: "root" + name: "root" + size: 0 + parent: false + FacilityLocation_P: + roomNumber: "P" + name: "Pince" + size: 970.88 + parent: FacilityLocation_ROOT + FacilityLocation_F: + roomNumber: "F" + name: "Földszint" + size: 1064.86 + parent: FacilityLocation_ROOT + FacilityLocation_1: + roomNumber: "1" + name: "1. emelet" + size: 970.47 + parent: FacilityLocation_ROOT + FacilityLocation_2: + roomNumber: "2" + name: "2. emelet" + size: 1009.21 + parent: FacilityLocation_ROOT + FacilityLocation_3: + roomNumber: "3" + name: "3. emelet" + size: 1158.62 + parent: FacilityLocation_ROOT + FacilityLocation_4: + roomNumber: "4" + name: "4. emelet" + size: 1190.81 + parent: FacilityLocation_ROOT + +# __P__ pince helyiségek + FacilityLocation_P01: + roomNumber: "P01" + name: "trafó" + size: 20.09 + parent: FacilityLocation_P + FacilityLocation_P02: + roomNumber: "P02" + name: "büfé" + size: 11.84 + parent: FacilityLocation_P + FacilityLocation_P03: + roomNumber: "P03" + name: "elektromos kapcsló" + size: 9.63 + parent: FacilityLocation_P + FacilityLocation_P04: + roomNumber: "P04" + name: "raktár" + size: 13.97 + parent: FacilityLocation_P + FacilityLocation_P05: + roomNumber: "P05" + name: "raktár" + size: 9.63 + parent: FacilityLocation_P + FacilityLocation_P06: + roomNumber: "P06" + name: "telefonközpont" + size: 22.36 + parent: FacilityLocation_P + FacilityLocation_P07: + roomNumber: "P07" + name: "raktár" + size: 22.36 + parent: FacilityLocation_P + FacilityLocation_P08: + roomNumber: "P08" + name: "öltörző" + size: 12.76 + parent: FacilityLocation_P + FacilityLocation_P08e: + roomNumber: "P08e" + name: "előtér" + size: 1.76 + parent: FacilityLocation_P08 + FacilityLocation_P08g: + roomNumber: "P08g" + name: "WC" + size: 1.68 + parent: FacilityLocation_P08 + FacilityLocation_P08f: + roomNumber: "P08f" + name: "zuhanyozó" + size: 1.98 + parent: FacilityLocation_P08 + FacilityLocation_P09: + roomNumber: "P09" + name: "bútorraktár" + size: 52.69 + parent: FacilityLocation_P + FacilityLocation_P10: + roomNumber: "P10" + name: "öltörző" + size: 12.08 + parent: FacilityLocation_P + FacilityLocation_P10e: + roomNumber: "P10e" + name: "előtér" + size: 1.76 + parent: FacilityLocation_P10 + FacilityLocation_P10g: + roomNumber: "P10g" + name: "WC" + size: 1.68 + parent: FacilityLocation_P10 + FacilityLocation_P10f: + roomNumber: "P10f" + name: "zuhanyozó" + size: 1.98 + parent: FacilityLocation_P10 + FacilityLocation_P11: + roomNumber: "P11" + name: "szárazáru raktár" + size: 24.74 + parent: FacilityLocation_P + FacilityLocation_P12: + roomNumber: "P12" + name: "öltöző" + size: 22.88 + parent: FacilityLocation_P + FacilityLocation_P12e: + roomNumber: "P12e" + name: "előtér" + size: 3.20 + parent: FacilityLocation_P12 + FacilityLocation_P12g: + roomNumber: "P12g" + name: "WC" + size: 5.03 + parent: FacilityLocation_P12 + FacilityLocation_P12f: + roomNumber: "P12f" + name: "zuhanyozó" + size: 5.51 + parent: FacilityLocation_P12 + FacilityLocation_P13: + roomNumber: "P13" + name: "szárazáru raktár" + size: 24.74 + parent: FacilityLocation_P + FacilityLocation_P14: + roomNumber: "P14" + name: "raktár" + size: 27.65 + parent: FacilityLocation_P + FacilityLocation_P15: + roomNumber: "P15" + name: "földesáru raktár" + size: 10.49 + parent: FacilityLocation_P + FacilityLocation_P16: + roomNumber: "P16" + name: "raktár" + size: 25.54 + parent: FacilityLocation_P + FacilityLocation_P17: + roomNumber: "P17" + name: "közlekedő" + size: 21.60 + parent: FacilityLocation_P + FacilityLocation_P18: + roomNumber: "P18" + name: "raktár" + size: 25.46 + parent: FacilityLocation_P + FacilityLocation_P19: + roomNumber: "P19" + name: "ital, göngyöleg raktár" + size: 8.08 + parent: FacilityLocation_P + FacilityLocation_P20: + roomNumber: "P20" + name: "hulladéktároló" + size: 8.19 + parent: FacilityLocation_P + FacilityLocation_P21: + roomNumber: "P21" + name: "hűtőkamra" + size: 3.36 + parent: FacilityLocation_P + FacilityLocation_P22: + roomNumber: "P22" + name: "mosléktároló" + size: 8.51 + parent: FacilityLocation_P + FacilityLocation_P23: + roomNumber: "P23" + name: "hűtőkamra" + size: 3.36 + parent: FacilityLocation_P + FacilityLocation_P24: + roomNumber: "P24" + name: "tároló" + size: 4.20 + parent: FacilityLocation_P + FacilityLocation_P25: + roomNumber: "P25" + name: "iroda" + size: 6.78 + parent: FacilityLocation_P + FacilityLocation_P26: + roomNumber: "P26" + name: "klub" + size: 93.58 + parent: FacilityLocation_P + FacilityLocation_P27: + roomNumber: "P27" + name: "közlekedő" + size: 47.29 + parent: FacilityLocation_P + FacilityLocation_P28: + roomNumber: "P28" + name: "tároló" + size: 8.56 + parent: FacilityLocation_P + FacilityLocation_P29: + roomNumber: "P29" + name: "közlekedő" + size: 59.36 + parent: FacilityLocation_P + FacilityLocation_P30: + roomNumber: "P30" + name: "raktár" + size: 5.12 + parent: FacilityLocation_P + FacilityLocation_P31: + roomNumber: "P31" + name: "előtér" + size: 11.62 + parent: FacilityLocation_P + FacilityLocation_P32: + roomNumber: "P32" + name: "WC előtér" + size: 4.37 + parent: FacilityLocation_P + FacilityLocation_P33: + roomNumber: "P33" + name: "közlekedő" + size: 33.12 + parent: FacilityLocation_P + FacilityLocation_P34: + roomNumber: "P34" + name: "mozgássérült WC" + size: 3.24 + parent: FacilityLocation_P + FacilityLocation_P35: + roomNumber: "P35" + name: "kazánház" + size: 57.78 + parent: FacilityLocation_P + FacilityLocation_P36: + roomNumber: "P36" + name: "ffi. WC mosdóval" + size: 4.77 + parent: FacilityLocation_P + FacilityLocation_P37: + roomNumber: "P37" + name: "tároló" + size: 3.91 + parent: FacilityLocation_P + FacilityLocation_P38: + roomNumber: "P38" + name: "női WC mosdóval" + size: 2.94 + parent: FacilityLocation_P + FacilityLocation_P39: + roomNumber: "P39" + name: "boiler tér" + size: 7.81 + parent: FacilityLocation_P + FacilityLocation_P40: + roomNumber: "P40" + name: "öltöző" + size: 12.88 + parent: FacilityLocation_P + FacilityLocation_P40e: + roomNumber: "P40e" + name: "előtér" + size: 1.76 + parent: FacilityLocation_P40 + FacilityLocation_P40g: + roomNumber: "P40g" + name: "WC" + size: 1.68 + parent: FacilityLocation_P40 + FacilityLocation_P40f: + roomNumber: "P40f" + name: "zuhanyozó" + size: 1.98 + parent: FacilityLocation_P40 + FacilityLocation_P41: + roomNumber: "P41" + name: "mosószoba" + size: 12.99 + parent: FacilityLocation_P + FacilityLocation_P42: + roomNumber: "P42" + name: "öltöző" + size: 12.88 + parent: FacilityLocation_P + FacilityLocation_P42e: + roomNumber: "P42e" + name: "előtér" + size: 1.76 + parent: FacilityLocation_P42 + FacilityLocation_P42g: + roomNumber: "P42g" + name: "WC" + size: 1.68 + parent: FacilityLocation_P42 + FacilityLocation_P42f: + roomNumber: "P42f" + name: "zuhanyozó" + size: 1.98 + parent: FacilityLocation_P42 + FacilityLocation_P43: + roomNumber: "P43" + name: "szauna" + size: 24.81 + parent: FacilityLocation_P + FacilityLocation_P44: + roomNumber: "P44" + name: "kondicionáló terem" + size: 115.43 + parent: FacilityLocation_P + +# __F__ földszinti helyiségek + FacilityLocation_F01: + roomNumber: "F01" + name: "előlépcső (nyugati)" + size: 17.87 + parent: FacilityLocation_F + FacilityLocation_F02: + roomNumber: "F02" + name: "előcsarnok" + size: 59.72 + parent: FacilityLocation_F + FacilityLocation_F03: + roomNumber: "F03" + name: "előlépcső (keleti)" + size: 17.87 + parent: FacilityLocation_F + FacilityLocation_F04: + roomNumber: "F04" + name: "étterem" + size: 150.85 + parent: FacilityLocation_F + FacilityLocation_F05: + roomNumber: "F05" + name: "különterem" + size: 54.86 + parent: FacilityLocation_F + FacilityLocation_F06: + roomNumber: "F06" + name: "tálaló" + size: 9.31 + parent: FacilityLocation_F + FacilityLocation_F07: + roomNumber: "F07" + name: "feketemosogató" + size: 8.85 + parent: FacilityLocation_F + FacilityLocation_F08: + roomNumber: "F08" + name: "húselőkészítő" + size: 8.46 + parent: FacilityLocation_F + FacilityLocation_F09: + roomNumber: "F09" + name: "főzőkonyha" + size: 23.25 + parent: FacilityLocation_F + FacilityLocation_F10: + roomNumber: "F10" + name: "közlekedő" + size: 15.00 + parent: FacilityLocation_F + FacilityLocation_F11: + roomNumber: "F11" + name: "szennyesbeadó" + size: 7.90 + parent: FacilityLocation_F + FacilityLocation_F12: + roomNumber: "F12" + name: "fehérmosogató" + size: 11.70 + parent: FacilityLocation_F + FacilityLocation_F13: + roomNumber: "F13" + name: "zölség utánmosó" + size: 8.30 + parent: FacilityLocation_F + FacilityLocation_F14: + roomNumber: "F14" + name: "hidegkonyha" + size: 14.40 + parent: FacilityLocation_F + FacilityLocation_F15: + roomNumber: "F15" + name: "hűtőkamra" + size: 5.08 + parent: FacilityLocation_F + FacilityLocation_F16: + roomNumber: "F16" + name: "teherlift előtér" + size: 5.25 + parent: FacilityLocation_F + FacilityLocation_F17: + roomNumber: "F17" + name: "kocsimosó" + size: 3.20 + parent: FacilityLocation_F + FacilityLocation_F18: + roomNumber: "F18" + name: "takarítószer tároló" + size: 8.51 + parent: FacilityLocation_F + FacilityLocation_F10lk: + roomNumber: "F10lk" + name: "lépcsőkarok pihenővel" + size: 15.12 + parent: FacilityLocation_F + FacilityLocation_F19: + roomNumber: "F19" + name: "tároló" + size: 0.98 + parent: FacilityLocation_F + FacilityLocation_F20: + roomNumber: "F20" + name: "üzlet" + size: 13.27 + parent: FacilityLocation_F + FacilityLocation_F21: + roomNumber: "F21" + name: "pénzváltó" + size: 12.49 + parent: FacilityLocation_F + FacilityLocation_F22: + roomNumber: "F22" + name: "előcsarnok" + size: 53.41 + parent: FacilityLocation_F + FacilityLocation_F23: + roomNumber: "F23" + name: "recepció/porta" + size: 15.07 + parent: FacilityLocation_F + FacilityLocation_F24: + roomNumber: "F24" + name: "iroda" + size: 11.38 + parent: FacilityLocation_F + FacilityLocation_F25: + roomNumber: "F25" + name: "iroda" + size: 12.29 + parent: FacilityLocation_F + FacilityLocation_F26: + roomNumber: "F26" + name: "lépcső beléptetővel" + size: 3.70 + parent: FacilityLocation_F + FacilityLocation_F27: + roomNumber: "F27" + name: "hall" + size: 102.51 + parent: FacilityLocation_F + FacilityLocation_F27lk: + roomNumber: "F27lk" + name: "lépcsőkarok pihenővel" + size: 17.82 + parent: FacilityLocation_F + FacilityLocation_F28: + roomNumber: "F28" + name: "ffi. WC" + size: 7.71 + parent: FacilityLocation_F + FacilityLocation_F29: + roomNumber: "F29" + name: "ak.mentes WC" + size: 2.99 + parent: FacilityLocation_F + FacilityLocation_F30: + roomNumber: "F30" + name: "női WC" + size: 9.93 + parent: FacilityLocation_F + FacilityLocation_F31: + roomNumber: "F31" + name: "raktár" + size: 8.30 + parent: FacilityLocation_F + FacilityLocation_F32: + roomNumber: "F32" + name: "raktár" + size: 8.70 + parent: FacilityLocation_F + FacilityLocation_F33: + roomNumber: "F33" + name: "könyvtár" + size: 231.84 + parent: FacilityLocation_F + FacilityLocation_F34: + roomNumber: "F34" + name: "iroda" + size: 19.65 + parent: FacilityLocation_F + FacilityLocation_F35: + roomNumber: "F35" + name: "számítógép terem" + size: 40.38 + parent: FacilityLocation_F + FacilityLocation_F36: + roomNumber: "F36" + name: "előlépcső rámpával (keleti)" + size: 31.85 + parent: FacilityLocation_F + FacilityLocation_L1: + roomNumber: "L1" + name: "lift 8 fő - 630 kg" + size: 1.50 + parent: FacilityLocation_F + FacilityLocation_L2: + roomNumber: "L2" + name: "lift - 6 fő 500 kg" + size: 1.50 + parent: FacilityLocation_F + FacilityLocation_L3: + roomNumber: "L3" + name: "teherlift 250 kg" + size: 1.20 + parent: FacilityLocation_F + FacilityLocation_L4: + roomNumber: "L4" + name: "teherlift 250 kg" + size: 1.20 + parent: FacilityLocation_F + FacilityLocation_L5: + roomNumber: "L5" + name: "teherlift 200 kg" + size: 1.20 + parent: FacilityLocation_F + FacilityLocation_Klk: + roomNumber: "Klk" + name: "külső lépcső (pincébe)" + size: 8.50 + parent: FacilityLocation_F + +# __1__ első emeleti helyiségek + FacilityLocation_101: + roomNumber: "101" + name: "mozgássérült szoba" + size: 22.44 + parent: FacilityLocation_1 + FacilityLocation_101e: + roomNumber: "101e" + name: "előtér" + size: 3.26 + parent: FacilityLocation_101 + FacilityLocation_101f: + roomNumber: "101f" + name: "fürdő" + size: 5.27 + parent: FacilityLocation_101 + FacilityLocation_101t: + roomNumber: "101t" + name: "erkély" + size: 7.43 + parent: FacilityLocation_101 + FacilityLocation_102: + roomNumber: "102" + name: "raktár" + size: 3.85 + parent: FacilityLocation_1 + FacilityLocation_103: + roomNumber: "103" + name: "szobasszony" + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_103e: + roomNumber: "103e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_103 + FacilityLocation_103f: + roomNumber: "103f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_103 + FacilityLocation_103t: + roomNumber: "103t" + name: "erkély" + size: 6.16 + parent: FacilityLocation_103 + FacilityLocation_104: + roomNumber: "104" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_104e: + roomNumber: "104e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_104 + FacilityLocation_104f: + roomNumber: "104f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_104 + FacilityLocation_104t: + roomNumber: "104t" + name: "erkély" + size: 5.84 + parent: FacilityLocation_104 + FacilityLocation_105: + roomNumber: "105" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_105e: + roomNumber: "105e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_105 + FacilityLocation_105f: + roomNumber: "105f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_105 + FacilityLocation_105t: + roomNumber: "105t" + name: "erkély" + size: 5.84 + parent: FacilityLocation_105 + FacilityLocation_106: + roomNumber: "106" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_106e: + roomNumber: "106e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_106 + FacilityLocation_106f: + roomNumber: "106f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_106 + FacilityLocation_106t: + roomNumber: "106t" + name: "erkély" + size: 5.84 + parent: FacilityLocation_106 + FacilityLocation_107: + roomNumber: "107" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_107e: + roomNumber: "107e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_107 + FacilityLocation_107f: + roomNumber: "107f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_107 + FacilityLocation_107t: + roomNumber: "107t" + name: "erkély" + size: 5.84 + parent: FacilityLocation_107 + FacilityLocation_108: + roomNumber: "108" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_108e: + roomNumber: "108e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_108 + FacilityLocation_108f: + roomNumber: "108f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_108 + FacilityLocation_108t: + roomNumber: "108t" + name: "erkély" + size: 5.84 + parent: FacilityLocation_108 + FacilityLocation_109: + roomNumber: "109" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_109e: + roomNumber: "109e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_109 + FacilityLocation_109f: + roomNumber: "109f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_109 + FacilityLocation_109t: + roomNumber: "109t" + name: "erkély" + size: 5.84 + parent: FacilityLocation_109 + FacilityLocation_110: + roomNumber: "110" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_110e: + roomNumber: "110e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_110 + FacilityLocation_110f: + roomNumber: "110f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_110 + FacilityLocation_110t: + roomNumber: "110t" + name: "erkély" + size: 5.84 + parent: FacilityLocation_110 + FacilityLocation_111: + roomNumber: "111" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_111e: + roomNumber: "111e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_111 + FacilityLocation_111f: + roomNumber: "111f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_111 + FacilityLocation_111t: + roomNumber: "111t" + name: "erkély" + size: 5.84 + parent: FacilityLocation_111 + FacilityLocation_112: + roomNumber: "112" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_112e: + roomNumber: "112e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_112 + FacilityLocation_112f: + roomNumber: "112f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_112 + FacilityLocation_112t: + roomNumber: "112t" + name: "erkély" + size: 5.84 + parent: FacilityLocation_112 + FacilityLocation_113: + roomNumber: "113" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_113e: + roomNumber: "113e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_113 + FacilityLocation_113f: + roomNumber: "113f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_113 + FacilityLocation_113t: + roomNumber: "113t" + name: "erkély" + size: 5.84 + parent: FacilityLocation_113 + FacilityLocation_114: + roomNumber: "114" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_114e: + roomNumber: "114e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_114 + FacilityLocation_114f: + roomNumber: "114f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_114 + FacilityLocation_114t: + roomNumber: "114t" + name: "erkély" + size: 5.84 + parent: FacilityLocation_114 + FacilityLocation_115: + roomNumber: "115" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_115e: + roomNumber: "115e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_115 + FacilityLocation_115f: + roomNumber: "115f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_115 + FacilityLocation_115t: + roomNumber: "115t" + name: "erkély" + size: 5.84 + parent: FacilityLocation_115 + FacilityLocation_116: + roomNumber: "116" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_116e: + roomNumber: "116e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_116 + FacilityLocation_116f: + roomNumber: "116f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_116 + FacilityLocation_116t: + roomNumber: "116t" + name: "erkély" + size: 5.84 + parent: FacilityLocation_116 + FacilityLocation_117: + roomNumber: "117" + name: "szoba IV." + size: 16.48 + parent: FacilityLocation_1 + FacilityLocation_117e: + roomNumber: "117e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_117 + FacilityLocation_117f: + roomNumber: "117f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_117 + FacilityLocation_117t: + roomNumber: "117t" + name: "terasz" + size: 5.33 + parent: FacilityLocation_117 + FacilityLocation_119: + roomNumber: "119" + name: "gépészeti terúlet" + size: 28.07 + parent: FacilityLocation_1 + FacilityLocation_120: + roomNumber: "120" + name: "elektromos kapcsolótér" + size: 1.87 + parent: FacilityLocation_1 + FacilityLocation_121: + roomNumber: "121" + name: "szoba III." + size: 18.42 + parent: FacilityLocation_1 + FacilityLocation_121e: + roomNumber: "121e" + name: "előtér" + size: 2.66 + parent: FacilityLocation_121 + FacilityLocation_121f: + roomNumber: "121f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_121 + FacilityLocation_121t: + roomNumber: "121t" + name: "erkély" + size: 7.13 + parent: FacilityLocation_121 + FacilityLocation_122: + roomNumber: "122" + name: "szoba VI." + size: 21.70 + parent: FacilityLocation_1 + FacilityLocation_122e: + roomNumber: "122e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_122 + FacilityLocation_122f: + roomNumber: "122f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_122 + FacilityLocation_122t: + roomNumber: "122t" + name: "terasz" + size: 7.13 + parent: FacilityLocation_122 + FacilityLocation_123: + roomNumber: "123" + name: "szoba I." + size: 16.85 + parent: FacilityLocation_1 + FacilityLocation_123e: + roomNumber: "123e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_123 + FacilityLocation_123f: + roomNumber: "123f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_123 + FacilityLocation_123t: + roomNumber: "123t" + name: "terasz" + size: 5.54 + parent: FacilityLocation_123 + FacilityLocation_124: + roomNumber: "124" + name: "szoba I." + size: 16.98 + parent: FacilityLocation_1 + FacilityLocation_124e: + roomNumber: "124e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_124 + FacilityLocation_124f: + roomNumber: "124f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_124 + FacilityLocation_124t: + roomNumber: "124t" + name: "terasz" + size: 5.38 + parent: FacilityLocation_124 + FacilityLocation_125: + roomNumber: "125" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_125e: + roomNumber: "125e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_125 + FacilityLocation_125f: + roomNumber: "125f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_125 + FacilityLocation_125t: + roomNumber: "125t" + name: "terasz" + size: 5.54 + parent: FacilityLocation_125 + FacilityLocation_126: + roomNumber: "126" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_126e: + roomNumber: "126e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_126 + FacilityLocation_126f: + roomNumber: "126f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_126 + FacilityLocation_126t: + roomNumber: "126t" + name: "terasz" + size: 5.54 + parent: FacilityLocation_126 + FacilityLocation_127: + roomNumber: "127" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_127e: + roomNumber: "127e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_127 + FacilityLocation_127f: + roomNumber: "127f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_127 + FacilityLocation_127t: + roomNumber: "127t" + name: "terasz" + size: 5.54 + parent: FacilityLocation_127 + FacilityLocation_128: + roomNumber: "128" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_128e: + roomNumber: "128e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_128 + FacilityLocation_128f: + roomNumber: "128f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_128 + FacilityLocation_128at: + roomNumber: "128at" + name: "terasz" + size: 5.54 + parent: FacilityLocation_128 + FacilityLocation_129: + roomNumber: "129" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_129e: + roomNumber: "129e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_129 + FacilityLocation_129f: + roomNumber: "129f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_129 + FacilityLocation_129t: + roomNumber: "129t" + name: "terasz" + size: 5.54 + parent: FacilityLocation_129 + FacilityLocation_130: + roomNumber: "130" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_1 + FacilityLocation_130e: + roomNumber: "130e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_130 + FacilityLocation_130f: + roomNumber: "130f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_130 + FacilityLocation_130t: + roomNumber: "130t" + name: "terasz" + size: 5.54 + parent: FacilityLocation_130 + FacilityLocation_131: + roomNumber: "131" + name: "szoba II." + size: 17.22 + parent: FacilityLocation_1 + FacilityLocation_131e: + roomNumber: "131e" + name: "előtér" + size: 2.66 + parent: FacilityLocation_131 + FacilityLocation_131f: + roomNumber: "131f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_131 + FacilityLocation_132: + roomNumber: "132" + name: "szoba II." + size: 17.22 + parent: FacilityLocation_1 + FacilityLocation_132e: + roomNumber: "132e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_132 + FacilityLocation_132f: + roomNumber: "132f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_132 + FacilityLocation_132t: + roomNumber: "132t" + name: "terasz" + size: 5.60 + parent: FacilityLocation_132 + FacilityLocation_133: + roomNumber: "133" + name: "menekülési ajtó külső lépcsővel" + size: 0 + parent: FacilityLocation_1 + FacilityLocation_134: + roomNumber: "134" + name: "közlekedő" + size: 46.03 + parent: FacilityLocation_1 + FacilityLocation_135: + roomNumber: "135" + name: "lift előtér telefonos sarokkal" + size: 18.00 + parent: FacilityLocation_1 + FacilityLocation_135lk: + roomNumber: "135lk" + name: "lépcsőkarok pihenővel" + size: 17.82 + parent: FacilityLocation_135 + FacilityLocation_137: + roomNumber: "137" + name: "lépcsőház" + size: 25.86 + parent: FacilityLocation_1 + FacilityLocation_137lk: + roomNumber: "137lk" + name: "lépcsőkarok pihenővel" + size: 15.12 + parent: FacilityLocation_1 + FacilityLocation_138: + roomNumber: "138" + name: "tároló" + size: 0.98 + parent: FacilityLocation_1 + +# __2__ első emeleti helyiségek + FacilityLocation_201: + roomNumber: "201" + name: "mozgássérült szoba" + size: 22.44 + parent: FacilityLocation_2 + FacilityLocation_201e: + roomNumber: "201e" + name: "előtér" + size: 3.26 + parent: FacilityLocation_201 + FacilityLocation_201f: + roomNumber: "201f" + name: "fürdő" + size: 5.27 + parent: FacilityLocation_201 + FacilityLocation_201t: + roomNumber: "201t" + name: "erkély" + size: 7.43 + parent: FacilityLocation_201 + FacilityLocation_202: + roomNumber: "202" + name: "raktár" + size: 3.85 + parent: FacilityLocation_2 + FacilityLocation_203: + roomNumber: "203" + name: "szobasszony" + size: 17.47 + parent: FacilityLocation_2 + FacilityLocation_203e: + roomNumber: "203e" + name: "előtér" + size: 4.34 + parent: FacilityLocation_203 + FacilityLocation_203t: + roomNumber: "203t" + name: "erkély" + size: 6.16 + parent: FacilityLocation_203 + FacilityLocation_204: + roomNumber: "204" + name: "szoba V." + size: 17.47 + parent: FacilityLocation_2 + FacilityLocation_204e: + roomNumber: "204e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_204 + FacilityLocation_204f: + roomNumber: "204f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_204 + FacilityLocation_204t: + roomNumber: "204t" + name: "erkély" + size: 5.84 + parent: FacilityLocation_204 + FacilityLocation_205: + roomNumber: "205" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_205e: + roomNumber: "205e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_205 + FacilityLocation_205f: + roomNumber: "205f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_205 + FacilityLocation_205t: + roomNumber: "205t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_205 + FacilityLocation_206: + roomNumber: "206" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_206e: + roomNumber: "206e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_206 + FacilityLocation_206f: + roomNumber: "206f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_206 + FacilityLocation_206t: + roomNumber: "206t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_206 + FacilityLocation_207: + roomNumber: "207" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_207e: + roomNumber: "207e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_207 + FacilityLocation_207f: + roomNumber: "207f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_207 + FacilityLocation_207t: + roomNumber: "207t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_207 + FacilityLocation_208: + roomNumber: "208" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_208e: + roomNumber: "208e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_208 + FacilityLocation_208f: + roomNumber: "208f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_208 + FacilityLocation_208t: + roomNumber: "208t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_208 + FacilityLocation_209: + roomNumber: "209" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_209e: + roomNumber: "209e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_209 + FacilityLocation_209f: + roomNumber: "209f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_209 + FacilityLocation_209t: + roomNumber: "209t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_209 + FacilityLocation_210: + roomNumber: "210" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_210e: + roomNumber: "210e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_210 + FacilityLocation_210f: + roomNumber: "210f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_210 + FacilityLocation_210t: + roomNumber: "210t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_210 + FacilityLocation_211: + roomNumber: "211" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_211e: + roomNumber: "211e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_211 + FacilityLocation_211f: + roomNumber: "211f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_211 + FacilityLocation_211t: + roomNumber: "211t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_211 + FacilityLocation_212: + roomNumber: "212" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_212e: + roomNumber: "212e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_212 + FacilityLocation_212f: + roomNumber: "212f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_212 + FacilityLocation_212t: + roomNumber: "212t" + name: erkély + size: 5.54 + parent: FacilityLocation_212 + FacilityLocation_213: + roomNumber: "213" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_213e: + roomNumber: "213e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_213 + FacilityLocation_213f: + roomNumber: "213f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_213 + FacilityLocation_213t: + roomNumber: "213t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_213 + FacilityLocation_214: + roomNumber: "214" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_214e: + roomNumber: "214e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_214 + FacilityLocation_214f: + roomNumber: "214f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_214 + FacilityLocation_214t: + roomNumber: "214t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_214 + FacilityLocation_215: + roomNumber: "215" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_215e: + roomNumber: "215e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_215 + FacilityLocation_215f: + roomNumber: "215f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_215 + FacilityLocation_215t: + roomNumber: "215t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_215 + FacilityLocation_216: + roomNumber: "216" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_216e: + roomNumber: "216e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_216 + FacilityLocation_216f: + roomNumber: "216f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_216 + FacilityLocation_216t: + roomNumber: "216t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_216 + FacilityLocation_217: + roomNumber: "217" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_217e: + roomNumber: "217e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_217 + FacilityLocation_217f: + roomNumber: "217f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_217 + FacilityLocation_217t: + roomNumber: "217t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_217 + FacilityLocation_218: + roomNumber: "218" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_218e: + roomNumber: "218e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_218 + FacilityLocation_218f: + roomNumber: "218f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_218 + FacilityLocation_218t: + roomNumber: "218t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_218 + FacilityLocation_219: + roomNumber: "219" + name: "szoba V." + size: 19.70 + parent: FacilityLocation_2 + FacilityLocation_219e: + roomNumber: "219e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_219 + FacilityLocation_219f: + roomNumber: "219f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_219 + FacilityLocation_219t: + roomNumber: "219t" + name: "erkély" + size: 6.39 + parent: FacilityLocation_219 + FacilityLocation_220: + roomNumber: "220" + name: "elektromos kapcsolótér" + size: 1.87 + parent: FacilityLocation_2 + FacilityLocation_221: + roomNumber: "221" + name: "szoba III." + size: 18.68 + parent: FacilityLocation_2 + FacilityLocation_221e: + roomNumber: "221e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_221 + FacilityLocation_221f: + roomNumber: "221f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_221 + FacilityLocation_221t: + roomNumber: "221t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_221 + FacilityLocation_222: + roomNumber: "222" + name: "szoba VI." + size: 21.70 + parent: FacilityLocation_2 + FacilityLocation_222e: + roomNumber: "222e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_222 + FacilityLocation_222f: + roomNumber: "222f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_222 + FacilityLocation_222t: + roomNumber: "222t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_222 + FacilityLocation_223: + roomNumber: "223" + name: "szoba I." + size: 16.85 + parent: FacilityLocation_2 + FacilityLocation_223e: + roomNumber: "223e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_223 + FacilityLocation_223f: + roomNumber: "223f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_223 + FacilityLocation_223t: + roomNumber: "223t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_223 + FacilityLocation_224: + roomNumber: "224" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_224e: + roomNumber: "224e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_224 + FacilityLocation_224f: + roomNumber: "224f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_224 + FacilityLocation_224t: + roomNumber: "224t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_224 + FacilityLocation_225: + roomNumber: "225" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_225e: + roomNumber: "225e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_225 + FacilityLocation_225f: + roomNumber: "225f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_225 + FacilityLocation_225t: + roomNumber: "225t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_225 + FacilityLocation_226: + roomNumber: "226" + name: "szoba I." + size: 16.73 + parent: FacilityLocation_2 + FacilityLocation_226e: + roomNumber: "226e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_226 + FacilityLocation_226f: + roomNumber: "226f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_226 + FacilityLocation_226t: + roomNumber: "226t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_226 + FacilityLocation_227: + roomNumber: "227" + name: "szoba I." + size: 13.17 + parent: FacilityLocation_2 + FacilityLocation_227n: + roomNumber: "227n" + name: "nappali" + size: 20.70 + parent: FacilityLocation_227 + FacilityLocation_227e: + roomNumber: "227e" + name: "előtér" + size: 6.27 + parent: FacilityLocation_227 + FacilityLocation_227f: + roomNumber: "227f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_227 + FacilityLocation_227k: + roomNumber: "227k" + name: "konyha" + size: 5.26 + parent: FacilityLocation_227 + FacilityLocation_227t: + roomNumber: "227t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_227 + FacilityLocation_227tn: + roomNumber: "227tn" + name: "erkély" + size: 5.54 + parent: FacilityLocation_227 + FacilityLocation_228: + roomNumber: "228" + name: "szoba" + size: 20.70 + parent: FacilityLocation_2 + FacilityLocation_228e: + roomNumber: "228e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_228 + FacilityLocation_228f: + roomNumber: "228f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_228 + FacilityLocation_228t: + roomNumber: "228t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_228 + FacilityLocation_229: + roomNumber: "229" + name: "szoba II." + size: 17.22 + parent: FacilityLocation_2 + FacilityLocation_229e: + roomNumber: "229e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_229 + FacilityLocation_229f: + roomNumber: "229f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_229 + FacilityLocation_229t: + roomNumber: "229t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_229 + FacilityLocation_230: + roomNumber: "230" + name: "szoba" + size: 20.70 + parent: FacilityLocation_2 + FacilityLocation_230e: + roomNumber: "230e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_230 + FacilityLocation_230f: + roomNumber: "230f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_230 + FacilityLocation_230t: + roomNumber: "230t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_230 + FacilityLocation_231: + roomNumber: "231" + name: "menekülési ajtó külső lépcsővel" + size: 0 + parent: FacilityLocation_2 + FacilityLocation_232: + roomNumber: "232" + name: "szoba II." + size: 17.22 + parent: FacilityLocation_2 + FacilityLocation_232e: + roomNumber: "232e" + name: "előtér" + size: 2.04 + parent: FacilityLocation_232 + FacilityLocation_232f: + roomNumber: "232f" + name: "fürdő" + size: 3.85 + parent: FacilityLocation_232 + FacilityLocation_232t: + roomNumber: "232t" + name: "erkély" + size: 5.54 + parent: FacilityLocation_232 + FacilityLocation_233: + roomNumber: "233" + name: "lépcsőház - lift eleőtér" + size: 25.86 + parent: FacilityLocation_2 + FacilityLocation_233lk: + roomNumber: "233lk" + name: "lépcsőkarok pihenővel" + size: 15.12 + parent: FacilityLocation_2 + FacilityLocation_234: + roomNumber: "234" + name: "tároló" + size: 0.98 + parent: FacilityLocation_2 + FacilityLocation_235: + roomNumber: "235" + name: "közlekedő" + size: 46.03 + parent: FacilityLocation_2 + FacilityLocation_236: + roomNumber: "236" + name: "lift előtér telefonos sarokkal" + size: 18.00 + parent: FacilityLocation_2 + FacilityLocation_236lk: + roomNumber: "236lk" + name: "lépcsőkarok pihenővel" + size: 17.82 + parent: FacilityLocation_2 + +# __3__ első emeleti helyiségek + FacilityLocation_301: + roomNumber: "301" + name: "mozgássérült szoba" + size: 22.44 + parent: FacilityLocation_3 + FacilityLocation_301e: + roomNumber: "301e" + name: "előtér" + size: 4.88 + parent: FacilityLocation_301 + FacilityLocation_301f: + roomNumber: "301f" + name: "fürdő" + size: 5.08 + parent: FacilityLocation_301 + FacilityLocation_301t: + roomNumber: "301t" + name: "erkély" + size: 6.35 + parent: FacilityLocation_301 + FacilityLocation_302: + roomNumber: "302" + name: "elektromos kapcsolótér" + size: 1.87 + parent: FacilityLocation_3 + FacilityLocation_303: + roomNumber: "303" + name: "iroda" + size: 27.47 + parent: FacilityLocation_3 + FacilityLocation_303e: + roomNumber: "303e" + name: "előtér" + size: 4.32 + parent: FacilityLocation_303 + FacilityLocation_303_1: + roomNumber: "303/1" + name: "számtech. elosztó" + size: 3.66 + parent: FacilityLocation_303 + FacilityLocation_303t: + roomNumber: "303t" + name: "erkély" + size: 5.13 + parent: FacilityLocation_303 + FacilityLocation_304: + roomNumber: "304" + name: "szoba V." + size: 17.72 + parent: FacilityLocation_3 + FacilityLocation_304e: + roomNumber: "304e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_304 + FacilityLocation_304f: + roomNumber: "304f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_304 + FacilityLocation_304t: + roomNumber: "304t" + name: "erkély" + size: 5.38 + parent: FacilityLocation_304 + FacilityLocation_305: + roomNumber: "305" + name: "iroda" + size: 25.09 + parent: FacilityLocation_3 + FacilityLocation_305t: + roomNumber: "305t" + name: "erkély" + size: 5.33 + parent: FacilityLocation_305 + FacilityLocation_306: + roomNumber: "306" + name: "szoba I." + size: 16.98 + parent: FacilityLocation_3 + FacilityLocation_306e: + roomNumber: "306e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_306 + FacilityLocation_306f: + roomNumber: "306f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_306 + FacilityLocation_306t: + roomNumber: "306t" + name: "erkély" + size: 5.38 + parent: FacilityLocation_306 + FacilityLocation_307: + roomNumber: "307" + name: "szoba I." + size: 16.98 + parent: FacilityLocation_3 + FacilityLocation_307e: + roomNumber: "307e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_307 + FacilityLocation_307f: + roomNumber: "307f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_307 + FacilityLocation_307t: + roomNumber: "307t" + name: "erkély" + size: 5.33 + parent: FacilityLocation_307 + FacilityLocation_308: + roomNumber: "308" + name: "szoba I." + size: 16.98 + parent: FacilityLocation_3 + FacilityLocation_308e: + roomNumber: "308e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_308 + FacilityLocation_308f: + roomNumber: "308f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_308 + FacilityLocation_308t: + roomNumber: "308t" + name: "erkély" + size: 5.38 + parent: FacilityLocation_308 + FacilityLocation_309: + roomNumber: "309" + name: "szoba I." + size: 16.98 + parent: FacilityLocation_3 + FacilityLocation_309e: + roomNumber: "309e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_309 + FacilityLocation_309f: + roomNumber: "309f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_309 + FacilityLocation_309t: + roomNumber: "309t" + name: "erkély" + size: 5.33 + parent: FacilityLocation_309 + FacilityLocation_310: + roomNumber: "310" + name: "szoba I." + size: 16.98 + parent: FacilityLocation_3 + FacilityLocation_310e: + roomNumber: "310e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_310 + FacilityLocation_310f: + roomNumber: "310f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_310 + FacilityLocation_310t: + roomNumber: "310t" + name: "erkély" + size: 5.38 + parent: FacilityLocation_310 + FacilityLocation_311: + roomNumber: "311" + name: "szoba I." + size: 16.98 + parent: FacilityLocation_3 + FacilityLocation_311e: + roomNumber: "311e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_311 + FacilityLocation_311f: + roomNumber: "311f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_311 + FacilityLocation_311t: + roomNumber: "311t" + name: "erkély" + size: 5.33 + parent: FacilityLocation_311 + FacilityLocation_312: + roomNumber: "312" + name: "szoba I." + size: 16.98 + parent: FacilityLocation_3 + FacilityLocation_312e: + roomNumber: "312e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_312 + FacilityLocation_312f: + roomNumber: "312f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_312 + FacilityLocation_312t: + roomNumber: "312t" + name: "erkély" + size: 5.38 + parent: FacilityLocation_312 + FacilityLocation_313: + roomNumber: "313" + name: "szoba I." + size: 16.98 + parent: FacilityLocation_3 + FacilityLocation_313e: + roomNumber: "313e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_313 + FacilityLocation_313f: + roomNumber: "313f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_313 + FacilityLocation_313t: + roomNumber: "313t" + name: "erkély" + size: 5.33 + parent: FacilityLocation_313 + FacilityLocation_314: + roomNumber: "314" + name: "szoba I." + size: 16.98 + parent: FacilityLocation_3 + FacilityLocation_314e: + roomNumber: "314e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_314 + FacilityLocation_314f: + roomNumber: "314f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_314 + FacilityLocation_314t: + roomNumber: "314t" + name: "erkély" + size: 5.38 + parent: FacilityLocation_314 + FacilityLocation_315: + roomNumber: "315" + name: "szoba I." + size: 16.98 + parent: FacilityLocation_3 + FacilityLocation_315e: + roomNumber: "315e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_315 + FacilityLocation_315f: + roomNumber: "315f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_315 + FacilityLocation_315t: + roomNumber: "315t" + name: "erkély" + size: 5.33 + parent: FacilityLocation_315 + FacilityLocation_316: + roomNumber: "316" + name: "szoba I." + size: 16.98 + parent: FacilityLocation_3 + FacilityLocation_316e: + roomNumber: "316e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_316 + FacilityLocation_316f: + roomNumber: "316f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_316 + FacilityLocation_316t: + roomNumber: "316t" + name: "erkély" + size: 5.38 + parent: FacilityLocation_316 + FacilityLocation_317: + roomNumber: "317" + name: "szoba I." + size: 16.98 + parent: FacilityLocation_3 + FacilityLocation_317e: + roomNumber: "317e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_317 + FacilityLocation_317f: + roomNumber: "317f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_317 + FacilityLocation_317t: + roomNumber: "317t" + name: "erkély" + size: 5.33 + parent: FacilityLocation_317 + FacilityLocation_318: + roomNumber: "318" + name: "szoba IV." + size: 16.48 + parent: FacilityLocation_3 + FacilityLocation_318e: + roomNumber: "318e" + name: "előtér" + size: 3.89 + parent: FacilityLocation_318 + FacilityLocation_318f: + roomNumber: "318f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_318 + FacilityLocation_318t: + roomNumber: "318t" + name: "erkély" + size: 5.38 + parent: FacilityLocation_318 + FacilityLocation_319: + roomNumber: "319" + name: "szoba V." + size: 20.07 + parent: FacilityLocation_3 + FacilityLocation_319e: + roomNumber: "319e" + name: "előtér" + size: 3.66 + parent: FacilityLocation_319 + FacilityLocation_319f: + roomNumber: "319f" + name: "fürdő" + size: 3.65 + parent: FacilityLocation_319 + FacilityLocation_319t: + roomNumber: "319t" + name: "erkély" + size: 6.10 + parent: FacilityLocation_319 + FacilityLocation_320: + roomNumber: "320" + name: "iroda" + size: 21.69 + parent: FacilityLocation_3 + FacilityLocation_320t: + roomNumber: "320t" + name: "erkély" + size: 5.38 + parent: FacilityLocation_320 + FacilityLocation_321: + roomNumber: "321" + name: "iroda" + size: 18.42 + parent: FacilityLocation_3 + FacilityLocation_321t: + roomNumber: "321t" + name: "erkély" + size: 5.33 + parent: FacilityLocation_321 + FacilityLocation_322: + roomNumber: "322" + name: "iroda" + size: 25.17 + parent: FacilityLocation_3 + FacilityLocation_322t: + roomNumber: "322t" + name: "erkély" + size: 5.376 + parent: FacilityLocation_322 + FacilityLocation_323: + roomNumber: "323" + name: "iroda" + size: 16.85 + parent: FacilityLocation_3 + FacilityLocation_323t: + roomNumber: "323t" + name: "erkély" + size: 5.33 + parent: FacilityLocation_323 + FacilityLocation_324: + roomNumber: "324" + name: "iroda" + size: 25.17 + parent: FacilityLocation_3 + FacilityLocation_324t: + roomNumber: "324t" + name: "erkély" + size: 5.38 + parent: FacilityLocation_324 + FacilityLocation_325: + roomNumber: "325" + name: "iroda" + size: 16.73 + parent: FacilityLocation_3 + FacilityLocation_325t: + roomNumber: "325t" + name: "erkély" + size: 5.33 + parent: FacilityLocation_325 + FacilityLocation_326: + roomNumber: "326" + name: "iroda" + size: 25.17 + parent: FacilityLocation_3 + FacilityLocation_326t: + roomNumber: "326t" + name: "erkély" + size: 5.38 + parent: FacilityLocation_326 + FacilityLocation_327: + roomNumber: "327" + name: "iroda" + size: 16.75 + parent: FacilityLocation_3 + FacilityLocation_327t: + roomNumber: "327t" + name: "erkély" + size: 5.33 + parent: FacilityLocation_327 + FacilityLocation_328a: + roomNumber: "328a" + name: "tárgyaló" + size: 37.31 + parent: FacilityLocation_3 + FacilityLocation_328at: + roomNumber: "328at" + name: "erkély" + size: 5.38 + parent: FacilityLocation_328a + FacilityLocation_328b: + roomNumber: "328b" + name: "konyha-étkező" + size: 24.02 + parent: FacilityLocation_3 + FacilityLocation_328bt: + roomNumber: "328bt" + name: "konyha-étkező" + size: 24.02 + parent: FacilityLocation_328b + FacilityLocation_329: + roomNumber: "329" + name: "iroda" + size: 012.12 + parent: FacilityLocation_3 + FacilityLocation_329t: + roomNumber: "329t" + name: "erkély" + size: 6.02 + parent: FacilityLocation_329 + FacilityLocation_330: + roomNumber: "330" + name: "közlekedő" + size: 12.20 + parent: FacilityLocation_3 + FacilityLocation_330t: + roomNumber: "330t" + name: "erkély" + size: 5.38 + parent: FacilityLocation_330 + FacilityLocation_331: + roomNumber: "331" + name: "iroda" + size: 12.48 + parent: FacilityLocation_3 + FacilityLocation_332: + roomNumber: "332" + name: "ffi. WC mosdóval" + size: 2.76 + parent: FacilityLocation_3 + FacilityLocation_333: + roomNumber: "333" + name: "raktár" + size: 4.65 + parent: FacilityLocation_3 + FacilityLocation_334: + roomNumber: "334" + name: "közlekedő" + size: 27.76 + parent: FacilityLocation_3 + FacilityLocation_335: + roomNumber: "335" + name: "fénymásoló" + size: 8.86 + parent: FacilityLocation_3 + FacilityLocation_336: + roomNumber: "336" + name: "menekülési ajtó külső lépcsővel" + size: 0 + parent: FacilityLocation_3 + FacilityLocation_337: + roomNumber: "337" + name: "társalgó" + size: 31.04 + parent: FacilityLocation_3 + FacilityLocation_338: + roomNumber: "338" + name: "női WC mosdóval" + size: 3.79 + parent: FacilityLocation_3 + FacilityLocation_339: + roomNumber: "339" + name: "közlekedő" + size: 19.33 + parent: FacilityLocation_3 + FacilityLocation_340: + roomNumber: "340" + name: "akadálymentes WC" + size: 3.81 + parent: FacilityLocation_3 + FacilityLocation_341: + roomNumber: "341" + name: "lift előtér telefonos sarokkal" + size: 10.00 + parent: FacilityLocation_3 + FacilityLocation_341lk: + roomNumber: "341lk" + name: "lépcsőkarok pihenővel" + size: 17.82 + parent: FacilityLocation_3 + FacilityLocation_342: + roomNumber: "342" + name: "közlekedő" + size: 8.64 + parent: FacilityLocation_3 + FacilityLocation_343: + roomNumber: "343" + name: "közlekedő" + size: 67.84 + parent: FacilityLocation_3 + FacilityLocation_344: + roomNumber: "344" + name: "lépcsőház" + size: 25.86 + parent: FacilityLocation_3 + FacilityLocation_344lk: + roomNumber: "344lk" + name: "lépcsőkarok pihenővel" + size: 15.12 + parent: FacilityLocation_3 + + +# __4__ első emeleti helyiségek + FacilityLocation_401: + roomNumber: "401" + name: "ruhatár" + size: 11.23 + parent: FacilityLocation_4 + FacilityLocation_402: + roomNumber: "402" + name: "előtér" + size: 7.75 + parent: FacilityLocation_4 + FacilityLocation_403: + roomNumber: "403" + name: "székraktár" + size: 27.59 + parent: FacilityLocation_4 + FacilityLocation_404: + roomNumber: "404" + name: "női WC mosdóval" + size: 9.22 + parent: FacilityLocation_4 + FacilityLocation_405: + roomNumber: "405" + name: "mosdó" + size: 1.98 + parent: FacilityLocation_4 + FacilityLocation_406: + roomNumber: "406" + name: "ffi. WC" + size: 7.50 + parent: FacilityLocation_4 + FacilityLocation_407: + roomNumber: "407" + name: "mozgássérült WC" + size: 3.24 + parent: FacilityLocation_4 + FacilityLocation_408: + roomNumber: "408" + name: "kistanácsterem" + size: 82.26 + parent: FacilityLocation_4 + FacilityLocation_409: + roomNumber: "409" + name: "kistanácsterem" + size: 81.11 + parent: FacilityLocation_4 + FacilityLocation_409tK: + roomNumber: "409tK" + name: "erkély keleti oldal" + size: 93.36 + parent: FacilityLocation_4 + FacilityLocation_410: + roomNumber: "410" + name: "belépő" + size: 2.05 + parent: FacilityLocation_4 + FacilityLocation_411: + roomNumber: "411" + name: "tolmácsfülke" + size: 6.25 + parent: FacilityLocation_4 + FacilityLocation_412: + roomNumber: "412" + name: "tolmácsfülke" + size: 6.25 + parent: FacilityLocation_4 + FacilityLocation_413: + roomNumber: "413" + name: "női WC mosdóval" + size: 4.31 + parent: FacilityLocation_4 + FacilityLocation_414: + roomNumber: "414" + name: "ffi. WC mosdóval" + size: 10.92 + parent: FacilityLocation_4 + FacilityLocation_415: + roomNumber: "415" + name: "közlekedő" + size: 36.19 + parent: FacilityLocation_4 + FacilityLocation_416: + roomNumber: "416" + name: "computer szoba" + size: 26.64 + parent: FacilityLocation_4 + FacilityLocation_417: + roomNumber: "417" + name: "csoportvezetői szoba" + size: 27.81 + parent: FacilityLocation_4 + FacilityLocation_418: + roomNumber: "418" + name: "takrítószer tároló" + size: 3.31 + parent: FacilityLocation_4 + FacilityLocation_419: + roomNumber: "419" + name: "hidraulika" + size: 5.46 + parent: FacilityLocation_4 + FacilityLocation_420: + roomNumber: "420" + name: "lift előtér - lépcsőház" + size: 7.92 + parent: FacilityLocation_4 + FacilityLocation_421lk: + roomNumber: "421lk" + name: "lépcsőkarok pihenővel" + size: 14.55 + parent: FacilityLocation_4 + FacilityLocation_421: + roomNumber: "421" + name: "tároló" + size: 0.98 + parent: FacilityLocation_4 + FacilityLocation_422: + roomNumber: "422" + name: "előcsarnok" + size: 229.81 + parent: FacilityLocation_4 + FacilityLocation_422tNY: + roomNumber: "422tNY" + name: "erkély nyugati oldal" + size: 93.36 + parent: FacilityLocation_4 + FacilityLocation_422lk: + roomNumber: "422lk" + name: "lépcsőkarok pihenővel" + size: 17.82 + parent: FacilityLocation_4 + FacilityLocation_423: + roomNumber: "423" + name: "elektromos kapcsolótér" + size: 2.94 + parent: FacilityLocation_4 + FacilityLocation_424: + roomNumber: "424" + name: "teakonyha" + size: 7.41 + parent: FacilityLocation_4 + FacilityLocation_425: + roomNumber: "425" + name: "tolmácsfülke" + size: 9.69 + parent: FacilityLocation_4 + FacilityLocation_426: + roomNumber: "426" + name: "tolmácsfülke" + size: 6.00 + parent: FacilityLocation_4 + FacilityLocation_427: + roomNumber: "427" + name: "közlekedő" + size: 2.59 + parent: FacilityLocation_4 + FacilityLocation_428: + roomNumber: "428" + name: "osztható tanácsterem" + size: 283.49 + parent: FacilityLocation_4 + FacilityLocation_429: + roomNumber: "429" + name: "közlekedő" + size: 31.26 + parent: FacilityLocation_4 + FacilityLocation_430: + roomNumber: "430" + name: "menekülési ajtó külső lépcsővel" + size: 0 + parent: FacilityLocation_4 + FacilityLocation_431: + roomNumber: "431" + name: "tolmácsfülke" + size: 6.00 + parent: FacilityLocation_4 + FacilityLocation_432: + roomNumber: "432" + name: "tolmácsfülke" + size: 6.00 + parent: FacilityLocation_4 + FacilityLocation_433: + roomNumber: "433" + name: "stúdió" + size: 4.56 + parent: FacilityLocation_4 + FacilityLocation_434: + roomNumber: "434" + name: "tolmácsfülke" + size: 6.00 + parent: FacilityLocation_4 + FacilityLocation_435: + roomNumber: "435" + name: "tolmácsfülke" + size: 6.00 + parent: FacilityLocation_4 diff --git a/data/fixture/solution-time-interval.yml b/data/fixture/solution-time-interval.yml new file mode 100644 index 0000000..f3180d7 --- /dev/null +++ b/data/fixture/solution-time-interval.yml @@ -0,0 +1,11 @@ +SolutionTimeIntervals: + SolutionTimeInterval_1: + id: 1 + name: "Sürgős" + code: "S" + active: true + SolutionTimeInterval_2: + id: 2 + name: "Normál" + code: "N" + active: true diff --git a/data/fixture/user.yml b/data/fixture/user.yml new file mode 100644 index 0000000..7d8aaa5 --- /dev/null +++ b/data/fixture/user.yml @@ -0,0 +1,255 @@ +Users: + User_1: + id: 1 + name: Dávid + email: yvan@yvan.hu + wantsEmail: true + job: tesztelő + phone: "+36 1 123 4567" + roles: admin + active: true +# uzemeltetesi_vezeto + User_MajorosZoltan: + id: 10 + name: Majoros Zoltán + email: techsupport.eycb@coe.int + wantsEmail: false + job: technical support + phone: "+36-1-438-0174" + roles: uzemeltetesi_vezeto + active: true + canChangePassword: false + User_RozsaSandor: + id: 11 + name: Rózsa Sándor + email: techsupport.eycb@coe.int + wantsEmail: false + job: technical support + phone: "+36-1-438-0174" + roles: uzemeltetesi_vezeto + active: true + canChangePassword: false + User_HorvathCsaba: + id: 12 + name: Horváth Csaba + email: techsupport.eycb@coe.int + wantsEmail: false + job: technical support + phone: "+36-1-438-0174" + roles: uzemeltetesi_vezeto + active: true + canChangePassword: false + User_PohlottLaszlo: + id: 13 + name: Pohlott László + email: techsupport.eycb@coe.int + wantsEmail: false + job: technical support + phone: "+36-1-438-0174" + roles: uzemeltetesi_vezeto + active: true + canChangePassword: false + User_BalogKaroly: + id: 14 + name: Balog Károly + email: keyrm.beik@gmail.com + wantsEmail: false + job: biztonsági szolgálat + phone: "+36-1-438-1041" + roles: uzemeltetesi_vezeto + active: true + canChangePassword: false + User_SzenteRoland: + id: 15 + name: Szente Roland + email: keyrm.beik@gmail.com + wantsEmail: false + job: biztonsági szolgálat + phone: "+36-1-438-1041" + roles: uzemeltetesi_vezeto + active: true + canChangePassword: false + User_NekamIstvan: + id: 16 + name: Nékám István + email: keyrm.beik@gmail.com + wantsEmail: false + job: biztonsági szolgálat + phone: "+36-1-438-1041" + roles: uzemeltetesi_vezeto + active: true + canChangePassword: false + User_KotroczoIstvan: + id: 17 + name: Kotroczó István + email: keyrm.beik@gmail.com + wantsEmail: false + job: biztonsági szolgálat + phone: "+36-1-438-1041" + roles: uzemeltetesi_vezeto + active: true + canChangePassword: false + User_LandszmannZsolt: + id: 18 + name: LandszmannZsolt + email: keyrm.beik@gmail.com + wantsEmail: false + job: biztonsági szolgálat + phone: "+36-1-438-1041" + roles: uzemeltetesi_vezeto + active: true + canChangePassword: false + User_GoliczaZoltan: + id: 19 + name: Golicza Zoltán + email: keyrm.beik@gmail.com + wantsEmail: false + job: biztonsági szolgálat + phone: "+36-1-438-1041" + roles: uzemeltetesi_vezeto + active: true + canChangePassword: false + User_EckermannTibor: + id: 20 + name: Eckermann Tibor + email: keyrm.beik@gmail.com + wantsEmail: false + job: biztonsági szolgálat + phone: "+36-1-438-1041" + roles: uzemeltetesi_vezeto + active: true + canChangePassword: false + User_FarkasAndras: + id: 21 + name: Farkas András + email: keyrm.beik@gmail.com + wantsEmail: false + job: biztonsági szolgálat + phone: "+36-1-438-1041" + roles: uzemeltetesi_vezeto + active: true + canChangePassword: false + User_SimonZoltan: + id: 22 + name: Simon Zoltán + email: keyrm.beik@gmail.com + wantsEmail: false + job: biztonsági szolgálat + phone: "+36-1-438-1041" + roles: uzemeltetesi_vezeto + active: true + canChangePassword: false + User_ZsoldosGeza: + id: 23 + name: Zsoldos Géza + email: keyrm.beik@gmail.com + wantsEmail: false + job: biztonsági szolgálat + phone: "+36-1-438-1041" + roles: uzemeltetesi_vezeto + active: true + canChangePassword: false + User_MareschDavid: + id: 24 + name: Maresch Dávid + email: keyrm.beik@gmail.com + wantsEmail: false + job: biztonsági szolgálat + phone: "+36-1-438-1041" + roles: uzemeltetesi_vezeto + active: true + canChangePassword: false + User_BuczkoAttila: + id: 25 + name: Buczkó Attila + email: attila.buczko@coe.int + wantsEmail: true + job: technikus + phone: "+36-1-438-1078" + roles: uzemeltetesi_vezeto + active: true + User_KedveCsaba: + id: 26 + name: Kedve Csaba + email: csaba.kedves@coe.int + wantsEmail: true + job: üzemeltetési vezető + phone: "+36-1-438-1079" + roles: uzemeltetesi_vezeto + active: true +# ufo + User_DrHeimPeter: + id: 40 + name: Dr. Heim Péter + email: peter.heim@mfa.gov.hu + wantsEmail: true + job: főosztályvezető h. + phone: "" + roles: ufo + active: true + User_KrivdaLaszlo: + id: 41 + name: Krivda László + email: krivda@t-online.hu + wantsEmail: true + job: műszaki ellenőr + phone: "+36 30 942 9072" + roles: ufo + active: true +# betekinto + User_BaloghGabor: + id: 60 + name: Balogh Gábor + email: gabor.balogh@mfa.gov.hu + wantsEmail: true + job: főosztályvezető + phone: "" + roles: betekinto + active: true + User_CsicselyTibor: + id: 61 + name: Csicsely Tibor + email: csicselyt@laterex.hu + wantsEmail: true + job: ügyvezető + phone: "+36 30 555 3634" + roles: betekinto + active: true +# projektvezeto + User_HantzmannGergely: + id: 82 + name: Hantzmann Gergely + email: hantzmanng@laterex.hu + wantsEmail: true + job: karbantartási csv. + phone: "+36 30 181 3591" + roles: projektvezeto,karbantarto + active: true + User_KovacsLudovit: + id: 83 + name: Kovác Ludovit + email: kovacl@laterex.hu + wantsEmail: true + job: projektvezető + phone: "+36 30 257 4183" + roles: projektvezeto + active: true +# karbantarto + User_MeszarosBela: + id: 90 + name: Mészáros Béla + email: karbantarto1@laterex.hu + wantsEmail: false + job: karbantartó + phone: "" + roles: karbantarto + active: true + User_SzathmaryZsoltMiklos: + id: 91 + name: Szathmáry Zsolt Miklos + email: karbantarto2@laterex.hu + wantsEmail: false + job: karbantartó + phone: "" + roles: karbantarto + active: true diff --git a/data/mail-template/faultFooter.txt b/data/mail-template/faultFooter.txt new file mode 100644 index 0000000..4f4d0ec --- /dev/null +++ b/data/mail-template/faultFooter.txt @@ -0,0 +1,3 @@ +Ez az értesítés egy automatikusan generált levél, ne válaszoljon rá. +Amennyiben módosítani kívánja az értesítési beállításait azt megteheti a %%WEBNAPLO_URI%% címen, +felhasználói beállítások menüpont alatt. \ No newline at end of file diff --git a/data/mail-template/faultHeader.txt b/data/mail-template/faultHeader.txt new file mode 100644 index 0000000..71cca02 --- /dev/null +++ b/data/mail-template/faultHeader.txt @@ -0,0 +1,10 @@ +Intézményerész: %%FACILITY_LOCATION%% +Intézményrész pontosítva: +%%FACILITY_LOCATION_DESCRIPTION%% + +Hiba szakág: %%ERROR_CATEGORY%% +Hiba eredet: %%ERROR_ORIGIN%% +Hiba leírás: +%%ERROR_DESCRIPTION%% + +Hiba javítás ideje: %%SOLUTION_TIME%% \ No newline at end of file diff --git a/data/pdf-resources/asdf b/data/pdf-resources/asdf new file mode 100644 index 0000000..74ab59c --- /dev/null +++ b/data/pdf-resources/asdf @@ -0,0 +1,4 @@ + + + + + + + + + \ No newline at end of file diff --git a/data/pdf-resources/fonts/Times_New_Roman.ttf b/data/pdf-resources/fonts/Times_New_Roman.ttf new file mode 100644 index 0000000..55f734a Binary files /dev/null and b/data/pdf-resources/fonts/Times_New_Roman.ttf differ diff --git a/data/pdf-resources/fonts/Times_New_Roman_Bold.ttf b/data/pdf-resources/fonts/Times_New_Roman_Bold.ttf new file mode 100644 index 0000000..0fc9d84 Binary files /dev/null and b/data/pdf-resources/fonts/Times_New_Roman_Bold.ttf differ diff --git a/data/pdf-resources/fonts/Times_New_Roman_Bold_Italic.ttf b/data/pdf-resources/fonts/Times_New_Roman_Bold_Italic.ttf new file mode 100644 index 0000000..8a6266f Binary files /dev/null and b/data/pdf-resources/fonts/Times_New_Roman_Bold_Italic.ttf differ diff --git a/data/pdf-resources/fonts/Times_New_Roman_Italic.ttf b/data/pdf-resources/fonts/Times_New_Roman_Italic.ttf new file mode 100644 index 0000000..a326a5c Binary files /dev/null and b/data/pdf-resources/fonts/Times_New_Roman_Italic.ttf differ diff --git a/data/pdf-resources/laterex-logo.png b/data/pdf-resources/laterex-logo.png new file mode 100644 index 0000000..08ead05 Binary files /dev/null and b/data/pdf-resources/laterex-logo.png differ diff --git a/data/pdf-template/maintenanceSheet-style.xml b/data/pdf-template/maintenanceSheet-style.xml new file mode 100644 index 0000000..02764e5 --- /dev/null +++ b/data/pdf-template/maintenanceSheet-style.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ + +
+ +
+ +
+ +
+ +
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + +
+ + + + + + + +
+ +
\ No newline at end of file diff --git a/data/pdf-template/maintenanceSheet.xml b/data/pdf-template/maintenanceSheet.xml new file mode 100644 index 0000000..6d843fe --- /dev/null +++ b/data/pdf-template/maintenanceSheet.xml @@ -0,0 +1,168 @@ + + + + + + + + + + +
+ + + + + + + + + +
+
+ + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
+ + + + + + + + + + +
+ + + + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + +
+ +
+
\ No newline at end of file diff --git a/data/pdf-template/monthlyReport-style.xml b/data/pdf-template/monthlyReport-style.xml new file mode 100644 index 0000000..bd60bde --- /dev/null +++ b/data/pdf-template/monthlyReport-style.xml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + + + +
+ + + +
+ +
+
\ No newline at end of file diff --git a/data/pdf-template/monthlyReport.xml b/data/pdf-template/monthlyReport.xml new file mode 100644 index 0000000..3114316 --- /dev/null +++ b/data/pdf-template/monthlyReport.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + +
  
  
+ + + + + + + + + + + + + + + + %%TABLE_DATA%% + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
 
 
 
 
+ + + + + + + + + + +
+
+
\ No newline at end of file diff --git a/data/pdf-template/monthlyReport/fault.xml b/data/pdf-template/monthlyReport/fault.xml new file mode 100644 index 0000000..dc5a8fe --- /dev/null +++ b/data/pdf-template/monthlyReport/fault.xml @@ -0,0 +1,8 @@ + + + +   + +   +   + \ No newline at end of file diff --git a/data/pdf-template/monthlyReport/faultCostItem.xml b/data/pdf-template/monthlyReport/faultCostItem.xml new file mode 100644 index 0000000..9d4b927 --- /dev/null +++ b/data/pdf-template/monthlyReport/faultCostItem.xml @@ -0,0 +1,11 @@ + +   + +   + + + + +   + 0 + \ No newline at end of file diff --git a/data/pdf-template/monthlyReport/faultCostLate.xml b/data/pdf-template/monthlyReport/faultCostLate.xml new file mode 100644 index 0000000..d78684f --- /dev/null +++ b/data/pdf-template/monthlyReport/faultCostLate.xml @@ -0,0 +1,11 @@ + +   + +   + + + +   +   + + \ No newline at end of file diff --git a/data/pdf-template/monthlyReport/faultCostWork.xml b/data/pdf-template/monthlyReport/faultCostWork.xml new file mode 100644 index 0000000..cfb2ece --- /dev/null +++ b/data/pdf-template/monthlyReport/faultCostWork.xml @@ -0,0 +1,11 @@ + +   + +   +   +   +   +   + + + \ No newline at end of file diff --git a/data/pdf-template/monthlyReport/institute.xml b/data/pdf-template/monthlyReport/institute.xml new file mode 100644 index 0000000..c511f4f --- /dev/null +++ b/data/pdf-template/monthlyReport/institute.xml @@ -0,0 +1,7 @@ + + + + +   +   + \ No newline at end of file diff --git a/data/pdf-template/php-pdf.dtd b/data/pdf-template/php-pdf.dtd new file mode 100644 index 0000000..10de2c5 --- /dev/null +++ b/data/pdf-template/php-pdf.dtd @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + +"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/pdf-template/worksheet-style.xml b/data/pdf-template/worksheet-style.xml new file mode 100644 index 0000000..02764e5 --- /dev/null +++ b/data/pdf-template/worksheet-style.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ + +
+ +
+ +
+ +
+ +
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + +
+ + + + + + + +
+ +
\ No newline at end of file diff --git a/data/pdf-template/worksheet.xml b/data/pdf-template/worksheet.xml new file mode 100644 index 0000000..ea334c1 --- /dev/null +++ b/data/pdf-template/worksheet.xml @@ -0,0 +1,192 @@ + + + + + + + + + + +
+ + + + + + + + + +
+
+ + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + +
+ + + + + + +
 
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + +
+ +
+
\ No newline at end of file diff --git a/deploy.php b/deploy.php new file mode 100644 index 0000000..b94f81c --- /dev/null +++ b/deploy.php @@ -0,0 +1,62 @@ +stage('production') + ->user('latuzcs_beik_api_access') + ->forwardAgent() + ->set('bin/php', '/usr/bin/php7.1') + ->set('bin/composer', '{{bin/php}} /var/www/clients/client5/web20/bin/composer') + ->set('php_service_name', 'php7.1-fpm') + ->set('deploy_path', '/var/www/clients/client5/web20/deploy'); + +// Tasks + +desc('Restart PHP-FPM service'); +task('php-fpm:reload', function () { + // The user must have rights for restart service + // /etc/sudoers: $username ALL=NOPASSWD:/bin/systemctl restart php-fpm.service + run('sudo service {{php_service_name}} reload'); +}); +after('deploy:symlink', 'php-fpm:reload'); + +desc('Deploy your project'); +task('deploy', [ + 'deploy:prepare', + 'deploy:lock', + 'deploy:release', + 'deploy:update_code', + 'deploy:shared', + 'deploy:writable', + 'deploy:vendors', + 'deploy:clear_paths', + 'deploy:symlink', + 'deploy:unlock', + 'cleanup', +]); + +after('deploy', 'success'); diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..de3035d --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,20 @@ + + + Expressive Skeleton coding standard + + + + + + + + + + + + + + + + src + diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..4c66f07 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,17 @@ + + + + + ./test + + + + + + ./src + + + diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..a5c4081 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,17 @@ +RewriteEngine On +# The following rule tells Apache that if the requested filename +# exists, simply serve it. +RewriteCond %{REQUEST_FILENAME} -s [OR] +RewriteCond %{REQUEST_FILENAME} -l [OR] +RewriteCond %{REQUEST_FILENAME} -d +RewriteRule ^.*$ - [NC,L] + +# The following rewrites all other queries to index.php. The +# condition ensures that if you are using Apache aliases to do +# mass virtual hosting, the base path will be prepended to +# allow proper resolution of the index.php file; it will work +# in non-aliased environments as well, providing a safe, one-size +# fits all solution. +RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$ +RewriteRule ^(.*) - [E=BASE:%1] +RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L] diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..17f1199 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..0fad61d --- /dev/null +++ b/public/index.php @@ -0,0 +1,29 @@ +get(\Zend\Expressive\Application::class); + + // Import programmatic/declarative middleware pipeline and routing + // configuration statements + require 'config/pipeline.php'; + require 'config/routes.php'; + + $app->run(); +}); diff --git a/public/zf-logo.png b/public/zf-logo.png new file mode 100644 index 0000000..ea5880e Binary files /dev/null and b/public/zf-logo.png differ diff --git a/src/App/Action/AbstractCrudAction.php b/src/App/Action/AbstractCrudAction.php new file mode 100644 index 0000000..db58baf --- /dev/null +++ b/src/App/Action/AbstractCrudAction.php @@ -0,0 +1,182 @@ +getMethod()); + $id = $request->getAttribute(static::IDENTIFIER_NAME); + + switch ($requestMethod) { + case 'GET': + return isset($id) + ? $this->get($request, $delegate) + : $this->getList($request, $delegate); + case 'POST': + return $this->create($request, $delegate); + case 'PUT': + return $this->update($request, $delegate); + case 'DELETE': + return isset($id) + ? $this->delete($request, $delegate) + : $this->deleteList($request, $delegate); + case 'HEAD': + return $this->head($request, $delegate); + case 'OPTIONS': + return $this->options($request, $delegate); + case 'PATCH': + return $this->patch($request, $delegate); + default: + return $delegate->process($request); + } + } + + public function get(ServerRequestInterface $request, DelegateInterface $delegate) + { + return $this->createResponse(['content' => 'Method not allowed'], 405); + } + + public function getList(ServerRequestInterface $request, DelegateInterface $delegate) + { + return $this->createResponse(['content' => 'Method not allowed'], 405); + } + + public function create(ServerRequestInterface $request, DelegateInterface $delegate) + { + return $this->createResponse(['content' => 'Method not allowed'], 405); + } + + public function update(ServerRequestInterface $request, DelegateInterface $delegate) + { + return $this->createResponse(['content' => 'Method not allowed'], 405); + } + + public function delete(ServerRequestInterface $request, DelegateInterface $delegate) + { + return $this->createResponse(['content' => 'Method not allowed'], 405); + } + + public function deleteList(ServerRequestInterface $request, DelegateInterface $delegate) + { + return $this->createResponse(['content' => 'Method not allowed'], 405); + } + + public function head(ServerRequestInterface $request, DelegateInterface $delegate) + { + return $this->createResponse(['content' => 'Method not allowed'], 405); + } + + public function options(ServerRequestInterface $request, DelegateInterface $delegate) + { + return $this->createResponse(['content' => 'Method not allowed'], 405); + } + + public function patch(ServerRequestInterface $request, DelegateInterface $delegate) + { + return $this->createResponse(['content' => 'Method not allowed'], 405); + } + + final protected function createResponse($data, $status = 200) + { + return new JsonResponse($data, $status); + } + + /** + * + * @param ServerRequestInterface $request + * @return array|object + */ + public function getRequestData(ServerRequestInterface $request) + { + $body = $request->getParsedBody(); + + if (!empty($body)) { + return $body; + } + + return $this->parseRequestData( + $request->getBody()->getContents(), + $request->getHeaderLine('content-type') + ); + } + + protected function withCorsHeaders(ResponseInterface $response, iterable $methods = []) + { + if ($methods) { + $methodsHeader = implode(',', $methods); + $response = $response->withHeader('Accept', $methodsHeader) + ->withHeader('Access-Control-Allow-Methods', $methodsHeader); + } + return $response + ->withHeader('Access-Control-Allow-Origin', '*') + ->withHeader('Access-Control-Allow-Headers', implode(",", self::CORS_ALLOW_HEADERS)); + } + + /** + * + * @param string $input + * @param string $contentType + * @return mixed + */ + private function parseRequestData($input, $contentType) + { + $contentTypeParts = preg_split('/\s*[;,]\s*/', $contentType); + $parser = $this->returnParserContentType($contentTypeParts[0]); + + return $parser($input); + } + + /** + * + * @param string $contentType + * @return callable + */ + private function returnParserContentType(string $contentType) + { + if ($contentType === 'application/x-www-form-urlencoded') { + return function ($input) { + parse_str($input, $data); + return $data; + }; + } elseif ($contentType === 'application/json') { + return function ($input) { + $jsonDecoder = new Json(); + try { + return $jsonDecoder->decode($input, Json::TYPE_ARRAY); + } catch (\Exception $e) { + return false; + } + }; + } elseif ($contentType === 'multipart/form-data') { + return function ($input) { + return $input; + }; + } + + return function ($input) { + return $input; + }; + } +} diff --git a/src/App/Action/Auth/AuthAction.php b/src/App/Action/Auth/AuthAction.php new file mode 100644 index 0000000..3a32ce5 --- /dev/null +++ b/src/App/Action/Auth/AuthAction.php @@ -0,0 +1,83 @@ +authService = $authService; + } + + /** + * Create new auth token (login) + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response\JsonResponse + */ + public function create(ServerRequestInterface $request, DelegateInterface $delegate) + { + $authData = $this->getRequestData($request); + try { + return new JsonCorsResponse($this->authService->authenticate($authData['login'], $authData['password'])); + } catch (NoResultException $e) { + return new JsonCorsResponse([ + 'message' => $e->getMessage() + ], 403); + } catch (\Exception $e) { + return new JsonCorsResponse([ + 'message' => $e->getMessage() + ], 500); + } + } + + /** + * Renew auth token + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response\JsonResponse + */ + public function getList(ServerRequestInterface $request, DelegateInterface $delegate) + { + try { + $token = $request->getAttribute('token', false); + return new JsonCorsResponse($this->authService->renewToken($token)); + } catch (\Exception $e) { + return new JsonCorsResponse([ + 'message' => $e->getMessage() + ], 500); + } + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return static + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate) + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/Auth/AuthFactory.php b/src/App/Action/Auth/AuthFactory.php new file mode 100644 index 0000000..67ead40 --- /dev/null +++ b/src/App/Action/Auth/AuthFactory.php @@ -0,0 +1,15 @@ +get(AuthService::class); + return new AuthAction($faultManagerService); + } +} diff --git a/src/App/Action/ErrorCategoryAction.php b/src/App/Action/ErrorCategoryAction.php new file mode 100644 index 0000000..0560367 --- /dev/null +++ b/src/App/Action/ErrorCategoryAction.php @@ -0,0 +1,51 @@ +errorCategoryService = $errorCategoryService; + } + + /** + * Return all faults accessible to the user + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function getList(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return new JsonCorsResponse($this->errorCategoryService->getList()); + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/ErrorCategoryFactory.php b/src/App/Action/ErrorCategoryFactory.php new file mode 100644 index 0000000..055211f --- /dev/null +++ b/src/App/Action/ErrorCategoryFactory.php @@ -0,0 +1,16 @@ +get(ErrorCategoryService::class); + return new ErrorCategoryAction($errorCategoryService); + } +} diff --git a/src/App/Action/ErrorOriginAction.php b/src/App/Action/ErrorOriginAction.php new file mode 100644 index 0000000..0704e6f --- /dev/null +++ b/src/App/Action/ErrorOriginAction.php @@ -0,0 +1,51 @@ +errorOriginService = $errorOriginService; + } + + /** + * Return all faults accessible to the user + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function getList(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return new JsonCorsResponse($this->errorOriginService->getList()); + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/ErrorOriginFactory.php b/src/App/Action/ErrorOriginFactory.php new file mode 100644 index 0000000..883fa3d --- /dev/null +++ b/src/App/Action/ErrorOriginFactory.php @@ -0,0 +1,16 @@ +get(ErrorOriginService::class); + return new ErrorOriginAction($errorOriginService); + } +} diff --git a/src/App/Action/FacilityLocationAction.php b/src/App/Action/FacilityLocationAction.php new file mode 100644 index 0000000..9eb748f --- /dev/null +++ b/src/App/Action/FacilityLocationAction.php @@ -0,0 +1,52 @@ +facilityLocationService = $facilityLocationService; + } + + /** + * Return all faults accessible to the user + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function getList(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return new JsonCorsResponse($this->facilityLocationService->getFacilityLocationListFlat()); + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/FacilityLocationFactory.php b/src/App/Action/FacilityLocationFactory.php new file mode 100644 index 0000000..e6de325 --- /dev/null +++ b/src/App/Action/FacilityLocationFactory.php @@ -0,0 +1,16 @@ +get(FacilityLocationService::class); + return new FacilityLocationAction($facilityLocationService); + } +} diff --git a/src/App/Action/Fault/FaultAction.php b/src/App/Action/Fault/FaultAction.php new file mode 100644 index 0000000..d7238cd --- /dev/null +++ b/src/App/Action/Fault/FaultAction.php @@ -0,0 +1,122 @@ +faultManagerService = $faultManagerService; + } + + /** + * Return all faults accessible to the user + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function getList(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return new JsonCorsResponse($this->faultManagerService->getFaultList()); + } + + /** + * Return a single fault + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function get(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + $id = $request->getAttribute('id', false); + return new JsonCorsResponse($this->faultManagerService->getFault($id)); + } + + /** + * Post a new fault report + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function create(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + try { + $data = $this->getRequestData($request); + $token = $request->getAttribute('token'); + return new JsonCorsResponse($this->faultManagerService->createFault($data, $token->uid), 201); + } catch (\Exception $e) { + return new JsonCorsResponse($e->getMessage(), 500); + } + } + + /** + * Update a fault report + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function update(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + try { + $id = $request->getAttribute('id'); + $token = $request->getAttribute('token'); + $data = $this->getRequestData($request); + return new JsonCorsResponse($this->faultManagerService->updateFault($id, $data, $token->uid)); + } catch (\Exception $e) { + return new JsonCorsResponse($e->getMessage(), 500); + } + } + + /** + * Delete a fault report (NYI) + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function delete(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + try { + $id = $request->getAttribute('id'); + return new JsonCorsResponse($this->faultManagerService->deleteFault($id)); + } catch (\Exception $e) { + return new JsonCorsResponse($e->getMessage(), $e->getCode()); + } + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/Fault/FaultAttachmentAction.php b/src/App/Action/Fault/FaultAttachmentAction.php new file mode 100644 index 0000000..7ae1112 --- /dev/null +++ b/src/App/Action/Fault/FaultAttachmentAction.php @@ -0,0 +1,104 @@ +faultManagerService = $faultManagerService; + $this->attachmentService = $attachmentService; + } + + /** + * Post a new fault report + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function create(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + $faultId = $request->getAttribute('id'); + $type = $request->getAttribute('type', 'file'); + $token = $request->getAttribute('token'); + try { + /** @var UploadedFileInterface[] $files */ + $files = $request->getUploadedFiles()['file']; + return new JsonCorsResponse( + $this->attachmentService->createAttachments($faultId, $files, $token->uid, $type), + 201 + ); + } catch (\Exception $e) { + return new JsonCorsResponse($e->getMessage(), 500); + } + } + + /** + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return Response + */ + public function get(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + $id = $request->getAttribute('id'); + $attachment = $this->attachmentService->get($id); + $stream = new Stream($attachment->getIoStream()); + switch ($attachment->getType()) { + case 'image': + $contentType = 'image/jpg'; + break; + case 'expense': + $contentType = 'application/pdf'; + break; + default: + $contentType = 'application/octet-stream'; + } + $response = new Response($stream); + return $response->withStatus(200) + ->withHeader('Content-type', $contentType) +// ->withHeader('Content-disposition', 'attachment;filename='.$attachment->getFileName()) + ; + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/Fault/FaultAttachmentFactory.php b/src/App/Action/Fault/FaultAttachmentFactory.php new file mode 100644 index 0000000..70dd392 --- /dev/null +++ b/src/App/Action/Fault/FaultAttachmentFactory.php @@ -0,0 +1,17 @@ +get(FaultManagerService::class); + $attachmentService = $container->get(FaultAttachmentService::class); + return new FaultAttachmentAction($faultManagerService, $attachmentService); + } +} diff --git a/src/App/Action/Fault/FaultCommentAction.php b/src/App/Action/Fault/FaultCommentAction.php new file mode 100644 index 0000000..216b6f0 --- /dev/null +++ b/src/App/Action/Fault/FaultCommentAction.php @@ -0,0 +1,59 @@ +faultManagerService = $faultManagerService; + } + + /** + * Post a new fault report + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function create(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + $faultId = $request->getAttribute('id'); + $jwt = $request->getAttribute('token'); + try { + $data = $this->getRequestData($request); + return new JsonCorsResponse($this->faultManagerService->addFaultComment($faultId, $data, $jwt->uid), 201); + } catch (\Exception $e) { + return new JsonCorsResponse($e->getMessage(), $e->getCode()); + } + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/Fault/FaultCommentFactory.php b/src/App/Action/Fault/FaultCommentFactory.php new file mode 100644 index 0000000..2323035 --- /dev/null +++ b/src/App/Action/Fault/FaultCommentFactory.php @@ -0,0 +1,15 @@ +get(FaultManagerService::class); + return new FaultCommentAction($faultManagerService); + } +} diff --git a/src/App/Action/Fault/FaultFactory.php b/src/App/Action/Fault/FaultFactory.php new file mode 100644 index 0000000..9226fda --- /dev/null +++ b/src/App/Action/Fault/FaultFactory.php @@ -0,0 +1,15 @@ +get(FaultManagerService::class); + return new FaultAction($faultManagerService); + } +} diff --git a/src/App/Action/Fault/FaultRejectAction.php b/src/App/Action/Fault/FaultRejectAction.php new file mode 100644 index 0000000..fd5f496 --- /dev/null +++ b/src/App/Action/Fault/FaultRejectAction.php @@ -0,0 +1,59 @@ +faultManagerService = $faultManagerService; + } + + /** + * Post a new fault report + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function create(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + $faultId = $request->getAttribute('id'); + $jwt = $request->getAttribute('token'); + try { + $data = $this->getRequestData($request); + return new JsonCorsResponse($this->faultManagerService->rejectFault($faultId, $data, $jwt->uid), 201); + } catch (\Exception $e) { + return new JsonCorsResponse($e->getMessage(), 500); + } + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/Fault/FaultRejectFactory.php b/src/App/Action/Fault/FaultRejectFactory.php new file mode 100644 index 0000000..91d1e2a --- /dev/null +++ b/src/App/Action/Fault/FaultRejectFactory.php @@ -0,0 +1,15 @@ +get(FaultManagerService::class); + return new FaultRejectAction($faultManagerService); + } +} diff --git a/src/App/Action/Fault/FaultS2ConfirmAction.php b/src/App/Action/Fault/FaultS2ConfirmAction.php new file mode 100644 index 0000000..08b9c15 --- /dev/null +++ b/src/App/Action/Fault/FaultS2ConfirmAction.php @@ -0,0 +1,58 @@ +faultManagerService = $faultManagerService; + } + + /** + * Update a fault report + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function update(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + try { + $id = $request->getAttribute('id'); + $data = $this->getRequestData($request); + return new JsonCorsResponse($this->faultManagerService->confirmFault($id, $data)); + } catch (\Exception $e) { + return new JsonCorsResponse($e->getMessage(), $e->getCode()); + } + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/Fault/FaultS3AcknowledgeAction.php b/src/App/Action/Fault/FaultS3AcknowledgeAction.php new file mode 100644 index 0000000..6216881 --- /dev/null +++ b/src/App/Action/Fault/FaultS3AcknowledgeAction.php @@ -0,0 +1,58 @@ +faultManagerService = $faultManagerService; + } + + /** + * Update a fault report + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function update(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + try { + $id = $request->getAttribute('id'); + $data = $this->getRequestData($request); + return new JsonCorsResponse($this->faultManagerService->ackFault($id, $data)); + } catch (\Exception $e) { + return new JsonCorsResponse($e->getMessage(), $e->getCode()); + } + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/Fault/FaultS4RepairedAction.php b/src/App/Action/Fault/FaultS4RepairedAction.php new file mode 100644 index 0000000..a6e3a30 --- /dev/null +++ b/src/App/Action/Fault/FaultS4RepairedAction.php @@ -0,0 +1,58 @@ +faultManagerService = $faultManagerService; + } + + /** + * Update a fault report + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function update(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + try { + $id = $request->getAttribute('id'); + $data = $this->getRequestData($request); + return new JsonCorsResponse($this->faultManagerService->repairFault($id, $data)); + } catch (\Exception $e) { + return new JsonCorsResponse($e->getMessage(), $e->getCode()); + } + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/Fault/FaultS5AcceptedAction.php b/src/App/Action/Fault/FaultS5AcceptedAction.php new file mode 100644 index 0000000..bcc8e5a --- /dev/null +++ b/src/App/Action/Fault/FaultS5AcceptedAction.php @@ -0,0 +1,58 @@ +faultManagerService = $faultManagerService; + } + + /** + * Update a fault report + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function update(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + try { + $id = $request->getAttribute('id'); + $data = $this->getRequestData($request); + return new JsonCorsResponse($this->faultManagerService->acceptFault($id, $data)); + } catch (\Exception $e) { + return new JsonCorsResponse($e->getMessage(), $e->getCode()); + } + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/MaintenanceAction.php b/src/App/Action/MaintenanceAction.php new file mode 100644 index 0000000..47aee97 --- /dev/null +++ b/src/App/Action/MaintenanceAction.php @@ -0,0 +1,68 @@ +maintenanceManagerService = $maintenanceManagerService; + } + + /** + * Renew auth token + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response\JsonResponse + */ + public function getList(ServerRequestInterface $request, DelegateInterface $delegate) + { + return new JsonCorsResponse($this->maintenanceManagerService->getMaintenanceList()->getValues()); + } + + /** + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return JsonCorsResponse|\Zend\Diactoros\Response\JsonResponse + * @throws \Doctrine\ORM\ORMException + * @throws \Doctrine\ORM\OptimisticLockException + * @throws \Doctrine\ORM\TransactionRequiredException + */ + public function get(ServerRequestInterface $request, DelegateInterface $delegate) + { + $hash = $request->getAttribute(self::IDENTIFIER_NAME); + return new JsonCorsResponse($this->maintenanceManagerService->get($hash)); + } + + /** + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return JsonCorsResponse|\Zend\Diactoros\Response\JsonResponse + * @throws \Doctrine\ORM\ORMException + * @throws \Doctrine\ORM\OptimisticLockException + * @throws \Doctrine\ORM\TransactionRequiredException + */ + public function update(ServerRequestInterface $request, DelegateInterface $delegate) + { + $hash = $request->getAttribute(self::IDENTIFIER_NAME); + $data = $this->getRequestData($request); + $jwt = $request->getAttribute('token'); + return new JsonCorsResponse($this->maintenanceManagerService->update($hash, $data, $jwt->uid)); + } +} diff --git a/src/App/Action/MaintenanceFactory.php b/src/App/Action/MaintenanceFactory.php new file mode 100644 index 0000000..604af51 --- /dev/null +++ b/src/App/Action/MaintenanceFactory.php @@ -0,0 +1,21 @@ +get(MaintenanceManagerService::class); + return new MaintenanceAction($maintenanceManagerService); + } +} diff --git a/src/App/Action/MaintenanceUpcomingAction.php b/src/App/Action/MaintenanceUpcomingAction.php new file mode 100644 index 0000000..de062bb --- /dev/null +++ b/src/App/Action/MaintenanceUpcomingAction.php @@ -0,0 +1,37 @@ +maintenanceManagerService = $maintenanceManagerService; + } + + /** + * Renew auth token + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response\JsonResponse + */ + public function getList(ServerRequestInterface $request, DelegateInterface $delegate) + { + return new JsonCorsResponse($this->maintenanceManagerService->getUpcomingMaintenanceList()->getValues()); + } +} diff --git a/src/App/Action/MaintenanceUpcomingFactory.php b/src/App/Action/MaintenanceUpcomingFactory.php new file mode 100644 index 0000000..2afbe26 --- /dev/null +++ b/src/App/Action/MaintenanceUpcomingFactory.php @@ -0,0 +1,21 @@ +get(MaintenanceManagerService::class); + return new MaintenanceUpcomingAction($maintenanceManagerService); + } +} diff --git a/src/App/Action/Pdf/GenerateMaintenanceSheetAction.php b/src/App/Action/Pdf/GenerateMaintenanceSheetAction.php new file mode 100644 index 0000000..0eb4882 --- /dev/null +++ b/src/App/Action/Pdf/GenerateMaintenanceSheetAction.php @@ -0,0 +1,63 @@ +pdfService = $pdfService; + $this->maintenanceManager = $maintenanceManagerService; + } + + /** + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response\JsonResponse|TextResponse|static + * @throws \PHPPdf\Core\PHPPdf\Exception\Exception + */ + public function get(ServerRequestInterface $request, DelegateInterface $delegate) + { + $id = $request->getAttribute('id', false); + try { + return (new TextResponse($this->pdfService->getMaintenanceSheet($id))) + ->withHeader('Content-type', 'application/pdf'); + } catch (\Exception $e) { + return new TextResponse($e->getMessage(), 500); + } + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return static + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate) + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/Pdf/GenerateMaintenanceSheetFactory.php b/src/App/Action/Pdf/GenerateMaintenanceSheetFactory.php new file mode 100644 index 0000000..b76e1f5 --- /dev/null +++ b/src/App/Action/Pdf/GenerateMaintenanceSheetFactory.php @@ -0,0 +1,25 @@ +get(PdfService::class); + /** @var MaintenanceManagerService $maintenanceManagerService */ + $maintenanceManagerService = $container->get(MaintenanceManagerService::class); + return new GenerateMaintenanceSheetAction($pdfService, $maintenanceManagerService); + } +} diff --git a/src/App/Action/Pdf/GenerateWorksheetAction.php b/src/App/Action/Pdf/GenerateWorksheetAction.php new file mode 100644 index 0000000..181221e --- /dev/null +++ b/src/App/Action/Pdf/GenerateWorksheetAction.php @@ -0,0 +1,67 @@ +pdfService = $pdfService; + $this->faultManager = $faultManagerService; + } + + /** + * Renew auth token + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function get(ServerRequestInterface $request, DelegateInterface $delegate) + { + $id = $request->getAttribute('id', false); + try { + return (new TextResponse($this->pdfService->getWorksheet($id))) + ->withHeader('Content-type', 'application/pdf') +// ->withHeader('Content-disposition', 'attachment; filename=' +// . $this->faultManager->getFault($id)->getWorksheetNumber() . '.pdf') + ; + } catch (\Exception $e) { + return new TextResponse($e->getMessage(), 500); + } + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return static + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate) + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/Pdf/GenerateWorksheetFactory.php b/src/App/Action/Pdf/GenerateWorksheetFactory.php new file mode 100644 index 0000000..48441f7 --- /dev/null +++ b/src/App/Action/Pdf/GenerateWorksheetFactory.php @@ -0,0 +1,19 @@ +get(PdfService::class); + /** @var FaultManagerService $faultManager */ + $faultManager = $container->get(FaultManagerService::class); + return new GenerateWorksheetAction($pdfService, $faultManager); + } +} diff --git a/src/App/Action/PingAction.php b/src/App/Action/PingAction.php new file mode 100644 index 0000000..a1afba0 --- /dev/null +++ b/src/App/Action/PingAction.php @@ -0,0 +1,16 @@ + time()]); + } +} diff --git a/src/App/Action/SolutionTimeIntervalAction.php b/src/App/Action/SolutionTimeIntervalAction.php new file mode 100644 index 0000000..870c532 --- /dev/null +++ b/src/App/Action/SolutionTimeIntervalAction.php @@ -0,0 +1,51 @@ +solutionTimeIntervalService = $facilityLocationService; + } + + /** + * Return all faults accessible to the user + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function getList(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return new JsonCorsResponse($this->solutionTimeIntervalService->getList()); + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate): Response + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/SolutionTimeIntervalFactory.php b/src/App/Action/SolutionTimeIntervalFactory.php new file mode 100644 index 0000000..6c1f475 --- /dev/null +++ b/src/App/Action/SolutionTimeIntervalFactory.php @@ -0,0 +1,16 @@ +get(SolutionTimeIntervalService::class); + return new SolutionTimeIntervalAction($facilityLocationService); + } +} diff --git a/src/App/Action/User/PasswordAction.php b/src/App/Action/User/PasswordAction.php new file mode 100644 index 0000000..ea68cef --- /dev/null +++ b/src/App/Action/User/PasswordAction.php @@ -0,0 +1,57 @@ +userService = $userService; + } + + /** + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return JsonCorsResponse + */ + public function create(ServerRequestInterface $request, DelegateInterface $delegate) + { + $token = $request->getAttribute('token'); + try { + $data = $this->getRequestData($request); + return new JsonCorsResponse($this->userService->changePassword($token->uid, $data['old'], $data['new'])); + } catch (\Exception $e) { + return new JsonCorsResponse([ + 'message' => $e->getMessage() + ], $e->getCode()); + } + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return static + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate) + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/User/PasswordFactory.php b/src/App/Action/User/PasswordFactory.php new file mode 100644 index 0000000..c518dc1 --- /dev/null +++ b/src/App/Action/User/PasswordFactory.php @@ -0,0 +1,16 @@ +get(UserService::class); + return new PasswordAction($userService); + } +} diff --git a/src/App/Action/User/UserAction.php b/src/App/Action/User/UserAction.php new file mode 100644 index 0000000..841dfac --- /dev/null +++ b/src/App/Action/User/UserAction.php @@ -0,0 +1,93 @@ +userService = $userService; + } + + /** + * Renew auth token + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return \Zend\Diactoros\Response\JsonResponse + */ + public function getList(ServerRequestInterface $request, DelegateInterface $delegate) + { + try { + return new JsonCorsResponse($this->userService->getList()); + } catch (\Exception $e) { + return new JsonCorsResponse([ + 'message' => $e->getMessage() + ], 500); + } + } + + /** + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return JsonCorsResponse + */ + public function get(ServerRequestInterface $request, DelegateInterface $delegate) + { + $id = $request->getAttribute('id'); + try { + return new JsonCorsResponse($this->userService->get($id)); + } catch (\Exception $e) { + return new JsonCorsResponse([ + 'message' => $e->getMessage() + ], 500); + } + } + + /** + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return JsonCorsResponse + */ + public function update(ServerRequestInterface $request, DelegateInterface $delegate) + { + $id = $request->getAttribute('id'); + try { + $data = $this->getRequestData($request); + return new JsonCorsResponse($this->userService->update($id, $data)); + } catch (\Exception $e) { + return new JsonCorsResponse([ + 'message' => $e->getMessage() + ], 500); + } + } + + /** + * Configure CORS preflight + * + * @param ServerRequestInterface $request + * @param DelegateInterface $delegate + * @return static + */ + public function options(ServerRequestInterface $request, DelegateInterface $delegate) + { + return $this->withCorsHeaders(new EmptyResponse(), self::CORS_ALLOW_METHODS); + } +} diff --git a/src/App/Action/User/UserFactory.php b/src/App/Action/User/UserFactory.php new file mode 100644 index 0000000..5788562 --- /dev/null +++ b/src/App/Action/User/UserFactory.php @@ -0,0 +1,16 @@ +get(UserService::class); + return new UserAction($userService); + } +} diff --git a/src/App/Command/ConvertMaintenanceHashCommand.php b/src/App/Command/ConvertMaintenanceHashCommand.php new file mode 100644 index 0000000..599e55f --- /dev/null +++ b/src/App/Command/ConvertMaintenanceHashCommand.php @@ -0,0 +1,60 @@ +entityManager = $entityManager; + $this->maintenanceManager = $maintenanceManagerService; + parent::__construct(); + } + + protected function configure() + { + $this->setName('convert:hash') + ->setDescription('convert v1 hash to v2'); + } + + /** + * @param InputInterface $input + * @param OutputInterface $output + * @return int|null|void + * @throws \Doctrine\ORM\OptimisticLockException + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + /** @var DeviceGroup[] $maintGroups */ + $maintGroups = $this->maintenanceManager->getMaintenanceList(); + + foreach ($maintGroups as $maintGroup) { + foreach ($maintGroup->getDevices() as $device) { + foreach ($device->getTasks() as $task) { + if(null !== ($entity = $this->entityManager->getRepository(Maintenance::class)->findOneBy([ + 'oldHash' => $task->getLegacyHash(), + ]))) { + /** @var Maintenance $entity */ + $entity->setHash($task->getHash()); + } + } + } + } + $this->entityManager->flush(); + } +} diff --git a/src/App/Command/ConvertMaintenanceHashCommandFactory.php b/src/App/Command/ConvertMaintenanceHashCommandFactory.php new file mode 100644 index 0000000..1591d12 --- /dev/null +++ b/src/App/Command/ConvertMaintenanceHashCommandFactory.php @@ -0,0 +1,25 @@ +get('doctrine.entity_manager.orm_default'); + /** @var MaintenanceManagerService $maintenanceManager */ + $maintenanceManager = $container->get(MaintenanceManagerService::class); + return new ConvertMaintenanceHashCommand($entityManager, $maintenanceManager); + } +} diff --git a/src/App/Command/InitializeFixtureCommand.php b/src/App/Command/InitializeFixtureCommand.php new file mode 100644 index 0000000..b187a55 --- /dev/null +++ b/src/App/Command/InitializeFixtureCommand.php @@ -0,0 +1,34 @@ +fixtureLoaderService = $fixtureLoaderService; + parent::__construct(); + } + + protected function configure() + { + $this->setName('initialize:fixture') + ->setDescription('Loads data fixture into the database, replacing already existing data'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->fixtureLoaderService->load($output); + } +} diff --git a/src/App/Command/InitializeFixtureCommandFactory.php b/src/App/Command/InitializeFixtureCommandFactory.php new file mode 100644 index 0000000..5385e81 --- /dev/null +++ b/src/App/Command/InitializeFixtureCommandFactory.php @@ -0,0 +1,16 @@ +get(FixtureLoaderService::class); + return new InitializeFixtureCommand($fixtureLoaderService); + } +} diff --git a/src/App/Command/MailTestCommand.php b/src/App/Command/MailTestCommand.php new file mode 100644 index 0000000..c60e262 --- /dev/null +++ b/src/App/Command/MailTestCommand.php @@ -0,0 +1,33 @@ +mailerService = $mailerService; + parent::__construct(); + } + + protected function configure() + { + $this->setName('mail:test') + ->setDescription('Test email'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->mailerService->sendTestMessage(); + } +} diff --git a/src/App/Command/MailTestCommandFactory.php b/src/App/Command/MailTestCommandFactory.php new file mode 100644 index 0000000..2cc8129 --- /dev/null +++ b/src/App/Command/MailTestCommandFactory.php @@ -0,0 +1,16 @@ +get(MailerService::class); + return new MailTestCommand($mailerService); + } +} diff --git a/src/App/ConfigProvider.php b/src/App/ConfigProvider.php new file mode 100644 index 0000000..bf4a875 --- /dev/null +++ b/src/App/ConfigProvider.php @@ -0,0 +1,95 @@ + $this->getDependencies(), + 'templates' => $this->getTemplates(), + ]; + } + + /** + * Returns the container dependencies + * + * @return array + */ + public function getDependencies() + { + return [ + 'invokables' => [ + Action\PingAction::class => Action\PingAction::class, + + ], + 'factories' => [ + Action\MaintenanceAction::class => Action\MaintenanceFactory::class, + Action\MaintenanceUpcomingAction::class => Action\MaintenanceUpcomingFactory::class, + + Action\Auth\AuthAction::class => Action\Auth\AuthFactory::class, + Action\User\UserAction::class => Action\User\UserFactory::class, + Action\User\PasswordAction::class => Action\User\PasswordFactory::class, + Action\Fault\FaultAction::class => Action\Fault\FaultFactory::class, + Action\Fault\FaultAttachmentAction::class => Action\Fault\FaultAttachmentFactory::class, + Action\Fault\FaultCommentAction::class => Action\Fault\FaultCommentFactory::class, + Action\Fault\FaultRejectAction::class => Action\Fault\FaultRejectFactory::class, + Action\ErrorOriginAction::class => Action\ErrorOriginFactory::class, + Action\ErrorCategoryAction::class => Action\ErrorCategoryFactory::class, + Action\FacilityLocationAction::class => Action\FacilityLocationFactory::class, + Action\SolutionTimeIntervalAction::class => Action\SolutionTimeIntervalFactory::class, + Action\Pdf\GenerateWorksheetAction::class => Action\Pdf\GenerateWorksheetFactory::class, + Action\Pdf\GenerateMaintenanceSheetAction::class => Action\Pdf\GenerateMaintenanceSheetFactory::class, + + Service\AuthService::class => Service\AuthServiceFactory::class, + Service\UserService::class => Service\UserServiceFactory::class, + Service\FaultManagerService::class => Service\FaultManagerServiceFactory::class, + Service\FaultAttachmentService::class => Service\FaultAttachmentServiceFactory::class, + Service\FixtureLoaderService::class => Service\FixtureLoaderServiceFactory::class, + Service\ErrorCategoryService::class => Service\ErrorCategoryServiceFactory::class, + Service\ErrorOriginService::class => Service\ErrorOriginServiceFactory::class, + Service\FacilityLocationService::class => Service\FacilityLocationServiceFactory::class, + Service\SolutionTimeIntervalService::class => Service\SolutionTimeIntervalServiceFactory::class, + Service\PdfService::class => Service\PdfServiceFactory::class, + Service\MailerService::class => Service\MailerServiceFactory::class, + Service\MaintenanceManagerService::class => Service\MaintenanceManagerServiceFactory::class, + Service\XlsxParserService::class => Service\XlsxParserServiceFactory::class, + + 'service.acl' => Service\RbaclFactory::class, + Logger::class => Service\LoggerFactory::class, + ], + ]; + } + + /** + * Returns the templates configuration + * + * @return array + */ + public function getTemplates() + { + return [ + 'paths' => [ + 'app' => ['templates/app'], + 'error' => ['templates/error'], + 'layout' => ['templates/layout'], + ], + ]; + } +} diff --git a/src/App/Entity/Attachment.php b/src/App/Entity/Attachment.php new file mode 100644 index 0000000..2dfcdc5 --- /dev/null +++ b/src/App/Entity/Attachment.php @@ -0,0 +1,346 @@ +id; + } + + /** + * @param int $id + * @return Attachment + */ + public function setId(int $id): Attachment + { + $this->id = $id; + return $this; + } + + /** + * @return Fault + */ + public function getFault(): Fault + { + return $this->fault; + } + + /** + * @param Fault $fault + * @return Attachment + */ + public function setFault(Fault $fault) + { + $this->fault = $fault; + return $this; + } + + /** + * @return User + */ + public function getUser(): User + { + return $this->user; + } + + /** + * @param User $user + * @return Attachment + */ + public function setUser(User $user): Attachment + { + $this->user = $user; + return $this; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @param string $type + * @return Attachment + */ + public function setType(string $type): Attachment + { + $this->type = $type; + return $this; + } + + /** + * @return boolean + */ + public function getActive(): bool + { + return $this->active; + } + + /** + * @param boolean $active + * @return Attachment + */ + public function setActive(bool $active): Attachment + { + $this->active = $active; + return $this; + } + + /** + * @return string + */ + public function getRawFileData(): string + { + return $this->rawFileData; + } + + /** + * @param string $rawFileData + * @return Attachment + */ + public function setRawFileData(string $rawFileData): Attachment + { + $this->rawFileData = $rawFileData; + return $this; + } + + /** + * @ORM\PrePersist + * @return Attachment + */ + public function validatePrePersist(): Attachment + { + if ($this->getRawFileData() == null) { + throw new \InvalidArgumentException("File data can't be empty"); + } + return $this; + } + + /** + * @ORM\PostPersist + * @return Attachment + */ + public function saveOnPersist(): Attachment + { + if ($this->getType() == 'image') { + return $this->saveDataAsImageFile($this->rawFileData); + } + + return $this->saveDataAsBinaryFile($this->rawFileData); + } + + /** + * @ORM\PreRemove + * @return Attachment + */ + public function preDeleteHelper(): Attachment + { + $this->idPreDeleteTemp = $this->id; + return $this; + } + + /** + * @ORM\PostRemove + * @return Attachment + */ + public function deleteImage(): Attachment + { + unlink($this->getFileName($this->idPreDeleteTemp)); + return $this; + } + + /** + * @param string $rawFileData + * @return Attachment + */ + public function saveDataAsImageFile(string $rawFileData): Attachment + { + $folder = $this->getContainingFolder(); + if (!file_exists($folder)) { + mkdir($folder, 0755, true); + } + + $extendedId = $this->getExtendedId(); + $pathSplit = str_split($extendedId, 3); + $fileName = array_pop($pathSplit); + $imagine = new Imagine(); + $image = $imagine->load($rawFileData); + $originBox = $image->getSize(); + $originWidth = $originBox->getWidth(); + $originHeight = $originBox->getHeight(); + if ($originWidth > self::MAX_PIXEL_SPREAD || $originHeight > self::MAX_PIXEL_SPREAD) { + if ($originWidth > $originHeight) { + $newWidth = self::MAX_PIXEL_SPREAD; + $newHeight = floor(self::MAX_PIXEL_SPREAD * $originHeight / $originWidth); + } elseif ($originHeight > $originWidth) { + $newWidth = floor(self::MAX_PIXEL_SPREAD * $originWidth / $originHeight); + $newHeight = self::MAX_PIXEL_SPREAD; + } else { + $newWidth = self::MAX_PIXEL_SPREAD; + $newHeight = self::MAX_PIXEL_SPREAD; + } +// $image->resize(new Box($newWidth, $newHeight), ImageInterface::FILTER_LANCZOS); + $image->resize(new Box($newWidth, $newHeight)); + $image->effects()->sharpen(); + } + $image->save(sprintf("%s/%s", $folder, $fileName), [ + 'format' => 'jpeg', + 'jpeg_quality' => 80, + ]); + return $this; + } + + public function saveDataAsBinaryFile(string $rawFileData): Attachment + { + $folder = $this->getContainingFolder(); + if (!file_exists($folder)) { + mkdir($folder, 0755, true); + } + $pathSplit = str_split($this->getExtendedId(), 3); + $fileName = array_pop($pathSplit); + file_put_contents(sprintf("%s/%s", $folder, $fileName), $rawFileData); + return $this; + } + + /** + * @param int $id + * @return string + */ + private function getContainingFolder($id = null): string + { + $attachmentFolder = str_split($this->getExtendedId($id), 3); + array_pop($attachmentFolder); + return sprintf('data/attachments/%s', implode('/', $attachmentFolder)); + } + + /** + * @param int $id + * @return string + * @throws \Exception + */ + private function getExtendedId($id = null): string + { + if ($this->id == null && $id == null) { + throw new \Exception("Entity must be persisted first."); + } + + return sprintf("%09d", $id ? $id : $this->getId()); + } + + /** + * @param int $id + * @return string + */ + public function getFileName($id = null): string + { + $splitParts = str_split($this->getExtendedId($id), 3); + $fileName = array_pop($splitParts); + return sprintf("%s/%s", $this->getContainingFolder($id), $fileName); + } + + /** + * @return resource + */ + public function getIoStream() + { + return fopen($this->getFileName(), 'r'); + } + + /** + * @return string + */ + public function getRawAttachmentData(): string + { + return file_get_contents($this->getFileName()); + } + + /** + * @return array + */ + public function jsonSerialize() + { + return [ + 'id' => $this->getId(), + 'type' => $this->getType(), + 'active' => $this->getActive(), + 'user' => $this->getUser(), + ]; + } +} diff --git a/src/App/Entity/AuthResponse.php b/src/App/Entity/AuthResponse.php new file mode 100644 index 0000000..bad7901 --- /dev/null +++ b/src/App/Entity/AuthResponse.php @@ -0,0 +1,66 @@ +message; + } + + /** + * @param string $message + * @return AuthResponse + */ + public function setMessage(string $message): AuthResponse + { + $this->message = $message; + return $this; + } + + /** + * @return string + */ + public function getToken(): string + { + return $this->token; + } + + /** + * @param string $token + * @return AuthResponse + */ + public function setToken(string $token): AuthResponse + { + $this->token = $token; + return $this; + } + + /** + * @return array + */ + public function jsonSerialize() + { + return [ + 'message' => $this->getMessage(), + 'token' => $this->getToken(), + ]; + } +} diff --git a/src/App/Entity/Device.php b/src/App/Entity/Device.php new file mode 100644 index 0000000..791107f --- /dev/null +++ b/src/App/Entity/Device.php @@ -0,0 +1,179 @@ +group = $group; + $this->tasks = new ArrayCollection(); + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @param string $name + * @return Device + */ + public function setName(string $name): Device + { + $this->name = trim($name); + return $this; + } + + /** + * @return string + */ + public function getResponsible(): string + { + return $this->responsible; + } + + /** + * @param string $responsible + * @return Device + */ + public function setResponsible(string $responsible): Device + { + $this->responsible = trim($responsible); + return $this; + } + + /** + * @return int + */ + public function getCount(): int + { + return $this->count; + } + + /** + * @param int $count + * @return Device + */ + public function setCount(int $count): Device + { + $this->count = $count; + return $this; + } + + /** + * @return string + */ + public function getWorkDescription(): string + { + return $this->workDescription; + } + + /** + * @param string $workDescription + * @return Device + */ + public function setWorkDescription(string $workDescription): Device + { + $this->workDescription = trim($workDescription); + return $this; + } + + /** + * @return DeviceMaintenanceTask[]|ArrayCollection + */ + public function getTasks(): ?ArrayCollection + { + return $this->tasks; + } + + /** + * @param DeviceMaintenanceTask[]|ArrayCollection $tasks + * @return Device + */ + public function setTasks(ArrayCollection $tasks) + { + $this->tasks = $tasks; + return $this; + } + + /** + * @param DeviceMaintenanceTask $device + * @return Device + */ + public function addTask(DeviceMaintenanceTask $device): Device + { + if (!$this->tasks->contains($device)) { + $this->tasks->add($device); + } + return $this; + } + + /** + * @param DeviceMaintenanceTask $maintenanceTask + * @return Device + */ + public function removeTask(DeviceMaintenanceTask $maintenanceTask): Device + { + if ($this->tasks->contains($maintenanceTask)) { + $this->tasks->removeElement($maintenanceTask); + } + return $this; + } + + public function getGroup(): DeviceGroup + { + return $this->group; + } + + /** + * Specify data which should be serialized to JSON + * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + * @return mixed data which can be serialized by json_encode, + * which is a value of any type other than a resource. + * @since 5.4.0 + */ + public function jsonSerialize() + { + return [ + 'name' => $this->getName(), + 'count' => $this->getCount(), + 'responsible' => $this->getResponsible(), + 'workDescription' => $this->getWorkDescription(), + 'tasks' => $this->getTasks()->getValues(), + ]; + } +} diff --git a/src/App/Entity/DeviceGroup.php b/src/App/Entity/DeviceGroup.php new file mode 100644 index 0000000..2aaa3b0 --- /dev/null +++ b/src/App/Entity/DeviceGroup.php @@ -0,0 +1,99 @@ +devices = new ArrayCollection(); + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @param string $name + * @return DeviceGroup + */ + public function setName(string $name): DeviceGroup + { + $this->name = trim($name); + return $this; + } + + /** + * @return Device[]|ArrayCollection + */ + public function getDevices(): ArrayCollection + { + return $this->devices; + } + + /** + * @param Device[]|ArrayCollection $devices + * @return DeviceGroup + */ + public function setDevices($devices): DeviceGroup + { + $this->devices = $devices; + return $this; + } + + /** + * @param Device $device + * @return DeviceGroup + */ + public function addDevice(Device $device): DeviceGroup + { + if (!$this->devices->contains($device)) { + $this->devices->add($device); + } + return $this; + } + + /** + * @param Device $device + * @return DeviceGroup + */ + public function removeDevice(Device $device): DeviceGroup + { + if ($this->devices->contains($device)) { + $this->devices->removeElement($device); + } + return $this; + } + + /** + * Specify data which should be serialized to JSON + * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + * @return mixed data which can be serialized by json_encode, + * which is a value of any type other than a resource. + * @since 5.4.0 + */ + public function jsonSerialize() + { + return [ + 'name' => $this->getName(), + 'devices' => $this->getDevices()->getValues(), + ]; + } +} diff --git a/src/App/Entity/DeviceMaintenanceTask.php b/src/App/Entity/DeviceMaintenanceTask.php new file mode 100644 index 0000000..2e3779e --- /dev/null +++ b/src/App/Entity/DeviceMaintenanceTask.php @@ -0,0 +1,247 @@ +device = $device; + } + + /** + * @return int + */ + public function getYear(): int + { + return $this->year; + } + + /** + * @param int $year + * @return DeviceMaintenanceTask + */ + public function setYear(int $year): DeviceMaintenanceTask + { + $this->year = $year; + return $this; + } + + /** + * @return int + */ + public function getMonth(): int + { + return $this->month; + } + + /** + * @param int $month + * @return DeviceMaintenanceTask + */ + public function setMonth(int $month): DeviceMaintenanceTask + { + $this->month = $month; + return $this; + } + + /** + * @return int + */ + public function getWeek(): int + { + return $this->week; + } + + /** + * @param int $week + * @return DeviceMaintenanceTask + */ + public function setWeek(int $week): DeviceMaintenanceTask + { + $this->week = $week; + return $this; + } + + /** + * @return int + */ + public function getWorkerCount(): int + { + return $this->workerCount; + } + + /** + * @param int $workerCount + * @return DeviceMaintenanceTask + */ + public function setWorkerCount(int $workerCount): DeviceMaintenanceTask + { + $this->workerCount = $workerCount; + return $this; + } + + /** + * @return float + */ + public function getTimeCost(): float + { + return $this->timeCost; + } + + /** + * @param float $timeCost + * @return DeviceMaintenanceTask + */ + public function setTimeCost(float $timeCost): DeviceMaintenanceTask + { + $this->timeCost = $timeCost; + return $this; + } + + /** + * @return \DateTime + */ + public function getShouldStartAt(): \DateTime + { + return $this->shouldStartAt; + } + + /** + * @param \DateTime $shouldStartAt + * @return DeviceMaintenanceTask + */ + public function setShouldStartAt(\DateTime $shouldStartAt): DeviceMaintenanceTask + { + $this->shouldStartAt = $shouldStartAt; + return $this; + } + + /** + * @return \DateTime + */ + public function getShouldBeDoneBy(): \DateTime + { + return $this->shouldBeDoneBy; + } + + /** + * @param \DateTime $shouldBeDoneBy + * @return DeviceMaintenanceTask + */ + public function setShouldBeDoneBy(\DateTime $shouldBeDoneBy): DeviceMaintenanceTask + { + $this->shouldBeDoneBy = $shouldBeDoneBy; + return $this; + } + + /** + * @return bool + */ + public function isDone(): bool + { + return $this->state == 'fin'; + } + + /** + * @return string + */ + public function getState(): string + { + return $this->state; + } + + /** + * @param string $state + * @return DeviceMaintenanceTask + */ + public function setState(string $state): DeviceMaintenanceTask + { + $this->state = $state; + return $this; + } + + /** + * device.name + device.workDescription + task.month + task.week + * @return string + * @deprecated + */ + public function getLegacyHash(): string + { + $dirty = $this->device->getName() + . $this->device->getWorkDescription() + . $this->getMonth() . $this->getWeek(); + $cleanBaseName = str_replace(" ", "", $dirty); + return md5($cleanBaseName); + } + + /** + * year + device.name + device.workDescription + task.month + task.week + * @return string + */ + public function getHash(): string + { + $dirty = $this->getYear() + . sprintf('%02d', $this->getMonth()) . sprintf('%02d', $this->getWeek()) + . $this->device->getName() + . $this->device->getWorkDescription(); + $cleanBaseName = str_replace(" ", "", $dirty); + return md5($cleanBaseName); + } + + public function getDevice(): Device + { + return $this->device; + } + + /** + * Specify data which should be serialized to JSON + * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + * @return mixed data which can be serialized by json_encode, + * which is a value of any type other than a resource. + * @since 5.4.0 + */ + public function jsonSerialize() + { + return [ + 'year' => $this->getYear(), + 'month' => $this->getMonth(), + 'week' => $this->getWeek(), + 'workerCount' => $this->getWorkerCount(), + 'timeCost' => $this->getTimeCost(), + 'shouldStartAt' => $this->getShouldStartAt()->format("Y-m-d"), + 'shouldBeDoneBy' => $this->getShouldBeDoneBy()->format("Y-m-d"), + 'done' => $this->isDone(), + 'state' => $this->getState(), + 'hash' => $this->getHash(), + 'legacyHash' => $this->getLegacyHash(), + ]; + } +} diff --git a/src/App/Entity/ErrorCategory.php b/src/App/Entity/ErrorCategory.php new file mode 100644 index 0000000..834b519 --- /dev/null +++ b/src/App/Entity/ErrorCategory.php @@ -0,0 +1,154 @@ + 'gépész', + self::TYPE_ELECTRIC => 'elektromos', + self::TYPE_BUILDING => 'építész', + self::TYPE_OTHER => 'egyéb', + ]; + + /** + * @ORM\Id + * @ORM\Column(name="id", type="integer") + * @ORM\GeneratedValue(strategy="IDENTITY") + * @var int + */ + private $id; + + /** + * @ORM\Column(name="name", type="string", length=250, nullable=false) + * @var string + */ + private $name; + + /** + * @ORM\Column(name="type", type="string", length=10, nullable=false) + * @var string + */ + private $type; + + /** + * @ORM\Column(name="active", type="boolean", options={"default": true}) + * @var bool + */ + private $active = true; + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @param int $id + * @return ErrorCategory + */ + public function setId(int $id): ErrorCategory + { + $this->id = $id; + return $this; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @param string $name + * @return ErrorCategory + */ + public function setName(string $name): ErrorCategory + { + $this->name = $name; + return $this; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @return string + */ + public function getMappedType(): string + { + return $this->typeMap[$this->getType()]; + } + + /** + * @param string $type + * @return ErrorCategory + */ + public function setType(string $type): ErrorCategory + { + $this->type = $type; + return $this; + } + + /** + * @return boolean + */ + public function getActive(): bool + { + return $this->active; + } + + /** + * @param boolean $active + * @return ErrorCategory + */ + public function setActive(bool $active): ErrorCategory + { + $this->active = $active; + return $this; + } + + /** + * @return array + */ + public function jsonSerialize() + { + return [ + 'id' => $this->id, + 'name' => $this->name, + 'type' => $this->type, + 'active' => $this->active, + ]; + } +} diff --git a/src/App/Entity/ErrorOrigin.php b/src/App/Entity/ErrorOrigin.php new file mode 100644 index 0000000..47f44de --- /dev/null +++ b/src/App/Entity/ErrorOrigin.php @@ -0,0 +1,134 @@ +id; + } + + /** + * @param int $id + * @return ErrorOrigin + */ + public function setId(int $id) + { + $this->id = $id; + return $this; + } + + /** + * @return string + */ + public function getCode(): string + { + return $this->code; + } + + /** + * @param string $code + * @return ErrorOrigin + */ + public function setCode(string $code): ErrorOrigin + { + $this->code = $code; + return $this; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @param string $name + * @return ErrorOrigin + */ + public function setName(string $name): ErrorOrigin + { + $this->name = $name; + return $this; + } + + /** + * @return boolean + */ + public function getActive(): bool + { + return $this->active; + } + + /** + * @param boolean $active + * @return ErrorOrigin + */ + public function setActive(bool $active): ErrorOrigin + { + $this->active = $active; + return $this; + } + + /** + * @return array + */ + public function jsonSerialize() + { + return [ + 'id' => $this->id, + 'code' => $this->code, + 'name' => $this->name, + 'active' => $this->active, + ]; + } +} diff --git a/src/App/Entity/FacilityLocation.php b/src/App/Entity/FacilityLocation.php new file mode 100644 index 0000000..3aea642 --- /dev/null +++ b/src/App/Entity/FacilityLocation.php @@ -0,0 +1,224 @@ +id; + } + + /** + * @param int $id + * @return FacilityLocation + */ + public function setId(int $id): FacilityLocation + { + $this->id = $id; + return $this; + } + + /** + * @return string + */ + public function getRoomNumber(): string + { + return $this->roomNumber; + } + + /** + * @param string $roomNumber + * @return FacilityLocation + */ + public function setRoomNumber(string $roomNumber): FacilityLocation + { + $this->roomNumber = $roomNumber; + return $this; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @param string $name + * @return FacilityLocation + */ + public function setName(string $name): FacilityLocation + { + $this->name = $name; + return $this; + } + + /** + * @return float + */ + public function getSize(): float + { + return $this->size; + } + + /** + * @param float $size + * @return FacilityLocation + */ + public function setSize(float $size): FacilityLocation + { + $this->size = $size; + return $this; + } + + /** + * @return mixed + */ + public function getLevel() + { + return $this->level; + } + + /** + * @param mixed $level + * @return FacilityLocation + */ + public function setLevel($level) + { + $this->level = $level; + return $this; + } + + /** + * @return mixed + */ + public function getParent() + { + return $this->parent; + } + + /** + * @param mixed $parent + * @return FacilityLocation + */ + public function setParent($parent) + { + $this->parent = $parent; + return $this; + } + + /** + * @param FacilityLocationClosure $closure + */ + public function addClosure(FacilityLocationClosure $closure) + { + $this->closures[] = $closure; + } + + /** + * @return boolean + */ + public function getActive(): bool + { + return $this->active; + } + + /** + * @param boolean $active + * @return FacilityLocation + */ + public function setActive(bool $active): FacilityLocation + { + $this->active = $active; + return $this; + } + + /** + * @return array + */ + public function jsonSerialize() + { + return [ + 'id' => $this->getId(), + 'roomNumber' => $this->getRoomNumber(), + 'name' => $this->getName(), + 'size' => $this->getSize(), + 'level' => $this->getLevel(), + 'active' => $this->getActive(), + ]; + } +} diff --git a/src/App/Entity/FacilityLocationClosure.php b/src/App/Entity/FacilityLocationClosure.php new file mode 100644 index 0000000..d171b6a --- /dev/null +++ b/src/App/Entity/FacilityLocationClosure.php @@ -0,0 +1,15 @@ +attachments = new ArrayCollection(); + $this->snapshots = new ArrayCollection(); + $this->comments = new ArrayCollection(); + } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @param int $id + * @return Fault + */ + public function setId(int $id): Fault + { + $this->id = $id; + return $this; + } + + /** + * @return string + */ + public function getWorksheetNumber(): ?string + { + return $this->worksheetNumber; + } + + /** + * @param string $worksheetNumber + * @return Fault + */ + public function setWorksheetNumber(?string $worksheetNumber): Fault + { + $this->worksheetNumber = $worksheetNumber; + return $this; + } + + /** + * @return FacilityLocation + */ + public function getFacilityLocation(): FacilityLocation + { + return $this->facilityLocation; + } + + /** + * @param FacilityLocation $facilityLocation + * @return Fault + */ + public function setFacilityLocation(FacilityLocation $facilityLocation): Fault + { + $this->facilityLocation = $facilityLocation; + return $this; + } + + /** + * @return string + */ + public function getFacilityLocationDescription() + { + return $this->facilityLocationDescription; + } + + /** + * @param string $facilityLocationDescription + * @return Fault + */ + public function setFacilityLocationDescription(string $facilityLocationDescription): Fault + { + $this->facilityLocationDescription = $facilityLocationDescription; + return $this; + } + + /** + * @return ErrorCategory + */ + public function getErrorCategory(): ErrorCategory + { + return $this->errorCategory; + } + + /** + * @param ErrorCategory $errorCategory + * @return Fault + */ + public function setErrorCategory(ErrorCategory $errorCategory): Fault + { + $this->errorCategory = $errorCategory; + return $this; + } + + /** + * @return ErrorOrigin + */ + public function getErrorOrigin(): ErrorOrigin + { + return $this->errorOrigin; + } + + /** + * @param ErrorOrigin $errorOrigin + * @return Fault + */ + public function setErrorOrigin(ErrorOrigin $errorOrigin): Fault + { + $this->errorOrigin = $errorOrigin; + return $this; + } + + /** + * @return string + */ + public function getErrorDescription() + { + return $this->errorDescription; + } + + /** + * @param string $errorDescription + * @return Fault + */ + public function setErrorDescription(string $errorDescription): Fault + { + $this->errorDescription = $errorDescription; + return $this; + } + + /** + * @return SolutionTimeInterval + */ + public function getSolutionTimeInterval(): SolutionTimeInterval + { + return $this->solutionTimeInterval; + } + + /** + * @param SolutionTimeInterval $solutionTimeInterval + * @return Fault + */ + public function setSolutionTimeInterval(SolutionTimeInterval $solutionTimeInterval): Fault + { + $this->solutionTimeInterval = $solutionTimeInterval; + return $this; + } + + /** + * @return string + */ + public function getSolutionTimeIntervalOther() + { + return $this->solutionTimeIntervalOther; + } + + /** + * @param string $solutionTimeIntervalOther + * @return Fault + */ + public function setSolutionTimeIntervalOther(string $solutionTimeIntervalOther): Fault + { + $this->solutionTimeIntervalOther = $solutionTimeIntervalOther; + return $this; + } + + /** + * @return string + */ + public function getState(): string + { + return $this->state; + } + + /** + * @param string $state + * @return Fault + */ + public function setState(string $state): Fault + { + $this->state = $state; + return $this; + } + + /** + * @return ArrayCollection + */ + public function getAttachments() + { + return $this->attachments; + } + + /** + * @param Attachment $attachment + * @return Fault + */ + public function addAttachment(Attachment $attachment): Fault + { + $this->attachments->add($attachment); + $attachment->setFault($this); + return $this; + } + + public function addAttachments(Collection $attachments): Fault + { + foreach ($attachments as $attachment) { + $this->addAttachment($attachment); + } + return $this; + } + + /** + * @param Attachment $attachment + * @return Fault + */ + public function removeAttachment(Attachment $attachment): Fault + { + $this->attachments->removeElement($attachment); + return $this; + } + + public function removeAttachments(Collection $attachments): Fault + { + foreach ($attachments as $attachment) { + $this->removeAttachment($attachment); + } + return $this; + } + + /** + * @return User + */ + public function getReporter() + { + return $this->reporter; + } + + /** + * @param User $reporter + * @return Fault + */ + public function setReporter(User $reporter) + { + $this->reporter = $reporter; + return $this; + } + + /** + * @return User + */ + public function getWorker() + { + return $this->worker; + } + + /** + * @param User $worker + * @return Fault + */ + public function setWorker($worker) + { + $this->worker = $worker; + return $this; + } + + /** + * @return User + */ + public function getConfirmer(): ?User + { + return $this->confirmer; + } + + /** + * @param User $confirmer + * @return Fault + */ + public function setConfirmer(?User $confirmer): Fault + { + $this->confirmer = $confirmer; + return $this; + } + + /** + * @return \DateTime + */ + public function getConfirmedAt(): ?\DateTime + { + return $this->confirmedAt; + } + + /** + * @param \DateTime $confirmedAt + * @return Fault + */ + public function setConfirmedAt(?\DateTime $confirmedAt): Fault + { + $this->confirmedAt = $confirmedAt; + return $this; + } + + /** + * @return User + */ + public function getAcknowledgedBy(): ?User + { + return $this->acknowledgedBy; + } + + /** + * @param User $acknowledgedBy + * @return Fault + */ + public function setAcknowledgedBy(?User $acknowledgedBy): Fault + { + $this->acknowledgedBy = $acknowledgedBy; + return $this; + } + + /** + * @return \DateTime + */ + public function getAcknowledgedAt(): ?\DateTime + { + return $this->acknowledgedAt; + } + + /** + * @param \DateTime $acknowledgedAt + * @return Fault + */ + public function setAcknowledgedAt(?\DateTime $acknowledgedAt): Fault + { + $this->acknowledgedAt = $acknowledgedAt; + return $this; + } + + /** + * @return User + */ + public function getApprovedBy(): ?User + { + return $this->approvedBy; + } + + /** + * @param User $approvedBy + * @return Fault + */ + public function setApprovedBy(?User $approvedBy): Fault + { + $this->approvedBy = $approvedBy; + return $this; + } + + /** + * @return \DateTime + */ + public function getApprovedAt(): ?\DateTime + { + return $this->approvedAt; + } + + /** + * @param \DateTime $approvedAt + * @return Fault + */ + public function setApprovedAt(?\DateTime $approvedAt): Fault + { + $this->approvedAt = $approvedAt; + return $this; + } + + /** + * @return \DateTime + */ + public function getReportAccepted(): ?\DateTime + { + return $this->reportAccepted; + } + + /** + * @param \DateTime $reportAccepted + * @return Fault + */ + public function setReportAccepted(?\DateTime $reportAccepted): Fault + { + $this->reportAccepted = $reportAccepted; + return $this; + } + + /** + * @return \DateTime + */ + public function getWorkStarted() + { + return $this->workStarted; + } + + /** + * @param \DateTime $workStarted + * @return Fault + */ + public function setWorkStarted(\DateTime $workStarted): Fault + { + $this->workStarted = $workStarted; + return $this; + } + + /** + * @return \DateTime + */ + public function getWorkFinished() + { + return $this->workFinished; + } + + /** + * @param \DateTime $workFinished + * @return Fault + */ + public function setWorkFinished(\DateTime $workFinished): Fault + { + $this->workFinished = $workFinished; + return $this; + } + + /** + * @return float + */ + public function getTimeSpent(): ?float + { + return $this->timeSpent; + } + + /** + * @param float $timeSpent + * @return Fault + */ + public function setTimeSpent(?float $timeSpent): Fault + { + $this->timeSpent = $timeSpent; + return $this; + } + + /** + * @return int + */ + public function getWorkCostEstimate(): ?int + { + return $this->workCostEstimate; + } + + /** + * @param int $workCostEstimate + * @return Fault + */ + public function setWorkCostEstimate(?int $workCostEstimate): Fault + { + $this->workCostEstimate = $workCostEstimate; + return $this; + } + + /** + * @return int + */ + public function getMaterialCostEstimate(): ?int + { + return $this->materialCostEstimate; + } + + /** + * @param int $materialCostEstimate + * @return Fault + */ + public function setMaterialCostEstimate(?int $materialCostEstimate): Fault + { + $this->materialCostEstimate = $materialCostEstimate; + return $this; + } + + /** + * @return mixed + */ + public function getUsedMaterials() + { + return $this->usedMaterials; + } + + /** + * @param mixed $usedMaterials + * @return Fault + */ + public function setUsedMaterials($usedMaterials) + { + $this->usedMaterials = $usedMaterials; + return $this; + } + + /** + * @return mixed + */ + public function getWorkDone() + { + return $this->workDone; + } + + /** + * @param mixed $workDone + * @return Fault + */ + public function setWorkDone($workDone) + { + $this->workDone = $workDone; + return $this; + } + + /** + * @return \DateTime + */ + public function getCreatedAt() + { + return $this->createdAt; + } + + /** + * @param \DateTime $createdAt + * @return Fault + */ + public function setCreatedAt(\DateTime $createdAt): Fault + { + $this->createdAt = $createdAt; + return $this; + } + + /** + * @return ArrayCollection + */ + public function getSnapshots() + { + return $this->snapshots; + } + + + /** + * @return ArrayCollection + */ + public function getComments() + { + return $this->comments; + } + + /** + * @param FaultComment $comment + * @return Fault + */ + public function addComment(FaultComment $comment): Fault + { + if (!$this->comments->contains($comment)) { + $this->comments->add($comment); + $comment->setFault($this); + } + return $this; + } + + public function addComments(Collection $comments): Fault + { + foreach ($comments as $comment) { + $this->addComment($comment); + } + return $this; + } + + /** + * @param FaultComment $comment + * @return Fault + */ + public function removeComment(FaultComment $comment): Fault + { + if ($this->comments->contains($comment)) { + $this->comments->removeElement($comment); + } + return $this; + } + + public function removeComments(Collection $comments): Fault + { + foreach ($comments as $comment) { + $this->removeComment($comment); + } + return $this; + } + + /** + * @return bool + */ + public function isMustLowerCost(): ?bool + { + return $this->mustLowerCost; + } + + /** + * @param bool $mustLowerCost + * @return Fault + */ + public function setMustLowerCost(?bool $mustLowerCost): Fault + { + $this->mustLowerCost = $mustLowerCost; + return $this; + } + + /** + * @return int + */ + public function getAllocatedExpense(): ?int + { + return $this->allocatedExpense; + } + + /** + * @param int $allocatedExpense + * @return Fault + */ + public function setAllocatedExpense(?int $allocatedExpense): Fault + { + $this->allocatedExpense = $allocatedExpense; + return $this; + } + + + /** + * @return array + */ + public function jsonSerialize() + { + return [ + 'id' => $this->id, + 'facilityLocation' => $this->getFacilityLocation(), + 'facilityLocationDescription' => $this->getFacilityLocationDescription(), + 'errorCategory' => $this->getErrorCategory(), + 'errorOrigin' => $this->getErrorOrigin(), + 'errorDescription' => $this->getErrorDescription(), + 'solutionTimeInterval' => $this->getSolutionTimeInterval(), + 'solutionTimeIntervalOther' => $this->getSolutionTimeIntervalOther(), + 'state' => $this->getState(), + 'attachments' => $this->getAttachments()->getValues() ?? [], + 'worker' => $this->getWorker(), + 'confirmer' => $this->getConfirmer(), + 'confirmedAt' => $this->getConfirmedAt(), + 'acknowledgedBy' => $this->getAcknowledgedBy(), + 'acknowledgedAt' => $this->getAcknowledgedAt(), + 'approvedBy' => $this->getApprovedBy(), + 'approvedAt' => $this->getApprovedAt(), + 'reportAccepted' => $this->getReportAccepted(), + 'workStarted' => $this->getWorkStarted(), + 'workFinished' => $this->getWorkFinished(), + 'worksheetNumber' => $this->getWorksheetNumber(), + 'timeSpent' => $this->getTimeSpent(), + 'workCostEstimate' => $this->getWorkCostEstimate(), + 'materialCostEstimate' => $this->getMaterialCostEstimate(), + 'usedMaterials' => $this->getUsedMaterials() ?? [], + 'workDone' => $this->getWorkDone() ?? [], + 'createdAt' => $this->getCreatedAt(), + 'faultSnapshots' => $this->getSnapshots()->toArray() ?? [], + 'comments' => $this->getComments()->toArray() ?? [], + 'mustLowerCost' => $this->isMustLowerCost(), + 'allocatedExpense' => $this->getAllocatedExpense(), + ]; + } + + public function getFlatValues() + { + return [ + 'id' => $this->id, + 'facilityLocation' => $this->getFacilityLocation()->getId(), + 'facilityLocationDescription' => $this->getFacilityLocationDescription(), + 'errorCategory' => $this->getErrorCategory()->getId(), + 'errorOrigin' => $this->getErrorOrigin()->getId(), + 'errorDescription' => $this->getErrorDescription(), + 'solutionTimeInterval' => $this->getSolutionTimeInterval()->getId(), + 'solutionTimeIntervalOther' => $this->getSolutionTimeIntervalOther(), + 'state' => $this->getState(), + 'attachments' => $this->getAttachments()->getValues() ?? [], + 'worker' => $this->getWorker() ? $this->getWorker()->getId() : null, + 'confirmer' => $this->getConfirmer() ? $this->getConfirmer()->getId() : null, + 'confirmedAt' => $this->getConfirmedAt(), + 'acknowledgedBy' => $this->getAcknowledgedBy() ? $this->getAcknowledgedBy()->getId() : null, + 'acknowledgedAt' => $this->getAcknowledgedAt(), + 'approvedBy' => $this->getApprovedBy() ? $this->getApprovedBy()->getId() : null, + 'approvedAt' => $this->getApprovedAt(), + 'reportAccepted' => $this->getReportAccepted(), + 'workStarted' => $this->getWorkStarted(), + 'workFinished' => $this->getWorkFinished(), + 'worksheetNumber' => $this->getWorksheetNumber(), + 'timeSpent' => $this->getTimeSpent(), + 'workCostEstimate' => $this->getWorkCostEstimate(), + 'materialCostEstimate' => $this->getMaterialCostEstimate(), + 'usedMaterials' => $this->getUsedMaterials() ?? [], + 'workDone' => $this->getWorkDone() ?? [], + 'createdAt' => $this->getCreatedAt(), + 'faultSnapshots' => $this->getSnapshots()->toArray() ?? [], + 'comments' => $this->getComments()->toArray() ?? [], + 'mustLowerCost' => $this->isMustLowerCost(), + 'allocatedExpense' => $this->getAllocatedExpense(), + ]; + } +} diff --git a/src/App/Entity/FaultComment.php b/src/App/Entity/FaultComment.php new file mode 100644 index 0000000..ca0ebb2 --- /dev/null +++ b/src/App/Entity/FaultComment.php @@ -0,0 +1,164 @@ +id; + } + + /** + * @param int $id + * @return FaultComment + */ + public function setId(int $id): FaultComment + { + $this->id = $id; + return $this; + } + + /** + * @return Fault + */ + public function getFault(): Fault + { + return $this->fault; + } + + /** + * @param Fault $fault + * @return FaultComment + */ + public function setFault(Fault $fault): FaultComment + { + $this->fault = $fault; + return $this; + } + + /** + * @return User + */ + public function getUser(): User + { + return $this->user; + } + + /** + * @param User $user + * @return FaultComment + */ + public function setUser(User $user): FaultComment + { + $this->user = $user; + return $this; + } + + /** + * @return string + */ + public function getComment(): string + { + return $this->comment; + } + + /** + * @param string $comment + * @return FaultComment + */ + public function setComment(string $comment): FaultComment + { + $this->comment = $comment; + return $this; + } + + /** + * @return \DateTime + */ + public function getCreatedAt(): \DateTime + { + return $this->createdAt; + } + + /** + * @param \DateTime $createdAt + * @return FaultComment + */ + public function setCreatedAt(\DateTime $createdAt): FaultComment + { + $this->createdAt = $createdAt; + return $this; + } + + + /** + * @return array + */ + public function jsonSerialize() + { + return [ + 'id' => $this->id, + 'user' => $this->getUser(), + 'comment' => $this->getComment(), + 'createdAt' => $this->getCreatedAt(), + ]; + } +} diff --git a/src/App/Entity/FaultSnapshot.php b/src/App/Entity/FaultSnapshot.php new file mode 100644 index 0000000..b003f90 --- /dev/null +++ b/src/App/Entity/FaultSnapshot.php @@ -0,0 +1,239 @@ +id; + } + + /** + * @param int $id + * @return FaultSnapshot + */ + public function setId(int $id): FaultSnapshot + { + $this->id = $id; + return $this; + } + + /** + * @return Fault + */ + public function getFault(): Fault + { + return $this->fault; + } + + /** + * @param Fault $fault + * @return FaultSnapshot + */ + public function setFault(Fault $fault): FaultSnapshot + { + $this->fault = $fault; + return $this; + } + + /** + * @return User + */ + public function getUser(): User + { + return $this->user; + } + + /** + * @param User $user + * @return FaultSnapshot + */ + public function setUser(User $user): FaultSnapshot + { + $this->user = $user; + return $this; + } + + /** + * @return string + */ + public function getOldState(): ?string + { + return $this->oldState; + } + + /** + * @param string $oldState + * @return FaultSnapshot + */ + public function setOldState(string $oldState): FaultSnapshot + { + $this->oldState = $oldState; + return $this; + } + + /** + * @return string + */ + public function getNewState(): ?string + { + return $this->newState; + } + + /** + * @param string $newState + * @return FaultSnapshot + */ + public function setNewState(string $newState): FaultSnapshot + { + $this->newState = $newState; + return $this; + } + + /** + * @return mixed + */ + public function getPayload() + { + return $this->payload; + } + + /** + * @param mixed $payload + * @return FaultSnapshot + */ + public function setPayload($payload) + { + $this->payload = $payload; + return $this; + } + + /** + * @return string + */ + public function getComment(): ?string + { + return $this->comment; + } + + /** + * @param string $comment + * @return FaultSnapshot + */ + public function setComment(string $comment): FaultSnapshot + { + $this->comment = $comment; + return $this; + } + + /** + * @return mixed + */ + public function getCreatedAt(): ?\DateTime + { + return $this->createdAt; + } + + /** + * @param \DateTime $createdAt + * @return FaultSnapshot + */ + public function setCreatedAt(\DateTime $createdAt) + { + $this->createdAt = $createdAt; + return $this; + } + + /** + * @return array + */ + public function jsonSerialize() + { + return [ + 'id' => $this->id, + 'user' => $this->getUser(), + 'oldState' => $this->getOldState(), + 'newState' => $this->getNewState(), + 'payload' => $this->getPayload(), + 'comment' => $this->getComment(), + 'createdAt' => $this->getCreatedAt(), + ]; + } +} diff --git a/src/App/Entity/Maintenance.php b/src/App/Entity/Maintenance.php new file mode 100644 index 0000000..3dd466f --- /dev/null +++ b/src/App/Entity/Maintenance.php @@ -0,0 +1,649 @@ +hash; + } + + /** + * @param string $hash + * @return Maintenance + */ + public function setHash(string $hash): Maintenance + { + $this->hash = $hash; + return $this; + } + + /** + * @return string + */ + public function getOldHash(): string + { + return $this->oldHash; + } + + /** + * @param string $oldHash + * @return Maintenance + */ + public function setOldHash(string $oldHash): Maintenance + { + $this->oldHash = $oldHash; + return $this; + } + + /** + * @return string + */ + public function getDeviceName(): string + { + return $this->deviceName; + } + + /** + * @param string $deviceName + * @return Maintenance + */ + public function setDeviceName(string $deviceName): Maintenance + { + $this->deviceName = $deviceName; + return $this; + } + + /** + * @return string + */ + public function getComponentName(): string + { + return $this->componentName; + } + + /** + * @param string $componentName + * @return Maintenance + */ + public function setComponentName(string $componentName): Maintenance + { + $this->componentName = $componentName; + return $this; + } + + /** + * @return string + */ + public function getResponsible(): string + { + return $this->responsible; + } + + /** + * @param string $responsible + * @return Maintenance + */ + public function setResponsible(string $responsible): Maintenance + { + $this->responsible = $responsible; + return $this; + } + + /** + * @return string + */ + public function getWorkDescription(): string + { + return $this->workDescription; + } + + /** + * @param string $workDescription + * @return Maintenance + */ + public function setWorkDescription(string $workDescription): Maintenance + { + $this->workDescription = $workDescription; + return $this; + } + + /** + * @return int + */ + public function getCount(): int + { + return $this->count; + } + + /** + * @param int $count + * @return Maintenance + */ + public function setCount(int $count): Maintenance + { + $this->count = $count; + return $this; + } + + /** + * @return int + */ + public function getYear(): int + { + return $this->year; + } + + /** + * @param int $year + * @return Maintenance + */ + public function setYear(int $year): Maintenance + { + $this->year = $year; + return $this; + } + + /** + * @return int + */ + public function getMonth(): int + { + return $this->month; + } + + /** + * @param int $month + * @return Maintenance + */ + public function setMonth(int $month): Maintenance + { + $this->month = $month; + return $this; + } + + /** + * @return int + */ + public function getWeek(): int + { + return $this->week; + } + + /** + * @param int $week + * @return Maintenance + */ + public function setWeek(int $week): Maintenance + { + $this->week = $week; + return $this; + } + + /** + * @return int + */ + public function getWorkerCount(): int + { + return $this->workerCount; + } + + /** + * @param int $workerCount + * @return Maintenance + */ + public function setWorkerCount(int $workerCount): Maintenance + { + $this->workerCount = $workerCount; + return $this; + } + + /** + * @return float + */ + public function getTimeCost(): float + { + return $this->timeCost; + } + + /** + * @param float $timeCost + * @return Maintenance + */ + public function setTimeCost(float $timeCost): Maintenance + { + $this->timeCost = $timeCost; + return $this; + } + + /** + * @return \DateTime + */ + public function getShouldStartAt(): \DateTime + { + return $this->shouldStartAt; + } + + /** + * @param \DateTime $shouldStartAt + * @return Maintenance + */ + public function setShouldStartAt(\DateTime $shouldStartAt): Maintenance + { + $this->shouldStartAt = $shouldStartAt; + return $this; + } + + /** + * @return \DateTime + */ + public function getShouldBeDoneBy(): \DateTime + { + return $this->shouldBeDoneBy; + } + + /** + * @param \DateTime $shouldBeDoneBy + * @return Maintenance + */ + public function setShouldBeDoneBy(\DateTime $shouldBeDoneBy): Maintenance + { + $this->shouldBeDoneBy = $shouldBeDoneBy; + return $this; + } + + /** + * @return string + */ + public function getWorksheetNumber(): ?string + { + return $this->worksheetNumber; + } + + /** + * @param string $worksheetNumber + * @return Maintenance + */ + public function setWorksheetNumber(?string $worksheetNumber): Maintenance + { + $this->worksheetNumber = $worksheetNumber; + return $this; + } + + /** + * @return string + */ + public function getState(): string + { + return $this->state; + } + + /** + * @param string $state + * @return Maintenance + */ + public function setState(string $state): Maintenance + { + $this->state = $state; + return $this; + } + + /** + * @return User + */ + public function getWorker() + { + return $this->worker; + } + + /** + * @param User $worker + * @return Maintenance + */ + public function setWorker($worker): Maintenance + { + $this->worker = $worker; + return $this; + } + + /** + * @return User + */ + public function getApprovedBy(): ?User + { + return $this->approvedBy; + } + + /** + * @param User $approvedBy + * @return Maintenance + */ + public function setApprovedBy(?User $approvedBy): Maintenance + { + $this->approvedBy = $approvedBy; + return $this; + } + + /** + * @return \DateTime + */ + public function getApprovedAt(): ?\DateTime + { + return $this->approvedAt; + } + + /** + * @param \DateTime $approvedAt + * @return Maintenance + */ + public function setApprovedAt(?\DateTime $approvedAt): Maintenance + { + $this->approvedAt = $approvedAt; + return $this; + } + + /** + * @return \DateTime + */ + public function getWorkStarted(): ?\DateTime + { + return $this->workStarted; + } + + /** + * @param \DateTime $workStarted + * @return Maintenance + */ + public function setWorkStarted(?\DateTime $workStarted): Maintenance + { + $this->workStarted = $workStarted; + return $this; + } + + /** + * @return User + */ + public function getStartedBy(): ?User + { + return $this->startedBy; + } + + /** + * @param User $startedBy + * @return Maintenance + */ + public function setStartedBy(User $startedBy): Maintenance + { + $this->startedBy = $startedBy; + return $this; + } + + /** + * @return \DateTime + */ + public function getWorkFinished(): ?\DateTime + { + return $this->workFinished; + } + + /** + * @param \DateTime $workFinished + * @return Maintenance + */ + public function setWorkFinished(?\DateTime $workFinished): Maintenance + { + $this->workFinished = $workFinished; + return $this; + } + + /** + * @return User + */ + public function getFinishedBy(): ?User + { + return $this->finishedBy; + } + + /** + * @param User $finishedBy + * @return Maintenance + */ + public function setFinishedBy(User $finishedBy): Maintenance + { + $this->finishedBy = $finishedBy; + return $this; + } + + /** + * @return array + */ + public function jsonSerialize() + { + $formatString = "Y-m-d H:i"; + return [ + 'hash' => $this->getHash(), + 'deviceName' => $this->getDeviceName(), + 'componentName' => $this->getComponentName(), + 'responsible' => $this->getResponsible(), + 'workDescription' => $this->getWorkDescription(), + 'count' => $this->getCount(), + 'year' => $this->getYear(), + 'month' => $this->getMonth(), + 'week' => $this->getWeek(), + 'workerCount' => $this->getWorkerCount(), + 'timeCost' => $this->getTimeCost(), + 'shouldStartAt' => $this->getShouldStartAt() + ? $this->getShouldStartAt()->format($formatString) : null, + 'shouldBeDoneBy' => $this->getShouldBeDoneBy() + ? $this->getShouldBeDoneBy()->format($formatString) : null, + 'state' => $this->getState(), + 'worker' => $this->getWorker(), + 'approvedBy' => $this->getApprovedBy(), + 'approvedAt' => $this->getApprovedAt() + ? $this->getApprovedAt()->format($formatString) : null, + 'workStarted' => $this->getWorkStarted() + ? $this->getWorkStarted()->format($formatString) : null, + 'staretedBy' => $this->getStartedBy(), + 'workFinished' => $this->getWorkFinished() + ? $this->getWorkFinished()->format($formatString) : null, + 'finishedBy' => $this->getFinishedBy(), + 'worksheetNumber' => $this->getWorksheetNumber(), + ]; + } + + public function getFlatValues() + { + $formatString = "Y-m-d H:i"; + return [ + 'hash' => $this->getHash(), + 'deviceName' => $this->getDeviceName(), + 'componentName' => $this->getComponentName(), + 'responsible' => $this->getResponsible(), + 'workDescription' => $this->getWorkDescription(), + 'count' => $this->getCount(), + 'year' => $this->getYear(), + 'month' => $this->getMonth(), + 'week' => $this->getWeek(), + 'workerCount' => $this->getWorkerCount(), + 'timeCost' => $this->getTimeCost(), + 'shouldStartAt' => $this->getShouldStartAt() + ? $this->getShouldStartAt()->format($formatString) : null, + 'shouldBeDoneBy' => $this->getShouldBeDoneBy() + ? $this->getShouldBeDoneBy()->format($formatString) : null, + 'state' => $this->getState(), + 'worker' => $this->getWorker() ? $this->getWorker()->getId() : null, + 'approvedBy' => $this->getApprovedBy() ? $this->getApprovedBy()->getId() : null, + 'approvedAt' => $this->getApprovedAt() + ? $this->getApprovedAt()->format($formatString) : null, + 'workStarted' => $this->getWorkStarted() + ? $this->getWorkStarted()->format($formatString) : null, + 'staretedBy' => $this->getStartedBy(), + 'workFinished' => $this->getWorkFinished() + ? $this->getWorkFinished()->format($formatString) : null, + 'finishedBy' => $this->getFinishedBy(), + 'worksheetNumber' => $this->getWorksheetNumber(), + ]; + } +} diff --git a/src/App/Entity/SolutionTimeInterval.php b/src/App/Entity/SolutionTimeInterval.php new file mode 100644 index 0000000..54a54d5 --- /dev/null +++ b/src/App/Entity/SolutionTimeInterval.php @@ -0,0 +1,133 @@ +id; + } + + /** + * @param int $id + * @return SolutionTimeInterval + */ + public function setId(int $id): SolutionTimeInterval + { + $this->id = $id; + return $this; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @param string $name + * @return SolutionTimeInterval + */ + public function setName(string $name): SolutionTimeInterval + { + $this->name = $name; + return $this; + } + + /** + * @return string + */ + public function getCode(): string + { + return $this->code; + } + + /** + * @param string $code + * @return SolutionTimeInterval + */ + public function setCode(string $code): SolutionTimeInterval + { + $this->code = $code; + return $this; + } + + /** + * @return boolean + */ + public function getActive(): bool + { + return $this->active; + } + + /** + * @param boolean $active + * @return SolutionTimeInterval + */ + public function setActive(bool $active): SolutionTimeInterval + { + $this->active = $active; + return $this; + } + + /** + * @return array + */ + public function jsonSerialize() + { + return [ + 'id' => $this->id, + 'name' => $this->name, + 'code' => $this->code, + 'active' => $this->active, + ]; + } +} diff --git a/src/App/Entity/User.php b/src/App/Entity/User.php new file mode 100644 index 0000000..8aacb3d --- /dev/null +++ b/src/App/Entity/User.php @@ -0,0 +1,354 @@ +reportedFaults = new ArrayCollection(); + } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @param int $id + * @return User + */ + public function setId(int $id): User + { + $this->id = $id; + return $this; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @param string $name + * @return User + */ + public function setName(string $name): User + { + $this->name = $name; + return $this; + } + + /** + * @return string + */ + public function getEmail() + { + return $this->email; + } + + /** + * @param string $email + * @return User + */ + public function setEmail(string $email): User + { + $this->email = $email; + return $this; + } + + /** + * @return bool + */ + public function isWantsEmail() + { + return $this->wantsEmail; + } + + /** + * @param bool $wantsEmail + * @return User + */ + public function setWantsEmail(bool $wantsEmail): User + { + $this->wantsEmail = $wantsEmail; + return $this; + } + + /** + * @return string + */ + public function getJob(): string + { + return $this->job; + } + + /** + * @param string $job + * @return User + */ + public function setJob(string $job): User + { + $this->job = $job; + return $this; + } + + /** + * @return string + */ + public function getPhone(): string + { + return $this->phone; + } + + /** + * @param string $phone + * @return User + */ + public function setPhone(string $phone): User + { + $this->phone = $phone; + return $this; + } + + /** + * @return string + */ + public function getPassword(): string + { + return $this->password; + } + + /** + * @param string $password + * @return User + */ + public function setPassword(string $password): User + { + $this->password = $password; + return $this; + } + + /** + * @return mixed + */ + public function getRoles() + { + return $this->roles; + } + + /** + * @param mixed $roles + * @return User + */ + public function setRoles($roles) + { + $this->roles = $roles; + return $this; + } + + /** + * @return Fault[]|ArrayCollection + */ + public function getReportedFaults(): ArrayCollection + { + return $this->reportedFaults; + } + + /** + * @param Fault $reportedFault + * @return User + */ + public function addReportedFault(Fault $reportedFault): User + { + if (!$this->reportedFaults->contains($reportedFault)) { + $this->reportedFaults->add($reportedFault); + $reportedFault->setReporter($this); + } + return $this; + } + + /** + * @param Fault $reportedFault + * @return User + */ + public function removeReportedFault(Fault $reportedFault): User + { + if ($this->reportedFaults->contains($reportedFault)) { + $this->reportedFaults->removeElement($reportedFault); + $reportedFault->setReporter(null); + } + return $this; + } + + /** + * @return bool + */ + public function isPasswordMustChange(): bool + { + return $this->passwordMustChange; + } + + /** + * @param bool $passwordMustChange + * @return User + */ + public function setPasswordMustChange(bool $passwordMustChange): User + { + $this->passwordMustChange = $passwordMustChange; + return $this; + } + + /** + * @return bool + */ + public function getCanChangePassword(): bool + { + return $this->canChangePassword; + } + + /** + * @param bool $canChangePassword + * @return User + */ + public function setCanChangePassword(bool $canChangePassword): User + { + $this->canChangePassword = $canChangePassword; + return $this; + } + + /** + * @return boolean + */ + public function getActive(): bool + { + return $this->active; + } + + /** + * @param boolean $active + * @return User + */ + public function setActive(bool $active): User + { + $this->active = $active; + return $this; + } + + /** + * @return array + */ + public function jsonSerialize() + { + return [ + 'id' => $this->getId(), + 'name' => $this->getName(), + 'email' => $this->getEmail(), + 'wantsEmail' => $this->isWantsEmail(), + 'job' => $this->getJob(), + 'phone' => $this->getPhone(), + 'roles' => $this->getRoles(), + 'passwordMustChange' => $this->isPasswordMustChange(), + 'canChangePassword' => $this->getCanChangePassword(), + 'active' => $this->getActive(), + ]; + } +} diff --git a/src/App/Fixture/ErrorCategoryLoader.php b/src/App/Fixture/ErrorCategoryLoader.php new file mode 100644 index 0000000..c56da2d --- /dev/null +++ b/src/App/Fixture/ErrorCategoryLoader.php @@ -0,0 +1,57 @@ +output = $output; + } + + public function load(ObjectManager $manager) + { + $inputFileContents = file_get_contents("data/fixture/error-category.yml"); + $yamlData = Yaml::parse($inputFileContents); + + /** @var \Doctrine\ORM\Mapping\ClassMetadata $metadata */ + $metadata = $manager->getClassMetadata(ErrorCategory::class); + $metadata->setIdGenerator(new AssignedGenerator()); + $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE); + + $this->output->writeln(sprintf(" > %s BEGIN", __CLASS__)); + foreach ($yamlData['ErrorCategories'] as $entityId => $entityData) { + $entity = new ErrorCategory(); + $entity->setId($entityData['id']) + ->setName($entityData['name']) + ->setType($entityData['type']) + ->setActive($entityData['active']); + + $this->addReference($entityId, $entity); + + $manager->persist($entity); + $this->output->writeln(" * " . $entityId); + } + $manager->flush(); + $this->output->writeln(sprintf(" > %s END", __CLASS__)); + } + + public function getOrder() + { + return 10; + } +} diff --git a/src/App/Fixture/ErrorOriginLoader.php b/src/App/Fixture/ErrorOriginLoader.php new file mode 100644 index 0000000..51113fc --- /dev/null +++ b/src/App/Fixture/ErrorOriginLoader.php @@ -0,0 +1,57 @@ +output = $output; + } + + public function load(ObjectManager $manager) + { + $inputFileContents = file_get_contents("data/fixture/error-origin.yml"); + $yamlData = Yaml::parse($inputFileContents); + + /** @var \Doctrine\ORM\Mapping\ClassMetadata $metadata */ + $metadata = $manager->getClassMetadata(ErrorOrigin::class); + $metadata->setIdGenerator(new AssignedGenerator()); + $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE); + + $this->output->writeln(sprintf(" > %s BEGIN", __CLASS__)); + foreach ($yamlData['ErrorOrigins'] as $entityId => $entityData) { + $entity = new ErrorOrigin(); + $entity->setId($entityData['id']) + ->setName($entityData['name']) + ->setCode($entityData['code']) + ->setActive($entityData['active']); + + $this->addReference($entityId, $entity); + + $manager->persist($entity); + $this->output->writeln(" * " . $entityId); + } + $manager->flush(); + $this->output->writeln(sprintf(" > %s END", __CLASS__)); + } + + public function getOrder() + { + return 10; + } +} diff --git a/src/App/Fixture/FacilityLocationLoader.php b/src/App/Fixture/FacilityLocationLoader.php new file mode 100644 index 0000000..37f2f4e --- /dev/null +++ b/src/App/Fixture/FacilityLocationLoader.php @@ -0,0 +1,55 @@ +output = $output; + } + + public function load(ObjectManager $manager) + { + $inputFileContents = file_get_contents("data/fixture/facility-location.yml"); + $yamlData = Yaml::parse($inputFileContents); + + $this->output->writeln(sprintf(" > %s BEGIN", __CLASS__)); + foreach ($yamlData['FacilityLocations'] as $entityId => $entityData) { + $entity = new FacilityLocation(); + $entity + ->setRoomNumber($entityData['roomNumber']) + ->setName($entityData['name']) + ->setSize($entityData['size']); + + if ($entityData['parent']) { + $entity->setParent($this->getReference($entityData['parent'])); + } + + $this->addReference($entityId, $entity); + + $manager->persist($entity); + $this->output->writeln(" * " . $entityId); + } + $manager->flush(); + $this->output->writeln(sprintf(" > %s END", __CLASS__)); + } + + public function getOrder() + { + return 10; + } +} diff --git a/src/App/Fixture/SolutionTimeIntervalLoader.php b/src/App/Fixture/SolutionTimeIntervalLoader.php new file mode 100644 index 0000000..8284d3e --- /dev/null +++ b/src/App/Fixture/SolutionTimeIntervalLoader.php @@ -0,0 +1,57 @@ +output = $output; + } + + public function load(ObjectManager $manager) + { + $inputFileContents = file_get_contents("data/fixture/solution-time-interval.yml"); + $yamlData = Yaml::parse($inputFileContents); + + /** @var \Doctrine\ORM\Mapping\ClassMetadata $metadata */ + $metadata = $manager->getClassMetadata(SolutionTimeInterval::class); + $metadata->setIdGenerator(new AssignedGenerator()); + $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE); + + $this->output->writeln(sprintf(" > %s BEGIN", __CLASS__)); + foreach ($yamlData['SolutionTimeIntervals'] as $entityId => $entityData) { + $entity = new SolutionTimeInterval(); + $entity->setId($entityData['id']) + ->setName($entityData['name']) + ->setCode($entityData['code']) + ->setActive($entityData['active']); + + $this->addReference($entityId, $entity); + + $manager->persist($entity); + $this->output->writeln(" * " . $entityId); + } + $manager->flush(); + $this->output->writeln(sprintf(" > %s END", __CLASS__)); + } + + public function getOrder() + { + return 10; + } +} diff --git a/src/App/Fixture/UserLoader.php b/src/App/Fixture/UserLoader.php new file mode 100644 index 0000000..e81f66a --- /dev/null +++ b/src/App/Fixture/UserLoader.php @@ -0,0 +1,91 @@ +output = $output; + } + + public function load(ObjectManager $manager) + { + $inputFileContents = file_get_contents("data/fixture/user.yml"); + $yamlData = Yaml::parse($inputFileContents); + + /** @var \Doctrine\ORM\Mapping\ClassMetadata $metadata */ + $metadata = $manager->getClassMetadata(User::class); + $metadata->setIdGenerator(new AssignedGenerator()); + $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE); + + $this->output->writeln(sprintf(" > %s BEGIN", __CLASS__)); + + $crypt = new Bcrypt(); + $crypt->setCost(self::PASSWORD_COST); + + if (file_exists(self::GEN_PW_FILE)) { + unlink(self::GEN_PW_FILE); + } + + foreach ($yamlData['Users'] as $entityId => $entityData) { + $canChangePassword = $entityData['canChangePassword'] ?? true; + if (!$canChangePassword) { + $entityData['password'] = substr(md5(uniqid()), 0, 8); + file_put_contents(self::GEN_PW_FILE, sprintf( + "%s : %s\n", + $entityData['name'], + $entityData['password'] + ), FILE_APPEND); + } + + $entity = new User(); + $entity->setId($entityData['id']) + ->setName($entityData['name']) + ->setEmail($entityData['email']) + ->setWantsEmail($entityData['wantsEmail']) + ->setJob($entityData['job']) + ->setPhone($entityData['phone']) + ->setPassword($crypt->create(isset($entityData['password']) ? $entityData['password'] : '1234')) + ->setRoles(explode(',', $entityData['roles'])) + ->setCanChangePassword($canChangePassword) + ->setActive($entityData['active']); + + $this->addReference($entityId, $entity); + + $manager->persist($entity); + $this->output->writeln(" * " . $entityId); + } + $manager->flush(); + $this->output->writeln(sprintf(" > %s END", __CLASS__)); + } + + /** + * Used as fixture load order + * + * @return int + */ + public function getOrder() + { + return 9; + } +} diff --git a/src/App/Hydrator/DoctrineObject.php b/src/App/Hydrator/DoctrineObject.php new file mode 100644 index 0000000..912e5c2 --- /dev/null +++ b/src/App/Hydrator/DoctrineObject.php @@ -0,0 +1,594 @@ +. + */ + +namespace App\Hydrator; + +use DateTime; +use Doctrine\Common\Persistence\Mapping\ClassMetadata; +use Doctrine\Common\Persistence\ObjectManager; +use Doctrine\Common\Util\Inflector; +use InvalidArgumentException; +use RuntimeException; +use Traversable; +use Zend\Stdlib\ArrayUtils; +use Zend\Hydrator\AbstractHydrator; +use Zend\Hydrator\Filter\FilterProviderInterface; + +/** + * This hydrator has been completely refactored for DoctrineModule 0.7.0. It provides an easy and powerful way + * of extracting/hydrator objects in Doctrine, by handling most associations types. + * + * Starting from DoctrineModule 0.8.0, the hydrator can be used multiple times with different objects + * + * @license MIT + * @link http://www.doctrine-project.org/ + * @since 0.7.0 + * @author Michael Gallego + */ +class DoctrineObject extends AbstractHydrator +{ + /** + * @var ObjectManager + */ + protected $objectManager; + + /** + * @var ClassMetadata + */ + protected $metadata; + + /** + * @var bool + */ + protected $byValue = true; + + + /** + * Constructor + * + * @param ObjectManager $objectManager The ObjectManager to use + * @param bool $byValue If set to true, hydrator will always use entity's public API + */ + public function __construct(ObjectManager $objectManager, $byValue = true) + { + parent::__construct(); + + $this->objectManager = $objectManager; + $this->byValue = (bool) $byValue; + } + + /** + * Extract values from an object + * + * @param object $object + * @return array + */ + public function extract($object) + { + $this->prepare($object); + + if ($this->byValue) { + return $this->extractByValue($object); + } + + return $this->extractByReference($object); + } + + /** + * Hydrate $object with the provided $data. + * + * @param array $data + * @param object $object + * @return object + */ + public function hydrate(array $data, $object) + { + $this->prepare($object); + + if ($this->byValue) { + return $this->hydrateByValue($data, $object); + } + + return $this->hydrateByReference($data, $object); + } + + /** + * Prepare the hydrator by adding strategies to every collection valued associations + * + * @param object $object + * @return void + */ + protected function prepare($object) + { + $this->metadata = $this->objectManager->getClassMetadata(get_class($object)); + $this->prepareStrategies(); + } + + /** + * Prepare strategies before the hydrator is used + * + * @throws \InvalidArgumentException + * @return void + */ + protected function prepareStrategies() + { + $associations = $this->metadata->getAssociationNames(); + + foreach ($associations as $association) { + if ($this->metadata->isCollectionValuedAssociation($association)) { + // Add a strategy if the association has none set by user + if (!$this->hasStrategy($association)) { + if ($this->byValue) { + $this->addStrategy($association, new Strategy\AllowRemoveByValue()); + } else { + $this->addStrategy($association, new Strategy\AllowRemoveByReference()); + } + } + + $strategy = $this->getStrategy($association); + + if (!$strategy instanceof Strategy\AbstractCollectionStrategy) { + throw new InvalidArgumentException( + sprintf( + 'Strategies used for collections valued associations must inherit from ' + . 'Strategy\AbstractCollectionStrategy, %s given', + get_class($strategy) + ) + ); + } + + $strategy->setCollectionName($association) + ->setClassMetadata($this->metadata); + } + } + } + + /** + * Extract values from an object using a by-value logic (this means that it uses the entity + * API, in this case, getters) + * + * @param object $object + * @throws RuntimeException + * @return array + */ + protected function extractByValue($object) + { + $fieldNames = array_merge($this->metadata->getFieldNames(), $this->metadata->getAssociationNames()); + $methods = get_class_methods($object); + $filter = $object instanceof FilterProviderInterface + ? $object->getFilter() + : $this->filterComposite; + + $data = []; + foreach ($fieldNames as $fieldName) { + if ($filter && !$filter->filter($fieldName)) { + continue; + } + + $getter = 'get' . Inflector::classify($fieldName); + $isser = 'is' . Inflector::classify($fieldName); + + $dataFieldName = $this->computeExtractFieldName($fieldName); + if (in_array($getter, $methods)) { + $data[$dataFieldName] = $this->extractValue($fieldName, $object->$getter(), $object); + } elseif (in_array($isser, $methods)) { + $data[$dataFieldName] = $this->extractValue($fieldName, $object->$isser(), $object); + } elseif (substr($fieldName, 0, 2) === 'is' + && ctype_upper(substr($fieldName, 2, 1)) + && in_array($fieldName, $methods)) { + $data[$dataFieldName] = $this->extractValue($fieldName, $object->$fieldName(), $object); + } + + // Unknown fields are ignored + } + + return $data; + } + + /** + * Extract values from an object using a by-reference logic (this means that values are + * directly fetched without using the public API of the entity, in this case, getters) + * + * @param object $object + * @return array + */ + protected function extractByReference($object) + { + $fieldNames = array_merge($this->metadata->getFieldNames(), $this->metadata->getAssociationNames()); + $refl = $this->metadata->getReflectionClass(); + $filter = $object instanceof FilterProviderInterface + ? $object->getFilter() + : $this->filterComposite; + + $data = []; + foreach ($fieldNames as $fieldName) { + if ($filter && !$filter->filter($fieldName)) { + continue; + } + $reflProperty = $refl->getProperty($fieldName); + $reflProperty->setAccessible(true); + + $dataFieldName = $this->computeExtractFieldName($fieldName); + $data[$dataFieldName] = $this->extractValue($fieldName, $reflProperty->getValue($object), $object); + } + + return $data; + } + + /** + * Hydrate the object using a by-value logic (this means that it uses the entity API, in this + * case, setters) + * + * @param array $data + * @param object $object + * @throws RuntimeException + * @return object + */ + protected function hydrateByValue(array $data, $object) + { + $tryObject = $this->tryConvertArrayToObject($data, $object); + $metadata = $this->metadata; + + if (is_object($tryObject)) { + $object = $tryObject; + } + + foreach ($data as $field => $value) { + $field = $this->computeHydrateFieldName($field); + $value = $this->handleTypeConversions($value, $metadata->getTypeOfField($field)); + $setter = 'set' . Inflector::classify($field); + + if ($metadata->hasAssociation($field)) { + $target = $metadata->getAssociationTargetClass($field); + + if ($metadata->isSingleValuedAssociation($field)) { + if (! method_exists($object, $setter)) { + continue; + } + + $value = $this->toOne($target, $this->hydrateValue($field, $value, $data)); + + if (null === $value + && !current($metadata->getReflectionClass()->getMethod($setter)->getParameters())->allowsNull() + ) { + continue; + } + + $object->$setter($value); + } elseif ($metadata->isCollectionValuedAssociation($field)) { + $this->toMany($object, $field, $target, $value); + } + } else { + if (! method_exists($object, $setter)) { + continue; + } + + $object->$setter($this->hydrateValue($field, $value, $data)); + } + } + + return $object; + } + + /** + * Hydrate the object using a by-reference logic (this means that values are modified directly without + * using the public API, in this case setters, and hence override any logic that could be done in those + * setters) + * + * @param array $data + * @param object $object + * @return object + */ + protected function hydrateByReference(array $data, $object) + { + $tryObject = $this->tryConvertArrayToObject($data, $object); + $metadata = $this->metadata; + $refl = $metadata->getReflectionClass(); + + if (is_object($tryObject)) { + $object = $tryObject; + } + + foreach ($data as $field => $value) { + $field = $this->computeHydrateFieldName($field); + + // Ignore unknown fields + if (!$refl->hasProperty($field)) { + continue; + } + + $value = $this->handleTypeConversions($value, $metadata->getTypeOfField($field)); + $reflProperty = $refl->getProperty($field); + $reflProperty->setAccessible(true); + + if ($metadata->hasAssociation($field)) { + $target = $metadata->getAssociationTargetClass($field); + + if ($metadata->isSingleValuedAssociation($field)) { + $value = $this->toOne($target, $this->hydrateValue($field, $value, $data)); + $reflProperty->setValue($object, $value); + } elseif ($metadata->isCollectionValuedAssociation($field)) { + $this->toMany($object, $field, $target, $value); + } + } else { + $reflProperty->setValue($object, $this->hydrateValue($field, $value, $data)); + } + } + + return $object; + } + + /** + * This function tries, given an array of data, to convert it to an object if the given array contains + * an identifier for the object. This is useful in a context of updating existing entities, without ugly + * tricks like setting manually the existing id directly into the entity + * + * @param array $data The data that may contain identifiers keys + * @param object $object + * @return object + */ + protected function tryConvertArrayToObject($data, $object) + { + $metadata = $this->metadata; + $identifierNames = $metadata->getIdentifierFieldNames($object); + $identifierValues = []; + + if (empty($identifierNames)) { + return $object; + } + + foreach ($identifierNames as $identifierName) { + if (!isset($data[$identifierName])) { + return $object; + } + + $identifierValues[$identifierName] = $data[$identifierName]; + } + + return $this->find($identifierValues, $metadata->getName()); + } + + /** + * Handle ToOne associations + * + * When $value is an array but is not the $target's identifiers, $value is + * most likely an array of fieldset data. The identifiers will be determined + * and a target instance will be initialized and then hydrated. The hydrated + * target will be returned. + * + * @param string $target + * @param mixed $value + * @return object + */ + protected function toOne($target, $value) + { + $metadata = $this->objectManager->getClassMetadata($target); + + if (is_array($value) && array_keys($value) != $metadata->getIdentifier()) { + // $value is most likely an array of fieldset data + $identifiers = array_intersect_key( + $value, + array_flip($metadata->getIdentifier()) + ); + $object = $this->find($identifiers, $target) ?: new $target; + return $this->hydrate($value, $object); + } + + return $this->find($value, $target); + } + + /** + * Handle ToMany associations. In proper Doctrine design, Collections should not be swapped, so + * collections are always handled by reference. Internally, every collection is handled using specials + * strategies that inherit from AbstractCollectionStrategy class, and that add or remove elements but without + * changing the collection of the object + * + * @param object $object + * @param mixed $collectionName + * @param string $target + * @param mixed $values + * + * @throws \InvalidArgumentException + * + * @return void + */ + protected function toMany($object, $collectionName, $target, $values) + { + $metadata = $this->objectManager->getClassMetadata(ltrim($target, '\\')); + $identifier = $metadata->getIdentifier(); + + if (!is_array($values) && !$values instanceof Traversable) { + $values = (array)$values; + } + + $collection = []; + + // If the collection contains identifiers, fetch the objects from database + foreach ($values as $value) { + if ($value instanceof $target) { + // assumes modifications have already taken place in object + $collection[] = $value; + continue; + } elseif (empty($value)) { + // assumes no id and retrieves new $target + $collection[] = $this->find($value, $target); + continue; + } + + $find = []; + if (is_array($identifier)) { + foreach ($identifier as $field) { + switch (gettype($value)) { + case 'object': + $getter = 'get' . ucfirst($field); + if (method_exists($value, $getter)) { + $find[$field] = $value->$getter(); + } elseif (property_exists($value, $field)) { + $find[$field] = $value->$field; + } + break; + case 'array': + if (array_key_exists($field, $value) && $value[$field] != null) { + $find[$field] = $value[$field]; + unset($value[$field]); // removed identifier from persistable data + } + break; + default: + $find[$field] = $value; + break; + } + } + } + + if (!empty($find) && $found = $this->find($find, $target)) { + $collection[] = (is_array($value)) ? $this->hydrate($value, $found) : $found; + } else { + $collection[] = (is_array($value)) ? $this->hydrate($value, new $target) : new $target; + } + } + + $collection = array_filter( + $collection, + function ($item) { + return null !== $item; + } + ); + + // Set the object so that the strategy can extract the Collection from it + + /** @var \DoctrineModule\Stdlib\Hydrator\Strategy\AbstractCollectionStrategy $collectionStrategy */ + $collectionStrategy = $this->getStrategy($collectionName); + $collectionStrategy->setObject($object); + + // We could directly call hydrate method from the strategy, but if people want to override + // hydrateValue function, they can do it and do their own stuff + $this->hydrateValue($collectionName, $collection, $values); + } + + /** + * Handle various type conversions that should be supported natively by Doctrine (like DateTime) + * + * @param mixed $value + * @param string $typeOfField + * @return DateTime + */ + protected function handleTypeConversions($value, $typeOfField) + { + switch ($typeOfField) { + case 'datetimetz': + case 'datetime': + case 'time': + case 'date': + if ('' === $value) { + return null; + } + + if (is_int($value)) { + $dateTime = new DateTime(); + $dateTime->setTimestamp($value); + $value = $dateTime; + } elseif (is_string($value)) { + $value = new DateTime($value); + } + + break; + default: + } + + return $value; + } + + /** + * Find an object by a given target class and identifier + * + * @param mixed $identifiers + * @param string $targetClass + * + * @return object|null + */ + protected function find($identifiers, $targetClass) + { + if ($identifiers instanceof $targetClass) { + return $identifiers; + } + + if ($this->isNullIdentifier($identifiers)) { + return null; + } + + return $this->objectManager->find($targetClass, $identifiers); + } + + /** + * Verifies if a provided identifier is to be considered null + * + * @param mixed $identifier + * + * @return bool + */ + private function isNullIdentifier($identifier) + { + if (null === $identifier) { + return true; + } + + if ($identifier instanceof Traversable || is_array($identifier)) { + $nonNullIdentifiers = array_filter( + ArrayUtils::iteratorToArray($identifier), + function ($value) { + return null !== $value; + } + ); + + return empty($nonNullIdentifiers); + } + + return false; + } + + /** + * Applies the naming strategy if there is one set + * + * @param string $field + * + * @return string + */ + protected function computeHydrateFieldName($field) + { + if ($this->hasNamingStrategy()) { + $field = $this->getNamingStrategy()->hydrate($field); + } + return $field; + } + + /** + * Applies the naming strategy if there is one set + * + * @param string $field + * + * @return string + */ + protected function computeExtractFieldName($field) + { + if ($this->hasNamingStrategy()) { + $field = $this->getNamingStrategy()->extract($field); + } + return $field; + } +} diff --git a/src/App/Hydrator/DoctrineObjectFactory.php b/src/App/Hydrator/DoctrineObjectFactory.php new file mode 100644 index 0000000..d7d10ea --- /dev/null +++ b/src/App/Hydrator/DoctrineObjectFactory.php @@ -0,0 +1,15 @@ +get('doctrine.entity_manager.orm_default'); + return new DoctrineObject($em); + } +} diff --git a/src/App/Hydrator/Filter/PropertyName.php b/src/App/Hydrator/Filter/PropertyName.php new file mode 100644 index 0000000..daafc86 --- /dev/null +++ b/src/App/Hydrator/Filter/PropertyName.php @@ -0,0 +1,66 @@ +. + */ + +namespace App\Hydrator\Filter; + +use Zend\Hydrator\Filter\FilterInterface; + +/** + * Provides a filter to restrict returned fields by whitelisting or + * blacklisting property names. + * + * @license MIT + * @link http://www.doctrine-project.org/ + * @author Liam O'Boyle + */ +class PropertyName implements FilterInterface +{ + /** + * The propteries to exclude. + * + * @var array + */ + protected $properties = []; + + /** + * Either an exclude or an include. + * + * @var bool + */ + protected $exclude = null; + + /** + * @param [ string | array ] $properties The properties to exclude or include. + * @param bool $exclude If the method should be excluded + */ + public function __construct($properties, $exclude = true) + { + $this->exclude = $exclude; + $this->properties = is_array($properties) + ? $properties + : [$properties]; + } + + public function filter($property) + { + return in_array($property, $this->properties) + ? !$this->exclude + : $this->exclude; + } +} diff --git a/src/App/Hydrator/Strategy/AbstractCollectionStrategy.php b/src/App/Hydrator/Strategy/AbstractCollectionStrategy.php new file mode 100644 index 0000000..37e6738 --- /dev/null +++ b/src/App/Hydrator/Strategy/AbstractCollectionStrategy.php @@ -0,0 +1,190 @@ +. + */ + +namespace App\Hydrator\Strategy; + +use InvalidArgumentException; +use Doctrine\Common\Collections\Collection; +use Doctrine\Common\Persistence\Mapping\ClassMetadata; +use Zend\Hydrator\Strategy\StrategyInterface; + +/** + * @license MIT + * @link http://www.doctrine-project.org/ + * @since 0.7.0 + * @author Michael Gallego + */ +abstract class AbstractCollectionStrategy implements StrategyInterface +{ + /** + * @var string + */ + protected $collectionName; + + /** + * @var ClassMetadata + */ + protected $metadata; + + /** + * @var object + */ + protected $object; + + + /** + * Set the name of the collection + * + * @param string $collectionName + * @return AbstractCollectionStrategy + */ + public function setCollectionName($collectionName) + { + $this->collectionName = (string) $collectionName; + return $this; + } + + /** + * Get the name of the collection + * + * @return string + */ + public function getCollectionName() + { + return $this->collectionName; + } + + /** + * Set the class metadata + * + * @param ClassMetadata $classMetadata + * @return AbstractCollectionStrategy + */ + public function setClassMetadata(ClassMetadata $classMetadata) + { + $this->metadata = $classMetadata; + return $this; + } + + /** + * Get the class metadata + * + * @return ClassMetadata + */ + public function getClassMetadata() + { + return $this->metadata; + } + + /** + * Set the object + * + * @param object $object + * + * @throws \InvalidArgumentException + * + * @return AbstractCollectionStrategy + */ + public function setObject($object) + { + if (!is_object($object)) { + throw new InvalidArgumentException( + sprintf('The parameter given to setObject method of %s class is not an object', get_called_class()) + ); + } + + $this->object = $object; + return $this; + } + + /** + * Get the object + * + * @return object + */ + public function getObject() + { + return $this->object; + } + + /** + * {@inheritDoc} + */ + public function extract($value) + { + return $value; + } + + /** + * Return the collection by value (using the public API) + * + * @throws \InvalidArgumentException + * + * @return Collection + */ + protected function getCollectionFromObjectByValue() + { + $object = $this->getObject(); + $getter = 'get' . ucfirst($this->getCollectionName()); + + if (!method_exists($object, $getter)) { + throw new InvalidArgumentException( + sprintf( + 'The getter %s to access collection %s in object %s does not exist', + $getter, + $this->getCollectionName(), + get_class($object) + ) + ); + } + + return $object->$getter(); + } + + /** + * Return the collection by reference (not using the public API) + * + * @return Collection + */ + protected function getCollectionFromObjectByReference() + { + $object = $this->getObject(); + $refl = $this->getClassMetadata()->getReflectionClass(); + $reflProperty = $refl->getProperty($this->getCollectionName()); + + $reflProperty->setAccessible(true); + + return $reflProperty->getValue($object); + } + + + /** + * This method is used internally by array_udiff to check if two objects are equal, according to their + * SPL hash. This is needed because the native array_diff only compare strings + * + * @param object $a + * @param object $b + * + * @return int + */ + protected function compareObjects($a, $b) + { + return strcmp(spl_object_hash($a), spl_object_hash($b)); + } +} diff --git a/src/App/Hydrator/Strategy/AllowRemoveByReference.php b/src/App/Hydrator/Strategy/AllowRemoveByReference.php new file mode 100644 index 0000000..57e4222 --- /dev/null +++ b/src/App/Hydrator/Strategy/AllowRemoveByReference.php @@ -0,0 +1,58 @@ +. + */ + +namespace App\Hydrator\Strategy; + +/** + * When this strategy is used for Collections, if the new collection does not contain elements that are present in + * the original collection, then this strategy remove elements from the original collection. For instance, if the + * collection initially contains elements A and B, and that the new collection contains elements B and C, then the + * final collection will contain elements B and C (while element A will be asked to be removed). + * + * This strategy is by reference, this means it won't use public API to add/remove elements to the collection + * + * @license MIT + * @link http://www.doctrine-project.org/ + * @since 0.7.0 + * @author Michael Gallego + */ +class AllowRemoveByReference extends AbstractCollectionStrategy +{ + /** + * {@inheritDoc} + */ + public function hydrate($value) + { + $collection = $this->getCollectionFromObjectByReference(); + $collectionArray = $collection->toArray(); + + $toAdd = array_udiff($value, $collectionArray, [$this, 'compareObjects']); + $toRemove = array_udiff($collectionArray, $value, [$this, 'compareObjects']); + + foreach ($toAdd as $element) { + $collection->add($element); + } + + foreach ($toRemove as $element) { + $collection->removeElement($element); + } + + return $collection; + } +} diff --git a/src/App/Hydrator/Strategy/AllowRemoveByValue.php b/src/App/Hydrator/Strategy/AllowRemoveByValue.php new file mode 100644 index 0000000..2ac85ae --- /dev/null +++ b/src/App/Hydrator/Strategy/AllowRemoveByValue.php @@ -0,0 +1,76 @@ +. + */ + +namespace App\Hydrator\Strategy; + +use Doctrine\Common\Collections\Collection; +use LogicException; +use Doctrine\Common\Collections\ArrayCollection; + +/** + * When this strategy is used for Collections, if the new collection does not contain elements that are present in + * the original collection, then this strategy remove elements from the original collection. For instance, if the + * collection initially contains elements A and B, and that the new collection contains elements B and C, then the + * final collection will contain elements B and C (while element A will be asked to be removed). + * + * This strategy is by value, this means it will use the public API (in this case, adder and remover) + * + * @license MIT + * @link http://www.doctrine-project.org/ + * @since 0.7.0 + * @author Michael Gallego + */ +class AllowRemoveByValue extends AbstractCollectionStrategy +{ + /** + * {@inheritDoc} + */ + public function hydrate($value) + { + // AllowRemove strategy need "adder" and "remover" + $adder = 'add' . ucfirst($this->collectionName); + $remover = 'remove' . ucfirst($this->collectionName); + + if (!method_exists($this->object, $adder) || !method_exists($this->object, $remover)) { + throw new LogicException( + sprintf( + 'AllowRemove strategy for DoctrineModule hydrator requires both %s and %s to be defined in %s + entity domain code, but one or both seem to be missing', + $adder, + $remover, + get_class($this->object) + ) + ); + } + + $collection = $this->getCollectionFromObjectByValue(); + + if ($collection instanceof Collection) { + $collection = $collection->toArray(); + } + + $toAdd = new ArrayCollection(array_udiff($value, $collection, [$this, 'compareObjects'])); + $toRemove = new ArrayCollection(array_udiff($collection, $value, [$this, 'compareObjects'])); + + $this->object->$adder($toAdd); + $this->object->$remover($toRemove); + + return $collection; + } +} diff --git a/src/App/Hydrator/Strategy/DisallowRemoveByReference.php b/src/App/Hydrator/Strategy/DisallowRemoveByReference.php new file mode 100644 index 0000000..e1cbb41 --- /dev/null +++ b/src/App/Hydrator/Strategy/DisallowRemoveByReference.php @@ -0,0 +1,53 @@ +. + */ + +namespace App\Hydrator\Strategy; + +/** + * When this strategy is used for Collections, if the new collection does not contain elements that are present in + * the original collection, then this strategy will not remove those elements. At most, it will add new elements. For + * instance, if the collection initially contains elements A and B, and that the new collection contains elements B + * and C, then the final collection will contain elements A, B and C. + * + * This strategy is by reference, this means it won't use the public API to remove elements + * + * @license MIT + * @link http://www.doctrine-project.org/ + * @since 0.7.0 + * @author Michael Gallego + */ +class DisallowRemoveByReference extends AbstractCollectionStrategy +{ + /** + * {@inheritDoc} + */ + public function hydrate($value) + { + $collection = $this->getCollectionFromObjectByReference(); + $collectionArray = $collection->toArray(); + + $toAdd = array_udiff($value, $collectionArray, [$this, 'compareObjects']); + + foreach ($toAdd as $element) { + $collection->add($element); + } + + return $collection; + } +} diff --git a/src/App/Hydrator/Strategy/DisallowRemoveByValue.php b/src/App/Hydrator/Strategy/DisallowRemoveByValue.php new file mode 100644 index 0000000..6f2bbcc --- /dev/null +++ b/src/App/Hydrator/Strategy/DisallowRemoveByValue.php @@ -0,0 +1,72 @@ +. + */ + +namespace App\Hydrator\Strategy; + +use Doctrine\Common\Collections\Collection; +use LogicException; +use Doctrine\Common\Collections\ArrayCollection; + +/** + * When this strategy is used for Collections, if the new collection does not contain elements that are present in + * the original collection, then this strategy will not remove those elements. At most, it will add new elements. For + * instance, if the collection initially contains elements A and B, and that the new collection contains elements B + * and C, then the final collection will contain elements A, B and C. + * + * This strategy is by value, this means it will use the public API (in this case, remover) + * + * @license MIT + * @link http://www.doctrine-project.org/ + * @since 0.7.0 + * @author Michael Gallego + */ +class DisallowRemoveByValue extends AbstractCollectionStrategy +{ + /** + * {@inheritDoc} + */ + public function hydrate($value) + { + // AllowRemove strategy need "adder" + $adder = 'add' . ucfirst($this->collectionName); + + if (!method_exists($this->object, $adder)) { + throw new LogicException( + sprintf( + 'DisallowRemove strategy for DoctrineModule hydrator requires %s to + be defined in %s entity domain code, but it seems to be missing', + $adder, + get_class($this->object) + ) + ); + } + + $collection = $this->getCollectionFromObjectByValue(); + + if ($collection instanceof Collection) { + $collection = $collection->toArray(); + } + + $toAdd = new ArrayCollection(array_udiff($value, $collection, [$this, 'compareObjects'])); + + $this->object->$adder($toAdd); + + return $collection; + } +} diff --git a/src/App/Middleware/CorsMiddlewareFactory.php b/src/App/Middleware/CorsMiddlewareFactory.php new file mode 100644 index 0000000..a74d930 --- /dev/null +++ b/src/App/Middleware/CorsMiddlewareFactory.php @@ -0,0 +1,45 @@ + ["*"], + "methods" => ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"], + "headers.allow" => [ + 'DNT', + 'X-CustomHeader', + 'Keep-Alive', + 'User-Agent', + 'X-Requested-With', + 'If-Match', + 'If-Modified-Since', + 'If-Unmodified-Since', + 'Cache-Control', + 'Content-Type', + 'Authorization', + ], + "headers.expose" => ["Etag"], + "credentials" => true, +// "cache" => 86400 + ]); + } +} diff --git a/src/App/Middleware/JwtAuthenticationFactory.php b/src/App/Middleware/JwtAuthenticationFactory.php new file mode 100644 index 0000000..67a9a0d --- /dev/null +++ b/src/App/Middleware/JwtAuthenticationFactory.php @@ -0,0 +1,69 @@ +get('config'); + $this->config = (new Config($config))->get('acl_config'); + return new JwtAuthentication([ + "secret" => $this->config->get('hmac_key', self::DEFAULT_HMAC), + "path" => "/api", + "passthrough" => $this->getPassThroughRoutes($container), + "secure" => true, + "relaxed" => [ + "localhost", + "wnapi.yvan.hu", + ], + "error" => function (RequestInterface $request, ResponseInterface $response, $arguments) { + $data["status"] = "error"; + $data["message"] = $arguments["message"]; + return new JsonCorsResponse($data, 401); + } + ]); + } + + /** + * @param ContainerInterface $container + * @return array + */ + private function getPassThroughRoutes(ContainerInterface $container) + { + $passThroughRoutes = []; + + /** @var Application $app */ + $app = $container->get(Application::class); + $appRoutes = $app->getRoutes(); + + $unguardedRoutes = $this->config->get('unguarded_routes', new Config([]))->toArray(); + /** @var Route $route */ + foreach ($appRoutes as $route) { + if (in_array($route->getName(), $unguardedRoutes)) { + $passThroughRoutes[] = $route->getPath(); + } + } + $passThroughRoutes[] = '/show-attachment'; + $passThroughRoutes[] = '/hibajegy-pdf'; + $passThroughRoutes[] = '/havi-riport-pdf'; + + return $passThroughRoutes; + } +} diff --git a/src/App/Middleware/RouteAuthorization.php b/src/App/Middleware/RouteAuthorization.php new file mode 100644 index 0000000..9013903 --- /dev/null +++ b/src/App/Middleware/RouteAuthorization.php @@ -0,0 +1,75 @@ +config = $config; + $this->aclService = $aclService; + } + + public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null) + { + if ($request->getMethod() == 'OPTIONS') { + return $next($request, $response); + } + + /** @var RouteResult $routeResult */ + $routeResult = $request->getAttribute(RouteResult::class, false); + $token = $request->getAttribute('token'); + + if ($this->hasRouteAccess($routeResult->getMatchedRouteName(), $token->roles ?? [])) { + return $next($request, $response); + } + + return new JsonCorsResponse([ + 'status' => 'err', + 'message' => "Access denied to " . $routeResult->getMatchedRouteName(), + ], 401); + } + + private function hasRouteAccess(string $route, $roles = []) + { + // admin role has full access + if (in_array('admin', $roles)) { + return true; + } + + // bail out if route is white listed + $unguardedRoutes = $this->config->get('unguarded_routes', new Config([]))->toArray(); + if (in_array($route, $unguardedRoutes)) { + return true; + } + + // check configuration for other options + foreach ($roles as $role) { + if ($this->roleCanAccessRoute($role, $route)) { + return true; + } + } + + return false; + } + + private function roleCanAccessRoute(string $role, string $routeName) + { + return $this->aclService->isGranted($role, $routeName); + } +} diff --git a/src/App/Middleware/RouteAuthorizationFactory.php b/src/App/Middleware/RouteAuthorizationFactory.php new file mode 100644 index 0000000..32cfefa --- /dev/null +++ b/src/App/Middleware/RouteAuthorizationFactory.php @@ -0,0 +1,19 @@ +get('config')['acl_config']); + /** @var Rbac $aclService */ + $aclService = $container->get('service.acl'); + return new RouteAuthorization($config, $aclService); + } +} diff --git a/src/App/Response/JsonCorsResponse.php b/src/App/Response/JsonCorsResponse.php new file mode 100644 index 0000000..7b71dd9 --- /dev/null +++ b/src/App/Response/JsonCorsResponse.php @@ -0,0 +1,32 @@ +entityManager = $em; + $this->config = $config; + } + + /** + * @param string $users + * @param string $pass + * @return AuthResponse + * @throws NoResultException + */ + public function authenticate(string $users, string $pass): AuthResponse + { + $response = new AuthResponse(); + + $crypt = new Bcrypt(); + $crypt->setCost(self::PASSWORD_COST); + + /** + * Extremely bad idea, but client requested this implementation regardless of the warnings. + * As an extra security measure "shared" type users can't change their password + */ + + /** @var User[] $users */ + $users = $this->entityManager->getRepository(User::class)->findBy([ + 'email' => $users, + 'active' => true, + ]); + if (null === $users || empty($users)) { + throw new NoResultException(); + } + shuffle($users); + + foreach ($users as $user) { + if ($crypt->verify($pass, $user->getPassword())) { + $token = (string)$this->generateJWT($user); + $response->setToken($token) + ->setMessage('login'); + return $response; + } + } + + throw new NoResultException(); + } + + /** + * @param $token + * @return AuthResponse + */ + public function renewToken($token): AuthResponse + { + $response = new AuthResponse(); + $response->setMessage('renew') + ->setToken((string)$this->renewJWT($token)); + return $response; + } + + /** + * @param User $user + * @return Token + */ + private function generateJwt(User $user): Token + { + /** @var string $hmacKey */ + $hmacKey = $this->config->get('hmac_key'); + + $signer = new Sha512(); + $builder = new Builder(); + + return $builder + ->setId(base64_encode(uniqid()), true) + ->setIssuedAt(time()) + ->setNotBefore(time()) + ->setExpiration(time() + 3600) + ->set('uid', $user->getId()) + ->set('name', $user->getName()) + ->set('email', $user->getEmail()) + ->set('roles', $user->getRoles()) + ->sign($signer, $hmacKey) + ->getToken(); + } + + /** + * @param $token + * @return Token + */ + private function renewJWT($token): Token + { + /** @var string $hmacKey */ + $hmacKey = $this->config->get('hmac_key'); + + $signer = new Sha512(); + $builder = new Builder(); + + return $builder + ->setId($token->jti, true) + ->setIssuedAt(time()) + ->setNotBefore(time()) + ->setExpiration(time() + 3600) + ->set('uid', $token->uid) + ->set('name', $token->name) + ->set('email', $token->email) + ->set('roles', $token->roles) + ->sign($signer, $hmacKey) + ->getToken(); + } +} diff --git a/src/App/Service/AuthServiceFactory.php b/src/App/Service/AuthServiceFactory.php new file mode 100644 index 0000000..a7cde11 --- /dev/null +++ b/src/App/Service/AuthServiceFactory.php @@ -0,0 +1,17 @@ +get('doctrine.entity_manager.orm_default'); + $configArr = $container->get('config')['acl_config']; + $config = new Config($configArr); + return new AuthService($em, $config); + } +} diff --git a/src/App/Service/ErrorCategoryService.php b/src/App/Service/ErrorCategoryService.php new file mode 100644 index 0000000..a6e0865 --- /dev/null +++ b/src/App/Service/ErrorCategoryService.php @@ -0,0 +1,32 @@ +em = $em; + } + + /** + * Return FacilityLocations in a tree form + * + * @return array + */ + public function getList() + { + /** @var EntityRepository $treeRepository */ + $repository = $this->em->getRepository(ErrorCategory::class); + return $repository->findAll(); + } +} diff --git a/src/App/Service/ErrorCategoryServiceFactory.php b/src/App/Service/ErrorCategoryServiceFactory.php new file mode 100644 index 0000000..27fae1d --- /dev/null +++ b/src/App/Service/ErrorCategoryServiceFactory.php @@ -0,0 +1,16 @@ +get('doctrine.entity_manager.orm_default'); + return new ErrorCategoryService($em); + } +} diff --git a/src/App/Service/ErrorOriginService.php b/src/App/Service/ErrorOriginService.php new file mode 100644 index 0000000..54d3c8b --- /dev/null +++ b/src/App/Service/ErrorOriginService.php @@ -0,0 +1,32 @@ +em = $em; + } + + /** + * Return FacilityLocations in a tree form + * + * @return array + */ + public function getList() + { + /** @var EntityRepository $treeRepository */ + $repository = $this->em->getRepository(ErrorOrigin::class); + return $repository->findAll(); + } +} diff --git a/src/App/Service/ErrorOriginServiceFactory.php b/src/App/Service/ErrorOriginServiceFactory.php new file mode 100644 index 0000000..24535f1 --- /dev/null +++ b/src/App/Service/ErrorOriginServiceFactory.php @@ -0,0 +1,16 @@ +get('doctrine.entity_manager.orm_default'); + return new ErrorOriginService($em); + } +} diff --git a/src/App/Service/FacilityLocationService.php b/src/App/Service/FacilityLocationService.php new file mode 100644 index 0000000..90707ab --- /dev/null +++ b/src/App/Service/FacilityLocationService.php @@ -0,0 +1,61 @@ +em = $em; + } + + /** + * Return FacilityLocations in a tree form + * @return array + */ + public function getFacilityLocationListTree() + { + /** @var ClosureTreeRepository $treeRepository */ + $treeRepository = $this->em->getRepository(FacilityLocation::class); + $rootNode = $treeRepository->findOneBy(['name' => 'root']); + return $treeRepository->childrenHierarchy($rootNode); + } + + /** + * @return array + */ + public function getFacilityLocationListFlat() + { + $result = []; + $tree = $this->getFacilityLocationListTree(); + return $this->flatner($tree, $result); + } + + /** + * @param $items + * @param $result + * @return array + */ + private function flatner($items, &$result) + { + foreach ($items as $item) { + $children = $item['__children']; + unset($item['__children']); + $result[] = $item; + if ($children) { + $this->flatner($children, $result); + } + unset($children); + } + return $result; + } +} diff --git a/src/App/Service/FacilityLocationServiceFactory.php b/src/App/Service/FacilityLocationServiceFactory.php new file mode 100644 index 0000000..1028d6a --- /dev/null +++ b/src/App/Service/FacilityLocationServiceFactory.php @@ -0,0 +1,16 @@ +get('doctrine.entity_manager.orm_default'); + return new FacilityLocationService($em); + } +} diff --git a/src/App/Service/FaultAttachmentService.php b/src/App/Service/FaultAttachmentService.php new file mode 100644 index 0000000..ceb5e00 --- /dev/null +++ b/src/App/Service/FaultAttachmentService.php @@ -0,0 +1,168 @@ +em = $em; + $this->hydrator = $hydrator; + $this->authService = $authService; + $this->mailer = $mailer; + $this->userService = $userService; + } + + /** + * @param int $id + * @return Attachment[]|null + */ + public function getList(int $id) + { + $qb = $this->em->createQueryBuilder(); + $entities = $qb->select('p') + ->from(Attachment::class, 'p') + ->leftJoin('p.fault', 'f') + ->where('f.id = :fid') + ->setParameter('fid', $id) + ->getQuery() + ->getResult(); + return $entities; + } + + /** + * + * @param int $id + * @return Attachment + * @throws NonUniqueResultException + * @throws NoResultException + */ + public function get(int $id) + { + $qb = $this->em->createQueryBuilder(); + + $entity = $qb->select('p') + ->from(Attachment::class, 'p') + ->where('p.id = :id') + ->setParameter('id', $id) + ->getQuery() + ->getSingleResult(Query::HYDRATE_OBJECT); + + return $entity; + } + + /** + * @param int $faultId + * @param UploadedFileInterface[] $files + * @param int $uid + * @param string $type Type can be image or invoice + * @return Fault + */ + public function createAttachments(int $faultId, array $files, int $uid, $type = 'image'): Fault + { + /** @var User $user */ + $user = $this->em->find(User::class, $uid); + /** @var Fault $fault */ + $fault = $this->em->find(Fault::class, $faultId); + foreach ($files as $file) { + $attachment = new Attachment(); + $attachment->setFault($fault) + ->setUser($user) + ->setType($type) + ->setRawFileData($file->getStream()->getContents()); + $this->em->persist($attachment); + } + $this->em->flush(); + if ($type=='image') { + $this->sendPhotoAttachedMail($fault, $user); + } + return $fault; + } + + /** + * Send message if new photo was attached to a Fault + * + * @param Fault $fault + * @param User $user + */ + private function sendPhotoAttachedMail(Fault $fault, User $user) + { + $recipientsUsers = $this->userService->getAllUsersOfRole('ufo'); + $recipientsUsers[] = $fault->getReporter(); + $recipients = $this->getMailAddresses($recipientsUsers); + + $this->mailer->sendFaultMail( + $recipients, + sprintf("[WN] Kép feltöltés - %s", $fault->getWorksheetNumber()), + $fault, + sprintf("%s új képet csatolt az hibához.", $user->getName()) + ); + } + + /** + * @param User[] $mailRecipientUsers + * @return string[] + */ + private function getMailAddresses(array $mailRecipientUsers): array + { + $usersWhoWantEmail = array_filter($mailRecipientUsers, function (User $user) { + return $user->isWantsEmail(); + }); + + $recipients = array_map(function (User $user) { + return $user->getEmail(); + }, $usersWhoWantEmail); + + return array_unique($recipients); + } +} diff --git a/src/App/Service/FaultAttachmentServiceFactory.php b/src/App/Service/FaultAttachmentServiceFactory.php new file mode 100644 index 0000000..35a2692 --- /dev/null +++ b/src/App/Service/FaultAttachmentServiceFactory.php @@ -0,0 +1,26 @@ +get('doctrine.entity_manager.orm_default'); + /** @var DoctrineObject $hydrator */ + $hydrator = $container->get('doctrine.hydrator'); + /** @var AuthService $authService */ + $authService = $container->get(AuthService::class); + /** @var MailerService $mailer */ + $mailer = $container->get(MailerService::class); + /** @var UserService $userService */ + $userService = $container->get(UserService::class); + return new FaultAttachmentService($em, $hydrator, $authService, $mailer, $userService); + } +} diff --git a/src/App/Service/FaultManagerService.php b/src/App/Service/FaultManagerService.php new file mode 100644 index 0000000..981b95a --- /dev/null +++ b/src/App/Service/FaultManagerService.php @@ -0,0 +1,470 @@ +em = $em; + $this->hydrator = $hydrator; + $this->authService = $authService; + $this->mailer = $mailer; + $this->userService = $userService; + } + + public function getFaultList() + { + $faults = $this->em->getRepository(Fault::class)->findBy([], [ + 'createdAt' => 'DESC', + ]); + // @todo queryBuilder might be better here? + return $faults; + } + + /** + * @param int $id + * @return Fault|null + */ + public function getFault(int $id): ?Fault + { + /** @var Fault $fault */ + $fault = $this->em->find(Fault::class, $id); + return $fault; + } + + public function createFault($data, $uid): Fault + { + /** @var User $user */ + $user = $this->em->find(User::class, $uid); + /** @var Fault $fault */ + $fault = $this->hydrator->hydrate($data, new Fault()); + // @todo validate user permissions versus the data before persisting + $fault->setReporter($user); + $this->em->persist($fault); + $this->em->flush(); + + $this->sendNewMail($fault); + + return $fault; + } + + /** + * States: + * new - fault was just created + * cnf - fault confirmed, repair ongoing + * exp - fault is high expense, needs approval + * wip - fault is being worked on + * fin - repair is finished, acknowledged + * + * @param int $id + * @param array $data + * @param int $uid + * @return Fault + */ + public function updateFault(int $id, array $data, int $uid): Fault + { + // @todo validate user permissions versus the data before persisting + /** @var User $user */ + $user = $this->em->find(User::class, $uid); + $oldFault = $this->getFault($id); + $prevState = $oldFault->getState(); + $this->snapshotHandler($oldFault, $user, $data['state']); + /** @var Fault $fault */ + $fault = $this->hydrator->hydrate($data, $oldFault); + // fault is confirmed + $now = new \DateTime(); + if ($prevState == 'new' && in_array($data['state'], ['cnf','exp'])) { + $fault->setConfirmer($user) + ->setConfirmedAt($now); + } + // high expense approved + if ($prevState == 'exp' && $data['state'] == 'cnf') { + $fault->setApprovedBy($user) + ->setApprovedAt($now); + } + if ($data['state'] == 'fin') { + $fault->setAcknowledgedBy($user) + ->setAcknowledgedAt($now) + ->setWorkFinished($now); + } + if ($fault->getWorksheetNumber() == null && $fault->getState() == 'cnf') { + $fault->setWorksheetNumber($this->generateWorksheetId()); + } + $this->em->persist($fault); + $this->em->flush(); + + switch ($fault->getState()) { + case 'cnf': + if ($prevState == 'exp') { + $this->sendExpensiveConfirmedMail($fault, $user); + } + if ($prevState == 'new') { + $this->sendConfirmedMail($fault, $user); + } + break; + case 'exp': + $this->sendHighExpenseFaultMail($fault, $user); + break; + case 'wip': + if ($prevState == 'cnf') { + $this->sendDoneEmail($fault, $user); + } + if ($prevState == 'fin') { + $this->sendNotFinishedMail($fault, $user); + } +// if($prevState == 'wip') { +// } + break; + case 'fin': + $this->sendFinishedMail($fault, $user); + break; + } + + return $fault; + } + + /** + * Faults are not meant to be deleted at any point + * + * @param int $id + * @return bool + */ + public function deleteFault(int $id): bool + { + return false; + } + + public function addFaultComment(int $id, $data, int $uid): Fault + { + /** @var Fault $fault */ + $fault = $this->em->find(Fault::class, $id); + /** @var User $user */ + $user = $this->em->find(User::class, $uid); + /** @var FaultComment $faultComment */ + $faultComment = $this->hydrator->hydrate($data, new FaultComment()); + // @todo validate user permissions versus the data before persisting + $faultComment->setFault($fault)->setUser($user); + $this->em->persist($faultComment); + $this->em->flush(); + $this->sendNewCommentOnFaultMail($fault, $user, $faultComment); + return $fault; + } + + /** + * @param int $id + * @param $data + * @param int $uid + * @return Fault + */ + public function rejectFault(int $id, $data, int $uid): Fault + { + $rejectReason = $data['__reason'] ?? ""; + /** @var User $user */ + $user = $this->em->find(User::class, $uid); + /** @var Fault $fault */ + $fault = $this->em->find(Fault::class, $id); + $this->snapshotHandler($fault, $user, $data['state'], $rejectReason); + $fault->setState($data['state']); + $rejectComment = new FaultComment(); + $rejectComment->setUser($user) + ->setComment(sprintf("Elutasítva:\n%s", $rejectReason)); + $fault->addComment($rejectComment); + $this->em->persist($rejectComment); + $this->em->flush(); + + $this->sendRejectedMail($fault, $user); + + return $fault; + } + + /** + * Create fault snapshots, provide Fault object before modification + * + * @param Fault $fault + * @param User $user + * @param $newState + * @param string $comment + */ + private function snapshotHandler(Fault $fault, User $user, $newState, $comment = '') + { + $snapShot = new FaultSnapshot(); + $faultSerialized = $fault->jsonSerialize(); + unset($faultSerialized['faultSnapshots']); + $snapShot->setUser($user) + ->setFault($fault) + ->setOldState($fault->getState()) + ->setNewState($newState) + ->setComment($comment) + ->setPayload($faultSerialized); + $this->em->persist($snapShot); + $this->em->flush(); + } + + /** + * @return string + */ + private function generateWorksheetId(): string + { + $year = date("Y"); + $yearsFaultCount = $this->em->createQueryBuilder() + ->select('count(f.id)') + ->from(Fault::class, 'f') + ->where('YEAR(f.createdAt) = :thisYear') + ->andWhere('f.createdAt IS NOT null') + ->andWhere('f.worksheetNumber IS NOT null') + ->setParameter('thisYear', $year) + ->getQuery() + ->setHydrationMode(Query::HYDRATE_SINGLE_SCALAR) + ->execute(); + return sprintf("%s/%s", $year, $yearsFaultCount+1); + } + + /** + * ->new + * @param Fault $fault + */ + private function sendNewMail(Fault $fault) + { + $ufoUsers = $this->userService->getAllUsersOfRole('ufo'); + $pvUsers = $this->userService->getAllUsersOfRole('projektvezeto'); + $recipientsUsers = array_merge($ufoUsers, $pvUsers); + $recipients = $this->getMailAddresses($recipientsUsers); + + $this->mailer->sendFaultMail( + array_unique($recipients), + "[WN] Új hibabejelentés", + $fault + ); + } + + /** + * new -> cnf + * @param Fault $fault + * @param User $user + */ + private function sendConfirmedMail(Fault $fault, User $user) + { + $recipientsUsers = $this->userService->getAllUsersOfRole('ufo'); + $recipientsUsers[] = $fault->getReporter(); + $recipients = $this->getMailAddresses($recipientsUsers); + + $this->mailer->sendFaultMail( + $recipients, + sprintf("[WN] Kisértékű munka - %s", $fault->getWorksheetNumber()), + $fault, + sprintf( + "Becsült munkaköltség: %s\nBecsült alapanyagköltség: %s\nVisszaigazolta: %s", + $fault->getWorkCostEstimate(), + $fault->getMaterialCostEstimate(), + $user->getName() + ) + ); + } + + /** + * new -> exp + * @param Fault $fault + * @param User $user + */ + private function sendHighExpenseFaultMail(Fault $fault, User $user) + { + $recipientsUsers = $this->userService->getAllUsersOfRole('ufo'); + $recipientsUsers[] = $fault->getReporter(); + $recipients = $this->getMailAddresses($recipientsUsers); + + $this->mailer->sendFaultMail( + $recipients, + "[WN] Nagyértékű munka", + $fault, + sprintf( + "Becsült munkaköltség: %s\nBecsült alapanyagköltség: %s\nVisszaigazolta: %s", + $fault->getWorkCostEstimate(), + $fault->getMaterialCostEstimate(), + $user->getName() + ) + ); + } + + /** + * exp -> cnf + * @param Fault $fault + * @param User $user + */ + private function sendExpensiveConfirmedMail(Fault $fault, User $user) + { + $recipientsUsers = $this->userService->getAllUsersOfRole('ufo'); + $recipientsUsers[] = $fault->getReporter(); + $recipients = $this->getMailAddresses($recipientsUsers); + + $this->mailer->sendFaultMail( + $recipients, + sprintf("[WN] Nagyértékű munka jóváhagyva - %s", $fault->getWorksheetNumber()), + $fault, + sprintf( + "Becsült munkaköltség: %s\nBecsült alapanyagköltség: %s\nJóváhagyta: %s", + $fault->getWorkCostEstimate(), + $fault->getMaterialCostEstimate(), + $user->getName() + ) + ); + } + + /** + * exp -> rej + * @param Fault $fault + * @param User $user + */ + private function sendRejectedMail(Fault $fault, User $user) + { + $recipientsUsers = $this->userService->getAllUsersOfRole('projektvezeto'); + $recipientsUsers[] = $fault->getReporter(); + $recipients = $this->getMailAddresses($recipientsUsers); + + $this->mailer->sendFaultMail( + $recipients, + "[WN] Nagyértékű munka elutasítva", + $fault, + sprintf("A hiba javítását %s elutasította", $user->getName()) + ); + } + + /** + * Send an email to all users involved in fault communication + * + * @param Fault $fault + * @param User $user + */ + private function sendNewCommentOnFaultMail(Fault $fault, User $user, FaultComment $comment) + { + $ufoUsers = $this->userService->getAllUsersOfRole('ufo'); + $comments = $fault->getComments()->toArray(); + $involvedUsers = array_map(function (FaultComment $comment) { + return $comment->getUser(); + }, $comments); + $recipientsUsers = array_merge($ufoUsers, $involvedUsers); + $recipients = $this->getMailAddresses($recipientsUsers); + + $this->mailer->sendFaultMail( + $recipients, + sprintf("[WN] Új hozzászólás - %s", $fault->getWorksheetNumber()), + $fault, + sprintf("Hozzászólt: %s\n%s", $comment->getUser()->getName(), $comment->getComment()) + ); + } + + /** + * cnf -> wip + * @param Fault $fault + * @param User $user + */ + private function sendDoneEmail(Fault $fault, User $user) + { + $recipientsUsers = $this->userService->getAllUsersOfRole('ufo'); + $recipientsUsers[] = $fault->getReporter(); + $recipients = $this->getMailAddresses($recipientsUsers); + + $this->mailer->sendFaultMail( + $recipients, + sprintf("[WN] Hiba javítása elkészült - %s", $fault->getWorksheetNumber()), + $fault, + sprintf("A hiba javítást lezárta: %s", $user->getName()) + ); + } + + /** + * wip -> fin + * @param Fault $fault + * @param User $user + */ + private function sendFinishedMail(Fault $fault, User $user) + { + $ufoUsers = $this->userService->getAllUsersOfRole('ufo'); + $pvUsers = $this->userService->getAllUsersOfRole('projektvezeto'); + $recipientsUsers = array_merge($ufoUsers, $pvUsers); + $recipients = $this->getMailAddresses($recipientsUsers); + + $this->mailer->sendFaultMail( + $recipients, + sprintf("[WN] Hiba javítása visszaigazolva - %s", $fault->getWorksheetNumber()), + $fault, + sprintf("A hiba javítást visszaigazolta: %s", $user->getName()) + ); + } + + /** + * fin -> wip + * @param Fault $fault + * @param User $user + */ + private function sendNotFinishedMail(Fault $fault, User $user) + { + $ufoUsers = $this->userService->getAllUsersOfRole('ufo'); + $pvUsers = $this->userService->getAllUsersOfRole('projektvezeto'); + $recipientsUsers = array_merge($ufoUsers, $pvUsers); + $recipients = $this->getMailAddresses($recipientsUsers); + + $this->mailer->sendFaultMail( + $recipients, + sprintf("[WN] Hiba javítása elutasítva - %s", $fault->getWorksheetNumber()), + $fault, + sprintf("A hiba javítást visszaigazolta: %s", $user->getName()) + ); + } + + /** + * @param User[] $mailRecipientUsers + * @return string[] + */ + private function getMailAddresses(array $mailRecipientUsers): array + { + $usersWhoWantEmail = array_filter($mailRecipientUsers, function (User $user) { + return $user->isWantsEmail(); + }); + + $recipients = array_map(function (User $user) { + return $user->getEmail(); + }, $usersWhoWantEmail); + + return array_unique($recipients); + } +} diff --git a/src/App/Service/FaultManagerServiceFactory.php b/src/App/Service/FaultManagerServiceFactory.php new file mode 100644 index 0000000..98fa02b --- /dev/null +++ b/src/App/Service/FaultManagerServiceFactory.php @@ -0,0 +1,25 @@ +get('doctrine.entity_manager.orm_default'); + /** @var DoctrineObject $hydrator */ + $hydrator = $container->get('doctrine.hydrator'); + /** @var AuthService $authService */ + $authService = $container->get(AuthService::class); + /** @var MailerService $mailer */ + $mailer = $container->get(MailerService::class); + /** @var UserService $userService */ + $userService = $container->get(UserService::class); + return new FaultManagerService($em, $hydrator, $authService, $mailer, $userService); + } +} diff --git a/src/App/Service/FixtureLoaderService.php b/src/App/Service/FixtureLoaderService.php new file mode 100644 index 0000000..75f361d --- /dev/null +++ b/src/App/Service/FixtureLoaderService.php @@ -0,0 +1,44 @@ +em = $em; + } + + public function load(OutputInterface $output) + { + $loader = new Loader(); + $loader->addFixture(new ErrorCategoryLoader($output)); + $loader->addFixture(new ErrorOriginLoader($output)); + $loader->addFixture(new FacilityLocationLoader($output)); + $loader->addFixture(new SolutionTimeIntervalLoader($output)); + $loader->addFixture(new UserLoader($output)); + + $purger = new ORMPurger(); + $executor = new ORMExecutor($this->em, $purger); + $executor->execute($loader->getFixtures()); + + return 0; + } +} diff --git a/src/App/Service/FixtureLoaderServiceFactory.php b/src/App/Service/FixtureLoaderServiceFactory.php new file mode 100644 index 0000000..f2858e8 --- /dev/null +++ b/src/App/Service/FixtureLoaderServiceFactory.php @@ -0,0 +1,17 @@ +get('doctrine.entity_manager.orm_default'); + return new FixtureLoaderService($em); + } +} diff --git a/src/App/Service/LoggerFactory.php b/src/App/Service/LoggerFactory.php new file mode 100644 index 0000000..cdc6ff4 --- /dev/null +++ b/src/App/Service/LoggerFactory.php @@ -0,0 +1,23 @@ +get('config'); + $logger = new Logger("webnaplo"); + $logger->pushHandler(new StreamHandler('data/log/application.log')); + if ($config['debug']) { + $logger->pushHandler(new ChromePHPHandler()); + } + return $logger; + } +} diff --git a/src/App/Service/MailerService.php b/src/App/Service/MailerService.php new file mode 100644 index 0000000..83620c5 --- /dev/null +++ b/src/App/Service/MailerService.php @@ -0,0 +1,130 @@ +config = $config; + $this->transport = $transport; + $this->logger = $logger; + } + + /** + * @param $recipients + * @param string $subject + * @param string $body + * @return bool + */ + public function sendMail($recipients, string $subject, string $body): bool + { + $message = new Message(); + $message->setEncoding("UTF-8") + ->setFrom($this->config['self']['sender'], "Webnapló") + ->setTo($recipients) + ->setSubject($subject) + ->setBody($body); + try { + $this->transport->send($message); + } catch (RuntimeException $ex) { + $this->logger->error($ex->getMessage(), [ + 'recipients' => $recipients, + 'subject' => $subject, + 'body' => $body, + ]); + return false; + } + return true; + } + + public function sendFaultMail($recipients, string $subject, Fault $fault, string $body = ""): bool + { + $compiledBody = sprintf( + "%s\n\n%s\n\n\n%s", + $this->getFaultHeader($fault), + $body, + $this->getFaultFooter() + ); + return $this->sendMail($recipients, $subject, $compiledBody); + } + + /** + * @param Fault $fault + * @return string + */ + private function getFaultHeader(Fault $fault): string + { + $replacements = [ + '%%FACILITY_LOCATION%%' => $fault->getFacilityLocation()->getName(), + '%%FACILITY_LOCATION_DESCRIPTION%%' => $fault->getFacilityLocationDescription(), + '%%ERROR_CATEGORY%%' => $fault->getErrorCategory()->getName(), + '%%ERROR_ORIGIN%%' => $fault->getErrorOrigin()->getName(), + '%%ERROR_DESCRIPTION%%' => $fault->getErrorDescription(), + '%%SOLUTION_TIME%%' => $fault->getSolutionTimeInterval()->getId() == 3 + ? $fault->getSolutionTimeIntervalOther() + : $fault->getSolutionTimeInterval()->getName(), + ]; + $mailTemplate = $this->getTemplate(self::TEMPLATE_FAULT_HEADER); + return str_replace(array_keys($replacements), array_values($replacements), $mailTemplate); + } + + private function getFaultFooter(): string + { + $replacements = [ + '%%WEBNAPLO_URI%%' => $this->config['self']['site-uri'], + ]; + $mailTemplate = $this->getTemplate(self::TEMPLATE_FAULT_FOOTER); + return str_replace(array_keys($replacements), array_values($replacements), $mailTemplate); + } + + /** + * @param string $name + * @return string + */ + private function getTemplate(string $name): string + { + return file_get_contents(sprintf("data/mail-template/%s.txt", $name)); + } + + public function sendTestMessage() + { + $this->sendMail([ + "danyi.david@gmail.com" + ], "Teszt levél", "Teszt levél tartalom"); + } +} diff --git a/src/App/Service/MailerServiceFactory.php b/src/App/Service/MailerServiceFactory.php new file mode 100644 index 0000000..fb68ce4 --- /dev/null +++ b/src/App/Service/MailerServiceFactory.php @@ -0,0 +1,25 @@ +get('config'); + + /** @var Smtp|File $mailTransport */ + $mailTransport = new $config['mailer']['transportClass'](); + $transportOptions = new $config['mailer']['optionsClass']($config['mailer']['options']); + $mailTransport->setOptions($transportOptions); + /** @var Logger $logger */ + $logger = $container->get(Logger::class); + return new MailerService($mailTransport, $config, $logger); + } +} diff --git a/src/App/Service/MaintenanceManagerService.php b/src/App/Service/MaintenanceManagerService.php new file mode 100644 index 0000000..5a7da33 --- /dev/null +++ b/src/App/Service/MaintenanceManagerService.php @@ -0,0 +1,250 @@ +year = date("Y"); + $this->year = 2018; + $this->em = $em; + $this->hydrator = $hydrator; + $this->xlsxParserService = $xlsxParserService; + $this->userService = $userService; + } + + public function getMaintenanceList(): ArrayCollection + { + return $this->getUpdatedXlsxData(); + } + + public function getUpcomingMaintenanceList(): ArrayCollection + { + $firstDayOfThisWeek = new \DateTime("@" . strtotime(sprintf("-%s days", date("N") - 0))); + $firstDayOfThisWeek + ->setTimezone(new \DateTimeZone(date_default_timezone_get())) + ->setTime(0, 0); + $twoWeeksFromNow = (clone $firstDayOfThisWeek)->add(\DateInterval::createFromDateString("+14 days")); + + $deviceGroups = $this->getUpdatedXlsxData(); + + foreach ($deviceGroups as $deviceGroup) { + /** @var DeviceGroup $deviceGroup */ + foreach ($deviceGroup->getDevices() as $device) { + $tasks = $device->getTasks()->filter(function (DeviceMaintenanceTask $task) use ( + $firstDayOfThisWeek, + $twoWeeksFromNow + ) { + return $task->getShouldStartAt() >= $firstDayOfThisWeek + && $task->getShouldStartAt() < $twoWeeksFromNow; + }); + $device->setTasks($tasks); + } + + $devices = $deviceGroup->getDevices()->filter(function (Device $device) { + return count($device->getTasks()); + }); + $deviceGroup->setDevices($devices); + } + + return $deviceGroups->filter(function (DeviceGroup $deviceGroup) { + return count($deviceGroup->getDevices()); + }); + } + + /** + * @return DeviceGroup[]|ArrayCollection + */ + private function getUpdatedXlsxData() + { + /** @var DeviceGroup[] $loadedCacheData */ + $loadedCacheData = $this->xlsxParserService->getXlsxData(); + + /** @var Maintenance[] $dbMaintenances */ + $dbMaintenances = $this->getMaintenancesInYear($this->year); + foreach ($dbMaintenances as $maintenance) { + foreach ($loadedCacheData as &$deviceGroup) { + foreach ($deviceGroup->getDevices() as &$device) { + foreach ($device->getTasks() as &$task) { + if ($task->getHash() == $maintenance->getHash()) { + $task->setState($maintenance->getState()); + } + } + } + } + } + return $loadedCacheData; + } + + public function getMaintenancesInYear($year): array + { + $qb = $this->em->createQueryBuilder(); + return $qb->select('m') + ->from(Maintenance::class, 'm') + ->where('m.year = :thisYear') + ->setParameter('thisYear', $year) + ->orderBy('m.month') + ->addOrderBy('m.week') + ->getQuery() + ->execute(); + } + + /** + * @param string $hash + * @return Maintenance + * @throws \Doctrine\ORM\ORMException + * @throws \Doctrine\ORM\OptimisticLockException + * @throws \Doctrine\ORM\TransactionRequiredException + */ + public function get(string $hash): Maintenance + { + /** @var Maintenance $maintenance */ + if (null == ($maintenance = $this->em->find(Maintenance::class, $hash))) { + $maintenance = $this->initMaintenanceInDatabase($hash); + } + return $maintenance; + } + + /** + * @param string $hash + * @param $data + * @param int $uid + * @return Maintenance + * @throws \Doctrine\ORM\ORMException + * @throws \Doctrine\ORM\OptimisticLockException + * @throws \Doctrine\ORM\TransactionRequiredException + */ + public function update(string $hash, $data, int $uid): Maintenance + { + $maintenance = $this->get($hash); + /** @var Maintenance $maintenance */ + $maintenance = $this->hydrator->hydrate($data, $maintenance); + if (null == $maintenance->getStartedBy()) { + $maintenance->setStartedBy($this->userService->get($uid)); + } + if (null == $maintenance->getFinishedBy() && $data['state'] == 'fin') { + $maintenance->setFinishedBy($this->userService->get($uid)); + } + if (null == $maintenance->getWorksheetNumber() && null != $maintenance->getShouldStartAt()) { + $maintenance->setWorksheetNumber($this->generateWorksheetId($maintenance->getShouldStartAt()->format("Y"))); + } + $this->em->flush(); + return $maintenance; + } + + /** + * @param string $id + * @param string $state + * @param int $uid + * @return Maintenance + * @throws \Doctrine\ORM\ORMException + * @throws \Doctrine\ORM\OptimisticLockException + * @throws \Doctrine\ORM\TransactionRequiredException + * @deprecated + */ + public function setStatus(string $id, string $state, int $uid): Maintenance + { + $user = $this->userService->get($uid); + $maintenance = $this->get($id); + $maintenance->setState($state); + switch ($state) { + case "wip": + $maintenance->setWorkStarted(new \DateTime()) + ->setWorksheetNumber($this->generateWorksheetId($maintenance->getShouldStartAt()->format("Y"))) + ->setStartedBy($user); + break; + case "fin": + $maintenance->setWorkFinished(new \DateTime()) + ->setFinishedBy($user); + break; + } + $this->em->flush(); + return $maintenance; + } + + /** + * @param string $id + * @return Maintenance + * @throws \Doctrine\ORM\OptimisticLockException + */ + private function initMaintenanceInDatabase(string $id): Maintenance + { + $taskFound = null; + $loadedCacheData = $this->getUpdatedXlsxData(); + foreach ($loadedCacheData as $deviceGroup) { + foreach ($deviceGroup->getDevices() as $device) { + foreach ($device->getTasks() as $task) { + if ($task->getHash() == $id) { + $taskFound = $task; + break 3; + } + } + } + } + + $maintenance = new Maintenance(); + $maintenance->setHash($id) + ->setDeviceName($taskFound->getDevice()->getGroup()->getName()) + ->setComponentName($taskFound->getDevice()->getName()) + ->setResponsible($taskFound->getDevice()->getResponsible()) + ->setCount($taskFound->getDevice()->getCount()) + ->setWorkDescription($taskFound->getDevice()->getWorkDescription()) + ->setYear($this->year) + ->setMonth($taskFound->getMonth()) + ->setWeek($taskFound->getWeek()) + ->setWorkerCount($taskFound->getWorkerCount()) + ->setTimeCost($taskFound->getTimeCost()) + ->setShouldStartAt($taskFound->getShouldStartAt()) + ->setShouldBeDoneBy($taskFound->getShouldBeDoneBy()); + $this->em->persist($maintenance); + $this->em->flush(); + return $maintenance; + } + + /** + * @return string + */ + private function generateWorksheetId($year): string + { + $yearsFaultCount = $this->em->createQueryBuilder() + ->select('count(f.hash)') + ->from(Maintenance::class, 'f') + ->where('YEAR(f.shouldStartAt) = :thisYear') +// ->andWhere('f.shouldStartAt IS NOT null') + ->andWhere('f.worksheetNumber IS NOT null') + ->setParameter('thisYear', $year) + ->getQuery() + ->setHydrationMode(Query::HYDRATE_SINGLE_SCALAR) + ->execute(); + return sprintf("%s/%s", $this->year, $yearsFaultCount+1); + } +} diff --git a/src/App/Service/MaintenanceManagerServiceFactory.php b/src/App/Service/MaintenanceManagerServiceFactory.php new file mode 100644 index 0000000..1d72066 --- /dev/null +++ b/src/App/Service/MaintenanceManagerServiceFactory.php @@ -0,0 +1,29 @@ +get('doctrine.entity_manager.orm_default'); + /** @var DoctrineObject $hydrator */ + $hydrator = $container->get('doctrine.hydrator'); + /** @var XlsxParserService $xlsxParserService */ + $xlsxParserService = $container->get(XlsxParserService::class); + /** @var UserService $userService */ + $userService = $container->get(UserService::class); + return new MaintenanceManagerService($em, $hydrator, $xlsxParserService, $userService); + } +} diff --git a/src/App/Service/PdfService.php b/src/App/Service/PdfService.php new file mode 100644 index 0000000..95aebe6 --- /dev/null +++ b/src/App/Service/PdfService.php @@ -0,0 +1,405 @@ +em = $em; + $this->faultManager = $faultManager; + $this->config = $config; + } + + /** + * @param int $id + * @return string + * @throws \PHPPdf\Core\PHPPdf\Exception\Exception + */ + public function getWorksheet(int $id): string + { + /** @var Fault $faultEntity */ + $faultEntity = $this->em->getRepository(Fault::class)->find($id); + + $pdfTemplate = $this->fillWorksheetTemplate(file_get_contents(self::WORKSHEET_TEMPLATE_FILE), $faultEntity); + $styleData = file_get_contents(self::WORKSHEET_STYLESHEET_FILE); + + $loader = new LoaderImpl(); + $loader->setFontFile("data/pdf-resources/config/font-config.xml"); + + $builder = FacadeBuilder::create($loader) + ->setCache('File', ['cache_dir' => 'data/cache']) + ->setEngineType('pdf'); + $pdfRenderer = $builder->build(); + + $oldErrorLevel = error_reporting(); + error_reporting($oldErrorLevel & ~E_NOTICE); + $rendered = $pdfRenderer->render($pdfTemplate, $styleData); + error_reporting($oldErrorLevel); + return $rendered; + } + + /** + * @param string $id + * @return string + * @throws \PHPPdf\Core\PHPPdf\Exception\Exception + */ + public function getMaintenanceSheet(string $id): string + { + /** @var Maintenance $maintenance */ + $maintenance = $this->em->getRepository(Maintenance::class)->find($id); + + $pdfTemplate = $this->fillMaintenanceSheetTemplate( + file_get_contents(self::MAINTENANCESHEET_TEMPLATE_FILE), + $maintenance + ); + $styleData = file_get_contents(self::MAINTENANCESHEET_STYLESHEET_FILE); + + $loader = new LoaderImpl(); + $loader->setFontFile("data/pdf-resources/config/font-config.xml"); + + $builder = FacadeBuilder::create($loader) + ->setCache('File', ['cache_dir' => 'data/cache']) + ->setEngineType('pdf'); + $pdfRenderer = $builder->build(); + + $oldErrorLevel = error_reporting(); + error_reporting($oldErrorLevel & ~E_NOTICE); + $rendered = $pdfRenderer->render($pdfTemplate, $styleData); + error_reporting($oldErrorLevel); + return $rendered; + } + + /** + * @param string $template + * @param Fault $fault + * @return string + */ + private function fillWorksheetTemplate(string $template, Fault $fault): string + { + $formatString = "Y.m.d H:i"; + $replacementMatches = [ + '%%WS_ID%%' => $fault->getWorksheetNumber(), + + '%%REPORTED_AT%%' => $fault->getCreatedAt()->format($formatString), + '%%FINISHED_AT%%' => $fault->getWorkFinished() + ? $fault->getWorkFinished()->format($formatString) + : '', + '%%APPROVED_AT%%' => $fault->getApprovedAt() + ? $fault->getApprovedAt()->format($formatString) + : '', + '%%CONFIRMED_AT%%' => $fault->getConfirmedAt() + ? $fault->getConfirmedAt()->format($formatString) + : '', + '%%ACKNOWLEDGED_AT%%' => $fault->getAcknowledgedAt() + ? $fault->getAcknowledgedAt()->format($formatString) + : '', + + '%%FAULT_DECISION%%' => $fault->isMustLowerCost() + ? 'költség csökkentés szükséges' + : 'elfogadva', + '%%ALLOCATED_EXPENSE%%' => $fault->getAllocatedExpense() ?? '', + /** + * @todo calculate real repair cost here when possible + */ + '%%REPAIR_COST%%' => $fault->getWorkCostEstimate() + $fault->getMaterialCostEstimate(), + + '%%TIMESPENT_HOUR%%' => '', + '%%TIMESPENT_DAY%%' => '', + '%%FAULT_DURATION%%' => '', + '%%LATE_FINE_PERCENT%%' => '', + +// '%%APPROVE_YEAR%%' => $appYear, +// '%%APPROVE_MONTH%%' => $appMonth, +// '%%APPROVE_DAY%%' => $appDay, +// '%%APPROVE_HOUR%%' => $appHour, +// '%%APPROVE_MINUTE%%' => $appMinute, + + '%%SELF_NAME%%' => $this->config['self']['name'], + '%%SELF_ADDRESS%%' => $this->config['self']['address'], + '%%SELF_TAXNUMBER%%' => $this->config['self']['tax_number'], + // owner +// '%%OWNER_SHORT%%' => $this->config['client']['short'], + '%%OWNER_NAME%%' => $this->config['client']['name'], + '%%OWNER_ADDRESS%%' => $this->config['client']['address'], + '%%OWNER_TAXNUMBER%%' => $this->config['client']['tax_number'], + // creator + '%%CREATOR_NAME%%' => $fault->getReporter()->getName(), + '%%CREATOR_JOB%%' => $fault->getReporter()->getJob(), +// '%%CREATOR_EMAIL%%' => $fault->getReporter()->getEmail(), +// '%%CREATOR_PHONE%%' => $fault->getReporter()->getPhone(), + // confirmer + '%%CONFIRMER_NAME%%' => $fault->getConfirmer()->getName(), + '%%CONFIRMER_JOB%%' => $fault->getConfirmer()->getJob(), + // worker + '%%WORKER_NAME%%' => $fault->getConfirmer()->getName(), + '%%WORKER_JOB%%' => $fault->getConfirmer()->getJob(), + // cost approver + '%%APPROVER_NAME%%' => $fault->getApprovedBy() ? $fault->getApprovedBy()->getName() : '', + '%%APPROVER_JOB%%' => $fault->getApprovedBy() ? $fault->getApprovedBy()->getJob() : '', + // repair acknowledged by + '%%ACKNOWLEDGEDBY_NAME%%' => $fault->getAcknowledgedBy() ? $fault->getAcknowledgedBy()->getName() : '', + '%%ACKNOWLEDGEDBY_JOB%%' => $fault->getAcknowledgedBy()? $fault->getAcknowledgedBy()->getJob() : '', + // fault + '%%FAULT_LOCATION_ROOMNUMBER%%' => $fault->getFacilityLocation()->getRoomNumber(), + '%%FAULT_LOCATION_NAME%%' => $fault->getFacilityLocation()->getName(), + '%%FAULT_LOCATION_SIZE%%' => $fault->getFacilityLocation()->getSize(), + '%%FAULT_LOCATION_DESC%%' => $fault->getFacilityLocationDescription(), + '%%FAULT_COST_TYPE%%' => + ($fault->getWorkCostEstimate() > 100000 || $fault->getMaterialCostEstimate() > 200000) + ? 'NM' + : 'KM', + '%%FAULT_ERROR_CATEGORY_TYPE%%' => $fault->getErrorCategory()->getMappedType(), + '%%FAULT_CODE%%' => $fault->getSolutionTimeInterval()->getCode(), + '%%FAULT_ERROR_CATEGORY_ID%%' => $fault->getErrorCategory()->getId(), + '%%FAULT_ERROR_CATEGORY_NAME%%' => $fault->getErrorCategory()->getName(), + '%%FAULT_ERROR_DESC%%' => $fault->getErrorDescription(), + '%%FAULT_ERROR_ORIGIN%%' => $fault->getErrorOrigin()->getName(), + '%%FAULT_ERROR_URGENCY%%' => $fault->getSolutionTimeInterval()->getName(), + ]; + return str_replace(array_keys($replacementMatches), array_values($replacementMatches), $template); + } + + private function fillMaintenanceSheetTemplate(string $template, Maintenance $maintenance): string + { + $formatString = "Y.m.d H:i"; + $replacementMatches = [ + '%%SELF_NAME%%' => $this->config['self']['name'], + '%%SELF_ADDRESS%%' => $this->config['self']['address'], + '%%SELF_TAXNUMBER%%' => $this->config['self']['tax_number'], + '%%OWNER_NAME%%' => $this->config['client']['name'], + '%%OWNER_ADDRESS%%' => $this->config['client']['address'], + '%%OWNER_TAXNUMBER%%' => $this->config['client']['tax_number'], + + '%%MS_ID%%' => $maintenance->getWorksheetNumber(), + '%%MAINTENANCE_GROUP%%' => $maintenance->getDeviceName(), + '%%MAINTENANCE_DEVICE%%' => $maintenance->getComponentName(), + '%%WORK_DESCRIPTION%%' => $maintenance->getWorkDescription(), + +// '%%CONFIRMER_NAME%%' => $maintenance->getStartedBy()->getName(), +// '%%CONFIRMER_JOB%%' => $maintenance->getStartedBy()->getJob(), + '%%MAINTENER_NAME%%' => $maintenance->getResponsible(), + '%%MAINTENER_JOB%%' => '', + + '%%SHOULD_START_AT%%' => $maintenance->getShouldStartAt()->format($formatString), + '%%SHOULDBE_DONE_BY%%' => $maintenance->getShouldBeDoneBy()->format($formatString), + + '%%STARTED_AT%%' => '', +// '%%STARTED_AT%%' => $maintenance->getWorkStarted() +// ? $maintenance->getWorkStarted()->format($formatString) : '', + '%%FINISHED_AT%%' => $maintenance->getWorkFinished() + ? $maintenance->getWorkStarted()->format($formatString) : '', + + '%%TIMESPENT_HOUR%%' => '', + '%%TIMESPENT_DAY%%' => '', + +// '%%FINISHEDBY_NAME%%' => $maintenance->getFinishedBy() +// ? $maintenance->getFinishedBy()->getName() : '', +// '%%FINISHEDBY_JOB%%' => $maintenance->getFinishedBy() +// ? $maintenance->getFinishedBy()->getJob() : '', + '%%ACKNOWLEDGED_AT%%' => $maintenance->getWorkFinished() + ? $maintenance->getWorkStarted()->format($formatString) : '', + ]; + return str_replace(array_keys($replacementMatches), array_values($replacementMatches), $template); + } + +// /** +// * @param int $year +// * @param int $month +// * @return string +// */ +// public function getMonthlyReport($year, $month): string +// { +// $data = $this->getMonthlyReportData($year, $month); +// $compiledData = $this->compileTableData($data); +// setlocale(LC_TIME, "hu_HU.UTF-8"); +// $compiledData['reportDatePeriod'] = strftime("%Y. %B", strtotime("${year}-${month}")); +// +// $pdfTemplate = $this->fillMonthlyReportTemplate( +// file_get_contents(self::MONTHLY_REPORT_TEMPLATE_FILE), +// $compiledData +// ); +// $styleData = file_get_contents(self::MONTHLY_REPORT_STYLESHEET_FILE); +// +// $loader = new LoaderImpl(); +// $loader->setFontFile("data/pdf-resources/config/font-config.xml"); +// +// $builder = FacadeBuilder::create($loader) +// ->setCache('File', ['cache_dir' => 'data/cache']) +// ->setEngineType('pdf'); +// $pdfRenderer = $builder->build(); +// +// return $pdfRenderer->render($pdfTemplate, $styleData); +// } + +// /** +// * @param string $template +// * @param array $data +// * @return string +// */ +// private function fillMonthlyReportTemplate(string $template, array $data): string +// { +// $replacementMatches = [ +// '%%REPORT_DATE_PERIOD%%' => $data['reportDatePeriod'], +// '%%REPORT_DATE_PRINTED%%' => date("Y-m-d"), +// +// '%%TABLE_DATA%%' => $data['itemTemplate'], +// +// '%%SUM_MATERIAL_COST%%' => $data['sumMaterialCost'], +// '%%SUM_WORK_COST%%' => $data['sumWorkCost'], +// '%%LATE_PENALTY_COST%%' => $data['lateFine'], +// '%%SUM_NETT_COST%%' => $data['sumNettCost'], +// '%%VAT_COST%%' => $data['vat'], +// '%%BRUT_COST%%' => $data['sumTotalCost'], +// ]; +// return str_replace(array_keys($replacementMatches), array_values($replacementMatches), $template); +// } + +// /** +// * @param $data +// * @return array compiled data +// * @todo late fine calculation +// */ +// private function compileTableData($data) +// { +// /** @var FaultService $faultService */ +// $faultService = $this->container->get(FaultService::class); +// +// $sumMaterialCost = 0; +// $sumWorkCost = 0; +// $sumLateFine = 0; +// $itemTemplate = ''; +// +// $instituteTpl = file_get_contents(self::MONTHLY_REPORT_INSTITUTE_TPL); +// $faultTpl = file_get_contents(self::MONTHLY_REPORT_FAULT_TPL); +// $faultCostItemTpl = file_get_contents(self::MONTHLY_REPORT_FAULT_COST_ITEM_TPL); +// $faultCostWorkTpl = file_get_contents(self::MONTHLY_REPORT_FAULT_COST_WORK_TPL); +// $faultCostLateTpl = file_get_contents(self::MONTHLY_REPORT_FAULT_COST_LATE_TPL); +// +// /** @var Institute $institute */ +// foreach ($data as $institute) { +// $itemTemplate .= sprintf( +// $instituteTpl, +// $institute->getId(), +// $institute->getName(), +// $institute->getAddress() +// ); +// +// foreach ($institute->getFaults() as $fault) { +// $itemTemplate .= sprintf( +// $faultTpl, +// $fault->getWorksheetNumber(), +// $fault->getErrorCategory()->getName(), +// $fault->getFacilityLocation()->getName() +// ); +// +// foreach ($fault->getUsedMaterials() as $material) { +// $itemTemplate .= sprintf( +// $faultCostItemTpl, +// $material['name'], +// $material['unit'], +// $material['amount'], +// $material['nettPrice'], +// $material['amount'] * $material['nettPrice'] +// ); +// } +// +// $sumMaterialCost += $faultService->calculateMaterialCost($fault); +// $workCost = $faultService->calculateWorkCost($fault); +// $sumWorkCost += $workCost; +// $workHours = $faultService->calculateWorkHours($fault); +// +// $lateFine = $faultService->calculateLateFine($fault); +// $sumLateFine += $lateFine->sum(); +// +// $itemTemplate .= sprintf($faultCostWorkTpl, $workHours, $workCost); +// foreach ($lateFine->getItems() as $item) { +// $itemTemplate .= sprintf( +// $faultCostLateTpl, +// $item->getUnit(), +// $item->getCount(), +// -$item->getAmount(), +// -$item->sum() +// ); +// } +// } +// } +// +// $sumNettCost = $sumWorkCost + $sumMaterialCost - $sumLateFine; +// return [ +// 'itemTemplate' => $itemTemplate, +// 'sumMaterialCost' => $sumMaterialCost, +// 'sumWorkCost' => $sumWorkCost, +// 'lateFine' => $sumLateFine, +// 'sumNettCost' => $sumNettCost, +// 'vat' => floor($sumNettCost * 0.27), +// 'sumTotalCost' => floor($sumNettCost * 1.27), +// ]; +// } + +// /** +// * @param int $year +// * @param int $month +// * @return array +// */ +// private function getMonthlyReportData($year, $month) +// { +// $qb = $this->em->createQueryBuilder(); +// +// $entities = $qb->select('i', 'f', 'fl', 'ec') +// ->from(Institute::class, 'i') +// ->innerJoin('i.faults', 'f') +// ->innerJoin('f.facilityLocation', 'fl') +// ->innerJoin('f.errorCategory', 'ec') +// ->where('YEAR(f.workFinished) = :year') +// ->andWhere('MONTH(f.workFinished) = :month') +// ->orderBy('i.id') +// ->setParameter('year', $year) +// ->setParameter('month', $month) +// ->getQuery() +// ->getResult(Query::HYDRATE_OBJECT); +// +// return $entities; +// } +} diff --git a/src/App/Service/PdfServiceFactory.php b/src/App/Service/PdfServiceFactory.php new file mode 100644 index 0000000..017f318 --- /dev/null +++ b/src/App/Service/PdfServiceFactory.php @@ -0,0 +1,20 @@ +get('doctrine.entity_manager.orm_default'); + /** @var FaultManagerService $faultManager */ + $faultManager = $container->get(FaultManagerService::class); + $config = $container->get('config'); + return new PdfService($em, $faultManager, $config); + } +} diff --git a/src/App/Service/RbaclFactory.php b/src/App/Service/RbaclFactory.php new file mode 100644 index 0000000..0d2b534 --- /dev/null +++ b/src/App/Service/RbaclFactory.php @@ -0,0 +1,36 @@ +get('config')['acl_config']); + $routeGuard = $config->get('route_guard', $emptyCfg); + + $rbac = new Rbac(); + $rbac->setCreateMissingRoles(true); + // roles + $roles = $routeGuard->get('roles', $emptyCfg)->toArray(); + foreach ($roles as $roleName => $parents) { + $rbac->addRole($roleName, $parents); + } + + // permissions + $permissionCfg = $routeGuard->get('permissions', $emptyCfg)->toArray(); + foreach ($permissionCfg as $role => $permissions) { + foreach ($permissions as $permission) { + $rbac->getRole($role)->addPermission($permission); + } + } + + return $rbac; + } +} diff --git a/src/App/Service/SolutionTimeIntervalService.php b/src/App/Service/SolutionTimeIntervalService.php new file mode 100644 index 0000000..6bfc45c --- /dev/null +++ b/src/App/Service/SolutionTimeIntervalService.php @@ -0,0 +1,32 @@ +em = $em; + } + + /** + * Return FacilityLocations in a tree form + * + * @return array + */ + public function getList() + { + /** @var EntityRepository $treeRepository */ + $repository = $this->em->getRepository(SolutionTimeInterval::class); + return $repository->findAll(); + } +} diff --git a/src/App/Service/SolutionTimeIntervalServiceFactory.php b/src/App/Service/SolutionTimeIntervalServiceFactory.php new file mode 100644 index 0000000..e58c5b8 --- /dev/null +++ b/src/App/Service/SolutionTimeIntervalServiceFactory.php @@ -0,0 +1,16 @@ +get('doctrine.entity_manager.orm_default'); + return new SolutionTimeIntervalService($em); + } +} diff --git a/src/App/Service/UserService.php b/src/App/Service/UserService.php new file mode 100644 index 0000000..14a59c0 --- /dev/null +++ b/src/App/Service/UserService.php @@ -0,0 +1,102 @@ +em = $em; + $this->hydrator = $hydrator; + } + + /** + * Return FacilityLocations in a tree form + * + * @return array + */ + public function getList() + { + /** @var EntityRepository $treeRepository */ + $repository = $this->em->getRepository(User::class); + return $repository->findAll(); + } + + /** + * @param int $id + * @return User + */ + public function get(int $id): User + { + /** @var User $user */ + $user = $this->em->find(User::class, $id); + return $user; + } + + /** + * @param int $id + * @param $data + * @return User + */ + public function update(int $id, $data): User + { + /** @var User $user */ + $user = $this->hydrator->hydrate($data, $this->get($id)); + $this->em->persist($user); + $this->em->flush(); + return $user; + } + + /** + * @param int $id + * @param string $old + * @param string $new + * @return User + * @throws \Exception + */ + public function changePassword(int $id, string $old, string $new): User + { + $user = $this->get($id); + + $crypt = new Bcrypt(); + $crypt->setCost(AuthService::PASSWORD_COST); + + if (!$crypt->verify($old, $user->getPassword())) { + throw new \Exception("Old password doesn't match", 401); + } + + $user->setPassword($crypt->create($new)); + $this->em->flush(); + return $user; + } + + /** + * @param string $role + * @return User[]|null + */ + public function getAllUsersOfRole(string $role): ?array + { + $activeUsers = $this->em->getRepository(User::class)->findBy([ + 'active' => true, + ]); + return array_filter($activeUsers, function (User $user) use ($role) { + return in_array($role, $user->getRoles()); + }); + } +} diff --git a/src/App/Service/UserServiceFactory.php b/src/App/Service/UserServiceFactory.php new file mode 100644 index 0000000..80e0f81 --- /dev/null +++ b/src/App/Service/UserServiceFactory.php @@ -0,0 +1,19 @@ +get('doctrine.entity_manager.orm_default'); + /** @var DoctrineObject $hydrator */ + $hydrator = $container->get('doctrine.hydrator'); + return new UserService($em, $hydrator); + } +} diff --git a/src/App/Service/XlsxParserService.php b/src/App/Service/XlsxParserService.php new file mode 100644 index 0000000..d75108b --- /dev/null +++ b/src/App/Service/XlsxParserService.php @@ -0,0 +1,226 @@ +deviceGroups = new ArrayCollection(); +// $this->year = date("Y"); + $this->year = 2018; + } + + /** + * @param DeviceGroup $device + * @return XlsxParserService + */ + public function addDeviceGroup(DeviceGroup $device): XlsxParserService + { + if (!$this->deviceGroups->contains($device)) { + $this->deviceGroups->add($device); + } + return $this; + } + + /** + * @param DeviceGroup $deviceGroup + * @return XlsxParserService + */ + public function removeDevice(DeviceGroup $deviceGroup): XlsxParserService + { + if ($this->deviceGroups->contains($deviceGroup)) { + $this->deviceGroups->removeElement($deviceGroup); + } + return $this; + } + + /** + * @return ArrayCollection|Maintenance[] + */ + public function getXlsxData(): ArrayCollection + { + if (!file_exists($this->getXlsxFileName())) { + return new ArrayCollection(); + } + + if (!file_exists($this->getTimestampFileName()) || + !file_exists($this->getCacheFileName()) || + file_get_contents($this->getTimestampFileName()) < filemtime($this->getXlsxFileName()) + ) { + $this->rebuildCache(); + } + + /** @var ArrayCollection|DeviceGroup[] $loadedCacheData */ + $loadedCacheData = unserialize(file_get_contents($this->getCacheFileName())); + return $loadedCacheData; + } + + private function rebuildCache() + { + $mtime = filemtime($this->getXlsxFileName()); + $parsedXlsxData = $this->parseXlsx(); + file_put_contents($this->getCacheFileName(), serialize($parsedXlsxData)); + file_put_contents($this->getTimestampFileName(), $mtime); + } + + /** + * @return ArrayCollection + * @throws \PHPExcel_Exception + * @throws \PHPExcel_Reader_Exception + */ + public function parseXlsx(): ArrayCollection + { + $objPHPExcel = \PHPExcel_IOFactory::load($this->getXlsxFileName()); + $sheet = $objPHPExcel->getSheetByName(self::XLSX_SHEET_NAME); + + $totalRows = $sheet->getHighestRow(); + $monthColumns = $this->year == 2017 + ? range(43, 58) + : range(11, 58); + $rowCursor = 7; + + $group = null; + while ($rowCursor < $totalRows) { + /** + * step over empty rows + */ + $firstCell = $sheet->getCell("A{$rowCursor}"); + if (!$firstCell->isMergeRangeValueCell() + && $firstCell->getValue() == "" + ) { + $rowCursor += 1; + continue; + } + + /** + * start of new group block + */ + if ($firstCell->getMergeRange() == "A{$rowCursor}:K{$rowCursor}") { + $group = new DeviceGroup(); + $group->setName($firstCell->getValue()); + $this->addDeviceGroup($group); + $rowCursor += 1; + continue; + } + + /** + * start of new device + */ + if ($sheet->getCell("A{$rowCursor}")->isMergeRangeValueCell()) { + $device = new Device($group); + $device->setName($this->compressWhitespace( + $sheet->getCellByColumnAndRow(0, $rowCursor)->getValue() ?? "" + )) + ->setResponsible($sheet->getCellByColumnAndRow(1, $rowCursor)->getValue() ?? "") + ->setCount(intval($sheet->getCellByColumnAndRow(2, $rowCursor)->getValue())) + ->setWorkDescription($sheet->getCellByColumnAndRow(3, $rowCursor)->getValue() ?? ""); + $group->addDevice($device); + $mergeRange = $sheet->getCell("A{$rowCursor}")->getMergeRange(); + sscanf($mergeRange, "A{$rowCursor}:A%d", $endRow); + foreach ($monthColumns as $column) { + $weekDataCell = $sheet->getCellByColumnAndRow($column, $rowCursor); + if ($weekDataCell->getValue() != "") { + $month = floor(($column - 11) / 4 + 1); + $firstDayOfFirstWeek = $this->getFirstWeekOfMonth($month); + $week = ($column - 11) % 4 + 1; + + $task = new DeviceMaintenanceTask($device); + $task->setYear($this->year) + ->setMonth($month) + ->setWeek($week) + ->setShouldStartAt($firstDayOfFirstWeek->add( + \DateInterval::createFromDateString(sprintf("%s weeks", $week - 1)) + )) + ->setShouldBeDoneBy((clone $firstDayOfFirstWeek)->add( + \DateInterval::createFromDateString("1 week") + )) + ->setWorkerCount(intval($weekDataCell->getCalculatedValue())) + ->setTimeCost(floatval( + $sheet->getCellByColumnAndRow($column, $rowCursor + 1)->getCalculatedValue() + )); + $device->addTask($task); + } + } + $rowCursor += $endRow - $rowCursor; + } + $rowCursor += 1; + } + return $this->deviceGroups; + } + + /** + * @param string $input + * @return string + */ + private function compressWhitespace(string $input): string + { + return preg_replace("#[\s]+#msiu", " ", $input); + } + + /** + * @param int $month + * @return \DateTime + */ + private function getFirstWeekOfMonth(int $month): \DateTime + { + $firstDayOfMonth = mktime(0, 0, 0, $month, 1, $this->year); + $weekDayOfFirst = date("N", $firstDayOfMonth); + + if ($weekDayOfFirst == 2) { + return (new \DateTime("@".strtotime("-1 day", $firstDayOfMonth))) + ->setTimezone(new \DateTimeZone(date_default_timezone_get())); + } + + $firstWeekMonday = 1; + if ($weekDayOfFirst > 2) { + $firstWeekMonday = 8 - ($weekDayOfFirst - 1); + } + + return new \DateTime(sprintf( + "%s-%s-%s", + $this->year, + $month, + $firstWeekMonday + )); + } + + private function getCacheFileName(): string + { + return sprintf(self::XLSX_CACHE_FILE, $this->year); + } + + private function getTimestampFileName(): string + { + return sprintf(self::XLSX_TIMESTAMP, $this->year); + } + + private function getXlsxFileName(): string + { + return sprintf(self::XLSX_FILE_NAME, $this->year); + } +} diff --git a/src/App/Service/XlsxParserServiceFactory.php b/src/App/Service/XlsxParserServiceFactory.php new file mode 100644 index 0000000..0bdce4d --- /dev/null +++ b/src/App/Service/XlsxParserServiceFactory.php @@ -0,0 +1,13 @@ +router = $this->prophesize(RouterInterface::class); + } + + public function testReturnsJsonResponseWhenNoTemplateRendererProvided() + { + $homePage = new HomePageAction($this->router->reveal(), null); + $response = $homePage->process( + $this->prophesize(ServerRequestInterface::class)->reveal(), + $this->prophesize(DelegateInterface::class)->reveal() + ); + + $this->assertInstanceOf(JsonResponse::class, $response); + } + + public function testReturnsHtmlResponseWhenTemplateRendererProvided() + { + $renderer = $this->prophesize(TemplateRendererInterface::class); + $renderer + ->render('app::home-page', Argument::type('array')) + ->willReturn(''); + + $homePage = new HomePageAction($this->router->reveal(), $renderer->reveal()); + + $response = $homePage->process( + $this->prophesize(ServerRequestInterface::class)->reveal(), + $this->prophesize(DelegateInterface::class)->reveal() + ); + + $this->assertInstanceOf(HtmlResponse::class, $response); + } +} diff --git a/test/AppTest/Action/HomePageFactoryTest.php b/test/AppTest/Action/HomePageFactoryTest.php new file mode 100644 index 0000000..627a20c --- /dev/null +++ b/test/AppTest/Action/HomePageFactoryTest.php @@ -0,0 +1,51 @@ +container = $this->prophesize(ContainerInterface::class); + $router = $this->prophesize(RouterInterface::class); + + $this->container->get(RouterInterface::class)->willReturn($router); + } + + public function testFactoryWithoutTemplate() + { + $factory = new HomePageFactory(); + $this->container->has(TemplateRendererInterface::class)->willReturn(false); + + $this->assertInstanceOf(HomePageFactory::class, $factory); + + $homePage = $factory($this->container->reveal()); + + $this->assertInstanceOf(HomePageAction::class, $homePage); + } + + public function testFactoryWithTemplate() + { + $factory = new HomePageFactory(); + $this->container->has(TemplateRendererInterface::class)->willReturn(true); + $this->container + ->get(TemplateRendererInterface::class) + ->willReturn($this->prophesize(TemplateRendererInterface::class)); + + $this->assertInstanceOf(HomePageFactory::class, $factory); + + $homePage = $factory($this->container->reveal()); + + $this->assertInstanceOf(HomePageAction::class, $homePage); + } +} diff --git a/test/AppTest/Action/PingActionTest.php b/test/AppTest/Action/PingActionTest.php new file mode 100644 index 0000000..71a22fb --- /dev/null +++ b/test/AppTest/Action/PingActionTest.php @@ -0,0 +1,26 @@ +process( + $this->prophesize(ServerRequestInterface::class)->reveal(), + $this->prophesize(DelegateInterface::class)->reveal() + ); + + $json = json_decode((string) $response->getBody()); + + $this->assertInstanceOf(JsonResponse::class, $response); + $this->assertTrue(isset($json->ack)); + } +}