Path: blob/master/src/infrastructure/diff/viewstate/PhabricatorChangesetViewStateEngine.php
12242 views
<?php12final class PhabricatorChangesetViewStateEngine3extends Phobject {45private $viewer;6private $objectPHID;7private $changeset;8private $storage;910public function setViewer(PhabricatorUser $viewer) {11$this->viewer = $viewer;12return $this;13}1415public function getViewer() {16return $this->viewer;17}1819public function setObjectPHID($object_phid) {20$this->objectPHID = $object_phid;21return $this;22}2324public function getObjectPHID() {25return $this->objectPHID;26}2728public function setChangeset(DifferentialChangeset $changeset) {29$this->changeset = $changeset;30return $this;31}3233public function getChangeset() {34return $this->changeset;35}3637public function newViewStateFromRequest(AphrontRequest $request) {38$storage = $this->loadViewStateStorage();3940$this->setStorage($storage);4142$highlight = $request->getStr('highlight');43if ($highlight !== null) {44$this->setChangesetProperty('highlight', $highlight);45}4647$encoding = $request->getStr('encoding');48if ($encoding !== null) {49$this->setChangesetProperty('encoding', $encoding);50}5152$engine = $request->getStr('engine');53if ($engine !== null) {54$this->setChangesetProperty('engine', $engine);55}5657$renderer = $request->getStr('renderer');58if ($renderer !== null) {59$this->setChangesetProperty('renderer', $renderer);60}6162$hidden = $request->getStr('hidden');63if ($hidden !== null) {64$this->setChangesetProperty('hidden', (int)$hidden);65}6667$this->saveViewStateStorage();6869$state = new PhabricatorChangesetViewState();7071$highlight_language = $this->getChangesetProperty('highlight');72$state->setHighlightLanguage($highlight_language);7374$encoding = $this->getChangesetProperty('encoding');75$state->setCharacterEncoding($encoding);7677$document_engine = $this->getChangesetProperty('engine');78$state->setDocumentEngineKey($document_engine);7980$renderer = $this->getChangesetProperty('renderer');81$state->setRendererKey($renderer);8283$this->updateHiddenState($state);8485// This is the client-selected default renderer based on viewport86// dimensions.8788$device_key = $request->getStr('device');89if ($device_key !== null) {90$state->setDefaultDeviceRendererKey($device_key);91}9293$discard_response = $request->getStr('discard');94if ($discard_response !== null) {95$state->setDiscardResponse(true);96}9798return $state;99}100101private function setStorage(DifferentialViewState $storage) {102$this->storage = $storage;103return $this;104}105106private function getStorage() {107return $this->storage;108}109110private function setChangesetProperty(111$key,112$value) {113114$storage = $this->getStorage();115$changeset = $this->getChangeset();116117$storage->setChangesetProperty($changeset, $key, $value);118}119120private function getChangesetProperty(121$key,122$default = null) {123124$storage = $this->getStorage();125$changeset = $this->getChangeset();126127return $storage->getChangesetProperty($changeset, $key, $default);128}129130private function loadViewStateStorage() {131$viewer = $this->getViewer();132133$object_phid = $this->getObjectPHID();134$viewer_phid = $viewer->getPHID();135136$storage = null;137138if ($viewer_phid !== null) {139$storage = id(new DifferentialViewStateQuery())140->setViewer($viewer)141->withViewerPHIDs(array($viewer_phid))142->withObjectPHIDs(array($object_phid))143->executeOne();144}145146if ($storage === null) {147$storage = id(new DifferentialViewState())148->setObjectPHID($object_phid);149150if ($viewer_phid !== null) {151$storage->setViewerPHID($viewer_phid);152} else {153$storage->makeEphemeral();154}155}156157return $storage;158}159160private function saveViewStateStorage() {161if (PhabricatorEnv::isReadOnly()) {162return;163}164165$storage = $this->getStorage();166167$viewer_phid = $storage->getViewerPHID();168if ($viewer_phid === null) {169return;170}171172if (!$storage->getHasModifications()) {173return;174}175176$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();177178try {179$storage->save();180} catch (AphrontDuplicateKeyQueryException $ex) {181// We may race another process to save view state. For now, just discard182// our state if we do.183}184185unset($unguarded);186}187188private function updateHiddenState(PhabricatorChangesetViewState $state) {189$is_hidden = false;190$was_modified = false;191192$storage = $this->getStorage();193$changeset = $this->getChangeset();194195$entries = $storage->getChangesetPropertyEntries($changeset, 'hidden');196$entries = isort($entries, 'epoch');197198if ($entries) {199$other_spec = last($entries);200201$this_version = (int)$changeset->getDiffID();202$other_version = (int)idx($other_spec, 'diffID');203$other_value = (bool)idx($other_spec, 'value', false);204$other_id = (int)idx($other_spec, 'changesetID');205206if ($other_value === false) {207$is_hidden = false;208} else if ($other_version >= $this_version) {209$is_hidden = $other_value;210} else {211$viewer = $this->getViewer();212213if ($other_id) {214$other_changeset = id(new DifferentialChangesetQuery())215->setViewer($viewer)216->withIDs(array($other_id))217->executeOne();218} else {219$other_changeset = null;220}221222$is_modified = false;223if ($other_changeset) {224if (!$changeset->hasSameEffectAs($other_changeset)) {225$is_modified = true;226}227}228229$is_hidden = false;230$was_modified = true;231}232}233234$state->setHidden($is_hidden);235$state->setModifiedSinceHide($was_modified);236}237238}239240241