From 42e31f1063bfb821326e99733bca3d30cad86345 Mon Sep 17 00:00:00 2001 From: Dominik Hebeler <dominik@suma-ev.de> Date: Mon, 18 Feb 2019 14:29:41 +0100 Subject: [PATCH] Added Filter Options to the Websearch --- app/MetaGer.php | 34 ++++++++ app/Models/Searchengine.php | 8 +- app/Models/parserSkripte/Bing.php | 84 +++++++++++++++++++ app/Models/parserSkripte/BingBilder.php | 1 + app/Models/parserSkripte/Overture.php | 20 +++-- resources/lang/de/metaGer.php | 42 ++++++++++ resources/less/metager/general/general.less | 1 + .../metager/pages/resultpage/result-page.less | 47 +++++++---- .../less/metager/pages/resultpage/result.less | 2 +- .../views/layouts/researchandtabs.blade.php | 24 ++++-- resources/views/parts/foki.blade.php | 7 -- 11 files changed, 237 insertions(+), 33 deletions(-) create mode 100644 app/Models/parserSkripte/Bing.php diff --git a/app/MetaGer.php b/app/MetaGer.php index 5fe8044c5..65a1e4a69 100644 --- a/app/MetaGer.php +++ b/app/MetaGer.php @@ -28,6 +28,7 @@ class MetaGer protected $stopWords = []; protected $phrases = []; protected $engines = []; + protected $totalResults = 0; protected $results = []; protected $queryFilter = []; protected $parameterFilter = []; @@ -562,6 +563,21 @@ class MetaGer } } } + # Check if this engine should only be active when filter is used + if ($this->sumaFile->sumas->{$suma}->{"filter-opt-in"}) { + # This search engine should only be used when a parameter filter of it is used + $validTmp = false; + foreach ($this->parameterFilter as $filterName => $filter) { + if (!empty($filter->sumas->{$suma})) { + $validTmp = true; + break; + } + } + if (!$validTmp) { + $valid = false; + } + + } # If it can we add it if ($valid) { $this->enabledSearchengines[$suma] = $this->sumaFile->sumas->{$suma}; @@ -621,6 +637,11 @@ class MetaGer $this->waitForResults($enginesToLoad, $overtureEnabled, $canBreak); $this->retrieveResults($engines); + foreach ($engines as $engine) { + if (!empty($engine->totalResults) && $engine->totalResults > $this->totalResults) { + $this->totalResults = $engine->totalResults; + } + } } # Spezielle Suchen und Sumas @@ -685,6 +706,14 @@ class MetaGer $availableFilter[$filterName] = $filter; } } + # We will also add the filter from the opt-in search engines (the searchengines that are only used when a filter of it is too) + foreach ($this->sumaFile->foki->{$this->fokus}->sumas as $suma) { + if ($this->sumaFile->sumas->{$suma}->{"filter-opt-in"}) { + if (!empty($filter->sumas->{$suma})) { + $availableFilter[$filterName] = $filter; + } + } + } } return $availableFilter; @@ -1541,6 +1570,11 @@ class MetaGer return $this->sumaFile; } + public function getTotalResultCount() + { + return number_format($this->totalResults, 0, ",", "."); + } + public function getQueryFilter() { return $this->queryFilter; diff --git a/app/Models/Searchengine.php b/app/Models/Searchengine.php index b8a21b5a5..686268a28 100644 --- a/app/Models/Searchengine.php +++ b/app/Models/Searchengine.php @@ -15,6 +15,7 @@ abstract class Searchengine public $getString = ""; # Der String für die Get-Anfrage public $engine; # Die ursprüngliche Engine XML + public $totalResults = 0; # How many Results the Searchengine has found public $results = []; # Die geladenen Ergebnisse public $ads = []; # Die geladenen Werbungen public $products = []; # Die geladenen Produkte @@ -48,7 +49,7 @@ abstract class Searchengine # Cache Standarddauer 60 $this->cacheDuration = 60; - if (!empty($engine->{"cache-duration"}) && $engine->{"cache-duration"} >= 0) { + if (isset($engine->{"cache-duration"}) && $engine->{"cache-duration"} !== -1) { $this->cacheDuration = $engine->{"cache-duration"}; } @@ -183,6 +184,10 @@ abstract class Searchengine { foreach ($this->results as $result) { $result->rank($eingabe); + if (str_contains($this->engine->{"display-name"}, "Yahoo")) { + #die(var_dump($result)); + } + } } @@ -199,6 +204,7 @@ abstract class Searchengine } $body = ""; + if ($this->canCache && $this->cacheDuration > 0 && Cache::has($this->hash)) { $body = Cache::get($this->hash); } elseif (Redis::hexists('search.' . $this->resultHash, $this->name)) { diff --git a/app/Models/parserSkripte/Bing.php b/app/Models/parserSkripte/Bing.php new file mode 100644 index 000000000..cda8166a7 --- /dev/null +++ b/app/Models/parserSkripte/Bing.php @@ -0,0 +1,84 @@ +<?php + +namespace app\Models\parserSkripte; + +use App\Models\Searchengine; +use Log; + +class Bing extends Searchengine +{ + public $results = []; + + public function __construct($name, \stdClass $engine, \App\MetaGer $metager) + { + parent::__construct($name, $engine, $metager); + } + + public function loadResults($result) + { + try { + $results = json_decode($result); + $this->totalResults = $results->webPages->totalEstimatedMatches; + $results = $results->webPages->value; + + foreach ($results as $result) { + $title = $result->name; + $link = $result->url; + $anzeigeLink = $result->displayUrl; + $descr = $result->snippet; + $this->counter++; + $this->results[] = new \App\Models\Result( + $this->engine, + $title, + $link, + $anzeigeLink, + $descr, + $this->engine->{"display-name"}, $this->engine->homepage, + $this->counter, + [] + ); + + } + + } catch (\Exception $e) { + Log::error("A problem occurred parsing results from $this->name:"); + Log::error($e->getMessage()); + return; + } + } + + public function getNext(\App\MetaGer $metager, $result) + { + try { + $results = json_decode($result); + + $totalMatches = $results->webPages->totalEstimatedMatches; + + $newEngine = unserialize(serialize($this->engine)); + + $perPage = $newEngine->{"get-parameter"}->count; + + $offset = 0; + if (empty($newEngine->{"get-parameter"}->offset)) { + $offset = $perPage; + } else { + $offset = $newEngine->{"get-parameter"}->offset + $perPage; + } + + if ($totalMatches < ($offset + $perPage)) { + return; + } else { + $newEngine->{"get-parameter"}->offset = $offset; + } + + $next = new Bing($this->name, $newEngine, $metager); + $this->next = $next; + + } catch (\Exception $e) { + Log::error("A problem occurred parsing results from $this->name:"); + Log::error($e->getMessage()); + return; + } + + } +} diff --git a/app/Models/parserSkripte/BingBilder.php b/app/Models/parserSkripte/BingBilder.php index 1587e230f..3ccc2a3a5 100644 --- a/app/Models/parserSkripte/BingBilder.php +++ b/app/Models/parserSkripte/BingBilder.php @@ -18,6 +18,7 @@ class BingBilder extends Searchengine { try { $results = json_decode($result); + $this->totalResults = $results->totalEstimatedMatches; $results = $results->value; foreach ($results as $result) { diff --git a/app/Models/parserSkripte/Overture.php b/app/Models/parserSkripte/Overture.php index c8351132d..5d7a7e8eb 100644 --- a/app/Models/parserSkripte/Overture.php +++ b/app/Models/parserSkripte/Overture.php @@ -25,7 +25,14 @@ class Overture extends Searchengine if (!$content) { return; } - + # Yahoo gives us the total Result Count + $resultCount = $content->xpath('//Results/ResultSet[@id="inktomi"]/MetaData/TotalHits'); + if (sizeof($resultCount) > 0) { + $resultCount = intval($resultCount[0]->__toString()); + } else { + $resultCount = 0; + } + $this->totalResults = $resultCount; $results = $content->xpath('//Results/ResultSet[@id="inktomi"]/Listing'); foreach ($results as $result) { $title = $result["title"]; @@ -40,8 +47,9 @@ class Overture extends Searchengine $anzeigeLink, $descr, $this->engine->{"display-name"}, - $this->engine->homepage, - $this->counter + $this->engine->{"homepage"}, + $this->counter, + [] ); } @@ -59,8 +67,10 @@ class Overture extends Searchengine $link, $anzeigeLink, $descr, - $this->engine->{"display-name"}, $this->engine->homepage, - $this->counter + $this->engine->{"display-name"}, + $this->engine->{"homepage"}, + $this->counter, + [] ); } } catch (\Exception $e) { diff --git a/resources/lang/de/metaGer.php b/resources/lang/de/metaGer.php index 7d06f80a4..4722f9c15 100644 --- a/resources/lang/de/metaGer.php +++ b/resources/lang/de/metaGer.php @@ -22,7 +22,9 @@ return [ '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: ', + 'results' => "Ergebnisse", 'filter.noFilter' => 'Alle', + 'filter.reset' => 'Filter zurücksetzen', 'filter.sitesearch' => 'Sitesearch', 'filter.safesearch' => "SafeSearch", @@ -79,4 +81,44 @@ return [ "filter.freshness.day" => "Letzte 24h", "filter.freshness.week" => "Letzte Woche", "filter.freshness.month" => "Letzter Monat", + + "filter.market" => "Sprache", + "filter.market.ga" => "Deutsch (Österreich)", + "filter.market.gg" => "Deutsch (Deutschland)", + "filter.market.gs" => "Deutsch (Schweiz)", + "filter.market.ea" => "Englisch (Australien)", + "filter.market.ec" => "Englisch (Kanada)", + "filter.market.ei" => "Englisch (Indien)", + "filter.market.ein" => "Englisch (Indonesien)", + "filter.market.em" => "Englisch (Malaysia)", + "filter.market.enz" => "Englisch (Neuseeland)", + "filter.market.ep" => "Englisch (Philippinen)", + "filter.market.esa" => "Englisch (Süd-Afrika)", + "filter.market.euk" => "Englisch (UK)", + "filter.market.eus" => "Englisch (US)", + "filter.market.sa" => "Spanisch (Argentinien)", + "filter.market.sc" => "Spanisch (Chile)", + "filter.market.sm" => "Spanisch (Mexiko)", + "filter.market.ss" => "Spanisch (Spanien)", + "filter.market.sus" => "Spanisch (US)", + "filter.market.fb" => "Französisch (Belgien)", + "filter.market.fc" => "Französisch (Kanada)", + "filter.market.ff" => "Französisch (Frankreich)", + "filter.market.fs" => "Französisch (Schweiz)", + "filter.market.ii" => "Italienisch (Italien)", + "filter.market.db" => "Niederländisch (Belgien)", + "filter.market.dn" => "Niederländisch (Niederlande)", + "filter.market.pp" => "Polnisch (Polen)", + "filter.market.pb" => "Portugiesisch (Brasilien)", + "filter.market.dd" => "Dänisch (Dänemark)", + "filter.market.fif" => "Finnisch (Finnland)", + "filter.market.nn" => "Norwegisch (Norwegen)", + "filter.market.scs" => "Schwedisch (Schweden)", + "filter.market.rr" => "Russisch (Russland)", + "filter.market.jj" => "Japanisch (Japan)", + "filter.market.kk" => "Koreanisch (Korea)", + "filter.market.tt" => "Türkisch (Türkei)", + "filter.market.chk" => "Chinesisch (Hong Kong SAR)", + "filter.market.cc" => "Chinesisch (China)", + "filter.market.ct" => "Chinesisch (Taiwan)", ]; diff --git a/resources/less/metager/general/general.less b/resources/less/metager/general/general.less index 56b8dad84..7b7fe480d 100644 --- a/resources/less/metager/general/general.less +++ b/resources/less/metager/general/general.less @@ -77,6 +77,7 @@ body { background: -webkit-gradient(linear, left top, right top, from(@scrollfade-color), color-stop(fade(@scrollfade-color, 80%)), to(fade(@scrollfade-color, 0%))); background: linear-gradient(to right, @scrollfade-color, fade(@scrollfade-color, 80%), fade(@scrollfade-color, 0%)); left: 1px; + margin-left: -20px; } &right { background: -webkit-gradient(linear, right top, left top, from(@scrollfade-color), color-stop(fade(@scrollfade-color, 80%)), to(fade(@scrollfade-color, 0%))); diff --git a/resources/less/metager/pages/resultpage/result-page.less b/resources/less/metager/pages/resultpage/result-page.less index 876a33261..80d488c6f 100644 --- a/resources/less/metager/pages/resultpage/result-page.less +++ b/resources/less/metager/pages/resultpage/result-page.less @@ -483,8 +483,12 @@ a { #options { grid-area: options; - display: flex; - justify-content: left; + background-color: white; + max-width: @results-width-max; + padding: 0 8px; + @media(max-width: @screen-mobile){ + .card; + } input[type=checkbox]{ display: none; } @@ -498,17 +502,33 @@ a { max-height:200px; transform: scaleY(1); } + #toggle-box { + display: flex; + align-items: center; + #result-count { + flex-grow: 1; + text-align: right; + } + #options-reset { + margin-left: 10px; + } + .option-toggle { + text-align: center; + label{ + font-weight: normal; + margin-bottom: 0; + } + } + } #options-box{ width: 100%; - max-width: 700px; - background-color: white; - border-bottom: 1px solid #ccc; - @media(max-width: @screen-mobile){ - .card; - } + display: flex; + justify-content: left; overflow: hidden; overflow-x: auto; - padding: 8px; + border-bottom: 1px solid #ccc; + padding-bottom: 8px; + padding-top: 8px; #options-items { display: -ms-flexbox; display: flex; @@ -531,10 +551,9 @@ a { border-radius: 5px; } } - } - #options-reset { - margin-left: 10px; - margin-bottom: 8px; + .option-selector:nth-child(1){ + margin-left: 0; + } } } } @@ -549,7 +568,7 @@ a { } footer.resultPageFooter { - max-width: 700px; + max-width: @results-width-max; margin-top: 20px; @media (max-width: (2 * @results-margin-left + @results-width-max - 1px)) { margin: 20px 0 0 0; diff --git a/resources/less/metager/pages/resultpage/result.less b/resources/less/metager/pages/resultpage/result.less index 2560f4954..d697d7fd0 100644 --- a/resources/less/metager/pages/resultpage/result.less +++ b/resources/less/metager/pages/resultpage/result.less @@ -14,7 +14,7 @@ .card; } margin: @padding-small-default 0px; - padding: 8px 15px 5px 15px; + padding: 8px 8px 5px 8px; width: 100%; .result-header { display: flex; diff --git a/resources/views/layouts/researchandtabs.blade.php b/resources/views/layouts/researchandtabs.blade.php index 47f1ec34a..13b06bb93 100644 --- a/resources/views/layouts/researchandtabs.blade.php +++ b/resources/views/layouts/researchandtabs.blade.php @@ -28,15 +28,29 @@ </div> @if(sizeof($metager->getAvailableParameterFilter()) > 0) <div id="options"> + <div id="toggle-box"> + @if(sizeof($metager->getAvailableParameterFilter()) > 0) + <div class="option-toggle"> + <label class="navigation-element" for="options-toggle"> + <i class="fas fa-filter"></i> Filter… + </label> + </div> + @endif + @if(sizeof($metager->getParameterFilter()) > 0) + <div id="options-reset"> + <a href="{{$metager->generateSearchLink($metager->getFokus())}}"><nobr>{{ trans('filter.reset') }}</nobr></a> + </div> + @endif + @if($metager->getTotalResultCount() > 0) + <div id="result-count"> + ~ {{$metager->getTotalResultCount()}} {{ trans('metaGer.results') }} + </div> + @endif + </div> <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"> diff --git a/resources/views/parts/foki.blade.php b/resources/views/parts/foki.blade.php index 25c3bd328..cc748c53a 100644 --- a/resources/views/parts/foki.blade.php +++ b/resources/views/parts/foki.blade.php @@ -3,10 +3,3 @@ <a href="@if($metager->getFokus() === $name)#@else{!!$metager->generateSearchLink($name)!!}@endif" target="_self" tabindex="0">@lang($fokus->{"display-name"})</a> </div> @endforeach -@if(sizeof($metager->getAvailableParameterFilter()) > 0) -<div class="option-toggle"> - <label class="navigation-element" for="options-toggle"> - <i class="fas fa-filter"></i> - </label> -</div> -@endif -- GitLab