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()};
}
}