Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/draft/storage/PhabricatorVersionedDraft.php
12242 views
1
<?php
2
3
final class PhabricatorVersionedDraft extends PhabricatorDraftDAO {
4
5
const KEY_VERSION = 'draft.version';
6
7
protected $objectPHID;
8
protected $authorPHID;
9
protected $version;
10
protected $properties = array();
11
12
protected function getConfiguration() {
13
return array(
14
self::CONFIG_SERIALIZATION => array(
15
'properties' => self::SERIALIZATION_JSON,
16
),
17
self::CONFIG_COLUMN_SCHEMA => array(
18
'version' => 'uint32',
19
),
20
self::CONFIG_KEY_SCHEMA => array(
21
'key_object' => array(
22
'columns' => array('objectPHID', 'authorPHID', 'version'),
23
'unique' => true,
24
),
25
),
26
) + parent::getConfiguration();
27
}
28
29
public function setProperty($key, $value) {
30
$this->properties[$key] = $value;
31
return $this;
32
}
33
34
public function getProperty($key, $default = null) {
35
return idx($this->properties, $key, $default);
36
}
37
38
public static function loadDrafts(
39
array $object_phids,
40
$viewer_phid) {
41
42
$rows = id(new self())->loadAllWhere(
43
'objectPHID IN (%Ls) AND authorPHID = %s ORDER BY version ASC',
44
$object_phids,
45
$viewer_phid);
46
47
$map = array();
48
foreach ($rows as $row) {
49
$map[$row->getObjectPHID()] = $row;
50
}
51
52
return $map;
53
}
54
55
public static function loadDraft(
56
$object_phid,
57
$viewer_phid) {
58
59
return id(new PhabricatorVersionedDraft())->loadOneWhere(
60
'objectPHID = %s AND authorPHID = %s ORDER BY version DESC LIMIT 1',
61
$object_phid,
62
$viewer_phid);
63
}
64
65
public static function loadOrCreateDraft(
66
$object_phid,
67
$viewer_phid,
68
$version) {
69
70
$draft = self::loadDraft($object_phid, $viewer_phid);
71
if ($draft) {
72
return $draft;
73
}
74
75
try {
76
return id(new self())
77
->setObjectPHID($object_phid)
78
->setAuthorPHID($viewer_phid)
79
->setVersion((int)$version)
80
->save();
81
} catch (AphrontDuplicateKeyQueryException $ex) {
82
$duplicate_exception = $ex;
83
}
84
85
// In rare cases we can race ourselves, and at one point there was a bug
86
// which caused the browser to submit two preview requests at exactly
87
// the same time. If the insert failed with a duplicate key exception,
88
// try to load the colliding row to recover from it.
89
90
$draft = self::loadDraft($object_phid, $viewer_phid);
91
if ($draft) {
92
return $draft;
93
}
94
95
throw $duplicate_exception;
96
}
97
98
public static function purgeDrafts(
99
$object_phid,
100
$viewer_phid) {
101
102
$draft = new PhabricatorVersionedDraft();
103
$conn_w = $draft->establishConnection('w');
104
105
queryfx(
106
$conn_w,
107
'DELETE FROM %T WHERE objectPHID = %s AND authorPHID = %s',
108
$draft->getTableName(),
109
$object_phid,
110
$viewer_phid);
111
}
112
113
}
114
115