Page MenuHomePhabricator

D15201.id36698.diff
No OneTemporary

D15201.id36698.diff

diff --git a/resources/sql/autopatches/20160206.cover.1.sql b/resources/sql/autopatches/20160206.cover.1.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160206.cover.1.sql
@@ -0,0 +1,5 @@
+ALTER TABLE {$NAMESPACE}_maniphest.maniphest_task
+ ADD properties LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT};
+
+UPDATE {$NAMESPACE}_maniphest.maniphest_task
+ SET properties = '{}' WHERE properties = '';
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1815,6 +1815,7 @@
'PhabricatorBinariesSetupCheck' => 'applications/config/check/PhabricatorBinariesSetupCheck.php',
'PhabricatorBitbucketAuthProvider' => 'applications/auth/provider/PhabricatorBitbucketAuthProvider.php',
'PhabricatorBoardLayoutEngine' => 'applications/project/engine/PhabricatorBoardLayoutEngine.php',
+ 'PhabricatorBoardRenderingEngine' => 'applications/project/engine/PhabricatorBoardRenderingEngine.php',
'PhabricatorBot' => 'infrastructure/daemon/bot/PhabricatorBot.php',
'PhabricatorBotChannel' => 'infrastructure/daemon/bot/target/PhabricatorBotChannel.php',
'PhabricatorBotDebugLogHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotDebugLogHandler.php',
@@ -6043,6 +6044,7 @@
'PhabricatorBinariesSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorBitbucketAuthProvider' => 'PhabricatorOAuth1AuthProvider',
'PhabricatorBoardLayoutEngine' => 'Phobject',
+ 'PhabricatorBoardRenderingEngine' => 'Phobject',
'PhabricatorBot' => 'PhabricatorDaemon',
'PhabricatorBotChannel' => 'PhabricatorBotTarget',
'PhabricatorBotDebugLogHandler' => 'PhabricatorBotHandler',
diff --git a/src/applications/files/transform/PhabricatorFileThumbnailTransform.php b/src/applications/files/transform/PhabricatorFileThumbnailTransform.php
--- a/src/applications/files/transform/PhabricatorFileThumbnailTransform.php
+++ b/src/applications/files/transform/PhabricatorFileThumbnailTransform.php
@@ -7,6 +7,7 @@
const TRANSFORM_PINBOARD = 'pinboard';
const TRANSFORM_THUMBGRID = 'thumbgrid';
const TRANSFORM_PREVIEW = 'preview';
+ const TRANSFORM_WORKCARD = 'workcard';
private $name;
private $key;
@@ -73,6 +74,10 @@
->setName(pht('Preview (220px)'))
->setKey(self::TRANSFORM_PREVIEW)
->setDimensions(220, null),
+ id(new self())
+ ->setName(pht('Workcard (526px)'))
+ ->setKey(self::TRANSFORM_WORKCARD)
+ ->setDimensions(526, null),
);
}
diff --git a/src/applications/maniphest/editor/ManiphestEditEngine.php b/src/applications/maniphest/editor/ManiphestEditEngine.php
--- a/src/applications/maniphest/editor/ManiphestEditEngine.php
+++ b/src/applications/maniphest/editor/ManiphestEditEngine.php
@@ -334,39 +334,27 @@
'sortMap' => $sort_map,
);
- // TODO: This should just use HandlePool once we get through the EditEngine
- // transition.
- $owner = null;
- if ($task->getOwnerPHID()) {
- $owner = id(new PhabricatorHandleQuery())
- ->setViewer($viewer)
- ->withPHIDs(array($task->getOwnerPHID()))
- ->executeOne();
- }
-
- $handle_phids = $task->getProjectPHIDs();
- $handle_phids = array_fuse($handle_phids);
- $handle_phids = array_diff_key($handle_phids, $board_phids);
-
- $project_handles = $viewer->loadHandles($handle_phids);
- $project_handles = iterator_to_array($project_handles);
-
- $tasks = id(new ProjectBoardTaskCard())
+ $rendering_engine = id(new PhabricatorBoardRenderingEngine())
->setViewer($viewer)
- ->setTask($task)
- ->setOwner($owner)
- ->setProjectHandles($project_handles)
- ->setCanEdit(true)
- ->getItem();
+ ->setObjects(array($task))
+ ->setExcludedProjectPHIDs($board_phids);
- $tasks->addClass('phui-workcard');
+ $card = $rendering_engine->renderCard($task->getPHID());
+
+ $item = $card->getItem();
+ $item->addClass('phui-workcard');
$payload = array(
- 'tasks' => $tasks,
+ 'tasks' => $item,
'data' => $data,
);
- return id(new AphrontAjaxResponse())->setContent($payload);
+ return id(new AphrontAjaxResponse())
+ ->setContent(
+ array(
+ 'tasks' => $item,
+ 'data' => $data,
+ ));
}
diff --git a/src/applications/maniphest/storage/ManiphestTask.php b/src/applications/maniphest/storage/ManiphestTask.php
--- a/src/applications/maniphest/storage/ManiphestTask.php
+++ b/src/applications/maniphest/storage/ManiphestTask.php
@@ -38,6 +38,7 @@
protected $ownerOrdering;
protected $spacePHID;
+ protected $properties = array();
private $subscriberPHIDs = self::ATTACHABLE;
private $groupByProjectPHID = self::ATTACHABLE;
@@ -74,6 +75,7 @@
'ccPHIDs' => self::SERIALIZATION_JSON,
'attached' => self::SERIALIZATION_JSON,
'projectPHIDs' => self::SERIALIZATION_JSON,
+ 'properties' => self::SERIALIZATION_JSON,
),
self::CONFIG_COLUMN_SCHEMA => array(
'ownerPHID' => 'phid?',
@@ -215,6 +217,19 @@
);
}
+ public function setProperty($key, $value) {
+ $this->properties[$key] = $value;
+ return $this;
+ }
+
+ public function getProperty($key, $default = null) {
+ return idx($this->properties, $key, $default);
+ }
+
+ public function getCoverImageThumbnailPHID() {
+ return idx($this->properties, 'cover.thumbnailPHID');
+ }
+
/* -( PhabricatorSubscribableInterface )----------------------------------- */
diff --git a/src/applications/project/controller/PhabricatorProjectBoardViewController.php b/src/applications/project/controller/PhabricatorProjectBoardViewController.php
--- a/src/applications/project/controller/PhabricatorProjectBoardViewController.php
+++ b/src/applications/project/controller/PhabricatorProjectBoardViewController.php
@@ -7,7 +7,6 @@
private $id;
private $slug;
- private $handles;
private $queryKey;
private $filter;
private $sortKey;
@@ -226,22 +225,9 @@
'project-boards',
$behavior_config);
- $this->handles = ManiphestTaskListView::loadTaskHandles($viewer, $tasks);
-
- $all_project_phids = array();
- foreach ($tasks as $task) {
- foreach ($task->getProjectPHIDs() as $project_phid) {
- $all_project_phids[$project_phid] = $project_phid;
- }
- }
-
- foreach ($select_phids as $phid) {
- unset($all_project_phids[$phid]);
- }
-
- $all_handles = $viewer->loadHandles($all_project_phids);
- $all_handles = iterator_to_array($all_handles);
-
+ $visible_columns = array();
+ $column_phids = array();
+ $visible_phids = array();
foreach ($columns as $column) {
if (!$this->showHidden) {
if ($column->isHidden()) {
@@ -268,6 +254,25 @@
$column_tasks = array_select_keys($column_tasks, array_keys($tasks));
}
+ $column_phid = $column->getPHID();
+
+ $visible_columns[$column_phid] = $column;
+ $column_phids[$column_phid] = $column_tasks;
+
+ foreach ($column_tasks as $phid => $task) {
+ $visible_phids[$phid] = $phid;
+ }
+ }
+
+ $rendering_engine = id(new PhabricatorBoardRenderingEngine())
+ ->setViewer($viewer)
+ ->setObjects(array_select_keys($tasks, $visible_phids))
+ ->setEditMap($task_can_edit_map)
+ ->setExcludedProjectPHIDs($select_phids);
+
+ foreach ($visible_columns as $column_phid => $column) {
+ $column_tasks = $column_phids[$column_phid];
+
$panel = id(new PHUIWorkpanelView())
->setHeader($column->getDisplayName())
->setSubHeader($column->getDisplayType())
@@ -317,22 +322,10 @@
));
foreach ($column_tasks as $task) {
- $owner = null;
- if ($task->getOwnerPHID()) {
- $owner = $this->handles[$task->getOwnerPHID()];
- }
- $can_edit = idx($task_can_edit_map, $task->getPHID(), false);
-
- $handles = array_select_keys($all_handles, $task->getProjectPHIDs());
-
- $cards->addItem(id(new ProjectBoardTaskCard())
- ->setViewer($viewer)
- ->setProjectHandles($handles)
- ->setTask($task)
- ->setOwner($owner)
- ->setCanEdit($can_edit)
- ->getItem());
+ $card = $rendering_engine->renderCard($task->getPHID());
+ $cards->addItem($card->getItem());
}
+
$panel->setCards($cards);
$board->addPanel($panel);
}
diff --git a/src/applications/project/controller/PhabricatorProjectMoveController.php b/src/applications/project/controller/PhabricatorProjectMoveController.php
--- a/src/applications/project/controller/PhabricatorProjectMoveController.php
+++ b/src/applications/project/controller/PhabricatorProjectMoveController.php
@@ -175,24 +175,11 @@
$editor->applyTransactions($object, $xactions);
- $owner = null;
- if ($object->getOwnerPHID()) {
- $owner = id(new PhabricatorHandleQuery())
- ->setViewer($viewer)
- ->withPHIDs(array($object->getOwnerPHID()))
- ->executeOne();
- }
-
// Reload the object so it reflects edits which have been applied.
$object = id(new ManiphestTaskQuery())
->setViewer($viewer)
->withPHIDs(array($object_phid))
->needProjectPHIDs(true)
- ->requireCapabilities(
- array(
- PhabricatorPolicyCapability::CAN_VIEW,
- PhabricatorPolicyCapability::CAN_EDIT,
- ))
->executeOne();
$except_phids = array($board_phid);
@@ -206,25 +193,21 @@
}
}
- $except_phids = array_fuse($except_phids);
- $handle_phids = array_fuse($object->getProjectPHIDs());
- $handle_phids = array_diff_key($handle_phids, $except_phids);
-
- $project_handles = $viewer->loadHandles($handle_phids);
- $project_handles = iterator_to_array($project_handles);
-
- $card = id(new ProjectBoardTaskCard())
+ $rendering_engine = id(new PhabricatorBoardRenderingEngine())
->setViewer($viewer)
- ->setTask($object)
- ->setOwner($owner)
- ->setCanEdit(true)
- ->setProjectHandles($project_handles)
- ->getItem();
+ ->setObjects(array($object))
+ ->setExcludedProjectPHIDs($except_phids);
- $card->addClass('phui-workcard');
+ $card = $rendering_engine->renderCard($object->getPHID());
- return id(new AphrontAjaxResponse())->setContent(
- array('task' => $card));
+ $item = $card->getItem();
+ $item->addClass('phui-workcard');
+
+ return id(new AphrontAjaxResponse())
+ ->setContent(
+ array(
+ 'task' => $item,
+ ));
}
}
diff --git a/src/applications/project/engine/PhabricatorBoardRenderingEngine.php b/src/applications/project/engine/PhabricatorBoardRenderingEngine.php
new file mode 100644
--- /dev/null
+++ b/src/applications/project/engine/PhabricatorBoardRenderingEngine.php
@@ -0,0 +1,144 @@
+<?php
+
+final class PhabricatorBoardRenderingEngine extends Phobject {
+
+ private $viewer;
+ private $objects;
+ private $excludedProjectPHIDs;
+ private $editMap;
+
+ private $loaded;
+ private $handles;
+ private $coverFiles;
+
+ public function setViewer(PhabricatorUser $viewer) {
+ $this->viewer = $viewer;
+ return $this;
+ }
+
+ public function getViewer() {
+ return $this->viewer;
+ }
+
+ public function setObjects(array $objects) {
+ $this->objects = mpull($objects, null, 'getPHID');
+ return $this;
+ }
+
+ public function getObjects() {
+ return $this->objects;
+ }
+
+ public function setExcludedProjectPHIDs(array $phids) {
+ $this->excludedProjectPHIDs = $phids;
+ return $this;
+ }
+
+ public function getExcludedProjectPHIDs() {
+ return $this->excludedProjectPHIDs;
+ }
+
+ public function setEditMap(array $edit_map) {
+ $this->editMap = $edit_map;
+ return $this;
+ }
+
+ public function getEditMap() {
+ return $this->editMap;
+ }
+
+ public function renderCard($phid) {
+ $this->willRender();
+
+ $viewer = $this->getViewer();
+ $object = idx($this->getObjects(), $phid);
+
+ $card = id(new ProjectBoardTaskCard())
+ ->setViewer($viewer)
+ ->setTask($object)
+ ->setCanEdit($this->getCanEdit($phid));
+
+ $owner_phid = $object->getOwnerPHID();
+ if ($owner_phid) {
+ $owner_handle = $this->handles[$owner_phid];
+ $card->setOwner($owner_handle);
+ }
+
+ $project_phids = $object->getProjectPHIDs();
+ $project_handles = array_select_keys($this->handles, $project_phids);
+ if ($project_handles) {
+ $card->setProjectHandles($project_handles);
+ }
+
+ $cover_phid = $object->getCoverImageThumbnailPHID();
+ if ($cover_phid) {
+ $cover_file = idx($this->coverFiles, $cover_phid);
+ if ($cover_file) {
+ $card->setCoverImageFile($cover_file);
+ }
+ }
+
+ return $card;
+ }
+
+ private function willRender() {
+ if ($this->loaded) {
+ return;
+ }
+
+ $phids = array();
+ foreach ($this->objects as $object) {
+ $owner_phid = $object->getOwnerPHID();
+ if ($owner_phid) {
+ $phids[$owner_phid] = $owner_phid;
+ }
+
+ foreach ($object->getProjectPHIDs() as $phid) {
+ $phids[$phid] = $phid;
+ }
+ }
+
+ if ($this->excludedProjectPHIDs) {
+ foreach ($this->excludedProjectPHIDs as $excluded_phid) {
+ unset($phids[$excluded_phid]);
+ }
+ }
+
+ $viewer = $this->getViewer();
+
+ $handles = $viewer->loadHandles($phids);
+ $handles = iterator_to_array($handles);
+ $this->handles = $handles;
+
+ $cover_phids = array();
+ foreach ($this->objects as $object) {
+ $cover_phid = $object->getCoverImageThumbnailPHID();
+ if ($cover_phid) {
+ $cover_phids[$cover_phid] = $cover_phid;
+ }
+ }
+
+ if ($cover_phids) {
+ $cover_files = id(new PhabricatorFileQuery())
+ ->setViewer($viewer)
+ ->withPHIDs($cover_phids)
+ ->execute();
+ $cover_files = mpull($cover_files, null, 'getPHID');
+ } else {
+ $cover_files = array();
+ }
+
+ $this->coverFiles = $cover_files;
+
+ $this->loaded = true;
+ }
+
+ private function getCanEdit($phid) {
+ if ($this->editMap === null) {
+ return true;
+ }
+
+ return idx($this->editMap, $phid);
+ }
+
+}
diff --git a/src/applications/project/view/ProjectBoardTaskCard.php b/src/applications/project/view/ProjectBoardTaskCard.php
--- a/src/applications/project/view/ProjectBoardTaskCard.php
+++ b/src/applications/project/view/ProjectBoardTaskCard.php
@@ -7,6 +7,7 @@
private $task;
private $owner;
private $canEdit;
+ private $coverImageFile;
public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
@@ -25,6 +26,15 @@
return $this->projectHandles;
}
+ public function setCoverImageFile(PhabricatorFile $cover_image_file) {
+ $this->coverImageFile = $cover_image_file;
+ return $this;
+ }
+
+ public function getCoverImageFile() {
+ return $this->coverImageFile;
+ }
+
public function setTask(ManiphestTask $task) {
$this->task = $task;
return $this;
@@ -84,6 +94,11 @@
$card->addHandleIcon($owner, $owner->getName());
}
+ $cover_file = $this->getCoverImageFile();
+ if ($cover_file) {
+ $card->setCoverImage($cover_file->getBestURI());
+ }
+
if ($task->isClosed()) {
$icon = ManiphestTaskStatus::getStatusIcon($task->getStatus());
$icon = id(new PHUIIconView())

File Metadata

Mime Type
text/plain
Expires
Thu, Oct 24, 6:14 AM (3 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6726813
Default Alt Text
D15201.id36698.diff (15 KB)

Event Timeline