1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-02-01 17:38:24 +01:00
phorge-phorge/src/applications/draft/storage/PhabricatorVersionedDraft.php
epriestley fe501bd7f7 Save drafts for inline comments currently being edited
Summary:
Ref T13513. As users type text into inline comments, save the comment state as a draft on the server.

This has some rough edges, particularly around previews, but mostly works. See T13513 for notes.

Test Plan: Started an inline, typed some text, waited a second, reloaded the page, saw an editing inline with the saved text.

Maniphest Tasks: T13513

Differential Revision: https://secure.phabricator.com/D21216
2020-05-04 13:19:42 -07:00

113 lines
2.7 KiB
PHP

<?php
final class PhabricatorVersionedDraft extends PhabricatorDraftDAO {
const KEY_VERSION = 'draft.version';
protected $objectPHID;
protected $authorPHID;
protected $version;
protected $properties = array();
protected function getConfiguration() {
return array(
self::CONFIG_SERIALIZATION => array(
'properties' => self::SERIALIZATION_JSON,
),
self::CONFIG_COLUMN_SCHEMA => array(
'version' => 'uint32',
),
self::CONFIG_KEY_SCHEMA => array(
'key_object' => array(
'columns' => array('objectPHID', 'authorPHID', 'version'),
'unique' => true,
),
),
) + parent::getConfiguration();
}
public function setProperty($key, $value) {
$this->properties[$key] = $value;
return $this;
}
public function getProperty($key, $default = null) {
return idx($this->properties, $key, $default);
}
public static function loadDrafts(
array $object_phids,
$viewer_phid) {
$rows = id(new self())->loadAllWhere(
'objectPHID IN (%Ls) AND authorPHID = %s ORDER BY version ASC',
$object_phids,
$viewer_phid);
$map = array();
foreach ($rows as $row) {
$map[$row->getObjectPHID()] = $row;
}
return $map;
}
public static function loadDraft(
$object_phid,
$viewer_phid) {
return id(new PhabricatorVersionedDraft())->loadOneWhere(
'objectPHID = %s AND authorPHID = %s ORDER BY version DESC LIMIT 1',
$object_phid,
$viewer_phid);
}
public static function loadOrCreateDraft(
$object_phid,
$viewer_phid,
$version) {
$draft = self::loadDraft($object_phid, $viewer_phid);
if ($draft) {
return $draft;
}
try {
return id(new self())
->setObjectPHID($object_phid)
->setAuthorPHID($viewer_phid)
->setVersion((int)$version)
->save();
} catch (AphrontDuplicateKeyQueryException $ex) {
$duplicate_exception = $ex;
}
// In rare cases we can race ourselves, and at one point there was a bug
// which caused the browser to submit two preview requests at exactly
// the same time. If the insert failed with a duplicate key exception,
// try to load the colliding row to recover from it.
$draft = self::loadDraft($object_phid, $viewer_phid);
if ($draft) {
return $draft;
}
throw $duplicate_exception;
}
public static function purgeDrafts(
$object_phid,
$viewer_phid) {
$draft = new PhabricatorVersionedDraft();
$conn_w = $draft->establishConnection('w');
queryfx(
$conn_w,
'DELETE FROM %T WHERE objectPHID = %s AND authorPHID = %s',
$draft->getTableName(),
$object_phid,
$viewer_phid);
}
}