diff --git a/.phan/config.php b/.phan/config.php new file mode 100644 index 0000000..0c22da6 --- /dev/null +++ b/.phan/config.php @@ -0,0 +1,293 @@ + '7.1', + + // If enabled, missing properties will be created when + // they are first seen. If false, we'll report an + // error message if there is an attempt to write + // to a class property that wasn't explicitly + // defined. + 'allow_missing_properties' => false, + + // If enabled, null can be cast as any type and any + // type can be cast to null. Setting this to true + // will cut down on false positives. + 'null_casts_as_any_type' => false, + + // If enabled, allow null to be cast as any array-like type. + // This is an incremental step in migrating away from null_casts_as_any_type. + // If null_casts_as_any_type is true, this has no effect. + 'null_casts_as_array' => true, + + // If enabled, allow any array-like type to be cast to null. + // This is an incremental step in migrating away from null_casts_as_any_type. + // If null_casts_as_any_type is true, this has no effect. + 'array_casts_as_null' => true, + + // If enabled, scalars (int, float, bool, string, null) + // are treated as if they can cast to each other. + // This does not affect checks of array keys. See scalar_array_key_cast. + 'scalar_implicit_cast' => false, + + // If enabled, any scalar array keys (int, string) + // are treated as if they can cast to each other. + // E.g. array can cast to array and vice versa. + // Normally, a scalar type such as int could only cast to/from int and mixed. + 'scalar_array_key_cast' => true, + + // If this has entries, scalars (int, float, bool, string, null) + // are allowed to perform the casts listed. + // E.g. ['int' => ['float', 'string'], 'float' => ['int'], 'string' => ['int'], 'null' => ['string']] + // allows casting null to a string, but not vice versa. + // (subset of scalar_implicit_cast) + 'scalar_implicit_partial' => [], + + // If true, seemingly undeclared variables in the global + // scope will be ignored. This is useful for projects + // with complicated cross-file globals that you have no + // hope of fixing. + 'ignore_undeclared_variables_in_global_scope' => true, + + // Set this to false to emit PhanUndeclaredFunction issues for internal functions that Phan has signatures for, + // but aren't available in the codebase, or the internal functions used to run phan + // (may lead to false positives if an extension isn't loaded) + // If this is true(default), then Phan will not warn. + 'ignore_undeclared_functions_with_known_signatures' => true, + + // Backwards Compatibility Checking. This is slow + // and expensive, but you should consider running + // it before upgrading your version of PHP to a + // new version that has backward compatibility + // breaks. + 'backward_compatibility_checks' => false, + + // If true, check to make sure the return type declared + // in the doc-block (if any) matches the return type + // declared in the method signature. + 'check_docblock_signature_return_type_match' => false, + + // (*Requires check_docblock_signature_param_type_match to be true*) + // If true, make narrowed types from phpdoc params override + // the real types from the signature, when real types exist. + // (E.g. allows specifying desired lists of subclasses, + // or to indicate a preference for non-nullable types over nullable types) + // Affects analysis of the body of the method and the param types passed in by callers. + 'prefer_narrowed_phpdoc_param_type' => true, + + // (*Requires check_docblock_signature_return_type_match to be true*) + // If true, make narrowed types from phpdoc returns override + // the real types from the signature, when real types exist. + // (E.g. allows specifying desired lists of subclasses, + // or to indicate a preference for non-nullable types over nullable types) + // Affects analysis of return statements in the body of the method and the return types passed in by callers. + 'prefer_narrowed_phpdoc_return_type' => true, + + // If enabled, check all methods that override a + // parent method to make sure its signature is + // compatible with the parent's. This check + // can add quite a bit of time to the analysis. + // This will also check if final methods are overridden, etc. + 'analyze_signature_compatibility' => true, + + // This setting maps case insensitive strings to union types. + // This is useful if a project uses phpdoc that differs from the phpdoc2 standard. + // If the corresponding value is the empty string, Phan will ignore that union type (E.g. can ignore 'the' in `@return the value`) + // If the corresponding value is not empty, Phan will act as though it saw the corresponding unionTypes(s) when the keys show up in a UnionType of @param, @return, @var, @property, etc. + // + // This matches the **entire string**, not parts of the string. + // (E.g. `@return the|null` will still look for a class with the name `the`, but `@return the` will be ignored with the below setting) + // + // (These are not aliases, this setting is ignored outside of doc comments). + // (Phan does not check if classes with these names exist) + // + // Example setting: ['unknown' => '', 'number' => 'int|float', 'char' => 'string', 'long' => 'int', 'the' => ''] + 'phpdoc_type_mapping' => [], + + // Set to true in order to attempt to detect dead + // (unreferenced) code. Keep in mind that the + // results will only be a guess given that classes, + // properties, constants and methods can be referenced + // as variables (like `$class->$property` or + // `$class->$method()`) in ways that we're unable + // to make sense of. + 'dead_code_detection' => false, + + // Set to true in order to attempt to detect unused variables. + // dead_code_detection will also enable unused variable detection. + // This has a few known false positives, e.g. for loops or branches. + 'unused_variable_detection' => false, + + // If true, this run a quick version of checks that takes less + // time at the cost of not running as thorough + // an analysis. You should consider setting this + // to true only when you wish you had more **undiagnosed** issues + // to fix in your code base. + // + // In quick-mode the scanner doesn't rescan a function + // or a method's code block every time a call is seen. + // This means that the problem here won't be detected: + // + // ```php + // false, + + // If true, then before analysis, try to simplify AST into a form + // which improves Phan's type inference in edge cases. + // + // This may conflict with 'dead_code_detection'. + // When this is true, this slows down analysis slightly. + // + // E.g. rewrites `if ($a = value() && $a > 0) {...}` + // into $a = value(); if ($a) { if ($a > 0) {...}}` + 'simplify_ast' => true, + + // Enable or disable support for generic templated + // class types. + 'generic_types_enabled' => true, + + // Override to hardcode existence and types of (non-builtin) globals in the global scope. + // Class names should be prefixed with '\\'. + // (E.g. ['_FOO' => '\\FooClass', 'page' => '\\PageClass', 'userId' => 'int']) + 'globals_type_map' => [], + + // The minimum severity level to report on. This can be + // set to Issue::SEVERITY_LOW, Issue::SEVERITY_NORMAL or + // Issue::SEVERITY_CRITICAL. Setting it to only + // critical issues is a good place to start on a big + // sloppy mature code base. + 'minimum_severity' => Issue::SEVERITY_LOW, + + // Add any issue types (such as 'PhanUndeclaredMethod') + // to this black-list to inhibit them from being reported. + 'suppress_issue_types' => [ + 'PhanTypeInvalidThrowsIsInterface', + ], + + // A regular expression to match files to be excluded + // from parsing and analysis and will not be read at all. + // + // This is useful for excluding groups of test or example + // directories/files, unanalyzable files, or files that + // can't be removed for whatever reason. + // (e.g. '@Test\.php$@', or '@vendor/.*/(tests|Tests)/@') + 'exclude_file_regex' => '@^vendor/.*/(tests?|Tests?)/@', + + // A file list that defines files that will be excluded + // from parsing and analysis and will not be read at all. + // + // This is useful for excluding hopelessly unanalyzable + // files that can't be removed for whatever reason. + 'exclude_file_list' => [], + + // A directory list that defines files that will be excluded + // from static analysis, but whose class and method + // information should be included. + // + // Generally, you'll want to include the directories for + // third-party code (such as "vendor/") in this list. + // + // n.b.: If you'd like to parse but not analyze 3rd + // party code, directories containing that code + // should be added to the `directory_list` as + // to `excluce_analysis_directory_list`. + 'exclude_analysis_directory_list' => [ + 'vendor/', + ], + + // The number of processes to fork off during the analysis + // phase. + 'processes' => 4, + + // List of case-insensitive file extensions supported by Phan. + // (e.g. php, html, htm) + 'analyzed_file_extensions' => [ + 'php', + ], + + // You can put paths to stubs of internal extensions in this config option. + // If the corresponding extension is **not** loaded, then phan will use the stubs instead. + // Phan will continue using its detailed type annotations, + // but load the constants, classes, functions, and classes (and their Reflection types) + // from these stub files (doubling as valid php files). + // Use a different extension from php to avoid accidentally loading these. + // The 'tools/make_stubs' script can be used to generate your own stubs (compatible with php 7.0+ right now) + 'autoload_internal_extension_signatures' => [], + + // A list of plugin files to execute + // Plugins which are bundled with Phan can be added here by providing their name (e.g. 'AlwaysReturnPlugin') + // Alternately, you can pass in the full path to a PHP file with the plugin's implementation (e.g. 'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php') + 'plugins' => [ + 'AlwaysReturnPlugin', + 'PregRegexCheckerPlugin', + 'UnreachableCodePlugin', + ], + + // A list of directories that should be parsed for class and + // method information. After excluding the directories + // defined in exclude_analysis_directory_list, the remaining + // files will be statically analyzed for errors. + // + // Thus, both first-party and third-party code being used by + // your application should be included in this list. + 'directory_list' => [ + 'src/App', + 'vendor/', + ], +]; diff --git a/composer.json b/composer.json index 61f64a4..53ffc7e 100644 --- a/composer.json +++ b/composer.json @@ -24,13 +24,18 @@ "zendframework/zend-http": "^2.7", "zendframework/zend-json": "^3.1", "zendframework/zend-servicemanager": "^3.3", - "zendframework/zend-stdlib": "^3.1" + "zendframework/zend-stdlib": "^3.1", + "ext-openssl": "*", + "ext-dom": "*", + "ext-libxml": "*", + "ext-json": "*" }, "require-dev": { + "filp/whoops": "^2.1.7", + "phan/phan": "^1.0", "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" + "zfcampus/zf-development-mode": "^3.1" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index aef5832..d0434b4 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f887d48863e41f6fd79fe54033c7fa41", + "content-hash": "e8f48721a59fb28db0982e0205d3b7d0", "packages": [ { "name": "container-interop/container-interop", @@ -146,16 +146,16 @@ }, { "name": "doctrine/cache", - "version": "v1.7.1", + "version": "v1.8.0", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "b3217d58609e9c8e661cd41357a54d926c4a2a1a" + "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/b3217d58609e9c8e661cd41357a54d926c4a2a1a", - "reference": "b3217d58609e9c8e661cd41357a54d926c4a2a1a", + "url": "https://api.github.com/repos/doctrine/cache/zipball/d768d58baee9a4862ca783840eca1b9add7a7f57", + "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57", "shasum": "" }, "require": { @@ -166,8 +166,9 @@ }, "require-dev": { "alcaeus/mongo-php-adapter": "^1.1", + "doctrine/coding-standard": "^4.0", "mongodb/mongodb": "^1.1", - "phpunit/phpunit": "^5.7", + "phpunit/phpunit": "^7.0", "predis/predis": "~1.0" }, "suggest": { @@ -176,7 +177,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7.x-dev" + "dev-master": "1.8.x-dev" } }, "autoload": { @@ -211,12 +212,12 @@ } ], "description": "Caching library offering an object-oriented API for many cache backends", - "homepage": "http://www.doctrine-project.org", + "homepage": "https://www.doctrine-project.org", "keywords": [ "cache", "caching" ], - "time": "2017-08-25T07:02:50+00:00" + "time": "2018-08-21T18:01:43+00:00" }, { "name": "doctrine/collections", @@ -287,33 +288,39 @@ }, { "name": "doctrine/common", - "version": "v2.8.1", + "version": "v2.9.0", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "f68c297ce6455e8fd794aa8ffaf9fa458f6ade66" + "reference": "a210246d286c77d2b89040f8691ba7b3a713d2c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/f68c297ce6455e8fd794aa8ffaf9fa458f6ade66", - "reference": "f68c297ce6455e8fd794aa8ffaf9fa458f6ade66", + "url": "https://api.github.com/repos/doctrine/common/zipball/a210246d286c77d2b89040f8691ba7b3a713d2c1", + "reference": "a210246d286c77d2b89040f8691ba7b3a713d2c1", "shasum": "" }, "require": { - "doctrine/annotations": "1.*", - "doctrine/cache": "1.*", - "doctrine/collections": "1.*", - "doctrine/inflector": "1.*", - "doctrine/lexer": "1.*", - "php": "~7.1" + "doctrine/annotations": "^1.0", + "doctrine/cache": "^1.0", + "doctrine/collections": "^1.0", + "doctrine/event-manager": "^1.0", + "doctrine/inflector": "^1.0", + "doctrine/lexer": "^1.0", + "doctrine/persistence": "^1.0", + "doctrine/reflection": "^1.0", + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^5.7" + "doctrine/coding-standard": "^1.0", + "phpunit/phpunit": "^6.3", + "squizlabs/php_codesniffer": "^3.0", + "symfony/phpunit-bridge": "^4.0.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8.x-dev" + "dev-master": "2.9.x-dev" } }, "autoload": { @@ -345,10 +352,14 @@ { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" } ], "description": "Common Library for Doctrine projects", - "homepage": "http://www.doctrine-project.org", + "homepage": "https://www.doctrine-project.org", "keywords": [ "annotations", "collections", @@ -356,32 +367,35 @@ "persistence", "spl" ], - "time": "2017-08-31T08:43:38+00:00" + "time": "2018-07-12T21:16:12+00:00" }, { "name": "doctrine/dbal", - "version": "v2.7.1", + "version": "v2.8.0", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "11037b4352c008373561dc6fc836834eed80c3b5" + "reference": "5140a64c08b4b607b9bedaae0cedd26f04a0e621" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/11037b4352c008373561dc6fc836834eed80c3b5", - "reference": "11037b4352c008373561dc6fc836834eed80c3b5", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/5140a64c08b4b607b9bedaae0cedd26f04a0e621", + "reference": "5140a64c08b4b607b9bedaae0cedd26f04a0e621", "shasum": "" }, "require": { - "doctrine/common": "^2.7.1", + "doctrine/cache": "^1.0", + "doctrine/event-manager": "^1.0", "ext-pdo": "*", "php": "^7.1" }, "require-dev": { "doctrine/coding-standard": "^4.0", - "phpunit/phpunit": "^7.0", + "jetbrains/phpstorm-stubs": "^2018.1.2", + "phpstan/phpstan": "^0.10.1", + "phpunit/phpunit": "^7.1.2", "phpunit/phpunit-mock-objects": "!=3.2.4,!=3.2.5", - "symfony/console": "^2.0.5||^3.0", + "symfony/console": "^2.0.5|^3.0|^4.0", "symfony/phpunit-bridge": "^3.4.5|^4.0.5" }, "suggest": { @@ -393,7 +407,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7.x-dev" + "dev-master": "2.8.x-dev", + "dev-develop": "3.0.x-dev" } }, "autoload": { @@ -431,7 +446,81 @@ "persistence", "queryobject" ], - "time": "2018-04-07T18:44:18+00:00" + "time": "2018-07-13T03:16:35+00:00" + }, + { + "name": "doctrine/event-manager", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/event-manager.git", + "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3", + "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "conflict": { + "doctrine/common": "<2.9@dev" + }, + "require-dev": { + "doctrine/coding-standard": "^4.0", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Doctrine Event Manager component", + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", + "keywords": [ + "event", + "eventdispatcher", + "eventmanager" + ], + "time": "2018-06-11T11:59:03+00:00" }, { "name": "doctrine/inflector", @@ -610,16 +699,16 @@ }, { "name": "doctrine/orm", - "version": "v2.6.1", + "version": "v2.6.2", "source": { "type": "git", "url": "https://github.com/doctrine/doctrine2.git", - "reference": "87ee409783a4a322b5597ebaae558661404055a7" + "reference": "d2b4dd71d2a276edd65d0c170375b445f8a4a4a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/87ee409783a4a322b5597ebaae558661404055a7", - "reference": "87ee409783a4a322b5597ebaae558661404055a7", + "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/d2b4dd71d2a276edd65d0c170375b445f8a4a4a8", + "reference": "d2b4dd71d2a276edd65d0c170375b445f8a4a4a8", "shasum": "" }, "require": { @@ -688,7 +777,160 @@ "database", "orm" ], - "time": "2018-02-27T07:30:56+00:00" + "time": "2018-07-12T20:47:13+00:00" + }, + { + "name": "doctrine/persistence", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/persistence.git", + "reference": "af1ec238659a83e320f03e0e454e200f689b4b97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/af1ec238659a83e320f03e0e454e200f689b4b97", + "reference": "af1ec238659a83e320f03e0e454e200f689b4b97", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.0", + "doctrine/cache": "^1.0", + "doctrine/collections": "^1.0", + "doctrine/event-manager": "^1.0", + "doctrine/reflection": "^1.0", + "php": "^7.1" + }, + "conflict": { + "doctrine/common": "<2.9@dev" + }, + "require-dev": { + "doctrine/coding-standard": "^4.0", + "phpstan/phpstan": "^0.8", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Doctrine Persistence abstractions.", + "homepage": "https://doctrine-project.org/projects/persistence.html", + "keywords": [ + "persistence" + ], + "time": "2018-07-12T12:37:50+00:00" + }, + { + "name": "doctrine/reflection", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/reflection.git", + "reference": "02538d3f95e88eb397a5f86274deb2c6175c2ab6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/reflection/zipball/02538d3f95e88eb397a5f86274deb2c6175c2ab6", + "reference": "02538d3f95e88eb397a5f86274deb2c6175c2ab6", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.0", + "ext-tokenizer": "*", + "php": "^7.1" + }, + "require-dev": { + "doctrine/coding-standard": "^4.0", + "doctrine/common": "^2.8", + "phpstan/phpstan": "^0.9.2", + "phpstan/phpstan-phpunit": "^0.9.4", + "phpunit/phpunit": "^7.0", + "squizlabs/php_codesniffer": "^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Doctrine Reflection component", + "homepage": "https://www.doctrine-project.org/projects/reflection.html", + "keywords": [ + "reflection" + ], + "time": "2018-06-14T14:45:07+00:00" }, { "name": "fig/http-message-util", @@ -1290,17 +1532,6 @@ { "name": "roave/security-advisories", "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "0253937ef2720f45fbe421e3ba486587b3080c35" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/0253937ef2720f45fbe421e3ba486587b3080c35", - "reference": "0253937ef2720f45fbe421e3ba486587b3080c35", - "shasum": "" - }, "conflict": { "3f/pygmentize": "<1.2", "adodb/adodb-php": "<5.20.12", @@ -1308,6 +1539,7 @@ "amphp/http": "<1.0.1", "asymmetricrypt/asymmetricrypt": ">=0,<9.9.99", "aws/aws-sdk-php": ">=3,<3.2.1", + "brightlocal/phpwhois": "<=4.2.5", "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|>=3.4,<3.4.14|>=3.5,<3.5.17|>=3.6,<3.6.4", "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4", @@ -1319,6 +1551,7 @@ "contao/core-bundle": ">=4,<4.4.18|>=4.5,<4.5.8", "contao/listing-bundle": ">=4,<4.4.8", "contao/newsletter-bundle": ">=4,<4.1", + "david-garcia/phpwhois": "<=4.3.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", @@ -1333,6 +1566,7 @@ "drupal/drupal": ">=7,<7.59|>=8,<8.4.8|>=8.5,<8.5.3", "erusev/parsedown": "<1.7", "ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.3|>=5.4,<5.4.11.3|>=2017.8,<2017.8.1.1|>=2017.12,<2017.12.2.1", + "ezyang/htmlpurifier": "<4.1.1", "firebase/php-jwt": "<2", "friendsofsymfony/rest-bundle": ">=1.2,<1.2.2", "friendsofsymfony/user-bundle": ">=1.2,<1.3.5", @@ -1341,18 +1575,24 @@ "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.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.10", + "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30", "illuminate/database": ">=4,<4.0.99|>=4.1,<4.1.29", "illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15", + "ivankristianto/phpwhois": "<=4.3", + "james-heinrich/getid3": "<1.9.9", "joomla/session": "<1.3.1", + "jsmitty12/phpwhois": "<5.1", + "kazist/phpwhois": "<=4.2.6", "kreait/firebase-php": ">=3.2,<3.8.1", - "laravel/framework": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15", + "laravel/framework": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30", "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10", - "magento/magento1ce": ">=1.5.0.1,<1.9.3.2", + "magento/magento1ce": "<1.9.3.9", "magento/magento1ee": ">=1.9,<1.14.3.2", "magento/product-community-edition": ">=2,<2.2.5", "monolog/monolog": ">=1.8,<1.12", "namshi/jose": "<2.2", "onelogin/php-saml": "<2.10.4", + "openid/php-openid": "<2.3", "oro/crm": ">=1.7,<1.7.4", "oro/platform": ">=1.7,<1.7.4", "padraic/humbug_get_contents": "<1.1.2", @@ -1361,29 +1601,35 @@ "paypal/merchant-sdk-php": "<3.12", "phpmailer/phpmailer": ">=5,<5.2.24", "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3", + "phpwhois/phpwhois": "<=4.2.5", "phpxmlrpc/extras": "<0.6.1", "propel/propel": ">=2.0.0-alpha1,<=2.0.0-alpha7", "propel/propel1": ">=1,<=1.7.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", "sensiolabs/connect": "<4.2.3", + "serluck/phpwhois": "<=4.2.6", "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", + "simple-updates/phpwhois": "<=1", "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4", "simplesamlphp/simplesamlphp": "<1.15.2", "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1", "slim/slim": "<2.6", + "smarty/smarty": "<3.1.33", "socalnick/scn-social-auth": "<1.15.2", "squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1", "stormpath/sdk": ">=0,<9.9.99", "swiftmailer/swiftmailer": ">=4,<5.4.5", + "sylius/admin-bundle": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2", + "sylius/sylius": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2", "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.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", + "symfony/http-foundation": ">=2,<2.7.49|>=2.8,<2.8.44|>=3,<3.3.18|>=3.4,<3.4.14|>=4,<4.0.14|>=4.1,<4.1.3", "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", @@ -1394,16 +1640,19 @@ "symfony/security-guard": ">=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", "symfony/serializer": ">=2,<2.0.11", - "symfony/symfony": ">=2,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", + "symfony/symfony": ">=2,<2.7.49|>=2.8,<2.8.44|>=3,<3.3.18|>=3.4,<3.4.14|>=4,<4.0.14|>=4.1,<4.1.3", "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", + "theonedemon/phpwhois": "<=4.2.5", "titon/framework": ">=0,<9.9.99", + "truckersmp/phpwhois": "<=4.3.1", "twig/twig": "<1.20", - "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.22|>=8,<8.7.5", + "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.30|>=8,<8.7.17|>=9,<9.3.2", + "typo3/cms-core": ">=8,<8.7.17|>=9,<9.3.2", "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", @@ -1419,9 +1668,10 @@ "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-diactoros": ">=1,<1.8.4", + "zendframework/zend-feed": ">=1,<2.10.3", "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-http": ">=1,<2.8.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", @@ -1430,7 +1680,7 @@ "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/zendframework": "<2.5.1", "zendframework/zendframework1": "<1.12.20", "zendframework/zendopenid": ">=2,<2.0.2", "zendframework/zendxml": ">=1,<1.0.1", @@ -1452,20 +1702,20 @@ } ], "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", - "time": "2018-07-04T05:48:21+00:00" + "time": "2018-09-17T20:20:31+00:00" }, { "name": "symfony/console", - "version": "v4.1.1", + "version": "v4.1.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "70591cda56b4b47c55776ac78e157c4bb6c8b43f" + "reference": "ca80b8ced97cf07390078b29773dc384c39eee1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/70591cda56b4b47c55776ac78e157c4bb6c8b43f", - "reference": "70591cda56b4b47c55776ac78e157c4bb6c8b43f", + "url": "https://api.github.com/repos/symfony/console/zipball/ca80b8ced97cf07390078b29773dc384c39eee1f", + "reference": "ca80b8ced97cf07390078b29773dc384c39eee1f", "shasum": "" }, "require": { @@ -1520,20 +1770,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-05-31T10:17:53+00:00" + "time": "2018-07-26T11:24:31+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.8.0", + "version": "v1.9.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "3296adf6a6454a050679cde90f95350ad604b171" + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171", - "reference": "3296adf6a6454a050679cde90f95350ad604b171", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", "shasum": "" }, "require": { @@ -1545,7 +1795,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8-dev" + "dev-master": "1.9-dev" } }, "autoload": { @@ -1579,7 +1829,7 @@ "portable", "shim" ], - "time": "2018-04-26T10:06:28+00:00" + "time": "2018-08-06T14:22:27+00:00" }, { "name": "zendframework/zend-component-installer", @@ -1690,16 +1940,16 @@ }, { "name": "zendframework/zend-diactoros", - "version": "1.8.0", + "version": "1.8.6", "source": { "type": "git", "url": "https://github.com/zendframework/zend-diactoros.git", - "reference": "11c9c1835e60eef6f9234377a480fcec096ebd9e" + "reference": "20da13beba0dde8fb648be3cc19765732790f46e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/11c9c1835e60eef6f9234377a480fcec096ebd9e", - "reference": "11c9c1835e60eef6f9234377a480fcec096ebd9e", + "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/20da13beba0dde8fb648be3cc19765732790f46e", + "reference": "20da13beba0dde8fb648be3cc19765732790f46e", "shasum": "" }, "require": { @@ -1712,7 +1962,8 @@ "require-dev": { "ext-dom": "*", "ext-libxml": "*", - "phpunit/phpunit": "^5.7.16 || ^6.0.8", + "php-http/psr7-integration-tests": "dev-master", + "phpunit/phpunit": "^5.7.16 || ^6.0.8 || ^7.2.7", "zendframework/zend-coding-standard": "~1.0" }, "type": "library", @@ -1749,7 +2000,7 @@ "psr", "psr-7" ], - "time": "2018-06-27T18:52:43+00:00" + "time": "2018-09-05T19:29:37+00:00" }, { "name": "zendframework/zend-escaper", @@ -1852,16 +2103,16 @@ }, { "name": "zendframework/zend-expressive", - "version": "3.0.2", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-expressive.git", - "reference": "4ea54ed15906c0e06d5211daf88a00ed36a0df83" + "reference": "1ddf213b4c0c7dcf39be83e8eb1a5d5b944ee346" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-expressive/zipball/4ea54ed15906c0e06d5211daf88a00ed36a0df83", - "reference": "4ea54ed15906c0e06d5211daf88a00ed36a0df83", + "url": "https://api.github.com/repos/zendframework/zend-expressive/zipball/1ddf213b4c0c7dcf39be83e8eb1a5d5b944ee346", + "reference": "1ddf213b4c0c7dcf39be83e8eb1a5d5b944ee346", "shasum": "" }, "require": { @@ -1940,20 +2191,20 @@ "zend-expressive", "zf" ], - "time": "2018-04-10T16:22:30+00:00" + "time": "2018-07-30T21:23:01+00:00" }, { "name": "zendframework/zend-expressive-fastroute", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-expressive-fastroute.git", - "reference": "e5b94197c9145810055133a09a277a29239e1a64" + "reference": "da91f1ba3d03e3aad58d9f0290518f8e28e2e8f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-expressive-fastroute/zipball/e5b94197c9145810055133a09a277a29239e1a64", - "reference": "e5b94197c9145810055133a09a277a29239e1a64", + "url": "https://api.github.com/repos/zendframework/zend-expressive-fastroute/zipball/da91f1ba3d03e3aad58d9f0290518f8e28e2e8f0", + "reference": "da91f1ba3d03e3aad58d9f0290518f8e28e2e8f0", "shasum": "" }, "require": { @@ -2007,20 +2258,20 @@ "zend-expressive", "zf" ], - "time": "2018-03-20T16:34:28+00:00" + "time": "2018-08-02T14:10:40+00:00" }, { "name": "zendframework/zend-expressive-helpers", - "version": "5.1.0", + "version": "5.1.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-expressive-helpers.git", - "reference": "9c6a287438f429f036efa159876e2a29c16f8010" + "reference": "c4db15318ae53965794f46618535fc61dd058ea7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-expressive-helpers/zipball/9c6a287438f429f036efa159876e2a29c16f8010", - "reference": "9c6a287438f429f036efa159876e2a29c16f8010", + "url": "https://api.github.com/repos/zendframework/zend-expressive-helpers/zipball/c4db15318ae53965794f46618535fc61dd058ea7", + "reference": "c4db15318ae53965794f46618535fc61dd058ea7", "shasum": "" }, "require": { @@ -2067,7 +2318,7 @@ "zend-expressive", "zf" ], - "time": "2018-06-05T15:22:07+00:00" + "time": "2018-07-26T20:05:23+00:00" }, { "name": "zendframework/zend-expressive-router", @@ -2187,16 +2438,16 @@ }, { "name": "zendframework/zend-http", - "version": "2.8.0", + "version": "2.8.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-http.git", - "reference": "f48b276ffa11b48dd1ae3c6bc306d6ed7958ef51" + "reference": "2c8aed3d25522618573194e7cc51351f8cd4a45b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-http/zipball/f48b276ffa11b48dd1ae3c6bc306d6ed7958ef51", - "reference": "f48b276ffa11b48dd1ae3c6bc306d6ed7958ef51", + "url": "https://api.github.com/repos/zendframework/zend-http/zipball/2c8aed3d25522618573194e7cc51351f8cd4a45b", + "reference": "2c8aed3d25522618573194e7cc51351f8cd4a45b", "shasum": "" }, "require": { @@ -2238,7 +2489,7 @@ "zend", "zf" ], - "time": "2018-04-26T21:04:50+00:00" + "time": "2018-08-13T18:47:03+00:00" }, { "name": "zendframework/zend-httphandlerrunner", @@ -2530,16 +2781,16 @@ }, { "name": "zendframework/zend-stdlib", - "version": "3.2.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-stdlib.git", - "reference": "cd164b4a18b5d1aeb69be2c26db035b5ed6925ae" + "reference": "66536006722aff9e62d1b331025089b7ec71c065" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/cd164b4a18b5d1aeb69be2c26db035b5ed6925ae", - "reference": "cd164b4a18b5d1aeb69be2c26db035b5ed6925ae", + "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/66536006722aff9e62d1b331025089b7ec71c065", + "reference": "66536006722aff9e62d1b331025089b7ec71c065", "shasum": "" }, "require": { @@ -2572,20 +2823,20 @@ "stdlib", "zf" ], - "time": "2018-04-30T13:50:40+00:00" + "time": "2018-08-28T21:34:05+00:00" }, { "name": "zendframework/zend-stratigility", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-stratigility.git", - "reference": "1efae7142c64a795034fd0dbf8013aa8f531edf3" + "reference": "75b64558201807514734a9f46386816f2900d7f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-stratigility/zipball/1efae7142c64a795034fd0dbf8013aa8f531edf3", - "reference": "1efae7142c64a795034fd0dbf8013aa8f531edf3", + "url": "https://api.github.com/repos/zendframework/zend-stratigility/zipball/75b64558201807514734a9f46386816f2900d7f7", + "reference": "75b64558201807514734a9f46386816f2900d7f7", "shasum": "" }, "require": { @@ -2638,7 +2889,7 @@ "psr-7", "zf" ], - "time": "2018-04-04T17:47:35+00:00" + "time": "2018-07-24T20:39:18+00:00" }, { "name": "zendframework/zend-uri", @@ -2761,17 +3012,164 @@ ], "packages-dev": [ { - "name": "filp/whoops", - "version": "2.2.0", + "name": "composer/semver", + "version": "1.4.2", "source": { "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "181c4502d8f34db7aed7bfe88d4f87875b8e947a" + "url": "https://github.com/composer/semver.git", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/181c4502d8f34db7aed7bfe88d4f87875b8e947a", - "reference": "181c4502d8f34db7aed7bfe88d4f87875b8e947a", + "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "time": "2016-08-30T16:08:34+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/b8e9745fb9b06ea6664d8872c4505fb16df4611c", + "reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "time": "2018-08-31T19:07:57+00:00" + }, + { + "name": "felixfbecker/advanced-json-rpc", + "version": "v3.0.3", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", + "reference": "241c470695366e7b83672be04ea0e64d8085a551" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/241c470695366e7b83672be04ea0e64d8085a551", + "reference": "241c470695366e7b83672be04ea0e64d8085a551", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^1.0", + "php": ">=7.0", + "phpdocumentor/reflection-docblock": "^4.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "A more advanced JSONRPC implementation", + "time": "2018-09-10T08:58:41+00:00" + }, + { + "name": "filp/whoops", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "e79cd403fb77fc8963a99ecc30e80ddd885b3311" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/e79cd403fb77fc8963a99ecc30e80ddd885b3311", + "reference": "e79cd403fb77fc8963a99ecc30e80ddd885b3311", "shasum": "" }, "require": { @@ -2790,7 +3188,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } }, "autoload": { @@ -2819,7 +3217,48 @@ "throwable", "whoops" ], - "time": "2018-03-03T17:56:25+00:00" + "time": "2018-06-30T13:14:06+00:00" + }, + { + "name": "microsoft/tolerant-php-parser", + "version": "v0.0.13", + "source": { + "type": "git", + "url": "https://github.com/Microsoft/tolerant-php-parser.git", + "reference": "89ade271e639e0612deeccb0555f13c2224ecf84" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Microsoft/tolerant-php-parser/zipball/89ade271e639e0612deeccb0555f13c2224ecf84", + "reference": "89ade271e639e0612deeccb0555f13c2224ecf84", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Microsoft\\PhpParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Lourens", + "email": "roblou@microsoft.com" + } + ], + "description": "Tolerant PHP-to-AST parser designed for IDE usage scenarios", + "time": "2018-08-07T04:52:21+00:00" }, { "name": "myclabs/deep-copy", @@ -2869,6 +3308,114 @@ ], "time": "2018-06-11T23:09:50+00:00" }, + { + "name": "netresearch/jsonmapper", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "3868fe1128ce1169228acdb623359dca74db5ef3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/3868fe1128ce1169228acdb623359dca74db5ef3", + "reference": "3868fe1128ce1169228acdb623359dca74db5ef3", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "~4.8.35 || ~5.7 || ~6.4", + "squizlabs/php_codesniffer": "~1.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonMapper": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@cweiske.de", + "homepage": "http://github.com/cweiske/jsonmapper/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "time": "2017-11-28T21:30:01+00:00" + }, + { + "name": "phan/phan", + "version": "1.0.6", + "source": { + "type": "git", + "url": "https://github.com/phan/phan.git", + "reference": "11eb4f3235ccc2ce5a5709bccdbdb674152e36ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phan/phan/zipball/11eb4f3235ccc2ce5a5709bccdbdb674152e36ba", + "reference": "11eb4f3235ccc2ce5a5709bccdbdb674152e36ba", + "shasum": "" + }, + "require": { + "composer/semver": "^1.4", + "composer/xdebug-handler": "^1.3", + "ext-filter": "*", + "ext-json": "*", + "felixfbecker/advanced-json-rpc": "^3.0.3", + "microsoft/tolerant-php-parser": "0.0.13", + "php": "^7.0.0", + "sabre/event": "^5.0", + "symfony/console": "^2.3|^3.0|~4.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.3.0" + }, + "suggest": { + "ext-ast": "^0.1.5", + "ext-tokenizer": "Needed for non-AST support and file/line-based suppressions" + }, + "bin": [ + "phan", + "phan_client", + "tocheckstyle" + ], + "type": "project", + "autoload": { + "psr-4": { + "Phan\\": "src/Phan" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rasmus Lerdorf" + }, + { + "name": "Andrew S. Morrison" + }, + { + "name": "Tyson Andre" + } + ], + "description": "A static analyzer for PHP", + "keywords": [ + "analyzer", + "php", + "static" + ], + "time": "2018-09-25T21:55:43+00:00" + }, { "name": "phar-io/manifest", "version": "1.0.1", @@ -3125,16 +3672,16 @@ }, { "name": "phpspec/prophecy", - "version": "1.7.6", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712" + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712", - "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", "shasum": "" }, "require": { @@ -3146,12 +3693,12 @@ }, "require-dev": { "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7.x-dev" + "dev-master": "1.8.x-dev" } }, "autoload": { @@ -3184,7 +3731,7 @@ "spy", "stub" ], - "time": "2018-04-18T13:57:24+00:00" + "time": "2018-08-05T17:53:17+00:00" }, { "name": "phpunit/php-code-coverage", @@ -3437,16 +3984,16 @@ }, { "name": "phpunit/phpunit", - "version": "6.5.9", + "version": "6.5.13", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "093ca5508174cd8ab8efe44fd1dde447adfdec8f" + "reference": "0973426fb012359b2f18d3bd1e90ef1172839693" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/093ca5508174cd8ab8efe44fd1dde447adfdec8f", - "reference": "093ca5508174cd8ab8efe44fd1dde447adfdec8f", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0973426fb012359b2f18d3bd1e90ef1172839693", + "reference": "0973426fb012359b2f18d3bd1e90ef1172839693", "shasum": "" }, "require": { @@ -3464,7 +4011,7 @@ "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", + "phpunit/phpunit-mock-objects": "^5.0.9", "sebastian/comparator": "^2.1", "sebastian/diff": "^2.0", "sebastian/environment": "^3.1", @@ -3517,20 +4064,20 @@ "testing", "xunit" ], - "time": "2018-07-03T06:40:40+00:00" + "time": "2018-09-08T15:10:43+00:00" }, { "name": "phpunit/phpunit-mock-objects", - "version": "5.0.7", + "version": "5.0.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "3eaf040f20154d27d6da59ca2c6e28ac8fd56dce" + "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3eaf040f20154d27d6da59ca2c6e28ac8fd56dce", - "reference": "3eaf040f20154d27d6da59ca2c6e28ac8fd56dce", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/cd1cf05c553ecfec36b170070573e540b67d3f1f", + "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f", "shasum": "" }, "require": { @@ -3543,7 +4090,7 @@ "phpunit/phpunit": "<6.0" }, "require-dev": { - "phpunit/phpunit": "^6.5" + "phpunit/phpunit": "^6.5.11" }, "suggest": { "ext-soap": "*" @@ -3576,7 +4123,67 @@ "mock", "xunit" ], - "time": "2018-05-29T13:50:43+00:00" + "time": "2018-08-09T05:50:03+00:00" + }, + { + "name": "sabre/event", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/event.git", + "reference": "f5cf802d240df1257866d8813282b98aee3bc548" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/event/zipball/f5cf802d240df1257866d8813282b98aee3bc548", + "reference": "f5cf802d240df1257866d8813282b98aee3bc548", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": ">=6", + "sabre/cs": "~1.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sabre\\Event\\": "lib/" + }, + "files": [ + "lib/coroutine.php", + "lib/Loop/functions.php", + "lib/Promise/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "sabre/event is a library for lightweight event-based programming", + "homepage": "http://sabre.io/event/", + "keywords": [ + "EventEmitter", + "async", + "coroutine", + "eventloop", + "events", + "hooks", + "plugin", + "promise", + "reactor", + "signal" + ], + "time": "2018-03-05T13:55:47+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -4363,7 +4970,11 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "^7.1" + "php": "^7.1", + "ext-openssl": "*", + "ext-dom": "*", + "ext-libxml": "*", + "ext-json": "*" }, "platform-dev": [] } diff --git a/config/autoload/dependencies.global.php b/config/autoload/dependencies.global.php index cf8d398..c39b9bf 100644 --- a/config/autoload/dependencies.global.php +++ b/config/autoload/dependencies.global.php @@ -36,7 +36,6 @@ return [ Middleware\NotFoundHandler::class => Container\NotFoundHandlerFactory::class, 'doctrine.entity_manager.orm_default' => \ContainerInteropDoctrine\EntityManagerFactory::class, - 'doctrine.hydrator' => \App\Hydrator\DoctrineObjectFactory::class, \App\Middleware\EventSubscriberMiddleware::class => \App\Middleware\EventSubscriberMiddlewareFactory::class, ], diff --git a/config/autoload/loslog.global.php b/config/autoload/loslog.global.php index 11b6289..7c2d2c1 100644 --- a/config/autoload/loslog.global.php +++ b/config/autoload/loslog.global.php @@ -1,5 +1,7 @@ [ ErrorHandler::class => [ - LosMiddleware\LosLog\ErrorHandlerListenerDelegatorFactory::class, +// LosMiddleware\LosLog\ErrorHandlerListenerDelegatorFactory::class, + App\Log\ExceptionHandlerListenerDelegatorFactory::class, ], ], ], diff --git a/src/App/Action/AbstractAction.php b/src/App/Action/AbstractAction.php index d6c5382..fa202f6 100644 --- a/src/App/Action/AbstractAction.php +++ b/src/App/Action/AbstractAction.php @@ -1,5 +1,7 @@ options($request); case 'PATCH': return $this->patch($request); + default: + return $this->createResponse(['content' => 'Method not allowed'], 405); } } diff --git a/src/App/Action/HomePageAction.php b/src/App/Action/HomePageAction.php index 0a1a36e..7b1ccae 100644 --- a/src/App/Action/HomePageAction.php +++ b/src/App/Action/HomePageAction.php @@ -1,5 +1,7 @@ smsStore = $smsStore; } + /** + * @param ServerRequestInterface $request + * @return ResponseInterface + * @throws \Doctrine\ORM\ORMException + * @throws \Doctrine\ORM\OptimisticLockException + */ public function create(ServerRequestInterface $request): ResponseInterface { $hashKey = $request->getAttribute('hashKey'); $direction = $request->getAttribute('direction'); $mappedDirection = Sms::MAP_DIRECTIONS[$direction]; $requestData = $this->getRequestData($request); + $isStored = $this->smsStore->storeSms($hashKey, $mappedDirection, $requestData); return new JsonCorsResponse($isStored); } diff --git a/src/App/Action/StoreFactory.php b/src/App/Action/StoreFactory.php index b556a2e..4b9b646 100644 --- a/src/App/Action/StoreFactory.php +++ b/src/App/Action/StoreFactory.php @@ -1,5 +1,7 @@ getArgument('id'); diff --git a/src/App/Command/KoinImportCommandFactory.php b/src/App/Command/KoinImportCommandFactory.php index f315089..809b40a 100644 --- a/src/App/Command/KoinImportCommandFactory.php +++ b/src/App/Command/KoinImportCommandFactory.php @@ -1,5 +1,7 @@ setDescription('Parse SZEP card'); } + /** + * @param InputInterface $input + * @param OutputInterface $output + * @return int|null|void + * @throws \Doctrine\ORM\ORMException + * @throws \Doctrine\ORM\OptimisticLockException + * @throws \Doctrine\ORM\TransactionRequiredException + */ protected function execute(InputInterface $input, OutputInterface $output) { - $result = $this->szepManager->pollRecent(); - $output->writeln($result); + $this->szepManager->pollRecent(); } } diff --git a/src/App/Command/PeriodicSZEPCommandFactory.php b/src/App/Command/PeriodicSZEPCommandFactory.php index 07406a3..2b1f23d 100644 --- a/src/App/Command/PeriodicSZEPCommandFactory.php +++ b/src/App/Command/PeriodicSZEPCommandFactory.php @@ -1,5 +1,7 @@ parsedAndHandled; + } + + /** + * @param bool $parsedAndHandled + * @return Sms + */ + public function setParsedAndHandled(bool $parsedAndHandled): Sms + { + $this->parsedAndHandled = $parsedAndHandled; + return $this; + } + /** * Specify data which should be serialized to JSON * @link http://php.net/manual/en/jsonserializable.jsonserialize.php @@ -215,6 +241,7 @@ class Sms implements \JsonSerializable 'when' => $this->getOccuredAt(), 'direction' => $this->getDirection(), 'owner' => $this->getOwner(), + 'isParsedAndHandled' => $this->isParsedAndHandled(), ]; } } diff --git a/src/App/Entity/User.php b/src/App/Entity/User.php index 0b64999..5de3b77 100644 --- a/src/App/Entity/User.php +++ b/src/App/Entity/User.php @@ -1,9 +1,11 @@ . - */ - -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 deleted file mode 100644 index d7d10ea..0000000 --- a/src/App/Hydrator/DoctrineObjectFactory.php +++ /dev/null @@ -1,15 +0,0 @@ -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 deleted file mode 100644 index daafc86..0000000 --- a/src/App/Hydrator/Filter/PropertyName.php +++ /dev/null @@ -1,66 +0,0 @@ -. - */ - -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 deleted file mode 100644 index 37e6738..0000000 --- a/src/App/Hydrator/Strategy/AbstractCollectionStrategy.php +++ /dev/null @@ -1,190 +0,0 @@ -. - */ - -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 deleted file mode 100644 index 57e4222..0000000 --- a/src/App/Hydrator/Strategy/AllowRemoveByReference.php +++ /dev/null @@ -1,58 +0,0 @@ -. - */ - -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 deleted file mode 100644 index 2ac85ae..0000000 --- a/src/App/Hydrator/Strategy/AllowRemoveByValue.php +++ /dev/null @@ -1,76 +0,0 @@ -. - */ - -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 deleted file mode 100644 index e1cbb41..0000000 --- a/src/App/Hydrator/Strategy/DisallowRemoveByReference.php +++ /dev/null @@ -1,53 +0,0 @@ -. - */ - -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 deleted file mode 100644 index 6f2bbcc..0000000 --- a/src/App/Hydrator/Strategy/DisallowRemoveByValue.php +++ /dev/null @@ -1,72 +0,0 @@ -. - */ - -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/Logger/ExceptionHandlerListenerDelegatorFactory.php b/src/App/Logger/ExceptionHandlerListenerDelegatorFactory.php new file mode 100644 index 0000000..4230377 --- /dev/null +++ b/src/App/Logger/ExceptionHandlerListenerDelegatorFactory.php @@ -0,0 +1,37 @@ +has(LoggerInterface::class)) { + throw new \RuntimeException( + "You must define a factory for LoggerInterface. Check loslog.global.php.dist for an example." + ); + } + $logger = $container->get(LoggerInterface::class); + + /* @var ErrorHandler $errorHandler */ + $errorHandler = $callback(); + $errorHandler->attachListener(new LosLogExceptionListener($logger)); + return $errorHandler; + } +} diff --git a/src/App/Logger/LosLogExceptionListener.php b/src/App/Logger/LosLogExceptionListener.php new file mode 100644 index 0000000..0608240 --- /dev/null +++ b/src/App/Logger/LosLogExceptionListener.php @@ -0,0 +1,43 @@ +logger = $logger; + } + + /** + * @param \Throwable $error + * @param Request $request + * @param Response $response + */ + public function __invoke($error, Request $request, Response $response) + { + $this->logger->error(sprintf( + self::LOG_FORMAT, + $response->getStatusCode(), + $request->getMethod(), + (string) $request->getUri(), + $error->getMessage(), + $error->getFile(), + $error->getLine(), + $error->getTraceAsString() + )); + } +} diff --git a/src/App/Middleware/EventSubscriberMiddleware.php b/src/App/Middleware/EventSubscriberMiddleware.php index a164a90..90619c3 100644 --- a/src/App/Middleware/EventSubscriberMiddleware.php +++ b/src/App/Middleware/EventSubscriberMiddleware.php @@ -1,5 +1,7 @@ config = $config; $this->httpClient = $httpClient; + $this->entityManager = $em; } + /** + * @param Event $event + * @throws \Doctrine\ORM\ORMException + * @throws \Doctrine\ORM\OptimisticLockException + */ public function onReceiveSmsListener(Event $event) { $this->onReceiveSms($event->getParam('sms')); @@ -78,20 +74,30 @@ class KoinService /** * @param Sms $sms * @return int + * @throws \Doctrine\ORM\ORMException + * @throws \Doctrine\ORM\OptimisticLockException */ public function onReceiveSms(Sms $sms) { + $setIsHandledFlag = true; if (1 === ($matchStatus = preg_match(self::OTP_SMS_PATTERN, $sms->getText(), $otpMatches))) { $datePart = implode("-", sscanf($otpMatches[1], '%2c%2c%2c')); - $this->saveTransaction( + $result = $this->saveTransaction( str_replace(",", ".", str_replace(".", "", $otpMatches[3])), $otpMatches[4], "20${datePart}", $this->getExpenseCategory($otpMatches[5]), $this->getExpenseTags($otpMatches[5]) ); + + if ( 200 > $result || 299 < $result) { + $setIsHandledFlag = false; + } } + + $sms->setParsedAndHandled($setIsHandledFlag); + $this->entityManager->flush(); return $matchStatus; } @@ -133,6 +139,18 @@ class KoinService return 'Étel'; } + if (false !== strpos($posInfo, "HAI NAM BISTRÓ")) { + return 'Étel'; + } + + if (false !== strpos($posInfo, "FIRPO BURGER")) { + return 'Étel'; + } + + if (false !== strpos($posInfo, "VENDIT AUTOMATÁK")) { + return 'Étel'; + } + if (false !== strpos($posInfo, "SZLOVàK ABC")) { return 'Bevásárlás'; } @@ -173,6 +191,14 @@ class KoinService return 'Közművek'; } + if (false !== strpos($posInfo, "FUNDAMENTA")) { + return 'Megtakarítás'; + } + + if (false !== strpos($posInfo, "STEAMGAMES")) { + return 'Szórakozás'; + } + if (false !== strpos($posInfo, "Aqua Electromax")) { return 'Szórakozás'; } @@ -181,6 +207,10 @@ class KoinService return 'Sport'; } + if (false !== strpos($posInfo, "JYSK")) { + return 'Háztartás'; + } + if (false !== strpos($posInfo, "MOL TÖLTÖàLL")) { return 'Autó'; } @@ -226,8 +256,20 @@ class KoinService } elseif (false !== strpos($posInfo, "BKK AUTOMATA")) { $tags[] = "Bérlet"; $tags[] = "BKV"; + } elseif (false !== strpos($posInfo, "BKK-AUTOMATA")) { + $tags[] = "Bérlet"; + $tags[] = "BKV"; } elseif (false !== strpos($posInfo, "SPAR")) { $tags[] = 'Spar'; + } elseif (false !== strpos($posInfo, "HAI NAM BISTRÓ")) { + $tags[] = 'Hai Nam Bistro'; + $tags[] = 'Vietnámi'; + } elseif (false !== strpos($posInfo, "FIRPO BURGER")) { + $tags[] = 'Firpo Burger'; + $tags[] = 'Burger'; + } elseif (false !== strpos($posInfo, "VENDIT AUTOMATÁK")) { + $tags[] = 'Junk food'; + $tags[] = 'Automata'; } elseif (false !== strpos($posInfo, "TESCO")) { $tags[] = 'Tesco'; } elseif (false !== strpos($posInfo, "SZLOVàK ABC")) { @@ -256,10 +298,17 @@ class KoinService $tags[] = 'Google play'; } elseif (false !== strpos($posInfo, "DIGI ")) { $tags[] = 'Digi'; + } elseif (false !== strpos($posInfo, "FUNDAMENTA")) { + $tags[] = 'Fundamenta'; + } elseif (false !== strpos($posInfo, "STEAMGAMES")) { + $tags[] = 'Steam'; + $tags[] = 'Gáma'; } elseif (false !== strpos($posInfo, "Aqua Electromax")) { $tags[] = 'Aqua'; } elseif (false !== strpos($posInfo, "DECATHLON")) { $tags[] = 'Decathlon'; + } elseif (false !== strpos($posInfo, "JYSK")) { + $tags[] = 'Jysk'; } elseif (false !== strpos($posInfo, "MOL TÖLTÖàLL")) { $tags[] = 'MOL'; $tags[] = 'Benzinkút'; @@ -286,14 +335,14 @@ class KoinService * @return int */ public function saveTransaction(string $amount, - string $currency = 'HUF', + string $currency, string $date, string $category, array $tags): int { $pageData = $this->login($this->config['koin.user'], $this->config['koin.pass']); - $this->loadFormData($pageData->getBody()); + $this->loadFormData($pageData->getBody()->getContents()); return $this->postData( $amount, $currency, @@ -314,7 +363,7 @@ class KoinService $body = $httpResponse->getBody(); - $this->getCsrfToken($body); + $this->getCsrfToken($body->getContents()); $httpResponse = $this->httpClient ->post(self::BASE_URI . "/site/login", [ @@ -336,9 +385,7 @@ class KoinService $documentXpath = $this->getCsrfToken($htmlData); $this->getAccountId($documentXpath); - /** @var \DOMNodeList $expenseOptionElements */ $expenseOptionElements = $documentXpath->query('//select[@id="transaction-category_id"]/optgroup[@label="Kiadás"]/option'); - /** @var \DOMNodeList $incomeOptionElements */ $incomeOptionElements = $documentXpath->query('//select[@id="transaction-category_id"]/optgroup[@label="Bevétel"]/option'); /** @var \DOMElement $element */ @@ -367,13 +414,15 @@ class KoinService libxml_use_internal_errors($xmlErrorHandling); $documentXpath = new \DOMXPath($domDocument); - /** @var \DOMElement $paramElement */ $paramElement = $documentXpath->query('//meta[@name="csrf-param"]')->item(0); - /** @var \DOMElement $tokenElement */ $tokenElement = $documentXpath->query('//meta[@name="csrf-token"]')->item(0); - $this->csrfParam = $paramElement->getAttribute("content"); - $this->csrfToken = $tokenElement->getAttribute("content"); + if ($paramElement instanceof \DOMElement) { + $this->csrfParam = $paramElement->getAttribute("content"); + } + if ($tokenElement instanceof \DOMElement) { + $this->csrfToken = $tokenElement->getAttribute("content"); + } return $documentXpath; } @@ -384,9 +433,10 @@ class KoinService */ private function getAccountId(\DOMXPath $documentXpath) { - /** @var \DOMElement $accountIdElement */ $accountIdElement = $documentXpath->query('//input[@id="transaction-account_id"]')->item(0); - $this->accountId = $accountIdElement->getAttribute("value"); + if ($accountIdElement instanceof \DOMElement) { + $this->accountId = $accountIdElement->getAttribute("value"); + } } /** @@ -397,7 +447,7 @@ class KoinService * @param string $tags * @return int */ - private function postData(string $amount, string $currency = 'HUF', string $date, string $category, string $tags): int + private function postData(string $amount, string $currency, string $date, string $category, string $tags): int { $saveResponse = $this->httpClient ->post(self::BASE_URI . "/main/save-transaction", [ diff --git a/src/App/Service/KoinServiceFactory.php b/src/App/Service/KoinServiceFactory.php index d784aa0..d9d7d51 100644 --- a/src/App/Service/KoinServiceFactory.php +++ b/src/App/Service/KoinServiceFactory.php @@ -1,22 +1,27 @@ true, - ]); - $config = $container->get('config'); - return new KoinService($httpClient, $config); - } + /** + * @param ContainerInterface $container + * @return KoinService + */ + public function __invoke(ContainerInterface $container) + { + $httpClient = new Client([ + 'cookies' => true, + ]); + $config = $container->get('config'); + $em = $container->get('doctrine.entity_manager.orm_default'); + + return new KoinService($httpClient, $config, $em); + } } diff --git a/src/App/Service/SZEPManagerService.php b/src/App/Service/SZEPManagerService.php index 533bfe0..597b4a4 100644 --- a/src/App/Service/SZEPManagerService.php +++ b/src/App/Service/SZEPManagerService.php @@ -1,5 +1,7 @@ setHash($hash) - ->setAmount($amount) + ->setAmount(intval($amount)) ->setMerchant($merchant) ->setPocket($pocket) ->setDate(new \DateTimeImmutable(str_replace(".", "-", $date))); @@ -150,7 +153,7 @@ class SZEPManagerService /** @var SZEPCardEntry $newRecord */ foreach ($newRecords as $newRecord) { $resultCode = $this->koinService->saveTransaction( - abs($newRecord->getAmount()), + (string)abs($newRecord->getAmount()), 'HUF', $newRecord->getDate()->format("Y-m-d"), $this->getCategory($newRecord), @@ -202,6 +205,8 @@ class SZEPManagerService $tags[] = 'Sushi'; } elseif (false !== strpos($SZEPCardEntry->getMerchant(), "Szentmihályi Uszoda")) { $tags[] = 'Tope'; + } elseif (false !== strpos($SZEPCardEntry->getMerchant(), "BME Sportközpont")) { + $tags[] = 'BME Sportközpont'; } switch ($SZEPCardEntry->getPocket()) { @@ -222,8 +227,8 @@ class SZEPManagerService */ private function encryptPayload(string $payload, $key = self::AES_KEY, $iv = self::IV_PARAM): string { - $aesKeyString = call_user_func_array("pack", array_merge(array("c*"), $key)); - $ivParamStr = call_user_func_array("pack", array_merge(array("c*"), $iv)); + $aesKeyString = call_user_func_array("pack", array_merge(["c*"], $key)); + $ivParamStr = call_user_func_array("pack", array_merge(["c*"], $iv)); return openssl_encrypt($payload, "AES-256-CBC", $aesKeyString, 0, $ivParamStr); } diff --git a/src/App/Service/SZEPManagerServiceFactory.php b/src/App/Service/SZEPManagerServiceFactory.php index a74e565..dd4a2ca 100644 --- a/src/App/Service/SZEPManagerServiceFactory.php +++ b/src/App/Service/SZEPManagerServiceFactory.php @@ -1,8 +1,10 @@ em = $em; - $this->eventManager = $eventManager; - } + /** @var EventManager */ + private $eventManager; - public function storeSms(string $hashKey, int $direction, array $requestData): bool - { - $normalizedDate = str_replace("at ", "", $requestData['when']); - $user = $this->ensureUserExists($hashKey); - $sms = new Sms(); - $sms->setDirection($direction) - ->setContactName($requestData['contactName']) - ->setContactNumber($requestData['contactNumber']) - ->setOccuredAt(new \DateTime($normalizedDate)) - ->setOwner($user) - ->setText($requestData['text']); - $this->em->persist($sms); - $this->em->flush(); + public function __construct(EntityManager $em, EventManager $eventManager) + { + $this->em = $em; + $this->eventManager = $eventManager; + } - $this->eventManager->trigger('store.sms.persisted', $this, [ - 'sms' => $sms, - ]); + /** + * @param string $hashKey + * @param int $direction + * @param array $requestData + * @return bool + * @throws \Doctrine\ORM\ORMException + * @throws \Doctrine\ORM\OptimisticLockException + */ + public function storeSms(string $hashKey, int $direction, array $requestData): bool + { + $normalizedDate = str_replace("at ", "", $requestData['when']); + $user = $this->ensureUserExists($hashKey); + $sms = new Sms(); + $sms->setDirection($direction) + ->setContactName($requestData['contactName']) + ->setContactNumber($requestData['contactNumber']) + ->setOccuredAt(new \DateTime($normalizedDate)) + ->setOwner($user) + ->setText($requestData['text']); + $this->em->persist($sms); + $this->em->flush(); - return true; - } + $this->eventManager->trigger('store.sms.persisted', $this, [ + 'sms' => $sms, + ]); + + return true; + } /** * @param string $hashKey @@ -49,20 +58,20 @@ class SmsStoreService * @throws \Doctrine\ORM\ORMException * @throws \Doctrine\ORM\OptimisticLockException */ - private function ensureUserExists(string $hashKey): User - { - /** @var User $user */ - $user = $this->em->getRepository(User::class)->findOneBy([ - 'hashKey' => $hashKey - ]); + private function ensureUserExists(string $hashKey): User + { + /** @var User $user */ + $user = $this->em->getRepository(User::class)->findOneBy([ + 'hashKey' => $hashKey + ]); - if($user === null) { - $user = new User(); - $user->setHashKey($hashKey)->setName("Unknown"); - $this->em->persist($user); - $this->em->flush(); + if ($user === null) { + $user = new User(); + $user->setHashKey($hashKey)->setName("Unknown"); + $this->em->persist($user); + $this->em->flush(); + } + + return $user; } - - return $user; - } } diff --git a/src/App/Service/SmsStoreServiceFactory.php b/src/App/Service/SmsStoreServiceFactory.php index d3bb410..821a4f3 100644 --- a/src/App/Service/SmsStoreServiceFactory.php +++ b/src/App/Service/SmsStoreServiceFactory.php @@ -1,13 +1,12 @@