HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/topswtwmobile.komma.pro/app/KommaApp/Shop/Search/SearchService.php
<?php


namespace KommaApp\Shop\Search;

use KommaApp\Shop\Pages\PageRepository;
use KommaApp\Shop\Products\ProductRepository;
use KommaApp\Shop\Categories\CategoryRepository;
use MyProject\Proxies\__CG__\OtherProject\Proxies\__CG__\stdClass;

class SearchService
{
    /**
     * @var ProductRepository
     */
    private $productRepository;
    /**
     * @var CategoryRepository
     */
    private $categoryRepository;
    /**
     * @var PageRepository
     */
    private $pageRepository;

    /**
     * @param ProductRepository $productRepository
     * @param CategoryRepository $categoryRepository
     * @param PageRepository $pageRepository
     */
    public function __construct(
        ProductRepository $productRepository,
        CategoryRepository $categoryRepository,
        PageRepository $pageRepository
    )
    {
        $this->productRepository = $productRepository;
        $this->categoryRepository = $categoryRepository;
        $this->pageRepository = $pageRepository;
    }

    /**
     * @return array
     */
    public function searchProducts($query, $compact = false, $count = 10)
    {
        $results = $this->searchIndex('products', $query);

        if( ! isset($results['ids'])) return [];

        if($compact)
        {
            $results['result'] = $this->productRepository->getProductsByIdsCompact($results['ids'], $count);

            return $results;
        }
        $results['result'] = $this->productRepository->getProductsByIds($results['ids']);

        return $results;
    }

    public function searchCategories($query, $compact = false, $thorough = true, $count = 10)
    {
        $results = $this->searchIndex('categories', $query, $thorough);

        if( ! isset($results['ids'])) return [];

        if($compact)
        {
            $results['result'] = $this->categoryRepository->getCategoriesByIdsCompact($results['ids'], $count);

            return $results;
        }
        $results['result'] = $this->categoryRepository->getCategoriesByIds($results['ids']);

        //If in the first runn there are now categories found ($thorough== true), we will do a seccond runn with $thorough set to false
        if(empty($results['result']) && $thorough) return $this->searchCategories($query, $compact, false);

        return $results;
    }

    /**
     * @return array
     */
    public function searchPages($query, $compact = false, $count = 10)
    {
        $results = $this->searchIndex('pages', $query);

        if( ! isset($results['ids'])) return [];

        if($compact)
        {
            $results['result'] = $this->pageRepository->getPagesByIdsCompact($results['ids'], $count);

            return $results;
        }
        $results['result'] = $this->pageRepository->getPagesByIds($results['ids']);

        return $results;
    }

    /**
     * Search based on an index eg. products, categories,...
     *
     * @param $index
     * @param $query
     * @param $thorough , if set to false, there will be an less thorough search
     * @return array
     */

    public function searchIndex($index, $query, $thorough = true)
    {


        //If the query is empty return empty result
        if(empty($query)) return ['query' => '', 'result' => [], 'count' => 0];

        //Create a search index
        $result = \Search::index($index);
        //Check if $thorough is true
        if($thorough)
        {
            //$thorough is true, so we are going to search on each part individually

            //We are going to seperate the query in parts
            $query_parts = $this->prepare($query, true);

            //Loop trough the Query parts
            foreach ($query_parts as $part)
            {

                $part = preg_replace('#(^OR$)#i', '\'$1\'', $part);
                $part = preg_replace('#(^AND$)#i', '+', $part);

                //If the part is empty, skip to the next part
                if(empty($part)) continue;


                if(preg_match('/T[0-9]{5,}/i', $part))
                {
                    //T number strict search
                    $result = $result->search(null, $part, ['required' => true, 'fuzzy' => false]);
                    //continue to the next part
                    continue;
                }

                //Check if there is an number in the part
                if(preg_match('/(^[0-9]*$)|[+|\'|\"|\-|\s]/', $part))
                {
                    //Yes, so no fuzzy search, beceause numbers should be exact.
                    $result = $result->search(null, $part, ['required' => true, 'fuzzy' => false]);
                    //continue to the next part
                    continue;

                }

                //String without numbers maybe fuzzy eg "whitout" will be found as without.
                $result = $result->search(null, $part, ['required' => true, 'fuzzy' => true]);
            }
        } //thorough is false
        else
        {
            $fuzzy = true;
            if(preg_match('/(^[0-9]*$)|[+|\'|\"|\-|\s]/', $query)) $fuzzy = false;
            //Quick search on the entire string
            $result = $result->search(null, $this->prepare($query, false), ['required' => true, 'fuzzy' => $fuzzy]);
        }

        //Get only the results based on the shop_id and the language
        $result = $result
            ->where('shopId', \Shop::getId())
            ->where('languageId', '=', \Shop::getLanguageService()->getCurrentLanguageId())
            ->get();

        $results = [];
        $results['query'] = $query;
        $results['result'] = $result;
        $results['count'] = count($results['result']);
        $results['ids'] = [];
        foreach ($results['result'] as $result)
        {
            $results['ids'][] = $result['id'];
        }

        return $results;
    }

    /**
     * @param $repository
     * @return array
     */
    public function search($query)
    {

        $query = $this->prepare($query);
        if( ! $query) return ['query' => '', 'result' => [], 'count' => 0];

        $results = [];
        $results['query'] = $query;
        $results['result'] = \Search::search(null, $query, ['fuzzy' => true])
            ->where('shopId', \Shop::getId())
            ->where('languageId', \Shop::getLanguageService()->getCurrentLanguageId())
            ->get();
        $results['count'] = count($results['result']);

        $results['ids'] = [];
        foreach ($results['result'] as $result)
        {
            $results['ids'][] = $result['id'];
        }

        return $results;
    }

    protected function prepare($query, $parts = false)
    {
        $query = trim($query);
        $query = \Str::ascii($query);
        $query = preg_replace('/[^A-Za-z0-9\ \-+]/', ' ', $query);

        //Check if the parts is set
        if($parts)
        {
            //return the query in parts based on a space
            return explode(' ', $query);
        }

        return $query;
    }

    public function getRelatedSearchString($query)
    {

        $relatedSearchString = false;
        $newSearch = [];
        if( ! $relatedSearch = $this->getRelatedSearch()) return null;

        $query_parts = explode(' ', $query);
        //Loop trough the Query parts to collect releatedSearchItems
        foreach ($query_parts as $part)
        {
            //check if the part is in the related items, and add it to the relatedsearch
            if(isset($relatedSearch->{strtolower($part)}))
            {
                $newSearch [] = $relatedSearch->{strtolower($part)};
                $relatedSearchString = true;
                continue;
            }
            $newSearch [strtolower($part)] = $part;

        }

        if( ! $relatedSearchString) return null;

        return implode(' ', $newSearch);
    }


    /**
     * This method will get the json file of the related-search
     *
     * @return \stdClass
     *
     */
    protected function getRelatedSearch()
    {

        //Check if the file exist, if it fails, return empty object
        if( ! file_exists(app_path() . '/KommaApp/Shop/Search/related-search.json')) return false;
        //Get the file and json_decode, if it fails, return empty object
        if( ! $relatedSearch = json_decode(\File::get(app_path() . '/KommaApp/Shop/Search/related-search.json'))) return false;
        //Check if the language object exist, if it fails, return empty object
        if( ! isset($relatedSearch->{\Shop::getLanguageService()->getCurrentLanguage()})) return false;

        return $relatedSearch->{\Shop::getLanguageService()->getCurrentLanguage()};

    }

}