1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-18 11:30:55 +01:00

Add storage and read logic for workboard card cover photos

Summary:
No way to set photos yet, but if you magic them in they work.

Primarily, this consolidates rendering logic so the move + edit + view controllers all run the same code to do tags / cover photos.

Test Plan: {F1095870}

Reviewers: chad

Reviewed By: chad

Differential Revision: https://secure.phabricator.com/D15201
This commit is contained in:
epriestley 2016-02-06 13:02:13 -08:00
parent f097c9c595
commit b6a38b403c
9 changed files with 237 additions and 87 deletions

View file

@ -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 = '';

View file

@ -1815,6 +1815,7 @@ phutil_register_library_map(array(
'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 @@ phutil_register_library_map(array(
'PhabricatorBinariesSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorBitbucketAuthProvider' => 'PhabricatorOAuth1AuthProvider',
'PhabricatorBoardLayoutEngine' => 'Phobject',
'PhabricatorBoardRenderingEngine' => 'Phobject',
'PhabricatorBot' => 'PhabricatorDaemon',
'PhabricatorBotChannel' => 'PhabricatorBotTarget',
'PhabricatorBotDebugLogHandler' => 'PhabricatorBotHandler',

View file

@ -7,6 +7,7 @@ final class PhabricatorFileThumbnailTransform
const TRANSFORM_PINBOARD = 'pinboard';
const TRANSFORM_THUMBGRID = 'thumbgrid';
const TRANSFORM_PREVIEW = 'preview';
const TRANSFORM_WORKCARD = 'workcard';
private $name;
private $key;
@ -73,6 +74,10 @@ final class PhabricatorFileThumbnailTransform
->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),
);
}

View file

@ -334,39 +334,27 @@ final class ManiphestEditEngine
'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,
));
}

View file

@ -38,6 +38,7 @@ final class ManiphestTask extends ManiphestDAO
protected $ownerOrdering;
protected $spacePHID;
protected $properties = array();
private $subscriberPHIDs = self::ATTACHABLE;
private $groupByProjectPHID = self::ATTACHABLE;
@ -74,6 +75,7 @@ final class ManiphestTask extends ManiphestDAO
'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 @@ final class ManiphestTask extends ManiphestDAO
);
}
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 )----------------------------------- */

View file

@ -7,7 +7,6 @@ final class PhabricatorProjectBoardViewController
private $id;
private $slug;
private $handles;
private $queryKey;
private $filter;
private $sortKey;
@ -226,22 +225,9 @@ final class PhabricatorProjectBoardViewController
'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 @@ final class PhabricatorProjectBoardViewController
$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 @@ final class PhabricatorProjectBoardViewController
));
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);
}

View file

@ -175,24 +175,11 @@ final class PhabricatorProjectMoveController
$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 @@ final class PhabricatorProjectMoveController
}
}
$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,
));
}
}

View file

@ -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);
}
}

View file

@ -7,6 +7,7 @@ final class ProjectBoardTaskCard extends Phobject {
private $task;
private $owner;
private $canEdit;
private $coverImageFile;
public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
@ -25,6 +26,15 @@ final class ProjectBoardTaskCard extends Phobject {
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 @@ final class ProjectBoardTaskCard extends Phobject {
$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())