protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PhabricatorMacroTransaction::TYPE_FILE: case PhabricatorMacroTransaction::TYPE_AUDIO: // When changing a macro's image or audio, attach the underlying files // to the macro (and detach the old files). $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); $all = array(); if ($old) { $all[] = $old; } if ($new) { $all[] = $new; } $files = id(new PhabricatorFileQuery())->setViewer($this->requireActor())->withPHIDs($all)->execute(); $files = mpull($files, null, 'getPHID'); $old_file = idx($files, $old); if ($old_file) { $old_file->detachFromObject($object->getPHID()); } $new_file = idx($files, $new); if ($new_file) { $new_file->attachToObject($object->getPHID()); } break; } }
protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case AlmanacDeviceTransaction::TYPE_NAME: return; case AlmanacDeviceTransaction::TYPE_INTERFACE: $old = $xaction->getOldValue(); if ($old) { $interface = id(new AlmanacInterfaceQuery())->setViewer($this->requireActor())->withIDs(array($old['id']))->executeOne(); if (!$interface) { throw new Exception(pht('Unable to load interface!')); } } else { $interface = AlmanacInterface::initializeNewInterface()->setDevicePHID($object->getPHID()); } $new = $xaction->getNewValue(); if ($new) { $interface->setNetworkPHID($new['networkPHID'])->setAddress($new['address'])->setPort((int) $new['port']); if (idx($new, 'phid')) { $interface->setPHID($new['phid']); } $interface->save(); } else { $interface->delete(); } return; } return parent::applyCustomExternalTransaction($object, $xaction); }
protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PhabricatorTransactions::TYPE_COMMENT: case PhabricatorTransactions::TYPE_SUBSCRIBERS: case PhabricatorTransactions::TYPE_EDGE: case PhabricatorAuditActionConstants::ACTION: case PhabricatorAuditActionConstants::INLINE: return; case PhabricatorAuditActionConstants::ADD_AUDITORS: $new = $xaction->getNewValue(); if (!is_array($new)) { $new = array(); } $old = $xaction->getOldValue(); if (!is_array($old)) { $old = array(); } $add = array_diff_key($new, $old); $actor = $this->requireActor(); $requests = $object->getAudits(); $requests = mpull($requests, null, 'getAuditorPHID'); foreach ($add as $phid) { if (isset($requests[$phid])) { continue; } $audit_requested = PhabricatorAuditStatusConstants::AUDIT_REQUESTED; $requests[] = id(new PhabricatorRepositoryAuditRequest())->setCommitPHID($object->getPHID())->setAuditorPHID($phid)->setAuditStatus($audit_requested)->setAuditReasons(array('Added by ' . $actor->getUsername()))->save(); } $object->attachAudits($requests); return; } return parent::applyCustomExternalTransaction($object, $xaction); }
protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case AlmanacBindingTransaction::TYPE_DISABLE: return; case AlmanacBindingTransaction::TYPE_INTERFACE: $interface_phids = array(); $interface_phids[] = $xaction->getOldValue(); $interface_phids[] = $xaction->getNewValue(); $interface_phids = array_filter($interface_phids); $interface_phids = array_unique($interface_phids); $interfaces = id(new AlmanacInterfaceQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withPHIDs($interface_phids)->execute(); $device_phids = array(); foreach ($interfaces as $interface) { $device_phids[] = $interface->getDevicePHID(); } $device_phids = array_unique($device_phids); $devices = id(new AlmanacDeviceQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withPHIDs($device_phids)->execute(); foreach ($devices as $device) { $device->rebuildClusterBindingStatus(); } return; } return parent::applyCustomExternalTransaction($object, $xaction); }
public function getApplicationTransactionTitleForFeed(PhabricatorApplicationTransaction $xaction) { $object_phid = $xaction->getObjectPHID(); $author_phid = $xaction->getAuthorPHID(); $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); return pht('%s updated the blame revision for %s.', $xaction->renderHandleLink($author_phid), $xaction->renderHandleLink($object_phid)); }
public function getApplicationTransactionTitle(PhabricatorApplicationTransaction $xaction) { $author_phid = $xaction->getAuthorPHID(); $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); if ($new) { return pht('%s checked %s.', $xaction->renderHandleLink($author_phid), $this->getFieldName()); } else { return pht('%s unchecked %s.', $xaction->renderHandleLink($author_phid), $this->getFieldName()); } }
public function getApplicationTransactionTitleForFeed(PhabricatorApplicationTransaction $xaction, PhabricatorFeedStory $story) { $object_phid = $xaction->getObjectPHID(); $author_phid = $xaction->getAuthorPHID(); $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); if (strlen($old)) { return pht('%s retitled %s, from "%s" to "%s".', $xaction->renderHandleLink($author_phid), $xaction->renderHandleLink($object_phid), $old, $new); } else { return pht('%s created %s.', $xaction->renderHandleLink($author_phid), $xaction->renderHandleLink($object_phid)); } }
public function getApplicationTransactionTitleForFeed(PhabricatorApplicationTransaction $xaction, PhabricatorFeedStory $story) { $object_phid = $xaction->getObjectPHID(); $author_phid = $xaction->getAuthorPHID(); $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); if ($old) { return pht('%s updated the repository for %s from %s to %s.', $xaction->renderHandleLink($author_phid), $xaction->renderHandleLink($object_phid), $xaction->renderHandleLink($old), $xaction->renderHandleLink($new)); } else { return pht('%s set the repository for %s to %s.', $xaction->renderHandleLink($author_phid), $xaction->renderHandleLink($object_phid), $xaction->renderHandleLink($new)); } }
public function getApplicationTransactionHasEffect(PhabricatorApplicationTransaction $xaction) { $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); if (!strlen($old) && strlen($new)) { return true; } else { if (strlen($old) && !strlen($new)) { return true; } else { return (int) $old !== (int) $new; } } }
protected function transactionHasEffect(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); $type = $xaction->getTransactionType(); switch ($type) { case PhabricatorConfigTransaction::TYPE_EDIT: // If an edit deletes an already-deleted entry, no-op it. if (idx($old, 'deleted') && idx($new, 'deleted')) { return false; } break; } return parent::transactionHasEffect($object, $xaction); }
public function getApplicationTransactionTitle(PhabricatorApplicationTransaction $xaction) { $author_phid = $xaction->getAuthorPHID(); $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); if ($old && !$new) { return pht('%s removed %s as %s.', $xaction->renderHandleLink($author_phid), $xaction->renderHandleLink($old), $this->getFieldName()); } else { if ($new && !$old) { return pht('%s set %s to %s.', $xaction->renderHandleLink($author_phid), $this->getFieldName(), $xaction->renderHandleLink($new)); } else { return pht('%s changed %s from %s to %s.', $xaction->renderHandleLink($author_phid), $this->getFieldName(), $xaction->renderHandleLink($old), $xaction->renderHandleLink($new)); } } }
public function applyApplicationTransactionExternalEffects(PhabricatorApplicationTransaction $xaction) { $object_phid = $xaction->getObjectPHID(); $old = $this->decodeValue($xaction->getOldValue()); $new = $this->decodeValue($xaction->getNewValue()); $old_phids = array_fuse($old); $new_phids = array_fuse($new); $rem_phids = array_diff_key($old_phids, $new_phids); $add_phids = array_diff_key($new_phids, $old_phids); $altered_phids = $rem_phids + $add_phids; if (!$altered_phids) { return; } $authorizations = id(new DrydockAuthorizationQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withObjectPHIDs(array($object_phid))->withBlueprintPHIDs($altered_phids)->execute(); $authorizations = mpull($authorizations, null, 'getBlueprintPHID'); $state_active = DrydockAuthorization::OBJECTAUTH_ACTIVE; $state_inactive = DrydockAuthorization::OBJECTAUTH_INACTIVE; $state_requested = DrydockAuthorization::BLUEPRINTAUTH_REQUESTED; // Disable the object side of the authorization for any existing // authorizations. foreach ($rem_phids as $rem_phid) { $authorization = idx($authorizations, $rem_phid); if (!$authorization) { continue; } $authorization->setObjectAuthorizationState($state_inactive)->save(); } // For new authorizations, either add them or reactivate them depending // on the current state. foreach ($add_phids as $add_phid) { $needs_update = false; $authorization = idx($authorizations, $add_phid); if (!$authorization) { $authorization = id(new DrydockAuthorization())->setObjectPHID($object_phid)->setObjectAuthorizationState($state_active)->setBlueprintPHID($add_phid)->setBlueprintAuthorizationState($state_requested); $needs_update = true; } else { $current_state = $authorization->getObjectAuthorizationState(); if ($current_state != $state_active) { $authorization->setObjectAuthorizationState($state_active); $needs_update = true; } } if ($needs_update) { $authorization->save(); } } }
protected function transactionHasEffect(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); switch ($xaction->getTransactionType()) { case PhabricatorSlowvoteTransaction::TYPE_RESPONSES: if ($old === null) { return true; } return (int) $old !== (int) $new; case PhabricatorSlowvoteTransaction::TYPE_SHUFFLE: if ($old === null) { return true; } return (bool) $old !== (bool) $new; } return parent::transactionHasEffect($object, $xaction); }
protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case ManiphestTransaction::TYPE_PROJECT_COLUMN: $board_phid = idx($xaction->getNewValue(), 'projectPHID'); if (!$board_phid) { throw new Exception(pht("Expected '%s' in column transaction.", 'projectPHID')); } $old_phids = idx($xaction->getOldValue(), 'columnPHIDs', array()); $new_phids = idx($xaction->getNewValue(), 'columnPHIDs', array()); if (count($new_phids) !== 1) { throw new Exception(pht("Expected exactly one '%s' in column transaction.", 'columnPHIDs')); } $columns = id(new PhabricatorProjectColumnQuery())->setViewer($this->requireActor())->withPHIDs($new_phids)->execute(); $columns = mpull($columns, null, 'getPHID'); $positions = id(new PhabricatorProjectColumnPositionQuery())->setViewer($this->requireActor())->withObjectPHIDs(array($object->getPHID()))->withBoardPHIDs(array($board_phid))->execute(); $before_phid = idx($xaction->getNewValue(), 'beforePHID'); $after_phid = idx($xaction->getNewValue(), 'afterPHID'); if (!$before_phid && !$after_phid && $old_phids == $new_phids) { // If we are not moving the object between columns and also not // reordering the position, this is a move on some other order // (like priority). We can leave the positions untouched and just // bail, there's no work to be done. return; } // Otherwise, we're either moving between columns or adjusting the // object's position in the "natural" ordering, so we do need to update // some rows. // Remove all existing column positions on the board. foreach ($positions as $position) { $position->delete(); } // Add the new column positions. foreach ($new_phids as $phid) { $column = idx($columns, $phid); if (!$column) { throw new Exception(pht('No such column "%s" exists!', $phid)); } // Load the other object positions in the column. Note that we must // skip implicit column creation to avoid generating a new position // if the target column is a backlog column. $other_positions = id(new PhabricatorProjectColumnPositionQuery())->setViewer($this->requireActor())->withColumns(array($column))->withBoardPHIDs(array($board_phid))->setSkipImplicitCreate(true)->execute(); $other_positions = msort($other_positions, 'getOrderingKey'); // Set up the new position object. We're going to figure out the // right sequence number and then persist this object with that // sequence number. $new_position = id(new PhabricatorProjectColumnPosition())->setBoardPHID($board_phid)->setColumnPHID($column->getPHID())->setObjectPHID($object->getPHID()); $updates = array(); $sequence = 0; // If we're just dropping this into the column without any specific // position information, put it at the top. if (!$before_phid && !$after_phid) { $new_position->setSequence($sequence)->save(); $sequence++; } foreach ($other_positions as $position) { $object_phid = $position->getObjectPHID(); // If this is the object we're moving before and we haven't // saved yet, insert here. if ($before_phid == $object_phid && !$new_position->getID()) { $new_position->setSequence($sequence)->save(); $sequence++; } // This object goes here in the sequence; we might need to update // the row. if ($sequence != $position->getSequence()) { $updates[$position->getID()] = $sequence; } $sequence++; // If this is the object we're moving after and we haven't saved // yet, insert here. if ($after_phid == $object_phid && !$new_position->getID()) { $new_position->setSequence($sequence)->save(); $sequence++; } } // We should have found a place to put it. if (!$new_position->getID()) { throw new Exception(pht('Unable to find a place to insert object on column!')); } // If we changed other objects' column positions, bulk reorder them. if ($updates) { $position = new PhabricatorProjectColumnPosition(); $conn_w = $position->establishConnection('w'); $pairs = array(); foreach ($updates as $id => $sequence) { // This is ugly because MySQL gets upset with us if it is // configured strictly and we attempt inserts which can't work. // We'll never actually do these inserts since they'll always // collide (triggering the ON DUPLICATE KEY logic), so we just // provide dummy values in order to get there. $pairs[] = qsprintf($conn_w, '(%d, %d, "", "", "")', $id, $sequence); } queryfx($conn_w, 'INSERT INTO %T (id, sequence, boardPHID, columnPHID, objectPHID) VALUES %Q ON DUPLICATE KEY UPDATE sequence = VALUES(sequence)', $position->getTableName(), implode(', ', $pairs)); } } break; default: break; } }
private function applyInverseEdgeTransactions(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction, $inverse_type) { $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); $add = array_keys(array_diff_key($new, $old)); $rem = array_keys(array_diff_key($old, $new)); $add = array_fuse($add); $rem = array_fuse($rem); $all = $add + $rem; $nodes = id(new PhabricatorObjectQuery())->setViewer($this->requireActor())->withPHIDs($all)->execute(); foreach ($nodes as $node) { if (!$node instanceof PhabricatorApplicationTransactionInterface) { continue; } $editor = $node->getApplicationTransactionEditor(); $template = $node->getApplicationTransactionTemplate(); $target = $node->getApplicationTransactionObject(); if (isset($add[$node->getPHID()])) { $edge_edit_type = '+'; } else { $edge_edit_type = '-'; } $template->setTransactionType($xaction->getTransactionType())->setMetadataValue('edge:type', $inverse_type)->setNewValue(array($edge_edit_type => array($object->getPHID() => $object->getPHID()))); $editor->setContinueOnNoEffect(true)->setContinueOnMissingFields(true)->setParentMessageID($this->getParentMessageID())->setIsInverseEdgeEditor(true)->setActor($this->requireActor())->setActingAsPHID($this->getActingAsPHID())->setContentSource($this->getContentSource()); $editor->applyTransactions($target, array($template)); } }
protected function requireCapabilities(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PhabricatorProjectTransaction::TYPE_NAME: case PhabricatorProjectTransaction::TYPE_STATUS: case PhabricatorProjectTransaction::TYPE_IMAGE: case PhabricatorProjectTransaction::TYPE_ICON: case PhabricatorProjectTransaction::TYPE_COLOR: PhabricatorPolicyFilter::requireCapability($this->requireActor(), $object, PhabricatorPolicyCapability::CAN_EDIT); return; case PhabricatorProjectTransaction::TYPE_LOCKED: PhabricatorPolicyFilter::requireCapability($this->requireActor(), newv($this->getEditorApplicationClass(), array()), ProjectCanLockProjectsCapability::CAPABILITY); return; case PhabricatorTransactions::TYPE_EDGE: switch ($xaction->getMetadataValue('edge:type')) { case PhabricatorProjectProjectHasMemberEdgeType::EDGECONST: $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); $add = array_keys(array_diff_key($new, $old)); $rem = array_keys(array_diff_key($old, $new)); $actor_phid = $this->requireActor()->getPHID(); $is_join = $add === array($actor_phid) && !$rem; $is_leave = $rem === array($actor_phid) && !$add; if ($is_join) { // You need CAN_JOIN to join a project. PhabricatorPolicyFilter::requireCapability($this->requireActor(), $object, PhabricatorPolicyCapability::CAN_JOIN); } else { if ($is_leave) { // You usually don't need any capabilities to leave a project. if ($object->getIsMembershipLocked()) { // you must be able to edit though to leave locked projects PhabricatorPolicyFilter::requireCapability($this->requireActor(), $object, PhabricatorPolicyCapability::CAN_EDIT); } } else { // You need CAN_EDIT to change members other than yourself. PhabricatorPolicyFilter::requireCapability($this->requireActor(), $object, PhabricatorPolicyCapability::CAN_EDIT); } } return; } break; } return parent::requireCapabilities($object, $xaction); }
protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PhabricatorAuditActionConstants::ACTION: case PhabricatorAuditTransaction::TYPE_COMMIT: return; case PhabricatorAuditActionConstants::INLINE: $reply = $xaction->getComment()->getReplyToComment(); if ($reply && !$reply->getHasReplies()) { $reply->setHasReplies(1)->save(); } return; case PhabricatorAuditActionConstants::ADD_AUDITORS: $new = $xaction->getNewValue(); if (!is_array($new)) { $new = array(); } $old = $xaction->getOldValue(); if (!is_array($old)) { $old = array(); } $add = array_diff_key($new, $old); $actor = $this->requireActor(); $requests = $object->getAudits(); $requests = mpull($requests, null, 'getAuditorPHID'); foreach ($add as $phid) { if (isset($requests[$phid])) { continue; } if ($this->getIsHeraldEditor()) { $audit_requested = $xaction->getMetadataValue('auditStatus'); $audit_reason_map = $xaction->getMetadataValue('auditReasonMap'); $audit_reason = $audit_reason_map[$phid]; } else { $audit_requested = PhabricatorAuditStatusConstants::AUDIT_REQUESTED; $audit_reason = $this->getAuditReasons($phid); } $requests[] = id(new PhabricatorRepositoryAuditRequest())->setCommitPHID($object->getPHID())->setAuditorPHID($phid)->setAuditStatus($audit_requested)->setAuditReasons($audit_reason)->save(); } $object->attachAudits($requests); return; } return parent::applyCustomExternalTransaction($object, $xaction); }
public function getApplicationTransactionChangeDetails(PhabricatorApplicationTransaction $xaction, PhabricatorUser $viewer) { return $xaction->renderTextCorpusChangeDetails($viewer, $xaction->getOldValue(), $xaction->getNewValue()); }
protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PholioTransactionType::TYPE_IMAGE_FILE: $old_map = array_fuse($xaction->getOldValue()); $new_map = array_fuse($xaction->getNewValue()); $obsolete_map = array_diff_key($old_map, $new_map); $images = $object->getImages(); foreach ($images as $seq => $image) { if (isset($obsolete_map[$image->getPHID()])) { $image->setIsObsolete(1); $image->save(); unset($images[$seq]); } } $object->attachImages($images); break; case PholioTransactionType::TYPE_IMAGE_REPLACE: $old = $xaction->getOldValue(); $images = $object->getImages(); foreach ($images as $seq => $image) { if ($image->getPHID() == $old) { $image->setIsObsolete(1); $image->save(); unset($images[$seq]); } } $object->attachImages($images); break; case PholioTransactionType::TYPE_IMAGE_NAME: $image = $this->getImageForXaction($object, $xaction); $value = (string) head($xaction->getNewValue()); $image->setName($value); $image->save(); break; case PholioTransactionType::TYPE_IMAGE_DESCRIPTION: $image = $this->getImageForXaction($object, $xaction); $value = (string) head($xaction->getNewValue()); $image->setDescription($value); $image->save(); break; case PholioTransactionType::TYPE_IMAGE_SEQUENCE: $image = $this->getImageForXaction($object, $xaction); $value = (int) head($xaction->getNewValue()); $image->setSequence($value); $image->save(); break; case PhabricatorTransactions::TYPE_EDGE: return; } }
public function getApplicationTransactionTitle(PhabricatorApplicationTransaction $xaction) { $author_phid = $xaction->getAuthorPHID(); $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); $viewer = $this->getViewer(); $old_date = null; if ($old) { $old_date = phabricator_datetime($old, $viewer); } $new_date = null; if ($new) { $new_date = phabricator_datetime($new, $viewer); } if (!$old) { return pht('%s set %s to %s.', $xaction->renderHandleLink($author_phid), $this->getFieldName(), $new_date); } else { if (!$new) { return pht('%s removed %s.', $xaction->renderHandleLink($author_phid), $this->getFieldName()); } else { return pht('%s changed %s from %s to %s.', $xaction->renderHandleLink($author_phid), $this->getFieldName(), $old_date, $new_date); } } }
protected function transactionHasEffect(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); $type = $xaction->getTransactionType(); switch ($type) { } return parent::transactionHasEffect($object, $xaction); }
protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case ConpherenceTransaction::TYPE_FILES: $editor = new PhabricatorEdgeEditor(); $edge_type = PhabricatorObjectHasFileEdgeType::EDGECONST; $old = array_fill_keys($xaction->getOldValue(), true); $new = array_fill_keys($xaction->getNewValue(), true); $add_edges = array_keys(array_diff_key($new, $old)); $remove_edges = array_keys(array_diff_key($old, $new)); foreach ($add_edges as $file_phid) { $editor->addEdge($object->getPHID(), $edge_type, $file_phid); } foreach ($remove_edges as $file_phid) { $editor->removeEdge($object->getPHID(), $edge_type, $file_phid); } $editor->save(); break; case ConpherenceTransaction::TYPE_PARTICIPANTS: if ($this->getIsNewObject()) { continue; } $participants = $object->getParticipants(); $old_map = array_fuse($xaction->getOldValue()); $new_map = array_fuse($xaction->getNewValue()); $remove = array_keys(array_diff_key($old_map, $new_map)); foreach ($remove as $phid) { $remove_participant = $participants[$phid]; $remove_participant->delete(); unset($participants[$phid]); } $add = array_keys(array_diff_key($new_map, $old_map)); foreach ($add as $phid) { if ($phid == $this->getActor()->getPHID()) { $status = ConpherenceParticipationStatus::UP_TO_DATE; $message_count = $object->getMessageCount(); } else { $status = ConpherenceParticipationStatus::BEHIND; $message_count = 0; } $participants[$phid] = id(new ConpherenceParticipant())->setConpherencePHID($object->getPHID())->setParticipantPHID($phid)->setParticipationStatus($status)->setDateTouched(time())->setBehindTransactionPHID($xaction->getPHID())->setSeenMessageCount($message_count)->save(); } $object->attachParticipants($participants); break; } }
public function getApplicationTransactionTitle(PhabricatorApplicationTransaction $xaction) { $author_phid = $xaction->getAuthorPHID(); $old = $this->decodeValue($xaction->getOldValue()); $new = $this->decodeValue($xaction->getNewValue()); $add = array_diff($new, $old); $rem = array_diff($old, $new); if ($add && !$rem) { return pht('%s updated %s, added %d: %s.', $xaction->renderHandleLink($author_phid), $this->getFieldName(), new PhutilNumber(count($add)), $xaction->renderHandleList($add)); } else { if ($rem && !$add) { return pht('%s updated %s, removed %d: %s.', $xaction->renderHandleLink($author_phid), $this->getFieldName(), new PhutilNumber(count($rem)), $xaction->renderHandleList($rem)); } else { return pht('%s updated %s, added %d: %s; removed %d: %s.', $xaction->renderHandleLink($author_phid), $this->getFieldName(), new PhutilNumber(count($add)), $xaction->renderHandleList($add), new PhutilNumber(count($rem)), $xaction->renderHandleList($rem)); } } }
protected function applyCustomInternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PonderQuestionTransaction::TYPE_TITLE: $object->setTitle($xaction->getNewValue()); break; case PonderQuestionTransaction::TYPE_CONTENT: $object->setContent($xaction->getNewValue()); break; case PonderQuestionTransaction::TYPE_STATUS: $object->setStatus($xaction->getNewValue()); break; case PonderQuestionTransaction::TYPE_ANSWERS: $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); $add = array_diff_key($new, $old); $rem = array_diff_key($old, $new); $count = $object->getAnswerCount(); $count += count($add); $count -= count($rem); $object->setAnswerCount($count); break; } }
protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case ManiphestTransaction::TYPE_PARENT: $parent_phid = $xaction->getNewValue(); $parent_type = ManiphestTaskDependsOnTaskEdgeType::EDGECONST; $task_phid = $object->getPHID(); id(new PhabricatorEdgeEditor())->addEdge($parent_phid, $parent_type, $task_phid)->save(); break; case ManiphestTransaction::TYPE_PROJECT_COLUMN: $board_phid = idx($xaction->getNewValue(), 'projectPHID'); if (!$board_phid) { throw new Exception(pht("Expected '%s' in column transaction.", 'projectPHID')); } $old_phids = idx($xaction->getOldValue(), 'columnPHIDs', array()); $new_phids = idx($xaction->getNewValue(), 'columnPHIDs', array()); if (count($new_phids) !== 1) { throw new Exception(pht("Expected exactly one '%s' in column transaction.", 'columnPHIDs')); } $before_phid = idx($xaction->getNewValue(), 'beforePHID'); $after_phid = idx($xaction->getNewValue(), 'afterPHID'); if (!$before_phid && !$after_phid && $old_phids == $new_phids) { // If we are not moving the object between columns and also not // reordering the position, this is a move on some other order // (like priority). We can leave the positions untouched and just // bail, there's no work to be done. return; } // Otherwise, we're either moving between columns or adjusting the // object's position in the "natural" ordering, so we do need to update // some rows. $object_phid = $object->getPHID(); // We're doing layout with the ominpotent viewer to make sure we don't // remove positions in columns that exist, but which the actual actor // can't see. $omnipotent_viewer = PhabricatorUser::getOmnipotentUser(); $select_phids = array($board_phid); $descendants = id(new PhabricatorProjectQuery())->setViewer($omnipotent_viewer)->withAncestorProjectPHIDs($select_phids)->execute(); foreach ($descendants as $descendant) { $select_phids[] = $descendant->getPHID(); } $board_tasks = id(new ManiphestTaskQuery())->setViewer($omnipotent_viewer)->withEdgeLogicPHIDs(PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, PhabricatorQueryConstraint::OPERATOR_ANCESTOR, array($select_phids))->execute(); $object_phids = mpull($board_tasks, 'getPHID'); $object_phids[] = $object_phid; $engine = id(new PhabricatorBoardLayoutEngine())->setViewer($omnipotent_viewer)->setBoardPHIDs(array($board_phid))->setObjectPHIDs($object_phids)->executeLayout(); // TODO: This logic needs to be revised if we legitimately support // multiple column positions. // NOTE: When a task is newly created, it's implicitly added to the // backlog but we don't currently record that in the "$old_phids". Just // clean it up for now. $columns = $engine->getObjectColumns($board_phid, $object_phid); foreach ($columns as $column) { $engine->queueRemovePosition($board_phid, $column->getPHID(), $object_phid); } // Remove all existing column positions on the board. foreach ($old_phids as $column_phid) { $engine->queueRemovePosition($board_phid, $column_phid, $object_phid); } // Add new positions. foreach ($new_phids as $column_phid) { if ($before_phid) { $engine->queueAddPositionBefore($board_phid, $column_phid, $object_phid, $before_phid); } else { if ($after_phid) { $engine->queueAddPositionAfter($board_phid, $column_phid, $object_phid, $after_phid); } else { $engine->queueAddPosition($board_phid, $column_phid, $object_phid); } } } $engine->applyPositionUpdates(); break; default: break; } }
public function getApplicationTransactionTitle(PhabricatorApplicationTransaction $xaction) { $old = $xaction->getOldValue(); if (!is_array($old)) { $old = array(); } $new = $xaction->getNewValue(); if (!is_array($new)) { $new = array(); } $add = array_diff($new, $old); $rem = array_diff($old, $new); $author_phid = $xaction->getAuthorPHID(); if ($add && $rem) { return pht('%s updated JIRA issue(s): added %d %s; removed %d %s.', $xaction->renderHandleLink($author_phid), phutil_count($add), implode(', ', $add), phutil_count($rem), implode(', ', $rem)); } else { if ($add) { return pht('%s added %d JIRA issue(s): %s.', $xaction->renderHandleLink($author_phid), phutil_count($add), implode(', ', $add)); } else { if ($rem) { return pht('%s removed %d JIRA issue(s): %s.', $xaction->renderHandleLink($author_phid), phutil_count($rem), implode(', ', $rem)); } } } return parent::getApplicationTransactionTitle($xaction); }
public function shouldHideInApplicationTransactions(PhabricatorApplicationTransaction $xaction) { return $xaction->getOldValue() === null; }
protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PhabricatorOwnersPackageTransaction::TYPE_NAME: case PhabricatorOwnersPackageTransaction::TYPE_PRIMARY: case PhabricatorOwnersPackageTransaction::TYPE_DESCRIPTION: case PhabricatorOwnersPackageTransaction::TYPE_AUDITING: return; case PhabricatorOwnersPackageTransaction::TYPE_OWNERS: $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); // TODO: needOwners this $owners = $object->loadOwners(); $owners = mpull($owners, null, 'getUserPHID'); $rem = array_diff($old, $new); foreach ($rem as $phid) { if (isset($owners[$phid])) { $owners[$phid]->delete(); unset($owners[$phid]); } } $add = array_diff($new, $old); foreach ($add as $phid) { $owners[$phid] = id(new PhabricatorOwnersOwner())->setPackageID($object->getID())->setUserPHID($phid)->save(); } // TODO: Attach owners here return; case PhabricatorOwnersPackageTransaction::TYPE_PATHS: $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); // TODO: needPaths this $paths = $object->loadPaths(); $diffs = PhabricatorOwnersPath::getTransactionValueChanges($old, $new); list($rem, $add) = $diffs; $set = PhabricatorOwnersPath::getSetFromTransactionValue($rem); foreach ($paths as $path) { $ref = $path->getRef(); if (PhabricatorOwnersPath::isRefInSet($ref, $set)) { $path->delete(); } } foreach ($add as $ref) { $path = PhabricatorOwnersPath::newFromRef($ref)->setPackageID($object->getID())->save(); } return; } return parent::applyCustomExternalTransaction($object, $xaction); }
protected function transactionHasEffect(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); switch ($xaction->getTransactionType()) { case PhabricatorTransactions::TYPE_COLUMNS: return (bool) $new; } return parent::transactionHasEffect($object, $xaction); }
protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PhabricatorRepositoryTransaction::TYPE_CREDENTIAL: // Adjust the object <-> credential edge for this repository. $old_phid = $xaction->getOldValue(); $new_phid = $xaction->getNewValue(); $editor = new PhabricatorEdgeEditor(); $edge_type = PhabricatorObjectUsesCredentialsEdgeType::EDGECONST; $src_phid = $object->getPHID(); if ($old_phid) { $editor->removeEdge($src_phid, $edge_type, $old_phid); } if ($new_phid) { $editor->addEdge($src_phid, $edge_type, $new_phid); } $editor->save(); break; case PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS: DrydockAuthorization::applyAuthorizationChanges($this->getActor(), $object->getPHID(), $xaction->getOldValue(), $xaction->getNewValue()); break; } }