Passed
Push — master ( 678db7...164b32 )
by Cody
06:12 queued 03:06
created
plugins/af_comics/filters/af_comics_dilbert.php 1 patch
Indentation   +51 added lines, -51 removed lines patch added patch discarded remove patch
@@ -2,73 +2,73 @@
 block discarded – undo
2 2
 
3 3
 class Af_Comics_Dilbert extends Af_ComicFilter {
4 4
 
5
-	public function supported() {
6
-		return array("Dilbert");
7
-	}
5
+    public function supported() {
6
+        return array("Dilbert");
7
+    }
8 8
 
9
-	public function process(&$article) {
10
-		if (strpos($article["link"], "dilbert.com") !== false ||
11
-			strpos($article["link"], "/DilbertDailyStrip") !== false) {
9
+    public function process(&$article) {
10
+        if (strpos($article["link"], "dilbert.com") !== false ||
11
+            strpos($article["link"], "/DilbertDailyStrip") !== false) {
12 12
 
13
-				$res = fetch_file_contents($article["link"], false, false, false,
14
-					 false, false, 0,
15
-					 "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0");
13
+                $res = fetch_file_contents($article["link"], false, false, false,
14
+                        false, false, 0,
15
+                        "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0");
16 16
 
17
-				global $fetch_last_error_content;
17
+                global $fetch_last_error_content;
18 18
 
19
-				if (!$res && $fetch_last_error_content) {
20
-									$res = $fetch_last_error_content;
21
-				}
19
+                if (!$res && $fetch_last_error_content) {
20
+                                    $res = $fetch_last_error_content;
21
+                }
22 22
 
23
-				$doc = new DOMDocument();
23
+                $doc = new DOMDocument();
24 24
 
25
-				if (@$doc->loadHTML($res)) {
26
-					$xpath = new DOMXPath($doc);
25
+                if (@$doc->loadHTML($res)) {
26
+                    $xpath = new DOMXPath($doc);
27 27
 
28
-					// Get the image container
29
-					$basenode = $xpath->query('(//div[@class="img-comic-container"]/a[@class="img-comic-link"])')->item(0);
28
+                    // Get the image container
29
+                    $basenode = $xpath->query('(//div[@class="img-comic-container"]/a[@class="img-comic-link"])')->item(0);
30 30
 
31
-					// Get the comic title
32
-					$comic_title = $xpath->query('(//span[@class="comic-title-name"])')->item(0)->textContent;
31
+                    // Get the comic title
32
+                    $comic_title = $xpath->query('(//span[@class="comic-title-name"])')->item(0)->textContent;
33 33
 
34
-					// Get tags from the article
35
-					$matches = $xpath->query('(//p[contains(@class, "comic-tags")][1]//a)');
36
-					$tags = array();
34
+                    // Get tags from the article
35
+                    $matches = $xpath->query('(//p[contains(@class, "comic-tags")][1]//a)');
36
+                    $tags = array();
37 37
 
38
-					foreach ($matches as $tag) {
39
-						// Only strings starting with a number sign are considered tags
40
-						if (substr($tag->textContent, 0, 1) == '#') {
41
-							$tags[] = mb_strtolower(substr($tag->textContent, 1), 'utf-8');
42
-						}
43
-					}
38
+                    foreach ($matches as $tag) {
39
+                        // Only strings starting with a number sign are considered tags
40
+                        if (substr($tag->textContent, 0, 1) == '#') {
41
+                            $tags[] = mb_strtolower(substr($tag->textContent, 1), 'utf-8');
42
+                        }
43
+                    }
44 44
 
45
-					// Get the current comics transcript and set it
46
-					// as the title so it will be visible on mousover
47
-					$transcript = $xpath->query('(//div[starts-with(@id, "js-toggle-transcript-")]//p)')->item(0);
48
-					if ($transcript) {
49
-						$basenode->setAttribute("title", $transcript->textContent);
50
-					}
45
+                    // Get the current comics transcript and set it
46
+                    // as the title so it will be visible on mousover
47
+                    $transcript = $xpath->query('(//div[starts-with(@id, "js-toggle-transcript-")]//p)')->item(0);
48
+                    if ($transcript) {
49
+                        $basenode->setAttribute("title", $transcript->textContent);
50
+                    }
51 51
 
52
-					if ($basenode) {
53
-						$article["content"] = $doc->saveHTML($basenode);
54
-					}
52
+                    if ($basenode) {
53
+                        $article["content"] = $doc->saveHTML($basenode);
54
+                    }
55 55
 
56
-					// Add comic title to article type if not empty (mostly Sunday strips)
57
-					if ($comic_title) {
58
-						$article["title"] = $article["title"]." - ".$comic_title;
59
-					}
56
+                    // Add comic title to article type if not empty (mostly Sunday strips)
57
+                    if ($comic_title) {
58
+                        $article["title"] = $article["title"]." - ".$comic_title;
59
+                    }
60 60
 
61
-					if (!empty($tags)) {
62
-						// Ignore existing tags and just replace them all
63
-						$article["tags"] = array_unique($tags);
64
-					}
61
+                    if (!empty($tags)) {
62
+                        // Ignore existing tags and just replace them all
63
+                        $article["tags"] = array_unique($tags);
64
+                    }
65 65
 
66
-				}
66
+                }
67 67
 
68
-			return true;
69
-		}
68
+            return true;
69
+        }
70 70
 
71
-		return false;
72
-	}
71
+        return false;
72
+    }
73 73
 }
74 74
 ?>
Please login to merge, or discard this patch.
plugins/af_comics/filters/af_comics_tfd.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -1,34 +1,34 @@
 block discarded – undo
1 1
 <?php
2 2
 class Af_Comics_Tfd extends Af_ComicFilter {
3 3
 
4
-	public function supported() {
5
-		return array("Toothpaste For Dinner", "Married to the Sea");
6
-	}
4
+    public function supported() {
5
+        return array("Toothpaste For Dinner", "Married to the Sea");
6
+    }
7 7
 
8
-	public function process(&$article) {
9
-		if (strpos($article["link"], "toothpastefordinner.com") !== false ||
10
-		    strpos($article["link"], "marriedtothesea.com") !== false) {
11
-			$res = fetch_file_contents($article["link"], false, false, false,
12
-				false, false, 0,
13
-				"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)");
8
+    public function process(&$article) {
9
+        if (strpos($article["link"], "toothpastefordinner.com") !== false ||
10
+            strpos($article["link"], "marriedtothesea.com") !== false) {
11
+            $res = fetch_file_contents($article["link"], false, false, false,
12
+                false, false, 0,
13
+                "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)");
14 14
 
15
-			if (!$res) {
16
-			    return $article;
17
-			}
15
+            if (!$res) {
16
+                return $article;
17
+            }
18 18
 
19
-			$doc = new DOMDocument();
19
+            $doc = new DOMDocument();
20 20
 
21
-			if (@$doc->loadHTML(fetch_file_contents($article["link"]))) {
22
-				$xpath = new DOMXPath($doc);
23
-				$basenode = $xpath->query('//img[contains(@src, ".gif")]')->item(0);
21
+            if (@$doc->loadHTML(fetch_file_contents($article["link"]))) {
22
+                $xpath = new DOMXPath($doc);
23
+                $basenode = $xpath->query('//img[contains(@src, ".gif")]')->item(0);
24 24
 
25
-				if ($basenode) {
26
-					$article["content"] = $doc->saveHTML($basenode);
27
-					return true;
28
-				}
29
-			}
30
-		}
25
+                if ($basenode) {
26
+                    $article["content"] = $doc->saveHTML($basenode);
27
+                    return true;
28
+                }
29
+            }
30
+        }
31 31
 
32
-		return false;
33
-	}
32
+        return false;
33
+    }
34 34
 }
Please login to merge, or discard this patch.
plugins/auto_assign_labels/init.php 1 patch
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -1,57 +1,57 @@
 block discarded – undo
1 1
 <?php
2 2
 class Auto_Assign_Labels extends Plugin {
3 3
 
4
-	/* @var PluginHost $host */
5
-	private $host;
4
+    /* @var PluginHost $host */
5
+    private $host;
6 6
 
7
-	public function about() {
8
-		return array(1.0,
9
-			"Assign labels automatically based on article title, content, and tags",
10
-			"fox");
11
-	}
7
+    public function about() {
8
+        return array(1.0,
9
+            "Assign labels automatically based on article title, content, and tags",
10
+            "fox");
11
+    }
12 12
 
13
-	public function init($host) {
14
-		$this->host = $host;
13
+    public function init($host) {
14
+        $this->host = $host;
15 15
 
16
-		$host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
17
-	}
16
+        $host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
17
+    }
18 18
 
19
-	public function get_all_labels_filter_format($owner_uid) {
20
-		$rv = array();
19
+    public function get_all_labels_filter_format($owner_uid) {
20
+        $rv = array();
21 21
 
22
-		$sth = $this->pdo->prepare("SELECT id, fg_color, bg_color, caption FROM ttrss_labels2 WHERE owner_uid = ?");
23
-		$sth->execute([$owner_uid]);
22
+        $sth = $this->pdo->prepare("SELECT id, fg_color, bg_color, caption FROM ttrss_labels2 WHERE owner_uid = ?");
23
+        $sth->execute([$owner_uid]);
24 24
 
25
-		while ($line = $sth->fetch()) {
26
-			array_push($rv, array(Labels::label_to_feed_id($line["id"]),
27
-				$line["caption"], $line["fg_color"], $line["bg_color"]));
28
-		}
25
+        while ($line = $sth->fetch()) {
26
+            array_push($rv, array(Labels::label_to_feed_id($line["id"]),
27
+                $line["caption"], $line["fg_color"], $line["bg_color"]));
28
+        }
29 29
 
30
-		return $rv;
31
-	}
30
+        return $rv;
31
+    }
32 32
 
33 33
 
34
-	public function hook_article_filter($article) {
34
+    public function hook_article_filter($article) {
35 35
 
36
-		$owner_uid = $article["owner_uid"];
37
-		$labels = $this->get_all_labels_filter_format($owner_uid);
38
-		$tags_str = join(",", $article["tags"]);
36
+        $owner_uid = $article["owner_uid"];
37
+        $labels = $this->get_all_labels_filter_format($owner_uid);
38
+        $tags_str = join(",", $article["tags"]);
39 39
 
40
-		foreach ($labels as $label) {
41
-			$caption = preg_quote($label[1], "/");
40
+        foreach ($labels as $label) {
41
+            $caption = preg_quote($label[1], "/");
42 42
 
43
-			if ($caption && preg_match("/\b$caption\b/i", "$tags_str ".strip_tags($article["content"])." ".$article["title"])) {
43
+            if ($caption && preg_match("/\b$caption\b/i", "$tags_str ".strip_tags($article["content"])." ".$article["title"])) {
44 44
 
45
-				if (!RSSUtils::labels_contains_caption($article["labels"], $caption)) {
46
-					array_push($article["labels"], $label);
47
-				}
48
-			}
49
-		}
45
+                if (!RSSUtils::labels_contains_caption($article["labels"], $caption)) {
46
+                    array_push($article["labels"], $label);
47
+                }
48
+            }
49
+        }
50 50
 
51
-		return $article;
52
-	}
51
+        return $article;
52
+    }
53 53
 
54
-	public function api_version() {
55
-		return 2;
56
-	}
54
+    public function api_version() {
55
+        return 2;
56
+    }
57 57
 }
Please login to merge, or discard this patch.
plugins/toggle_sidebar/init.php 1 patch
Indentation   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -1,26 +1,26 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 class Toggle_Sidebar extends Plugin {
3 3
 
4
-	private $host;
4
+    private $host;
5 5
 
6
-	public function about() {
7
-		return array(1.0,
8
-			"Adds a main toolbar button to toggle sidebar",
9
-			"fox");
10
-	}
6
+    public function about() {
7
+        return array(1.0,
8
+            "Adds a main toolbar button to toggle sidebar",
9
+            "fox");
10
+    }
11 11
 
12
-	public function init($host) {
13
-		$this->host = $host;
12
+    public function init($host) {
13
+        $this->host = $host;
14 14
 
15
-		$host->add_hook($host::HOOK_MAIN_TOOLBAR_BUTTON, $this);
16
-	}
15
+        $host->add_hook($host::HOOK_MAIN_TOOLBAR_BUTTON, $this);
16
+    }
17 17
 
18
-	public function get_js() {
19
-		return file_get_contents(__DIR__."/init.js");
20
-	}
18
+    public function get_js() {
19
+        return file_get_contents(__DIR__."/init.js");
20
+    }
21 21
 
22
-	public function hook_main_toolbar_button() {
23
-		?>
22
+    public function hook_main_toolbar_button() {
23
+        ?>
24 24
 
25 25
 		<button dojoType="dijit.form.Button" onclick="Plugins.Toggle_Sidebar.toggle(this)">
26 26
 			<i class="material-icons toggle-sidebar-label"
@@ -28,11 +28,11 @@  discard block
 block discarded – undo
28 28
 		</button>
29 29
 
30 30
 		<?php
31
-	}
31
+    }
32 32
 
33
-	public function api_version() {
34
-		return 2;
35
-	}
33
+    public function api_version() {
34
+        return 2;
35
+    }
36 36
 
37 37
 }
38 38
 ?>
Please login to merge, or discard this patch.
plugins/search_sphinx/init.php 1 patch
Indentation   +47 added lines, -47 removed lines patch added patch discarded remove patch
@@ -1,66 +1,66 @@
 block discarded – undo
1 1
 <?php
2 2
 
3 3
 class Search_Sphinx extends Plugin {
4
-	public function about() {
5
-		return array(1.0,
6
-			"Delegate searching for articles to Sphinx (don't forget to set options in config.php)",
7
-			"hoelzro",
8
-			true,
9
-			"https://git.tt-rss.org/fox/tt-rss/wiki/SphinxSearch");
10
-	}
4
+    public function about() {
5
+        return array(1.0,
6
+            "Delegate searching for articles to Sphinx (don't forget to set options in config.php)",
7
+            "hoelzro",
8
+            true,
9
+            "https://git.tt-rss.org/fox/tt-rss/wiki/SphinxSearch");
10
+    }
11 11
 
12
-	public function init($host) {
13
-		$host->add_hook($host::HOOK_SEARCH, $this);
12
+    public function init($host) {
13
+        $host->add_hook($host::HOOK_SEARCH, $this);
14 14
 
15
-		// idk if that would work but checking for the class being loaded is somehow not enough
16
-		if (class_exists("SphinxClient") && !defined('SEARCHD_COMMAND_SEARCH')) {
17
-			user_error("Your PHP has a separate systemwide Sphinx client installed which conflicts with the client library used by tt-rss. Either remove the system library or disable Sphinx support.");
18
-		}
15
+        // idk if that would work but checking for the class being loaded is somehow not enough
16
+        if (class_exists("SphinxClient") && !defined('SEARCHD_COMMAND_SEARCH')) {
17
+            user_error("Your PHP has a separate systemwide Sphinx client installed which conflicts with the client library used by tt-rss. Either remove the system library or disable Sphinx support.");
18
+        }
19 19
 
20
-		require_once __DIR__."/sphinxapi.php";
21
-	}
20
+        require_once __DIR__."/sphinxapi.php";
21
+    }
22 22
 
23
-	public function hook_search($search) {
24
-		$offset = 0;
25
-		$limit  = 500;
23
+    public function hook_search($search) {
24
+        $offset = 0;
25
+        $limit  = 500;
26 26
 
27
-		$sphinxClient = new SphinxClient();
27
+        $sphinxClient = new SphinxClient();
28 28
 
29
-		$sphinxpair = explode(":", SPHINX_SERVER, 2);
29
+        $sphinxpair = explode(":", SPHINX_SERVER, 2);
30 30
 
31
-		$sphinxClient->SetServer($sphinxpair[0], (int) $sphinxpair[1]);
32
-		$sphinxClient->SetConnectTimeout(1);
31
+        $sphinxClient->SetServer($sphinxpair[0], (int) $sphinxpair[1]);
32
+        $sphinxClient->SetConnectTimeout(1);
33 33
 
34
-		$sphinxClient->SetFieldWeights(array('title' => 70, 'content' => 30,
35
-			'feed_title' => 20));
34
+        $sphinxClient->SetFieldWeights(array('title' => 70, 'content' => 30,
35
+            'feed_title' => 20));
36 36
 
37
-		$sphinxClient->SetMatchMode(SPH_MATCH_EXTENDED2);
38
-		$sphinxClient->SetRankingMode(SPH_RANK_PROXIMITY_BM25);
39
-		$sphinxClient->SetLimits($offset, $limit, 1000);
40
-		$sphinxClient->SetArrayResult(false);
41
-		$sphinxClient->SetFilter('owner_uid', array($_SESSION['uid']));
37
+        $sphinxClient->SetMatchMode(SPH_MATCH_EXTENDED2);
38
+        $sphinxClient->SetRankingMode(SPH_RANK_PROXIMITY_BM25);
39
+        $sphinxClient->SetLimits($offset, $limit, 1000);
40
+        $sphinxClient->SetArrayResult(false);
41
+        $sphinxClient->SetFilter('owner_uid', array($_SESSION['uid']));
42 42
 
43
-		$result = $sphinxClient->Query($search, SPHINX_INDEX);
43
+        $result = $sphinxClient->Query($search, SPHINX_INDEX);
44 44
 
45
-		$ids = array();
45
+        $ids = array();
46 46
 
47
-		if (is_array($result['matches'])) {
48
-			foreach (array_keys($result['matches']) as $int_id) {
49
-				$ref_id = $result['matches'][$int_id]['attrs']['ref_id'];
50
-				array_push($ids, $ref_id);
51
-			}
52
-		}
47
+        if (is_array($result['matches'])) {
48
+            foreach (array_keys($result['matches']) as $int_id) {
49
+                $ref_id = $result['matches'][$int_id]['attrs']['ref_id'];
50
+                array_push($ids, $ref_id);
51
+            }
52
+        }
53 53
 
54
-		$ids = join(",", $ids);
54
+        $ids = join(",", $ids);
55 55
 
56
-		if ($ids) {
57
-					return array("ref_id IN ($ids)", array());
58
-		} else {
59
-					return array("ref_id = -1", array());
60
-		}
61
-	}
56
+        if ($ids) {
57
+                    return array("ref_id IN ($ids)", array());
58
+        } else {
59
+                    return array("ref_id = -1", array());
60
+        }
61
+    }
62 62
 
63
-	public function api_version() {
64
-		return 2;
65
-	}
63
+    public function api_version() {
64
+        return 2;
65
+    }
66 66
 }
Please login to merge, or discard this patch.
plugins/search_sphinx/sphinxapi.php 3 patches
Indentation   +1534 added lines, -1534 removed lines patch added patch discarded remove patch
@@ -123,1571 +123,1571 @@
 block discarded – undo
123 123
 /// pack 64-bit signed
124 124
 function sphPackI64($v)
125 125
 {
126
-	assert(is_numeric($v));
127
-
128
-	// x64
129
-	if (PHP_INT_SIZE >= 8)
130
-	{
131
-		$v = (int) $v;
132
-		return pack("NN", $v >> 32, $v & 0xFFFFFFFF);
133
-	}
134
-
135
-	// x32, int
136
-	if (is_int($v))
137
-		return pack("NN", $v < 0 ? -1 : 0, $v);
138
-
139
-	// x32, bcmath
140
-	if (function_exists("bcmul"))
141
-	{
142
-		if (bccomp($v, 0) == -1)
143
-			$v = bcadd("18446744073709551616", $v);
144
-		$h = bcdiv($v, "4294967296", 0);
145
-		$l = bcmod($v, "4294967296");
146
-		return pack("NN", (float) $h, (float) $l); // conversion to float is intentional; int would lose 31st bit
147
-	}
148
-
149
-	// x32, no-bcmath
150
-	$p = max(0, strlen($v) - 13);
151
-	$lo = abs((float) substr($v, $p));
152
-	$hi = abs((float) substr($v, 0, $p));
153
-
154
-	$m = $lo + $hi * 1316134912.0; // (10 ^ 13) % (1 << 32) = 1316134912
155
-	$q = floor($m / 4294967296.0);
156
-	$l = $m - ($q * 4294967296.0);
157
-	$h = $hi * 2328.0 + $q; // (10 ^ 13) / (1 << 32) = 2328
158
-
159
-	if ($v < 0)
160
-	{
161
-		if ($l == 0)
162
-			$h = 4294967296.0 - $h;
163
-		else
164
-		{
165
-			$h = 4294967295.0 - $h;
166
-			$l = 4294967296.0 - $l;
167
-		}
168
-	}
169
-	return pack("NN", $h, $l);
126
+    assert(is_numeric($v));
127
+
128
+    // x64
129
+    if (PHP_INT_SIZE >= 8)
130
+    {
131
+        $v = (int) $v;
132
+        return pack("NN", $v >> 32, $v & 0xFFFFFFFF);
133
+    }
134
+
135
+    // x32, int
136
+    if (is_int($v))
137
+        return pack("NN", $v < 0 ? -1 : 0, $v);
138
+
139
+    // x32, bcmath
140
+    if (function_exists("bcmul"))
141
+    {
142
+        if (bccomp($v, 0) == -1)
143
+            $v = bcadd("18446744073709551616", $v);
144
+        $h = bcdiv($v, "4294967296", 0);
145
+        $l = bcmod($v, "4294967296");
146
+        return pack("NN", (float) $h, (float) $l); // conversion to float is intentional; int would lose 31st bit
147
+    }
148
+
149
+    // x32, no-bcmath
150
+    $p = max(0, strlen($v) - 13);
151
+    $lo = abs((float) substr($v, $p));
152
+    $hi = abs((float) substr($v, 0, $p));
153
+
154
+    $m = $lo + $hi * 1316134912.0; // (10 ^ 13) % (1 << 32) = 1316134912
155
+    $q = floor($m / 4294967296.0);
156
+    $l = $m - ($q * 4294967296.0);
157
+    $h = $hi * 2328.0 + $q; // (10 ^ 13) / (1 << 32) = 2328
158
+
159
+    if ($v < 0)
160
+    {
161
+        if ($l == 0)
162
+            $h = 4294967296.0 - $h;
163
+        else
164
+        {
165
+            $h = 4294967295.0 - $h;
166
+            $l = 4294967296.0 - $l;
167
+        }
168
+    }
169
+    return pack("NN", $h, $l);
170 170
 }
171 171
 
172 172
 /// pack 64-bit unsigned
173 173
 function sphPackU64($v)
174 174
 {
175
-	assert(is_numeric($v));
176
-
177
-	// x64
178
-	if (PHP_INT_SIZE >= 8)
179
-	{
180
-		assert($v >= 0);
181
-
182
-		// x64, int
183
-		if (is_int($v))
184
-			return pack("NN", $v >> 32, $v & 0xFFFFFFFF);
185
-
186
-		// x64, bcmath
187
-		if (function_exists("bcmul"))
188
-		{
189
-			$h = bcdiv($v, 4294967296, 0);
190
-			$l = bcmod($v, 4294967296);
191
-			return pack("NN", $h, $l);
192
-		}
193
-
194
-		// x64, no-bcmath
195
-		$p = max(0, strlen($v) - 13);
196
-		$lo = (int) substr($v, $p);
197
-		$hi = (int) substr($v, 0, $p);
198
-
199
-		$m = $lo + $hi * 1316134912;
200
-		$l = $m % 4294967296;
201
-		$h = $hi * 2328 + (int) ($m / 4294967296);
202
-
203
-		return pack("NN", $h, $l);
204
-	}
205
-
206
-	// x32, int
207
-	if (is_int($v))
208
-		return pack("NN", 0, $v);
209
-
210
-	// x32, bcmath
211
-	if (function_exists("bcmul"))
212
-	{
213
-		$h = bcdiv($v, "4294967296", 0);
214
-		$l = bcmod($v, "4294967296");
215
-		return pack("NN", (float) $h, (float) $l); // conversion to float is intentional; int would lose 31st bit
216
-	}
217
-
218
-	// x32, no-bcmath
219
-	$p = max(0, strlen($v) - 13);
220
-	$lo = (float) substr($v, $p);
221
-	$hi = (float) substr($v, 0, $p);
222
-
223
-	$m = $lo + $hi * 1316134912.0;
224
-	$q = floor($m / 4294967296.0);
225
-	$l = $m - ($q * 4294967296.0);
226
-	$h = $hi * 2328.0 + $q;
227
-
228
-	return pack("NN", $h, $l);
175
+    assert(is_numeric($v));
176
+
177
+    // x64
178
+    if (PHP_INT_SIZE >= 8)
179
+    {
180
+        assert($v >= 0);
181
+
182
+        // x64, int
183
+        if (is_int($v))
184
+            return pack("NN", $v >> 32, $v & 0xFFFFFFFF);
185
+
186
+        // x64, bcmath
187
+        if (function_exists("bcmul"))
188
+        {
189
+            $h = bcdiv($v, 4294967296, 0);
190
+            $l = bcmod($v, 4294967296);
191
+            return pack("NN", $h, $l);
192
+        }
193
+
194
+        // x64, no-bcmath
195
+        $p = max(0, strlen($v) - 13);
196
+        $lo = (int) substr($v, $p);
197
+        $hi = (int) substr($v, 0, $p);
198
+
199
+        $m = $lo + $hi * 1316134912;
200
+        $l = $m % 4294967296;
201
+        $h = $hi * 2328 + (int) ($m / 4294967296);
202
+
203
+        return pack("NN", $h, $l);
204
+    }
205
+
206
+    // x32, int
207
+    if (is_int($v))
208
+        return pack("NN", 0, $v);
209
+
210
+    // x32, bcmath
211
+    if (function_exists("bcmul"))
212
+    {
213
+        $h = bcdiv($v, "4294967296", 0);
214
+        $l = bcmod($v, "4294967296");
215
+        return pack("NN", (float) $h, (float) $l); // conversion to float is intentional; int would lose 31st bit
216
+    }
217
+
218
+    // x32, no-bcmath
219
+    $p = max(0, strlen($v) - 13);
220
+    $lo = (float) substr($v, $p);
221
+    $hi = (float) substr($v, 0, $p);
222
+
223
+    $m = $lo + $hi * 1316134912.0;
224
+    $q = floor($m / 4294967296.0);
225
+    $l = $m - ($q * 4294967296.0);
226
+    $h = $hi * 2328.0 + $q;
227
+
228
+    return pack("NN", $h, $l);
229 229
 }
230 230
 
231 231
 // unpack 64-bit unsigned
232 232
 function sphUnpackU64($v)
233 233
 {
234
-	list ($hi, $lo) = array_values(unpack("N*N*", $v));
235
-
236
-	if (PHP_INT_SIZE >= 8)
237
-	{
238
-		if ($hi < 0) $hi += (1 << 32); // because php 5.2.2 to 5.2.5 is totally fucked up again
239
-		if ($lo < 0) $lo += (1 << 32);
240
-
241
-		// x64, int
242
-		if ($hi <= 2147483647)
243
-			return ($hi << 32) + $lo;
244
-
245
-		// x64, bcmath
246
-		if (function_exists("bcmul"))
247
-			return bcadd($lo, bcmul($hi, "4294967296"));
248
-
249
-		// x64, no-bcmath
250
-		$C = 100000;
251
-		$h = ((int) ($hi / $C) << 32) + (int) ($lo / $C);
252
-		$l = (($hi % $C) << 32) + ($lo % $C);
253
-		if ($l > $C)
254
-		{
255
-			$h += (int) ($l / $C);
256
-			$l  = $l % $C;
257
-		}
258
-
259
-		if ($h == 0)
260
-			return $l;
261
-		return sprintf("%d%05d", $h, $l);
262
-	}
263
-
264
-	// x32, int
265
-	if ($hi == 0)
266
-	{
267
-		if ($lo > 0)
268
-			return $lo;
269
-		return sprintf("%u", $lo);
270
-	}
271
-
272
-	$hi = sprintf("%u", $hi);
273
-	$lo = sprintf("%u", $lo);
274
-
275
-	// x32, bcmath
276
-	if (function_exists("bcmul"))
277
-		return bcadd($lo, bcmul($hi, "4294967296"));
278
-
279
-	// x32, no-bcmath
280
-	$hi = (float) $hi;
281
-	$lo = (float) $lo;
282
-
283
-	$q = floor($hi / 10000000.0);
284
-	$r = $hi - $q * 10000000.0;
285
-	$m = $lo + $r * 4967296.0;
286
-	$mq = floor($m / 10000000.0);
287
-	$l = $m - $mq * 10000000.0;
288
-	$h = $q * 4294967296.0 + $r * 429.0 + $mq;
289
-
290
-	$h = sprintf("%.0f", $h);
291
-	$l = sprintf("%07.0f", $l);
292
-	if ($h == "0")
293
-		return sprintf("%.0f", (float) $l);
294
-	return $h.$l;
234
+    list ($hi, $lo) = array_values(unpack("N*N*", $v));
235
+
236
+    if (PHP_INT_SIZE >= 8)
237
+    {
238
+        if ($hi < 0) $hi += (1 << 32); // because php 5.2.2 to 5.2.5 is totally fucked up again
239
+        if ($lo < 0) $lo += (1 << 32);
240
+
241
+        // x64, int
242
+        if ($hi <= 2147483647)
243
+            return ($hi << 32) + $lo;
244
+
245
+        // x64, bcmath
246
+        if (function_exists("bcmul"))
247
+            return bcadd($lo, bcmul($hi, "4294967296"));
248
+
249
+        // x64, no-bcmath
250
+        $C = 100000;
251
+        $h = ((int) ($hi / $C) << 32) + (int) ($lo / $C);
252
+        $l = (($hi % $C) << 32) + ($lo % $C);
253
+        if ($l > $C)
254
+        {
255
+            $h += (int) ($l / $C);
256
+            $l  = $l % $C;
257
+        }
258
+
259
+        if ($h == 0)
260
+            return $l;
261
+        return sprintf("%d%05d", $h, $l);
262
+    }
263
+
264
+    // x32, int
265
+    if ($hi == 0)
266
+    {
267
+        if ($lo > 0)
268
+            return $lo;
269
+        return sprintf("%u", $lo);
270
+    }
271
+
272
+    $hi = sprintf("%u", $hi);
273
+    $lo = sprintf("%u", $lo);
274
+
275
+    // x32, bcmath
276
+    if (function_exists("bcmul"))
277
+        return bcadd($lo, bcmul($hi, "4294967296"));
278
+
279
+    // x32, no-bcmath
280
+    $hi = (float) $hi;
281
+    $lo = (float) $lo;
282
+
283
+    $q = floor($hi / 10000000.0);
284
+    $r = $hi - $q * 10000000.0;
285
+    $m = $lo + $r * 4967296.0;
286
+    $mq = floor($m / 10000000.0);
287
+    $l = $m - $mq * 10000000.0;
288
+    $h = $q * 4294967296.0 + $r * 429.0 + $mq;
289
+
290
+    $h = sprintf("%.0f", $h);
291
+    $l = sprintf("%07.0f", $l);
292
+    if ($h == "0")
293
+        return sprintf("%.0f", (float) $l);
294
+    return $h.$l;
295 295
 }
296 296
 
297 297
 // unpack 64-bit signed
298 298
 function sphUnpackI64($v)
299 299
 {
300
-	list ($hi, $lo) = array_values(unpack("N*N*", $v));
301
-
302
-	// x64
303
-	if (PHP_INT_SIZE >= 8)
304
-	{
305
-		if ($hi < 0) $hi += (1 << 32); // because php 5.2.2 to 5.2.5 is totally fucked up again
306
-		if ($lo < 0) $lo += (1 << 32);
307
-
308
-		return ($hi << 32) + $lo;
309
-	}
310
-
311
-	// x32, int
312
-	if ($hi == 0)
313
-	{
314
-		if ($lo > 0)
315
-			return $lo;
316
-		return sprintf("%u", $lo);
317
-	}
318
-	// x32, int
319
-	elseif ($hi == -1)
320
-	{
321
-		if ($lo < 0)
322
-			return $lo;
323
-		return sprintf("%.0f", $lo - 4294967296.0);
324
-	}
325
-
326
-	$neg = "";
327
-	$c = 0;
328
-	if ($hi < 0)
329
-	{
330
-		$hi = ~$hi;
331
-		$lo = ~$lo;
332
-		$c = 1;
333
-		$neg = "-";
334
-	}
335
-
336
-	$hi = sprintf("%u", $hi);
337
-	$lo = sprintf("%u", $lo);
338
-
339
-	// x32, bcmath
340
-	if (function_exists("bcmul"))
341
-		return $neg.bcadd(bcadd($lo, bcmul($hi, "4294967296")), $c);
342
-
343
-	// x32, no-bcmath
344
-	$hi = (float) $hi;
345
-	$lo = (float) $lo;
346
-
347
-	$q = floor($hi / 10000000.0);
348
-	$r = $hi - $q * 10000000.0;
349
-	$m = $lo + $r * 4967296.0;
350
-	$mq = floor($m / 10000000.0);
351
-	$l = $m - $mq * 10000000.0 + $c;
352
-	$h = $q * 4294967296.0 + $r * 429.0 + $mq;
353
-	if ($l == 10000000)
354
-	{
355
-		$l = 0;
356
-		$h += 1;
357
-	}
358
-
359
-	$h = sprintf("%.0f", $h);
360
-	$l = sprintf("%07.0f", $l);
361
-	if ($h == "0")
362
-		return $neg.sprintf("%.0f", (float) $l);
363
-	return $neg.$h.$l;
300
+    list ($hi, $lo) = array_values(unpack("N*N*", $v));
301
+
302
+    // x64
303
+    if (PHP_INT_SIZE >= 8)
304
+    {
305
+        if ($hi < 0) $hi += (1 << 32); // because php 5.2.2 to 5.2.5 is totally fucked up again
306
+        if ($lo < 0) $lo += (1 << 32);
307
+
308
+        return ($hi << 32) + $lo;
309
+    }
310
+
311
+    // x32, int
312
+    if ($hi == 0)
313
+    {
314
+        if ($lo > 0)
315
+            return $lo;
316
+        return sprintf("%u", $lo);
317
+    }
318
+    // x32, int
319
+    elseif ($hi == -1)
320
+    {
321
+        if ($lo < 0)
322
+            return $lo;
323
+        return sprintf("%.0f", $lo - 4294967296.0);
324
+    }
325
+
326
+    $neg = "";
327
+    $c = 0;
328
+    if ($hi < 0)
329
+    {
330
+        $hi = ~$hi;
331
+        $lo = ~$lo;
332
+        $c = 1;
333
+        $neg = "-";
334
+    }
335
+
336
+    $hi = sprintf("%u", $hi);
337
+    $lo = sprintf("%u", $lo);
338
+
339
+    // x32, bcmath
340
+    if (function_exists("bcmul"))
341
+        return $neg.bcadd(bcadd($lo, bcmul($hi, "4294967296")), $c);
342
+
343
+    // x32, no-bcmath
344
+    $hi = (float) $hi;
345
+    $lo = (float) $lo;
346
+
347
+    $q = floor($hi / 10000000.0);
348
+    $r = $hi - $q * 10000000.0;
349
+    $m = $lo + $r * 4967296.0;
350
+    $mq = floor($m / 10000000.0);
351
+    $l = $m - $mq * 10000000.0 + $c;
352
+    $h = $q * 4294967296.0 + $r * 429.0 + $mq;
353
+    if ($l == 10000000)
354
+    {
355
+        $l = 0;
356
+        $h += 1;
357
+    }
358
+
359
+    $h = sprintf("%.0f", $h);
360
+    $l = sprintf("%07.0f", $l);
361
+    if ($h == "0")
362
+        return $neg.sprintf("%.0f", (float) $l);
363
+    return $neg.$h.$l;
364 364
 }
365 365
 
366 366
 
367 367
 function sphFixUint($value)
368 368
 {
369
-	if (PHP_INT_SIZE >= 8)
370
-	{
371
-		// x64 route, workaround broken unpack() in 5.2.2+
372
-		if ($value < 0) $value += (1 << 32);
373
-		return $value;
374
-	}
375
-	else
376
-	{
377
-		// x32 route, workaround php signed/unsigned braindamage
378
-		return sprintf("%u", $value);
379
-	}
369
+    if (PHP_INT_SIZE >= 8)
370
+    {
371
+        // x64 route, workaround broken unpack() in 5.2.2+
372
+        if ($value < 0) $value += (1 << 32);
373
+        return $value;
374
+    }
375
+    else
376
+    {
377
+        // x32 route, workaround php signed/unsigned braindamage
378
+        return sprintf("%u", $value);
379
+    }
380 380
 }
381 381
 
382 382
 
383 383
 /// sphinx searchd client class
384 384
 class SphinxClient
385 385
 {
386
-	var $_host; ///< searchd host (default is "localhost")
387
-	var $_port; ///< searchd port (default is 9312)
388
-	var $_offset; ///< how many records to seek from result-set start (default is 0)
389
-	var $_limit; ///< how many records to return from result-set starting at offset (default is 20)
390
-	var $_mode; ///< query matching mode (default is SPH_MATCH_ALL)
391
-	var $_weights; ///< per-field weights (default is 1 for all fields)
392
-	var $_sort; ///< match sorting mode (default is SPH_SORT_RELEVANCE)
393
-	var $_sortby; ///< attribute to sort by (defualt is "")
394
-	var $_min_id; ///< min ID to match (default is 0, which means no limit)
395
-	var $_max_id; ///< max ID to match (default is 0, which means no limit)
396
-	var $_filters; ///< search filters
397
-	var $_groupby; ///< group-by attribute name
398
-	var $_groupfunc; ///< group-by function (to pre-process group-by attribute value with)
399
-	var $_groupsort; ///< group-by sorting clause (to sort groups in result set with)
400
-	var $_groupdistinct; ///< group-by count-distinct attribute
401
-	var $_maxmatches; ///< max matches to retrieve
402
-	var $_cutoff; ///< cutoff to stop searching at (default is 0)
403
-	var $_retrycount; ///< distributed retries count
404
-	var $_retrydelay; ///< distributed retries delay
405
-	var $_anchor; ///< geographical anchor point
406
-	var $_indexweights; ///< per-index weights
407
-	var $_ranker; ///< ranking mode (default is SPH_RANK_PROXIMITY_BM25)
408
-	var $_maxquerytime; ///< max query time, milliseconds (default is 0, do not limit)
409
-	var $_fieldweights; ///< per-field-name weights
410
-	var $_overrides; ///< per-query attribute values overrides
411
-	var $_select; ///< select-list (attributes or expressions, with optional aliases)
412
-
413
-	var $_error; ///< last error message
414
-	var $_warning; ///< last warning message
415
-	var $_connerror; ///< connection error vs remote error flag
416
-
417
-	var $_reqs; ///< requests array for multi-query
418
-	var $_mbenc; ///< stored mbstring encoding
419
-	var $_arrayresult; ///< whether $result["matches"] should be a hash or an array
420
-	var $_timeout; ///< connect timeout
421
-
422
-	/////////////////////////////////////////////////////////////////////////////
423
-	// common stuff
424
-	/////////////////////////////////////////////////////////////////////////////
425
-
426
-	/// create a new client object and fill defaults
427
-	public function __construct()
428
-	{
429
-		// per-client-object settings
430
-		$this->_host		= "localhost";
431
-		$this->_port		= 9312;
432
-		$this->_path		= false;
433
-		$this->_socket		= false;
434
-
435
-		// per-query settings
436
-		$this->_offset		= 0;
437
-		$this->_limit = 20;
438
-		$this->_mode		= SPH_MATCH_ALL;
439
-		$this->_weights = array();
440
-		$this->_sort		= SPH_SORT_RELEVANCE;
441
-		$this->_sortby		= "";
442
-		$this->_min_id		= 0;
443
-		$this->_max_id		= 0;
444
-		$this->_filters		= array();
445
-		$this->_groupby		= "";
446
-		$this->_groupfunc	= SPH_GROUPBY_DAY;
447
-		$this->_groupsort	= "@group desc";
448
-		$this->_groupdistinct = "";
449
-		$this->_maxmatches	= 1000;
450
-		$this->_cutoff		= 0;
451
-		$this->_retrycount	= 0;
452
-		$this->_retrydelay	= 0;
453
-		$this->_anchor		= array();
454
-		$this->_indexweights = array();
455
-		$this->_ranker		= SPH_RANK_PROXIMITY_BM25;
456
-		$this->_maxquerytime = 0;
457
-		$this->_fieldweights = array();
458
-		$this->_overrides = array();
459
-		$this->_select = "*";
460
-
461
-		$this->_error = ""; // per-reply fields (for single-query case)
462
-		$this->_warning = "";
463
-		$this->_connerror = false;
464
-
465
-		$this->_reqs = array(); // requests storage (for multi-query case)
466
-		$this->_mbenc = "";
467
-		$this->_arrayresult = false;
468
-		$this->_timeout = 0;
469
-	}
470
-
471
-	public function __destruct()
472
-	{
473
-		if ($this->_socket !== false)
474
-			fclose($this->_socket);
475
-	}
476
-
477
-	/// get last error message (string)
478
-	public function GetLastError()
479
-	{
480
-		return $this->_error;
481
-	}
482
-
483
-	/// get last warning message (string)
484
-	public function GetLastWarning()
485
-	{
486
-		return $this->_warning;
487
-	}
488
-
489
-	/// get last error flag (to tell network connection errors from searchd errors or broken responses)
490
-	public function IsConnectError()
491
-	{
492
-		return $this->_connerror;
493
-	}
494
-
495
-	/// set searchd host name (string) and port (integer)
496
-	public function SetServer($host, $port = 0)
497
-	{
498
-		assert(is_string($host));
499
-		if ($host[0] == '/')
500
-		{
501
-			$this->_path = 'unix://'.$host;
502
-			return;
503
-		}
504
-		if (substr($host, 0, 7) == "unix://")
505
-		{
506
-			$this->_path = $host;
507
-			return;
508
-		}
509
-
510
-		assert(is_int($port));
511
-		$this->_host = $host;
512
-		$this->_port = $port;
513
-		$this->_path = '';
514
-
515
-	}
516
-
517
-	/// set server connection timeout (0 to remove)
518
-	public function SetConnectTimeout($timeout)
519
-	{
520
-		assert(is_numeric($timeout));
521
-		$this->_timeout = $timeout;
522
-	}
523
-
524
-
525
-	public function _Send($handle, $data, $length)
526
-	{
527
-		if (feof($handle) || fwrite($handle, $data, $length) !== $length)
528
-		{
529
-			$this->_error = 'connection unexpectedly closed (timed out?)';
530
-			$this->_connerror = true;
531
-			return false;
532
-		}
533
-		return true;
534
-	}
535
-
536
-	/////////////////////////////////////////////////////////////////////////////
537
-
538
-	/// enter mbstring workaround mode
539
-	public function _MBPush()
540
-	{
541
-		$this->_mbenc = "";
542
-		if (ini_get("mbstring.func_overload") & 2)
543
-		{
544
-			$this->_mbenc = mb_internal_encoding();
545
-			mb_internal_encoding("latin1");
546
-		}
386
+    var $_host; ///< searchd host (default is "localhost")
387
+    var $_port; ///< searchd port (default is 9312)
388
+    var $_offset; ///< how many records to seek from result-set start (default is 0)
389
+    var $_limit; ///< how many records to return from result-set starting at offset (default is 20)
390
+    var $_mode; ///< query matching mode (default is SPH_MATCH_ALL)
391
+    var $_weights; ///< per-field weights (default is 1 for all fields)
392
+    var $_sort; ///< match sorting mode (default is SPH_SORT_RELEVANCE)
393
+    var $_sortby; ///< attribute to sort by (defualt is "")
394
+    var $_min_id; ///< min ID to match (default is 0, which means no limit)
395
+    var $_max_id; ///< max ID to match (default is 0, which means no limit)
396
+    var $_filters; ///< search filters
397
+    var $_groupby; ///< group-by attribute name
398
+    var $_groupfunc; ///< group-by function (to pre-process group-by attribute value with)
399
+    var $_groupsort; ///< group-by sorting clause (to sort groups in result set with)
400
+    var $_groupdistinct; ///< group-by count-distinct attribute
401
+    var $_maxmatches; ///< max matches to retrieve
402
+    var $_cutoff; ///< cutoff to stop searching at (default is 0)
403
+    var $_retrycount; ///< distributed retries count
404
+    var $_retrydelay; ///< distributed retries delay
405
+    var $_anchor; ///< geographical anchor point
406
+    var $_indexweights; ///< per-index weights
407
+    var $_ranker; ///< ranking mode (default is SPH_RANK_PROXIMITY_BM25)
408
+    var $_maxquerytime; ///< max query time, milliseconds (default is 0, do not limit)
409
+    var $_fieldweights; ///< per-field-name weights
410
+    var $_overrides; ///< per-query attribute values overrides
411
+    var $_select; ///< select-list (attributes or expressions, with optional aliases)
412
+
413
+    var $_error; ///< last error message
414
+    var $_warning; ///< last warning message
415
+    var $_connerror; ///< connection error vs remote error flag
416
+
417
+    var $_reqs; ///< requests array for multi-query
418
+    var $_mbenc; ///< stored mbstring encoding
419
+    var $_arrayresult; ///< whether $result["matches"] should be a hash or an array
420
+    var $_timeout; ///< connect timeout
421
+
422
+    /////////////////////////////////////////////////////////////////////////////
423
+    // common stuff
424
+    /////////////////////////////////////////////////////////////////////////////
425
+
426
+    /// create a new client object and fill defaults
427
+    public function __construct()
428
+    {
429
+        // per-client-object settings
430
+        $this->_host		= "localhost";
431
+        $this->_port		= 9312;
432
+        $this->_path		= false;
433
+        $this->_socket		= false;
434
+
435
+        // per-query settings
436
+        $this->_offset		= 0;
437
+        $this->_limit = 20;
438
+        $this->_mode		= SPH_MATCH_ALL;
439
+        $this->_weights = array();
440
+        $this->_sort		= SPH_SORT_RELEVANCE;
441
+        $this->_sortby		= "";
442
+        $this->_min_id		= 0;
443
+        $this->_max_id		= 0;
444
+        $this->_filters		= array();
445
+        $this->_groupby		= "";
446
+        $this->_groupfunc	= SPH_GROUPBY_DAY;
447
+        $this->_groupsort	= "@group desc";
448
+        $this->_groupdistinct = "";
449
+        $this->_maxmatches	= 1000;
450
+        $this->_cutoff		= 0;
451
+        $this->_retrycount	= 0;
452
+        $this->_retrydelay	= 0;
453
+        $this->_anchor		= array();
454
+        $this->_indexweights = array();
455
+        $this->_ranker		= SPH_RANK_PROXIMITY_BM25;
456
+        $this->_maxquerytime = 0;
457
+        $this->_fieldweights = array();
458
+        $this->_overrides = array();
459
+        $this->_select = "*";
460
+
461
+        $this->_error = ""; // per-reply fields (for single-query case)
462
+        $this->_warning = "";
463
+        $this->_connerror = false;
464
+
465
+        $this->_reqs = array(); // requests storage (for multi-query case)
466
+        $this->_mbenc = "";
467
+        $this->_arrayresult = false;
468
+        $this->_timeout = 0;
469
+    }
470
+
471
+    public function __destruct()
472
+    {
473
+        if ($this->_socket !== false)
474
+            fclose($this->_socket);
475
+    }
476
+
477
+    /// get last error message (string)
478
+    public function GetLastError()
479
+    {
480
+        return $this->_error;
481
+    }
482
+
483
+    /// get last warning message (string)
484
+    public function GetLastWarning()
485
+    {
486
+        return $this->_warning;
487
+    }
488
+
489
+    /// get last error flag (to tell network connection errors from searchd errors or broken responses)
490
+    public function IsConnectError()
491
+    {
492
+        return $this->_connerror;
493
+    }
494
+
495
+    /// set searchd host name (string) and port (integer)
496
+    public function SetServer($host, $port = 0)
497
+    {
498
+        assert(is_string($host));
499
+        if ($host[0] == '/')
500
+        {
501
+            $this->_path = 'unix://'.$host;
502
+            return;
503
+        }
504
+        if (substr($host, 0, 7) == "unix://")
505
+        {
506
+            $this->_path = $host;
507
+            return;
508
+        }
509
+
510
+        assert(is_int($port));
511
+        $this->_host = $host;
512
+        $this->_port = $port;
513
+        $this->_path = '';
514
+
515
+    }
516
+
517
+    /// set server connection timeout (0 to remove)
518
+    public function SetConnectTimeout($timeout)
519
+    {
520
+        assert(is_numeric($timeout));
521
+        $this->_timeout = $timeout;
522
+    }
523
+
524
+
525
+    public function _Send($handle, $data, $length)
526
+    {
527
+        if (feof($handle) || fwrite($handle, $data, $length) !== $length)
528
+        {
529
+            $this->_error = 'connection unexpectedly closed (timed out?)';
530
+            $this->_connerror = true;
531
+            return false;
532
+        }
533
+        return true;
534
+    }
535
+
536
+    /////////////////////////////////////////////////////////////////////////////
537
+
538
+    /// enter mbstring workaround mode
539
+    public function _MBPush()
540
+    {
541
+        $this->_mbenc = "";
542
+        if (ini_get("mbstring.func_overload") & 2)
543
+        {
544
+            $this->_mbenc = mb_internal_encoding();
545
+            mb_internal_encoding("latin1");
546
+        }
547
+    }
548
+
549
+    /// leave mbstring workaround mode
550
+    public function _MBPop()
551
+    {
552
+        if ($this->_mbenc)
553
+            mb_internal_encoding($this->_mbenc);
554
+    }
555
+
556
+    /// connect to searchd server
557
+    public function _Connect()
558
+    {
559
+        if ($this->_socket !== false)
560
+        {
561
+            // we are in persistent connection mode, so we have a socket
562
+            // however, need to check whether it's still alive
563
+            if (!@feof($this->_socket))
564
+                return $this->_socket;
565
+
566
+            // force reopen
567
+            $this->_socket = false;
568
+        }
569
+
570
+        $errno = 0;
571
+        $errstr = "";
572
+        $this->_connerror = false;
573
+
574
+        if ($this->_path)
575
+        {
576
+            $host = $this->_path;
577
+            $port = 0;
578
+        }
579
+        else
580
+        {
581
+            $host = $this->_host;
582
+            $port = $this->_port;
583
+        }
584
+
585
+        if ($this->_timeout <= 0)
586
+            $fp = @fsockopen($host, $port, $errno, $errstr);
587
+        else
588
+            $fp = @fsockopen($host, $port, $errno, $errstr, $this->_timeout);
589
+
590
+        if (!$fp)
591
+        {
592
+            if ($this->_path)
593
+                $location = $this->_path;
594
+            else
595
+                $location = "{$this->_host}:{$this->_port}";
596
+
597
+            $errstr = trim($errstr);
598
+            $this->_error = "connection to $location failed (errno=$errno, msg=$errstr)";
599
+            $this->_connerror = true;
600
+            return false;
601
+        }
602
+
603
+        // send my version
604
+        // this is a subtle part. we must do it before (!) reading back from searchd.
605
+        // because otherwise under some conditions (reported on FreeBSD for instance)
606
+        // TCP stack could throttle write-write-read pattern because of Nagle.
607
+        if (!$this->_Send($fp, pack("N", 1), 4))
608
+        {
609
+            fclose($fp);
610
+            $this->_error = "failed to send client protocol version";
611
+            return false;
612
+        }
613
+
614
+        // check version
615
+        list(,$v) = unpack("N*", fread($fp, 4));
616
+        $v = (int) $v;
617
+        if ($v < 1)
618
+        {
619
+            fclose($fp);
620
+            $this->_error = "expected searchd protocol version 1+, got version '$v'";
621
+            return false;
622
+        }
623
+
624
+        return $fp;
625
+    }
626
+
627
+    /// get and check response packet from searchd server
628
+    public function _GetResponse($fp, $client_ver)
629
+    {
630
+        $response = "";
631
+        $len = 0;
632
+
633
+        $header = fread($fp, 8);
634
+        if (strlen($header) == 8)
635
+        {
636
+            list ($status, $ver, $len) = array_values(unpack("n2a/Nb", $header));
637
+            $left = $len;
638
+            while ($left > 0 && !feof($fp))
639
+            {
640
+                $chunk = fread($fp, min(8192, $left));
641
+                if ($chunk)
642
+                {
643
+                    $response .= $chunk;
644
+                    $left -= strlen($chunk);
645
+                }
646
+            }
647
+        }
648
+        if ($this->_socket === false)
649
+            fclose($fp);
650
+
651
+        // check response
652
+        $read = strlen($response);
653
+        if (!$response || $read != $len)
654
+        {
655
+            $this->_error = $len
656
+                ? "failed to read searchd response (status=$status, ver=$ver, len=$len, read=$read)"
657
+                : "received zero-sized searchd response";
658
+            return false;
659
+        }
660
+
661
+        // check status
662
+        if ($status == SEARCHD_WARNING)
663
+        {
664
+            list(,$wlen) = unpack("N*", substr($response, 0, 4));
665
+            $this->_warning = substr($response, 4, $wlen);
666
+            return substr($response, 4 + $wlen);
667
+        }
668
+        if ($status == SEARCHD_ERROR)
669
+        {
670
+            $this->_error = "searchd error: ".substr($response, 4);
671
+            return false;
672
+        }
673
+        if ($status == SEARCHD_RETRY)
674
+        {
675
+            $this->_error = "temporary searchd error: ".substr($response, 4);
676
+            return false;
677
+        }
678
+        if ($status != SEARCHD_OK)
679
+        {
680
+            $this->_error = "unknown status code '$status'";
681
+            return false;
682
+        }
683
+
684
+        // check version
685
+        if ($ver < $client_ver)
686
+        {
687
+            $this->_warning = sprintf("searchd command v.%d.%d older than client's v.%d.%d, some options might not work",
688
+                $ver >> 8, $ver & 0xff, $client_ver >> 8, $client_ver & 0xff);
689
+        }
690
+
691
+        return $response;
692
+    }
693
+
694
+    /////////////////////////////////////////////////////////////////////////////
695
+    // searching
696
+    /////////////////////////////////////////////////////////////////////////////
697
+
698
+    /// set offset and count into result set,
699
+    /// and optionally set max-matches and cutoff limits
700
+    public function SetLimits($offset, $limit, $max = 0, $cutoff = 0)
701
+    {
702
+        assert(is_int($offset));
703
+        assert(is_int($limit));
704
+        assert($offset >= 0);
705
+        assert($limit > 0);
706
+        assert($max >= 0);
707
+        $this->_offset = $offset;
708
+        $this->_limit = $limit;
709
+        if ($max > 0)
710
+            $this->_maxmatches = $max;
711
+        if ($cutoff > 0)
712
+            $this->_cutoff = $cutoff;
713
+    }
714
+
715
+    /// set maximum query time, in milliseconds, per-index
716
+    /// integer, 0 means "do not limit"
717
+    public function SetMaxQueryTime($max)
718
+    {
719
+        assert(is_int($max));
720
+        assert($max >= 0);
721
+        $this->_maxquerytime = $max;
722
+    }
723
+
724
+    /// set matching mode
725
+    public function SetMatchMode($mode)
726
+    {
727
+        assert($mode == SPH_MATCH_ALL
728
+            || $mode == SPH_MATCH_ANY
729
+            || $mode == SPH_MATCH_PHRASE
730
+            || $mode == SPH_MATCH_BOOLEAN
731
+            || $mode == SPH_MATCH_EXTENDED
732
+            || $mode == SPH_MATCH_FULLSCAN
733
+            || $mode == SPH_MATCH_EXTENDED2);
734
+        $this->_mode = $mode;
735
+    }
736
+
737
+    /// set ranking mode
738
+    public function SetRankingMode($ranker)
739
+    {
740
+        assert($ranker >= 0 && $ranker < SPH_RANK_TOTAL);
741
+        $this->_ranker = $ranker;
742
+    }
743
+
744
+    /// set matches sorting mode
745
+    public function SetSortMode($mode, $sortby = "")
746
+    {
747
+        assert(
748
+            $mode == SPH_SORT_RELEVANCE ||
749
+            $mode == SPH_SORT_ATTR_DESC ||
750
+            $mode == SPH_SORT_ATTR_ASC ||
751
+            $mode == SPH_SORT_TIME_SEGMENTS ||
752
+            $mode == SPH_SORT_EXTENDED ||
753
+            $mode == SPH_SORT_EXPR );
754
+        assert(is_string($sortby));
755
+        assert($mode == SPH_SORT_RELEVANCE || strlen($sortby) > 0);
756
+
757
+        $this->_sort = $mode;
758
+        $this->_sortby = $sortby;
759
+    }
760
+
761
+    /// bind per-field weights by order
762
+    /// DEPRECATED; use SetFieldWeights() instead
763
+    public function SetWeights($weights)
764
+    {
765
+        assert(is_array($weights));
766
+        foreach ($weights as $weight)
767
+            assert(is_int($weight));
768
+
769
+        $this->_weights = $weights;
770
+    }
771
+
772
+    /// bind per-field weights by name
773
+    public function SetFieldWeights($weights)
774
+    {
775
+        assert(is_array($weights));
776
+        foreach ($weights as $name=>$weight)
777
+        {
778
+            assert(is_string($name));
779
+            assert(is_int($weight));
780
+        }
781
+        $this->_fieldweights = $weights;
782
+    }
783
+
784
+    /// bind per-index weights by name
785
+    public function SetIndexWeights($weights)
786
+    {
787
+        assert(is_array($weights));
788
+        foreach ($weights as $index=>$weight)
789
+        {
790
+            assert(is_string($index));
791
+            assert(is_int($weight));
792
+        }
793
+        $this->_indexweights = $weights;
794
+    }
795
+
796
+    /// set IDs range to match
797
+    /// only match records if document ID is beetwen $min and $max (inclusive)
798
+    public function SetIDRange($min, $max)
799
+    {
800
+        assert(is_numeric($min));
801
+        assert(is_numeric($max));
802
+        assert($min <= $max);
803
+        $this->_min_id = $min;
804
+        $this->_max_id = $max;
805
+    }
806
+
807
+    /// set values set filter
808
+    /// only match records where $attribute value is in given set
809
+    public function SetFilter($attribute, $values, $exclude = false)
810
+    {
811
+        assert(is_string($attribute));
812
+        assert(is_array($values));
813
+        assert(count($values));
814
+
815
+        if (is_array($values) && count($values))
816
+        {
817
+            foreach ($values as $value)
818
+                assert(is_numeric($value));
819
+
820
+            $this->_filters[] = array("type"=>SPH_FILTER_VALUES, "attr"=>$attribute, "exclude"=>$exclude, "values"=>$values);
821
+        }
822
+    }
823
+
824
+    /// set range filter
825
+    /// only match records if $attribute value is beetwen $min and $max (inclusive)
826
+    public function SetFilterRange($attribute, $min, $max, $exclude = false)
827
+    {
828
+        assert(is_string($attribute));
829
+        assert(is_numeric($min));
830
+        assert(is_numeric($max));
831
+        assert($min <= $max);
832
+
833
+        $this->_filters[] = array("type"=>SPH_FILTER_RANGE, "attr"=>$attribute, "exclude"=>$exclude, "min"=>$min, "max"=>$max);
834
+    }
835
+
836
+    /// set float range filter
837
+    /// only match records if $attribute value is beetwen $min and $max (inclusive)
838
+    public function SetFilterFloatRange($attribute, $min, $max, $exclude = false)
839
+    {
840
+        assert(is_string($attribute));
841
+        assert(is_float($min));
842
+        assert(is_float($max));
843
+        assert($min <= $max);
844
+
845
+        $this->_filters[] = array("type"=>SPH_FILTER_FLOATRANGE, "attr"=>$attribute, "exclude"=>$exclude, "min"=>$min, "max"=>$max);
846
+    }
847
+
848
+    /// setup anchor point for geosphere distance calculations
849
+    /// required to use @geodist in filters and sorting
850
+    /// latitude and longitude must be in radians
851
+    public function SetGeoAnchor($attrlat, $attrlong, $lat, $long)
852
+    {
853
+        assert(is_string($attrlat));
854
+        assert(is_string($attrlong));
855
+        assert(is_float($lat));
856
+        assert(is_float($long));
857
+
858
+        $this->_anchor = array("attrlat"=>$attrlat, "attrlong"=>$attrlong, "lat"=>$lat, "long"=>$long);
859
+    }
860
+
861
+    /// set grouping attribute and function
862
+    public function SetGroupBy($attribute, $func, $groupsort = "@group desc")
863
+    {
864
+        assert(is_string($attribute));
865
+        assert(is_string($groupsort));
866
+        assert($func == SPH_GROUPBY_DAY
867
+            || $func == SPH_GROUPBY_WEEK
868
+            || $func == SPH_GROUPBY_MONTH
869
+            || $func == SPH_GROUPBY_YEAR
870
+            || $func == SPH_GROUPBY_ATTR
871
+            || $func == SPH_GROUPBY_ATTRPAIR);
872
+
873
+        $this->_groupby = $attribute;
874
+        $this->_groupfunc = $func;
875
+        $this->_groupsort = $groupsort;
876
+    }
877
+
878
+    /// set count-distinct attribute for group-by queries
879
+    public function SetGroupDistinct($attribute)
880
+    {
881
+        assert(is_string($attribute));
882
+        $this->_groupdistinct = $attribute;
883
+    }
884
+
885
+    /// set distributed retries count and delay
886
+    public function SetRetries($count, $delay = 0)
887
+    {
888
+        assert(is_int($count) && $count >= 0);
889
+        assert(is_int($delay) && $delay >= 0);
890
+        $this->_retrycount = $count;
891
+        $this->_retrydelay = $delay;
892
+    }
893
+
894
+    /// set result set format (hash or array; hash by default)
895
+    /// PHP specific; needed for group-by-MVA result sets that may contain duplicate IDs
896
+    public function SetArrayResult($arrayresult)
897
+    {
898
+        assert(is_bool($arrayresult));
899
+        $this->_arrayresult = $arrayresult;
900
+    }
901
+
902
+    /// set attribute values override
903
+    /// there can be only one override per attribute
904
+    /// $values must be a hash that maps document IDs to attribute values
905
+    public function SetOverride($attrname, $attrtype, $values)
906
+    {
907
+        assert(is_string($attrname));
908
+        assert(in_array($attrtype, array(SPH_ATTR_INTEGER, SPH_ATTR_TIMESTAMP, SPH_ATTR_BOOL, SPH_ATTR_FLOAT, SPH_ATTR_BIGINT)));
909
+        assert(is_array($values));
910
+
911
+        $this->_overrides[$attrname] = array("attr"=>$attrname, "type"=>$attrtype, "values"=>$values);
912
+    }
913
+
914
+    /// set select-list (attributes or expressions), SQL-like syntax
915
+    public function SetSelect($select)
916
+    {
917
+        assert(is_string($select));
918
+        $this->_select = $select;
919
+    }
920
+
921
+    //////////////////////////////////////////////////////////////////////////////
922
+
923
+    /// clear all filters (for multi-queries)
924
+    public function ResetFilters()
925
+    {
926
+        $this->_filters = array();
927
+        $this->_anchor = array();
928
+    }
929
+
930
+    /// clear groupby settings (for multi-queries)
931
+    public function ResetGroupBy()
932
+    {
933
+        $this->_groupby = "";
934
+        $this->_groupfunc	= SPH_GROUPBY_DAY;
935
+        $this->_groupsort	= "@group desc";
936
+        $this->_groupdistinct = "";
547 937
     }
548 938
 
549
-	/// leave mbstring workaround mode
550
-	public function _MBPop()
551
-	{
552
-		if ($this->_mbenc)
553
-			mb_internal_encoding($this->_mbenc);
554
-	}
555
-
556
-	/// connect to searchd server
557
-	public function _Connect()
558
-	{
559
-		if ($this->_socket !== false)
560
-		{
561
-			// we are in persistent connection mode, so we have a socket
562
-			// however, need to check whether it's still alive
563
-			if (!@feof($this->_socket))
564
-				return $this->_socket;
565
-
566
-			// force reopen
567
-			$this->_socket = false;
568
-		}
569
-
570
-		$errno = 0;
571
-		$errstr = "";
572
-		$this->_connerror = false;
573
-
574
-		if ($this->_path)
575
-		{
576
-			$host = $this->_path;
577
-			$port = 0;
578
-		}
579
-		else
580
-		{
581
-			$host = $this->_host;
582
-			$port = $this->_port;
583
-		}
584
-
585
-		if ($this->_timeout <= 0)
586
-			$fp = @fsockopen($host, $port, $errno, $errstr);
587
-		else
588
-			$fp = @fsockopen($host, $port, $errno, $errstr, $this->_timeout);
589
-
590
-		if (!$fp)
591
-		{
592
-			if ($this->_path)
593
-				$location = $this->_path;
594
-			else
595
-				$location = "{$this->_host}:{$this->_port}";
596
-
597
-			$errstr = trim($errstr);
598
-			$this->_error = "connection to $location failed (errno=$errno, msg=$errstr)";
599
-			$this->_connerror = true;
600
-			return false;
601
-		}
602
-
603
-		// send my version
604
-		// this is a subtle part. we must do it before (!) reading back from searchd.
605
-		// because otherwise under some conditions (reported on FreeBSD for instance)
606
-		// TCP stack could throttle write-write-read pattern because of Nagle.
607
-		if (!$this->_Send($fp, pack("N", 1), 4))
608
-		{
609
-			fclose($fp);
610
-			$this->_error = "failed to send client protocol version";
611
-			return false;
612
-		}
613
-
614
-		// check version
615
-		list(,$v) = unpack("N*", fread($fp, 4));
616
-		$v = (int) $v;
617
-		if ($v < 1)
618
-		{
619
-			fclose($fp);
620
-			$this->_error = "expected searchd protocol version 1+, got version '$v'";
621
-			return false;
622
-		}
623
-
624
-		return $fp;
625
-	}
626
-
627
-	/// get and check response packet from searchd server
628
-	public function _GetResponse($fp, $client_ver)
629
-	{
630
-		$response = "";
631
-		$len = 0;
632
-
633
-		$header = fread($fp, 8);
634
-		if (strlen($header) == 8)
635
-		{
636
-			list ($status, $ver, $len) = array_values(unpack("n2a/Nb", $header));
637
-			$left = $len;
638
-			while ($left > 0 && !feof($fp))
639
-			{
640
-				$chunk = fread($fp, min(8192, $left));
641
-				if ($chunk)
642
-				{
643
-					$response .= $chunk;
644
-					$left -= strlen($chunk);
645
-				}
646
-			}
647
-		}
648
-		if ($this->_socket === false)
649
-			fclose($fp);
650
-
651
-		// check response
652
-		$read = strlen($response);
653
-		if (!$response || $read != $len)
654
-		{
655
-			$this->_error = $len
656
-				? "failed to read searchd response (status=$status, ver=$ver, len=$len, read=$read)"
657
-				: "received zero-sized searchd response";
658
-			return false;
659
-		}
660
-
661
-		// check status
662
-		if ($status == SEARCHD_WARNING)
663
-		{
664
-			list(,$wlen) = unpack("N*", substr($response, 0, 4));
665
-			$this->_warning = substr($response, 4, $wlen);
666
-			return substr($response, 4 + $wlen);
667
-		}
668
-		if ($status == SEARCHD_ERROR)
669
-		{
670
-			$this->_error = "searchd error: ".substr($response, 4);
671
-			return false;
672
-		}
673
-		if ($status == SEARCHD_RETRY)
674
-		{
675
-			$this->_error = "temporary searchd error: ".substr($response, 4);
676
-			return false;
677
-		}
678
-		if ($status != SEARCHD_OK)
679
-		{
680
-			$this->_error = "unknown status code '$status'";
681
-			return false;
682
-		}
683
-
684
-		// check version
685
-		if ($ver < $client_ver)
686
-		{
687
-			$this->_warning = sprintf("searchd command v.%d.%d older than client's v.%d.%d, some options might not work",
688
-				$ver >> 8, $ver & 0xff, $client_ver >> 8, $client_ver & 0xff);
689
-		}
690
-
691
-		return $response;
692
-	}
693
-
694
-	/////////////////////////////////////////////////////////////////////////////
695
-	// searching
696
-	/////////////////////////////////////////////////////////////////////////////
697
-
698
-	/// set offset and count into result set,
699
-	/// and optionally set max-matches and cutoff limits
700
-	public function SetLimits($offset, $limit, $max = 0, $cutoff = 0)
701
-	{
702
-		assert(is_int($offset));
703
-		assert(is_int($limit));
704
-		assert($offset >= 0);
705
-		assert($limit > 0);
706
-		assert($max >= 0);
707
-		$this->_offset = $offset;
708
-		$this->_limit = $limit;
709
-		if ($max > 0)
710
-			$this->_maxmatches = $max;
711
-		if ($cutoff > 0)
712
-			$this->_cutoff = $cutoff;
713
-	}
714
-
715
-	/// set maximum query time, in milliseconds, per-index
716
-	/// integer, 0 means "do not limit"
717
-	public function SetMaxQueryTime($max)
718
-	{
719
-		assert(is_int($max));
720
-		assert($max >= 0);
721
-		$this->_maxquerytime = $max;
722
-	}
723
-
724
-	/// set matching mode
725
-	public function SetMatchMode($mode)
726
-	{
727
-		assert($mode == SPH_MATCH_ALL
728
-			|| $mode == SPH_MATCH_ANY
729
-			|| $mode == SPH_MATCH_PHRASE
730
-			|| $mode == SPH_MATCH_BOOLEAN
731
-			|| $mode == SPH_MATCH_EXTENDED
732
-			|| $mode == SPH_MATCH_FULLSCAN
733
-			|| $mode == SPH_MATCH_EXTENDED2);
734
-		$this->_mode = $mode;
735
-	}
736
-
737
-	/// set ranking mode
738
-	public function SetRankingMode($ranker)
739
-	{
740
-		assert($ranker >= 0 && $ranker < SPH_RANK_TOTAL);
741
-		$this->_ranker = $ranker;
742
-	}
743
-
744
-	/// set matches sorting mode
745
-	public function SetSortMode($mode, $sortby = "")
746
-	{
747
-		assert(
748
-			$mode == SPH_SORT_RELEVANCE ||
749
-			$mode == SPH_SORT_ATTR_DESC ||
750
-			$mode == SPH_SORT_ATTR_ASC ||
751
-			$mode == SPH_SORT_TIME_SEGMENTS ||
752
-			$mode == SPH_SORT_EXTENDED ||
753
-			$mode == SPH_SORT_EXPR );
754
-		assert(is_string($sortby));
755
-		assert($mode == SPH_SORT_RELEVANCE || strlen($sortby) > 0);
756
-
757
-		$this->_sort = $mode;
758
-		$this->_sortby = $sortby;
759
-	}
760
-
761
-	/// bind per-field weights by order
762
-	/// DEPRECATED; use SetFieldWeights() instead
763
-	public function SetWeights($weights)
764
-	{
765
-		assert(is_array($weights));
766
-		foreach ($weights as $weight)
767
-			assert(is_int($weight));
768
-
769
-		$this->_weights = $weights;
770
-	}
771
-
772
-	/// bind per-field weights by name
773
-	public function SetFieldWeights($weights)
774
-	{
775
-		assert(is_array($weights));
776
-		foreach ($weights as $name=>$weight)
777
-		{
778
-			assert(is_string($name));
779
-			assert(is_int($weight));
780
-		}
781
-		$this->_fieldweights = $weights;
782
-	}
783
-
784
-	/// bind per-index weights by name
785
-	public function SetIndexWeights($weights)
786
-	{
787
-		assert(is_array($weights));
788
-		foreach ($weights as $index=>$weight)
789
-		{
790
-			assert(is_string($index));
791
-			assert(is_int($weight));
792
-		}
793
-		$this->_indexweights = $weights;
794
-	}
795
-
796
-	/// set IDs range to match
797
-	/// only match records if document ID is beetwen $min and $max (inclusive)
798
-	public function SetIDRange($min, $max)
799
-	{
800
-		assert(is_numeric($min));
801
-		assert(is_numeric($max));
802
-		assert($min <= $max);
803
-		$this->_min_id = $min;
804
-		$this->_max_id = $max;
805
-	}
806
-
807
-	/// set values set filter
808
-	/// only match records where $attribute value is in given set
809
-	public function SetFilter($attribute, $values, $exclude = false)
810
-	{
811
-		assert(is_string($attribute));
812
-		assert(is_array($values));
813
-		assert(count($values));
814
-
815
-		if (is_array($values) && count($values))
816
-		{
817
-			foreach ($values as $value)
818
-				assert(is_numeric($value));
819
-
820
-			$this->_filters[] = array("type"=>SPH_FILTER_VALUES, "attr"=>$attribute, "exclude"=>$exclude, "values"=>$values);
821
-		}
822
-	}
823
-
824
-	/// set range filter
825
-	/// only match records if $attribute value is beetwen $min and $max (inclusive)
826
-	public function SetFilterRange($attribute, $min, $max, $exclude = false)
827
-	{
828
-		assert(is_string($attribute));
829
-		assert(is_numeric($min));
830
-		assert(is_numeric($max));
831
-		assert($min <= $max);
832
-
833
-		$this->_filters[] = array("type"=>SPH_FILTER_RANGE, "attr"=>$attribute, "exclude"=>$exclude, "min"=>$min, "max"=>$max);
834
-	}
835
-
836
-	/// set float range filter
837
-	/// only match records if $attribute value is beetwen $min and $max (inclusive)
838
-	public function SetFilterFloatRange($attribute, $min, $max, $exclude = false)
839
-	{
840
-		assert(is_string($attribute));
841
-		assert(is_float($min));
842
-		assert(is_float($max));
843
-		assert($min <= $max);
844
-
845
-		$this->_filters[] = array("type"=>SPH_FILTER_FLOATRANGE, "attr"=>$attribute, "exclude"=>$exclude, "min"=>$min, "max"=>$max);
846
-	}
847
-
848
-	/// setup anchor point for geosphere distance calculations
849
-	/// required to use @geodist in filters and sorting
850
-	/// latitude and longitude must be in radians
851
-	public function SetGeoAnchor($attrlat, $attrlong, $lat, $long)
852
-	{
853
-		assert(is_string($attrlat));
854
-		assert(is_string($attrlong));
855
-		assert(is_float($lat));
856
-		assert(is_float($long));
857
-
858
-		$this->_anchor = array("attrlat"=>$attrlat, "attrlong"=>$attrlong, "lat"=>$lat, "long"=>$long);
859
-	}
860
-
861
-	/// set grouping attribute and function
862
-	public function SetGroupBy($attribute, $func, $groupsort = "@group desc")
863
-	{
864
-		assert(is_string($attribute));
865
-		assert(is_string($groupsort));
866
-		assert($func == SPH_GROUPBY_DAY
867
-			|| $func == SPH_GROUPBY_WEEK
868
-			|| $func == SPH_GROUPBY_MONTH
869
-			|| $func == SPH_GROUPBY_YEAR
870
-			|| $func == SPH_GROUPBY_ATTR
871
-			|| $func == SPH_GROUPBY_ATTRPAIR);
872
-
873
-		$this->_groupby = $attribute;
874
-		$this->_groupfunc = $func;
875
-		$this->_groupsort = $groupsort;
876
-	}
877
-
878
-	/// set count-distinct attribute for group-by queries
879
-	public function SetGroupDistinct($attribute)
880
-	{
881
-		assert(is_string($attribute));
882
-		$this->_groupdistinct = $attribute;
883
-	}
884
-
885
-	/// set distributed retries count and delay
886
-	public function SetRetries($count, $delay = 0)
887
-	{
888
-		assert(is_int($count) && $count >= 0);
889
-		assert(is_int($delay) && $delay >= 0);
890
-		$this->_retrycount = $count;
891
-		$this->_retrydelay = $delay;
892
-	}
893
-
894
-	/// set result set format (hash or array; hash by default)
895
-	/// PHP specific; needed for group-by-MVA result sets that may contain duplicate IDs
896
-	public function SetArrayResult($arrayresult)
897
-	{
898
-		assert(is_bool($arrayresult));
899
-		$this->_arrayresult = $arrayresult;
900
-	}
901
-
902
-	/// set attribute values override
903
-	/// there can be only one override per attribute
904
-	/// $values must be a hash that maps document IDs to attribute values
905
-	public function SetOverride($attrname, $attrtype, $values)
906
-	{
907
-		assert(is_string($attrname));
908
-		assert(in_array($attrtype, array(SPH_ATTR_INTEGER, SPH_ATTR_TIMESTAMP, SPH_ATTR_BOOL, SPH_ATTR_FLOAT, SPH_ATTR_BIGINT)));
909
-		assert(is_array($values));
910
-
911
-		$this->_overrides[$attrname] = array("attr"=>$attrname, "type"=>$attrtype, "values"=>$values);
912
-	}
913
-
914
-	/// set select-list (attributes or expressions), SQL-like syntax
915
-	public function SetSelect($select)
916
-	{
917
-		assert(is_string($select));
918
-		$this->_select = $select;
919
-	}
920
-
921
-	//////////////////////////////////////////////////////////////////////////////
922
-
923
-	/// clear all filters (for multi-queries)
924
-	public function ResetFilters()
925
-	{
926
-		$this->_filters = array();
927
-		$this->_anchor = array();
928
-	}
929
-
930
-	/// clear groupby settings (for multi-queries)
931
-	public function ResetGroupBy()
932
-	{
933
-		$this->_groupby = "";
934
-		$this->_groupfunc	= SPH_GROUPBY_DAY;
935
-		$this->_groupsort	= "@group desc";
936
-		$this->_groupdistinct = "";
937
-	}
938
-
939
-	/// clear all attribute value overrides (for multi-queries)
940
-	public function ResetOverrides()
939
+    /// clear all attribute value overrides (for multi-queries)
940
+    public function ResetOverrides()
941 941
     {
942
-    	$this->_overrides = array();
942
+        $this->_overrides = array();
943 943
     }
944 944
 
945
-	//////////////////////////////////////////////////////////////////////////////
946
-
947
-	/// connect to searchd server, run given search query through given indexes,
948
-	/// and return the search results
949
-	public function Query($query, $index = "*", $comment = "")
950
-	{
951
-		assert(empty($this->_reqs));
952
-
953
-		$this->AddQuery($query, $index, $comment);
954
-		$results = $this->RunQueries();
955
-		$this->_reqs = array(); // just in case it failed too early
956
-
957
-		if (!is_array($results))
958
-			return false; // probably network error; error message should be already filled
959
-
960
-		$this->_error = $results[0]["error"];
961
-		$this->_warning = $results[0]["warning"];
962
-		if ($results[0]["status"] == SEARCHD_ERROR)
963
-			return false;
964
-		else
965
-			return $results[0];
966
-	}
967
-
968
-	/// helper to pack floats in network byte order
969
-	public function _PackFloat($f)
970
-	{
971
-		$t1 = pack("f", $f); // machine order
972
-		list(,$t2) = unpack("L*", $t1); // int in machine order
973
-		return pack("N", $t2);
974
-	}
975
-
976
-	/**
977
-	 * @SuppressWarnings(unused)
978
-	 */
979
-
980
-	/// add query to multi-query batch
981
-	/// returns index into results array from RunQueries() call
982
-	public function AddQuery($query, $index = "*", $comment = "")
983
-	{
984
-		// mbstring workaround
985
-		$this->_MBPush();
986
-
987
-		// build request
988
-		$req = pack("NNNNN", $this->_offset, $this->_limit, $this->_mode, $this->_ranker, $this->_sort); // mode and limits
989
-		$req .= pack("N", strlen($this->_sortby)).$this->_sortby;
990
-		$req .= pack("N", strlen($query)).$query; // query itself
991
-		$req .= pack("N", count($this->_weights)); // weights
992
-		foreach ($this->_weights as $weight)
993
-			$req .= pack("N", (int) $weight);
994
-		$req .= pack("N", strlen($index)).$index; // indexes
995
-		$req .= pack("N", 1); // id64 range marker
996
-		$req .= sphPackU64($this->_min_id).sphPackU64($this->_max_id); // id64 range
997
-
998
-		// filters
999
-		$req .= pack("N", count($this->_filters));
1000
-		foreach ($this->_filters as $filter)
1001
-		{
1002
-			$req .= pack("N", strlen($filter["attr"])).$filter["attr"];
1003
-			$req .= pack("N", $filter["type"]);
1004
-			switch ($filter["type"])
1005
-			{
1006
-				case SPH_FILTER_VALUES:
1007
-					$req .= pack("N", count($filter["values"]));
1008
-					foreach ($filter["values"] as $value)
1009
-						$req .= sphPackI64($value);
1010
-					break;
1011
-
1012
-				case SPH_FILTER_RANGE:
1013
-					$req .= sphPackI64($filter["min"]).sphPackI64($filter["max"]);
1014
-					break;
1015
-
1016
-				case SPH_FILTER_FLOATRANGE:
1017
-					$req .= $this->_PackFloat($filter["min"]).$this->_PackFloat($filter["max"]);
1018
-					break;
1019
-
1020
-				default:
1021
-					assert(0 && "internal error: unhandled filter type");
1022
-			}
1023
-			$req .= pack("N", $filter["exclude"]);
1024
-		}
1025
-
1026
-		// group-by clause, max-matches count, group-sort clause, cutoff count
1027
-		$req .= pack("NN", $this->_groupfunc, strlen($this->_groupby)).$this->_groupby;
1028
-		$req .= pack("N", $this->_maxmatches);
1029
-		$req .= pack("N", strlen($this->_groupsort)).$this->_groupsort;
1030
-		$req .= pack("NNN", $this->_cutoff, $this->_retrycount, $this->_retrydelay);
1031
-		$req .= pack("N", strlen($this->_groupdistinct)).$this->_groupdistinct;
1032
-
1033
-		// anchor point
1034
-		if (empty($this->_anchor))
1035
-		{
1036
-			$req .= pack("N", 0);
1037
-		} else
1038
-		{
1039
-			$a = & $this->_anchor;
1040
-			$req .= pack("N", 1);
1041
-			$req .= pack("N", strlen($a["attrlat"])).$a["attrlat"];
1042
-			$req .= pack("N", strlen($a["attrlong"])).$a["attrlong"];
1043
-			$req .= $this->_PackFloat($a["lat"]).$this->_PackFloat($a["long"]);
1044
-		}
1045
-
1046
-		// per-index weights
1047
-		$req .= pack("N", count($this->_indexweights));
1048
-		foreach ($this->_indexweights as $idx=>$weight)
1049
-			$req .= pack("N", strlen($idx)).$idx.pack("N", $weight);
1050
-
1051
-		// max query time
1052
-		$req .= pack("N", $this->_maxquerytime);
1053
-
1054
-		// per-field weights
1055
-		$req .= pack("N", count($this->_fieldweights));
1056
-		foreach ($this->_fieldweights as $field=>$weight)
1057
-			$req .= pack("N", strlen($field)).$field.pack("N", $weight);
1058
-
1059
-		// comment
1060
-		$req .= pack("N", strlen($comment)).$comment;
1061
-
1062
-		// attribute overrides
1063
-		$req .= pack("N", count($this->_overrides));
1064
-		foreach ($this->_overrides as $key => $entry)
1065
-		{
1066
-			$req .= pack("N", strlen($entry["attr"])).$entry["attr"];
1067
-			$req .= pack("NN", $entry["type"], count($entry["values"]));
1068
-			foreach ($entry["values"] as $id=>$val)
1069
-			{
1070
-				assert(is_numeric($id));
1071
-				assert(is_numeric($val));
1072
-
1073
-				$req .= sphPackU64($id);
1074
-				switch ($entry["type"])
1075
-				{
1076
-					case SPH_ATTR_FLOAT:	$req .= $this->_PackFloat($val); break;
1077
-					case SPH_ATTR_BIGINT:	$req .= sphPackI64($val); break;
1078
-					default:				$req .= pack("N", $val); break;
1079
-				}
1080
-			}
1081
-		}
1082
-
1083
-		// select-list
1084
-		$req .= pack("N", strlen($this->_select)).$this->_select;
1085
-
1086
-		// mbstring workaround
1087
-		$this->_MBPop();
1088
-
1089
-		// store request to requests array
1090
-		$this->_reqs[] = $req;
1091
-		return count($this->_reqs) - 1;
1092
-	}
1093
-
1094
-	/// connect to searchd, run queries batch, and return an array of result sets
1095
-	public function RunQueries()
1096
-	{
1097
-		if (empty($this->_reqs))
1098
-		{
1099
-			$this->_error = "no queries defined, issue AddQuery() first";
1100
-			return false;
1101
-		}
1102
-
1103
-		// mbstring workaround
1104
-		$this->_MBPush();
1105
-
1106
-		if (!($fp = $this->_Connect()))
1107
-		{
1108
-			$this->_MBPop();
1109
-			return false;
1110
-		}
1111
-
1112
-		// send query, get response
1113
-		$nreqs = count($this->_reqs);
1114
-		$req = join("", $this->_reqs);
1115
-		$len = 8 + strlen($req);
1116
-		$req = pack("nnNNN", SEARCHD_COMMAND_SEARCH, VER_COMMAND_SEARCH, $len, 0, $nreqs).$req; // add header
1117
-
1118
-		if (!($this->_Send($fp, $req, $len + 8)) ||
1119
-			 !($response = $this->_GetResponse($fp, VER_COMMAND_SEARCH)))
1120
-		{
1121
-			$this->_MBPop();
1122
-			return false;
1123
-		}
1124
-
1125
-		// query sent ok; we can reset reqs now
1126
-		$this->_reqs = array();
1127
-
1128
-		// parse and return response
1129
-		return $this->_ParseSearchResponse($response, $nreqs);
1130
-	}
1131
-
1132
-	/// parse and return search query (or queries) response
1133
-	public function _ParseSearchResponse($response, $nreqs)
1134
-	{
1135
-		$p = 0; // current position
1136
-		$max = strlen($response); // max position for checks, to protect against broken responses
1137
-
1138
-		$results = array();
1139
-		for ($ires = 0; $ires < $nreqs && $p < $max; $ires++)
1140
-		{
1141
-			$results[] = array();
1142
-			$result = & $results[$ires];
1143
-
1144
-			$result["error"] = "";
1145
-			$result["warning"] = "";
1146
-
1147
-			// extract status
1148
-			list(,$status) = unpack("N*", substr($response, $p, 4)); $p += 4;
1149
-			$result["status"] = $status;
1150
-			if ($status != SEARCHD_OK)
1151
-			{
1152
-				list(,$len) = unpack("N*", substr($response, $p, 4)); $p += 4;
1153
-				$message = substr($response, $p, $len); $p += $len;
1154
-
1155
-				if ($status == SEARCHD_WARNING)
1156
-				{
1157
-					$result["warning"] = $message;
1158
-				} else
1159
-				{
1160
-					$result["error"] = $message;
1161
-					continue;
1162
-				}
1163
-			}
1164
-
1165
-			// read schema
1166
-			$fields = array();
1167
-			$attrs = array();
1168
-
1169
-			list(,$nfields) = unpack("N*", substr($response, $p, 4)); $p += 4;
1170
-			while ($nfields-- > 0 && $p < $max)
1171
-			{
1172
-				list(,$len) = unpack("N*", substr($response, $p, 4)); $p += 4;
1173
-				$fields[] = substr($response, $p, $len); $p += $len;
1174
-			}
1175
-			$result["fields"] = $fields;
1176
-
1177
-			list(,$nattrs) = unpack("N*", substr($response, $p, 4)); $p += 4;
1178
-			while ($nattrs-- > 0 && $p < $max)
1179
-			{
1180
-				list(,$len) = unpack("N*", substr($response, $p, 4)); $p += 4;
1181
-				$attr = substr($response, $p, $len); $p += $len;
1182
-				list(,$type) = unpack("N*", substr($response, $p, 4)); $p += 4;
1183
-				$attrs[$attr] = $type;
1184
-			}
1185
-			$result["attrs"] = $attrs;
1186
-
1187
-			// read match count
1188
-			list(,$count) = unpack("N*", substr($response, $p, 4)); $p += 4;
1189
-			list(,$id64) = unpack("N*", substr($response, $p, 4)); $p += 4;
1190
-
1191
-			// read matches
1192
-			$idx = -1;
1193
-			while ($count-- > 0 && $p < $max)
1194
-			{
1195
-				// index into result array
1196
-				$idx++;
1197
-
1198
-				// parse document id and weight
1199
-				if ($id64)
1200
-				{
1201
-					$doc = sphUnpackU64(substr($response, $p, 8)); $p += 8;
1202
-					list(,$weight) = unpack("N*", substr($response, $p, 4)); $p += 4;
1203
-				}
1204
-				else
1205
-				{
1206
-					list ($doc, $weight) = array_values(unpack("N*N*",
1207
-						substr($response, $p, 8)));
1208
-					$p += 8;
1209
-					$doc = sphFixUint($doc);
1210
-				}
1211
-				$weight = sprintf("%u", $weight);
1212
-
1213
-				// create match entry
1214
-				if ($this->_arrayresult)
1215
-					$result["matches"][$idx] = array("id"=>$doc, "weight"=>$weight);
1216
-				else
1217
-					$result["matches"][$doc]["weight"] = $weight;
1218
-
1219
-				// parse and create attributes
1220
-				$attrvals = array();
1221
-				foreach ($attrs as $attr=>$type)
1222
-				{
1223
-					// handle 64bit ints
1224
-					if ($type == SPH_ATTR_BIGINT)
1225
-					{
1226
-						$attrvals[$attr] = sphUnpackI64(substr($response, $p, 8)); $p += 8;
1227
-						continue;
1228
-					}
1229
-
1230
-					// handle floats
1231
-					if ($type == SPH_ATTR_FLOAT)
1232
-					{
1233
-						list(,$uval) = unpack("N*", substr($response, $p, 4)); $p += 4;
1234
-						list(,$fval) = unpack("f*", pack("L", $uval));
1235
-						$attrvals[$attr] = $fval;
1236
-						continue;
1237
-					}
1238
-
1239
-					// handle everything else as unsigned ints
1240
-					list(,$val) = unpack("N*", substr($response, $p, 4)); $p += 4;
1241
-					if ($type & SPH_ATTR_MULTI)
1242
-					{
1243
-						$attrvals[$attr] = array();
1244
-						$nvalues = $val;
1245
-						while ($nvalues-- > 0 && $p < $max)
1246
-						{
1247
-							list(,$val) = unpack("N*", substr($response, $p, 4)); $p += 4;
1248
-							$attrvals[$attr][] = sphFixUint($val);
1249
-						}
1250
-					} else if ($type == SPH_ATTR_STRING)
1251
-					{
1252
-						$attrvals[$attr] = substr($response, $p, $val);
1253
-						$p += $val;
1254
-					} else
1255
-					{
1256
-						$attrvals[$attr] = sphFixUint($val);
1257
-					}
1258
-				}
1259
-
1260
-				if ($this->_arrayresult)
1261
-					$result["matches"][$idx]["attrs"] = $attrvals;
1262
-				else
1263
-					$result["matches"][$doc]["attrs"] = $attrvals;
1264
-			}
1265
-
1266
-			list ($total, $total_found, $msecs, $words) =
1267
-				array_values(unpack("N*N*N*N*", substr($response, $p, 16)));
1268
-			$result["total"] = sprintf("%u", $total);
1269
-			$result["total_found"] = sprintf("%u", $total_found);
1270
-			$result["time"] = sprintf("%.3f", $msecs / 1000);
1271
-			$p += 16;
1272
-
1273
-			while ($words-- > 0 && $p < $max)
1274
-			{
1275
-				list(,$len) = unpack("N*", substr($response, $p, 4)); $p += 4;
1276
-				$word = substr($response, $p, $len); $p += $len;
1277
-				list ($docs, $hits) = array_values(unpack("N*N*", substr($response, $p, 8))); $p += 8;
1278
-				$result["words"][$word] = array(
1279
-					"docs"=>sprintf("%u", $docs),
1280
-					"hits"=>sprintf("%u", $hits) );
1281
-			}
1282
-		}
1283
-
1284
-		$this->_MBPop();
1285
-		return $results;
1286
-	}
1287
-
1288
-	/////////////////////////////////////////////////////////////////////////////
1289
-	// excerpts generation
1290
-	/////////////////////////////////////////////////////////////////////////////
1291
-
1292
-	/// connect to searchd server, and generate exceprts (snippets)
1293
-	/// of given documents for given query. returns false on failure,
1294
-	/// an array of snippets on success
1295
-	public function BuildExcerpts($docs, $index, $words, $opts = array())
1296
-	{
1297
-		assert(is_array($docs));
1298
-		assert(is_string($index));
1299
-		assert(is_string($words));
1300
-		assert(is_array($opts));
1301
-
1302
-		$this->_MBPush();
1303
-
1304
-		if (!($fp = $this->_Connect()))
1305
-		{
1306
-			$this->_MBPop();
1307
-			return false;
1308
-		}
1309
-
1310
-		/////////////////
1311
-		// fixup options
1312
-		/////////////////
1313
-
1314
-		if (!isset($opts["before_match"]))		$opts["before_match"] = "<b>";
1315
-		if (!isset($opts["after_match"]))			$opts["after_match"] = "</b>";
1316
-		if (!isset($opts["chunk_separator"]))		$opts["chunk_separator"] = " ... ";
1317
-		if (!isset($opts["limit"]))				$opts["limit"] = 256;
1318
-		if (!isset($opts["limit_passages"]))		$opts["limit_passages"] = 0;
1319
-		if (!isset($opts["limit_words"]))			$opts["limit_words"] = 0;
1320
-		if (!isset($opts["around"]))				$opts["around"] = 5;
1321
-		if (!isset($opts["exact_phrase"]))		$opts["exact_phrase"] = false;
1322
-		if (!isset($opts["single_passage"]))		$opts["single_passage"] = false;
1323
-		if (!isset($opts["use_boundaries"]))		$opts["use_boundaries"] = false;
1324
-		if (!isset($opts["weight_order"]))		$opts["weight_order"] = false;
1325
-		if (!isset($opts["query_mode"]))			$opts["query_mode"] = false;
1326
-		if (!isset($opts["force_all_words"]))		$opts["force_all_words"] = false;
1327
-		if (!isset($opts["start_passage_id"]))	$opts["start_passage_id"] = 1;
1328
-		if (!isset($opts["load_files"]))			$opts["load_files"] = false;
1329
-		if (!isset($opts["html_strip_mode"]))		$opts["html_strip_mode"] = "index";
1330
-		if (!isset($opts["allow_empty"]))			$opts["allow_empty"] = false;
1331
-		if (!isset($opts["passage_boundary"]))	$opts["passage_boundary"] = "none";
1332
-		if (!isset($opts["emit_zones"]))			$opts["emit_zones"] = false;
1333
-
1334
-		/////////////////
1335
-		// build request
1336
-		/////////////////
1337
-
1338
-		// v.1.2 req
1339
-		$flags = 1; // remove spaces
1340
-		if ($opts["exact_phrase"])	$flags |= 2;
1341
-		if ($opts["single_passage"])	$flags |= 4;
1342
-		if ($opts["use_boundaries"])	$flags |= 8;
1343
-		if ($opts["weight_order"])	$flags |= 16;
1344
-		if ($opts["query_mode"])		$flags |= 32;
1345
-		if ($opts["force_all_words"])	$flags |= 64;
1346
-		if ($opts["load_files"])		$flags |= 128;
1347
-		if ($opts["allow_empty"])		$flags |= 256;
1348
-		if ($opts["emit_zones"])		$flags |= 512;
1349
-		$req = pack("NN", 0, $flags); // mode=0, flags=$flags
1350
-		$req .= pack("N", strlen($index)).$index; // req index
1351
-		$req .= pack("N", strlen($words)).$words; // req words
1352
-
1353
-		// options
1354
-		$req .= pack("N", strlen($opts["before_match"])).$opts["before_match"];
1355
-		$req .= pack("N", strlen($opts["after_match"])).$opts["after_match"];
1356
-		$req .= pack("N", strlen($opts["chunk_separator"])).$opts["chunk_separator"];
1357
-		$req .= pack("NN", (int) $opts["limit"], (int) $opts["around"]);
1358
-		$req .= pack("NNN", (int) $opts["limit_passages"], (int) $opts["limit_words"], (int) $opts["start_passage_id"]); // v.1.2
1359
-		$req .= pack("N", strlen($opts["html_strip_mode"])).$opts["html_strip_mode"];
1360
-		$req .= pack("N", strlen($opts["passage_boundary"])).$opts["passage_boundary"];
1361
-
1362
-		// documents
1363
-		$req .= pack("N", count($docs));
1364
-		foreach ($docs as $doc)
1365
-		{
1366
-			assert(is_string($doc));
1367
-			$req .= pack("N", strlen($doc)).$doc;
1368
-		}
1369
-
1370
-		////////////////////////////
1371
-		// send query, get response
1372
-		////////////////////////////
1373
-
1374
-		$len = strlen($req);
1375
-		$req = pack("nnN", SEARCHD_COMMAND_EXCERPT, VER_COMMAND_EXCERPT, $len).$req; // add header
1376
-		if (!($this->_Send($fp, $req, $len + 8)) ||
1377
-			 !($response = $this->_GetResponse($fp, VER_COMMAND_EXCERPT)))
1378
-		{
1379
-			$this->_MBPop();
1380
-			return false;
1381
-		}
1382
-
1383
-		//////////////////
1384
-		// parse response
1385
-		//////////////////
1386
-
1387
-		$pos = 0;
1388
-		$res = array();
1389
-		$rlen = strlen($response);
1390
-		for ($i = 0; $i < count($docs); $i++)
1391
-		{
1392
-			list(,$len) = unpack("N*", substr($response, $pos, 4));
1393
-			$pos += 4;
1394
-
1395
-			if ($pos + $len > $rlen)
1396
-			{
1397
-				$this->_error = "incomplete reply";
1398
-				$this->_MBPop();
1399
-				return false;
1400
-			}
1401
-			$res[] = $len ? substr ($response, $pos, $len) : "";
1402
-			$pos += $len;
1403
-		}
1404
-
1405
-		$this->_MBPop();
1406
-		return $res;
1407
-	}
1408
-
1409
-
1410
-	/////////////////////////////////////////////////////////////////////////////
1411
-	// keyword generation
1412
-	/////////////////////////////////////////////////////////////////////////////
1413
-
1414
-	/// connect to searchd server, and generate keyword list for a given query
1415
-	/// returns false on failure,
1416
-	/// an array of words on success
1417
-	public function BuildKeywords($query, $index, $hits)
1418
-	{
1419
-		assert(is_string($query));
1420
-		assert(is_string($index));
1421
-		assert(is_bool($hits));
1422
-
1423
-		$this->_MBPush();
1424
-
1425
-		if (!($fp = $this->_Connect()))
1426
-		{
1427
-			$this->_MBPop();
1428
-			return false;
1429
-		}
1430
-
1431
-		/////////////////
1432
-		// build request
1433
-		/////////////////
1434
-
1435
-		// v.1.0 req
1436
-		$req  = pack("N", strlen($query)).$query; // req query
1437
-		$req .= pack("N", strlen($index)).$index; // req index
1438
-		$req .= pack("N", (int) $hits);
1439
-
1440
-		////////////////////////////
1441
-		// send query, get response
1442
-		////////////////////////////
1443
-
1444
-		$len = strlen($req);
1445
-		$req = pack("nnN", SEARCHD_COMMAND_KEYWORDS, VER_COMMAND_KEYWORDS, $len).$req; // add header
1446
-		if (!($this->_Send($fp, $req, $len + 8)) ||
1447
-			 !($response = $this->_GetResponse($fp, VER_COMMAND_KEYWORDS)))
1448
-		{
1449
-			$this->_MBPop();
1450
-			return false;
1451
-		}
1452
-
1453
-		//////////////////
1454
-		// parse response
1455
-		//////////////////
1456
-
1457
-		$pos = 0;
1458
-		$res = array();
1459
-		$rlen = strlen($response);
1460
-		list(,$nwords) = unpack("N*", substr($response, $pos, 4));
1461
-		$pos += 4;
1462
-		for ($i = 0; $i < $nwords; $i++)
1463
-		{
1464
-			list(,$len) = unpack("N*", substr($response, $pos, 4)); $pos += 4;
1465
-			$tokenized = $len ? substr ($response, $pos, $len) : "";
1466
-			$pos += $len;
1467
-
1468
-			list(,$len) = unpack("N*", substr($response, $pos, 4)); $pos += 4;
1469
-			$normalized = $len ? substr ($response, $pos, $len) : "";
1470
-			$pos += $len;
1471
-
1472
-			$res[] = array("tokenized"=>$tokenized, "normalized"=>$normalized);
1473
-
1474
-			if ($hits)
1475
-			{
1476
-				list($ndocs, $nhits) = array_values(unpack("N*N*", substr($response, $pos, 8)));
1477
-				$pos += 8;
1478
-				$res [$i]["docs"] = $ndocs;
1479
-				$res [$i]["hits"] = $nhits;
1480
-			}
1481
-
1482
-			if ($pos > $rlen)
1483
-			{
1484
-				$this->_error = "incomplete reply";
1485
-				$this->_MBPop();
1486
-				return false;
1487
-			}
1488
-		}
1489
-
1490
-		$this->_MBPop();
1491
-		return $res;
1492
-	}
1493
-
1494
-	public function EscapeString($string)
1495
-	{
1496
-		$from = array('\\', '(', ')', '|', '-', '!', '@', '~', '"', '&', '/', '^', '$', '=');
1497
-		$to   = array('\\\\', '\(', '\)', '\|', '\-', '\!', '\@', '\~', '\"', '\&', '\/', '\^', '\$', '\=');
1498
-
1499
-		return str_replace($from, $to, $string);
1500
-	}
1501
-
1502
-	/////////////////////////////////////////////////////////////////////////////
1503
-	// attribute updates
1504
-	/////////////////////////////////////////////////////////////////////////////
1505
-
1506
-	/// batch update given attributes in given rows in given indexes
1507
-	/// returns amount of updated documents (0 or more) on success, or -1 on failure
1508
-	public function UpdateAttributes($index, $attrs, $values, $mva = false)
1509
-	{
1510
-		// verify everything
1511
-		assert(is_string($index));
1512
-		assert(is_bool($mva));
1513
-
1514
-		assert(is_array($attrs));
1515
-		foreach ($attrs as $attr)
1516
-			assert(is_string($attr));
1517
-
1518
-		assert(is_array($values));
1519
-		foreach ($values as $id=>$entry)
1520
-		{
1521
-			assert(is_numeric($id));
1522
-			assert(is_array($entry));
1523
-			assert(count($entry) == count($attrs));
1524
-			foreach ($entry as $v)
1525
-			{
1526
-				if ($mva)
1527
-				{
1528
-					assert(is_array($v));
1529
-					foreach ($v as $vv)
1530
-						assert(is_int($vv));
1531
-				} else
1532
-					assert(is_int($v));
1533
-			}
1534
-		}
1535
-
1536
-		// build request
1537
-		$this->_MBPush();
1538
-		$req = pack("N", strlen($index)).$index;
1539
-
1540
-		$req .= pack("N", count($attrs));
1541
-		foreach ($attrs as $attr)
1542
-		{
1543
-			$req .= pack("N", strlen($attr)).$attr;
1544
-			$req .= pack("N", $mva ? 1 : 0);
1545
-		}
1546
-
1547
-		$req .= pack("N", count($values));
1548
-		foreach ($values as $id=>$entry)
1549
-		{
1550
-			$req .= sphPackU64($id);
1551
-			foreach ($entry as $v)
1552
-			{
1553
-				$req .= pack("N", $mva ? count($v) : $v);
1554
-				if ($mva)
1555
-					foreach ($v as $vv)
1556
-						$req .= pack("N", $vv);
1557
-			}
1558
-		}
1559
-
1560
-		// connect, send query, get response
1561
-		if (!($fp = $this->_Connect()))
1562
-		{
1563
-			$this->_MBPop();
1564
-			return -1;
1565
-		}
1566
-
1567
-		$len = strlen($req);
1568
-		$req = pack("nnN", SEARCHD_COMMAND_UPDATE, VER_COMMAND_UPDATE, $len).$req; // add header
1569
-		if (!$this->_Send($fp, $req, $len + 8))
1570
-		{
1571
-			$this->_MBPop();
1572
-			return -1;
1573
-		}
1574
-
1575
-		if (!($response = $this->_GetResponse($fp, VER_COMMAND_UPDATE)))
1576
-		{
1577
-			$this->_MBPop();
1578
-			return -1;
1579
-		}
1580
-
1581
-		// parse response
1582
-		list(,$updated) = unpack("N*", substr($response, 0, 4));
1583
-		$this->_MBPop();
1584
-		return $updated;
1585
-	}
1586
-
1587
-	/////////////////////////////////////////////////////////////////////////////
1588
-	// persistent connections
1589
-	/////////////////////////////////////////////////////////////////////////////
1590
-
1591
-	public function Open()
1592
-	{
1593
-		if ($this->_socket !== false)
1594
-		{
1595
-			$this->_error = 'already connected';
1596
-			return false;
1597
-		}
1598
-		if (!$fp = $this->_Connect())
1599
-			return false;
1600
-
1601
-		// command, command version = 0, body length = 4, body = 1
1602
-		$req = pack("nnNN", SEARCHD_COMMAND_PERSIST, 0, 4, 1);
1603
-		if (!$this->_Send($fp, $req, 12))
1604
-			return false;
1605
-
1606
-		$this->_socket = $fp;
1607
-		return true;
1608
-	}
1609
-
1610
-	public function Close()
1611
-	{
1612
-		if ($this->_socket === false)
1613
-		{
1614
-			$this->_error = 'not connected';
1615
-			return false;
1616
-		}
1617
-
1618
-		fclose($this->_socket);
1619
-		$this->_socket = false;
1620
-
1621
-		return true;
1622
-	}
1623
-
1624
-	//////////////////////////////////////////////////////////////////////////
1625
-	// status
1626
-	//////////////////////////////////////////////////////////////////////////
1627
-
1628
-	public function Status()
1629
-	{
1630
-		$this->_MBPush();
1631
-		if (!($fp = $this->_Connect()))
1632
-		{
1633
-			$this->_MBPop();
1634
-			return false;
1635
-		}
1636
-
1637
-		$req = pack("nnNN", SEARCHD_COMMAND_STATUS, VER_COMMAND_STATUS, 4, 1); // len=4, body=1
1638
-		if (!($this->_Send($fp, $req, 12)) ||
1639
-			 !($response = $this->_GetResponse($fp, VER_COMMAND_STATUS)))
1640
-		{
1641
-			$this->_MBPop();
1642
-			return false;
1643
-		}
1644
-
1645
-		$res = substr($response, 4); // just ignore length, error handling, etc
1646
-		$p = 0;
1647
-		list ($rows, $cols) = array_values(unpack("N*N*", substr($response, $p, 8))); $p += 8;
1648
-
1649
-		$res = array();
1650
-		for ($i = 0; $i < $rows; $i++)
1651
-			for ($j = 0; $j < $cols; $j++)
1652
-		{
1653
-			list(,$len) = unpack("N*", substr($response, $p, 4)); $p += 4;
1654
-			$res[$i][] = substr($response, $p, $len); $p += $len;
1655
-		}
1656
-
1657
-		$this->_MBPop();
1658
-		return $res;
1659
-	}
1660
-
1661
-	//////////////////////////////////////////////////////////////////////////
1662
-	// flush
1663
-	//////////////////////////////////////////////////////////////////////////
1664
-
1665
-	public function FlushAttributes()
1666
-	{
1667
-		$this->_MBPush();
1668
-		if (!($fp = $this->_Connect()))
1669
-		{
1670
-			$this->_MBPop();
1671
-			return -1;
1672
-		}
1673
-
1674
-		$req = pack("nnN", SEARCHD_COMMAND_FLUSHATTRS, VER_COMMAND_FLUSHATTRS, 0); // len=0
1675
-		if (!($this->_Send($fp, $req, 8)) ||
1676
-			 !($response = $this->_GetResponse($fp, VER_COMMAND_FLUSHATTRS)))
1677
-		{
1678
-			$this->_MBPop();
1679
-			return -1;
1680
-		}
1681
-
1682
-		$tag = -1;
1683
-		if (strlen($response) == 4)
1684
-			list(,$tag) = unpack("N*", $response);
1685
-		else
1686
-			$this->_error = "unexpected response length";
1687
-
1688
-		$this->_MBPop();
1689
-		return $tag;
1690
-	}
945
+    //////////////////////////////////////////////////////////////////////////////
946
+
947
+    /// connect to searchd server, run given search query through given indexes,
948
+    /// and return the search results
949
+    public function Query($query, $index = "*", $comment = "")
950
+    {
951
+        assert(empty($this->_reqs));
952
+
953
+        $this->AddQuery($query, $index, $comment);
954
+        $results = $this->RunQueries();
955
+        $this->_reqs = array(); // just in case it failed too early
956
+
957
+        if (!is_array($results))
958
+            return false; // probably network error; error message should be already filled
959
+
960
+        $this->_error = $results[0]["error"];
961
+        $this->_warning = $results[0]["warning"];
962
+        if ($results[0]["status"] == SEARCHD_ERROR)
963
+            return false;
964
+        else
965
+            return $results[0];
966
+    }
967
+
968
+    /// helper to pack floats in network byte order
969
+    public function _PackFloat($f)
970
+    {
971
+        $t1 = pack("f", $f); // machine order
972
+        list(,$t2) = unpack("L*", $t1); // int in machine order
973
+        return pack("N", $t2);
974
+    }
975
+
976
+    /**
977
+     * @SuppressWarnings(unused)
978
+     */
979
+
980
+    /// add query to multi-query batch
981
+    /// returns index into results array from RunQueries() call
982
+    public function AddQuery($query, $index = "*", $comment = "")
983
+    {
984
+        // mbstring workaround
985
+        $this->_MBPush();
986
+
987
+        // build request
988
+        $req = pack("NNNNN", $this->_offset, $this->_limit, $this->_mode, $this->_ranker, $this->_sort); // mode and limits
989
+        $req .= pack("N", strlen($this->_sortby)).$this->_sortby;
990
+        $req .= pack("N", strlen($query)).$query; // query itself
991
+        $req .= pack("N", count($this->_weights)); // weights
992
+        foreach ($this->_weights as $weight)
993
+            $req .= pack("N", (int) $weight);
994
+        $req .= pack("N", strlen($index)).$index; // indexes
995
+        $req .= pack("N", 1); // id64 range marker
996
+        $req .= sphPackU64($this->_min_id).sphPackU64($this->_max_id); // id64 range
997
+
998
+        // filters
999
+        $req .= pack("N", count($this->_filters));
1000
+        foreach ($this->_filters as $filter)
1001
+        {
1002
+            $req .= pack("N", strlen($filter["attr"])).$filter["attr"];
1003
+            $req .= pack("N", $filter["type"]);
1004
+            switch ($filter["type"])
1005
+            {
1006
+                case SPH_FILTER_VALUES:
1007
+                    $req .= pack("N", count($filter["values"]));
1008
+                    foreach ($filter["values"] as $value)
1009
+                        $req .= sphPackI64($value);
1010
+                    break;
1011
+
1012
+                case SPH_FILTER_RANGE:
1013
+                    $req .= sphPackI64($filter["min"]).sphPackI64($filter["max"]);
1014
+                    break;
1015
+
1016
+                case SPH_FILTER_FLOATRANGE:
1017
+                    $req .= $this->_PackFloat($filter["min"]).$this->_PackFloat($filter["max"]);
1018
+                    break;
1019
+
1020
+                default:
1021
+                    assert(0 && "internal error: unhandled filter type");
1022
+            }
1023
+            $req .= pack("N", $filter["exclude"]);
1024
+        }
1025
+
1026
+        // group-by clause, max-matches count, group-sort clause, cutoff count
1027
+        $req .= pack("NN", $this->_groupfunc, strlen($this->_groupby)).$this->_groupby;
1028
+        $req .= pack("N", $this->_maxmatches);
1029
+        $req .= pack("N", strlen($this->_groupsort)).$this->_groupsort;
1030
+        $req .= pack("NNN", $this->_cutoff, $this->_retrycount, $this->_retrydelay);
1031
+        $req .= pack("N", strlen($this->_groupdistinct)).$this->_groupdistinct;
1032
+
1033
+        // anchor point
1034
+        if (empty($this->_anchor))
1035
+        {
1036
+            $req .= pack("N", 0);
1037
+        } else
1038
+        {
1039
+            $a = & $this->_anchor;
1040
+            $req .= pack("N", 1);
1041
+            $req .= pack("N", strlen($a["attrlat"])).$a["attrlat"];
1042
+            $req .= pack("N", strlen($a["attrlong"])).$a["attrlong"];
1043
+            $req .= $this->_PackFloat($a["lat"]).$this->_PackFloat($a["long"]);
1044
+        }
1045
+
1046
+        // per-index weights
1047
+        $req .= pack("N", count($this->_indexweights));
1048
+        foreach ($this->_indexweights as $idx=>$weight)
1049
+            $req .= pack("N", strlen($idx)).$idx.pack("N", $weight);
1050
+
1051
+        // max query time
1052
+        $req .= pack("N", $this->_maxquerytime);
1053
+
1054
+        // per-field weights
1055
+        $req .= pack("N", count($this->_fieldweights));
1056
+        foreach ($this->_fieldweights as $field=>$weight)
1057
+            $req .= pack("N", strlen($field)).$field.pack("N", $weight);
1058
+
1059
+        // comment
1060
+        $req .= pack("N", strlen($comment)).$comment;
1061
+
1062
+        // attribute overrides
1063
+        $req .= pack("N", count($this->_overrides));
1064
+        foreach ($this->_overrides as $key => $entry)
1065
+        {
1066
+            $req .= pack("N", strlen($entry["attr"])).$entry["attr"];
1067
+            $req .= pack("NN", $entry["type"], count($entry["values"]));
1068
+            foreach ($entry["values"] as $id=>$val)
1069
+            {
1070
+                assert(is_numeric($id));
1071
+                assert(is_numeric($val));
1072
+
1073
+                $req .= sphPackU64($id);
1074
+                switch ($entry["type"])
1075
+                {
1076
+                    case SPH_ATTR_FLOAT:	$req .= $this->_PackFloat($val); break;
1077
+                    case SPH_ATTR_BIGINT:	$req .= sphPackI64($val); break;
1078
+                    default:				$req .= pack("N", $val); break;
1079
+                }
1080
+            }
1081
+        }
1082
+
1083
+        // select-list
1084
+        $req .= pack("N", strlen($this->_select)).$this->_select;
1085
+
1086
+        // mbstring workaround
1087
+        $this->_MBPop();
1088
+
1089
+        // store request to requests array
1090
+        $this->_reqs[] = $req;
1091
+        return count($this->_reqs) - 1;
1092
+    }
1093
+
1094
+    /// connect to searchd, run queries batch, and return an array of result sets
1095
+    public function RunQueries()
1096
+    {
1097
+        if (empty($this->_reqs))
1098
+        {
1099
+            $this->_error = "no queries defined, issue AddQuery() first";
1100
+            return false;
1101
+        }
1102
+
1103
+        // mbstring workaround
1104
+        $this->_MBPush();
1105
+
1106
+        if (!($fp = $this->_Connect()))
1107
+        {
1108
+            $this->_MBPop();
1109
+            return false;
1110
+        }
1111
+
1112
+        // send query, get response
1113
+        $nreqs = count($this->_reqs);
1114
+        $req = join("", $this->_reqs);
1115
+        $len = 8 + strlen($req);
1116
+        $req = pack("nnNNN", SEARCHD_COMMAND_SEARCH, VER_COMMAND_SEARCH, $len, 0, $nreqs).$req; // add header
1117
+
1118
+        if (!($this->_Send($fp, $req, $len + 8)) ||
1119
+             !($response = $this->_GetResponse($fp, VER_COMMAND_SEARCH)))
1120
+        {
1121
+            $this->_MBPop();
1122
+            return false;
1123
+        }
1124
+
1125
+        // query sent ok; we can reset reqs now
1126
+        $this->_reqs = array();
1127
+
1128
+        // parse and return response
1129
+        return $this->_ParseSearchResponse($response, $nreqs);
1130
+    }
1131
+
1132
+    /// parse and return search query (or queries) response
1133
+    public function _ParseSearchResponse($response, $nreqs)
1134
+    {
1135
+        $p = 0; // current position
1136
+        $max = strlen($response); // max position for checks, to protect against broken responses
1137
+
1138
+        $results = array();
1139
+        for ($ires = 0; $ires < $nreqs && $p < $max; $ires++)
1140
+        {
1141
+            $results[] = array();
1142
+            $result = & $results[$ires];
1143
+
1144
+            $result["error"] = "";
1145
+            $result["warning"] = "";
1146
+
1147
+            // extract status
1148
+            list(,$status) = unpack("N*", substr($response, $p, 4)); $p += 4;
1149
+            $result["status"] = $status;
1150
+            if ($status != SEARCHD_OK)
1151
+            {
1152
+                list(,$len) = unpack("N*", substr($response, $p, 4)); $p += 4;
1153
+                $message = substr($response, $p, $len); $p += $len;
1154
+
1155
+                if ($status == SEARCHD_WARNING)
1156
+                {
1157
+                    $result["warning"] = $message;
1158
+                } else
1159
+                {
1160
+                    $result["error"] = $message;
1161
+                    continue;
1162
+                }
1163
+            }
1164
+
1165
+            // read schema
1166
+            $fields = array();
1167
+            $attrs = array();
1168
+
1169
+            list(,$nfields) = unpack("N*", substr($response, $p, 4)); $p += 4;
1170
+            while ($nfields-- > 0 && $p < $max)
1171
+            {
1172
+                list(,$len) = unpack("N*", substr($response, $p, 4)); $p += 4;
1173
+                $fields[] = substr($response, $p, $len); $p += $len;
1174
+            }
1175
+            $result["fields"] = $fields;
1176
+
1177
+            list(,$nattrs) = unpack("N*", substr($response, $p, 4)); $p += 4;
1178
+            while ($nattrs-- > 0 && $p < $max)
1179
+            {
1180
+                list(,$len) = unpack("N*", substr($response, $p, 4)); $p += 4;
1181
+                $attr = substr($response, $p, $len); $p += $len;
1182
+                list(,$type) = unpack("N*", substr($response, $p, 4)); $p += 4;
1183
+                $attrs[$attr] = $type;
1184
+            }
1185
+            $result["attrs"] = $attrs;
1186
+
1187
+            // read match count
1188
+            list(,$count) = unpack("N*", substr($response, $p, 4)); $p += 4;
1189
+            list(,$id64) = unpack("N*", substr($response, $p, 4)); $p += 4;
1190
+
1191
+            // read matches
1192
+            $idx = -1;
1193
+            while ($count-- > 0 && $p < $max)
1194
+            {
1195
+                // index into result array
1196
+                $idx++;
1197
+
1198
+                // parse document id and weight
1199
+                if ($id64)
1200
+                {
1201
+                    $doc = sphUnpackU64(substr($response, $p, 8)); $p += 8;
1202
+                    list(,$weight) = unpack("N*", substr($response, $p, 4)); $p += 4;
1203
+                }
1204
+                else
1205
+                {
1206
+                    list ($doc, $weight) = array_values(unpack("N*N*",
1207
+                        substr($response, $p, 8)));
1208
+                    $p += 8;
1209
+                    $doc = sphFixUint($doc);
1210
+                }
1211
+                $weight = sprintf("%u", $weight);
1212
+
1213
+                // create match entry
1214
+                if ($this->_arrayresult)
1215
+                    $result["matches"][$idx] = array("id"=>$doc, "weight"=>$weight);
1216
+                else
1217
+                    $result["matches"][$doc]["weight"] = $weight;
1218
+
1219
+                // parse and create attributes
1220
+                $attrvals = array();
1221
+                foreach ($attrs as $attr=>$type)
1222
+                {
1223
+                    // handle 64bit ints
1224
+                    if ($type == SPH_ATTR_BIGINT)
1225
+                    {
1226
+                        $attrvals[$attr] = sphUnpackI64(substr($response, $p, 8)); $p += 8;
1227
+                        continue;
1228
+                    }
1229
+
1230
+                    // handle floats
1231
+                    if ($type == SPH_ATTR_FLOAT)
1232
+                    {
1233
+                        list(,$uval) = unpack("N*", substr($response, $p, 4)); $p += 4;
1234
+                        list(,$fval) = unpack("f*", pack("L", $uval));
1235
+                        $attrvals[$attr] = $fval;
1236
+                        continue;
1237
+                    }
1238
+
1239
+                    // handle everything else as unsigned ints
1240
+                    list(,$val) = unpack("N*", substr($response, $p, 4)); $p += 4;
1241
+                    if ($type & SPH_ATTR_MULTI)
1242
+                    {
1243
+                        $attrvals[$attr] = array();
1244
+                        $nvalues = $val;
1245
+                        while ($nvalues-- > 0 && $p < $max)
1246
+                        {
1247
+                            list(,$val) = unpack("N*", substr($response, $p, 4)); $p += 4;
1248
+                            $attrvals[$attr][] = sphFixUint($val);
1249
+                        }
1250
+                    } else if ($type == SPH_ATTR_STRING)
1251
+                    {
1252
+                        $attrvals[$attr] = substr($response, $p, $val);
1253
+                        $p += $val;
1254
+                    } else
1255
+                    {
1256
+                        $attrvals[$attr] = sphFixUint($val);
1257
+                    }
1258
+                }
1259
+
1260
+                if ($this->_arrayresult)
1261
+                    $result["matches"][$idx]["attrs"] = $attrvals;
1262
+                else
1263
+                    $result["matches"][$doc]["attrs"] = $attrvals;
1264
+            }
1265
+
1266
+            list ($total, $total_found, $msecs, $words) =
1267
+                array_values(unpack("N*N*N*N*", substr($response, $p, 16)));
1268
+            $result["total"] = sprintf("%u", $total);
1269
+            $result["total_found"] = sprintf("%u", $total_found);
1270
+            $result["time"] = sprintf("%.3f", $msecs / 1000);
1271
+            $p += 16;
1272
+
1273
+            while ($words-- > 0 && $p < $max)
1274
+            {
1275
+                list(,$len) = unpack("N*", substr($response, $p, 4)); $p += 4;
1276
+                $word = substr($response, $p, $len); $p += $len;
1277
+                list ($docs, $hits) = array_values(unpack("N*N*", substr($response, $p, 8))); $p += 8;
1278
+                $result["words"][$word] = array(
1279
+                    "docs"=>sprintf("%u", $docs),
1280
+                    "hits"=>sprintf("%u", $hits) );
1281
+            }
1282
+        }
1283
+
1284
+        $this->_MBPop();
1285
+        return $results;
1286
+    }
1287
+
1288
+    /////////////////////////////////////////////////////////////////////////////
1289
+    // excerpts generation
1290
+    /////////////////////////////////////////////////////////////////////////////
1291
+
1292
+    /// connect to searchd server, and generate exceprts (snippets)
1293
+    /// of given documents for given query. returns false on failure,
1294
+    /// an array of snippets on success
1295
+    public function BuildExcerpts($docs, $index, $words, $opts = array())
1296
+    {
1297
+        assert(is_array($docs));
1298
+        assert(is_string($index));
1299
+        assert(is_string($words));
1300
+        assert(is_array($opts));
1301
+
1302
+        $this->_MBPush();
1303
+
1304
+        if (!($fp = $this->_Connect()))
1305
+        {
1306
+            $this->_MBPop();
1307
+            return false;
1308
+        }
1309
+
1310
+        /////////////////
1311
+        // fixup options
1312
+        /////////////////
1313
+
1314
+        if (!isset($opts["before_match"]))		$opts["before_match"] = "<b>";
1315
+        if (!isset($opts["after_match"]))			$opts["after_match"] = "</b>";
1316
+        if (!isset($opts["chunk_separator"]))		$opts["chunk_separator"] = " ... ";
1317
+        if (!isset($opts["limit"]))				$opts["limit"] = 256;
1318
+        if (!isset($opts["limit_passages"]))		$opts["limit_passages"] = 0;
1319
+        if (!isset($opts["limit_words"]))			$opts["limit_words"] = 0;
1320
+        if (!isset($opts["around"]))				$opts["around"] = 5;
1321
+        if (!isset($opts["exact_phrase"]))		$opts["exact_phrase"] = false;
1322
+        if (!isset($opts["single_passage"]))		$opts["single_passage"] = false;
1323
+        if (!isset($opts["use_boundaries"]))		$opts["use_boundaries"] = false;
1324
+        if (!isset($opts["weight_order"]))		$opts["weight_order"] = false;
1325
+        if (!isset($opts["query_mode"]))			$opts["query_mode"] = false;
1326
+        if (!isset($opts["force_all_words"]))		$opts["force_all_words"] = false;
1327
+        if (!isset($opts["start_passage_id"]))	$opts["start_passage_id"] = 1;
1328
+        if (!isset($opts["load_files"]))			$opts["load_files"] = false;
1329
+        if (!isset($opts["html_strip_mode"]))		$opts["html_strip_mode"] = "index";
1330
+        if (!isset($opts["allow_empty"]))			$opts["allow_empty"] = false;
1331
+        if (!isset($opts["passage_boundary"]))	$opts["passage_boundary"] = "none";
1332
+        if (!isset($opts["emit_zones"]))			$opts["emit_zones"] = false;
1333
+
1334
+        /////////////////
1335
+        // build request
1336
+        /////////////////
1337
+
1338
+        // v.1.2 req
1339
+        $flags = 1; // remove spaces
1340
+        if ($opts["exact_phrase"])	$flags |= 2;
1341
+        if ($opts["single_passage"])	$flags |= 4;
1342
+        if ($opts["use_boundaries"])	$flags |= 8;
1343
+        if ($opts["weight_order"])	$flags |= 16;
1344
+        if ($opts["query_mode"])		$flags |= 32;
1345
+        if ($opts["force_all_words"])	$flags |= 64;
1346
+        if ($opts["load_files"])		$flags |= 128;
1347
+        if ($opts["allow_empty"])		$flags |= 256;
1348
+        if ($opts["emit_zones"])		$flags |= 512;
1349
+        $req = pack("NN", 0, $flags); // mode=0, flags=$flags
1350
+        $req .= pack("N", strlen($index)).$index; // req index
1351
+        $req .= pack("N", strlen($words)).$words; // req words
1352
+
1353
+        // options
1354
+        $req .= pack("N", strlen($opts["before_match"])).$opts["before_match"];
1355
+        $req .= pack("N", strlen($opts["after_match"])).$opts["after_match"];
1356
+        $req .= pack("N", strlen($opts["chunk_separator"])).$opts["chunk_separator"];
1357
+        $req .= pack("NN", (int) $opts["limit"], (int) $opts["around"]);
1358
+        $req .= pack("NNN", (int) $opts["limit_passages"], (int) $opts["limit_words"], (int) $opts["start_passage_id"]); // v.1.2
1359
+        $req .= pack("N", strlen($opts["html_strip_mode"])).$opts["html_strip_mode"];
1360
+        $req .= pack("N", strlen($opts["passage_boundary"])).$opts["passage_boundary"];
1361
+
1362
+        // documents
1363
+        $req .= pack("N", count($docs));
1364
+        foreach ($docs as $doc)
1365
+        {
1366
+            assert(is_string($doc));
1367
+            $req .= pack("N", strlen($doc)).$doc;
1368
+        }
1369
+
1370
+        ////////////////////////////
1371
+        // send query, get response
1372
+        ////////////////////////////
1373
+
1374
+        $len = strlen($req);
1375
+        $req = pack("nnN", SEARCHD_COMMAND_EXCERPT, VER_COMMAND_EXCERPT, $len).$req; // add header
1376
+        if (!($this->_Send($fp, $req, $len + 8)) ||
1377
+             !($response = $this->_GetResponse($fp, VER_COMMAND_EXCERPT)))
1378
+        {
1379
+            $this->_MBPop();
1380
+            return false;
1381
+        }
1382
+
1383
+        //////////////////
1384
+        // parse response
1385
+        //////////////////
1386
+
1387
+        $pos = 0;
1388
+        $res = array();
1389
+        $rlen = strlen($response);
1390
+        for ($i = 0; $i < count($docs); $i++)
1391
+        {
1392
+            list(,$len) = unpack("N*", substr($response, $pos, 4));
1393
+            $pos += 4;
1394
+
1395
+            if ($pos + $len > $rlen)
1396
+            {
1397
+                $this->_error = "incomplete reply";
1398
+                $this->_MBPop();
1399
+                return false;
1400
+            }
1401
+            $res[] = $len ? substr ($response, $pos, $len) : "";
1402
+            $pos += $len;
1403
+        }
1404
+
1405
+        $this->_MBPop();
1406
+        return $res;
1407
+    }
1408
+
1409
+
1410
+    /////////////////////////////////////////////////////////////////////////////
1411
+    // keyword generation
1412
+    /////////////////////////////////////////////////////////////////////////////
1413
+
1414
+    /// connect to searchd server, and generate keyword list for a given query
1415
+    /// returns false on failure,
1416
+    /// an array of words on success
1417
+    public function BuildKeywords($query, $index, $hits)
1418
+    {
1419
+        assert(is_string($query));
1420
+        assert(is_string($index));
1421
+        assert(is_bool($hits));
1422
+
1423
+        $this->_MBPush();
1424
+
1425
+        if (!($fp = $this->_Connect()))
1426
+        {
1427
+            $this->_MBPop();
1428
+            return false;
1429
+        }
1430
+
1431
+        /////////////////
1432
+        // build request
1433
+        /////////////////
1434
+
1435
+        // v.1.0 req
1436
+        $req  = pack("N", strlen($query)).$query; // req query
1437
+        $req .= pack("N", strlen($index)).$index; // req index
1438
+        $req .= pack("N", (int) $hits);
1439
+
1440
+        ////////////////////////////
1441
+        // send query, get response
1442
+        ////////////////////////////
1443
+
1444
+        $len = strlen($req);
1445
+        $req = pack("nnN", SEARCHD_COMMAND_KEYWORDS, VER_COMMAND_KEYWORDS, $len).$req; // add header
1446
+        if (!($this->_Send($fp, $req, $len + 8)) ||
1447
+             !($response = $this->_GetResponse($fp, VER_COMMAND_KEYWORDS)))
1448
+        {
1449
+            $this->_MBPop();
1450
+            return false;
1451
+        }
1452
+
1453
+        //////////////////
1454
+        // parse response
1455
+        //////////////////
1456
+
1457
+        $pos = 0;
1458
+        $res = array();
1459
+        $rlen = strlen($response);
1460
+        list(,$nwords) = unpack("N*", substr($response, $pos, 4));
1461
+        $pos += 4;
1462
+        for ($i = 0; $i < $nwords; $i++)
1463
+        {
1464
+            list(,$len) = unpack("N*", substr($response, $pos, 4)); $pos += 4;
1465
+            $tokenized = $len ? substr ($response, $pos, $len) : "";
1466
+            $pos += $len;
1467
+
1468
+            list(,$len) = unpack("N*", substr($response, $pos, 4)); $pos += 4;
1469
+            $normalized = $len ? substr ($response, $pos, $len) : "";
1470
+            $pos += $len;
1471
+
1472
+            $res[] = array("tokenized"=>$tokenized, "normalized"=>$normalized);
1473
+
1474
+            if ($hits)
1475
+            {
1476
+                list($ndocs, $nhits) = array_values(unpack("N*N*", substr($response, $pos, 8)));
1477
+                $pos += 8;
1478
+                $res [$i]["docs"] = $ndocs;
1479
+                $res [$i]["hits"] = $nhits;
1480
+            }
1481
+
1482
+            if ($pos > $rlen)
1483
+            {
1484
+                $this->_error = "incomplete reply";
1485
+                $this->_MBPop();
1486
+                return false;
1487
+            }
1488
+        }
1489
+
1490
+        $this->_MBPop();
1491
+        return $res;
1492
+    }
1493
+
1494
+    public function EscapeString($string)
1495
+    {
1496
+        $from = array('\\', '(', ')', '|', '-', '!', '@', '~', '"', '&', '/', '^', '$', '=');
1497
+        $to   = array('\\\\', '\(', '\)', '\|', '\-', '\!', '\@', '\~', '\"', '\&', '\/', '\^', '\$', '\=');
1498
+
1499
+        return str_replace($from, $to, $string);
1500
+    }
1501
+
1502
+    /////////////////////////////////////////////////////////////////////////////
1503
+    // attribute updates
1504
+    /////////////////////////////////////////////////////////////////////////////
1505
+
1506
+    /// batch update given attributes in given rows in given indexes
1507
+    /// returns amount of updated documents (0 or more) on success, or -1 on failure
1508
+    public function UpdateAttributes($index, $attrs, $values, $mva = false)
1509
+    {
1510
+        // verify everything
1511
+        assert(is_string($index));
1512
+        assert(is_bool($mva));
1513
+
1514
+        assert(is_array($attrs));
1515
+        foreach ($attrs as $attr)
1516
+            assert(is_string($attr));
1517
+
1518
+        assert(is_array($values));
1519
+        foreach ($values as $id=>$entry)
1520
+        {
1521
+            assert(is_numeric($id));
1522
+            assert(is_array($entry));
1523
+            assert(count($entry) == count($attrs));
1524
+            foreach ($entry as $v)
1525
+            {
1526
+                if ($mva)
1527
+                {
1528
+                    assert(is_array($v));
1529
+                    foreach ($v as $vv)
1530
+                        assert(is_int($vv));
1531
+                } else
1532
+                    assert(is_int($v));
1533
+            }
1534
+        }
1535
+
1536
+        // build request
1537
+        $this->_MBPush();
1538
+        $req = pack("N", strlen($index)).$index;
1539
+
1540
+        $req .= pack("N", count($attrs));
1541
+        foreach ($attrs as $attr)
1542
+        {
1543
+            $req .= pack("N", strlen($attr)).$attr;
1544
+            $req .= pack("N", $mva ? 1 : 0);
1545
+        }
1546
+
1547
+        $req .= pack("N", count($values));
1548
+        foreach ($values as $id=>$entry)
1549
+        {
1550
+            $req .= sphPackU64($id);
1551
+            foreach ($entry as $v)
1552
+            {
1553
+                $req .= pack("N", $mva ? count($v) : $v);
1554
+                if ($mva)
1555
+                    foreach ($v as $vv)
1556
+                        $req .= pack("N", $vv);
1557
+            }
1558
+        }
1559
+
1560
+        // connect, send query, get response
1561
+        if (!($fp = $this->_Connect()))
1562
+        {
1563
+            $this->_MBPop();
1564
+            return -1;
1565
+        }
1566
+
1567
+        $len = strlen($req);
1568
+        $req = pack("nnN", SEARCHD_COMMAND_UPDATE, VER_COMMAND_UPDATE, $len).$req; // add header
1569
+        if (!$this->_Send($fp, $req, $len + 8))
1570
+        {
1571
+            $this->_MBPop();
1572
+            return -1;
1573
+        }
1574
+
1575
+        if (!($response = $this->_GetResponse($fp, VER_COMMAND_UPDATE)))
1576
+        {
1577
+            $this->_MBPop();
1578
+            return -1;
1579
+        }
1580
+
1581
+        // parse response
1582
+        list(,$updated) = unpack("N*", substr($response, 0, 4));
1583
+        $this->_MBPop();
1584
+        return $updated;
1585
+    }
1586
+
1587
+    /////////////////////////////////////////////////////////////////////////////
1588
+    // persistent connections
1589
+    /////////////////////////////////////////////////////////////////////////////
1590
+
1591
+    public function Open()
1592
+    {
1593
+        if ($this->_socket !== false)
1594
+        {
1595
+            $this->_error = 'already connected';
1596
+            return false;
1597
+        }
1598
+        if (!$fp = $this->_Connect())
1599
+            return false;
1600
+
1601
+        // command, command version = 0, body length = 4, body = 1
1602
+        $req = pack("nnNN", SEARCHD_COMMAND_PERSIST, 0, 4, 1);
1603
+        if (!$this->_Send($fp, $req, 12))
1604
+            return false;
1605
+
1606
+        $this->_socket = $fp;
1607
+        return true;
1608
+    }
1609
+
1610
+    public function Close()
1611
+    {
1612
+        if ($this->_socket === false)
1613
+        {
1614
+            $this->_error = 'not connected';
1615
+            return false;
1616
+        }
1617
+
1618
+        fclose($this->_socket);
1619
+        $this->_socket = false;
1620
+
1621
+        return true;
1622
+    }
1623
+
1624
+    //////////////////////////////////////////////////////////////////////////
1625
+    // status
1626
+    //////////////////////////////////////////////////////////////////////////
1627
+
1628
+    public function Status()
1629
+    {
1630
+        $this->_MBPush();
1631
+        if (!($fp = $this->_Connect()))
1632
+        {
1633
+            $this->_MBPop();
1634
+            return false;
1635
+        }
1636
+
1637
+        $req = pack("nnNN", SEARCHD_COMMAND_STATUS, VER_COMMAND_STATUS, 4, 1); // len=4, body=1
1638
+        if (!($this->_Send($fp, $req, 12)) ||
1639
+             !($response = $this->_GetResponse($fp, VER_COMMAND_STATUS)))
1640
+        {
1641
+            $this->_MBPop();
1642
+            return false;
1643
+        }
1644
+
1645
+        $res = substr($response, 4); // just ignore length, error handling, etc
1646
+        $p = 0;
1647
+        list ($rows, $cols) = array_values(unpack("N*N*", substr($response, $p, 8))); $p += 8;
1648
+
1649
+        $res = array();
1650
+        for ($i = 0; $i < $rows; $i++)
1651
+            for ($j = 0; $j < $cols; $j++)
1652
+        {
1653
+            list(,$len) = unpack("N*", substr($response, $p, 4)); $p += 4;
1654
+            $res[$i][] = substr($response, $p, $len); $p += $len;
1655
+        }
1656
+
1657
+        $this->_MBPop();
1658
+        return $res;
1659
+    }
1660
+
1661
+    //////////////////////////////////////////////////////////////////////////
1662
+    // flush
1663
+    //////////////////////////////////////////////////////////////////////////
1664
+
1665
+    public function FlushAttributes()
1666
+    {
1667
+        $this->_MBPush();
1668
+        if (!($fp = $this->_Connect()))
1669
+        {
1670
+            $this->_MBPop();
1671
+            return -1;
1672
+        }
1673
+
1674
+        $req = pack("nnN", SEARCHD_COMMAND_FLUSHATTRS, VER_COMMAND_FLUSHATTRS, 0); // len=0
1675
+        if (!($this->_Send($fp, $req, 8)) ||
1676
+             !($response = $this->_GetResponse($fp, VER_COMMAND_FLUSHATTRS)))
1677
+        {
1678
+            $this->_MBPop();
1679
+            return -1;
1680
+        }
1681
+
1682
+        $tag = -1;
1683
+        if (strlen($response) == 4)
1684
+            list(,$tag) = unpack("N*", $response);
1685
+        else
1686
+            $this->_error = "unexpected response length";
1687
+
1688
+        $this->_MBPop();
1689
+        return $tag;
1690
+    }
1691 1691
 }
1692 1692
 
1693 1693
 //
Please login to merge, or discard this patch.
Switch Indentation   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -1003,22 +1003,22 @@  discard block
 block discarded – undo
1003 1003
 			$req .= pack("N", $filter["type"]);
1004 1004
 			switch ($filter["type"])
1005 1005
 			{
1006
-				case SPH_FILTER_VALUES:
1007
-					$req .= pack("N", count($filter["values"]));
1008
-					foreach ($filter["values"] as $value)
1009
-						$req .= sphPackI64($value);
1010
-					break;
1011
-
1012
-				case SPH_FILTER_RANGE:
1013
-					$req .= sphPackI64($filter["min"]).sphPackI64($filter["max"]);
1014
-					break;
1015
-
1016
-				case SPH_FILTER_FLOATRANGE:
1017
-					$req .= $this->_PackFloat($filter["min"]).$this->_PackFloat($filter["max"]);
1018
-					break;
1019
-
1020
-				default:
1021
-					assert(0 && "internal error: unhandled filter type");
1006
+			case SPH_FILTER_VALUES:
1007
+				$req .= pack("N", count($filter["values"]));
1008
+				foreach ($filter["values"] as $value)
1009
+					$req .= sphPackI64($value);
1010
+				break;
1011
+
1012
+			case SPH_FILTER_RANGE:
1013
+				$req .= sphPackI64($filter["min"]).sphPackI64($filter["max"]);
1014
+				break;
1015
+
1016
+			case SPH_FILTER_FLOATRANGE:
1017
+				$req .= $this->_PackFloat($filter["min"]).$this->_PackFloat($filter["max"]);
1018
+				break;
1019
+
1020
+			default:
1021
+				assert(0 && "internal error: unhandled filter type");
1022 1022
 			}
1023 1023
 			$req .= pack("N", $filter["exclude"]);
1024 1024
 		}
@@ -1073,9 +1073,9 @@  discard block
 block discarded – undo
1073 1073
 				$req .= sphPackU64($id);
1074 1074
 				switch ($entry["type"])
1075 1075
 				{
1076
-					case SPH_ATTR_FLOAT:	$req .= $this->_PackFloat($val); break;
1077
-					case SPH_ATTR_BIGINT:	$req .= sphPackI64($val); break;
1078
-					default:				$req .= pack("N", $val); break;
1076
+				case SPH_ATTR_FLOAT:	$req .= $this->_PackFloat($val); break;
1077
+				case SPH_ATTR_BIGINT:	$req .= sphPackI64($val); break;
1078
+				default:				$req .= pack("N", $val); break;
1079 1079
 				}
1080 1080
 			}
1081 1081
 		}
Please login to merge, or discard this patch.
Braces   +241 added lines, -134 removed lines patch added patch discarded remove patch
@@ -133,14 +133,16 @@  discard block
 block discarded – undo
133 133
 	}
134 134
 
135 135
 	// x32, int
136
-	if (is_int($v))
137
-		return pack("NN", $v < 0 ? -1 : 0, $v);
136
+	if (is_int($v)) {
137
+			return pack("NN", $v < 0 ? -1 : 0, $v);
138
+	}
138 139
 
139 140
 	// x32, bcmath
140 141
 	if (function_exists("bcmul"))
141 142
 	{
142
-		if (bccomp($v, 0) == -1)
143
-			$v = bcadd("18446744073709551616", $v);
143
+		if (bccomp($v, 0) == -1) {
144
+					$v = bcadd("18446744073709551616", $v);
145
+		}
144 146
 		$h = bcdiv($v, "4294967296", 0);
145 147
 		$l = bcmod($v, "4294967296");
146 148
 		return pack("NN", (float) $h, (float) $l); // conversion to float is intentional; int would lose 31st bit
@@ -158,9 +160,9 @@  discard block
 block discarded – undo
158 160
 
159 161
 	if ($v < 0)
160 162
 	{
161
-		if ($l == 0)
162
-			$h = 4294967296.0 - $h;
163
-		else
163
+		if ($l == 0) {
164
+					$h = 4294967296.0 - $h;
165
+		} else
164 166
 		{
165 167
 			$h = 4294967295.0 - $h;
166 168
 			$l = 4294967296.0 - $l;
@@ -180,8 +182,9 @@  discard block
 block discarded – undo
180 182
 		assert($v >= 0);
181 183
 
182 184
 		// x64, int
183
-		if (is_int($v))
184
-			return pack("NN", $v >> 32, $v & 0xFFFFFFFF);
185
+		if (is_int($v)) {
186
+					return pack("NN", $v >> 32, $v & 0xFFFFFFFF);
187
+		}
185 188
 
186 189
 		// x64, bcmath
187 190
 		if (function_exists("bcmul"))
@@ -204,8 +207,9 @@  discard block
 block discarded – undo
204 207
 	}
205 208
 
206 209
 	// x32, int
207
-	if (is_int($v))
208
-		return pack("NN", 0, $v);
210
+	if (is_int($v)) {
211
+			return pack("NN", 0, $v);
212
+	}
209 213
 
210 214
 	// x32, bcmath
211 215
 	if (function_exists("bcmul"))
@@ -235,16 +239,23 @@  discard block
 block discarded – undo
235 239
 
236 240
 	if (PHP_INT_SIZE >= 8)
237 241
 	{
238
-		if ($hi < 0) $hi += (1 << 32); // because php 5.2.2 to 5.2.5 is totally fucked up again
239
-		if ($lo < 0) $lo += (1 << 32);
242
+		if ($hi < 0) {
243
+		    $hi += (1 << 32);
244
+		}
245
+		// because php 5.2.2 to 5.2.5 is totally fucked up again
246
+		if ($lo < 0) {
247
+		    $lo += (1 << 32);
248
+		}
240 249
 
241 250
 		// x64, int
242
-		if ($hi <= 2147483647)
243
-			return ($hi << 32) + $lo;
251
+		if ($hi <= 2147483647) {
252
+					return ($hi << 32) + $lo;
253
+		}
244 254
 
245 255
 		// x64, bcmath
246
-		if (function_exists("bcmul"))
247
-			return bcadd($lo, bcmul($hi, "4294967296"));
256
+		if (function_exists("bcmul")) {
257
+					return bcadd($lo, bcmul($hi, "4294967296"));
258
+		}
248 259
 
249 260
 		// x64, no-bcmath
250 261
 		$C = 100000;
@@ -256,16 +267,18 @@  discard block
 block discarded – undo
256 267
 			$l  = $l % $C;
257 268
 		}
258 269
 
259
-		if ($h == 0)
260
-			return $l;
270
+		if ($h == 0) {
271
+					return $l;
272
+		}
261 273
 		return sprintf("%d%05d", $h, $l);
262 274
 	}
263 275
 
264 276
 	// x32, int
265 277
 	if ($hi == 0)
266 278
 	{
267
-		if ($lo > 0)
268
-			return $lo;
279
+		if ($lo > 0) {
280
+					return $lo;
281
+		}
269 282
 		return sprintf("%u", $lo);
270 283
 	}
271 284
 
@@ -273,8 +286,9 @@  discard block
 block discarded – undo
273 286
 	$lo = sprintf("%u", $lo);
274 287
 
275 288
 	// x32, bcmath
276
-	if (function_exists("bcmul"))
277
-		return bcadd($lo, bcmul($hi, "4294967296"));
289
+	if (function_exists("bcmul")) {
290
+			return bcadd($lo, bcmul($hi, "4294967296"));
291
+	}
278 292
 
279 293
 	// x32, no-bcmath
280 294
 	$hi = (float) $hi;
@@ -289,8 +303,9 @@  discard block
 block discarded – undo
289 303
 
290 304
 	$h = sprintf("%.0f", $h);
291 305
 	$l = sprintf("%07.0f", $l);
292
-	if ($h == "0")
293
-		return sprintf("%.0f", (float) $l);
306
+	if ($h == "0") {
307
+			return sprintf("%.0f", (float) $l);
308
+	}
294 309
 	return $h.$l;
295 310
 }
296 311
 
@@ -302,8 +317,13 @@  discard block
 block discarded – undo
302 317
 	// x64
303 318
 	if (PHP_INT_SIZE >= 8)
304 319
 	{
305
-		if ($hi < 0) $hi += (1 << 32); // because php 5.2.2 to 5.2.5 is totally fucked up again
306
-		if ($lo < 0) $lo += (1 << 32);
320
+		if ($hi < 0) {
321
+		    $hi += (1 << 32);
322
+		}
323
+		// because php 5.2.2 to 5.2.5 is totally fucked up again
324
+		if ($lo < 0) {
325
+		    $lo += (1 << 32);
326
+		}
307 327
 
308 328
 		return ($hi << 32) + $lo;
309 329
 	}
@@ -311,15 +331,17 @@  discard block
 block discarded – undo
311 331
 	// x32, int
312 332
 	if ($hi == 0)
313 333
 	{
314
-		if ($lo > 0)
315
-			return $lo;
334
+		if ($lo > 0) {
335
+					return $lo;
336
+		}
316 337
 		return sprintf("%u", $lo);
317 338
 	}
318 339
 	// x32, int
319 340
 	elseif ($hi == -1)
320 341
 	{
321
-		if ($lo < 0)
322
-			return $lo;
342
+		if ($lo < 0) {
343
+					return $lo;
344
+		}
323 345
 		return sprintf("%.0f", $lo - 4294967296.0);
324 346
 	}
325 347
 
@@ -337,8 +359,9 @@  discard block
 block discarded – undo
337 359
 	$lo = sprintf("%u", $lo);
338 360
 
339 361
 	// x32, bcmath
340
-	if (function_exists("bcmul"))
341
-		return $neg.bcadd(bcadd($lo, bcmul($hi, "4294967296")), $c);
362
+	if (function_exists("bcmul")) {
363
+			return $neg.bcadd(bcadd($lo, bcmul($hi, "4294967296")), $c);
364
+	}
342 365
 
343 366
 	// x32, no-bcmath
344 367
 	$hi = (float) $hi;
@@ -358,8 +381,9 @@  discard block
 block discarded – undo
358 381
 
359 382
 	$h = sprintf("%.0f", $h);
360 383
 	$l = sprintf("%07.0f", $l);
361
-	if ($h == "0")
362
-		return $neg.sprintf("%.0f", (float) $l);
384
+	if ($h == "0") {
385
+			return $neg.sprintf("%.0f", (float) $l);
386
+	}
363 387
 	return $neg.$h.$l;
364 388
 }
365 389
 
@@ -369,10 +393,11 @@  discard block
 block discarded – undo
369 393
 	if (PHP_INT_SIZE >= 8)
370 394
 	{
371 395
 		// x64 route, workaround broken unpack() in 5.2.2+
372
-		if ($value < 0) $value += (1 << 32);
396
+		if ($value < 0) {
397
+		    $value += (1 << 32);
398
+		}
373 399
 		return $value;
374
-	}
375
-	else
400
+	} else
376 401
 	{
377 402
 		// x32 route, workaround php signed/unsigned braindamage
378 403
 		return sprintf("%u", $value);
@@ -470,8 +495,9 @@  discard block
 block discarded – undo
470 495
 
471 496
 	public function __destruct()
472 497
 	{
473
-		if ($this->_socket !== false)
474
-			fclose($this->_socket);
498
+		if ($this->_socket !== false) {
499
+					fclose($this->_socket);
500
+		}
475 501
 	}
476 502
 
477 503
 	/// get last error message (string)
@@ -549,8 +575,9 @@  discard block
 block discarded – undo
549 575
 	/// leave mbstring workaround mode
550 576
 	public function _MBPop()
551 577
 	{
552
-		if ($this->_mbenc)
553
-			mb_internal_encoding($this->_mbenc);
578
+		if ($this->_mbenc) {
579
+					mb_internal_encoding($this->_mbenc);
580
+		}
554 581
 	}
555 582
 
556 583
 	/// connect to searchd server
@@ -560,8 +587,9 @@  discard block
 block discarded – undo
560 587
 		{
561 588
 			// we are in persistent connection mode, so we have a socket
562 589
 			// however, need to check whether it's still alive
563
-			if (!@feof($this->_socket))
564
-				return $this->_socket;
590
+			if (!@feof($this->_socket)) {
591
+							return $this->_socket;
592
+			}
565 593
 
566 594
 			// force reopen
567 595
 			$this->_socket = false;
@@ -575,24 +603,25 @@  discard block
 block discarded – undo
575 603
 		{
576 604
 			$host = $this->_path;
577 605
 			$port = 0;
578
-		}
579
-		else
606
+		} else
580 607
 		{
581 608
 			$host = $this->_host;
582 609
 			$port = $this->_port;
583 610
 		}
584 611
 
585
-		if ($this->_timeout <= 0)
586
-			$fp = @fsockopen($host, $port, $errno, $errstr);
587
-		else
588
-			$fp = @fsockopen($host, $port, $errno, $errstr, $this->_timeout);
612
+		if ($this->_timeout <= 0) {
613
+					$fp = @fsockopen($host, $port, $errno, $errstr);
614
+		} else {
615
+					$fp = @fsockopen($host, $port, $errno, $errstr, $this->_timeout);
616
+		}
589 617
 
590 618
 		if (!$fp)
591 619
 		{
592
-			if ($this->_path)
593
-				$location = $this->_path;
594
-			else
595
-				$location = "{$this->_host}:{$this->_port}";
620
+			if ($this->_path) {
621
+							$location = $this->_path;
622
+			} else {
623
+							$location = "{$this->_host}:{$this->_port}";
624
+			}
596 625
 
597 626
 			$errstr = trim($errstr);
598 627
 			$this->_error = "connection to $location failed (errno=$errno, msg=$errstr)";
@@ -645,8 +674,9 @@  discard block
 block discarded – undo
645 674
 				}
646 675
 			}
647 676
 		}
648
-		if ($this->_socket === false)
649
-			fclose($fp);
677
+		if ($this->_socket === false) {
678
+					fclose($fp);
679
+		}
650 680
 
651 681
 		// check response
652 682
 		$read = strlen($response);
@@ -706,10 +736,12 @@  discard block
 block discarded – undo
706 736
 		assert($max >= 0);
707 737
 		$this->_offset = $offset;
708 738
 		$this->_limit = $limit;
709
-		if ($max > 0)
710
-			$this->_maxmatches = $max;
711
-		if ($cutoff > 0)
712
-			$this->_cutoff = $cutoff;
739
+		if ($max > 0) {
740
+					$this->_maxmatches = $max;
741
+		}
742
+		if ($cutoff > 0) {
743
+					$this->_cutoff = $cutoff;
744
+		}
713 745
 	}
714 746
 
715 747
 	/// set maximum query time, in milliseconds, per-index
@@ -763,8 +795,9 @@  discard block
 block discarded – undo
763 795
 	public function SetWeights($weights)
764 796
 	{
765 797
 		assert(is_array($weights));
766
-		foreach ($weights as $weight)
767
-			assert(is_int($weight));
798
+		foreach ($weights as $weight) {
799
+					assert(is_int($weight));
800
+		}
768 801
 
769 802
 		$this->_weights = $weights;
770 803
 	}
@@ -814,8 +847,9 @@  discard block
 block discarded – undo
814 847
 
815 848
 		if (is_array($values) && count($values))
816 849
 		{
817
-			foreach ($values as $value)
818
-				assert(is_numeric($value));
850
+			foreach ($values as $value) {
851
+							assert(is_numeric($value));
852
+			}
819 853
 
820 854
 			$this->_filters[] = array("type"=>SPH_FILTER_VALUES, "attr"=>$attribute, "exclude"=>$exclude, "values"=>$values);
821 855
 		}
@@ -954,15 +988,18 @@  discard block
 block discarded – undo
954 988
 		$results = $this->RunQueries();
955 989
 		$this->_reqs = array(); // just in case it failed too early
956 990
 
957
-		if (!is_array($results))
958
-			return false; // probably network error; error message should be already filled
991
+		if (!is_array($results)) {
992
+					return false;
993
+		}
994
+		// probably network error; error message should be already filled
959 995
 
960 996
 		$this->_error = $results[0]["error"];
961 997
 		$this->_warning = $results[0]["warning"];
962
-		if ($results[0]["status"] == SEARCHD_ERROR)
963
-			return false;
964
-		else
965
-			return $results[0];
998
+		if ($results[0]["status"] == SEARCHD_ERROR) {
999
+					return false;
1000
+		} else {
1001
+					return $results[0];
1002
+		}
966 1003
 	}
967 1004
 
968 1005
 	/// helper to pack floats in network byte order
@@ -989,8 +1026,9 @@  discard block
 block discarded – undo
989 1026
 		$req .= pack("N", strlen($this->_sortby)).$this->_sortby;
990 1027
 		$req .= pack("N", strlen($query)).$query; // query itself
991 1028
 		$req .= pack("N", count($this->_weights)); // weights
992
-		foreach ($this->_weights as $weight)
993
-			$req .= pack("N", (int) $weight);
1029
+		foreach ($this->_weights as $weight) {
1030
+					$req .= pack("N", (int) $weight);
1031
+		}
994 1032
 		$req .= pack("N", strlen($index)).$index; // indexes
995 1033
 		$req .= pack("N", 1); // id64 range marker
996 1034
 		$req .= sphPackU64($this->_min_id).sphPackU64($this->_max_id); // id64 range
@@ -1005,8 +1043,9 @@  discard block
 block discarded – undo
1005 1043
 			{
1006 1044
 				case SPH_FILTER_VALUES:
1007 1045
 					$req .= pack("N", count($filter["values"]));
1008
-					foreach ($filter["values"] as $value)
1009
-						$req .= sphPackI64($value);
1046
+					foreach ($filter["values"] as $value) {
1047
+											$req .= sphPackI64($value);
1048
+					}
1010 1049
 					break;
1011 1050
 
1012 1051
 				case SPH_FILTER_RANGE:
@@ -1045,16 +1084,18 @@  discard block
 block discarded – undo
1045 1084
 
1046 1085
 		// per-index weights
1047 1086
 		$req .= pack("N", count($this->_indexweights));
1048
-		foreach ($this->_indexweights as $idx=>$weight)
1049
-			$req .= pack("N", strlen($idx)).$idx.pack("N", $weight);
1087
+		foreach ($this->_indexweights as $idx=>$weight) {
1088
+					$req .= pack("N", strlen($idx)).$idx.pack("N", $weight);
1089
+		}
1050 1090
 
1051 1091
 		// max query time
1052 1092
 		$req .= pack("N", $this->_maxquerytime);
1053 1093
 
1054 1094
 		// per-field weights
1055 1095
 		$req .= pack("N", count($this->_fieldweights));
1056
-		foreach ($this->_fieldweights as $field=>$weight)
1057
-			$req .= pack("N", strlen($field)).$field.pack("N", $weight);
1096
+		foreach ($this->_fieldweights as $field=>$weight) {
1097
+					$req .= pack("N", strlen($field)).$field.pack("N", $weight);
1098
+		}
1058 1099
 
1059 1100
 		// comment
1060 1101
 		$req .= pack("N", strlen($comment)).$comment;
@@ -1200,8 +1241,7 @@  discard block
 block discarded – undo
1200 1241
 				{
1201 1242
 					$doc = sphUnpackU64(substr($response, $p, 8)); $p += 8;
1202 1243
 					list(,$weight) = unpack("N*", substr($response, $p, 4)); $p += 4;
1203
-				}
1204
-				else
1244
+				} else
1205 1245
 				{
1206 1246
 					list ($doc, $weight) = array_values(unpack("N*N*",
1207 1247
 						substr($response, $p, 8)));
@@ -1211,10 +1251,11 @@  discard block
 block discarded – undo
1211 1251
 				$weight = sprintf("%u", $weight);
1212 1252
 
1213 1253
 				// create match entry
1214
-				if ($this->_arrayresult)
1215
-					$result["matches"][$idx] = array("id"=>$doc, "weight"=>$weight);
1216
-				else
1217
-					$result["matches"][$doc]["weight"] = $weight;
1254
+				if ($this->_arrayresult) {
1255
+									$result["matches"][$idx] = array("id"=>$doc, "weight"=>$weight);
1256
+				} else {
1257
+									$result["matches"][$doc]["weight"] = $weight;
1258
+				}
1218 1259
 
1219 1260
 				// parse and create attributes
1220 1261
 				$attrvals = array();
@@ -1257,10 +1298,11 @@  discard block
 block discarded – undo
1257 1298
 					}
1258 1299
 				}
1259 1300
 
1260
-				if ($this->_arrayresult)
1261
-					$result["matches"][$idx]["attrs"] = $attrvals;
1262
-				else
1263
-					$result["matches"][$doc]["attrs"] = $attrvals;
1301
+				if ($this->_arrayresult) {
1302
+									$result["matches"][$idx]["attrs"] = $attrvals;
1303
+				} else {
1304
+									$result["matches"][$doc]["attrs"] = $attrvals;
1305
+				}
1264 1306
 			}
1265 1307
 
1266 1308
 			list ($total, $total_found, $msecs, $words) =
@@ -1311,25 +1353,63 @@  discard block
 block discarded – undo
1311 1353
 		// fixup options
1312 1354
 		/////////////////
1313 1355
 
1314
-		if (!isset($opts["before_match"]))		$opts["before_match"] = "<b>";
1315
-		if (!isset($opts["after_match"]))			$opts["after_match"] = "</b>";
1316
-		if (!isset($opts["chunk_separator"]))		$opts["chunk_separator"] = " ... ";
1317
-		if (!isset($opts["limit"]))				$opts["limit"] = 256;
1318
-		if (!isset($opts["limit_passages"]))		$opts["limit_passages"] = 0;
1319
-		if (!isset($opts["limit_words"]))			$opts["limit_words"] = 0;
1320
-		if (!isset($opts["around"]))				$opts["around"] = 5;
1321
-		if (!isset($opts["exact_phrase"]))		$opts["exact_phrase"] = false;
1322
-		if (!isset($opts["single_passage"]))		$opts["single_passage"] = false;
1323
-		if (!isset($opts["use_boundaries"]))		$opts["use_boundaries"] = false;
1324
-		if (!isset($opts["weight_order"]))		$opts["weight_order"] = false;
1325
-		if (!isset($opts["query_mode"]))			$opts["query_mode"] = false;
1326
-		if (!isset($opts["force_all_words"]))		$opts["force_all_words"] = false;
1327
-		if (!isset($opts["start_passage_id"]))	$opts["start_passage_id"] = 1;
1328
-		if (!isset($opts["load_files"]))			$opts["load_files"] = false;
1329
-		if (!isset($opts["html_strip_mode"]))		$opts["html_strip_mode"] = "index";
1330
-		if (!isset($opts["allow_empty"]))			$opts["allow_empty"] = false;
1331
-		if (!isset($opts["passage_boundary"]))	$opts["passage_boundary"] = "none";
1332
-		if (!isset($opts["emit_zones"]))			$opts["emit_zones"] = false;
1356
+		if (!isset($opts["before_match"])) {
1357
+		    $opts["before_match"] = "<b>";
1358
+		}
1359
+		if (!isset($opts["after_match"])) {
1360
+		    $opts["after_match"] = "</b>";
1361
+		}
1362
+		if (!isset($opts["chunk_separator"])) {
1363
+		    $opts["chunk_separator"] = " ... ";
1364
+		}
1365
+		if (!isset($opts["limit"])) {
1366
+		    $opts["limit"] = 256;
1367
+		}
1368
+		if (!isset($opts["limit_passages"])) {
1369
+		    $opts["limit_passages"] = 0;
1370
+		}
1371
+		if (!isset($opts["limit_words"])) {
1372
+		    $opts["limit_words"] = 0;
1373
+		}
1374
+		if (!isset($opts["around"])) {
1375
+		    $opts["around"] = 5;
1376
+		}
1377
+		if (!isset($opts["exact_phrase"])) {
1378
+		    $opts["exact_phrase"] = false;
1379
+		}
1380
+		if (!isset($opts["single_passage"])) {
1381
+		    $opts["single_passage"] = false;
1382
+		}
1383
+		if (!isset($opts["use_boundaries"])) {
1384
+		    $opts["use_boundaries"] = false;
1385
+		}
1386
+		if (!isset($opts["weight_order"])) {
1387
+		    $opts["weight_order"] = false;
1388
+		}
1389
+		if (!isset($opts["query_mode"])) {
1390
+		    $opts["query_mode"] = false;
1391
+		}
1392
+		if (!isset($opts["force_all_words"])) {
1393
+		    $opts["force_all_words"] = false;
1394
+		}
1395
+		if (!isset($opts["start_passage_id"])) {
1396
+		    $opts["start_passage_id"] = 1;
1397
+		}
1398
+		if (!isset($opts["load_files"])) {
1399
+		    $opts["load_files"] = false;
1400
+		}
1401
+		if (!isset($opts["html_strip_mode"])) {
1402
+		    $opts["html_strip_mode"] = "index";
1403
+		}
1404
+		if (!isset($opts["allow_empty"])) {
1405
+		    $opts["allow_empty"] = false;
1406
+		}
1407
+		if (!isset($opts["passage_boundary"])) {
1408
+		    $opts["passage_boundary"] = "none";
1409
+		}
1410
+		if (!isset($opts["emit_zones"])) {
1411
+		    $opts["emit_zones"] = false;
1412
+		}
1333 1413
 
1334 1414
 		/////////////////
1335 1415
 		// build request
@@ -1337,15 +1417,33 @@  discard block
 block discarded – undo
1337 1417
 
1338 1418
 		// v.1.2 req
1339 1419
 		$flags = 1; // remove spaces
1340
-		if ($opts["exact_phrase"])	$flags |= 2;
1341
-		if ($opts["single_passage"])	$flags |= 4;
1342
-		if ($opts["use_boundaries"])	$flags |= 8;
1343
-		if ($opts["weight_order"])	$flags |= 16;
1344
-		if ($opts["query_mode"])		$flags |= 32;
1345
-		if ($opts["force_all_words"])	$flags |= 64;
1346
-		if ($opts["load_files"])		$flags |= 128;
1347
-		if ($opts["allow_empty"])		$flags |= 256;
1348
-		if ($opts["emit_zones"])		$flags |= 512;
1420
+		if ($opts["exact_phrase"]) {
1421
+		    $flags |= 2;
1422
+		}
1423
+		if ($opts["single_passage"]) {
1424
+		    $flags |= 4;
1425
+		}
1426
+		if ($opts["use_boundaries"]) {
1427
+		    $flags |= 8;
1428
+		}
1429
+		if ($opts["weight_order"]) {
1430
+		    $flags |= 16;
1431
+		}
1432
+		if ($opts["query_mode"]) {
1433
+		    $flags |= 32;
1434
+		}
1435
+		if ($opts["force_all_words"]) {
1436
+		    $flags |= 64;
1437
+		}
1438
+		if ($opts["load_files"]) {
1439
+		    $flags |= 128;
1440
+		}
1441
+		if ($opts["allow_empty"]) {
1442
+		    $flags |= 256;
1443
+		}
1444
+		if ($opts["emit_zones"]) {
1445
+		    $flags |= 512;
1446
+		}
1349 1447
 		$req = pack("NN", 0, $flags); // mode=0, flags=$flags
1350 1448
 		$req .= pack("N", strlen($index)).$index; // req index
1351 1449
 		$req .= pack("N", strlen($words)).$words; // req words
@@ -1512,8 +1610,9 @@  discard block
 block discarded – undo
1512 1610
 		assert(is_bool($mva));
1513 1611
 
1514 1612
 		assert(is_array($attrs));
1515
-		foreach ($attrs as $attr)
1516
-			assert(is_string($attr));
1613
+		foreach ($attrs as $attr) {
1614
+					assert(is_string($attr));
1615
+		}
1517 1616
 
1518 1617
 		assert(is_array($values));
1519 1618
 		foreach ($values as $id=>$entry)
@@ -1526,10 +1625,12 @@  discard block
 block discarded – undo
1526 1625
 				if ($mva)
1527 1626
 				{
1528 1627
 					assert(is_array($v));
1529
-					foreach ($v as $vv)
1530
-						assert(is_int($vv));
1531
-				} else
1532
-					assert(is_int($v));
1628
+					foreach ($v as $vv) {
1629
+											assert(is_int($vv));
1630
+					}
1631
+				} else {
1632
+									assert(is_int($v));
1633
+				}
1533 1634
 			}
1534 1635
 		}
1535 1636
 
@@ -1551,9 +1652,10 @@  discard block
 block discarded – undo
1551 1652
 			foreach ($entry as $v)
1552 1653
 			{
1553 1654
 				$req .= pack("N", $mva ? count($v) : $v);
1554
-				if ($mva)
1555
-					foreach ($v as $vv)
1655
+				if ($mva) {
1656
+									foreach ($v as $vv)
1556 1657
 						$req .= pack("N", $vv);
1658
+				}
1557 1659
 			}
1558 1660
 		}
1559 1661
 
@@ -1595,13 +1697,15 @@  discard block
 block discarded – undo
1595 1697
 			$this->_error = 'already connected';
1596 1698
 			return false;
1597 1699
 		}
1598
-		if (!$fp = $this->_Connect())
1599
-			return false;
1700
+		if (!$fp = $this->_Connect()) {
1701
+					return false;
1702
+		}
1600 1703
 
1601 1704
 		// command, command version = 0, body length = 4, body = 1
1602 1705
 		$req = pack("nnNN", SEARCHD_COMMAND_PERSIST, 0, 4, 1);
1603
-		if (!$this->_Send($fp, $req, 12))
1604
-			return false;
1706
+		if (!$this->_Send($fp, $req, 12)) {
1707
+					return false;
1708
+		}
1605 1709
 
1606 1710
 		$this->_socket = $fp;
1607 1711
 		return true;
@@ -1647,8 +1751,10 @@  discard block
 block discarded – undo
1647 1751
 		list ($rows, $cols) = array_values(unpack("N*N*", substr($response, $p, 8))); $p += 8;
1648 1752
 
1649 1753
 		$res = array();
1650
-		for ($i = 0; $i < $rows; $i++)
1651
-			for ($j = 0; $j < $cols; $j++)
1754
+		for ($i = 0; $i < $rows; $i++) {
1755
+					for ($j = 0;
1756
+		}
1757
+		$j < $cols; $j++)
1652 1758
 		{
1653 1759
 			list(,$len) = unpack("N*", substr($response, $p, 4)); $p += 4;
1654 1760
 			$res[$i][] = substr($response, $p, $len); $p += $len;
@@ -1680,10 +1786,11 @@  discard block
 block discarded – undo
1680 1786
 		}
1681 1787
 
1682 1788
 		$tag = -1;
1683
-		if (strlen($response) == 4)
1684
-			list(,$tag) = unpack("N*", $response);
1685
-		else
1686
-			$this->_error = "unexpected response length";
1789
+		if (strlen($response) == 4) {
1790
+					list(,$tag) = unpack("N*", $response);
1791
+		} else {
1792
+					$this->_error = "unexpected response length";
1793
+		}
1687 1794
 
1688 1795
 		$this->_MBPop();
1689 1796
 		return $tag;
Please login to merge, or discard this patch.
plugins/af_proxy_http/init.php 1 patch
Indentation   +189 added lines, -189 removed lines patch added patch discarded remove patch
@@ -1,223 +1,223 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 class Af_Proxy_Http extends Plugin {
3 3
 
4
-	/* @var PluginHost $host */
5
-	private $host;
4
+    /* @var PluginHost $host */
5
+    private $host;
6 6
 
7
-	/* @var DiskCache $cache */
8
-	private $cache;
7
+    /* @var DiskCache $cache */
8
+    private $cache;
9 9
 
10
-	public function about() {
11
-		return array(1.0,
12
-			"Loads media served over plain HTTP via built-in secure proxy",
13
-			"fox");
14
-	}
10
+    public function about() {
11
+        return array(1.0,
12
+            "Loads media served over plain HTTP via built-in secure proxy",
13
+            "fox");
14
+    }
15 15
 
16
-	private $ssl_known_whitelist = "imgur.com gfycat.com i.reddituploads.com pbs.twimg.com i.redd.it i.sli.mg media.tumblr.com";
16
+    private $ssl_known_whitelist = "imgur.com gfycat.com i.reddituploads.com pbs.twimg.com i.redd.it i.sli.mg media.tumblr.com";
17 17
 
18
-	public function is_public_method($method) {
19
-		return $method === "imgproxy";
20
-	}
18
+    public function is_public_method($method) {
19
+        return $method === "imgproxy";
20
+    }
21 21
 
22
-	public function init($host) {
23
-		$this->host = $host;
24
-		$this->cache = new DiskCache("images");
22
+    public function init($host) {
23
+        $this->host = $host;
24
+        $this->cache = new DiskCache("images");
25 25
 
26
-		$host->add_hook($host::HOOK_RENDER_ARTICLE, $this, 150);
27
-		$host->add_hook($host::HOOK_RENDER_ARTICLE_CDM, $this, 150);
28
-		$host->add_hook($host::HOOK_ENCLOSURE_ENTRY, $this);
26
+        $host->add_hook($host::HOOK_RENDER_ARTICLE, $this, 150);
27
+        $host->add_hook($host::HOOK_RENDER_ARTICLE_CDM, $this, 150);
28
+        $host->add_hook($host::HOOK_ENCLOSURE_ENTRY, $this);
29 29
 
30
-		$host->add_hook($host::HOOK_PREFS_TAB, $this);
31
-	}
30
+        $host->add_hook($host::HOOK_PREFS_TAB, $this);
31
+    }
32 32
 
33
-	public function hook_enclosure_entry($enc) {
34
-		if (preg_match("/image/", $enc["content_type"])) {
35
-			$proxy_all = $this->host->get($this, "proxy_all");
33
+    public function hook_enclosure_entry($enc) {
34
+        if (preg_match("/image/", $enc["content_type"])) {
35
+            $proxy_all = $this->host->get($this, "proxy_all");
36 36
 
37
-			$enc["content_url"] = $this->rewrite_url_if_needed($enc["content_url"], $proxy_all);
38
-		}
37
+            $enc["content_url"] = $this->rewrite_url_if_needed($enc["content_url"], $proxy_all);
38
+        }
39 39
 
40
-		return $enc;
41
-	}
40
+        return $enc;
41
+    }
42 42
 
43
-	public function hook_render_article($article) {
44
-		return $this->hook_render_article_cdm($article);
45
-	}
43
+    public function hook_render_article($article) {
44
+        return $this->hook_render_article_cdm($article);
45
+    }
46 46
 
47
-	public function imgproxy() {
47
+    public function imgproxy() {
48 48
 
49
-		$url = rewrite_relative_url(get_self_url_prefix(), $_REQUEST["url"]);
49
+        $url = rewrite_relative_url(get_self_url_prefix(), $_REQUEST["url"]);
50 50
 
51
-		// called without user context, let's just redirect to original URL
52
-		if (!$_SESSION["uid"]) {
53
-			header("Location: $url");
54
-			return;
55
-		}
51
+        // called without user context, let's just redirect to original URL
52
+        if (!$_SESSION["uid"]) {
53
+            header("Location: $url");
54
+            return;
55
+        }
56 56
 
57
-		$local_filename = sha1($url);
57
+        $local_filename = sha1($url);
58 58
 
59
-		if ($this->cache->exists($local_filename)) {
60
-			header("Location: ".$this->cache->getUrl($local_filename));
61
-			return;
62
-			//$this->cache->send($local_filename);
63
-		} else {
64
-			$data = fetch_file_contents(["url" => $url, "max_size" => MAX_CACHE_FILE_SIZE]);
59
+        if ($this->cache->exists($local_filename)) {
60
+            header("Location: ".$this->cache->getUrl($local_filename));
61
+            return;
62
+            //$this->cache->send($local_filename);
63
+        } else {
64
+            $data = fetch_file_contents(["url" => $url, "max_size" => MAX_CACHE_FILE_SIZE]);
65 65
 
66
-			if ($data) {
66
+            if ($data) {
67 67
 
68
-				$disable_cache = $this->host->get($this, "disable_cache");
68
+                $disable_cache = $this->host->get($this, "disable_cache");
69 69
 
70
-				if (!$disable_cache) {
71
-					if ($this->cache->put($local_filename, $data)) {
72
-						header("Location: ".$this->cache->getUrl($local_filename));
73
-						return;
74
-					}
75
-				}
76
-
77
-				print $data;
78
-			} else {
79
-				global $fetch_last_error;
80
-				global $fetch_last_error_code;
81
-				global $fetch_last_error_content;
82
-
83
-				if (function_exists("imagecreate") && !isset($_REQUEST["text"])) {
84
-					$img = imagecreate(450, 75);
85
-
86
-					/*$bg =*/ imagecolorallocate($img, 255, 255, 255);
87
-					$textcolor = imagecolorallocate($img, 255, 0, 0);
70
+                if (!$disable_cache) {
71
+                    if ($this->cache->put($local_filename, $data)) {
72
+                        header("Location: ".$this->cache->getUrl($local_filename));
73
+                        return;
74
+                    }
75
+                }
88 76
 
89
-					imagerectangle($img, 0, 0, 450 - 1, 75 - 1, $textcolor);
77
+                print $data;
78
+            } else {
79
+                global $fetch_last_error;
80
+                global $fetch_last_error_code;
81
+                global $fetch_last_error_content;
90 82
 
91
-					imagestring($img, 5, 5, 5, "Proxy request failed", $textcolor);
92
-					imagestring($img, 5, 5, 30, truncate_middle($url, 46, "..."), $textcolor);
93
-					imagestring($img, 5, 5, 55, "HTTP Code: $fetch_last_error_code", $textcolor);
83
+                if (function_exists("imagecreate") && !isset($_REQUEST["text"])) {
84
+                    $img = imagecreate(450, 75);
94 85
 
95
-					header("Content-type: image/png");
96
-					print imagepng($img);
97
-					imagedestroy($img);
86
+                    /*$bg =*/ imagecolorallocate($img, 255, 255, 255);
87
+                    $textcolor = imagecolorallocate($img, 255, 0, 0);
98 88
 
99
-				} else {
100
-					header("Content-type: text/html");
101
-
102
-					http_response_code(400);
103
-
104
-					print "<h1>Proxy request failed.</h1>";
105
-					print "<p>Fetch error $fetch_last_error ($fetch_last_error_code)</p>";
106
-					print "<p>URL: $url</p>";
107
-					print "<textarea cols='80' rows='25'>".htmlspecialchars($fetch_last_error_content)."</textarea>";
108
-				}
109
-			}
110
-		}
111
-	}
89
+                    imagerectangle($img, 0, 0, 450 - 1, 75 - 1, $textcolor);
112 90
 
113
-	private function rewrite_url_if_needed($url, $all_remote = false) {
114
-		/* we don't need to handle URLs where local cache already exists, tt-rss rewrites those automatically */
115
-		if (!$this->cache->exists(sha1($url))) {
91
+                    imagestring($img, 5, 5, 5, "Proxy request failed", $textcolor);
92
+                    imagestring($img, 5, 5, 30, truncate_middle($url, 46, "..."), $textcolor);
93
+                    imagestring($img, 5, 5, 55, "HTTP Code: $fetch_last_error_code", $textcolor);
116 94
 
117
-			$scheme = parse_url($url, PHP_URL_SCHEME);
95
+                    header("Content-type: image/png");
96
+                    print imagepng($img);
97
+                    imagedestroy($img);
118 98
 
119
-			if ($all_remote) {
120
-				$host = parse_url($url, PHP_URL_HOST);
121
-				$self_host = parse_url(get_self_url_prefix(), PHP_URL_HOST);
99
+                } else {
100
+                    header("Content-type: text/html");
122 101
 
123
-				$is_remote = $host != $self_host;
124
-			} else {
125
-				$is_remote = false;
126
-			}
102
+                    http_response_code(400);
127 103
 
128
-			if (($scheme != 'https' && $scheme != "") || $is_remote) {
129
-				if (strpos($url, "data:") !== 0) {
130
-					$parts = parse_url($url);
131
-
132
-					foreach (explode(" ", $this->ssl_known_whitelist) as $host) {
133
-						if (substr(strtolower($parts['host']), -strlen($host)) === strtolower($host)) {
134
-							$parts['scheme'] = 'https';
135
-							$url = build_url($parts);
136
-							if ($all_remote && $is_remote) {
137
-								break;
138
-							} else {
139
-								return $url;
140
-							}
141
-						}
142
-					}
104
+                    print "<h1>Proxy request failed.</h1>";
105
+                    print "<p>Fetch error $fetch_last_error ($fetch_last_error_code)</p>";
106
+                    print "<p>URL: $url</p>";
107
+                    print "<textarea cols='80' rows='25'>".htmlspecialchars($fetch_last_error_content)."</textarea>";
108
+                }
109
+            }
110
+        }
111
+    }
143 112
 
144
-					return $this->host->get_public_method_url($this, "imgproxy", ["url" => $url]);
145
-				}
146
-			}
147
-		}
113
+    private function rewrite_url_if_needed($url, $all_remote = false) {
114
+        /* we don't need to handle URLs where local cache already exists, tt-rss rewrites those automatically */
115
+        if (!$this->cache->exists(sha1($url))) {
148 116
 
149
-		return $url;
150
-	}
117
+            $scheme = parse_url($url, PHP_URL_SCHEME);
151 118
 
152
-	/**
153
-	 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
154
-	 */
155
-	public function hook_render_article_cdm($article, $api_mode = false) {
119
+            if ($all_remote) {
120
+                $host = parse_url($url, PHP_URL_HOST);
121
+                $self_host = parse_url(get_self_url_prefix(), PHP_URL_HOST);
156 122
 
157
-		$need_saving = false;
158
-		$proxy_all = $this->host->get($this, "proxy_all");
123
+                $is_remote = $host != $self_host;
124
+            } else {
125
+                $is_remote = false;
126
+            }
159 127
 
160
-		$doc = new DOMDocument();
161
-		if (@$doc->loadHTML('<?xml encoding="UTF-8">'.$article["content"])) {
162
-			$xpath = new DOMXPath($doc);
163
-			$imgs = $xpath->query("//img[@src]");
128
+            if (($scheme != 'https' && $scheme != "") || $is_remote) {
129
+                if (strpos($url, "data:") !== 0) {
130
+                    $parts = parse_url($url);
164 131
 
165
-			foreach ($imgs as $img) {
166
-				$new_src = $this->rewrite_url_if_needed($img->getAttribute("src"), $proxy_all);
132
+                    foreach (explode(" ", $this->ssl_known_whitelist) as $host) {
133
+                        if (substr(strtolower($parts['host']), -strlen($host)) === strtolower($host)) {
134
+                            $parts['scheme'] = 'https';
135
+                            $url = build_url($parts);
136
+                            if ($all_remote && $is_remote) {
137
+                                break;
138
+                            } else {
139
+                                return $url;
140
+                            }
141
+                        }
142
+                    }
167 143
 
168
-				if ($new_src != $img->getAttribute("src")) {
169
-					$img->setAttribute("src", $new_src);
170
-					$img->removeAttribute("srcset");
144
+                    return $this->host->get_public_method_url($this, "imgproxy", ["url" => $url]);
145
+                }
146
+            }
147
+        }
171 148
 
172
-					$need_saving = true;
173
-				}
174
-			}
149
+        return $url;
150
+    }
151
+
152
+    /**
153
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
154
+     */
155
+    public function hook_render_article_cdm($article, $api_mode = false) {
175 156
 
176
-			$vids = $xpath->query("(//video|//picture)");
157
+        $need_saving = false;
158
+        $proxy_all = $this->host->get($this, "proxy_all");
159
+
160
+        $doc = new DOMDocument();
161
+        if (@$doc->loadHTML('<?xml encoding="UTF-8">'.$article["content"])) {
162
+            $xpath = new DOMXPath($doc);
163
+            $imgs = $xpath->query("//img[@src]");
177 164
 
178
-			foreach ($vids as $vid) {
179
-				if ($vid->hasAttribute("poster")) {
180
-					$new_src = $this->rewrite_url_if_needed($vid->getAttribute("poster"), $proxy_all);
165
+            foreach ($imgs as $img) {
166
+                $new_src = $this->rewrite_url_if_needed($img->getAttribute("src"), $proxy_all);
181 167
 
182
-					if ($new_src != $vid->getAttribute("poster")) {
183
-						$vid->setAttribute("poster", $new_src);
168
+                if ($new_src != $img->getAttribute("src")) {
169
+                    $img->setAttribute("src", $new_src);
170
+                    $img->removeAttribute("srcset");
171
+
172
+                    $need_saving = true;
173
+                }
174
+            }
184 175
 
185
-						$need_saving = true;
186
-					}
187
-				}
176
+            $vids = $xpath->query("(//video|//picture)");
188 177
 
189
-				$vsrcs = $xpath->query("source", $vid);
178
+            foreach ($vids as $vid) {
179
+                if ($vid->hasAttribute("poster")) {
180
+                    $new_src = $this->rewrite_url_if_needed($vid->getAttribute("poster"), $proxy_all);
190 181
 
191
-				foreach ($vsrcs as $vsrc) {
192
-					$new_src = $this->rewrite_url_if_needed($vsrc->getAttribute("src"), $proxy_all);
182
+                    if ($new_src != $vid->getAttribute("poster")) {
183
+                        $vid->setAttribute("poster", $new_src);
193 184
 
194
-					if ($new_src != $vsrc->getAttribute("src")) {
195
-						$vid->setAttribute("src", $new_src);
185
+                        $need_saving = true;
186
+                    }
187
+                }
196 188
 
197
-						$need_saving = true;
198
-					}
199
-				}
200
-			}
201
-		}
189
+                $vsrcs = $xpath->query("source", $vid);
202 190
 
203
-		if ($need_saving) {
204
-		    $article["content"] = $doc->saveHTML();
205
-		}
191
+                foreach ($vsrcs as $vsrc) {
192
+                    $new_src = $this->rewrite_url_if_needed($vsrc->getAttribute("src"), $proxy_all);
206 193
 
207
-		return $article;
208
-	}
194
+                    if ($new_src != $vsrc->getAttribute("src")) {
195
+                        $vid->setAttribute("src", $new_src);
196
+
197
+                        $need_saving = true;
198
+                    }
199
+                }
200
+            }
201
+        }
202
+
203
+        if ($need_saving) {
204
+            $article["content"] = $doc->saveHTML();
205
+        }
206
+
207
+        return $article;
208
+    }
209 209
 
210
-	public function hook_prefs_tab($args) {
211
-		if ($args != "prefFeeds") {
212
-		    return;
213
-		}
210
+    public function hook_prefs_tab($args) {
211
+        if ($args != "prefFeeds") {
212
+            return;
213
+        }
214 214
 
215
-		print "<div dojoType=\"dijit.layout.AccordionPane\"
215
+        print "<div dojoType=\"dijit.layout.AccordionPane\"
216 216
 			title=\"<i class='material-icons'>extension</i> ".__('Image proxy settings (af_proxy_http)')."\">";
217 217
 
218
-		print "<form dojoType=\"dijit.form.Form\">";
218
+        print "<form dojoType=\"dijit.form.Form\">";
219 219
 
220
-		print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\">
220
+        print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\">
221 221
 			evt.preventDefault();
222 222
 			if (this.validate()) {
223 223
 				console.log(dojo.objectToQuery(this.getValues()));
@@ -231,36 +231,36 @@  discard block
 block discarded – undo
231 231
 			}
232 232
 			</script>";
233 233
 
234
-		print_hidden("op", "pluginhandler");
235
-		print_hidden("method", "save");
236
-		print_hidden("plugin", "af_proxy_http");
234
+        print_hidden("op", "pluginhandler");
235
+        print_hidden("method", "save");
236
+        print_hidden("plugin", "af_proxy_http");
237 237
 
238
-		$proxy_all = $this->host->get($this, "proxy_all");
239
-		print_checkbox("proxy_all", $proxy_all);
240
-		print "&nbsp;<label for=\"proxy_all\">".__("Enable proxy for all remote images.")."</label><br/>";
238
+        $proxy_all = $this->host->get($this, "proxy_all");
239
+        print_checkbox("proxy_all", $proxy_all);
240
+        print "&nbsp;<label for=\"proxy_all\">".__("Enable proxy for all remote images.")."</label><br/>";
241 241
 
242
-		$disable_cache = $this->host->get($this, "disable_cache");
243
-		print_checkbox("disable_cache", $disable_cache);
244
-		print "&nbsp;<label for=\"disable_cache\">".__("Don't cache files locally.")."</label>";
242
+        $disable_cache = $this->host->get($this, "disable_cache");
243
+        print_checkbox("disable_cache", $disable_cache);
244
+        print "&nbsp;<label for=\"disable_cache\">".__("Don't cache files locally.")."</label>";
245 245
 
246
-		print "<p>"; print_button("submit", __("Save"));
246
+        print "<p>"; print_button("submit", __("Save"));
247 247
 
248
-		print "</form>";
248
+        print "</form>";
249 249
 
250
-		print "</div>";
251
-	}
250
+        print "</div>";
251
+    }
252 252
 
253
-	public function save() {
254
-		$proxy_all = checkbox_to_sql_bool($_POST["proxy_all"]);
255
-		$disable_cache = checkbox_to_sql_bool($_POST["disable_cache"]);
253
+    public function save() {
254
+        $proxy_all = checkbox_to_sql_bool($_POST["proxy_all"]);
255
+        $disable_cache = checkbox_to_sql_bool($_POST["disable_cache"]);
256 256
 
257
-		$this->host->set($this, "proxy_all", $proxy_all, false);
258
-		$this->host->set($this, "disable_cache", $disable_cache);
257
+        $this->host->set($this, "proxy_all", $proxy_all, false);
258
+        $this->host->set($this, "disable_cache", $disable_cache);
259 259
 
260
-		echo __("Configuration saved");
261
-	}
260
+        echo __("Configuration saved");
261
+    }
262 262
 
263
-	public function api_version() {
264
-		return 2;
265
-	}
263
+    public function api_version() {
264
+        return 2;
265
+    }
266 266
 }
Please login to merge, or discard this patch.
plugins/af_unburn/init.php 1 patch
Indentation   +60 added lines, -60 removed lines patch added patch discarded remove patch
@@ -1,87 +1,87 @@
 block discarded – undo
1 1
 <?php
2 2
 class Af_Unburn extends Plugin {
3
-	private $host;
3
+    private $host;
4 4
 
5
-	public function about() {
6
-		return array(1.0,
7
-			"Resolves feedburner and similar feed redirector URLs (requires CURL)",
8
-			"fox");
9
-	}
5
+    public function about() {
6
+        return array(1.0,
7
+            "Resolves feedburner and similar feed redirector URLs (requires CURL)",
8
+            "fox");
9
+    }
10 10
 
11
-	public function flags() {
12
-		return array("needs_curl" => true);
13
-	}
11
+    public function flags() {
12
+        return array("needs_curl" => true);
13
+    }
14 14
 
15
-	public function init($host) {
16
-		$this->host = $host;
15
+    public function init($host) {
16
+        $this->host = $host;
17 17
 
18
-		$host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
19
-	}
18
+        $host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
19
+    }
20 20
 
21
-	public function hook_article_filter($article) {
22
-		$owner_uid = $article["owner_uid"];
21
+    public function hook_article_filter($article) {
22
+        $owner_uid = $article["owner_uid"];
23 23
 
24
-		if (defined('NO_CURL') || !function_exists("curl_init") || ini_get("open_basedir")) {
25
-					return $article;
26
-		}
24
+        if (defined('NO_CURL') || !function_exists("curl_init") || ini_get("open_basedir")) {
25
+                    return $article;
26
+        }
27 27
 
28
-		if ((strpos($article["link"], "feedproxy.google.com") !== false ||
29
-		  		strpos($article["link"], "/~r/") !== false ||
30
-				strpos($article["link"], "feedsportal.com") !== false)) {
28
+        if ((strpos($article["link"], "feedproxy.google.com") !== false ||
29
+                  strpos($article["link"], "/~r/") !== false ||
30
+                strpos($article["link"], "feedsportal.com") !== false)) {
31 31
 
32
-				$ch = curl_init($article["link"]);
32
+                $ch = curl_init($article["link"]);
33 33
 
34
-				curl_setopt($ch, CURLOPT_TIMEOUT, 5);
35
-				curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
36
-				curl_setopt($ch, CURLOPT_HEADER, true);
37
-				curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
38
-				curl_setopt($ch, CURLOPT_NOBODY, true);
39
-				curl_setopt($ch, CURLOPT_USERAGENT, SELF_USER_AGENT);
34
+                curl_setopt($ch, CURLOPT_TIMEOUT, 5);
35
+                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
36
+                curl_setopt($ch, CURLOPT_HEADER, true);
37
+                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
38
+                curl_setopt($ch, CURLOPT_NOBODY, true);
39
+                curl_setopt($ch, CURLOPT_USERAGENT, SELF_USER_AGENT);
40 40
 
41
-				if (defined('_CURL_HTTP_PROXY')) {
42
-					curl_setopt($ch, CURLOPT_PROXY, _CURL_HTTP_PROXY);
43
-				}
41
+                if (defined('_CURL_HTTP_PROXY')) {
42
+                    curl_setopt($ch, CURLOPT_PROXY, _CURL_HTTP_PROXY);
43
+                }
44 44
 
45
-				@curl_exec($ch);
45
+                @curl_exec($ch);
46 46
 
47
-				$real_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
47
+                $real_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
48 48
 
49
-				curl_close($ch);
49
+                curl_close($ch);
50 50
 
51
-				if ($real_url) {
52
-					/* remove the rest of it */
51
+                if ($real_url) {
52
+                    /* remove the rest of it */
53 53
 
54
-					$query = parse_url($real_url, PHP_URL_QUERY);
54
+                    $query = parse_url($real_url, PHP_URL_QUERY);
55 55
 
56
-					if ($query && strpos($query, "utm_source") !== false) {
57
-						$args = array();
58
-						parse_str($query, $args);
56
+                    if ($query && strpos($query, "utm_source") !== false) {
57
+                        $args = array();
58
+                        parse_str($query, $args);
59 59
 
60
-						foreach (array("utm_source", "utm_medium", "utm_campaign") as $param) {
61
-							if (isset($args[$param])) {
62
-							    unset($args[$param]);
63
-							}
64
-						}
60
+                        foreach (array("utm_source", "utm_medium", "utm_campaign") as $param) {
61
+                            if (isset($args[$param])) {
62
+                                unset($args[$param]);
63
+                            }
64
+                        }
65 65
 
66
-						$new_query = http_build_query($args);
66
+                        $new_query = http_build_query($args);
67 67
 
68
-						if ($new_query != $query) {
69
-							$real_url = str_replace("?$query", "?$new_query", $real_url);
70
-						}
71
-					}
68
+                        if ($new_query != $query) {
69
+                            $real_url = str_replace("?$query", "?$new_query", $real_url);
70
+                        }
71
+                    }
72 72
 
73
-					$real_url = preg_replace("/\?$/", "", $real_url);
73
+                    $real_url = preg_replace("/\?$/", "", $real_url);
74 74
 
75
-					$article["plugin_data"] = "unburn,$owner_uid:".$article["plugin_data"];
76
-					$article["link"] = $real_url;
77
-				}
78
-		}
75
+                    $article["plugin_data"] = "unburn,$owner_uid:".$article["plugin_data"];
76
+                    $article["link"] = $real_url;
77
+                }
78
+        }
79 79
 
80
-		return $article;
81
-	}
80
+        return $article;
81
+    }
82 82
 
83
-	public function api_version() {
84
-		return 2;
85
-	}
83
+    public function api_version() {
84
+        return 2;
85
+    }
86 86
 
87 87
 }
Please login to merge, or discard this patch.
plugins/note/init.php 1 patch
Indentation   +46 added lines, -46 removed lines patch added patch discarded remove patch
@@ -1,78 +1,78 @@
 block discarded – undo
1 1
 <?php
2 2
 class Note extends Plugin {
3 3
 
4
-	/* @var PluginHost $host */
5
-	private $host;
4
+    /* @var PluginHost $host */
5
+    private $host;
6 6
 
7
-	public function about() {
8
-		return array(1.0,
9
-			"Adds support for setting article notes",
10
-			"fox");
11
-	}
7
+    public function about() {
8
+        return array(1.0,
9
+            "Adds support for setting article notes",
10
+            "fox");
11
+    }
12 12
 
13
-	public function init($host) {
14
-		$this->host = $host;
13
+    public function init($host) {
14
+        $this->host = $host;
15 15
 
16
-		$host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
17
-	}
16
+        $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
17
+    }
18 18
 
19
-	public function get_js() {
20
-		return file_get_contents(dirname(__FILE__)."/note.js");
21
-	}
19
+    public function get_js() {
20
+        return file_get_contents(dirname(__FILE__)."/note.js");
21
+    }
22 22
 
23 23
 
24
-	public function hook_article_button($line) {
25
-		return "<i class='material-icons' onclick=\"Plugins.Note.edit(".$line["id"].")\"
24
+    public function hook_article_button($line) {
25
+        return "<i class='material-icons' onclick=\"Plugins.Note.edit(".$line["id"].")\"
26 26
 			style='cursor : pointer' title='".__('Edit article note')."'>note</i>";
27
-	}
27
+    }
28 28
 
29
-	public function edit() {
30
-		$param = $_REQUEST['param'];
29
+    public function edit() {
30
+        $param = $_REQUEST['param'];
31 31
 
32
-		$sth = $this->pdo->prepare("SELECT note FROM ttrss_user_entries WHERE
32
+        $sth = $this->pdo->prepare("SELECT note FROM ttrss_user_entries WHERE
33 33
 			ref_id = ? AND owner_uid = ?");
34
-		$sth->execute([$param, $_SESSION['uid']]);
34
+        $sth->execute([$param, $_SESSION['uid']]);
35 35
 
36
-		if ($row = $sth->fetch()) {
36
+        if ($row = $sth->fetch()) {
37 37
 
38
-			$note = $row['note'];
38
+            $note = $row['note'];
39 39
 
40
-			print_hidden("id", "$param");
41
-			print_hidden("op", "pluginhandler");
42
-			print_hidden("method", "setNote");
43
-			print_hidden("plugin", "note");
40
+            print_hidden("id", "$param");
41
+            print_hidden("op", "pluginhandler");
42
+            print_hidden("method", "setNote");
43
+            print_hidden("plugin", "note");
44 44
 
45
-			print "<textarea dojoType='dijit.form.SimpleTextarea'
45
+            print "<textarea dojoType='dijit.form.SimpleTextarea'
46 46
 				style='font-size : 12px; width : 98%; height: 100px;'
47 47
 				name='note'>$note</textarea>";
48 48
 
49
-		}
49
+        }
50 50
 
51
-		print "<footer class='text-center'>";
52
-		print "<button dojoType=\"dijit.form.Button\"
51
+        print "<footer class='text-center'>";
52
+        print "<button dojoType=\"dijit.form.Button\"
53 53
 			onclick=\"dijit.byId('editNoteDlg').execute()\">".__('Save')."</button> ";
54
-		print "<button dojoType=\"dijit.form.Button\"
54
+        print "<button dojoType=\"dijit.form.Button\"
55 55
 			onclick=\"dijit.byId('editNoteDlg').hide()\">".__('Cancel')."</button>";
56
-		print "</footer>";
56
+        print "</footer>";
57 57
 
58
-	}
58
+    }
59 59
 
60
-	public function setNote() {
61
-		$id = $_REQUEST["id"];
62
-		$note = trim(strip_tags($_REQUEST["note"]));
60
+    public function setNote() {
61
+        $id = $_REQUEST["id"];
62
+        $note = trim(strip_tags($_REQUEST["note"]));
63 63
 
64
-		$sth = $this->pdo->prepare("UPDATE ttrss_user_entries SET note = ?
64
+        $sth = $this->pdo->prepare("UPDATE ttrss_user_entries SET note = ?
65 65
 			WHERE ref_id = ? AND owner_uid = ?");
66
-		$sth->execute([$note, $id, $_SESSION['uid']]);
66
+        $sth->execute([$note, $id, $_SESSION['uid']]);
67 67
 
68
-		$formatted_note = Article::format_article_note($id, $note);
68
+        $formatted_note = Article::format_article_note($id, $note);
69 69
 
70
-		print json_encode(array("note" => $formatted_note,
71
-				"raw_length" => mb_strlen($note)));
72
-	}
70
+        print json_encode(array("note" => $formatted_note,
71
+                "raw_length" => mb_strlen($note)));
72
+    }
73 73
 
74
-	public function api_version() {
75
-		return 2;
76
-	}
74
+    public function api_version() {
75
+        return 2;
76
+    }
77 77
 
78 78
 }
Please login to merge, or discard this patch.