Elastic search
This commit is contained in:
parent
c457b98b8e
commit
71d6198e03
|
|
@ -10,10 +10,12 @@
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.1",
|
"php": "^8.1",
|
||||||
"astrotomic/laravel-translatable": "^11.0.0",
|
"astrotomic/laravel-translatable": "^11.0.0",
|
||||||
|
"bagisto/laravel-datafaker": "^2.0@alpha",
|
||||||
"bagisto/rest-api": "^1.0",
|
"bagisto/rest-api": "^1.0",
|
||||||
"bagistobrasil/bagisto-product-social-share": "^0.1.2",
|
"bagistobrasil/bagisto-product-social-share": "^0.1.2",
|
||||||
"barryvdh/laravel-debugbar": "^3.1",
|
"barryvdh/laravel-debugbar": "^3.1",
|
||||||
"barryvdh/laravel-dompdf": "^2.0.0",
|
"barryvdh/laravel-dompdf": "^2.0.0",
|
||||||
|
"cviebrock/laravel-elasticsearch": "^9.0",
|
||||||
"diglactic/laravel-breadcrumbs": "^7.0",
|
"diglactic/laravel-breadcrumbs": "^7.0",
|
||||||
"doctrine/dbal": "^2.9",
|
"doctrine/dbal": "^2.9",
|
||||||
"enshrined/svg-sanitize": "^0.15.0",
|
"enshrined/svg-sanitize": "^0.15.0",
|
||||||
|
|
@ -27,7 +29,6 @@
|
||||||
"konekt/concord": "^1.2",
|
"konekt/concord": "^1.2",
|
||||||
"laravel/framework": "^9.0",
|
"laravel/framework": "^9.0",
|
||||||
"laravel/sanctum": "^2.12",
|
"laravel/sanctum": "^2.12",
|
||||||
"laravel/scout": "^9.0",
|
|
||||||
"laravel/socialite": "^5.0",
|
"laravel/socialite": "^5.0",
|
||||||
"laravel/tinker": "^2.0",
|
"laravel/tinker": "^2.0",
|
||||||
"laravel/ui": "^3.0",
|
"laravel/ui": "^3.0",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "24a0dc2b81de04eed28797f623305a33",
|
"content-hash": "f97b453abb0e5218dd71c940aaa63d00",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "astrotomic/laravel-translatable",
|
"name": "astrotomic/laravel-translatable",
|
||||||
|
|
@ -97,6 +97,59 @@
|
||||||
],
|
],
|
||||||
"time": "2022-02-05T10:42:52+00:00"
|
"time": "2022-02-05T10:42:52+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "bagisto/laravel-datafaker",
|
||||||
|
"version": "v2.0.0-ALPHA1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/bagisto/laravel-data-faker.git",
|
||||||
|
"reference": "09c3587a6cef80e84ddc16ea30cd2f0ade1d09b2"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/bagisto/laravel-data-faker/zipball/09c3587a6cef80e84ddc16ea30cd2f0ade1d09b2",
|
||||||
|
"reference": "09c3587a6cef80e84ddc16ea30cd2f0ade1d09b2",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"Webkul\\Faker\\Providers\\FakerServiceProvider"
|
||||||
|
],
|
||||||
|
"aliases": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Webkul\\Faker\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jitendra Singh",
|
||||||
|
"email": "jitendra@webkul.in",
|
||||||
|
"homepage": "https://bagisto.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Create fake customers, categories and products in Bagisto.",
|
||||||
|
"homepage": "https://github.com/bagisto/laravel-data-faker",
|
||||||
|
"keywords": [
|
||||||
|
"bagisto",
|
||||||
|
"fake categories",
|
||||||
|
"fake customers",
|
||||||
|
"fake products"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/bagisto/laravel-data-faker/issues",
|
||||||
|
"source": "https://github.com/bagisto/laravel-data-faker/tree/v2.0.0-ALPHA1"
|
||||||
|
},
|
||||||
|
"time": "2022-10-14T10:10:16+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "bagisto/rest-api",
|
"name": "bagisto/rest-api",
|
||||||
"version": "v1.0.0",
|
"version": "v1.0.0",
|
||||||
|
|
@ -405,6 +458,84 @@
|
||||||
],
|
],
|
||||||
"time": "2021-08-15T20:50:18+00:00"
|
"time": "2021-08-15T20:50:18+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "cviebrock/laravel-elasticsearch",
|
||||||
|
"version": "9.0.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/cviebrock/laravel-elasticsearch.git",
|
||||||
|
"reference": "e638493bb3a4d75a2a62b9d0db6234b8a5684917"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/cviebrock/laravel-elasticsearch/zipball/e638493bb3a4d75a2a62b9d0db6234b8a5684917",
|
||||||
|
"reference": "e638493bb3a4d75a2a62b9d0db6234b8a5684917",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"elasticsearch/elasticsearch": "^7.11",
|
||||||
|
"ext-json": "*",
|
||||||
|
"guzzlehttp/psr7": "^1.7|^2.0",
|
||||||
|
"illuminate/contracts": "^7.0|^8.0|^9.0",
|
||||||
|
"illuminate/support": "^7.0|^8.0|^9.0",
|
||||||
|
"php": "^7.3|^8.0",
|
||||||
|
"psr/http-message": "^1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"limedeck/phpunit-detailed-printer": "^6.0",
|
||||||
|
"mockery/mockery": "^1.4.3",
|
||||||
|
"orchestra/testbench": "^6.5|^7.0",
|
||||||
|
"phpunit/phpunit": "^9.4"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"aws/aws-sdk-php": "Required to connect to an Elasticsearch host on AWS (^3.80)"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"Cviebrock\\LaravelElasticsearch\\ServiceProvider"
|
||||||
|
],
|
||||||
|
"aliases": {
|
||||||
|
"Elasticsearch": "Cviebrock\\LaravelElasticsearch\\Facade"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Cviebrock\\LaravelElasticsearch\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Colin Viebrock",
|
||||||
|
"email": "colin@viebrock.ca"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "An easy way to use the official PHP ElasticSearch client in your Laravel applications.",
|
||||||
|
"homepage": "https://github.com/cviebrock/laravel-elasticsearch",
|
||||||
|
"keywords": [
|
||||||
|
"client",
|
||||||
|
"elasticsearch",
|
||||||
|
"laravel",
|
||||||
|
"search"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/cviebrock/laravel-elasticsearch/issues",
|
||||||
|
"source": "https://github.com/cviebrock/laravel-elasticsearch/tree/9.0.2"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/cviebrock",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2022-07-19T02:25:49+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "dflydev/dot-access-data",
|
"name": "dflydev/dot-access-data",
|
||||||
"version": "v3.0.1",
|
"version": "v3.0.1",
|
||||||
|
|
@ -1256,6 +1387,69 @@
|
||||||
],
|
],
|
||||||
"time": "2022-06-18T20:57:19+00:00"
|
"time": "2022-06-18T20:57:19+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "elasticsearch/elasticsearch",
|
||||||
|
"version": "v7.17.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git@github.com:elastic/elasticsearch-php.git",
|
||||||
|
"reference": "f1b8918f411b837ce5f6325e829a73518fd50367"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/elastic/elasticsearch-php/zipball/f1b8918f411b837ce5f6325e829a73518fd50367",
|
||||||
|
"reference": "f1b8918f411b837ce5f6325e829a73518fd50367",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-json": ">=1.3.7",
|
||||||
|
"ezimuel/ringphp": "^1.1.2",
|
||||||
|
"php": "^7.3 || ^8.0",
|
||||||
|
"psr/log": "^1|^2|^3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-yaml": "*",
|
||||||
|
"ext-zip": "*",
|
||||||
|
"mockery/mockery": "^1.2",
|
||||||
|
"phpstan/phpstan": "^0.12",
|
||||||
|
"phpunit/phpunit": "^9.3",
|
||||||
|
"squizlabs/php_codesniffer": "^3.4",
|
||||||
|
"symfony/finder": "~4.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-curl": "*",
|
||||||
|
"monolog/monolog": "Allows for client-level logging and tracing"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"src/autoload.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Elasticsearch\\": "src/Elasticsearch/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"Apache-2.0",
|
||||||
|
"LGPL-2.1-only"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Zachary Tong"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Enrico Zimuel"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP Client for Elasticsearch",
|
||||||
|
"keywords": [
|
||||||
|
"client",
|
||||||
|
"elasticsearch",
|
||||||
|
"search"
|
||||||
|
],
|
||||||
|
"time": "2022-09-30T12:28:55+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "enshrined/svg-sanitize",
|
"name": "enshrined/svg-sanitize",
|
||||||
"version": "0.15.4",
|
"version": "0.15.4",
|
||||||
|
|
@ -1301,6 +1495,116 @@
|
||||||
},
|
},
|
||||||
"time": "2022-02-21T09:13:59+00:00"
|
"time": "2022-02-21T09:13:59+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "ezimuel/guzzlestreams",
|
||||||
|
"version": "3.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/ezimuel/guzzlestreams.git",
|
||||||
|
"reference": "abe3791d231167f14eb80d413420d1eab91163a8"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/ezimuel/guzzlestreams/zipball/abe3791d231167f14eb80d413420d1eab91163a8",
|
||||||
|
"reference": "abe3791d231167f14eb80d413420d1eab91163a8",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.4.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~4.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.0-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"GuzzleHttp\\Stream\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Michael Dowling",
|
||||||
|
"email": "mtdowling@gmail.com",
|
||||||
|
"homepage": "https://github.com/mtdowling"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Fork of guzzle/streams (abandoned) to be used with elasticsearch-php",
|
||||||
|
"homepage": "http://guzzlephp.org/",
|
||||||
|
"keywords": [
|
||||||
|
"Guzzle",
|
||||||
|
"stream"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/ezimuel/guzzlestreams/tree/3.0.1"
|
||||||
|
},
|
||||||
|
"time": "2020-02-14T23:11:50+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ezimuel/ringphp",
|
||||||
|
"version": "1.2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/ezimuel/ringphp.git",
|
||||||
|
"reference": "92b8161404ab1ad84059ebed41d9f757e897ce74"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/ezimuel/ringphp/zipball/92b8161404ab1ad84059ebed41d9f757e897ce74",
|
||||||
|
"reference": "92b8161404ab1ad84059ebed41d9f757e897ce74",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ezimuel/guzzlestreams": "^3.0.1",
|
||||||
|
"php": ">=5.4.0",
|
||||||
|
"react/promise": "~2.0"
|
||||||
|
},
|
||||||
|
"replace": {
|
||||||
|
"guzzlehttp/ringphp": "self.version"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-curl": "*",
|
||||||
|
"phpunit/phpunit": "~9.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-curl": "Guzzle will use specific adapters if cURL is present"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.1-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"GuzzleHttp\\Ring\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Michael Dowling",
|
||||||
|
"email": "mtdowling@gmail.com",
|
||||||
|
"homepage": "https://github.com/mtdowling"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Fork of guzzle/RingPHP (abandoned) to be used with elasticsearch-php",
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/ezimuel/ringphp/tree/1.2.0"
|
||||||
|
},
|
||||||
|
"time": "2021-11-16T11:51:30+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "ezyang/htmlpurifier",
|
"name": "ezyang/htmlpurifier",
|
||||||
"version": "v4.14.0",
|
"version": "v4.14.0",
|
||||||
|
|
@ -2687,78 +2991,6 @@
|
||||||
},
|
},
|
||||||
"time": "2022-04-08T13:39:49+00:00"
|
"time": "2022-04-08T13:39:49+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "laravel/scout",
|
|
||||||
"version": "v9.4.9",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/laravel/scout.git",
|
|
||||||
"reference": "61ce79ce87fbebb28dcc0dd8f95776aa0dec00c8"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/laravel/scout/zipball/61ce79ce87fbebb28dcc0dd8f95776aa0dec00c8",
|
|
||||||
"reference": "61ce79ce87fbebb28dcc0dd8f95776aa0dec00c8",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"illuminate/bus": "^8.0|^9.0",
|
|
||||||
"illuminate/contracts": "^8.0|^9.0",
|
|
||||||
"illuminate/database": "^8.0|^9.0",
|
|
||||||
"illuminate/http": "^8.0|^9.0",
|
|
||||||
"illuminate/pagination": "^8.0|^9.0",
|
|
||||||
"illuminate/queue": "^8.0|^9.0",
|
|
||||||
"illuminate/support": "^8.0|^9.0",
|
|
||||||
"php": "^7.3|^8.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"meilisearch/meilisearch-php": "^0.19",
|
|
||||||
"mockery/mockery": "^1.0",
|
|
||||||
"orchestra/testbench": "^6.17|^7.0",
|
|
||||||
"phpunit/phpunit": "^9.3"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"algolia/algoliasearch-client-php": "Required to use the Algolia engine (^3.2).",
|
|
||||||
"meilisearch/meilisearch-php": "Required to use the MeiliSearch engine (^0.23)."
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "9.x-dev"
|
|
||||||
},
|
|
||||||
"laravel": {
|
|
||||||
"providers": [
|
|
||||||
"Laravel\\Scout\\ScoutServiceProvider"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Laravel\\Scout\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Taylor Otwell",
|
|
||||||
"email": "taylor@laravel.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Laravel Scout provides a driver based solution to searching your Eloquent models.",
|
|
||||||
"keywords": [
|
|
||||||
"algolia",
|
|
||||||
"laravel",
|
|
||||||
"search"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/laravel/scout/issues",
|
|
||||||
"source": "https://github.com/laravel/scout"
|
|
||||||
},
|
|
||||||
"time": "2022-05-05T14:24:18+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "laravel/serializable-closure",
|
"name": "laravel/serializable-closure",
|
||||||
"version": "v1.2.0",
|
"version": "v1.2.0",
|
||||||
|
|
@ -5802,6 +6034,82 @@
|
||||||
],
|
],
|
||||||
"time": "2022-03-27T21:42:02+00:00"
|
"time": "2022-03-27T21:42:02+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "react/promise",
|
||||||
|
"version": "v2.9.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/reactphp/promise.git",
|
||||||
|
"reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/reactphp/promise/zipball/234f8fd1023c9158e2314fa9d7d0e6a83db42910",
|
||||||
|
"reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.4.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"src/functions_include.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"React\\Promise\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jan Sorgalla",
|
||||||
|
"email": "jsorgalla@gmail.com",
|
||||||
|
"homepage": "https://sorgalla.com/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Christian Lück",
|
||||||
|
"email": "christian@clue.engineering",
|
||||||
|
"homepage": "https://clue.engineering/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Cees-Jan Kiewiet",
|
||||||
|
"email": "reactphp@ceesjankiewiet.nl",
|
||||||
|
"homepage": "https://wyrihaximus.net/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Chris Boden",
|
||||||
|
"email": "cboden@gmail.com",
|
||||||
|
"homepage": "https://cboden.dev/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A lightweight implementation of CommonJS Promises/A for PHP",
|
||||||
|
"keywords": [
|
||||||
|
"promise",
|
||||||
|
"promises"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/reactphp/promise/issues",
|
||||||
|
"source": "https://github.com/reactphp/promise/tree/v2.9.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/WyriHaximus",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/clue",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2022-02-11T10:27:51+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "sabberworm/php-css-parser",
|
"name": "sabberworm/php-css-parser",
|
||||||
"version": "8.4.0",
|
"version": "8.4.0",
|
||||||
|
|
@ -12361,6 +12669,7 @@
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
"stability-flags": {
|
"stability-flags": {
|
||||||
|
"bagisto/laravel-datafaker": 15,
|
||||||
"flynsarmy/db-blade-compiler": 20,
|
"flynsarmy/db-blade-compiler": 20,
|
||||||
"codeception/codeception": 20,
|
"codeception/codeception": 20,
|
||||||
"codeception/module-laravel": 20
|
"codeception/module-laravel": 20
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,210 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/**
|
||||||
|
* You can specify one of several different connections when building an
|
||||||
|
* Elasticsearch client.
|
||||||
|
*
|
||||||
|
* Here you may specify which of the connections below you wish to use
|
||||||
|
* as your default connection when building an client. Of course you may
|
||||||
|
* use create several clients at once, each with different configurations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'defaultConnection' => 'default',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These are the connection parameters used when building a client.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'connections' => [
|
||||||
|
|
||||||
|
'default' => [
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hosts
|
||||||
|
*
|
||||||
|
* This is an array of hosts that the client will connect to. It can be a
|
||||||
|
* single host, or an array if you are running a cluster of Elasticsearch
|
||||||
|
* instances.
|
||||||
|
*
|
||||||
|
* This is the only configuration value that is mandatory.
|
||||||
|
*
|
||||||
|
* Presently using "extended" host configuration method
|
||||||
|
*
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_extended_host_configuration
|
||||||
|
*
|
||||||
|
* There is also the shorter "inline" configuration method available
|
||||||
|
*
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_inline_host_configuration
|
||||||
|
*/
|
||||||
|
|
||||||
|
'hosts' => [
|
||||||
|
[
|
||||||
|
'host' => env('ELASTICSEARCH_HOST', 'localhost'),
|
||||||
|
// For local development, the default Elasticsearch port is 9200.
|
||||||
|
// If you are connecting to an Elasticsearch instance on AWS, you probably want to set this to null
|
||||||
|
'port' => env('ELASTICSEARCH_PORT', 9200),
|
||||||
|
'scheme' => env('ELASTICSEARCH_SCHEME', null),
|
||||||
|
'user' => env('ELASTICSEARCH_USER', null),
|
||||||
|
'pass' => env('ELASTICSEARCH_PASS', null),
|
||||||
|
|
||||||
|
// If you are connecting to an Elasticsearch instance on AWS, you will need these values as well
|
||||||
|
'aws' => env('AWS_ELASTICSEARCH_ENABLED', false),
|
||||||
|
'aws_region' => env('AWS_REGION', ''),
|
||||||
|
'aws_key' => env('AWS_ACCESS_KEY_ID', ''),
|
||||||
|
'aws_secret' => env('AWS_SECRET_ACCESS_KEY', ''),
|
||||||
|
'aws_credentials' => null,
|
||||||
|
'aws_session_token' => env('AWS_SESSION_TOKEN', null),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSL
|
||||||
|
*
|
||||||
|
* If your Elasticsearch instance uses an out-dated or self-signed SSL
|
||||||
|
* certificate, you will need to pass in the certificate bundle. This can
|
||||||
|
* either be the path to the certificate file (for self-signed certs), or a
|
||||||
|
* package like https://github.com/Kdyby/CurlCaBundle. See the documentation
|
||||||
|
* below for all the details.
|
||||||
|
*
|
||||||
|
* If you are using SSL instances, and the certificates are up-to-date and
|
||||||
|
* signed by a public certificate authority, then you can leave this null and
|
||||||
|
* just use "https" in the host path(s) above and you should be fine.
|
||||||
|
*
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_security.html#_ssl_encryption_2
|
||||||
|
*/
|
||||||
|
|
||||||
|
'sslVerification' => null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logging
|
||||||
|
*
|
||||||
|
* Logging is handled by passing in an instance of Monolog\Logger (which
|
||||||
|
* coincidentally is what Laravel's default logger is).
|
||||||
|
*
|
||||||
|
* If logging is enabled, you either need to set the path and log level
|
||||||
|
* (some defaults are given for you below), or you can use a custom logger by
|
||||||
|
* setting 'logObject' to an instance of Psr\Log\LoggerInterface. In fact,
|
||||||
|
* if you just want to use the default Laravel logger, then set 'logObject'
|
||||||
|
* to \Log::getMonolog().
|
||||||
|
*
|
||||||
|
* Note: 'logObject' takes precedent over 'logPath'/'logLevel', so set
|
||||||
|
* 'logObject' null if you just want file-based logging to a custom path.
|
||||||
|
*
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#enabling_logger
|
||||||
|
*/
|
||||||
|
|
||||||
|
'logging' => false,
|
||||||
|
|
||||||
|
// If you have an existing instance of Monolog you can use it here.
|
||||||
|
// 'logObject' => \Log::getMonolog(),
|
||||||
|
|
||||||
|
'logPath' => storage_path('logs/elasticsearch.log'),
|
||||||
|
|
||||||
|
'logLevel' => Monolog\Logger::INFO,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retries
|
||||||
|
*
|
||||||
|
* By default, the client will retry n times, where n = number of nodes in
|
||||||
|
* your cluster. If you would like to disable retries, or change the number,
|
||||||
|
* you can do so here.
|
||||||
|
*
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_set_retries
|
||||||
|
*/
|
||||||
|
|
||||||
|
'retries' => null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The remainder of the configuration options can almost always be left
|
||||||
|
* as-is unless you have specific reasons to change them. Refer to the
|
||||||
|
* appropriate sections in the Elasticsearch documentation for what each option
|
||||||
|
* does and what values it expects.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sniff On Start
|
||||||
|
*
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
'sniffOnStart' => false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP Handler
|
||||||
|
*
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_configure_the_http_handler
|
||||||
|
* @see http://ringphp.readthedocs.org/en/latest/client_handlers.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
'httpHandler' => null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection Pool
|
||||||
|
*
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_setting_the_connection_pool
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_connection_pool.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
'connectionPool' => null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection Selector
|
||||||
|
*
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_setting_the_connection_selector
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_selectors.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
'connectionSelector' => null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializer
|
||||||
|
*
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_setting_the_serializer
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_serializers.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
'serializer' => null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection Factory
|
||||||
|
*
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_setting_a_custom_connectionfactory
|
||||||
|
*/
|
||||||
|
|
||||||
|
'connectionFactory' => null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint
|
||||||
|
*
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/6.0/_configuration.html#_set_the_endpoint_closure
|
||||||
|
*/
|
||||||
|
|
||||||
|
'endpoint' => null,
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register additional namespaces
|
||||||
|
*
|
||||||
|
* An array of additional namespaces to register.
|
||||||
|
*
|
||||||
|
* @example 'namespaces' => [XPack::Security(), XPack::Watcher()]
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/ElasticsearchPHP_Endpoints.html#Elasticsearch_ClientBuilderregisterNamespace_registerNamespace
|
||||||
|
*/
|
||||||
|
'namespaces' => [],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracer
|
||||||
|
*
|
||||||
|
* Tracer is handled by passing in a name of the class implements Psr\Log\LoggerInterface.
|
||||||
|
*
|
||||||
|
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_setting_a_custom_connectionfactory
|
||||||
|
*/
|
||||||
|
'tracer' => null,
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
||||||
|
|
@ -41,7 +41,7 @@ class Indexer extends Command
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
$indexers = ['price', 'inventory'];
|
$indexers = ['inventory', 'price', 'elastic'];
|
||||||
|
|
||||||
if (! empty($this->option('type'))) {
|
if (! empty($this->option('type'))) {
|
||||||
$indexers = $this->option('type');
|
$indexers = $this->option('type');
|
||||||
|
|
|
||||||
|
|
@ -2,33 +2,33 @@
|
||||||
|
|
||||||
namespace Webkul\Product\Helpers;
|
namespace Webkul\Product\Helpers;
|
||||||
|
|
||||||
use Webkul\Core\Repositories\ChannelRepository;
|
|
||||||
use Webkul\Customer\Repositories\CustomerGroupRepository;
|
use Webkul\Customer\Repositories\CustomerGroupRepository;
|
||||||
use Webkul\Product\Repositories\ProductPriceIndexRepository;
|
use Webkul\Product\Repositories\ProductPriceIndexRepository;
|
||||||
use Webkul\Product\Repositories\ProductInventoryIndexRepository;
|
use Webkul\Product\Repositories\ProductInventoryIndexRepository;
|
||||||
use Webkul\Product\Helpers\Indexers\Flat\Product as FlatIndexer;
|
use Webkul\Product\Helpers\Indexers\Flat\Product as FlatIndexer;
|
||||||
use Webkul\Product\Helpers\Indexers\Inventory\Product as InventoryIndexer;
|
use Webkul\Product\Helpers\Indexers\Inventory\Product as InventoryIndexer;
|
||||||
|
use Webkul\Product\Helpers\Indexers\ElasticSearch\Product as ElasticSearchIndexer;
|
||||||
|
|
||||||
class Indexer
|
class Indexer
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Create a new command instance.
|
* Create a new command instance.
|
||||||
*
|
*
|
||||||
* @param \Webkul\Core\Repositories\ChannelRepository $channelRepository
|
|
||||||
* @param \Webkul\Customer\Repositories\CustomerGroupRepository $customerGroupRepository
|
* @param \Webkul\Customer\Repositories\CustomerGroupRepository $customerGroupRepository
|
||||||
* @param \Webkul\Product\Repositories\ProductPriceIndexRepository $productPriceIndexRepository
|
* @param \Webkul\Product\Repositories\ProductPriceIndexRepository $productPriceIndexRepository
|
||||||
* @param \Webkul\Product\Repositories\ProductInventoryIndexRepository $productInventoryIndexRepository
|
* @param \Webkul\Product\Repositories\ProductInventoryIndexRepository $productInventoryIndexRepository
|
||||||
* @param \Webkul\Product\Helpers\Indexers\Flat\Product $flatIndexer
|
* @param \Webkul\Product\Helpers\Indexers\Flat\Product $flatIndexer
|
||||||
* @param \Webkul\Product\Helpers\Indexers\Inventory\Product $inventoryIndexer
|
* @param \Webkul\Product\Helpers\Indexers\Inventory\Product $inventoryIndexer
|
||||||
|
* @param \Webkul\Product\Helpers\Indexers\ElasticSearch\Product $elasticSearchIndexer
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected ChannelRepository $channelRepository,
|
|
||||||
protected CustomerGroupRepository $customerGroupRepository,
|
protected CustomerGroupRepository $customerGroupRepository,
|
||||||
protected ProductPriceIndexRepository $productPriceIndexRepository,
|
protected ProductPriceIndexRepository $productPriceIndexRepository,
|
||||||
protected ProductInventoryIndexRepository $productInventoryIndexRepository,
|
protected ProductInventoryIndexRepository $productInventoryIndexRepository,
|
||||||
protected FlatIndexer $flatIndexer,
|
protected FlatIndexer $flatIndexer,
|
||||||
protected InventoryIndexer $inventoryIndexer
|
protected InventoryIndexer $inventoryIndexer,
|
||||||
|
protected ElasticSearchIndexer $elasticSearchIndexer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -40,14 +40,18 @@ class Indexer
|
||||||
* @param array $indexers
|
* @param array $indexers
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function refresh($product, array $indexers = ['price', 'inventory'])
|
public function refresh($product, array $indexers = ['inventory', 'price', 'elastic'])
|
||||||
{
|
{
|
||||||
|
if (in_array('inventory', $indexers)) {
|
||||||
|
$this->refreshInventory($product);
|
||||||
|
}
|
||||||
|
|
||||||
if (in_array('price', $indexers)) {
|
if (in_array('price', $indexers)) {
|
||||||
$this->refreshPrice($product);
|
$this->refreshPrice($product);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array('inventory', $indexers)) {
|
if (in_array('elastic', $indexers)) {
|
||||||
$this->refreshInventory($product);
|
$this->refreshElasticSearch($product);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,13 +100,30 @@ class Indexer
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$channels = $this->channelRepository->all();
|
foreach (core()->getAllChannels() as $channel) {
|
||||||
|
|
||||||
foreach ($channels as $channel) {
|
|
||||||
$this->productInventoryIndexRepository->updateOrCreate([
|
$this->productInventoryIndexRepository->updateOrCreate([
|
||||||
'channel_id' => $channel->id,
|
'channel_id' => $channel->id,
|
||||||
'product_id' => $product->id,
|
'product_id' => $product->id,
|
||||||
], $this->inventoryIndexer->setProduct($product)->getIndices($channel));
|
], $this->inventoryIndexer->setProduct($product)->getIndices($channel));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh elastic search indices
|
||||||
|
*
|
||||||
|
* @param \Webkul\Product\Contracts\Product $product
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function refreshElasticSearch($product)
|
||||||
|
{
|
||||||
|
foreach (core()->getAllChannels() as $channel) {
|
||||||
|
foreach ($channel->locales as $locale) {
|
||||||
|
$this->elasticSearchIndexer
|
||||||
|
->setProduct($product)
|
||||||
|
->setChannel($channel)
|
||||||
|
->setLocale($locale)
|
||||||
|
->refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,193 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Product\Helpers\Indexers\ElasticSearch;
|
||||||
|
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
use Elasticsearch;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||||
|
|
||||||
|
class Product
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new indexer instance.
|
||||||
|
*
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(protected AttributeRepository $attributeRepository)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Product instance.
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Contracts\Product
|
||||||
|
*/
|
||||||
|
protected $product;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Channel instance.
|
||||||
|
*
|
||||||
|
* @var \Webkul\Core\Contracts\Channel
|
||||||
|
*/
|
||||||
|
protected $channel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locale instance.
|
||||||
|
*
|
||||||
|
* @var \Webkul\Core\Contracts\Locale
|
||||||
|
*/
|
||||||
|
protected $locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set current product
|
||||||
|
*
|
||||||
|
* @param \Webkul\Product\Contracts\Product $product
|
||||||
|
* @return \Webkul\Product\Helpers\Indexers\ElasticSearch\Product
|
||||||
|
*/
|
||||||
|
public function setProduct($product)
|
||||||
|
{
|
||||||
|
$this->product = $product;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Channel
|
||||||
|
*
|
||||||
|
* @param \Webkul\Product\Contracts\Product $product
|
||||||
|
* @return \Webkul\Product\Helpers\Indexers\ElasticSearch\Product
|
||||||
|
*/
|
||||||
|
public function setChannel($channel)
|
||||||
|
{
|
||||||
|
$this->channel = $channel;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Locale
|
||||||
|
*
|
||||||
|
* @param \Webkul\Product\Contracts\Product $product
|
||||||
|
* @return \Webkul\Product\Helpers\Indexers\ElasticSearch\Product
|
||||||
|
*/
|
||||||
|
public function setLocale($locale)
|
||||||
|
{
|
||||||
|
$this->locale = $locale;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh product indices
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function refresh()
|
||||||
|
{
|
||||||
|
$params = [
|
||||||
|
'index' => $this->getIndexName(),
|
||||||
|
'id' => $this->product->id,
|
||||||
|
'body' => $this->getElasticProperties(),
|
||||||
|
];
|
||||||
|
|
||||||
|
Elasticsearch::index($params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh product indices
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function getIndexName()
|
||||||
|
{
|
||||||
|
return 'products_' . $this->channel->code . '_' . $this->locale->code . '_index';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns filterable attribute values
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function getElasticProperties()
|
||||||
|
{
|
||||||
|
$properties = [
|
||||||
|
'id' => $this->product->id,
|
||||||
|
'category_ids' => $this->product->categories->pluck('id')->toArray(),
|
||||||
|
'created_at' => $this->product->created_at,
|
||||||
|
];
|
||||||
|
|
||||||
|
$attributes = $this->attributeRepository->scopeQuery(function ($query) {
|
||||||
|
return $query->where(function ($ab) {
|
||||||
|
return $ab->orWhereIn('code', [
|
||||||
|
'sku',
|
||||||
|
'name',
|
||||||
|
'status',
|
||||||
|
'visible_individually',
|
||||||
|
'url_key',
|
||||||
|
'short_description',
|
||||||
|
'description',
|
||||||
|
])
|
||||||
|
->orWhere('is_filterable', 1);
|
||||||
|
});
|
||||||
|
})->get();
|
||||||
|
|
||||||
|
foreach ($attributes as $attribute) {
|
||||||
|
$attributeValue = $this->getAttributeValue($attribute);
|
||||||
|
|
||||||
|
if ($attribute->code == 'price') {
|
||||||
|
$properties[$attribute->code] = (float) $this->product->getTypeInstance()->getMinimalPrice();
|
||||||
|
} elseif ($attribute->type == 'boolean') {
|
||||||
|
$properties[$attribute->code] = intval($attributeValue?->{$attribute->column_name});
|
||||||
|
} else {
|
||||||
|
$properties[$attribute->code] = $attributeValue?->{$attribute->column_name};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->product->super_attributes as $attribute) {
|
||||||
|
foreach ($this->product->variants as $variant) {
|
||||||
|
$properties['ca_' . $attribute->code][] = $variant->{$attribute->code};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns filterable attribute values
|
||||||
|
*
|
||||||
|
* @param \Webkul\Attribute\Contracts\Attribute $attribute
|
||||||
|
* @param \Webkul\Product\Contracts\ProductAttributeValue
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function getAttributeValue($attribute)
|
||||||
|
{
|
||||||
|
if ($attribute->value_per_channel) {
|
||||||
|
if ($attribute->value_per_locale) {
|
||||||
|
$attributeValue = $this->product->attribute_values
|
||||||
|
->where('channel', $this->channel->code)
|
||||||
|
->where('locale', $this->locale->code)
|
||||||
|
->where('attribute_id', $attribute->id)
|
||||||
|
->first();
|
||||||
|
} else {
|
||||||
|
$attributeValue = $this->product->attribute_values
|
||||||
|
->where('channel', $this->channel->code)
|
||||||
|
->where('attribute_id', $attribute->id)
|
||||||
|
->first();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($attribute->value_per_locale) {
|
||||||
|
$attributeValue = $this->product->attribute_values
|
||||||
|
->where('locale', $this->locale->code)
|
||||||
|
->where('attribute_id', $attribute->id)
|
||||||
|
->first();
|
||||||
|
} else {
|
||||||
|
$attributeValue = $this->product->attribute_values
|
||||||
|
->where('attribute_id', $attribute->id)
|
||||||
|
->first();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $attributeValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -46,21 +46,21 @@ class Product
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refresh product indexer indexes
|
* Refresh product flat indices
|
||||||
*
|
*
|
||||||
* @param \Webkul\Product\Contracts\Product $product
|
* @param \Webkul\Product\Contracts\Product $product
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function refresh($product)
|
public function refresh($product)
|
||||||
{
|
{
|
||||||
$this->updateCreate($product);
|
$this->updateOrCreate($product);
|
||||||
|
|
||||||
if (! ProductType::hasVariants($product->type)) {
|
if (! ProductType::hasVariants($product->type)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($product->variants()->get() as $variant) {
|
foreach ($product->variants()->get() as $variant) {
|
||||||
$this->updateCreate($variant, $product);
|
$this->updateOrCreate($variant, $product);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,7 +71,7 @@ class Product
|
||||||
* @param \Webkul\Product\Contracts\Product $parentProduct
|
* @param \Webkul\Product\Contracts\Product $parentProduct
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function updateCreate($product, $parentProduct = null)
|
public function updateOrCreate($product, $parentProduct = null)
|
||||||
{
|
{
|
||||||
$familyAttributes = $this->getCachedFamilyAttributes($product);
|
$familyAttributes = $this->getCachedFamilyAttributes($product);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,11 @@ class Product
|
||||||
{
|
{
|
||||||
$this->indexer->refreshFlat($product);
|
$this->indexer->refreshFlat($product);
|
||||||
|
|
||||||
|
$this->refreshInventoryIndices($product);
|
||||||
|
|
||||||
$this->refreshPriceIndices($product);
|
$this->refreshPriceIndices($product);
|
||||||
|
|
||||||
$this->indexer->refreshInventory($product);
|
$this->refreshElasticSearchIndices($product);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -58,25 +60,78 @@ class Product
|
||||||
*/
|
*/
|
||||||
public function refreshPriceIndices($product)
|
public function refreshPriceIndices($product)
|
||||||
{
|
{
|
||||||
$products = [$product];
|
$products = $this->getAllRelatedProducts($product);
|
||||||
|
|
||||||
if ($product->type == 'simple') {
|
|
||||||
if ($product->parent_id) {
|
|
||||||
$products[] = $product->parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
$products = array_merge(
|
|
||||||
$products,
|
|
||||||
$this->getParentBundleProducts($product),
|
|
||||||
$this->getParentGroupProducts($product)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($products as $product) {
|
foreach ($products as $product) {
|
||||||
$this->indexer->refreshPrice($product);
|
$this->indexer->refreshPrice($product);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update or create product inventory indices
|
||||||
|
*
|
||||||
|
* @param \Webkul\Product\Contracts\Product $product
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function refreshInventoryIndices($product)
|
||||||
|
{
|
||||||
|
$products = $this->getAllRelatedProducts($product);
|
||||||
|
|
||||||
|
foreach ($products as $product) {
|
||||||
|
$this->indexer->refreshInventory($product);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update or create product ElasticSearch indices
|
||||||
|
*
|
||||||
|
* @param \Webkul\Product\Contracts\Product $product
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function refreshElasticSearchIndices($product)
|
||||||
|
{
|
||||||
|
$products = $this->getAllRelatedProducts($product);
|
||||||
|
|
||||||
|
foreach ($products as $product) {
|
||||||
|
$this->indexer->refreshElasticSearch($product);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns parents bundle products associated with simple product
|
||||||
|
*
|
||||||
|
* @param \Webkul\Product\Contracts\Product $product
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getAllRelatedProducts($product)
|
||||||
|
{
|
||||||
|
static $products = [];
|
||||||
|
|
||||||
|
if (array_key_exists($product->id, $products)) {
|
||||||
|
return $products[$product->id];
|
||||||
|
}
|
||||||
|
|
||||||
|
$products[$product->id] = [$product];
|
||||||
|
|
||||||
|
if ($product->type == 'simple') {
|
||||||
|
if ($product->parent_id) {
|
||||||
|
$products[$product->id][] = $product->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
$products[$product->id] = array_merge(
|
||||||
|
$products[$product->id],
|
||||||
|
$this->getParentBundleProducts($product),
|
||||||
|
$this->getParentGroupProducts($product)
|
||||||
|
);
|
||||||
|
} elseif ($product->type == 'configurable') {
|
||||||
|
foreach ($product->variants as $variant) {
|
||||||
|
$products[$product->id][] = $variant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $products[$product->id];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns parents bundle products associated with simple product
|
* Returns parents bundle products associated with simple product
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -60,28 +60,6 @@ class Product extends Model implements ProductContract
|
||||||
*/
|
*/
|
||||||
public static $loadedAttributeValues = [];
|
public static $loadedAttributeValues = [];
|
||||||
|
|
||||||
/**
|
|
||||||
* The `booted` method of the model.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected static function booted(): void
|
|
||||||
{
|
|
||||||
parent::boot();
|
|
||||||
|
|
||||||
static::deleting(function ($product) {
|
|
||||||
foreach ($product->product_flats as $productFlat) {
|
|
||||||
$productFlat->unsearchable();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($product->variants as $variant) {
|
|
||||||
foreach ($variant->product_flats as $productFlat) {
|
|
||||||
$productFlat->unsearchable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the product flat entries that are associated with product.
|
* Get the product flat entries that are associated with product.
|
||||||
* May be one for each locale and each channel.
|
* May be one for each locale and each channel.
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,11 @@
|
||||||
namespace Webkul\Product\Models;
|
namespace Webkul\Product\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Laravel\Scout\Searchable;
|
|
||||||
use Webkul\Attribute\Repositories\AttributeRepository;
|
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||||
use Webkul\Product\Contracts\ProductFlat as ProductFlatContract;
|
use Webkul\Product\Contracts\ProductFlat as ProductFlatContract;
|
||||||
|
|
||||||
class ProductFlat extends Model implements ProductFlatContract
|
class ProductFlat extends Model implements ProductFlatContract
|
||||||
{
|
{
|
||||||
use Searchable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The table associated with the model.
|
* The table associated with the model.
|
||||||
*
|
*
|
||||||
|
|
@ -40,16 +37,6 @@ class ProductFlat extends Model implements ProductFlatContract
|
||||||
'attribute_family_id',
|
'attribute_family_id',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the index name for the model.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function searchableAs()
|
|
||||||
{
|
|
||||||
return 'products_index';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an attribute from the model.
|
* Get an attribute from the model.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Product\Repositories;
|
||||||
|
|
||||||
|
use Elasticsearch;
|
||||||
|
use Elasticsearch\Common\Exceptions\Missing404Exception;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||||
|
|
||||||
|
class ElasticSearchRepository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new repository instance.
|
||||||
|
*
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(protected AttributeRepository $attributeRepository)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns product ids from Elasticsearch
|
||||||
|
*
|
||||||
|
* @param integer $categoryId
|
||||||
|
* @param array $options
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function search($categoryId, $options)
|
||||||
|
{
|
||||||
|
$from = ($options['page'] * $options['limit']) - $options['limit'];
|
||||||
|
|
||||||
|
$filters = $this->addFilters();
|
||||||
|
|
||||||
|
$params = [
|
||||||
|
'index' => $this->getIndexName(),
|
||||||
|
'body' => [
|
||||||
|
'from' => $from,
|
||||||
|
'stored_fields' => [],
|
||||||
|
'query' => [
|
||||||
|
'bool' => [
|
||||||
|
'filter' => $filters,
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'sort' => [
|
||||||
|
$options['sort'] . '.keyword' => [
|
||||||
|
'order' => $options['order'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
dd($params);
|
||||||
|
|
||||||
|
$results = Elasticsearch::search($params);
|
||||||
|
|
||||||
|
dd($results);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'total' => $results['hits']['total']['value'],
|
||||||
|
'ids' => collect($results['hits']['hits'])->pluck('_id')->toArray()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh product indices
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function getIndexName()
|
||||||
|
{
|
||||||
|
return 'products_' . core()->getRequestedChannelCode() . '_' . core()->getRequestedLocaleCode() . '_index';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh product indices
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function addFilters()
|
||||||
|
{
|
||||||
|
$params = request()->input();
|
||||||
|
|
||||||
|
$filterableAttributes = $this->attributeRepository
|
||||||
|
->getProductDefaultAttributes(array_keys($params));
|
||||||
|
|
||||||
|
$filters = [];
|
||||||
|
|
||||||
|
foreach ($filterableAttributes as $attribute) {
|
||||||
|
switch ($attribute->type) {
|
||||||
|
case 'price':
|
||||||
|
$range = explode(',', $params[$attribute->code]);
|
||||||
|
|
||||||
|
// $filters['range'][$attribute->code] = [
|
||||||
|
// 'gte' => core()->convertToBasePrice(current($range)),
|
||||||
|
// 'lte' => core()->convertToBasePrice(end($range)),
|
||||||
|
// ];
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'text':
|
||||||
|
$filters['match_phrase_prefix'][$attribute->code] = $params[$attribute->code];
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'select':
|
||||||
|
$filters['term'][$attribute->code] = $params[$attribute->code];
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $filters;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,6 +19,7 @@ class ProductRepository extends Repository
|
||||||
* @param \Webkul\Customer\Repositories\CustomerRepository $customerRepository
|
* @param \Webkul\Customer\Repositories\CustomerRepository $customerRepository
|
||||||
* @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
|
* @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
|
||||||
* @param \Webkul\Product\Repositories\ProductFlatRepository $productFlatRepository
|
* @param \Webkul\Product\Repositories\ProductFlatRepository $productFlatRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ElasticSearchRepository $elasticSearchRepository
|
||||||
* @param \Illuminate\Container\Container $container
|
* @param \Illuminate\Container\Container $container
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
|
@ -26,6 +27,7 @@ class ProductRepository extends Repository
|
||||||
protected CustomerRepository $customerRepository,
|
protected CustomerRepository $customerRepository,
|
||||||
protected AttributeRepository $attributeRepository,
|
protected AttributeRepository $attributeRepository,
|
||||||
protected ProductFlatRepository $productFlatRepository,
|
protected ProductFlatRepository $productFlatRepository,
|
||||||
|
protected ElasticSearchRepository $elasticSearchRepository,
|
||||||
Container $container
|
Container $container
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
@ -178,12 +180,29 @@ class ProductRepository extends Repository
|
||||||
* @return \Illuminate\Support\Collection
|
* @return \Illuminate\Support\Collection
|
||||||
*/
|
*/
|
||||||
public function getAll($categoryId = null)
|
public function getAll($categoryId = null)
|
||||||
|
{
|
||||||
|
$engine = 'elastic';
|
||||||
|
|
||||||
|
if ($engine == 'db') {
|
||||||
|
return $this->searchFromDatabase($categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->searchFromElastic($categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search product from database
|
||||||
|
*
|
||||||
|
* @param string $categoryId
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function searchFromDatabase($categoryId = null)
|
||||||
{
|
{
|
||||||
$params = request()->input();
|
$params = request()->input();
|
||||||
|
|
||||||
$query = $this->productFlatRepository->with([
|
$query = $this->productFlatRepository->with([
|
||||||
'images',
|
'images',
|
||||||
'product.videos',
|
'videos',
|
||||||
'product.attribute_values',
|
'product.attribute_values',
|
||||||
'product.price_indices',
|
'product.price_indices',
|
||||||
'product.inventory_indices',
|
'product.inventory_indices',
|
||||||
|
|
@ -272,28 +291,31 @@ class ProductRepository extends Repository
|
||||||
}
|
}
|
||||||
|
|
||||||
#Sort collection
|
#Sort collection
|
||||||
$sortOptions = explode('-', core()->getConfigData('catalog.products.storefront.sort_by') ?: 'name-desc');
|
$sortOptions = $this->getSortOptions($params);
|
||||||
|
|
||||||
$orderDirection = empty($params['order']) ? end($sortOptions) : $params['order'];
|
|
||||||
|
|
||||||
$this->checkSortAttributeAndGenerateQuery($qb, $params['sort'] ?? $sortOptions[0], $orderDirection);
|
|
||||||
|
|
||||||
|
if ($sortOptions['order'] != 'rand') {
|
||||||
|
$attribute = $this->attributeRepository->findOneByField('code', $sortOptions['sort']);
|
||||||
|
|
||||||
|
if ($attribute) {
|
||||||
|
if ($attribute->code === 'price') {
|
||||||
|
$qb->orderBy('product_price_indices.min_price', $sortOptions['order']);
|
||||||
|
} else {
|
||||||
|
$qb->orderBy($attribute->code, $sortOptions['order']);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* `created_at` is not an attribute so it will be in else case */
|
||||||
|
$qb->orderBy('product_flat.created_at', $sortOptions['order']);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return $qb->inRandomOrder();
|
||||||
|
}
|
||||||
|
|
||||||
return $qb->groupBy('product_flat.id');
|
return $qb->groupBy('product_flat.id');
|
||||||
});
|
});
|
||||||
|
|
||||||
if (core()->getConfigData('catalog.products.storefront.products_per_page')) {
|
|
||||||
$pages = explode(',', core()->getConfigData('catalog.products.storefront.products_per_page'));
|
|
||||||
|
|
||||||
$perPage = ! empty($params['limit']) ? $params['limit'] : current($pages);
|
|
||||||
} else {
|
|
||||||
$perPage = ! empty($params['limit']) ? $params['limit'] : 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
# apply scope query so we can fetch the raw sql and perform a count
|
# apply scope query so we can fetch the raw sql and perform a count
|
||||||
$query->applyScope();
|
$query->applyScope();
|
||||||
|
|
||||||
$page = Paginator::resolveCurrentPage('page');
|
|
||||||
|
|
||||||
$countQuery = clone $query->model;
|
$countQuery = clone $query->model;
|
||||||
|
|
||||||
$count = collect(
|
$count = collect(
|
||||||
|
|
@ -303,16 +325,20 @@ class ProductRepository extends Repository
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
|
|
||||||
|
$limit = $this->getPerPageLimit($params);
|
||||||
|
|
||||||
|
$currentPage = Paginator::resolveCurrentPage('page');
|
||||||
|
|
||||||
if ($count > 0) {
|
if ($count > 0) {
|
||||||
# apply a new scope query to limit results to one page
|
# apply a new scope query to limit results to one page
|
||||||
$query->scopeQuery(function ($query) use ($page, $perPage) {
|
$query->scopeQuery(function ($query) use ($currentPage, $limit) {
|
||||||
return $query->forPage($page, $perPage);
|
return $query->forPage($currentPage, $limit);
|
||||||
});
|
});
|
||||||
|
|
||||||
$items = $query->get();
|
$items = $query->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
$results = new LengthAwarePaginator($items, $count, $perPage, $page, [
|
$results = new LengthAwarePaginator($items, $count, $limit, $currentPage, [
|
||||||
'path' => request()->url(),
|
'path' => request()->url(),
|
||||||
'query' => request()->query(),
|
'query' => request()->query(),
|
||||||
]);
|
]);
|
||||||
|
|
@ -321,33 +347,95 @@ class ProductRepository extends Repository
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check sort attribute and generate query.
|
* Search product from elastic search
|
||||||
*
|
*
|
||||||
* @param object $query
|
* @param string $categoryId
|
||||||
* @param string $sort
|
* @return \Illuminate\Support\Collection
|
||||||
* @param string $direction
|
|
||||||
* @return object
|
|
||||||
*/
|
*/
|
||||||
private function checkSortAttributeAndGenerateQuery($query, $sort, $direction)
|
public function searchFromElastic($categoryId)
|
||||||
{
|
{
|
||||||
if ($direction == 'rand') {
|
$params = request()->input();
|
||||||
return $query->inRandomOrder();
|
|
||||||
|
$currentPage = Paginator::resolveCurrentPage('page');
|
||||||
|
|
||||||
|
$limit = $this->getPerPageLimit($params);
|
||||||
|
|
||||||
|
$sortOptions = $this->getSortOptions($params);
|
||||||
|
|
||||||
|
$indices = $this->elasticSearchRepository->search($categoryId, [
|
||||||
|
'page' => $currentPage,
|
||||||
|
'limit' => $limit,
|
||||||
|
'sort' => $sortOptions['sort'],
|
||||||
|
'order' => $sortOptions['order'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$query = $this->productFlatRepository->with([
|
||||||
|
'images',
|
||||||
|
'videos',
|
||||||
|
'product.attribute_values',
|
||||||
|
'product.price_indices',
|
||||||
|
'product.inventory_indices',
|
||||||
|
'product.reviews',
|
||||||
|
])->scopeQuery(function ($query) use ($indices) {
|
||||||
|
$qb = $query->distinct()
|
||||||
|
->whereIn('product_flat.product_id', $indices['ids'])
|
||||||
|
->where('product_flat.channel', core()->getRequestedChannelCode())
|
||||||
|
->where('product_flat.locale', core()->getRequestedLocaleCode());
|
||||||
|
|
||||||
|
#Sort collection
|
||||||
|
$qb->orderBy(DB::raw('FIELD(product_id, ' . implode(',', $indices['ids']) . ')'));
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
});
|
||||||
|
|
||||||
|
$items = $indices['total'] ? $query->get() : [];
|
||||||
|
|
||||||
|
$currentPage = Paginator::resolveCurrentPage('page');
|
||||||
|
|
||||||
|
$limit = $this->getPerPageLimit($params);
|
||||||
|
|
||||||
|
$results = new LengthAwarePaginator($items, $indices['total'], $limit, $currentPage, [
|
||||||
|
'path' => request()->url(),
|
||||||
|
'query' => request()->query(),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Products to show per page
|
||||||
|
*
|
||||||
|
* @param array $params
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getPerPageLimit($params)
|
||||||
|
{
|
||||||
|
$limit = $params['limit'] ?? 9;
|
||||||
|
|
||||||
|
if (core()->getConfigData('catalog.products.storefront.products_per_page')) {
|
||||||
|
$pages = explode(',', core()->getConfigData('catalog.products.storefront.products_per_page'));
|
||||||
|
|
||||||
|
$limit = $params['limit'] ?? current($pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
$attribute = $this->attributeRepository->findOneByField('code', $sort);
|
return $limit;
|
||||||
|
}
|
||||||
|
|
||||||
if ($attribute) {
|
/**
|
||||||
if ($attribute->code === 'price') {
|
* Products to show per page
|
||||||
$query->orderBy('product_price_indices.min_price', $direction);
|
*
|
||||||
} else {
|
* @param array $params
|
||||||
$query->orderBy($attribute->code, $direction);
|
* @return array
|
||||||
}
|
*/
|
||||||
} else {
|
public function getSortOptions($params)
|
||||||
/* `created_at` is not an attribute so it will be in else case */
|
{
|
||||||
$query->orderBy('product_flat.created_at', $direction);
|
$sortOptions = explode('-', core()->getConfigData('catalog.products.storefront.sort_by') ?: 'name-desc');
|
||||||
}
|
|
||||||
|
|
||||||
return $query;
|
return [
|
||||||
|
'sort' => $params['sort'] ?? current($sortOptions),
|
||||||
|
'order' => $params['order'] ?? end($sortOptions),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -384,65 +472,26 @@ class ProductRepository extends Repository
|
||||||
*/
|
*/
|
||||||
public function searchProductByAttribute($term)
|
public function searchProductByAttribute($term)
|
||||||
{
|
{
|
||||||
$channel = core()->getRequestedChannelCode();
|
$results = $this->productFlatRepository
|
||||||
|
->scopeQuery(function ($query) use ($term) {
|
||||||
|
$query = $query->distinct()
|
||||||
|
->addSelect('product_flat.*')
|
||||||
|
->where('product_flat.channel', core()->getRequestedChannelCode())
|
||||||
|
->where('product_flat.locale', core()->getRequestedLocaleCode())
|
||||||
|
->whereNotNull('product_flat.url_key');
|
||||||
|
|
||||||
$locale = core()->getRequestedLocaleCode();
|
return $query->where('product_flat.status', 1)
|
||||||
|
->where('product_flat.visible_individually', 1)
|
||||||
|
->where(function ($subQuery) use ($term) {
|
||||||
|
$queries = explode('_', $term);
|
||||||
|
|
||||||
if (config('scout.driver') == 'algolia') {
|
foreach (array_map('trim', $queries) as $value) {
|
||||||
$results = $this->productFlatRepository
|
$subQuery->orWhere('product_flat.name', 'like', '%' . urldecode($value) . '%')
|
||||||
->getModel()::search('query', function ($searchDriver, string $query, array $options) use ($term, $channel, $locale) {
|
->orWhere('product_flat.short_description', 'like', '%' . urldecode($value) . '%');
|
||||||
$queries = explode('_', $term);
|
}
|
||||||
|
})
|
||||||
$options['similarQuery'] = array_map('trim', $queries);
|
->orderBy('product_id', 'desc');
|
||||||
|
})->paginate(16);
|
||||||
$searchDriver->setSettings([
|
|
||||||
'attributesForFaceting' => [
|
|
||||||
'searchable(locale)',
|
|
||||||
'searchable(channel)',
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
$options['facetFilters'] = ['locale:' . $locale, 'channel:' . $channel];
|
|
||||||
|
|
||||||
return $searchDriver->search($query, $options);
|
|
||||||
})
|
|
||||||
->where('status', 1)
|
|
||||||
->where('visible_individually', 1)
|
|
||||||
->orderBy('product_id', 'desc')
|
|
||||||
->paginate(16);
|
|
||||||
} elseif (config('scout.driver') == 'elastic') {
|
|
||||||
$queries = explode('_', $term);
|
|
||||||
|
|
||||||
$results = $this->productFlatRepository
|
|
||||||
->getModel()::search(implode(' OR ', $queries))
|
|
||||||
->where('status', 1)
|
|
||||||
->where('visible_individually', 1)
|
|
||||||
->where('channel', $channel)
|
|
||||||
->where('locale', $locale)
|
|
||||||
->orderBy('product_id', 'desc')
|
|
||||||
->paginate(16);
|
|
||||||
} else {
|
|
||||||
$results = $this->productFlatRepository
|
|
||||||
->scopeQuery(function ($query) use ($term, $channel, $locale) {
|
|
||||||
$query = $query->distinct()
|
|
||||||
->addSelect('product_flat.*')
|
|
||||||
->where('product_flat.channel', $channel)
|
|
||||||
->where('product_flat.locale', $locale)
|
|
||||||
->whereNotNull('product_flat.url_key');
|
|
||||||
|
|
||||||
return $query->where('product_flat.status', 1)
|
|
||||||
->where('product_flat.visible_individually', 1)
|
|
||||||
->where(function ($subQuery) use ($term) {
|
|
||||||
$queries = explode('_', $term);
|
|
||||||
|
|
||||||
foreach (array_map('trim', $queries) as $value) {
|
|
||||||
$subQuery->orWhere('product_flat.name', 'like', '%' . urldecode($value) . '%')
|
|
||||||
->orWhere('product_flat.short_description', 'like', '%' . urldecode($value) . '%');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
->orderBy('product_id', 'desc');
|
|
||||||
})->paginate(16);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue