aboutsummaryrefslogtreecommitdiffhomepage
path: root/Digitigrade/Model/PushableModel.php
blob: 4df90c8fd10e8fa0ac7e255b975c81e3663e614a (plain)
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
<?php
namespace Digitigrade\Model;

use Digitigrade\Job\PushObject;

abstract class PushableModel extends FetchableModel implements \JsonSerializable {
    public ?int $id;
    public string $uri;
    public bool $deleted = false;

    public static function importFromReceivedObject(\stdClass $data, bool $autoSave = true): ?static {
        if ($data->type == 'tombstone') {
            // actually just delete the object if we know it and do nothing if not
            $obj = static::findWhere('uri = ?', [$data->self]);
            if ($obj == null)
                return null;
            $obj->deleted = true;
            $obj->save();
            return null;
        }

        $obj = static::createFromJson($data, $autoSave);
        if ($autoSave) {
            $obj->save();
            $obj->finaliseAfterSave();
        }
        return $obj;
    }

    /**
     * @return Instance[] a list of instances who this object should be pushed to
     */
    protected abstract function getRelevantServers(): array;

    /**
     * Sends this object to all instances it's relevant to.
     * 
     * Please don't call this on non-local objects :3
     * @return void
     */
    public function publish() {
        foreach ($this->getRelevantServers() as $instance) {
            if ($instance == null) // really this should not happen but i'm lazy so it might
                continue;
            (new PushObject($this, $instance))->submit();
        }
    }

    /**
     * Marks this object as deleted and publishes a tombstone in its place.
     * @return void
     */
    public function markDeleted() {
        $this->deleted = true;
        $this->save();
        $this->publish();
    }
}