Elastic search
This commit is contained in:
parent
c457b98b8e
commit
71d6198e03
|
|
@ -10,10 +10,12 @@
|
|||
"require": {
|
||||
"php": "^8.1",
|
||||
"astrotomic/laravel-translatable": "^11.0.0",
|
||||
"bagisto/laravel-datafaker": "^2.0@alpha",
|
||||
"bagisto/rest-api": "^1.0",
|
||||
"bagistobrasil/bagisto-product-social-share": "^0.1.2",
|
||||
"barryvdh/laravel-debugbar": "^3.1",
|
||||
"barryvdh/laravel-dompdf": "^2.0.0",
|
||||
"cviebrock/laravel-elasticsearch": "^9.0",
|
||||
"diglactic/laravel-breadcrumbs": "^7.0",
|
||||
"doctrine/dbal": "^2.9",
|
||||
"enshrined/svg-sanitize": "^0.15.0",
|
||||
|
|
@ -27,7 +29,6 @@
|
|||
"konekt/concord": "^1.2",
|
||||
"laravel/framework": "^9.0",
|
||||
"laravel/sanctum": "^2.12",
|
||||
"laravel/scout": "^9.0",
|
||||
"laravel/socialite": "^5.0",
|
||||
"laravel/tinker": "^2.0",
|
||||
"laravel/ui": "^3.0",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "24a0dc2b81de04eed28797f623305a33",
|
||||
"content-hash": "f97b453abb0e5218dd71c940aaa63d00",
|
||||
"packages": [
|
||||
{
|
||||
"name": "astrotomic/laravel-translatable",
|
||||
|
|
@ -97,6 +97,59 @@
|
|||
],
|
||||
"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",
|
||||
"version": "v1.0.0",
|
||||
|
|
@ -405,6 +458,84 @@
|
|||
],
|
||||
"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",
|
||||
"version": "v3.0.1",
|
||||
|
|
@ -1256,6 +1387,69 @@
|
|||
],
|
||||
"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",
|
||||
"version": "0.15.4",
|
||||
|
|
@ -1301,6 +1495,116 @@
|
|||
},
|
||||
"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",
|
||||
"version": "v4.14.0",
|
||||
|
|
@ -2687,78 +2991,6 @@
|
|||
},
|
||||
"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",
|
||||
"version": "v1.2.0",
|
||||
|
|
@ -5802,6 +6034,82 @@
|
|||
],
|
||||
"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",
|
||||
"version": "8.4.0",
|
||||
|
|
@ -12361,6 +12669,7 @@
|
|||
"aliases": [],
|
||||
"minimum-stability": "dev",
|
||||
"stability-flags": {
|
||||
"bagisto/laravel-datafaker": 15,
|
||||
"flynsarmy/db-blade-compiler": 20,
|
||||
"codeception/codeception": 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()
|
||||
{
|
||||
$indexers = ['price', 'inventory'];
|
||||
$indexers = ['inventory', 'price', 'elastic'];
|
||||
|
||||
if (! empty($this->option('type'))) {
|
||||
$indexers = $this->option('type');
|
||||
|
|
|
|||
|
|
@ -2,33 +2,33 @@
|
|||
|
||||
namespace Webkul\Product\Helpers;
|
||||
|
||||
use Webkul\Core\Repositories\ChannelRepository;
|
||||
use Webkul\Customer\Repositories\CustomerGroupRepository;
|
||||
use Webkul\Product\Repositories\ProductPriceIndexRepository;
|
||||
use Webkul\Product\Repositories\ProductInventoryIndexRepository;
|
||||
use Webkul\Product\Helpers\Indexers\Flat\Product as FlatIndexer;
|
||||
use Webkul\Product\Helpers\Indexers\Inventory\Product as InventoryIndexer;
|
||||
use Webkul\Product\Helpers\Indexers\ElasticSearch\Product as ElasticSearchIndexer;
|
||||
|
||||
class Indexer
|
||||
{
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @param \Webkul\Core\Repositories\ChannelRepository $channelRepository
|
||||
* @param \Webkul\Customer\Repositories\CustomerGroupRepository $customerGroupRepository
|
||||
* @param \Webkul\Product\Repositories\ProductPriceIndexRepository $productPriceIndexRepository
|
||||
* @param \Webkul\Product\Repositories\ProductInventoryIndexRepository $productInventoryIndexRepository
|
||||
* @param \Webkul\Product\Helpers\Indexers\Flat\Product $flatIndexer
|
||||
* @param \Webkul\Product\Helpers\Indexers\Inventory\Product $inventoryIndexer
|
||||
* @param \Webkul\Product\Helpers\Indexers\ElasticSearch\Product $elasticSearchIndexer
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
protected ChannelRepository $channelRepository,
|
||||
protected CustomerGroupRepository $customerGroupRepository,
|
||||
protected ProductPriceIndexRepository $productPriceIndexRepository,
|
||||
protected ProductInventoryIndexRepository $productInventoryIndexRepository,
|
||||
protected FlatIndexer $flatIndexer,
|
||||
protected InventoryIndexer $inventoryIndexer
|
||||
protected InventoryIndexer $inventoryIndexer,
|
||||
protected ElasticSearchIndexer $elasticSearchIndexer
|
||||
)
|
||||
{
|
||||
}
|
||||
|
|
@ -40,14 +40,18 @@ class Indexer
|
|||
* @param array $indexers
|
||||
* @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)) {
|
||||
$this->refreshPrice($product);
|
||||
}
|
||||
|
||||
if (in_array('inventory', $indexers)) {
|
||||
$this->refreshInventory($product);
|
||||
if (in_array('elastic', $indexers)) {
|
||||
$this->refreshElasticSearch($product);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -96,13 +100,30 @@ class Indexer
|
|||
return;
|
||||
}
|
||||
|
||||
$channels = $this->channelRepository->all();
|
||||
|
||||
foreach ($channels as $channel) {
|
||||
foreach (core()->getAllChannels() as $channel) {
|
||||
$this->productInventoryIndexRepository->updateOrCreate([
|
||||
'channel_id' => $channel->id,
|
||||
'product_id' => $product->id,
|
||||
], $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
|
||||
* @return void
|
||||
*/
|
||||
public function refresh($product)
|
||||
{
|
||||
$this->updateCreate($product);
|
||||
$this->updateOrCreate($product);
|
||||
|
||||
if (! ProductType::hasVariants($product->type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
* @return void
|
||||
*/
|
||||
public function updateCreate($product, $parentProduct = null)
|
||||
public function updateOrCreate($product, $parentProduct = null)
|
||||
{
|
||||
$familyAttributes = $this->getCachedFamilyAttributes($product);
|
||||
|
||||
|
|
|
|||
|
|
@ -45,9 +45,11 @@ class Product
|
|||
{
|
||||
$this->indexer->refreshFlat($product);
|
||||
|
||||
$this->refreshInventoryIndices($product);
|
||||
|
||||
$this->refreshPriceIndices($product);
|
||||
|
||||
$this->indexer->refreshInventory($product);
|
||||
$this->refreshElasticSearchIndices($product);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -58,25 +60,78 @@ class Product
|
|||
*/
|
||||
public function refreshPriceIndices($product)
|
||||
{
|
||||
$products = [$product];
|
||||
|
||||
if ($product->type == 'simple') {
|
||||
if ($product->parent_id) {
|
||||
$products[] = $product->parent;
|
||||
}
|
||||
|
||||
$products = array_merge(
|
||||
$products,
|
||||
$this->getParentBundleProducts($product),
|
||||
$this->getParentGroupProducts($product)
|
||||
);
|
||||
}
|
||||
$products = $this->getAllRelatedProducts($product);
|
||||
|
||||
foreach ($products as $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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -60,28 +60,6 @@ class Product extends Model implements ProductContract
|
|||
*/
|
||||
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.
|
||||
* May be one for each locale and each channel.
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@
|
|||
namespace Webkul\Product\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Laravel\Scout\Searchable;
|
||||
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||
use Webkul\Product\Contracts\ProductFlat as ProductFlatContract;
|
||||
|
||||
class ProductFlat extends Model implements ProductFlatContract
|
||||
{
|
||||
use Searchable;
|
||||
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
|
|
@ -40,16 +37,6 @@ class ProductFlat extends Model implements ProductFlatContract
|
|||
'attribute_family_id',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the index name for the model.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function searchableAs()
|
||||
{
|
||||
return 'products_index';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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\Attribute\Repositories\AttributeRepository $attributeRepository
|
||||
* @param \Webkul\Product\Repositories\ProductFlatRepository $productFlatRepository
|
||||
* @param \Webkul\Product\Repositories\ElasticSearchRepository $elasticSearchRepository
|
||||
* @param \Illuminate\Container\Container $container
|
||||
* @return void
|
||||
*/
|
||||
|
|
@ -26,6 +27,7 @@ class ProductRepository extends Repository
|
|||
protected CustomerRepository $customerRepository,
|
||||
protected AttributeRepository $attributeRepository,
|
||||
protected ProductFlatRepository $productFlatRepository,
|
||||
protected ElasticSearchRepository $elasticSearchRepository,
|
||||
Container $container
|
||||
)
|
||||
{
|
||||
|
|
@ -178,12 +180,29 @@ class ProductRepository extends Repository
|
|||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
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();
|
||||
|
||||
$query = $this->productFlatRepository->with([
|
||||
'images',
|
||||
'product.videos',
|
||||
'videos',
|
||||
'product.attribute_values',
|
||||
'product.price_indices',
|
||||
'product.inventory_indices',
|
||||
|
|
@ -272,28 +291,31 @@ class ProductRepository extends Repository
|
|||
}
|
||||
|
||||
#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'];
|
||||
if ($sortOptions['order'] != 'rand') {
|
||||
$attribute = $this->attributeRepository->findOneByField('code', $sortOptions['sort']);
|
||||
|
||||
$this->checkSortAttributeAndGenerateQuery($qb, $params['sort'] ?? $sortOptions[0], $orderDirection);
|
||||
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');
|
||||
});
|
||||
|
||||
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
|
||||
$query->applyScope();
|
||||
|
||||
$page = Paginator::resolveCurrentPage('page');
|
||||
|
||||
$countQuery = clone $query->model;
|
||||
|
||||
$count = collect(
|
||||
|
|
@ -303,16 +325,20 @@ class ProductRepository extends Repository
|
|||
|
||||
$items = [];
|
||||
|
||||
$limit = $this->getPerPageLimit($params);
|
||||
|
||||
$currentPage = Paginator::resolveCurrentPage('page');
|
||||
|
||||
if ($count > 0) {
|
||||
# apply a new scope query to limit results to one page
|
||||
$query->scopeQuery(function ($query) use ($page, $perPage) {
|
||||
return $query->forPage($page, $perPage);
|
||||
$query->scopeQuery(function ($query) use ($currentPage, $limit) {
|
||||
return $query->forPage($currentPage, $limit);
|
||||
});
|
||||
|
||||
$items = $query->get();
|
||||
}
|
||||
|
||||
$results = new LengthAwarePaginator($items, $count, $perPage, $page, [
|
||||
$results = new LengthAwarePaginator($items, $count, $limit, $currentPage, [
|
||||
'path' => request()->url(),
|
||||
'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 $sort
|
||||
* @param string $direction
|
||||
* @return object
|
||||
* @param string $categoryId
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
private function checkSortAttributeAndGenerateQuery($query, $sort, $direction)
|
||||
public function searchFromElastic($categoryId)
|
||||
{
|
||||
if ($direction == 'rand') {
|
||||
return $query->inRandomOrder();
|
||||
$params = request()->input();
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
$attribute = $this->attributeRepository->findOneByField('code', $sort);
|
||||
/**
|
||||
* Products to show per page
|
||||
*
|
||||
* @param array $params
|
||||
* @return integer
|
||||
*/
|
||||
public function getPerPageLimit($params)
|
||||
{
|
||||
$limit = $params['limit'] ?? 9;
|
||||
|
||||
if ($attribute) {
|
||||
if ($attribute->code === 'price') {
|
||||
$query->orderBy('product_price_indices.min_price', $direction);
|
||||
} else {
|
||||
$query->orderBy($attribute->code, $direction);
|
||||
}
|
||||
} else {
|
||||
/* `created_at` is not an attribute so it will be in else case */
|
||||
$query->orderBy('product_flat.created_at', $direction);
|
||||
if (core()->getConfigData('catalog.products.storefront.products_per_page')) {
|
||||
$pages = explode(',', core()->getConfigData('catalog.products.storefront.products_per_page'));
|
||||
|
||||
$limit = $params['limit'] ?? current($pages);
|
||||
}
|
||||
|
||||
return $query;
|
||||
return $limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Products to show per page
|
||||
*
|
||||
* @param array $params
|
||||
* @return array
|
||||
*/
|
||||
public function getSortOptions($params)
|
||||
{
|
||||
$sortOptions = explode('-', core()->getConfigData('catalog.products.storefront.sort_by') ?: 'name-desc');
|
||||
|
||||
return [
|
||||
'sort' => $params['sort'] ?? current($sortOptions),
|
||||
'order' => $params['order'] ?? end($sortOptions),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -384,50 +472,12 @@ class ProductRepository extends Repository
|
|||
*/
|
||||
public function searchProductByAttribute($term)
|
||||
{
|
||||
$channel = core()->getRequestedChannelCode();
|
||||
|
||||
$locale = core()->getRequestedLocaleCode();
|
||||
|
||||
if (config('scout.driver') == 'algolia') {
|
||||
$results = $this->productFlatRepository
|
||||
->getModel()::search('query', function ($searchDriver, string $query, array $options) use ($term, $channel, $locale) {
|
||||
$queries = explode('_', $term);
|
||||
|
||||
$options['similarQuery'] = array_map('trim', $queries);
|
||||
|
||||
$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) {
|
||||
->scopeQuery(function ($query) use ($term) {
|
||||
$query = $query->distinct()
|
||||
->addSelect('product_flat.*')
|
||||
->where('product_flat.channel', $channel)
|
||||
->where('product_flat.locale', $locale)
|
||||
->where('product_flat.channel', core()->getRequestedChannelCode())
|
||||
->where('product_flat.locale', core()->getRequestedLocaleCode())
|
||||
->whereNotNull('product_flat.url_key');
|
||||
|
||||
return $query->where('product_flat.status', 1)
|
||||
|
|
@ -442,7 +492,6 @@ class ProductRepository extends Repository
|
|||
})
|
||||
->orderBy('product_id', 'desc');
|
||||
})->paginate(16);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue