Result.php 11.1 KB
Newer Older
1
2
<?php

3
namespace App\Models;
4

Karl's avatar
Karl committed
5
6
7
/* Die Klasse Result sammelt alle Informationen über ein einzelnes Suchergebnis.
 *  Die Results werden von den Suchmaschinenspezifischen Parser-Skripten erstellt.
 */
8
9
class Result
{
Karl's avatar
Karl committed
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    public $provider; # Die Engine von der das Suchergebnis kommt
    public $titel; # Der Groß Angezeigte Name für das Suchergebnis
    public $link; # Der Link auf die Ergebnisseite
    public $anzeigeLink; # Der tatsächlich angezeigte Link (rein optisch)
    public $descr; # Die Beschreibung des Suchergebnisses
    public $gefVon; # Das bei Suchergebnissen angezeigte von ... mitsamt Verlinkung
    public $sourceRank; # Das Ranking für dieses Suchergebnis von der Seite, die es geliefert hat (implizit durch Ergebnisreihenfolge: 20 - Position in Ergebnisliste)
    public $partnershop; # Ist das Ergebnis von einem Partnershop? (bool)
    public $image; # Ein Vorschaubild für das Suchergebnis (als URL)

    public $proxyLink; # Der Link für die Seite über unseren Proxy-Service
    public $engineBoost = 1; # Der Boost für den Provider des Suchergebnisses
    public $valid       = true; # Ob das Ergebnis noch gültig ist (bool)
    public $host; # Der aus dem Link gelesene Host des Suchergebnisses
    public $strippedHost; # Der Host      in Form "foo.bar.de"
    public $strippedDomain; # Die Domain    in Form "bar.de"
    public $strippedLink; # Der Link      in Form "foo.bar.de/test"
    public $rank; # Das Ranking für das Ergebnis

    # Erstellt ein neues Ergebnis
Dominik Hebeler's avatar
Dominik Hebeler committed
30
    public function __construct($provider, $titel, $link, $anzeigeLink, $descr, $gefVon, $sourceRank, $partnershop = false, $image = "", $price = 0, $additionalInformation = [])
31
    {
32
        $provider          = simplexml_load_string($provider);
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
        $this->titel       = strip_tags(trim($titel));
        $this->link        = trim($link);
        $this->anzeigeLink = trim($anzeigeLink);
        $this->descr       = strip_tags(trim($descr), '<p>');
        $this->descr       = preg_replace("/\n+/si", " ", $this->descr);
        if (strlen($this->descr) > 250) {
            $this->descr = wordwrap($this->descr, 250);
            $this->descr = substr($this->descr, 0, strpos($this->descr, "\n"));

        }
        $this->gefVon     = trim($gefVon);
        $this->proxyLink  = $this->generateProxyLink($this->link);
        $this->sourceRank = $sourceRank;
        if ($this->sourceRank <= 0 || $this->sourceRank > 20) {
            $this->sourceRank = 20;
        }
        $this->sourceRank = 20 - $this->sourceRank;
        if (isset($provider["engineBoost"])) {
            $this->engineBoost = floatval($provider["engineBoost"]->__toString());
        } else {
            $this->engineBoost = 1;
        }
Dominik Hebeler's avatar
Dominik Hebeler committed
55
56
57
58
59
60
61
62
63
64
        $this->valid                 = true;
        $this->host                  = @parse_url($link, PHP_URL_HOST);
        $this->strippedHost          = $this->getStrippedHost($this->anzeigeLink);
        $this->strippedDomain        = $this->getStrippedDomain($this->strippedHost);
        $this->strippedLink          = $this->getStrippedLink($this->anzeigeLink);
        $this->rank                  = 0;
        $this->partnershop           = $partnershop;
        $this->image                 = $image;
        $this->price                 = $price;
        $this->additionalInformation = $additionalInformation;
65
66
    }

Karl's avatar
Karl committed
67
68
69
70
71
    /* Ranked das Ergebnis nach folgenden Aspekten:
     *  Startwert 0
     *  + 0.02 * Sourcerank (20 - Position in Ergebnisliste des Suchanbieters)
     *  * Engine-Boost
     */
72
73
74
    public function rank(\App\MetaGer $metager)
    {
        $rank = 0;
Karl's avatar
Karl committed
75
76
77
78

        $eingabe = $metager->getQ();

        # Boost für Source Ranking
79
80
        $rank += ($this->sourceRank * 0.02);

Karl's avatar
Karl committed
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
        # Boost für passende ??? URL
        $rank += $this->calcURLBoost($eingabe);

        # Boost für Vorkommen der Suchwörter:
        $rank += $this->calcSuchwortBoost($eingabe);

        # Boost für Suchmaschine
        if ($this->engineBoost > 0) {
            $rank *= floatval($this->engineBoost);
        }

        $this->rank = $rank;
    }

    # Berechnet den Ranking-Boost durch ??? URL
    public function calcURLBoost($tmpEingabe)
    {
98
99
100
101
        $link = $this->anzeigeLink;
        if (strpos($link, "http") !== 0) {
            $link = "http://" . $link;
        }
Karl's avatar
Karl committed
102
103
104
105
106
        $link    = @parse_url($link, PHP_URL_HOST) . @parse_url($link, PHP_URL_PATH);
        $tmpLi   = $link;
        $count   = 0;
        $tmpLink = "";
        # Löscht verschiedene unerwünschte Teile aus $link und $tmpEingabe
107
        $regex = [
Karl's avatar
Karl committed
108
109
110
111
112
113
114
            "/\s+/si", # Leerzeichen
            "/http:/si", # "http:"
            "/https:/si", # "https:"
            "/www\./si", # "www."
            "/\//si", # "/"
            "/\./si", # "."
            "/-/si", # "-"
115
116
117
118
119
120
        ];
        foreach ($regex as $reg) {
            $link       = preg_replace($regex, "", $link);
            $tmpEingabe = preg_replace($regex, "", $tmpEingabe);
        }
        foreach (str_split($tmpEingabe) as $char) {
Karl's avatar
Karl committed
121
122
123
124
125
            if (!$char
                || !$tmpEingabe
                || strlen($tmpEingabe) === 0
                || strlen($char) === 0
            ) {
126
127
128
129
130
131
132
                continue;
            }
            if (strpos(strtolower($tmpLink), strtolower($char)) >= 0) {
                $count++;
                $tmpLink = str_replace(urlencode($char), "", $tmpLink);
            }
        }
Karl's avatar
Karl committed
133
134
135
136
137
138
        if (strlen($this->descr) > 80 && strlen($link) > 0) {
            return $count / ((strlen($link)) * 60); # ???
        } else {
            return 0;
        }
    }
139

Karl's avatar
Karl committed
140
141
142
    # Berechnet den Ranking-Boost durch das Vorkommen von Suchwörtern
    private function calcSuchwortBoost($tmpEingabe)
    {
143
144
145
146
147
148
149
        $maxRank        = 0.1;
        $tmpTitle       = $this->titel;
        $tmpDescription = $this->descr;
        $isWithin       = false;
        $tmpRank        = 0;
        $tmpEingabe     = preg_replace("/\b\w{1,3}\b/si", "", $tmpEingabe);
        $tmpEingabe     = preg_replace("/\s+/si", " ", $tmpEingabe);
Karl's avatar
Karl committed
150

151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
        foreach (explode(" ", trim($tmpEingabe)) as $el) {
            if (strlen($tmpTitle) === 0 || strlen($el) === 0 || strlen($tmpDescription) === 0) {
                continue;
            }

            $el = preg_quote($el, "/");
            if (strlen($tmpTitle) > 0) {
                if (preg_match("/\b$el\b/si", $tmpTitle)) {
                    $tmpRank += .7 * .6 * $maxRank;
                } elseif (strpos($tmpTitle, $el) !== false) {
                    $tmpRank += .3 * .6 * $maxRank;
                }
            }
            if (strlen($tmpDescription) > 0) {
                if (preg_match("/\b$el\b/si", $tmpDescription)) {
                    $tmpRank += .7 * .4 * $maxRank;
                } elseif (strpos($tmpDescription, $el) !== false) {
                    $tmpRank += .3 * .4 * $maxRank;
                }
            }
        }

Karl's avatar
Karl committed
173
174
        $tmpRank /= sizeof(explode(" ", trim($tmpEingabe))) * 10;
        return $tmpRank;
175
176
    }

Karl's avatar
Karl committed
177
    # Überprüft ob das Ergebnis aus irgendwelchen Gründen unerwünscht ist.
178
179
    public function isValid(\App\MetaGer $metager)
    {
Karl's avatar
Karl committed
180
        # Perönliche URL und Domain Blacklist
181
182
183
184
185
        if (in_array($this->strippedHost, $metager->getUserHostBlacklist())
            || in_array($this->strippedDomain, $metager->getUserDomainBlacklist())) {
            return false;
        }

Karl's avatar
Karl committed
186
        # Allgemeine URL und Domain Blacklist
187
188
189
190
        if ($this->strippedHost !== "" && (in_array($this->strippedHost, $metager->getDomainBlacklist()) || in_array($this->strippedLink, $metager->getUrlBlacklist()))) {
            return false;
        }

Karl's avatar
Karl committed
191
        # Eventueller Sprachfilter
192
193
194
195
196
197
198
199
200
201
202
        if ($metager->getLang() !== "all") {
            $text = $this->titel . " " . $this->descr;
            $path = app_path() . "/Models/lang.pl";
            $lang = exec("echo '$text' | $path");

            if ($metager->getLang() !== $lang) {
                return false;
            }

        }

Karl's avatar
Karl committed
203
        # Stopworte
204
205
206
207
208
209
210
        foreach ($metager->getStopWords() as $stopWord) {
            $text = $this->titel . " " . $this->descr;
            if (stripos($text, $stopWord) !== false) {
                return false;
            }
        }

Karl's avatar
Karl committed
211
        # Phrasensuche:
212
213
214
215
216
217
218
219
        $text = strtolower($this->titel) . " " . strtolower($this->descr);
        foreach ($metager->getPhrases() as $phrase) {
            if (strpos($text, $phrase) === false) {
                return false;
            }

        }

Karl's avatar
Karl committed
220
221
222
223
        /* Der Host-Filter der sicherstellt,
         *  dass von jedem Host maximal 3 Links angezeigt werden.
         *  Diese Überprüfung führen wir unter bestimmten Bedingungen nicht durch.
         */
224
225
226
227
228
229
230
231
232
233
234
235
        if ($metager->getSite() === "" &&
            strpos($this->strippedHost, "ncbi.nlm.nih.gov") === false &&
            strpos($this->strippedHost, "twitter.com") === false &&
            strpos($this->strippedHost, "www.ladenpreis.net") === false &&
            strpos($this->strippedHost, "ncbi.nlm.nih.gov") === false &&
            strpos($this->strippedHost, "www.onenewspage.com") === false) {
            $count = $metager->getHostCount($this->strippedHost);
            if ($count >= 3) {
                return false;
            }
        }

Phil Höfer's avatar
Phil Höfer committed
236
        /* Der Dublettenfilter, der sicher stellt,
Karl's avatar
Karl committed
237
238
         *  dass wir nach Möglichkeit keinen Link doppelt in der Ergebnisliste haben.
         */
239
240
241
242
243
244
245
246
        if ($metager->addLink($this->strippedLink)) {
            $metager->addHostCount($this->strippedHost);
            return true;
        } else {
            return false;
        }
    }

Karl's avatar
Karl committed
247
248
249
250
251
    /* Liest aus einem Link den Host.
     *  Dieser wird dabei in die Form:
     *  "http://www.foo.bar.de/test?ja=1" -> "foo.bar.de"
     *  gebracht.
     */
252
253
254
255
256
257
258
259
260
261
    private function getStrippedHost($link)
    {
        if (strpos($link, "http") !== 0) {
            $link = "http://" . $link;
        }

        $link = @parse_url($link, PHP_URL_HOST);
        $link = preg_replace("/^www\./si", "", $link);
        return $link;
    }
Karl's avatar
Karl committed
262
263
264
265
266
267

    /* Entfernt "http://", "www" und Parameter von einem Link
     *  Dieser wird dabei in die Form:
     *  "http://www.foo.bar.de/test?ja=1" -> "foo.bar.de/test"
     *  gebracht.
     */
268
269
270
271
272
273
274
275
276
277
278
    private function getStrippedLink($link)
    {
        if (strpos($link, "http") !== 0) {
            $link = "http://" . $link;
        }

        $host = $this->strippedHost;
        $path = @parse_url($link, PHP_URL_PATH);
        return $host . $path;
    }

Karl's avatar
Karl committed
279
280
281
282
283
    /* Liest aus einem Link die Domain.
     *  Dieser wird dabei in die Form:
     *  "http://www.foo.bar.de/test?ja=1" -> "bar.de"
     *  gebracht.
     */
284
285
286
287
288
289
290
291
292
    private function getStrippedDomain($link)
    {
        if (preg_match("/([^\.]*\.[^\.]*)$/si", $link, $match)) {
            return $match[1];
        } else {
            return $link;
        }
    }

Karl's avatar
Karl committed
293
    # Erstellt aus einem Link einen Proxy-Link für unseren Proxy-Service
294
295
296
297
298
299
300
301
302
303
304
305
    private function generateProxyLink($link)
    {
        if (!$link) {
            return "";
        }

        $tmp = $link;
        $tmp = preg_replace("/\r?\n$/s", "", $tmp);
        $tmp = preg_replace("#^([\w+.-]+)://#s", "$1/", $tmp);
        return "https://proxy.suma-ev.de/cgi-bin/nph-proxy.cgi/en/I0/" . $tmp;

    }
Karl's avatar
Karl committed
306
307
308
309
310
311
312

    # Getter

    public function getRank()
    {
        return $this->rank;
    }
Phil Höfer's avatar
Phil Höfer committed
313
}