Page MenuHomePhorge

No OneTemporary

diff --git a/src/applications/differential/field/specification/maniphesttasks/DifferentialManiphestTasksFieldSpecification.php b/src/applications/differential/field/specification/maniphesttasks/DifferentialManiphestTasksFieldSpecification.php
index 3f2f9d4b8a..bd1f9c298d 100644
--- a/src/applications/differential/field/specification/maniphesttasks/DifferentialManiphestTasksFieldSpecification.php
+++ b/src/applications/differential/field/specification/maniphesttasks/DifferentialManiphestTasksFieldSpecification.php
@@ -1,54 +1,176 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* 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.
*/
final class DifferentialManiphestTasksFieldSpecification
extends DifferentialFieldSpecification {
+ private $maniphestTasks = array();
+
public function shouldAppearOnRevisionView() {
return PhabricatorEnv::getEnvConfig('maniphest.enabled');
}
public function getRequiredHandlePHIDsForRevisionView() {
return $this->getManiphestTaskPHIDs();
}
public function renderLabelForRevisionView() {
return 'Maniphest Tasks:';
}
public function renderValueForRevisionView() {
$task_phids = $this->getManiphestTaskPHIDs();
if (!$task_phids) {
return null;
}
$links = array();
foreach ($task_phids as $task_phid) {
$links[] = $this->getHandle($task_phid)->renderLink();
}
return implode('<br />', $links);
}
private function getManiphestTaskPHIDs() {
$revision = $this->getRevision();
return $revision->getAttachedPHIDs(
PhabricatorPHIDConstants::PHID_TYPE_TASK);
}
+ /**
+ * Attach the revision to the task(s) and the task(s) to the revision.
+ *
+ * @return void
+ */
+ public function willWriteRevision(DifferentialRevisionEditor $editor) {
+ // 1 -- revision => tasks
+ $revision = $editor->getRevision();
+ $revision->setAttachedPHIDs(PhabricatorPHIDConstants::PHID_TYPE_TASK,
+ $this->maniphestTasks);
+
+ // 2 -- tasks => revision
+ $maniphest_editor = new ManiphestTransactionEditor();
+ $user = $this->getUser();
+ $type = ManiphestTransactionType::TYPE_ATTACH;
+ $attach_type = PhabricatorPHIDConstants::PHID_TYPE_DREV;
+ $attach_data = array($revision->getPHID() => array());
+
+ $tasks = id(new ManiphestTask())
+ ->loadAllWhere('phid IN (%Ld)', $this->maniphestTasks);
+
+ foreach ($tasks as $task) {
+ $transaction = new ManiphestTransaction();
+ $transaction->setAuthorPHID($user->getPHID());
+ $transaction->setTransactionType($type);
+
+ $new = $task->getAttached();
+ $new[$attach_type] = $attach_data;
+
+ $transaction->setNewValue($new);
+ $maniphest_editor->applyTransactions($task, array($transaction));
+ }
+ }
+
+ protected function didSetRevision() {
+ $this->maniphestTasks = $this->getManiphestTaskPHIDs();
+ }
+
+ public function getRequiredHandlePHIDsForCommitMessage() {
+ return $this->maniphestTasks;
+ }
+
+ public function shouldAppearOnCommitMessageTemplate() {
+ return PhabricatorEnv::getEnvConfig('maniphest.enabled');
+ }
+
+ public function shouldAppearOnCommitMessage() {
+ return PhabricatorEnv::getEnvConfig('maniphest.enabled');
+ }
+
+ public function getCommitMessageKey() {
+ return 'maniphestTaskPHIDs';
+ }
+
+ public function setValueFromParsedCommitMessage($value) {
+ $this->maniphestTasks = nonempty($value, array());
+ return $this;
+ }
+
+ public function renderLabelForCommitMessage() {
+ return 'Maniphest Tasks';
+ }
+
+ public function getSupportedCommitMessageLabels() {
+ return array(
+ 'Maniphest Task',
+ 'Maniphest Tasks',
+ );
+ }
+
+ public function renderValueForCommitMessage($is_edit) {
+ if (!$this->maniphestTasks) {
+ return null;
+ }
+
+ $names = array();
+ foreach ($this->maniphestTasks as $phid) {
+ $handle = $this->getHandle($phid);
+ $names[] = 'T'.$handle->getAlternateID();
+ }
+ return implode(', ', $names);
+ }
+
+ public function parseValueFromCommitMessage($value) {
+ $matches = null;
+ preg_match_all('/T(\d+)/', $value, $matches);
+ if (empty($matches[0])) {
+ return array();
+ }
+
+
+ $task_ids = $matches[1];
+ $tasks = id(new ManiphestTask())
+ ->loadAllWhere('id in (%Ld)', $task_ids);
+
+ $task_phids = array();
+ $invalid = array();
+ foreach ($task_ids as $task_id) {
+ $task = idx($tasks, $task_id);
+ if (empty($task)) {
+ $invalid[] = 'T'.$task_id;
+ } else {
+ $task_phids[] = $task->getPHID();
+ }
+ }
+
+ if ($invalid) {
+ if (count($invalid) > 1) {
+ $what = 'Maniphest Tasks';
+ } else {
+ $what = 'Maniphest Task';
+ }
+ $invalid = implode(', ', $invalid);
+ throw new DifferentialFieldParseException(
+ "Commit message references nonexistent {$what}: {$invalid}.");
+ }
+
+ return $task_phids;
+ }
+
}
diff --git a/src/applications/differential/field/specification/maniphesttasks/__init__.php b/src/applications/differential/field/specification/maniphesttasks/__init__.php
index 54c0ba2d66..4f9b037319 100644
--- a/src/applications/differential/field/specification/maniphesttasks/__init__.php
+++ b/src/applications/differential/field/specification/maniphesttasks/__init__.php
@@ -1,14 +1,21 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
+phutil_require_module('phabricator', 'applications/differential/field/exception/parse');
phutil_require_module('phabricator', 'applications/differential/field/specification/base');
+phutil_require_module('phabricator', 'applications/maniphest/constants/transactiontype');
+phutil_require_module('phabricator', 'applications/maniphest/editor/transaction');
+phutil_require_module('phabricator', 'applications/maniphest/storage/task');
+phutil_require_module('phabricator', 'applications/maniphest/storage/transaction');
phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'infrastructure/env');
+phutil_require_module('phutil', 'utils');
+
phutil_require_source('DifferentialManiphestTasksFieldSpecification.php');
diff --git a/src/applications/phid/handle/data/PhabricatorObjectHandleData.php b/src/applications/phid/handle/data/PhabricatorObjectHandleData.php
index 91bf8096ea..74d9a433da 100644
--- a/src/applications/phid/handle/data/PhabricatorObjectHandleData.php
+++ b/src/applications/phid/handle/data/PhabricatorObjectHandleData.php
@@ -1,488 +1,489 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* 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.
*/
class PhabricatorObjectHandleData {
private $phids;
public function __construct(array $phids) {
$this->phids = array_unique($phids);
}
public function loadObjects() {
$types = array();
foreach ($this->phids as $phid) {
$type = $this->lookupType($phid);
$types[$type][] = $phid;
}
$objects = array_fill_keys($this->phids, null);
foreach ($types as $type => $phids) {
switch ($type) {
case PhabricatorPHIDConstants::PHID_TYPE_USER:
$user_dao = newv('PhabricatorUser', array());
$users = $user_dao->loadAllWhere(
'phid in (%Ls)',
$phids);
foreach ($users as $user) {
$objects[$user->getPHID()] = $user;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
$commit_dao = newv('PhabricatorRepositoryCommit', array());
$commits = $commit_dao->loadAllWhere(
'phid IN (%Ls)',
$phids);
$commit_data = array();
if ($commits) {
$data_dao = newv('PhabricatorRepositoryCommitData', array());
$commit_data = $data_dao->loadAllWhere(
'commitID IN (%Ld)',
mpull($commits, 'getID'));
$commit_data = mpull($commit_data, null, 'getCommitID');
}
foreach ($commits as $commit) {
$data = idx($commit_data, $commit->getID());
if ($data) {
$commit->attachCommitData($data);
$objects[$commit->getPHID()] = $commit;
} else {
// If we couldn't load the commit data, just act as though we
// couldn't load the object at all so we don't load half an object.
}
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_TASK:
$task_dao = newv('ManiphestTask', array());
$tasks = $task_dao->loadAllWhere(
'phid IN (%Ls)',
$phids);
foreach ($tasks as $task) {
$objects[$task->getPHID()] = $task;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_DREV:
$revision_dao = newv('DifferentialRevision', array());
$revisions = $revision_dao->loadAllWhere(
'phid IN (%Ls)',
$phids);
foreach ($revisions as $revision) {
$objects[$revision->getPHID()] = $revision;
}
break;
}
}
return $objects;
}
public function loadHandles() {
$types = array();
foreach ($this->phids as $phid) {
$type = $this->lookupType($phid);
$types[$type][] = $phid;
}
$handles = array();
$external_loaders = PhabricatorEnv::getEnvConfig('phid.external-loaders');
foreach ($types as $type => $phids) {
switch ($type) {
case PhabricatorPHIDConstants::PHID_TYPE_MAGIC:
// Black magic!
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
switch ($phid) {
case ManiphestTaskOwner::OWNER_UP_FOR_GRABS:
$handle->setName('Up For Grabs');
$handle->setFullName('upforgrabs (Up For Grabs)');
$handle->setComplete(true);
break;
default:
$handle->setName('Foul Magicks');
break;
}
$handles[$phid] = $handle;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_USER:
$class = 'PhabricatorUser';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$users = $object->loadAllWhere('phid IN (%Ls)', $phids);
$users = mpull($users, null, 'getPHID');
$image_phids = mpull($users, 'getProfileImagePHID');
$image_phids = array_unique(array_filter($image_phids));
$images = array();
if ($image_phids) {
$images = id(new PhabricatorFile())->loadAllWhere(
'phid IN (%Ls)',
$image_phids);
$images = mpull($images, 'getViewURI', 'getPHID');
}
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($users[$phid])) {
$handle->setName('Unknown User');
} else {
$user = $users[$phid];
$handle->setName($user->getUsername());
$handle->setURI('/p/'.$user->getUsername().'/');
$handle->setEmail($user->getEmail());
$handle->setFullName(
$user->getUsername().' ('.$user->getRealName().')');
$handle->setAlternateID($user->getID());
$handle->setComplete(true);
$handle->setDisabled($user->getIsDisabled());
$img_uri = idx($images, $user->getProfileImagePHID());
if ($img_uri) {
$handle->setImageURI($img_uri);
}
}
$handles[$phid] = $handle;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_MLST:
$class = 'PhabricatorMetaMTAMailingList';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$lists = $object->loadAllWhere('phid IN (%Ls)', $phids);
$lists = mpull($lists, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($lists[$phid])) {
$handle->setName('Unknown Mailing List');
} else {
$list = $lists[$phid];
$handle->setEmail($list->getEmail());
$handle->setName($list->getName());
$handle->setURI($list->getURI());
$handle->setFullName($list->getName());
$handle->setComplete(true);
}
$handles[$phid] = $handle;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_DREV:
$class = 'DifferentialRevision';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$revs = $object->loadAllWhere('phid in (%Ls)', $phids);
$revs = mpull($revs, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($revs[$phid])) {
$handle->setName('Unknown Revision');
} else {
$rev = $revs[$phid];
$handle->setName($rev->getTitle());
$handle->setURI('/D'.$rev->getID());
$handle->setFullName('D'.$rev->getID().': '.$rev->getTitle());
$handle->setComplete(true);
$status = $rev->getStatus();
if (($status == DifferentialRevisionStatus::COMMITTED) ||
($status == DifferentialRevisionStatus::ABANDONED)) {
$closed = PhabricatorObjectHandleStatus::STATUS_CLOSED;
$handle->setStatus($closed);
}
}
$handles[$phid] = $handle;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
$class = 'PhabricatorRepositoryCommit';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$commits = $object->loadAllWhere('phid in (%Ls)', $phids);
$commits = mpull($commits, null, 'getPHID');
$repository_ids = mpull($commits, 'getRepositoryID');
$repositories = id(new PhabricatorRepository())->loadAllWhere(
'id in (%Ld)', array_unique($repository_ids));
$callsigns = mpull($repositories, 'getCallsign');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($commits[$phid]) ||
!isset($callsigns[$repository_ids[$phid]])) {
$handle->setName('Unknown Commit');
} else {
$commit = $commits[$phid];
$callsign = $callsigns[$repository_ids[$phid]];
$repository = $repositories[$repository_ids[$phid]];
$commit_identifier = $commit->getCommitIdentifier();
// In case where the repository for the commit was deleted,
// we don't have have info about the repository anymore.
if ($repository) {
$vcs = $repository->getVersionControlSystem();
if ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT) {
$short_identifier = substr($commit_identifier, 0, 16);
} else {
$short_identifier = $commit_identifier;
}
$handle->setName('r'.$callsign.$short_identifier);
} else {
$handle->setName('Commit '.'r'.$callsign.$commit_identifier);
}
$handle->setURI('/r'.$callsign.$commit_identifier);
$handle->setFullName('r'.$callsign.$commit_identifier);
$handle->setTimestamp($commit->getEpoch());
$handle->setComplete(true);
}
$handles[$phid] = $handle;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_TASK:
$class = 'ManiphestTask';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$tasks = $object->loadAllWhere('phid in (%Ls)', $phids);
$tasks = mpull($tasks, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($tasks[$phid])) {
$handle->setName('Unknown Revision');
} else {
$task = $tasks[$phid];
$handle->setName($task->getTitle());
$handle->setURI('/T'.$task->getID());
$handle->setFullName('T'.$task->getID().': '.$task->getTitle());
$handle->setComplete(true);
+ $handle->setAlternateID($task->getID());
if ($task->getStatus() != ManiphestTaskStatus::STATUS_OPEN) {
$closed = PhabricatorObjectHandleStatus::STATUS_CLOSED;
$handle->setStatus($closed);
}
}
$handles[$phid] = $handle;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_FILE:
$class = 'PhabricatorFile';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$files = $object->loadAllWhere('phid IN (%Ls)', $phids);
$files = mpull($files, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($files[$phid])) {
$handle->setName('Unknown File');
} else {
$file = $files[$phid];
$handle->setName($file->getName());
$handle->setURI($file->getViewURI());
$handle->setComplete(true);
}
$handles[$phid] = $handle;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_PROJ:
$class = 'PhabricatorProject';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$projects = $object->loadAllWhere('phid IN (%Ls)', $phids);
$projects = mpull($projects, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($projects[$phid])) {
$handle->setName('Unknown Project');
} else {
$project = $projects[$phid];
$handle->setName($project->getName());
$handle->setURI('/project/view/'.$project->getID().'/');
$handle->setComplete(true);
}
$handles[$phid] = $handle;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_REPO:
$class = 'PhabricatorRepository';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$repositories = $object->loadAllWhere('phid in (%Ls)', $phids);
$repositories = mpull($repositories, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($repositories[$phid])) {
$handle->setName('Unknown Repository');
} else {
$repository = $repositories[$phid];
$handle->setName($repository->getCallsign());
$handle->setURI('/diffusion/'.$repository->getCallsign().'/');
$handle->setComplete(true);
}
$handles[$phid] = $handle;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_OPKG:
$class = 'PhabricatorOwnersPackage';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$packages = $object->loadAllWhere('phid in (%Ls)', $phids);
$packages = mpull($packages, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($packages[$phid])) {
$handle->setName('Unknown Package');
} else {
$package = $packages[$phid];
$handle->setName($package->getName());
$handle->setURI('/owners/package/'.$package->getID().'/');
$handle->setComplete(true);
}
$handles[$phid] = $handle;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_APRJ:
$project_dao = newv('PhabricatorRepositoryArcanistProject', array());
$projects = $project_dao->loadAllWhere(
'phid IN (%Ls)',
$phids);
$projects = mpull($projects, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($projects[$phid])) {
$handle->setName('Unknown Arcanist Project');
} else {
$project = $projects[$phid];
$handle->setName($project->getName());
$handle->setComplete(true);
}
$handles[$phid] = $handle;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_WIKI:
$document_dao = newv('PhrictionDocument', array());
$content_dao = newv('PhrictionContent', array());
$conn = $document_dao->establishConnection('r');
$documents = queryfx_all(
$conn,
'SELECT * FROM %T document JOIN %T content
ON document.contentID = content.id
WHERE document.phid IN (%Ls)',
$document_dao->getTableName(),
$content_dao->getTableName(),
$phids);
$documents = ipull($documents, null, 'phid');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($documents[$phid])) {
$handle->setName('Unknown Document');
} else {
$info = $documents[$phid];
$handle->setName($info['title']);
$handle->setURI(PhrictionDocument::getSlugURI($info['slug']));
$handle->setComplete(true);
}
$handles[$phid] = $handle;
}
break;
default:
$loader = null;
if (isset($external_loaders[$type])) {
$loader = $external_loaders[$type];
} else if (isset($external_loaders['*'])) {
$loader = $external_loaders['*'];
}
if ($loader) {
PhutilSymbolLoader::loadClass($loader);
$object = newv($loader, array());
$handles += $object->loadHandles($phids);
break;
}
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setType($type);
$handle->setPHID($phid);
$handle->setName('Unknown Object');
$handle->setFullName('An Unknown Object');
$handles[$phid] = $handle;
}
break;
}
}
return $handles;
}
private function lookupType($phid) {
$matches = null;
if (preg_match('/^PHID-([^-]{4})-/', $phid, $matches)) {
return $matches[1];
}
return PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Sun, Jan 19, 19:57 (2 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1128216
Default Alt Text
(24 KB)

Event Timeline