birzha/plugins/offline/sitesearch/components/SearchResults.php

219 lines
5.6 KiB
PHP

<?php namespace OFFLINE\SiteSearch\Components;
use DomainException;
use Event;
use Illuminate\Pagination\LengthAwarePaginator;
use OFFLINE\SiteSearch\Classes\ResultCollection;
use OFFLINE\SiteSearch\Classes\SearchService;
use Request;
use Url;
/**
* SearchResults Component
* @package OFFLINE\SiteSearch\Components
*/
class SearchResults extends BaseComponent
{
/**
* The message to display when no results are returned.
*
* @var string
*/
public $noResultsMessage;
/**
* What link text to display below each result.
*
* @var string
*/
public $visitPageMessage;
/**
* Whether or not to display a provider badge for reach result.
*
* @var int
*/
public $showProviderBadge;
/**
* The user's search query.
*
* @var string
*/
public $query;
/**
* @var int
*/
protected $resultsPerPage = 10;
/**
* The collection of all results.
*
* @var ResultCollection
*/
public $resultCollection;
/**
* The current page number.
*
* @var int
*/
protected $pageNumber;
/**
* The developer's forced search query.
* This query is used instead of $query if set.
*
* @var string
*/
protected $forcedQuery;
public $myPaginator;
/**
* The component's details.
*
* @return array
*/
public function componentDetails()
{
return [
'name' => 'offline.sitesearch::lang.searchResults.title',
'description' => 'offline.sitesearch::lang.searchResults.description',
];
}
/**
* The component's properties.
*
* @return array
*/
public function defineProperties()
{
return [
'resultsPerPage' => [
'title' => 'offline.sitesearch::lang.searchResults.properties.results_per_page.title',
'type' => 'string',
'validationPattern' => '^[0-9]+$',
'validationMessage' => 'Please enter only numbers',
'default' => '10',
],
'showProviderBadge' => [
'title' => 'offline.sitesearch::lang.searchResults.properties.provider_badge.title',
'description' => 'offline.sitesearch::lang.searchResults.properties.provider_badge.description',
'type' => 'checkbox',
'default' => 1,
],
'noResultsMessage' => [
'title' => 'offline.sitesearch::lang.searchResults.properties.no_results.title',
'description' => 'offline.sitesearch::lang.searchResults.properties.no_results.description',
'type' => 'string',
'default' => 'Your search returned no results.',
'showExternalParam' => false,
],
'visitPageMessage' => [
'title' => 'offline.sitesearch::lang.searchResults.properties.visit_page.title',
'description' => 'offline.sitesearch::lang.searchResults.properties.visit_page.description',
'type' => 'string',
'default' => 'Visit page',
'showExternalParam' => false,
],
];
}
/**
* Component setup.
*
* @return void
*/
public function onRun()
{
$this->prepareVars();
$this->resultCollection = $this->search();
}
/**
* Force a query to be used.
*
* This can be useful if you want to process the
* "q" GET parameter yourself and then use a modified query
* for the search.
*
* @param $query
*/
public function forceQuery($query)
{
$this->forcedQuery = $query;
}
/**
* Setup all needed variables.
*
* @return void
*/
protected function prepareVars()
{
$query = $this->forcedQuery ? $this->forcedQuery : Request::get('q', '');
$this->setVar('pageNumber', (int)Request::get('page', 1));
$this->setVar('query', $query);
$this->setVar('noResultsMessage');
$this->setVar('visitPageMessage');
$this->setVar('showProviderBadge');
$this->setVar('resultsPerPage');
}
/**
* Fetch the search results.
*
* @throws DomainException
* @return ResultCollection
*/
protected function search()
{
$search = new SearchService($this->query, $this->controller);
return $search->results();
}
/**
* Return the paginated results.
*
* @return Paginator
*/
public function results()
{
$paginator = new LengthAwarePaginator(
$this->getPaginatorSlice($this->resultCollection),
$this->resultCollection->count(),
$this->resultsPerPage,
$this->pageNumber
);
$this->myPaginator = $paginator;
$pageUrl = Url::to(Request::url());
return $paginator->setPath($pageUrl)->appends('q', $this->query);
}
/**
* Return number of last page.
*
* @return int
*/
public function lastPage()
{
return (int)ceil($this->resultCollection->count() / $this->resultsPerPage);
}
/**
* Returns the slice for the current page + 1
* extra element to make the pagination work.
*
* @param $results
*
* @return ResultCollection
*/
protected function getPaginatorSlice($results)
{
return $results->slice(($this->pageNumber - 1) * $this->resultsPerPage, $this->resultsPerPage);
}
}