birzha/plugins/offline/sitesearch/classes/providers/RainlabPagesResultsProvider...

171 lines
4.1 KiB
PHP

<?php
namespace OFFLINE\SiteSearch\Classes\Providers;
use October\Rain\Halcyon\Collection;
use OFFLINE\SiteSearch\Classes\Result;
use OFFLINE\SiteSearch\Models\Settings;
use RainLab\Pages\Classes\Page;
/**
* Searches the contents generated by the
* Rainlab.Pages plugin
*
* @package OFFLINE\SiteSearch\Classes\Providers
*/
class RainlabPagesResultsProvider extends ResultsProvider
{
/**
* Runs the search for this provider.
*
* @return ResultsProvider
*/
public function search()
{
if ( ! $this->isInstalledAndEnabled()) {
return $this;
}
foreach ($this->pages() as $page) {
// Make this result more relevant, if the query is found in the title
$title = $page->viewBag['meta_title'] ?? $page->viewBag['title'] ?? '';
$relevance = $this->containsQuery($title) ? 2 : 1;
$result = new Result($this->query, $relevance);
$result->title = $title;
$result->text = $page->parsedMarkup;
$result->url = $this->getUrl($page);
$result->model = $page;
$this->addResult($result);
}
return $this;
}
/**
* Get all pages with matching title or content.
*
* @return Collection
*/
protected function pages()
{
return Page::all()->filter(function ($page) {
$viewBag = $page->viewBag;
$isHidden = isset($viewBag['is_hidden']) ? (bool)$viewBag['is_hidden'] : false;
if ($isHidden) {
return false;
}
try {
return $this->containsQuery($page->parsedMarkup)
|| $this->containsQuery($page->placeholders)
|| $this->viewBagContainsQuery($viewBag);
} catch(\Throwable $e) {
// If an exception was thrown chances are that a page contained invalid markup.
return false;
}
});
}
/**
* Checks if the RainLab.Pages Plugin is installed and
* enabled in the config.
*
* @return bool
*/
protected function isInstalledAndEnabled()
{
return $this->isPluginAvailable($this->identifier)
&& Settings::get('rainlab_pages_enabled', true);
}
/**
* Checks if $subject contains the query string.
*
* @param $subject
*
* @return bool
*/
protected function containsQuery($subject)
{
return is_array($subject)
? $this->arrayContainsQuery($subject)
: mb_strpos(mb_strtolower($subject), mb_strtolower($this->query)) !== false;
}
/**
* Checks if a viewBag contains the query string.
*
* @param $viewBag
*
* @return bool
*/
protected function viewBagContainsQuery($viewBag)
{
$ignoreViewBagKeys = [
'url',
'layout',
'is_hidden',
'navigation_hidden',
];
$properties = collect($viewBag)->except($ignoreViewBagKeys)->toArray();
return $this->arrayContainsQuery($properties);
}
/**
* Checks if an array contains the query string.
*
* @param $array
*
* @return bool
*/
protected function arrayContainsQuery(array $array)
{
foreach ($array as $value) {
if ($this->containsQuery($value)) {
return true;
}
}
return false;
}
/**
* Display name for this provider.
*
* @return string
*/
public function displayName()
{
return Settings::get('rainlab_pages_label', 'Page');
}
/**
* Get the page's (translated) url.
*
* @param $page
*
* @return string
*/
protected function getUrl($page)
{
$langPrefix = $this->translator ? $this->translator->getLocale() : '';
return $langPrefix . $page->viewBag['url'];
}
/**
* Returns the plugin's identifier string.
*
* @return string
*/
public function identifier()
{
return 'RainLab.Pages';
}
}