Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14015662
D15201.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
15 KB
Referenced Files
None
Subscribers
None
D15201.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Mon, Nov 4, 11:30 PM (1 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6726813
Default Alt Text
D15201.diff (15 KB)
Attached To
Mode
D15201: Add storage and read logic for workboard card cover photos
Attached
Detach File
Event Timeline
Log In to Comment