1<?php
2
3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
4// See the LICENCE file in the repository root for full licence text.
5
6declare(strict_types=1);
7
8namespace App\Jobs;
9
10use Exception;
11use Illuminate\Bus\Queueable;
12use Illuminate\Contracts\Queue\ShouldQueue;
13use Illuminate\Foundation\Bus\Dispatchable;
14use Illuminate\Queue\InteractsWithQueue;
15
16class EsDocument implements ShouldQueue
17{
18 use Dispatchable, InteractsWithQueue, Queueable;
19
20 private array $modelMeta;
21
22 /**
23 * Create a new job instance.
24 *
25 * @return void
26 */
27 public function __construct($model)
28 {
29 $this->modelMeta = [
30 'class' => get_class($model),
31 'id' => $model->getKey(),
32 ];
33 }
34
35 public function displayName()
36 {
37 return static::class." ({$this->modelMeta['class']} {$this->modelMeta['id']})";
38 }
39
40 /**
41 * Execute the job.
42 *
43 * @return void
44 */
45 public function handle(): void
46 {
47 $id = $this->modelMeta['id'];
48
49 if (!is_scalar($id)) {
50 log_error(new Exception("can't index models with unsupported primary key: ".json_encode($id)));
51
52 return;
53 }
54
55 $class = $this->modelMeta['class'];
56 $query = $class::query();
57
58 if ($class::hasMacro('withTrashed')) {
59 $query->withTrashed();
60 }
61
62 $model = $query->find($id);
63
64 if ($model !== null) {
65 $model->esIndexDocument();
66 $this->incrementStat('index');
67
68 return;
69 }
70
71 $model = new $class();
72 $keyName = $model->getKeyName();
73 $model->setAttribute($keyName, $id);
74 $model->esDeleteDocument();
75 $this->incrementStat('delete');
76 }
77
78 private function incrementStat(string $action): void
79 {
80 datadog_increment('es_document', [
81 'action' => $action,
82 'class' => $this->modelMeta['class'],
83 ]);
84 }
85}