Commit 6d318cfa authored by Dominik Hebeler's avatar Dominik Hebeler
Browse files

Added Parameter Filter

parent 67f81ca0
......@@ -29,6 +29,8 @@ class MetaGer
protected $phrases = [];
protected $engines = [];
protected $results = [];
protected $queryFilter = [];
protected $parameterFilter = [];
protected $ads = [];
protected $warnings = [];
protected $errors = [];
......@@ -528,7 +530,7 @@ class MetaGer
return;
}
$enabledSearchengines = [];
$this->enabledSearchengines = [];
$overtureEnabled = false;
# Check if selected focus is valid
......@@ -546,22 +548,31 @@ class MetaGer
# Check if this engine can use eventually defined query-filter
$valid = true;
foreach ($this->queryFilter as $queryFilter => $filter) {
if (empty($this->sumaFile->filter->$queryFilter->sumas->$suma)) {
if (empty($this->sumaFile->filter->{"query-filter"}->$queryFilter->sumas->$suma)) {
$valid = false;
break;
}
}
# Check if this engine can use eventually defined parameter-filter
if ($valid) {
foreach ($this->parameterFilter as $filterName => $filter) {
if (empty($filter->sumas->$suma)) {
$valid = false;
break;
}
}
}
# If it can we add it
if ($valid) {
$enabledSearchengines[$suma] = $this->sumaFile->sumas->{$suma};
$this->enabledSearchengines[$suma] = $this->sumaFile->sumas->{$suma};
}
}
if (sizeof($enabledSearchengines) === 0) {
if (sizeof($this->enabledSearchengines) === 0) {
$filter = "";
foreach ($this->queryFilter as $queryFilter => $filterPhrase) {
$filter .= trans($this->sumaFile->filter->{$queryFilter}->name) . ",";
$filter .= trans($this->sumaFile->filter->{"query-filter"}->{$queryFilter}->name) . ",";
}
$filter = rtrim($filter, ",");
$error = trans('metaGer.engines.noSpecialSearch', ['fokus' => trans($this->sumaFile->foki->{$this->fokus}->{"display-name"}),
......@@ -570,7 +581,6 @@ class MetaGer
}
$engines = [];
$typeslist = [];
$counter = 0;
......@@ -581,8 +591,9 @@ class MetaGer
$engine->setResultHash($this->getHashCode());
}
} else {
$engines = $this->actuallyCreateSearchEngines($enabledSearchengines);
$engines = $this->actuallyCreateSearchEngines($this->enabledSearchengines);
}
# Wir starten alle Suchen
foreach ($engines as $engine) {
$engine->startSearch($this);
......@@ -661,6 +672,24 @@ class MetaGer
return $engines;
}
public function getAvailableParameterFilter()
{
$parameterFilter = $this->sumaFile->filter->{"parameter-filter"};
$availableFilter = [];
foreach ($parameterFilter as $filterName => $filter) {
# Check if any of the enabled search engines provide this filter
foreach ($this->enabledSearchengines as $engineName => $engine) {
if (!empty($filter->sumas->$engineName)) {
$availableFilter[$filterName] = $filter;
}
}
}
return $availableFilter;
}
public function isBildersuche()
{
return $this->fokus === "bilder";
......@@ -843,13 +872,6 @@ class MetaGer
}
}
# Nicht fertige Engines verwefen
foreach ($engines as $engine) {
if (!$engine->loaded) {
$engine->shutdown();
}
}
$this->engines = $engines;
}
......@@ -1006,10 +1028,7 @@ class MetaGer
$this->searchCheckPhrase();
# Check for query-filter (i.e. Sitesearch, etc.):
foreach ($this->sumaFile->filter as $filterName => $filter) {
if ($filter->type !== "query-filter") {
continue;
}
foreach ($this->sumaFile->filter->{"query-filter"} as $filterName => $filter) {
if (!empty($filter->{"optional-parameter"}) && $request->filled($filter->{"optional-parameter"})) {
$this->queryFilter[$filterName] = $request->input($filter->{"optional-parameter"});
} else if (preg_match_all("/" . $filter->regex . "/si", $this->q, $matches) > 0) {
......@@ -1027,6 +1046,19 @@ class MetaGer
}
}
# Check for parameter-filter (i.e. SafeSearch)
$this->parameterFilter = [];
$usedParameters = [];
foreach ($this->sumaFile->filter->{"parameter-filter"} as $filterName => $filter) {
if (!empty($usedParameters[$filter->{"get-parameter"}])) {
die("Der Get-Parameter \"" . $filter->{"get-parameter"} . "\" wird mehrfach verwendet!");
} else {
$usedParameters[$filter->{"get-parameter"}] = true;
}
if ($request->filled($filter->{"get-parameter"})) {
$this->parameterFilter[$filterName] = $filter;
}
}
$this->searchCheckHostBlacklist($request);
$this->searchCheckDomainBlacklist($request);
$this->searchCheckUrlBlacklist();
......@@ -1336,7 +1368,12 @@ class MetaGer
public function generateSearchLink($fokus, $results = true)
{
$requestData = $this->request->except(['page', 'next']);
$except = ['page', 'next'];
# Remove every Filter
foreach ($this->sumaFile->filter->{"parameter-filter"} as $filterName => $filter) {
$except[] = $filter->{"get-parameter"};
}
$requestData = $this->request->except($except);
$requestData['focus'] = $fokus;
$requestData['out'] = "";
......@@ -1509,6 +1546,11 @@ class MetaGer
return $this->queryFilter;
}
public function getParameterFilter()
{
return $this->parameterFilter;
}
public function getTime()
{
return $this->time;
......
......@@ -7,6 +7,7 @@ use App\MetaGer;
use Cache;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Support\Facades\Redis;
use Request;
abstract class Searchengine
{
......@@ -46,9 +47,11 @@ abstract class Searchengine
$this->name = $name;
# Cache Standarddauer 60
if (!isset($this->cacheDuration)) {
$this->cacheDuration = 60;
if (!empty($engine->{"cache-duration"}) && $engine->{"cache-duration"} >= 0) {
$this->cacheDuration = $engine->{"cache-duration"};
}
$this->useragent = $metager->getUserAgent();
$this->ip = $metager->getIp();
$this->startTime = microtime();
......@@ -64,12 +67,23 @@ abstract class Searchengine
$q = $metager->getQ();
$filters = $metager->getSumaFile()->filter;
foreach ($metager->getQueryFilter() as $queryFilter => $filter) {
$filterOptions = $filters->$queryFilter;
$filterOptions = $filters->{"query-filter"}->$queryFilter;
$filterOptionsEngine = $filterOptions->sumas->{$this->name};
$query = $filterOptionsEngine->prefix . $filter . $filterOptionsEngine->suffix;
$q = $query . " " . $q;
}
# Parse enabled Parameter-Filter
foreach ($metager->getParameterFilter() as $filterName => $filter) {
$inputParameter = Request::input($filter->{"get-parameter"}, "");
if (empty($inputParameter) || empty($filter->sumas->{$name}->values->{$inputParameter})) {
continue;
}
$engineParameterKey = $filter->sumas->{$name}->{"get-parameter"};
$engineParameterValue = $filter->sumas->{$name}->values->{$inputParameter};
$this->engine->{"get-parameter"}->{$engineParameterKey} = $engineParameterValue;
}
$this->getString = $this->generateGetString($q);
$this->hash = md5($this->engine->host . $this->getString . $this->engine->port . $this->name);
$this->resultHash = $metager->getHashCode();
......
......@@ -9,9 +9,9 @@ class Ebay extends Searchengine
{
public $results = [];
public function __construct(\SimpleXMLElement $engine, \App\MetaGer $metager)
public function __construct($name, \stdClass $engine, \App\MetaGer $metager)
{
parent::__construct($engine, $metager);
parent::__construct($name, $engine, $metager);
}
public function loadResults($result)
......@@ -51,7 +51,7 @@ class Ebay extends Searchengine
$link,
$anzeigeLink,
$descr,
$this->displayName,$this->homepage,
$this->engine->{"display-name"}, $this->engine->homepage,
$this->counter,
['partnershop' => false,
'price' => $price,
......
......@@ -6,11 +6,11 @@ use App\Models\Searchengine;
class Minisucher extends Searchengine
{
public function __construct(\SimpleXMLElement $engine, \App\MetaGer $metager)
public function __construct($name, \stdClass $engine, \App\MetaGer $metager)
{
parent::__construct($engine, $metager);
parent::__construct($name, $engine, $metager);
# Für die Newssuche stellen wir die Minisucher auf eine Sortierung nach Datum um.
if($metager->getFokus() === "nachrichten"){
if ($metager->getFokus() === "nachrichten") {
$this->getString .= "sort=" . $this->urlencode("documentDate desc");
}
}
......@@ -28,7 +28,6 @@ class Minisucher extends Searchengine
$results = $content->xpath('//response/result/doc');
$string = "";
$counter = 0;
......@@ -42,10 +41,12 @@ class Minisucher extends Searchengine
$link = $result->xpath('//doc/str[@name="url"]')[0]->__toString();
$anzeigeLink = $link;
$descr = "";
$descriptions = $content->xpath("//response/lst[@name='highlighting']/lst[@name='$link']/arr[@name='content']/str");
foreach ($descriptions as $description) {
$descr .= $description->__toString();
}
$descr = strip_tags($descr);
$dateString = $result->xpath('//doc/date[@name="documentDate"]')[0]->__toString();
......@@ -56,17 +57,9 @@ class Minisucher extends Searchengine
$additionalInformation = ['date' => $dateVal];
$minism = simplexml_load_string($this->engine)["subcollections"];
$subcollection = $result->xpath('//doc/str[@name="subcollection"]')[0]->__toString();
if(!$subcollection) {
$minism = $this->engine->{"display-name"};
$gefVon = "Minisucher: $minism";
} else {
$minism = array_map('strtolower', explode(', ', $minism));
$subcollection = array_map('strtolower', explode(' ', $subcollection));
$result = implode(', ', array_intersect($subcollection, $minism));
$gefVon = "Minisucher: $result";
}
$subcollection = $result->xpath('//doc/str[@name="subcollection"]')[0]->__toString();
$this->results[] = new \App\Models\Result(
$this->engine,
......@@ -78,6 +71,7 @@ class Minisucher extends Searchengine
$counter,
$additionalInformation
);
} catch (\ErrorException $e) {
continue;
}
......
......@@ -9,9 +9,9 @@ class Mnogosearch extends Searchengine
{
public $results = [];
public function __construct(\SimpleXMLElement $engine, \App\MetaGer $metager)
public function __construct($name, \stdClass $engine, \App\MetaGer $metager)
{
parent::__construct($engine, $metager);
parent::__construct($name, $engine, $metager);
}
public function loadResults($result)
......@@ -39,7 +39,7 @@ class Mnogosearch extends Searchengine
$link,
$anzeigeLink,
$descr,
$this->displayName,$this->homepage,
$this->engine->{"display-name"}, $this->engine->homepage,
$this->counter
);
});
......
......@@ -8,9 +8,9 @@ class Nebel extends Searchengine
{
public $results = [];
public function __construct(\SimpleXMLElement $engine, \App\MetaGer $metager)
public function __construct($name, \stdClass $engine, \App\MetaGer $metager)
{
parent::__construct($engine, $metager);
parent::__construct($name, $engine, $metager);
}
public function loadResults($result)
......@@ -34,7 +34,7 @@ class Nebel extends Searchengine
$link,
$anzeigeLink,
$descr,
$this->displayName,$this->homepage,
$this->engine->{"display-name"}, $this->engine->homepage,
$this->counter
);
}
......
......@@ -8,9 +8,9 @@ class Witch extends Searchengine
{
public $results = [];
public function __construct(\SimpleXMLElement $engine, \App\MetaGer $metager)
public function __construct($name, \stdClass $engine, \App\MetaGer $metager)
{
parent::__construct($engine, $metager);
parent::__construct($name, $engine, $metager);
}
public function loadResults($result)
......@@ -37,7 +37,7 @@ class Witch extends Searchengine
$link,
$anzeigeLink,
$descr,
$this->displayName,$this->homepage,
$this->engine->{"display-name"}, $this->engine->homepage,
$this->counter
);
}
......@@ -50,10 +50,10 @@ class Witch extends Searchengine
return;
}
$next = new Witch(simplexml_load_string($this->engine), $metager);
$offset = $metager->getPage() * 10;
$next->getString = preg_replace("/&cn=\d+/si", "&cn=$offset", $next->getString);
$next->hash = md5($next->host . $next->getString . $next->port . $next->name);
$newEngine = unserialize(serialize($this->engine));
$newEngine->{"get-parameter"}->cn = "$offset";
$next = new Witch($this->name, $newEngine, $metager);
$this->next = $next;
}
}
......@@ -9,9 +9,9 @@ class Yacy extends Searchengine
{
public $results = [];
public function __construct(\SimpleXMLElement $engine, \App\MetaGer $metager)
public function __construct($name, \stdClass $engine, \App\MetaGer $metager)
{
parent::__construct($engine, $metager);
parent::__construct($name, $engine, $metager);
}
public function loadResults($result)
......@@ -21,9 +21,9 @@ class Yacy extends Searchengine
$content = json_decode($result, true);
$content = $content["channels"];
foreach($content as $channel){
foreach ($content as $channel) {
$items = $channel["items"];
foreach($items as $item){
foreach ($items as $item) {
$title = $item["title"];
$link = $item["link"];
$anzeigeLink = $link;
......@@ -36,7 +36,7 @@ class Yacy extends Searchengine
$link,
$anzeigeLink,
$descr,
$this->displayName,$this->homepage,
$this->engine->{"display-name"}, $this->engine->homepage,
$this->counter
);
}
......
sumas.xml
sumasEn.xml
sumas.json
blacklistUrl.txt
blacklistDomains.txt
\ No newline at end of file
......@@ -18,7 +18,8 @@ return [
'plugin' => 'MetaGer-Plugin hinzufügen',
'plugin-title' => 'MetaGer zu Ihrem Browser hinzufügen',
'focus-creator.head' => 'Eigene Suche erstellen',
'options.head' => 'Filter verwalten',
'focus-creator.description' => 'Suchen Sie sich aus unseren Suchmaschinen Ihre eigene Suche zusammen.',
'focus-creator.name-placeholder' => 'Name der eigenen Suche',
'focus-creator.save' => 'Eigene Suche durchführen',
......
......@@ -21,5 +21,62 @@ return [
'sitesearch.failed' => 'Sie wollten eine Sitesearch auf :site durchführen. Leider unterstützen die eingestellten Suchmaschinen diese nicht. Sie können die Sitesearch im Web-Fokus durchführen. Es werden ihnen Ergebnisse ohne Sitesearch angezeigt.',
'sitesearch.success' => 'Sie führen eine Sitesearch durch. Es werden nur Ergebnisse von der Seite: ":site" angezeigt.',
'feedback' => 'Nichts Passendes dabei? Geben Sie uns Feedback: ',
'filter.noFilter' => 'Alle',
'filter.sitesearch' => 'Sitesearch',
'filter.safesearch' => "SafeSearch",
'filter.safesearch.strict' => 'Strikt',
'filter.safesearch.moderate' => 'Moderat',
'filter.safesearch.off' => 'Aus',
'filter.size' => 'Bildgröße',
'filter.size.small' => 'Klein',
'filter.size.medium' => 'Mittel',
'filter.size.large' => 'Groß',
'filter.size.xtralarge' => 'Extra Groß',
"filter.color" => "Farbe",
"filter.color.colorOnly" => "Nur Farbe",
"filter.color.monochrome" => "Schwarzweiß",
"filter.color.black" => "Schwarz",
"filter.color.blue" => "Blau",
"filter.color.brown" => "Braun",
"filter.color.gray" => "Grau",
"filter.color.green" => "Grün",
"filter.color.orange" => "Orange",
"filter.color.pink" => "Pink",
"filter.color.purple" => "Lila",
"filter.color.red" => "Rot",
"filter.color.teal" => "Petrol",
"filter.color.white" => "Weiß",
"filter.color.yellow" => "Gelb",
"filter.imagetype" => "Typ",
"filter.imagetype.photo" => "Foto",
"filter.imagetype.clipart" => "Grafik",
"filter.imagetype.strich" => "Strichzeichnung",
"filter.imagetype.gif" => "Animierte GIF",
"filter.imagetype.transparent" => "Transparent",
"filter.imageaspect" => "Layout",
"filter.imageaspect.square" => "Rechteck",
"filter.imageaspect.wide" => "Breit",
"filter.imageaspect.tall" => "Hoch",
"filter.imagecontent" => "Personen",
"filter.imagecontent.face" => "Nahaufnahmen",
"filter.imagecontent.portrait" => "Kopf & Schultern",
"filter.imagelicense" => "Lizenz",
"filter.imagelicense.any" => "Beliebig",
"filter.imagelicense.public" => "Public Domain",
"filter.imagelicense.share" => "Teilen",
"filter.imagelicense.sharecommercially" => "Teilen (kommerziell)",
"filter.imagelicense.modify" => "Verändern",
"filter.imagelicense.modifycommercially" => "Verändern (kommerziell)",
"filter.freshness" => "Datum",
"filter.freshness.day" => "Letzte 24h",
"filter.freshness.week" => "Letzte Woche",
"filter.freshness.month" => "Letzter Monat",
];
......@@ -332,7 +332,7 @@ a {
margin-left: @results-margin-left;
display: grid;
grid-template-columns: @results-width-max @additions-width-max;
grid-template-areas: "searchbar ." "foki ." "results additions";
grid-template-areas: "searchbar ." "foki ." "options ." "results additions";
grid-column-gap: (@padding-small-default * 2);
grid-row-gap: @padding-small-default;
justify-items: stretch;
......@@ -372,13 +372,13 @@ a {
@media (max-width: @resultpage-breakpoint-max) {
@supports (display: grid) {
grid-template-columns:~"calc(60% - 8px)"~"calc(40% - 8px)";
grid-template-areas: "searchbar ." "foki ." "results additions";
grid-template-areas: "searchbar ." "foki ." "options ." "results additions";
}
}
@media (max-width: @resultpage-breakpoint-min) {
margin-left: @padding-small-default;
grid-template-columns: 100%;
grid-template-areas: "searchbar" "foki" "results";
grid-template-areas: "searchbar" "foki" "options" "results";
#additions-container {
display: none;
}
......@@ -480,6 +480,60 @@ a {
}
}
#options {
grid-area: options;
display: flex;
justify-content: left;
input[type=checkbox]{
display: none;
}
.scrollbox {
max-height: 0;
transform-origin: top;
transform: scaleY(0);
transition: transform .5s, max-height .5s;
}
input[type=checkbox]:checked + div.scrollbox {
max-height:200px;
transform: scaleY(1);
}
#options-box{
width: 100%;
max-width: 700px;
background-color: white;
border: 1px solid #ccc;
box-shadow: 0px 1px 1.5px 0px rgba(0, 0, 0, 0.12), 1px 0px 1px 0px rgba(0, 0, 0, 0.24);
overflow: hidden;
overflow-x: auto;
padding: 8px;
#options-items {
display: -ms-flexbox;
display: flex;
align-items: center;
.option-selector {
display: flex;
flex-direction: column;
margin: 0 8px;
justify-content: center;
align-items: center;
label {
margin-bottom: 0;
}
select {
background-color: white;
border: 1px solid #77777780;
padding: 3px;
border-radius: 5px;
}
}
}
#options-reset {
margin-left: 10px;
margin-bottom: 8px;
}
}
}
#spendenaufruf {
margin-bottom: 10px;
a {
......
......@@ -26,6 +26,35 @@
<div class="scrollfade-right"></div>
</div>
</div>
@if(sizeof($metager->getAvailableParameterFilter()) > 0)
<div id="options">
<input type="checkbox" id="options-toggle" @if(sizeof($metager->getParameterFilter()) > 0)checked @endif />
<div class="scrollbox">
<div class="scrollfade-left"></div>
<div id="options-box">
@if(sizeof($metager->getParameterFilter()) > 0)
<div id="options-reset">
<a href="{{$metager->generateSearchLink($metager->getFokus())}}"><nobr>Filter zurücksetzen</nobr></a>
</div>
@endif
<div id="options-items">
@foreach($metager->getAvailableParameterFilter() as $filterName => $filter)
<div class="option-selector">
<label for="{{$filterName}}">@lang($filter->name)</label>
<select name="{{$filter->{'get-parameter'} }}" form="searchForm">
@foreach($filter->values as $value => $text)
<option value="{{$value}}" @if(Request::input($filter->{'get-parameter'}, '') === $value)selected="selected" @endif>{{trans($text)}}</option>
@endforeach
</select>
</div>
@endforeach
</div>
</div>
<div class="scrollfade-right"></div>
</div>
</div>
@endif
<div id="results-container">
@include('parts.errors')
@include('parts.warnings')
......
@if( array_has($metager->getAvailableFoki(), "web"))
<div id="web" @if($metager->getFokus() === "web")class="active"@endif>