-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathCirrusSearchJob.php
More file actions
149 lines (113 loc) · 4.61 KB
/
CirrusSearchJob.php
File metadata and controls
149 lines (113 loc) · 4.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<?php
namespace App\Jobs\CirrusSearch;
use App\Http\Curl\HttpRequest;
use App\Jobs\Job;
use App\Services\MediaWikiHostResolver;
use App\Wiki;
use App\WikiSetting;
use Illuminate\Contracts\Queue\ShouldBeUnique;
abstract class CirrusSearchJob extends Job implements ShouldBeUnique {
protected $wikiId;
protected $setting;
protected $wiki;
protected $wikiDB;
abstract public function apiModule(): string;
abstract public function handleResponse(string $rawResponse, $error): void;
public function __construct($wikiId) {
$this->wikiId = $wikiId;
}
/**
* The unique ID of the job.
*
* @return string
*/
public function uniqueId() {
return strval($this->wikiId);
}
public function wikiId(): int {
return $this->wikiId;
}
/**
* @return void
*/
public function handle(HttpRequest $request, MediaWikiHostResolver $mwHostResolver) {
$this->wiki = Wiki::whereId($this->wikiId)->with('settings')->with('wikiDb')->first();
// job got triggered but no wiki
if (!$this->wiki) {
$this->fail(new \RuntimeException($this->apiModule() . ' call for ' . $this->wikiId . ' was triggered but not wiki available.'));
return;
}
$this->setting = $this->wiki->settings()->where(['name' => WikiSetting::wwExtEnableElasticSearch])->first();
// job got triggered but no setting
if (!$this->setting) {
$this->fail(new \RuntimeException($this->apiModule() . ' call for ' . $this->wikiId . ' was triggered but not setting available'));
return;
}
$this->wikiDB = $this->wiki->wikiDb()->first();
// no wikiDB around
if (!$this->wikiDB) {
$this->fail(new \RuntimeException($this->apiModule() . ' call for ' . $this->wikiId . ' was triggered but not WikiDb available'));
return;
}
$request->setOptions(
[
CURLOPT_URL => $mwHostResolver->getBackendHostForDomain($this->wiki->domain) . '/w/api.php?action=' . $this->apiModule() . $this->getQueryParams(),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_TIMEOUT => $this->getRequestTimeout(),
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'content-type: application/x-www-form-urlencoded',
'host: ' . $this->wiki->domain,
],
]
);
$rawResponse = $request->execute();
$err = $request->error();
$request->close();
$this->handleResponse($rawResponse, $err);
}
protected function validateOrFailRequest(?array $response, string $rawResponse, $error): bool {
if ($error) {
$this->fail(new \RuntimeException($this->apiModule() . ' curl error for ' . $this->wikiId . ': ' . $error));
return false;
}
if ($this->hasApiError($response)) {
$this->fail(new \RuntimeException($this->apiModule() . ' call failed with api error: ' . $response['error']['info']));
return false;
}
if (!$this->isValid($response)) {
$this->fail(new \RuntimeException($this->apiModule() . ' call for ' . $this->wikiId . '. No ' . $this->apiModule() . ' key in response: ' . $rawResponse));
return false;
}
return true;
}
protected function validateSuccess(array $response, string $rawResponse, $error): bool {
if (!$this->isSuccessful($response)) {
$this->fail(new \RuntimeException($this->apiModule() . ' call for ' . $this->wikiId . ' was not successful:' . $rawResponse));
return false;
}
return true;
}
protected function getRequestTimeout(): int {
return 100;
}
// TODO Migrate this to some other baseclass for all internal api classes
// This and some other stuff would be usedful there too
protected function hasApiError(?array $response): bool {
return is_array($response) && array_key_exists('error', $response);
}
protected function isValid(?array $response): bool {
return is_array($response) && array_key_exists($this->apiModule(), $response);
}
protected function isSuccessful(array $response): bool {
return array_key_exists('return', $response[$this->apiModule()]) && $response[$this->apiModule()]['return'] == 0;
}
/**
* @return string
*/
protected function getQueryParams() {
return '&format=json';
}
}