protected function applyBuiltinExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PhabricatorTransactions::TYPE_INLINESTATE: $table = new DifferentialTransactionComment(); $conn_w = $table->establishConnection('w'); foreach ($xaction->getNewValue() as $phid => $state) { queryfx($conn_w, 'UPDATE %T SET fixedState = %s WHERE phid = %s', $table->getTableName(), $state, $phid); } break; } return parent::applyBuiltinExternalTransaction($object, $xaction); }
protected function applyBuiltinExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PhabricatorTransactions::TYPE_EDGE: $edge_type = $xaction->getMetadataValue('edge:type'); switch ($edge_type) { case PhabricatorProjectProjectHasMemberEdgeType::EDGECONST: case PhabricatorObjectHasWatcherEdgeType::EDGECONST: $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); // When adding members or watchers, we add subscriptions. $add = array_keys(array_diff_key($new, $old)); // When removing members, we remove their subscription too. // When unwatching, we leave subscriptions, since it's fine to be // subscribed to a project but not be a member of it. $edge_const = PhabricatorProjectProjectHasMemberEdgeType::EDGECONST; if ($edge_type == $edge_const) { $rem = array_keys(array_diff_key($old, $new)); } else { $rem = array(); } // NOTE: The subscribe is "explicit" because there's no implicit // unsubscribe, so Join -> Leave -> Join doesn't resubscribe you // if we use an implicit subscribe, even though you never willfully // unsubscribed. Not sure if adding implicit unsubscribe (which // would not write the unsubscribe row) is justified to deal with // this, which is a fairly weird edge case and pretty arguable both // ways. // Subscriptions caused by watches should also clearly be explicit, // and that case is unambiguous. id(new PhabricatorSubscriptionsEditor())->setActor($this->requireActor())->setObject($object)->subscribeExplicit($add)->unsubscribe($rem)->save(); if ($rem) { // When removing members, also remove any watches on the project. $edge_editor = new PhabricatorEdgeEditor(); foreach ($rem as $rem_phid) { $edge_editor->removeEdge($object->getPHID(), PhabricatorObjectHasWatcherEdgeType::EDGECONST, $rem_phid); } $edge_editor->save(); } break; } break; } return parent::applyBuiltinExternalTransaction($object, $xaction); }