Commit 4eae602e authored by Tino Goratsch's avatar Tino Goratsch

Squashed 'ACP3/Modules/ACP3/Search/' content from commit 2a77555

git-subtree-dir: ACP3/Modules/ACP3/Search
git-subtree-split: 2a775554c7a4be0e2a861114cfecae41cdab5450
parents
.idea
vendor/
<?php
namespace ACP3\Modules\ACP3\Search\Controller;
use ACP3\Core;
use ACP3\Modules\ACP3\Search;
/**
* Class Index
* @package ACP3\Modules\ACP3\Search\Controller
*/
class Index extends Core\Modules\Controller\Frontend
{
/**
* @var \ACP3\Modules\ACP3\Search\Helpers
*/
protected $searchHelpers;
/**
* @var \ACP3\Modules\ACP3\Search\Validator
*/
protected $searchValidator;
/**
* @var \ACP3\Modules\ACP3\Search\Extensions
*/
protected $searchExtensions;
/**
* @param \ACP3\Core\Context\Frontend $context
* @param \ACP3\Modules\ACP3\Search\Helpers $searchHelpers
* @param \ACP3\Modules\ACP3\Search\Validator $searchValidator
* @param \ACP3\Modules\ACP3\Search\Extensions $searchExtensions
*/
public function __construct(
Core\Context\Frontend $context,
Search\Helpers $searchHelpers,
Search\Validator $searchValidator,
Search\Extensions $searchExtensions)
{
parent::__construct($context);
$this->searchHelpers = $searchHelpers;
$this->searchValidator = $searchValidator;
$this->searchExtensions = $searchExtensions;
}
public function actionIndex()
{
if (empty($_POST) === false || isset($this->request->q)) {
$this->_indexPost(
(empty($_POST) === false) ? $_POST : ['search_term' => $this->request->q]
);
}
$this->view->assign('form', array_merge(['search_term' => ''], $_POST));
$this->view->assign('search_mods', $this->searchHelpers->getModules());
// Zu durchsuchende Bereiche
$langSearchAreas = [
$this->lang->t('search', 'title_and_content'),
$this->lang->t('search', 'title_only'),
$this->lang->t('search', 'content_only')
];
$this->view->assign('search_areas', $this->get('core.helpers.forms')->selectGenerator('area', ['title_content', 'title', 'content'], $langSearchAreas, 'title_content', 'checked'));
// Treffer sortieren
$langSortHits = [$this->lang->t('search', 'asc'), $this->lang->t('search', 'desc')];
$this->view->assign('sort_hits', $this->get('core.helpers.forms')->selectGenerator('sort', ['asc', 'desc'], $langSortHits, 'asc', 'checked'));
}
/**
* @param $modules
* @param $searchTerm
* @param $area
* @param $sort
*/
protected function _displaySearchResults($modules, $searchTerm, $area, $sort)
{
$this->breadcrumb
->append($this->lang->t('search', 'search'), 'search')
->append($this->lang->t('search', 'search_results'));
$searchResults = [];
foreach ($modules as $module) {
$action = $module . 'Search';
if (method_exists($this->searchExtensions, $action) &&
$this->acl->hasPermission('frontend/' . $module) === true
) {
$this->searchExtensions
->setArea($area)
->setSort($sort)
->setSearchTerm($searchTerm);
$searchResults = array_merge($searchResults, $this->searchExtensions->$action());
}
}
if (!empty($searchResults)) {
ksort($searchResults);
$this->view->assign('results_mods', $searchResults);
} else {
$this->view->assign('no_search_results', sprintf($this->lang->t('search', 'no_search_results'), $searchTerm));
}
$this->setTemplate('Search/Frontend/index.results.tpl');
}
/**
* @param array $formData
*/
protected function _indexPost(array $formData)
{
try {
if (isset($formData['search_term']) === true) {
if (isset($formData['mods']) === false) {
$modules = $this->searchHelpers->getModules();
$formData['mods'] = [];
foreach ($modules as $row) {
$formData['mods'][] = $row['dir'];
}
}
if (isset($formData['area']) === false) {
$formData['area'] = 'title_content';
}
if (isset($formData['sort']) === false) {
$formData['sort'] = 'asc';
}
}
$this->searchValidator->validate($formData);
$this->_displaySearchResults(
$formData['mods'],
Core\Functions::strEncode($formData['search_term']),
$formData['area'],
strtoupper($formData['sort'])
);
} catch (Core\Exceptions\ValidationFailed $e) {
$this->view->assign('error_msg', $this->get('core.helpers.alerts')->errorBox($e->getMessage()));
}
}
}
<?php
namespace ACP3\Modules\ACP3\Search\Controller\Sidebar;
use ACP3\Core;
use ACP3\Modules\ACP3\Search;
/**
* Class Index
* @package ACP3\Modules\ACP3\Search\Controller\Sidebar
*/
class Index extends Core\Modules\Controller
{
/**
* @var \ACP3\Modules\ACP3\Search\Helpers
*/
protected $searchHelpers;
/**
* @param \ACP3\Core\Context $context
* @param \ACP3\Modules\ACP3\Search\Helpers $searchHelpers
*/
public function __construct(
Core\Context $context,
Search\Helpers $searchHelpers)
{
parent::__construct($context);
$this->searchHelpers = $searchHelpers;
}
public function actionIndex()
{
$this->view->assign('search_mods', $this->searchHelpers->getModules());
$this->setTemplate('Search/Sidebar/index.index.tpl');
}
}
<?php
namespace ACP3\Modules\ACP3\Search;
use ACP3\Core;
use ACP3\Modules\ACP3\Articles;
use ACP3\Modules\ACP3\Files;
use ACP3\Modules\ACP3\News;
/**
* Class Extensions
* @package ACP3\Modules\ACP3\Search
*/
class Extensions
{
/**
*
* @var string
*/
protected $area;
/**
* Whether to sort the results ascending/descending
*
* @var string
*/
protected $sort;
/**
* The search term
*
* @var string
*/
protected $searchTerm;
/**
* The current datetime
*
* @var string
*/
protected $time;
/**
* @var \ACP3\Core\Lang
*/
protected $lang;
/**
* @var \ACP3\Core\Router
*/
protected $router;
/**
* @var \ACP3\Modules\ACP3\Articles\Model
*/
protected $articlesModel;
/**
* @var \ACP3\Modules\ACP3\Files\Model
*/
protected $filesModel;
/**
* @var \ACP3\Modules\ACP3\News\Model
*/
protected $newsModel;
/**
* @param Core\Date $date
* @param Core\Lang $lang
* @param Core\Router $router
*/
public function __construct(
Core\Date $date,
Core\Lang $lang,
Core\Router $router
) {
$this->lang = $lang;
$this->router = $router;
$this->time = $date->getCurrentDateTime();
}
/**
* @param \ACP3\Modules\ACP3\Articles\Model $articlesModel
*
* @return $this
*/
public function setArticlesModel(Articles\Model $articlesModel)
{
$this->articlesModel = $articlesModel;
return $this;
}
/**
* @param \ACP3\Modules\ACP3\Files\Model $filesModel
*
* @return $this
*/
public function setFilesModel(Files\Model $filesModel)
{
$this->filesModel = $filesModel;
return $this;
}
/**
* @param \ACP3\Modules\ACP3\News\Model $newsModel
*
* @return $this
*/
public function setNewsModel(News\Model $newsModel)
{
$this->newsModel = $newsModel;
return $this;
}
/**
* @param $area
*
* @return $this
*/
public function setArea($area)
{
$this->area = $area;
return $this;
}
/**
* @param $sort
*
* @return $this
*/
public function setSort($sort)
{
$this->sort = $sort;
return $this;
}
/**
* @param $searchTerm
*
* @return $this
*/
public function setSearchTerm($searchTerm)
{
$this->searchTerm = $searchTerm;
return $this;
}
/**
* @return array
*/
public function articlesSearch()
{
$searchResults = [];
if ($this->filesModel) {
switch ($this->area) {
case 'title':
$fields = 'title';
break;
case 'content':
$fields = 'text';
break;
default:
$fields = 'title, text';
}
$results = $this->articlesModel->getAllSearchResults($fields, $this->searchTerm, $this->sort, $this->time);
$c_results = count($results);
if ($c_results > 0) {
$name = $this->lang->t('articles', 'articles');
$searchResults[$name]['dir'] = 'articles';
for ($i = 0; $i < $c_results; ++$i) {
$searchResults[$name]['results'][$i] = $results[$i];
$searchResults[$name]['results'][$i]['hyperlink'] = $this->router->route('articles/index/details/id_' . $results[$i]['id']);
}
}
}
return $searchResults;
}
/**
* @return array
*/
public function filesSearch()
{
$searchResults = [];
if ($this->filesModel) {
switch ($this->area) {
case 'title':
$fields = 'title, file';
break;
case 'content':
$fields = 'text';
break;
default:
$fields = 'title, file, text';
}
$results = $this->filesModel->getAllSearchResults($fields, $this->searchTerm, $this->sort, $this->time);
$c_results = count($results);
if ($c_results > 0) {
$name = $this->lang->t('files', 'files');
$searchResults[$name]['dir'] = 'files';
for ($i = 0; $i < $c_results; ++$i) {
$searchResults[$name]['results'][$i] = $results[$i];
$searchResults[$name]['results'][$i]['hyperlink'] = $this->router->route('files/index/details/id_' . $results[$i]['id']);
}
}
}
return $searchResults;
}
/**
* @return array
*/
public function newsSearch()
{
$searchResults = [];
if ($this->newsModel) {
switch ($this->area) {
case 'title':
$fields = 'title';
break;
case 'content':
$fields = 'text';
break;
default:
$fields = 'title, text';
}
$results = $this->newsModel->getAllSearchResults($fields, $this->searchTerm, $this->sort, $this->time);
$c_results = count($results);
if ($c_results > 0) {
$name = $this->lang->t('news', 'news');
$searchResults[$name]['dir'] = 'news';
for ($i = 0; $i < $c_results; ++$i) {
$searchResults[$name]['results'][$i] = $results[$i];
$searchResults[$name]['results'][$i]['hyperlink'] = $this->router->route('news/index/details/id_' . $results[$i]['id']);
}
}
}
return $searchResults;
}
}
<?php
namespace ACP3\Modules\ACP3\Search;
use ACP3\Core;
/**
* Class Helpers
* @package ACP3\Modules\ACP3\Search
*/
class Helpers
{
/**
* @var \ACP3\Core\ACL
*/
protected $acl;
/**
* @var \ACP3\Core\Modules
*/
protected $modules;
/**
* @var \ACP3\Core\Helpers\Forms
*/
protected $formsHelper;
/**
* @var \ACP3\Modules\ACP3\Search\Extensions
*/
protected $searchExtensions;
/**
* @param \ACP3\Core\ACL $acl
* @param \ACP3\Core\Modules $modules
* @param \ACP3\Core\Helpers\Forms $formsHelper
* @param \ACP3\Modules\ACP3\Search\Extensions $searchExtensions
*/
public function __construct(
Core\ACL $acl,
Core\Modules $modules,
Core\Helpers\Forms $formsHelper,
Extensions $searchExtensions
) {
$this->acl = $acl;
$this->modules = $modules;
$this->formsHelper = $formsHelper;
$this->searchExtensions = $searchExtensions;
}
/**
* Gibt die für die Suche verfügbaren Module zurück
*
* @return array
*/
public function getModules()
{
$modules = get_class_methods($this->searchExtensions);
$searchModules = [];
foreach ($modules as $module) {
$module = substr($module, 0, strpos($module, 'Search'));
if ($this->acl->hasPermission('frontend/' . $module) === true) {
$info = $this->modules->getModuleInfo($module);
$name = $info['name'];
$searchModules[$name]['dir'] = $module;
$searchModules[$name]['checked'] = $this->formsHelper->selectEntry('mods', $module, $module, 'checked');
$searchModules[$name]['name'] = $name;
}
}
ksort($searchModules);
return $searchModules;
}
}
<?php
namespace ACP3\Modules\ACP3\Search;
use ACP3\Core\Modules;
/**
* Class Installer
* @package ACP3\Modules\ACP3\Search
*/
class Installer extends Modules\AbstractInstaller
{
const MODULE_NAME = 'search';
const SCHEMA_VERSION = 32;
/**
* @inheritdoc
*/
public function createTables()
{
return [];
}
/**
* @inheritdoc
*/
public function removeTables()
{
return [];
}
/**
* @inheritdoc
*/
public function settings()
{
return [];
}
/**
* @inheritdoc
*/
public function removeSettings()
{
return true;
}
/**
* @inheritdoc
*/
public function schemaUpdates()
{
return [
31 => [
"INSERT INTO `{pre}acl_resources` (`id`, `module_id`, `page`, `params`, `privilege_id`) VALUES ('', " . $this->getModuleId() . ", 'sidebar', '', 1);",
],
32 => [
'UPDATE `{pre}seo` SET `uri`=REPLACE(`uri`, "search/", "search/index/") WHERE `uri` LIKE "search/%";',
],
33 => [
$this->moduleIsInstalled('menus') || $this->moduleIsInstalled('menu_items') ? 'UPDATE `{pre}menu_items` SET `uri`=REPLACE(`uri`, "search/list/", "search/index/index/") WHERE `uri` LIKE "search/list/%";' : '',
]
];
}
}
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<language>
<info>
<name>Deutsch (Deutschland)</name>
<direction>ltr</direction>
</info>
<keys>
<item key="asc">Aufsteigend</item>
<item key="content_only">Nur Inhalt</item>
<item key="desc">Absteigend</item>
<item key="mod_description">Mit diesem Modul können andere Module durchsucht werden.</item>
<item key="no_area_selected">Bitte geben Sie an, welche Bereiche der Einträge durchsucht werden sollen.</item>
<item key="no_sorting_selected">Bitte wählen Sie aus, in welcher Reihenfolge die Treffer sortiert werden sollen.
</item>
<item key="no_module_selected">Bitte wählen Sie mindestens ein Modul aus, welches durchsucht werden soll.</item>
<item key="no_search_results">
<![CDATA[Es konnten keine Einträge mit dem Suchbegriff &quot;%s&quot; gefunden werden.]]></item>
<item key="search">Suche</item>
<item key="search_after_areas">Zu durchsuchende Bereiche</item>
<item key="search_after_modules">Zu durchsuchende Module</item>
<item key="search_options">Suchoptionen</item>
<item key="search_results">Suchergebnisse</item>
<item key="search_term">Suchbegriff</item>
<item key="search_term_to_short">Der Suchbegriff sollte mindestens 4 Zeichen lang sein.</item>
<item key="sort_hits">Reihenfolge der Treffer</item>
<item key="submit_search">Suche starten</item>
<item key="title_and_content">Titel und Inhalt</item>
<item key="title_only">Nur Titel</item>
</keys>
</language>
<?xml version="1.0" encoding="UTF-8"?>
<language>
<info>
<name>English (United States)</name>
<direction>ltr</direction>
</info>
<keys>
<item key="asc">Ascending</item>
<item key="content_only">Content only</item>
<item key="desc">Descending</item>
<item key="mod_description">With this module it is possible to search thorugh other modules.</item>
<item key="no_area_selected">Please specify which areas of the entries are to be searched.</item>
<item key="no_sorting_selected">Please sepcify the order of search results.</item>
<item key="no_module_selected">Please select at least one module, which is to be searched.</item>
<item key="no_search_results"><![CDATA[No entries matched search term &quot;%s&quot;.]]></item>
<item key="search">Search</item>
<item key="search_after_areas">Search through following areas</item>
<item key="search_after_modules">Search through following modules</item>
<item key="search_options">Search options</item>
<item key="search_results">Search results</item>
<item key="search_term">Search term</item>
<item key="search_term_to_short">The search term should be at least 4 characters long.</item>
<item key="sort_hits">Order of hits</item>
<item key="submit_search">Start search</item>
<item key="title_and_content">Title and content</item>
<item key="title_only">Title only</item>
</keys>
</language>
{extends file="asset:layout.tpl"}
{block CONTENT}
{if isset($error_msg)}
{$error_msg}
{/if}
{redirect_message}
<form action="{uri args="search"}" method="post" accept-charset="UTF-8" class="form-horizontal" data-ajax-form="true" data-ajax-form-loading-text="{lang t="system|loading_please_wait"}">
<div class="form-group">
<label for="search-term" class="col-sm-2 control-label">{lang t="search|search_term"}</label>
<div class="col-sm-10">
<input class="form-control" type="text" name="search_term" id="search-term" value="{$form.search_term}" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">{lang t="search|search_after_modules"}</label>
<div class="col-sm-10">
<div class="btn-group" data-toggle="buttons">
{foreach $search_mods as $row}
<label for="mods-{$row.dir}" class="btn btn-default{if !empty($row.checked)} active{/if}">
<input type="checkbox" name="mods[]" id="mods-{$row.dir}" value="{$row.dir}"{$row.checked}>
{$row.name}
</label>
{/foreach}
</div>
</div>
</div>
<div class="form-group">
<label for="{$search_areas.0.id}" class="col-sm-2 control-label">{lang t="search|search_after_areas"}</label>
<div class="col-sm-10">
<div class="btn-group" data-toggle="buttons">
{foreach $search_areas as $row}
<label for="{$row.id}" class="btn btn-default{if !empty($row.checked)} active{/if}">
<input type="radio" name="area" id="{$row.id}" value="{$row.value}"{$row.checked}>
{$row.lang}
</label>
{/foreach}
</div>
</div>
</div>
<div class="form-group">
<label for="{$sort_hits.0.id}" class="col-sm-2 control-label">{lang t="search|sort_hits"}</label>
<div class="col-sm-10">
<div class="btn-group" data-toggle="buttons">
{foreach $sort_hits as $row}
<label for="{$row.id}" class="btn btn-default{if !empty($row.checked)} active{/if}">
<input type="radio" name="sort" id="{$row.id}" value="{$row.value}"{$row.checked}>
{$row.lang}
</label>
{/foreach}
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="submit" class="btn btn-primary">{lang t="search|submit_search"}</button>
</div>
</div>
</form>
{javascripts}
{include_js module="system" file="forms"}
{/javascripts}
{/block}
\ No newline at end of file
{extends file="asset:layout.tpl"}
{block CONTENT}
{if isset($results_mods)}
<div class="tabbable">
<ul class="nav nav-tabs">
{$i=0}
{foreach $results_mods as $module => $values}
<li{if $i === 0} class="active"{/if}><a href="#tab-{$values.dir}" data-toggle="tab">{$module}</a></li>
{$i=$i+1}
{/foreach}
</ul>
<div class="tab-content">
{$i=0}
{foreach $results_mods as $module => $values}
<div id="tab-{$values.dir}" class="tab-pane{if $i === 0} active{/if}">
{foreach $values.results as $row}
<div class="dataset-box">
<header class="navbar navbar-default">
<div class="navbar-header">
<h2 class="navbar-brand"><a href="{$row.hyperlink}">{$row.title}</a></h2>
</div>
</header>
{if !empty($row.text)}
<div class="content">
{$row.text|strip_tags|truncate:200}
</div>
{/if}