public function destroyObject(PhabricatorDestructionEngine $engine, $object) { $src_phid = $object->getPHID(); try { $edges = id(new PhabricatorEdgeQuery())->withSourcePHIDs(array($src_phid))->execute(); } catch (Exception $ex) { // This is (presumably) a "no edges for this PHID type" exception. return; } $editor = new PhabricatorEdgeEditor(); foreach ($edges as $type => $type_edges) { foreach ($type_edges as $src => $src_edges) { foreach ($src_edges as $dst => $edge) { try { $editor->removeEdge($edge['src'], $edge['type'], $edge['dst']); } catch (Exception $ex) { // We can run into an exception while removing the edge if the // edge type no longer exists. This prevents us from figuring out // if there's an inverse type. Just ignore any errors here and // continue, since the best we can do is clean up all the edges // we still have information about. See T11201. phlog($ex); } } } } $editor->save(); }
/** * Edit a transaction's comment. This method effects the required create, * update or delete to set the transaction's comment to the provided comment. */ public function applyEdit(PhabricatorApplicationTransaction $xaction, PhabricatorApplicationTransactionComment $comment) { $this->validateEdit($xaction, $comment); $actor = $this->requireActor(); $comment->setContentSource($this->getContentSource()); $comment->setAuthorPHID($this->getActingAsPHID()); // TODO: This needs to be more sophisticated once we have meta-policies. $comment->setViewPolicy(PhabricatorPolicies::POLICY_PUBLIC); $comment->setEditPolicy($this->getActingAsPHID()); $file_phids = PhabricatorMarkupEngine::extractFilePHIDsFromEmbeddedFiles($actor, array($comment->getContent())); $xaction->openTransaction(); $xaction->beginReadLocking(); if ($xaction->getID()) { $xaction->reload(); } $new_version = $xaction->getCommentVersion() + 1; $comment->setCommentVersion($new_version); $comment->setTransactionPHID($xaction->getPHID()); $comment->save(); $old_comment = $xaction->getComment(); $comment->attachOldComment($old_comment); $xaction->setCommentVersion($new_version); $xaction->setCommentPHID($comment->getPHID()); $xaction->setViewPolicy($comment->getViewPolicy()); $xaction->setEditPolicy($comment->getEditPolicy()); $xaction->save(); $xaction->attachComment($comment); // For comment edits, we need to make sure there are no automagical // transactions like adding mentions or projects. if ($new_version > 1) { $object = id(new PhabricatorObjectQuery())->withPHIDs(array($xaction->getObjectPHID()))->setViewer($this->getActor())->executeOne(); if ($object && $object instanceof PhabricatorApplicationTransactionInterface) { $editor = $object->getApplicationTransactionEditor(); $editor->setActor($this->getActor()); $support_xactions = $editor->getExpandedSupportTransactions($object, $xaction); if ($support_xactions) { $editor->setContentSource($this->getContentSource())->setContinueOnNoEffect(true)->applyTransactions($object, $support_xactions); } } } $xaction->endReadLocking(); $xaction->saveTransaction(); // Add links to any files newly referenced by the edit. if ($file_phids) { $editor = new PhabricatorEdgeEditor(); foreach ($file_phids as $file_phid) { $editor->addEdge($xaction->getObjectPHID(), PhabricatorObjectHasFileEdgeType::EDGECONST, $file_phid); } $editor->save(); } return $this; }
private function destroyEdges($src_phid) { try { $edges = id(new PhabricatorEdgeQuery())->withSourcePHIDs(array($src_phid))->execute(); } catch (Exception $ex) { // This is (presumably) a "no edges for this PHID type" exception. return; } $editor = new PhabricatorEdgeEditor(); foreach ($edges as $type => $type_edges) { foreach ($type_edges as $src => $src_edges) { foreach ($src_edges as $dst => $edge) { $editor->removeEdge($edge['src'], $edge['type'], $edge['dst']); } } } $editor->save(); }
public function destroyObject(PhabricatorDestructionEngine $engine, $object) { $src_phid = $object->getPHID(); try { $edges = id(new PhabricatorEdgeQuery())->withSourcePHIDs(array($src_phid))->execute(); } catch (Exception $ex) { // This is (presumably) a "no edges for this PHID type" exception. return; } $editor = new PhabricatorEdgeEditor(); foreach ($edges as $type => $type_edges) { foreach ($type_edges as $src => $src_edges) { foreach ($src_edges as $dst => $edge) { $editor->removeEdge($edge['src'], $edge['type'], $edge['dst']); } } } $editor->save(); }
public function save() { if (!$this->object) { throw new PhutilInvalidStateException('setObject'); } $actor = $this->requireActor(); $src = $this->object->getPHID(); if ($this->implicitSubscribePHIDs) { $unsub = PhabricatorEdgeQuery::loadDestinationPHIDs($src, PhabricatorObjectHasUnsubscriberEdgeType::EDGECONST); $unsub = array_fill_keys($unsub, true); $this->implicitSubscribePHIDs = array_diff_key($this->implicitSubscribePHIDs, $unsub); } $add = $this->implicitSubscribePHIDs + $this->explicitSubscribePHIDs; $del = $this->unsubscribePHIDs; // If a PHID is marked for both subscription and unsubscription, treat // unsubscription as the stronger action. $add = array_diff_key($add, $del); if ($add || $del) { $u_type = PhabricatorObjectHasUnsubscriberEdgeType::EDGECONST; $s_type = PhabricatorObjectHasSubscriberEdgeType::EDGECONST; $editor = new PhabricatorEdgeEditor(); foreach ($add as $phid => $ignored) { $editor->removeEdge($src, $u_type, $phid); $editor->addEdge($src, $s_type, $phid); } foreach ($del as $phid => $ignored) { $editor->removeEdge($src, $s_type, $phid); $editor->addEdge($src, $u_type, $phid); } $editor->save(); } }
public function save() { if (!$this->object) { throw new Exception('Call setObject() before save()!'); } $actor = $this->requireActor(); $src = $this->object->getPHID(); if ($this->implicitSubscribePHIDs) { $unsub = PhabricatorEdgeQuery::loadDestinationPHIDs($src, PhabricatorEdgeConfig::TYPE_OBJECT_HAS_UNSUBSCRIBER); $unsub = array_fill_keys($unsub, true); $this->implicitSubscribePHIDs = array_diff_key($this->implicitSubscribePHIDs, $unsub); } $add = $this->implicitSubscribePHIDs + $this->explicitSubscribePHIDs; $del = $this->unsubscribePHIDs; // If a PHID is marked for both subscription and unsubscription, treat // unsubscription as the stronger action. $add = array_diff_key($add, $del); if ($add || $del) { $u_type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_UNSUBSCRIBER; $s_type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_SUBSCRIBER; $editor = new PhabricatorEdgeEditor(); foreach ($add as $phid => $ignored) { $editor->removeEdge($src, $u_type, $phid); $editor->addEdge($src, $s_type, $phid); } foreach ($del as $phid => $ignored) { $editor->removeEdge($src, $s_type, $phid); $editor->addEdge($src, $u_type, $phid); } $editor->save(); } }
/** * Edit a transaction's comment. This method effects the required create, * update or delete to set the transaction's comment to the provided comment. */ public function applyEdit(PhabricatorApplicationTransaction $xaction, PhabricatorApplicationTransactionComment $comment) { $this->validateEdit($xaction, $comment); $actor = $this->requireActor(); $comment->setContentSource($this->getContentSource()); $comment->setAuthorPHID($this->getActingAsPHID()); // TODO: This needs to be more sophisticated once we have meta-policies. $comment->setViewPolicy(PhabricatorPolicies::POLICY_PUBLIC); $comment->setEditPolicy($this->getActingAsPHID()); $file_phids = PhabricatorMarkupEngine::extractFilePHIDsFromEmbeddedFiles($actor, array($comment->getContent())); $xaction->openTransaction(); $xaction->beginReadLocking(); if ($xaction->getID()) { $xaction->reload(); } $new_version = $xaction->getCommentVersion() + 1; $comment->setCommentVersion($new_version); $comment->setTransactionPHID($xaction->getPHID()); $comment->save(); $xaction->setCommentVersion($new_version); $xaction->setCommentPHID($comment->getPHID()); $xaction->setViewPolicy($comment->getViewPolicy()); $xaction->setEditPolicy($comment->getEditPolicy()); $xaction->save(); $xaction->endReadLocking(); $xaction->saveTransaction(); // Add links to any files newly referenced by the edit. if ($file_phids) { $editor = new PhabricatorEdgeEditor(); foreach ($file_phids as $file_phid) { $editor->addEdge($xaction->getObjectPHID(), PhabricatorEdgeConfig::TYPE_OBJECT_HAS_FILE, $file_phid); } $editor->save(); } $xaction->attachComment($comment); return $this; }
<?php echo pht('Migrating %s to edges...', 'differential.revisionPHID') . "\n"; $commit_table = new PhabricatorRepositoryCommit(); $data_table = new PhabricatorRepositoryCommitData(); $editor = new PhabricatorEdgeEditor(); $commit_table->establishConnection('w'); $edges = 0; foreach (new LiskMigrationIterator($commit_table) as $commit) { $data = $commit->loadOneRelative($data_table, 'commitID'); if (!$data) { continue; } $revision_phid = $data->getCommitDetail('differential.revisionPHID'); if (!$revision_phid) { continue; } $commit_drev = DiffusionCommitHasRevisionEdgeType::EDGECONST; $editor->addEdge($commit->getPHID(), $commit_drev, $revision_phid); $edges++; if ($edges % 256 == 0) { echo '.'; $editor->save(); $editor = new PhabricatorEdgeEditor(); } } echo '.'; $editor->save(); echo "\n" . pht('Done.') . "\n";
* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ echo "Migrating task dependencies to edges...\n"; foreach (new LiskMigrationIterator(new ManiphestTask()) as $task) { $id = $task->getID(); echo "Task {$id}: "; $deps = $task->getAttachedPHIDs(PhabricatorPHIDConstants::PHID_TYPE_TASK); if (!$deps) { echo "-\n"; continue; } $editor = new PhabricatorEdgeEditor(); $editor->setSuppressEvents(true); foreach ($deps as $dep) { $editor->addEdge($task->getPHID(), PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK, $dep); } $editor->save(); echo "OKAY\n"; } echo "Done.\n";
public function save() { if ($this->getID()) { return parent::save(); } // NOTE: When mail is sent from CLI scripts that run tasks in-process, we // may re-enter this method from within scheduleTask(). The implementation // is intended to avoid anything awkward if we end up reentering this // method. $this->openTransaction(); // Save to generate a mail ID and PHID. $result = parent::save(); // Write the recipient edges. $editor = new PhabricatorEdgeEditor(); $edge_type = PhabricatorMetaMTAMailHasRecipientEdgeType::EDGECONST; $recipient_phids = array_merge($this->getToPHIDs(), $this->getCcPHIDs()); $expanded_phids = $this->expandRecipients($recipient_phids); $all_phids = array_unique(array_merge($recipient_phids, $expanded_phids)); foreach ($all_phids as $curr_phid) { $editor->addEdge($this->getPHID(), $edge_type, $curr_phid); } $editor->save(); // Queue a task to send this mail. $mailer_task = PhabricatorWorker::scheduleTask('PhabricatorMetaMTAWorker', $this->getID(), array('priority' => PhabricatorWorker::PRIORITY_ALERTS)); $this->saveTransaction(); return $result; }
public function applyApplicationTransactionExternalEffects(PhabricatorApplicationTransaction $xaction) { // Update the CustomField storage. parent::applyApplicationTransactionExternalEffects($xaction); // Now, synchronize the Doorkeeper edges. $revision = $this->getObject(); $revision_phid = $revision->getPHID(); $edge_type = PhabricatorJiraIssueHasObjectEdgeType::EDGECONST; $xobjs = $this->loadDoorkeeperExternalObjects($xaction->getNewValue()); $edge_dsts = mpull($xobjs, 'getPHID'); $edges = PhabricatorEdgeQuery::loadDestinationPHIDs($revision_phid, $edge_type); $editor = new PhabricatorEdgeEditor(); foreach (array_diff($edges, $edge_dsts) as $rem_edge) { $editor->removeEdge($revision_phid, $edge_type, $rem_edge); } foreach (array_diff($edge_dsts, $edges) as $add_edge) { $editor->addEdge($revision_phid, $edge_type, $add_edge); } $editor->save(); }
* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ echo "Migrating project members to edges...\n"; foreach (new LiskMigrationIterator(new PhabricatorProject()) as $proj) { $id = $proj->getID(); echo "Project {$id}: "; $members = queryfx_all($proj->establishConnection('r'), 'SELECT userPHID FROM %T WHERE projectPHID = %s', 'project_affiliation', $proj->getPHID()); if (!$members) { echo "-\n"; continue; } $members = ipull($members, 'userPHID'); $editor = new PhabricatorEdgeEditor(); $editor->setSuppressEvents(true); foreach ($members as $user_phid) { $editor->addEdge($proj->getPHID(), PhabricatorEdgeConfig::TYPE_PROJ_MEMBER, $user_phid); } $editor->save(); echo "OKAY\n"; } echo "Done.\n";
<?php echo "Migrating task dependencies to edges...\n"; $table = new ManiphestTask(); $table->openTransaction(); foreach (new LiskMigrationIterator($table) as $task) { $id = $task->getID(); echo "Task {$id}: "; $deps = $task->getAttachedPHIDs(ManiphestTaskPHIDType::TYPECONST); if (!$deps) { echo "-\n"; continue; } $editor = new PhabricatorEdgeEditor(); foreach ($deps as $dep) { $editor->addEdge($task->getPHID(), PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK, $dep); } $editor->save(); echo "OKAY\n"; } $table->saveTransaction(); echo "Done.\n";
* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ echo "Migrating task revisions to edges...\n"; foreach (new LiskMigrationIterator(new ManiphestTask()) as $task) { $id = $task->getID(); echo "Task {$id}: "; $revs = $task->getAttachedPHIDs(PhabricatorPHIDConstants::PHID_TYPE_DREV); if (!$revs) { echo "-\n"; continue; } $editor = new PhabricatorEdgeEditor(); $editor->setSuppressEvents(true); foreach ($revs as $rev) { $editor->addEdge($task->getPHID(), PhabricatorEdgeConfig::TYPE_TASK_HAS_RELATED_DREV, $rev); } $editor->save(); echo "OKAY\n"; } echo "Done.\n";
<?php $table = new DifferentialRevision(); $conn_w = $table->establishConnection('w'); // NOTE: We migrate by revision because the relationship table doesn't have // an "id" column. foreach (new LiskMigrationIterator($table) as $revision) { $revision_id = $revision->getID(); $revision_phid = $revision->getPHID(); echo "Migrating reviewers for D{$revision_id}...\n"; $reviewer_phids = queryfx_all($conn_w, 'SELECT objectPHID FROM %T WHERE revisionID = %d AND relation = %s ORDER BY sequence', 'differential_relationship', $revision_id, 'revw'); $reviewer_phids = ipull($reviewer_phids, 'objectPHID'); if (!$reviewer_phids) { continue; } $editor = new PhabricatorEdgeEditor(); foreach ($reviewer_phids as $dst) { if (phid_get_type($dst) == PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) { // At least one old install ran into some issues here. Skip the row if we // can't figure out what the destination PHID is. See here: // https://github.com/phacility/phabricator/pull/507 continue; } $editor->addEdge($revision_phid, PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER, $dst, array('data' => array('status' => DifferentialReviewerStatus::STATUS_ADDED))); } $editor->save(); } echo "Done.\n";
<?php echo pht('Migrating task dependencies to edges...') . "\n"; $table = new ManiphestTask(); $table->openTransaction(); foreach (new LiskMigrationIterator($table) as $task) { $id = $task->getID(); echo pht('Task %d: ', $id); $deps = $task->getAttachedPHIDs(ManiphestTaskPHIDType::TYPECONST); if (!$deps) { echo "-\n"; continue; } $editor = new PhabricatorEdgeEditor(); foreach ($deps as $dep) { $editor->addEdge($task->getPHID(), ManiphestTaskDependsOnTaskEdgeType::EDGECONST, $dep); } $editor->save(); echo pht('OKAY') . "\n"; } $table->saveTransaction(); echo pht('Done.') . "\n";
<?php echo pht('Migrating differential dependencies to edges...') . "\n"; $table = new DifferentialRevision(); $table->openTransaction(); foreach (new LiskMigrationIterator($table) as $rev) { $id = $rev->getID(); echo pht('Revision %d: ', $id); $deps = $rev->getAttachedPHIDs(DifferentialRevisionPHIDType::TYPECONST); if (!$deps) { echo "-\n"; continue; } $editor = new PhabricatorEdgeEditor(); foreach ($deps as $dep) { $editor->addEdge($rev->getPHID(), DifferentialRevisionDependsOnRevisionEdgeType::EDGECONST, $dep); } $editor->save(); echo pht('OKAY') . "\n"; } $table->saveTransaction(); echo pht('Done.') . "\n";
public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $e_phame_title = null; $e_title = null; $errors = array(); if ($this->isPostEdit()) { $posts = id(new PhamePostQuery())->withPHIDs(array($this->getPostPHID()))->execute(); $post = reset($posts); if (empty($post)) { return new Aphront404Response(); } if ($post->getBloggerPHID() != $user->getPHID()) { return new Aphront403Response(); } $post_noun = ucfirst($post->getHumanName()); $cancel_uri = $post->getViewURI($user->getUsername()); $submit_button = 'Save Changes'; $delete_button = javelin_render_tag('a', array('href' => $post->getDeleteURI(), 'class' => 'grey button', 'sigil' => 'workflow'), 'Delete ' . $post_noun); $page_title = 'Edit ' . $post_noun; } else { $post = id(new PhamePost())->setBloggerPHID($user->getPHID())->setVisibility(PhamePost::VISIBILITY_DRAFT); $cancel_uri = '/phame/draft/'; $submit_button = 'Create Draft'; $delete_button = null; $page_title = 'Create Draft'; } $this->setPost($post); $this->loadEdgesAndBlogs(); if ($request->isFormPost()) { $saved = true; $visibility = $request->getInt('visibility'); $comments = $request->getStr('comments_widget'); $data = array('comments_widget' => $comments); $phame_title = $request->getStr('phame_title'); $phame_title = PhabricatorSlug::normalize($phame_title); $title = $request->getStr('title'); $post->setTitle($title); $post->setPhameTitle($phame_title); $post->setBody($request->getStr('body')); $post->setVisibility($visibility); $post->setConfigData($data); // only publish once...! if ($visibility == PhamePost::VISIBILITY_PUBLISHED) { if (!$post->getDatePublished()) { $post->setDatePublished(time()); } // this is basically a cast of null to 0 if its a new post } else { if (!$post->getDatePublished()) { $post->setDatePublished(0); } } if ($phame_title == '/') { $errors[] = 'Phame title must be nonempty.'; $e_phame_title = 'Required'; } if (empty($title)) { $errors[] = 'Title must be nonempty.'; $e_title = 'Required'; } $blogs_published = array_keys($this->getPostBlogs()); $blogs_to_publish = array(); $blogs_to_depublish = array(); if ($visibility == PhamePost::VISIBILITY_PUBLISHED) { $blogs_arr = $request->getArr('blogs'); $blogs_to_publish = array_values($blogs_arr); $blogs_to_depublish = array_diff($blogs_published, $blogs_to_publish); } else { $blogs_to_depublish = $blogs_published; } if (empty($errors)) { try { $post->save(); $editor = new PhabricatorEdgeEditor(); $edge_type = PhabricatorEdgeConfig::TYPE_POST_HAS_BLOG; $editor->setUser($user); foreach ($blogs_to_publish as $phid) { $editor->addEdge($post->getPHID(), $edge_type, $phid); } foreach ($blogs_to_depublish as $phid) { $editor->removeEdge($post->getPHID(), $edge_type, $phid); } $editor->save(); } catch (AphrontQueryDuplicateKeyException $e) { $saved = false; $e_phame_title = 'Not Unique'; $errors[] = 'Another post already uses this slug. ' . 'Each post must have a unique slug.'; } } else { $saved = false; } if ($saved) { $uri = new PhutilURI($post->getViewURI($user->getUsername())); $uri->setQueryParam('saved', true); return id(new AphrontRedirectResponse())->setURI($uri); } } $panel = new AphrontPanelView(); $panel->setHeader($page_title); $panel->setWidth(AphrontPanelView::WIDTH_FULL); if ($delete_button) { $panel->addButton($delete_button); } $form = id(new AphrontFormView())->setUser($user)->appendChild(id(new AphrontFormTextControl())->setLabel('Title')->setName('title')->setValue($post->getTitle())->setID('post-title')->setError($e_title))->appendChild(id(new AphrontFormTextControl())->setLabel('Phame Title')->setName('phame_title')->setValue(rtrim($post->getPhameTitle(), '/'))->setID('post-phame-title')->setCaption('Up to 64 alphanumeric characters ' . 'with underscores for spaces. ' . 'Formatting is enforced.')->setError($e_phame_title))->appendChild(id(new PhabricatorRemarkupControl())->setLabel('Body')->setName('body')->setValue($post->getBody())->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)->setID('post-body'))->appendChild(id(new AphrontFormSelectControl())->setLabel('Visibility')->setName('visibility')->setValue($post->getVisibility())->setOptions(PhamePost::getVisibilityOptionsForSelect())->setID('post-visibility'))->appendChild($this->getBlogCheckboxControl($post))->appendChild(id(new AphrontFormSelectControl())->setLabel('Comments Widget')->setName('comments_widget')->setvalue($post->getCommentsWidget())->setOptions($post->getCommentsWidgetOptionsForSelect()))->appendChild(id(new AphrontFormSubmitControl())->addCancelButton($cancel_uri)->setValue($submit_button)); $panel->appendChild($form); $preview_panel = '<div class="aphront-panel-preview "> <div class="phame-post-preview-header"> Post Preview </div> <div id="post-preview"> <div class="aphront-panel-preview-loading-text"> Loading preview... </div> </div> </div>'; Javelin::initBehavior('phame-post-preview', array('preview' => 'post-preview', 'body' => 'post-body', 'title' => 'post-title', 'phame_title' => 'post-phame-title', 'uri' => '/phame/post/preview/')); $visibility_data = array('select_id' => 'post-visibility', 'current' => $post->getVisibility(), 'published' => PhamePost::VISIBILITY_PUBLISHED, 'draft' => PhamePost::VISIBILITY_DRAFT, 'change_uri' => $post->getChangeVisibilityURI()); $blogs_data = array('checkbox_id' => 'post-blogs', 'have_published' => (bool) count($this->getPostBlogs())); Javelin::initBehavior('phame-post-blogs', array('blogs' => $blogs_data, 'visibility' => $visibility_data)); if ($errors) { $error_view = id(new AphrontErrorView())->setTitle('Errors saving post.')->setErrors($errors); } else { $error_view = null; } $this->setShowSideNav(true); return $this->buildStandardPageResponse(array($error_view, $panel, $preview_panel), array('title' => $page_title)); }
/** * @task files */ private function attachFiles(PhabricatorLiskDAO $object, array $file_phids) { if (!$file_phids) { return; } $editor = new PhabricatorEdgeEditor(); $src = $object->getPHID(); $type = PhabricatorObjectHasFileEdgeType::EDGECONST; foreach ($file_phids as $dst) { $editor->addEdge($src, $type, $dst); } $editor->save(); }
$edge_type = PhabricatorSubscribedToObjectEdgeType::EDGECONST; $edge_inverse = PhabricatorObjectHasSubscriberEdgeType::EDGECONST; $map = PhabricatorPHIDType::getAllTypes(); foreach ($map as $type => $spec) { try { $object = $spec->newObject(); if (!$object) { continue; } $object_conn_w = $object->establishConnection('w'); queryfx($object_conn_w, 'UPDATE %T SET dst = %s WHERE dst = %s AND type = %s', PhabricatorEdgeConfig::TABLE_NAME_EDGE, $new_phid, $old_phid, $edge_inverse); } catch (Exception $ex) { // Just ignore these; they're mostly tables not existing. continue; } } try { $dst_phids = queryfx_all($conn_w, 'SELECT dst FROM %T WHERE src = %s AND type = %s', PhabricatorEdgeConfig::TABLE_NAME_EDGE, $old_phid, $edge_type); if ($dst_phids) { $editor = new PhabricatorEdgeEditor(); foreach ($dst_phids as $dst_phid) { $editor->addEdge($new_phid, $edge_type, $dst_phid['dst']); } $editor->save(); } } catch (Exception $ex) { echo pht('Unable to migrate some inverse edges for mailing list "%s": %s.', $name, $ex->getMessage()) . "\n"; continue; } echo pht('Migrated mailing list "%s" to mailing list user "%s".', $name, $user->getUsername()) . "\n"; }
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; } }
<?php echo "Migrating differential dependencies to edges...\n"; $table = new DifferentialRevision(); $table->openTransaction(); foreach (new LiskMigrationIterator($table) as $rev) { $id = $rev->getID(); echo "Revision {$id}: "; $deps = $rev->getAttachedPHIDs(DifferentialRevisionPHIDType::TYPECONST); if (!$deps) { echo "-\n"; continue; } $editor = new PhabricatorEdgeEditor(); foreach ($deps as $dep) { $editor->addEdge($rev->getPHID(), PhabricatorEdgeConfig::TYPE_DREV_DEPENDS_ON_DREV, $dep); } $editor->save(); echo "OKAY\n"; } $table->saveTransaction(); echo "Done.\n";
<?php echo pht('Migrating Differential unsubscribed users to edges...') . "\n"; $table = new DifferentialRevision(); $table->openTransaction(); // We couldn't use new LiskMigrationIterator($table) because the $unsubscribed // property gets deleted. $revs = queryfx_all($table->establishConnection('w'), 'SELECT id, phid, unsubscribed FROM differential_revision'); foreach ($revs as $rev) { echo '.'; $unsubscribed = json_decode($rev['unsubscribed']); if (!$unsubscribed) { continue; } $editor = new PhabricatorEdgeEditor(); foreach ($unsubscribed as $user_phid => $_) { $editor->addEdge($rev['phid'], PhabricatorObjectHasUnsubscriberEdgeType::EDGECONST, $user_phid); } $editor->save(); } $table->saveTransaction(); echo pht('Done.') . "\n";
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 = PhabricatorEdgeConfig::TYPE_OBJECT_USES_CREDENTIAL; $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; } }
<?php $table = new PhabricatorFileImageMacro(); foreach (new LiskMigrationIterator($table) as $macro) { $name = $macro->getName(); echo "Linking macro '{$name}'...\n"; $editor = new PhabricatorEdgeEditor(); $phids[] = $macro->getFilePHID(); $phids[] = $macro->getAudioPHID(); $phids = array_filter($phids); if ($phids) { foreach ($phids as $phid) { $editor->addEdge($macro->getPHID(), PhabricatorEdgeConfig::TYPE_OBJECT_HAS_FILE, $phid); } $editor->save(); } } echo "Done.\n";
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); }
<?php $table = new PhabricatorFileImageMacro(); foreach (new LiskMigrationIterator($table) as $macro) { $name = $macro->getName(); echo pht("Linking macro '%s'...", $name) . "\n"; $editor = new PhabricatorEdgeEditor(); $phids[] = $macro->getFilePHID(); $phids[] = $macro->getAudioPHID(); $phids = array_filter($phids); if ($phids) { foreach ($phids as $phid) { $editor->addEdge($macro->getPHID(), PhabricatorObjectHasFileEdgeType::EDGECONST, $phid); } $editor->save(); } } echo pht('Done.') . "\n";
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; } }
/** * @task files */ private function attachFiles(PhabricatorLiskDAO $object, array $file_phids) { if (!$file_phids) { return; } $editor = new PhabricatorEdgeEditor(); $src = $object->getPHID(); $type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_FILE; foreach ($file_phids as $dst) { $editor->addEdge($src, $type, $dst); } $editor->save(); }
<?php echo "Migrating task revisions to edges...\n"; $table = new ManiphestTask(); $table->establishConnection('w'); foreach (new LiskMigrationIterator($table) as $task) { $id = $task->getID(); echo "Task {$id}: "; $revs = $task->getAttachedPHIDs(DifferentialRevisionPHIDType::TYPECONST); if (!$revs) { echo "-\n"; continue; } $editor = new PhabricatorEdgeEditor(); foreach ($revs as $rev) { $editor->addEdge($task->getPHID(), ManiphestTaskHasRevisionEdgeType::EDGECONST, $rev); } $editor->save(); echo "OKAY\n"; } echo "Done.\n";