Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php namespace Matchish\Sitesearch;
- use Backend\Classes\Controller;
- use ElasticSearcher\ElasticSearcher;
- use ElasticSearcher\Environment;
- use Illuminate\Support\Collection;
- use Matchish\Sitesearch\Classes\Indices\ProductsIndex;
- use Matchish\Sitesearch\Classes\Queries\InstantSearchWithSuggestionsQuery;
- use Matchish\Sitesearch\Classes\Queries\ProductsQueryWithAggregations;
- use Matchish\Sitesearch\Classes\Support\TextLangCorrect;
- use Matchish\Sitesearch\Classes\Support\Url;
- use Matchish\Sitesearch\Components\ProductsFilter;
- use Matchish\Sitesearch\Contracts\Category;
- use Matchish\Sitesearch\Contracts\Characteristic;
- use Matchish\Sitesearch\Contracts\CharacteristicValue;
- use Matchish\Sitesearch\Contracts\Product;
- use Matchish\Sitesearch\Jobs\FetchCatalogPage;
- use Matchish\Sitesearch\Jobs\Reindex;
- use Model;
- use System\Classes\PluginBase;
- class Plugin extends PluginBase
- {
- public $require = ['Samorai.Catalog'];
- public function registerComponents()
- {
- return [
- Components\SearchInput::class => Components\SearchInput::IDENT,
- Components\ProductsFilter::class => Components\ProductsFilter::IDENT,
- Components\SortBy::class => Components\SortBy::IDENT,
- ];
- }
- public function registerMarkupTags()
- {
- return [
- 'functions' => [
- 'productsWithCharacteristicsUrl' => function ($category, $value) {
- //TODO: убрать хардкод
- return Url::to('catalog/category', $category, null, new Collection([$value]));
- }
- ],
- 'filters' => [
- 'groupByFrontName' => function($items) {
- //Так как значения характеристик с однинаковыми front_name считаем за одно же, поэтому обьединяем их
- //TODO: абстрация дала течь нужно придумать другую. Не нравится что нужно обьединять характеристики с одинаковыми front_name
- //потому что у этих значений свои sort_order итп
- $result = [];
- foreach ($items as $item) {
- $frontName = $item->front_name ? $item->front_name : $item->value;
- if (array_key_exists($frontName, $result)) {
- $result[$frontName]->id = $result[$frontName]->id . '|' . $item->id;
- $result[$frontName]->products_count = $result[$frontName]->products_count + $item->products_count;
- } else {
- $result[$frontName] = $item;
- }
- }
- return $result;
- }
- ]
- ];
- }
- public function registerSettings()
- {
- return [
- 'settings' => [
- 'label' => 'matchish.sitesearch::lang.settings.label',
- 'description' => 'matchish.sitesearch::lang.settings.description',
- 'icon' => 'icon-search',
- 'class' => Models\Settings::class,
- 'order' => 500,
- 'keywords' => 'search filters',
- ],
- ];
- }
- public function register()
- {
- $this->app->bind(Characteristic::class, \Samorai\Catalog\Models\Characteristic::class);
- $this->app->bind(CharacteristicValue::class, \Samorai\Catalog\Models\CharacteristicValue::class);
- $this->app->bind(Product::class, \Samorai\Catalog\Models\Product::class);
- $this->app->bind(Category::class, \Samorai\Catalog\Models\Category::class);
- $this->app->bind('ProductsQuery', function () {
- return new ProductsQueryWithAggregations(app('SiteSearcher'));
- });
- $this->app->bind('InstantSearchQuery', function () {
- return new InstantSearchWithSuggestionsQuery(app('SiteSearcher'));
- });
- $this->app->singleton('SiteSearcher', function () {
- $env = new Environment(
- config('matchish.sitesearch::env')
- );
- $searcher = new ElasticSearcher($env);
- $productsIndex = new ProductsIndex;
- $searcher->indicesManager()->register($productsIndex);
- return $searcher;
- });
- }
- public function boot()
- {
- Model::extend(function ($model) {
- $model->bindEvent('model.afterSave', function () use ($model) {
- $models = [
- \Samorai\Catalog\Models\Product::class,
- \Samorai\Catalog\Models\Category::class,
- \Samorai\Catalog\Models\Characteristic::class,
- \Samorai\Catalog\Models\CharacteristicValue::class,
- ];
- if (in_array(get_class($model), $models)) {
- $config = config('matchish.sitesearch::models.products');
- $job = new Reindex($config['index'], $config['model'], $config['type']);
- dispatch($job);
- }
- });
- });
- \Event::listen('cms.page.init', function ($controller, $page) {
- //TODO: вынести в класс. зарегистрировать в зависимостях
- /** @var $page \Cms\Classes\Page */
- if (!($page
- && $page->hasComponent(ProductsFilter::IDENT)
- && $controller->getAjaxHandler() != 'onInstantSearch')
- ) {
- return;
- }
- $category = null;
- $characteristicsValues = null;
- $categorySlug = $controller->param('categories_slug');
- if ($categorySlug) {
- # TODO: get category from page data if it exists
- $category = app(Category::class)->findBySlug($categorySlug);
- if (!$category) {
- return $controller->run('404');
- }
- } else {
- if (post('category_id')) {
- $category = app(Category::class)->find(post('category_id'));
- } else {
- $category = app(Category::class)->first();
- }
- }
- $ids = array_map(function ($item) {
- return explode('|', $item);
- }, request()->input('filters', []));
- if ($ids) {
- $ids = call_user_func_array('array_merge', $ids);
- }
- if ($controller->getAjaxHandler() == 'onFilter') {
- $characteristicsValues = app(CharacteristicValue::class)->with('characteristic')->findMany($ids);
- } else {
- $filtersSlug = $controller->param('filters');
- if ($filtersSlug) {
- $aliases = explode('-', $filtersSlug);
- $characteristicsValues = app(CharacteristicValue::class)
- ->with('characteristic')->findManyBySlug($aliases);
- if ($filtersSlug !== Url::getFilterSlug($characteristicsValues)) {
- return $controller->run('404');
- }
- }
- }
- $ranges = request()->input('ranges', []);
- $term = request()->input('q', '');
- if ($term) {
- $controller->vars['term'] = $term;
- }
- #TODO: there are no $page->{pageNumber,productPerPage} because component have start after cms.page.init
- $pageNumber = request()->input('page', $page->pageNumber);
- $defaultPerPage = 20;
- $productPerPage = request()->input('limit', $defaultPerPage);
- $sort = request()->input('sort', []);
- $params = [];
- $params['category'] = $category;
- $params['characteristics_values'] = $characteristicsValues;
- $params['term'] = $term;
- $params['ranges'] = $ranges;
- $params['page'] = $pageNumber;
- $params['size'] = $productPerPage;
- $params['sort'] = $sort;
- $params['tags'] = null;
- $cacheKey = serialize([
- 'matchish.sitesearch.plugin',
- 'category_id' => $category ? $category->id : null,
- 'values_ids' => $characteristicsValues ? $characteristicsValues->pluck('id')->all() : null,
- 'ranges' => $ranges,
- 'term' => $term,
- 'size' => $productPerPage,
- 'sort' => $sort,
- 'page' => $pageNumber,
- ]);
- $job = new FetchCatalogPage($params);
- $cacheTags = [
- app(Product::class)->getTable(),
- app(Category::class)->getTable(),
- app(Characteristic::class)->getTable(),
- app(CharacteristicValue::class)->getTable(),
- ];
- list($categoriesStatistics, $products, $filter) = \Cache::tags($cacheTags)->rememberForever($cacheKey,
- function () use ($job, $controller) {
- $response = $job->handle();
- $filter = $response->getCharacteristicsAggregations();
- $products = $response->getResults();
- $categoriesStatistics = $response->getCategoriesAggregations();
- return [
- $categoriesStatistics,
- $products,
- //TODO: Можно кешировать партиал фильтра.
- //данные нигде не используются кроме как в этом партиале
- // а дополнительный запрос в кеш идет в компоненте.
- // Экономия 30 мс у меня на ноуте
- $filter,
- ];
- });
- $url = $filter->getUrl($page->getBaseFileName(), $category, $term);
- $parsed = parse_url($url);
- if (array_key_exists('path', $parsed)) {
- $products->setPath($parsed['path']);
- }
- if (array_key_exists('query', $parsed)) {
- parse_str($parsed['query'], $queryArr);
- $products->appends($queryArr);
- }
- if ($productPerPage != $defaultPerPage) {
- $products->appends(['limit' => $productPerPage]);
- }
- if ($term) {
- if (!$products->total()) {
- $corrector = new TextLangCorrect;
- $correctedTerm = $corrector->parse($term, $corrector::KEYBOARD_LAYOUT);
- if ($correctedTerm !== $term) {
- $controller->vars['correctedTerm'] = $correctedTerm;
- }
- } else {
- $query = Models\SearchQuery::firstOrCreate(['text' => mb_strtolower($term)]);
- $query->frequency = $query->frequency + 1;
- $query->hits = $products->total();
- $query->update();
- }
- }
- $controller->vars['sort'] = $sort;
- $controller->vars['products'] = $products;
- $controller->vars['productsList'] = new \Matchish\ProductCompare\ViewModels\ProductsList($products->all());
- $controller->vars['filter'] = $filter;
- $controller->vars['categoriesStatistics'] = $categoriesStatistics;
- $controller->vars['category'] = $category;
- });
- }
- }
Add Comment
Please, Sign In to add comment