Choose default project image by icon
Summary: Builds out a map for icon->image in Projects, selects the icon's image as the default project image if there is no custom image chosen by the user. Test Plan: Select various icons, see image change. Test choose picture, pick a new image. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D18174
This commit is contained in:
@@ -56,4 +56,20 @@ final class PhabricatorFilesOnDiskBuiltinFile
|
|||||||
return $map;
|
return $map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getProjectBuiltinFiles() {
|
||||||
|
$root = dirname(phutil_get_library_root('phabricator'));
|
||||||
|
$root = $root.'/resources/builtin/projects/';
|
||||||
|
|
||||||
|
$map = array();
|
||||||
|
$list = id(new FileFinder($root))
|
||||||
|
->withType('f')
|
||||||
|
->withFollowSymlinks(true)
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($list as $file) {
|
||||||
|
$map[$file] = $root.$file;
|
||||||
|
}
|
||||||
|
return $map;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ a dictionary, which may contain these keys:
|
|||||||
- `key` //Required string.// Internal key identifying the icon.
|
- `key` //Required string.// Internal key identifying the icon.
|
||||||
- `name` //Required string.// Human-readable icon name.
|
- `name` //Required string.// Human-readable icon name.
|
||||||
- `icon` //Required string.// Specifies which actual icon image to use.
|
- `icon` //Required string.// Specifies which actual icon image to use.
|
||||||
|
- `image` //Optional string.// Selects a default image. Select an image from
|
||||||
|
`resources/builtins/projects/`.
|
||||||
- `default` //Optional bool.// Selects a default icon. Exactly one icon must
|
- `default` //Optional bool.// Selects a default icon. Exactly one icon must
|
||||||
be selected as the default.
|
be selected as the default.
|
||||||
- `disabled` //Optional bool.// If true, this icon will no longer be
|
- `disabled` //Optional bool.// If true, this icon will no longer be
|
||||||
|
|||||||
@@ -98,7 +98,10 @@ final class PhabricatorProjectEditPictureController
|
|||||||
$form = id(new PHUIFormLayoutView())
|
$form = id(new PHUIFormLayoutView())
|
||||||
->setUser($viewer);
|
->setUser($viewer);
|
||||||
|
|
||||||
$default_image = PhabricatorFile::loadBuiltin($viewer, 'project.png');
|
$builtin = PhabricatorProjectIconSet::getIconImage(
|
||||||
|
$project->getIcon());
|
||||||
|
$default_image = PhabricatorFile::loadBuiltin($this->getViewer(),
|
||||||
|
'projects/'.$builtin);
|
||||||
|
|
||||||
$images = array();
|
$images = array();
|
||||||
|
|
||||||
|
|||||||
@@ -296,10 +296,6 @@ final class PhabricatorProjectTransactionEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->getIsNewObject()) {
|
|
||||||
$this->setDefaultProfilePicture($object);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: We should dump an informational transaction onto the parent
|
// TODO: We should dump an informational transaction onto the parent
|
||||||
// project to show that we created the sub-thing.
|
// project to show that we created the sub-thing.
|
||||||
|
|
||||||
@@ -457,34 +453,6 @@ final class PhabricatorProjectTransactionEditor
|
|||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setDefaultProfilePicture(PhabricatorProject $project) {
|
|
||||||
if ($project->isMilestone()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$compose_color = $project->getDisplayIconComposeColor();
|
|
||||||
$compose_icon = $project->getDisplayIconComposeIcon();
|
|
||||||
|
|
||||||
$builtin = id(new PhabricatorFilesComposeIconBuiltinFile())
|
|
||||||
->setColor($compose_color)
|
|
||||||
->setIcon($compose_icon);
|
|
||||||
|
|
||||||
$data = $builtin->loadBuiltinFileData();
|
|
||||||
|
|
||||||
$file = PhabricatorFile::newFromFileData(
|
|
||||||
$data,
|
|
||||||
array(
|
|
||||||
'name' => $builtin->getBuiltinDisplayName(),
|
|
||||||
'profile' => true,
|
|
||||||
'canCDN' => true,
|
|
||||||
));
|
|
||||||
|
|
||||||
$project
|
|
||||||
->setProfileImagePHID($file->getPHID())
|
|
||||||
->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected function shouldApplyHeraldRules(
|
protected function shouldApplyHeraldRules(
|
||||||
PhabricatorLiskDAO $object,
|
PhabricatorLiskDAO $object,
|
||||||
array $xactions) {
|
array $xactions) {
|
||||||
|
|||||||
@@ -18,87 +18,104 @@ final class PhabricatorProjectIconSet
|
|||||||
'icon' => 'fa-briefcase',
|
'icon' => 'fa-briefcase',
|
||||||
'name' => pht('Project'),
|
'name' => pht('Project'),
|
||||||
'default' => true,
|
'default' => true,
|
||||||
|
'image' => 'v3/briefcase.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'tag',
|
'key' => 'tag',
|
||||||
'icon' => 'fa-tags',
|
'icon' => 'fa-tags',
|
||||||
'name' => pht('Tag'),
|
'name' => pht('Tag'),
|
||||||
|
'image' => 'v3/tag.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'policy',
|
'key' => 'policy',
|
||||||
'icon' => 'fa-lock',
|
'icon' => 'fa-lock',
|
||||||
'name' => pht('Policy'),
|
'name' => pht('Policy'),
|
||||||
|
'image' => 'v3/lock.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'group',
|
'key' => 'group',
|
||||||
'icon' => 'fa-users',
|
'icon' => 'fa-users',
|
||||||
'name' => pht('Group'),
|
'name' => pht('Group'),
|
||||||
|
'image' => 'v3/people.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'folder',
|
'key' => 'folder',
|
||||||
'icon' => 'fa-folder',
|
'icon' => 'fa-folder',
|
||||||
'name' => pht('Folder'),
|
'name' => pht('Folder'),
|
||||||
|
'image' => 'v3/folder.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'timeline',
|
'key' => 'timeline',
|
||||||
'icon' => 'fa-calendar',
|
'icon' => 'fa-calendar',
|
||||||
'name' => pht('Timeline'),
|
'name' => pht('Timeline'),
|
||||||
|
'image' => 'v3/calendar.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'goal',
|
'key' => 'goal',
|
||||||
'icon' => 'fa-flag-checkered',
|
'icon' => 'fa-flag-checkered',
|
||||||
'name' => pht('Goal'),
|
'name' => pht('Goal'),
|
||||||
|
'image' => 'v3/flag.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'release',
|
'key' => 'release',
|
||||||
'icon' => 'fa-truck',
|
'icon' => 'fa-truck',
|
||||||
'name' => pht('Release'),
|
'name' => pht('Release'),
|
||||||
|
'image' => 'v3/truck.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'bugs',
|
'key' => 'bugs',
|
||||||
'icon' => 'fa-bug',
|
'icon' => 'fa-bug',
|
||||||
'name' => pht('Bugs'),
|
'name' => pht('Bugs'),
|
||||||
|
'image' => 'v3/bug.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'cleanup',
|
'key' => 'cleanup',
|
||||||
'icon' => 'fa-trash-o',
|
'icon' => 'fa-trash-o',
|
||||||
'name' => pht('Cleanup'),
|
'name' => pht('Cleanup'),
|
||||||
|
'image' => 'v3/trash.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'umbrella',
|
'key' => 'umbrella',
|
||||||
'icon' => 'fa-umbrella',
|
'icon' => 'fa-umbrella',
|
||||||
'name' => pht('Umbrella'),
|
'name' => pht('Umbrella'),
|
||||||
|
'image' => 'v3/umbrella.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'communication',
|
'key' => 'communication',
|
||||||
'icon' => 'fa-envelope',
|
'icon' => 'fa-envelope',
|
||||||
'name' => pht('Communication'),
|
'name' => pht('Communication'),
|
||||||
|
'image' => 'v3/mail.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'organization',
|
'key' => 'organization',
|
||||||
'icon' => 'fa-building',
|
'icon' => 'fa-building',
|
||||||
'name' => pht('Organization'),
|
'name' => pht('Organization'),
|
||||||
|
'image' => 'v3/organization.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'infrastructure',
|
'key' => 'infrastructure',
|
||||||
'icon' => 'fa-cloud',
|
'icon' => 'fa-cloud',
|
||||||
'name' => pht('Infrastructure'),
|
'name' => pht('Infrastructure'),
|
||||||
|
'image' => 'v3/cloud.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'account',
|
'key' => 'account',
|
||||||
'icon' => 'fa-credit-card',
|
'icon' => 'fa-credit-card',
|
||||||
'name' => pht('Account'),
|
'name' => pht('Account'),
|
||||||
|
'image' => 'v3/creditcard.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'experimental',
|
'key' => 'experimental',
|
||||||
'icon' => 'fa-flask',
|
'icon' => 'fa-flask',
|
||||||
'name' => pht('Experimental'),
|
'name' => pht('Experimental'),
|
||||||
|
'image' => 'v3/experimental.png',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'key' => 'milestone',
|
'key' => 'milestone',
|
||||||
'icon' => 'fa-map-marker',
|
'icon' => 'fa-map-marker',
|
||||||
'name' => pht('Milestone'),
|
'name' => pht('Milestone'),
|
||||||
'special' => self::SPECIAL_MILESTONE,
|
'special' => self::SPECIAL_MILESTONE,
|
||||||
|
'image' => 'v3/marker.png',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -149,6 +166,11 @@ final class PhabricatorProjectIconSet
|
|||||||
return idx($spec, 'name', null);
|
return idx($spec, 'name', null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getIconImage($key) {
|
||||||
|
$spec = self::getIconSpec($key);
|
||||||
|
return idx($spec, 'image', 'v3/briefcase.png');
|
||||||
|
}
|
||||||
|
|
||||||
private static function getIconSpec($key) {
|
private static function getIconSpec($key) {
|
||||||
$icons = self::getIconSpecifications();
|
$icons = self::getIconSpecifications();
|
||||||
foreach ($icons as $icon) {
|
foreach ($icons as $icon) {
|
||||||
@@ -190,6 +212,7 @@ final class PhabricatorProjectIconSet
|
|||||||
'key' => 'string',
|
'key' => 'string',
|
||||||
'name' => 'string',
|
'name' => 'string',
|
||||||
'icon' => 'string',
|
'icon' => 'string',
|
||||||
|
'image' => 'optional string',
|
||||||
'special' => 'optional string',
|
'special' => 'optional string',
|
||||||
'disabled' => 'optional bool',
|
'disabled' => 'optional bool',
|
||||||
'default' => 'optional bool',
|
'default' => 'optional bool',
|
||||||
@@ -239,6 +262,25 @@ final class PhabricatorProjectIconSet
|
|||||||
|
|
||||||
$is_disabled = idx($value, 'disabled');
|
$is_disabled = idx($value, 'disabled');
|
||||||
|
|
||||||
|
if (idx($value, 'image')) {
|
||||||
|
$builtin = idx($value, 'image');
|
||||||
|
$builtin_map = id(new PhabricatorFilesOnDiskBuiltinFile())
|
||||||
|
->getProjectBuiltinFiles();
|
||||||
|
$builtin_map = array_flip($builtin_map);
|
||||||
|
|
||||||
|
$root = dirname(phutil_get_library_root('phabricator'));
|
||||||
|
$image = $root.'/resources/builtin/projects/'.$builtin;
|
||||||
|
|
||||||
|
if (!array_key_exists($image, $builtin_map)) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'The project image ("%s") specified for ("%s") '.
|
||||||
|
'was not found in the folder "resources/builtin/projects/".',
|
||||||
|
$builtin,
|
||||||
|
$key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (idx($value, 'default')) {
|
if (idx($value, 'default')) {
|
||||||
if ($default === null) {
|
if ($default === null) {
|
||||||
if ($is_disabled) {
|
if ($is_disabled) {
|
||||||
|
|||||||
@@ -358,8 +358,6 @@ final class PhabricatorProjectQuery
|
|||||||
|
|
||||||
protected function didFilterPage(array $projects) {
|
protected function didFilterPage(array $projects) {
|
||||||
if ($this->needImages) {
|
if ($this->needImages) {
|
||||||
$default = null;
|
|
||||||
|
|
||||||
$file_phids = mpull($projects, 'getProfileImagePHID');
|
$file_phids = mpull($projects, 'getProfileImagePHID');
|
||||||
$file_phids = array_filter($file_phids);
|
$file_phids = array_filter($file_phids);
|
||||||
if ($file_phids) {
|
if ($file_phids) {
|
||||||
@@ -376,12 +374,10 @@ final class PhabricatorProjectQuery
|
|||||||
foreach ($projects as $project) {
|
foreach ($projects as $project) {
|
||||||
$file = idx($files, $project->getProfileImagePHID());
|
$file = idx($files, $project->getProfileImagePHID());
|
||||||
if (!$file) {
|
if (!$file) {
|
||||||
if (!$default) {
|
$builtin = PhabricatorProjectIconSet::getIconImage(
|
||||||
$default = PhabricatorFile::loadBuiltin(
|
$project->getIcon());
|
||||||
$this->getViewer(),
|
$file = PhabricatorFile::loadBuiltin($this->getViewer(),
|
||||||
'project.png');
|
'projects/'.$builtin);
|
||||||
}
|
|
||||||
$file = $default;
|
|
||||||
}
|
}
|
||||||
$project->attachProfileImageFile($file);
|
$project->attachProfileImageFile($file);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user