Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/differential/storage/DifferentialViewState.php b/src/applications/differential/storage/DifferentialViewState.php
index 101061f379..44c1f308d8 100644
--- a/src/applications/differential/storage/DifferentialViewState.php
+++ b/src/applications/differential/storage/DifferentialViewState.php
@@ -1,145 +1,150 @@
<?php
final class DifferentialViewState
extends DifferentialDAO
implements PhabricatorPolicyInterface {
protected $viewerPHID;
protected $objectPHID;
protected $viewState = array();
private $hasModifications;
protected function getConfiguration() {
return array(
self::CONFIG_SERIALIZATION => array(
'viewState' => self::SERIALIZATION_JSON,
),
self::CONFIG_KEY_SCHEMA => array(
'key_viewer' => array(
'columns' => array('viewerPHID', 'objectPHID'),
'unique' => true,
),
'key_object' => array(
'columns' => array('objectPHID'),
),
'key_modified' => array(
'columns' => array('dateModified'),
),
),
) + parent::getConfiguration();
}
public function setChangesetProperty(
DifferentialChangeset $changeset,
$key,
$value) {
if ($this->getChangesetProperty($changeset, $key) === $value) {
return;
}
$properties = array(
'value' => $value,
'epoch' => PhabricatorTime::getNow(),
);
$diff_id = $changeset->getDiffID();
if ($diff_id !== null) {
$properties['diffID'] = (int)$diff_id;
}
+ $changeset_id = $changeset->getID();
+ if ($changeset_id !== null) {
+ $properties['changesetID'] = (int)$changeset_id;
+ }
+
$path_hash = $this->getChangesetPathHash($changeset);
$changeset_phid = $this->getChangesetKey($changeset);
$this->hasModifications = true;
$this->viewState['changesets'][$path_hash][$key][$changeset_phid] =
$properties;
}
public function getChangesetProperty(
DifferentialChangeset $changeset,
$key,
$default = null) {
$entries = $this->getChangesetPropertyEntries(
$changeset,
$key);
$entries = isort($entries, 'epoch');
$entry = last($entries);
if (!is_array($entry)) {
$entry = array();
}
return idx($entry, 'value', $default);
}
public function getChangesetPropertyEntries(
DifferentialChangeset $changeset,
$key) {
$path_hash = $this->getChangesetPathHash($changeset);
$entries = idxv($this->viewState, array('changesets', $path_hash, $key));
if (!is_array($entries)) {
$entries = array();
}
return $entries;
}
public function getHasModifications() {
return $this->hasModifications;
}
private function getChangesetPathHash(DifferentialChangeset $changeset) {
$path = $changeset->getFilename();
return PhabricatorHash::digestForIndex($path);
}
private function getChangesetKey(DifferentialChangeset $changeset) {
$key = $changeset->getID();
if ($key === null) {
return '*';
}
return (string)$key;
}
public static function copyViewStatesToObject($src_phid, $dst_phid) {
$table = new self();
$conn = $table->establishConnection('w');
queryfx(
$conn,
'INSERT IGNORE INTO %R
(viewerPHID, objectPHID, viewState, dateCreated, dateModified)
SELECT viewerPHID, %s, viewState, dateCreated, dateModified
FROM %R WHERE objectPHID = %s',
$table,
$dst_phid,
$table,
$src_phid);
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
);
}
public function getPolicy($capability) {
return PhabricatorPolicies::POLICY_NOONE;
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return ($viewer->getPHID() === $this->getViewerPHID());
}
}
diff --git a/src/infrastructure/diff/viewstate/PhabricatorChangesetViewStateEngine.php b/src/infrastructure/diff/viewstate/PhabricatorChangesetViewStateEngine.php
index 2363f7f0ff..5979ca2a7b 100644
--- a/src/infrastructure/diff/viewstate/PhabricatorChangesetViewStateEngine.php
+++ b/src/infrastructure/diff/viewstate/PhabricatorChangesetViewStateEngine.php
@@ -1,235 +1,239 @@
<?php
final class PhabricatorChangesetViewStateEngine
extends Phobject {
private $viewer;
private $objectPHID;
private $changeset;
private $storage;
public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
return $this;
}
public function getViewer() {
return $this->viewer;
}
public function setObjectPHID($object_phid) {
$this->objectPHID = $object_phid;
return $this;
}
public function getObjectPHID() {
return $this->objectPHID;
}
public function setChangeset(DifferentialChangeset $changeset) {
$this->changeset = $changeset;
return $this;
}
public function getChangeset() {
return $this->changeset;
}
public function newViewStateFromRequest(AphrontRequest $request) {
$storage = $this->loadViewStateStorage();
$this->setStorage($storage);
$highlight = $request->getStr('highlight');
if ($highlight !== null) {
$this->setChangesetProperty('highlight', $highlight);
}
$encoding = $request->getStr('encoding');
if ($encoding !== null) {
$this->setChangesetProperty('encoding', $encoding);
}
$engine = $request->getStr('engine');
if ($engine !== null) {
$this->setChangesetProperty('engine', $engine);
}
$renderer = $request->getStr('renderer');
if ($renderer !== null) {
$this->setChangesetProperty('renderer', $renderer);
}
$hidden = $request->getStr('hidden');
if ($hidden !== null) {
$this->setChangesetProperty('hidden', (int)$hidden);
}
$this->saveViewStateStorage();
$state = new PhabricatorChangesetViewState();
$highlight_language = $this->getChangesetProperty('highlight');
$state->setHighlightLanguage($highlight_language);
$encoding = $this->getChangesetProperty('encoding');
$state->setCharacterEncoding($encoding);
$document_engine = $this->getChangesetProperty('engine');
$state->setDocumentEngineKey($document_engine);
$renderer = $this->getChangesetProperty('renderer');
$state->setRendererKey($renderer);
$this->updateHiddenState($state);
// This is the client-selected default renderer based on viewport
// dimensions.
$device_key = $request->getStr('device');
if ($device_key !== null) {
$state->setDefaultDeviceRendererKey($device_key);
}
$discard_response = $request->getStr('discard');
if ($discard_response !== null) {
$state->setDiscardResponse(true);
}
return $state;
}
private function setStorage(DifferentialViewState $storage) {
$this->storage = $storage;
return $this;
}
private function getStorage() {
return $this->storage;
}
private function setChangesetProperty(
$key,
$value) {
$storage = $this->getStorage();
$changeset = $this->getChangeset();
$storage->setChangesetProperty($changeset, $key, $value);
}
private function getChangesetProperty(
$key,
$default = null) {
$storage = $this->getStorage();
$changeset = $this->getChangeset();
return $storage->getChangesetProperty($changeset, $key, $default);
}
private function loadViewStateStorage() {
$viewer = $this->getViewer();
$object_phid = $this->getObjectPHID();
$viewer_phid = $viewer->getPHID();
$storage = null;
if ($viewer_phid !== null) {
$storage = id(new DifferentialViewStateQuery())
->setViewer($viewer)
->withViewerPHIDs(array($viewer_phid))
->withObjectPHIDs(array($object_phid))
->executeOne();
}
if ($storage === null) {
$storage = id(new DifferentialViewState())
->setObjectPHID($object_phid);
if ($viewer_phid !== null) {
$storage->setViewerPHID($viewer_phid);
} else {
$storage->makeEphemeral();
}
}
return $storage;
}
private function saveViewStateStorage() {
if (PhabricatorEnv::isReadOnly()) {
return;
}
$storage = $this->getStorage();
$viewer_phid = $storage->getViewerPHID();
if ($viewer_phid === null) {
return;
}
if (!$storage->getHasModifications()) {
return;
}
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
try {
$storage->save();
} catch (AphrontDuplicateKeyQueryException $ex) {
// We may race another process to save view state. For now, just discard
// our state if we do.
}
unset($unguarded);
}
private function updateHiddenState(PhabricatorChangesetViewState $state) {
$is_hidden = false;
$was_modified = false;
$storage = $this->getStorage();
$changeset = $this->getChangeset();
$entries = $storage->getChangesetPropertyEntries($changeset, 'hidden');
$entries = isort($entries, 'epoch');
if ($entries) {
- $other_key = last_key($entries);
$other_spec = last($entries);
$this_version = (int)$changeset->getDiffID();
$other_version = (int)idx($other_spec, 'diffID');
$other_value = (bool)idx($other_spec, 'value', false);
+ $other_id = (int)idx($other_spec, 'changesetID');
if ($other_value === false) {
$is_hidden = false;
} else if ($other_version >= $this_version) {
$is_hidden = $other_value;
} else {
$viewer = $this->getViewer();
- $other_changeset = id(new DifferentialChangesetQuery())
- ->setViewer($viewer)
- ->withIDs(array($other_key))
- ->executeOne();
+ if ($other_id) {
+ $other_changeset = id(new DifferentialChangesetQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($other_id))
+ ->executeOne();
+ } else {
+ $other_changeset = null;
+ }
$is_modified = false;
if ($other_changeset) {
if (!$changeset->hasSameEffectAs($other_changeset)) {
$is_modified = true;
}
}
$is_hidden = false;
$was_modified = true;
}
}
$state->setHidden($is_hidden);
$state->setModifiedSinceHide($was_modified);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Dec 2, 12:39 AM (21 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
431483
Default Alt Text
(10 KB)

Event Timeline