diff --git a/.env.example b/.env.example new file mode 100644 index 000000000..9b46f29da --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +ELASTIC_HOST = localhost:9200 +ELASTIC_PASSWORD = secret_key \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..3095857d5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea/ +/vendor/ +.env \ No newline at end of file diff --git a/README.md b/README.md index e16b2a49b..ddfb06cb0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ -# PHP_2023 +Рефакторинг ДЗ № 11 (ElasticSearch): + -https://otus.ru/lessons/razrabotchik-php/?utm_source=github&utm_medium=free&utm_campaign=otus +## Пример запуска: +``` +php index.php --category роман --min-price 2000 --max-price 4000 рыцари +``` \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 000000000..2b4d4bc68 --- /dev/null +++ b/composer.json @@ -0,0 +1,22 @@ +{ + "name": "dimal/hw11", + "type": "project", + "autoload": { + "psr-4": { + "Dimal\\Hw11\\": "src/" + } + }, + "authors": [ + { + "name": "DmitryAleynik" + } + ], + "require": { + "elasticsearch/elasticsearch": "^8.11" + }, + "config": { + "allow-plugins": { + "php-http/discovery": true + } + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 000000000..eaf3ce3aa --- /dev/null +++ b/composer.lock @@ -0,0 +1,956 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "cce37ea75652f11b931f493299c1d88c", + "packages": [ + { + "name": "elastic/transport", + "version": "v8.8.0", + "source": { + "type": "git", + "url": "git@github.com:elastic/elastic-transport-php.git", + "reference": "cdf9f63a16ec6bfb4c881ab89aa0e2a61fb7c20b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/elastic/elastic-transport-php/zipball/cdf9f63a16ec6bfb4c881ab89aa0e2a61fb7c20b", + "reference": "cdf9f63a16ec6bfb4c881ab89aa0e2a61fb7c20b", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.0", + "php": "^7.4 || ^8.0", + "php-http/discovery": "^1.14", + "php-http/httplug": "^2.3", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0 || ^2.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "nyholm/psr7": "^1.5", + "php-http/mock-client": "^1.5", + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Elastic\\Transport\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "HTTP transport PHP library for Elastic products", + "keywords": [ + "PSR_17", + "elastic", + "http", + "psr-18", + "psr-7", + "transport" + ], + "time": "2023-11-08T10:51:51+00:00" + }, + { + "name": "elasticsearch/elasticsearch", + "version": "v8.11.0", + "source": { + "type": "git", + "url": "git@github.com:elastic/elasticsearch-php.git", + "reference": "4c16dc67788afdec63294f072999594d0fd14ebb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/elastic/elasticsearch-php/zipball/4c16dc67788afdec63294f072999594d0fd14ebb", + "reference": "4c16dc67788afdec63294f072999594d0fd14ebb", + "shasum": "" + }, + "require": { + "elastic/transport": "^8.8", + "guzzlehttp/guzzle": "^7.0", + "php": "^7.4 || ^8.0", + "psr/http-client": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "psr/log": "^1|^2|^3" + }, + "require-dev": { + "ext-yaml": "*", + "ext-zip": "*", + "mockery/mockery": "^1.5", + "nyholm/psr7": "^1.5", + "php-http/message-factory": "^1.1", + "php-http/mock-client": "^1.5", + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^9.5", + "symfony/finder": "~4.0", + "symfony/http-client": "^5.0|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Elastic\\Elasticsearch\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHP Client for Elasticsearch", + "keywords": [ + "client", + "elastic", + "elasticsearch", + "search" + ], + "time": "2023-11-11T09:01:22+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.8.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:35:24+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:19:20+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.6.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.6.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:05:35+00:00" + }, + { + "name": "php-http/discovery", + "version": "1.19.2", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "61e1a1eb69c92741f5896d9e05fb8e9d7e8bb0cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/61e1a1eb69c92741f5896d9e05fb8e9d7e8bb0cb", + "reference": "61e1a1eb69c92741f5896d9e05fb8e9d7e8bb0cb", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0", + "zendframework/zend-diactoros": "*" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "*", + "psr/http-factory-implementation": "*", + "psr/http-message-implementation": "*" + }, + "require-dev": { + "composer/composer": "^1.0.2|^2.0", + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", + "symfony/phpunit-bridge": "^6.2" + }, + "type": "composer-plugin", + "extra": { + "class": "Http\\Discovery\\Composer\\Plugin", + "plugin-optional": true + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + }, + "exclude-from-classmap": [ + "src/Composer/Plugin.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr17", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/1.19.2" + }, + "time": "2023-11-30T16:49:05+00:00" + }, + { + "name": "php-http/httplug", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/httplug.git", + "reference": "625ad742c360c8ac580fcc647a1541d29e257f67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/httplug/zipball/625ad742c360c8ac580fcc647a1541d29e257f67", + "reference": "625ad742c360c8ac580fcc647a1541d29e257f67", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/promise": "^1.1", + "psr/http-client": "^1.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.1 || ^5.0 || ^6.0", + "phpspec/phpspec": "^5.1 || ^6.0 || ^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eric GELOEN", + "email": "geloen.eric@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "HTTPlug, the HTTP client abstraction for PHP", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "http" + ], + "support": { + "issues": "https://github.com/php-http/httplug/issues", + "source": "https://github.com/php-http/httplug/tree/2.4.0" + }, + "time": "2023-04-14T15:10:03+00:00" + }, + { + "name": "php-http/promise", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/promise.git", + "reference": "44a67cb59f708f826f3bec35f22030b3edb90119" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/promise/zipball/44a67cb59f708f826f3bec35f22030b3edb90119", + "reference": "44a67cb59f708f826f3bec35f22030b3edb90119", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.3.2 || ^6.3", + "phpspec/phpspec": "^5.1.2 || ^6.2 || ^7.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joel Wurtz", + "email": "joel.wurtz@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Promise used for asynchronous HTTP requests", + "homepage": "http://httplug.io", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/php-http/promise/issues", + "source": "https://github.com/php-http/promise/tree/1.2.1" + }, + "time": "2023-11-08T12:57:08+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + }, + "time": "2023-04-10T20:10:41+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/index.php b/index.php new file mode 100644 index 000000000..802513eee --- /dev/null +++ b/index.php @@ -0,0 +1,10 @@ +run($argv); diff --git a/src/App.php b/src/App.php new file mode 100644 index 000000000..9c528e753 --- /dev/null +++ b/src/App.php @@ -0,0 +1,34 @@ +useCase = 'Dimal\Hw11\Application\UseCase\ConsoleSearchUseCase'; + $this->boookRepo = new ElastickBookRepository(); + $this->tableView = new ConsoleTableView(); + $this->inputSearchQuery = new ConsoleInputSearchQuery(); + } + + public function run(array $params): void + { + $useCase = new $this->useCase(); + $useCase($this->boookRepo, $this->tableView, $this->inputSearchQuery, $params); + } +} diff --git a/src/Application/InputSearchQueryInterface.php b/src/Application/InputSearchQueryInterface.php new file mode 100644 index 000000000..0b59398b0 --- /dev/null +++ b/src/Application/InputSearchQueryInterface.php @@ -0,0 +1,8 @@ +min_price = $min_price; + $this->max_price = $max_price; + $this->category = $category; + $this->title = $title; + } + + public function getTitle(): Title + { + return $this->title; + } + + public function getMinPrice(): Price + { + return $this->min_price; + } + + public function getMaxPrice(): Price + { + return $this->max_price; + } + + public function getCategory(): Category + { + return $this->category; + } +} diff --git a/src/Application/TableViewInterface.php b/src/Application/TableViewInterface.php new file mode 100644 index 000000000..a49138c03 --- /dev/null +++ b/src/Application/TableViewInterface.php @@ -0,0 +1,10 @@ +show($bookRepo->search($consoleInputSearchQuery($params))); + } +} diff --git a/src/Domain/Entity/Book.php b/src/Domain/Entity/Book.php new file mode 100644 index 000000000..8e03cb6b9 --- /dev/null +++ b/src/Domain/Entity/Book.php @@ -0,0 +1,56 @@ +id = $id; + $this->title = $title; + $this->category = $category; + $this->price = $price; + $this->stockCount = $stockCount; + } + + public function getId(): Id + { + return $this->id; + } + + public function getTitle(): Title + { + return $this->title; + } + + public function getPrice(): Price + { + return $this->price; + } + + public function getCategory(): Category + { + return $this->category; + } + + public function getStockCount(): array + { + return $this->stockCount; + } +} diff --git a/src/Domain/Entity/StockShopCount.php b/src/Domain/Entity/StockShopCount.php new file mode 100644 index 000000000..97bf51a4a --- /dev/null +++ b/src/Domain/Entity/StockShopCount.php @@ -0,0 +1,28 @@ +shop = $shop; + $this->stockCount = $stockCount; + } + + public function getShop(): Shop + { + return $this->shop; + } + + public function getStockCount(): StockCount + { + return $this->stockCount; + } +} diff --git a/src/Domain/Repository/BookRepositoryInterface.php b/src/Domain/Repository/BookRepositoryInterface.php new file mode 100644 index 000000000..6efd0a2f1 --- /dev/null +++ b/src/Domain/Repository/BookRepositoryInterface.php @@ -0,0 +1,15 @@ +name = $name; + } + + public function getName(): string + { + return $this->name; + } +} diff --git a/src/Domain/ValueObject/Id.php b/src/Domain/ValueObject/Id.php new file mode 100644 index 000000000..32b13766a --- /dev/null +++ b/src/Domain/ValueObject/Id.php @@ -0,0 +1,18 @@ +id = $id; + } + + public function getId(): string + { + return $this->id; + } +} diff --git a/src/Domain/ValueObject/Price.php b/src/Domain/ValueObject/Price.php new file mode 100644 index 000000000..81f2aad8a --- /dev/null +++ b/src/Domain/ValueObject/Price.php @@ -0,0 +1,23 @@ +price = $price; + } + + public function getPrice(): ?float + { + return $this->price; + } + + public function getFormattedPrice(): string + { + return $this->price ? number_format($this->price, 2, ',', ' ') : ''; + } +} diff --git a/src/Domain/ValueObject/Shop.php b/src/Domain/ValueObject/Shop.php new file mode 100644 index 000000000..ca9f9c656 --- /dev/null +++ b/src/Domain/ValueObject/Shop.php @@ -0,0 +1,18 @@ +name = $name; + } + + public function getName(): string + { + return $this->name; + } +} diff --git a/src/Domain/ValueObject/StockCount.php b/src/Domain/ValueObject/StockCount.php new file mode 100644 index 000000000..4c391e880 --- /dev/null +++ b/src/Domain/ValueObject/StockCount.php @@ -0,0 +1,18 @@ +count = $count; + } + + public function getCount(): int + { + return $this->count; + } +} diff --git a/src/Domain/ValueObject/Title.php b/src/Domain/ValueObject/Title.php new file mode 100644 index 000000000..380556807 --- /dev/null +++ b/src/Domain/ValueObject/Title.php @@ -0,0 +1,18 @@ +title = $title; + } + + public function getTitle(): string + { + return $this->title; + } +} diff --git a/src/Infrastructure/Console/ConsoleInputSearchQuery.php b/src/Infrastructure/Console/ConsoleInputSearchQuery.php new file mode 100644 index 000000000..86c253a7c --- /dev/null +++ b/src/Infrastructure/Console/ConsoleInputSearchQuery.php @@ -0,0 +1,51 @@ +setHosts([$conf['ELASTIC_HOST']]); + if ($conf['ELASTIC_PASSWORD']) { + $cl->setApiKey($conf['ELASTIC_PASSWORD']); + } + $cl = $cl->build(); + $this->client = $cl; + } + + public function add(Book $book): void + { + $this->books[] = $book; + } + + public function search(SearchQueryDTO $searchQuery): array + { + $results = $this->client->search($this->makeSearchParams($searchQuery)); + + $this->books = []; + + foreach ($results['hits']['hits'] as $item) { + $source = $item['_source']; + + $stockCount = []; + foreach ($source['stock'] as $stock) { + $stockCount[] = new StockShopCount( + new Shop($stock['shop']), + new StockCount($stock['stock']) + ); + } + + $book = new Book( + new Id($source['sku']), + new Title($source['title']), + new Category($source['category']), + new Price($source['price']), + $stockCount + ); + + array_push($this->books, $book); + } + + return $this->books; + } + + public function getAll(): array + { + return $this->books; + } + + private function makeSearchParams(SearchQueryDTO $searchQuery): array + { + $query = [ + 'must' => [ + 'match' => [ + 'title' => [ + "query" => $searchQuery->getTitle()->getTitle(), + 'fuzziness' => "auto" + ] + ], + ] + ]; + + if ($searchQuery->getCategory()->getName()) { + $query['filter'] = [ + 'term' => [ + 'category' => $searchQuery->getCategory()->getName() + ], + ]; + } + + if ($searchQuery->getMinPrice()->getPrice() || $searchQuery->getMaxPrice()->getPrice()) { + $range = []; + if ($searchQuery->getMinPrice()->getPrice()) { + $range['gte'] = $searchQuery->getMinPrice()->getPrice(); + } + + if ($searchQuery->getMaxPrice()->getPrice()) { + $range['lte'] = $searchQuery->getMaxPrice()->getPrice(); + } + $query['should'] = [ + 'range' => ['price' => $range] + ]; + } + + $params = [ + 'index' => 'otus-shop', + 'size' => 20, + 'body' => [ + 'query' => [ + 'bool' => $query + ] + ] + ]; + + return $params; + } +} diff --git a/src/Presentation/ConsoleTableView.php b/src/Presentation/ConsoleTableView.php new file mode 100644 index 000000000..6c8c99758 --- /dev/null +++ b/src/Presentation/ConsoleTableView.php @@ -0,0 +1,148 @@ +cols = [ + 'category' => ['title' => 'Категория', 'width' => 20], + 'title' => ['title' => 'Наименование', 'width' => 50], + 'id' => ['title' => 'sku', 'width' => 10], + 'price' => ['title' => 'Цена', 'width' => 10], + 'avail' => ['title' => 'Наличие', 'width' => 25] + ]; + } + + + private function setRows($rows): void + { + $this->rows = $rows; + } + + public function show(array $books): void + { + + $rows = []; + foreach ($books as $book) { + /** @var Book $book */ + + $availStr = ''; + foreach ($book->getStockCount() as $stockShopCount) { + /** @var StockShopCount $stockShopCount */ + $availStr .= $stockShopCount->getShop()->getName() . ': ' . $stockShopCount->getStockCount()->getCount() . ', '; + } + $availStr = substr($availStr, 0, -2); + + $row = [ + 'category' => $book->getCategory()->getName(), + 'title' => $book->getTitle()->getTitle(), + 'id' => $book->getId()->getId(), + 'price' => $book->getPrice()->getFormattedPrice(), + 'avail' => $availStr + ]; + + array_push($rows, $row); + } + + + $this->setRows($rows); + $this->showTableHeader(); + $this->showTableBody(); + $this->showTableFooter(); + } + + private function showTableHeader(): void + { + echo PHP_EOL; + foreach ($this->cols as $c) { + echo "+" . str_repeat('-', $c['width']); + } + echo "+" . PHP_EOL; + + foreach ($this->cols as $c) { + echo "| " . self::mbStrPad($c['title'], $c['width'] - 1); + } + echo "|" . PHP_EOL; + + foreach ($this->cols as $c) { + echo "+" . str_repeat('-', $c['width']); + } + echo "+" . PHP_EOL; + } + + private function showTableBody(): void + { + foreach ($this->rows as $row) { + foreach ($this->cols as $col_name => $col) { + echo "| " . self::mbStrPad($row[$col_name], $col['width'] - 1); + } + + echo "|" . PHP_EOL; + } + } + + private function showTableFooter(): void + { + foreach ($this->cols as $c) { + echo "+" . str_repeat('-', $c['width']); + } + echo "+" . PHP_EOL; + } + + + private static function mbStrPad($input, $pad_length, $pad_string = ' ', $pad_type = STR_PAD_RIGHT, $encoding = 'UTF-8'): string + { + $input_length = mb_strlen($input, $encoding); + $pad_string_length = mb_strlen($pad_string, $encoding); + + + if ($input_length > $pad_length) { + $result = mb_substr($input, 0, $pad_length, $encoding); + return $result; + } + + if ($pad_length <= 0 || ($pad_length - $input_length) <= 0) { + //return $input; + } + + $num_pad_chars = $pad_length - $input_length; + + switch ($pad_type) { + case STR_PAD_RIGHT: + $left_pad = 0; + $right_pad = $num_pad_chars; + break; + + case STR_PAD_LEFT: + $left_pad = $num_pad_chars; + $right_pad = 0; + break; + + case STR_PAD_BOTH: + $left_pad = floor($num_pad_chars / 2); + $right_pad = $num_pad_chars - $left_pad; + break; + } + + $result = ''; + for ($i = 0; $i < $left_pad; ++$i) { + $result .= mb_substr($pad_string, $i % $pad_string_length, 1, $encoding); + } + $result .= $input; + for ($i = 0; $i < $right_pad; ++$i) { + $result .= mb_substr($pad_string, $i % $pad_string_length, 1, $encoding); + } + + + return $result; + } +}