Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/files/controller/PhabricatorFileComposeController.php b/src/applications/files/controller/PhabricatorFileComposeController.php
index d698509e96..c3351e045f 100644
--- a/src/applications/files/controller/PhabricatorFileComposeController.php
+++ b/src/applications/files/controller/PhabricatorFileComposeController.php
@@ -1,250 +1,338 @@
<?php
final class PhabricatorFileComposeController
extends PhabricatorFileController {
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
$colors = array(
'red' => pht('Verbillion'),
'orange' => pht('Navel Orange'),
'yellow' => pht('Prim Goldenrod'),
'green' => pht('Lustrous Verdant'),
'blue' => pht('Tropical Deep'),
'sky' => pht('Wide Open Sky'),
'indigo' => pht('Pleated Khaki'),
'violet' => pht('Aged Merlot'),
+ 'pink' => pht('Easter Bunny'),
'charcoal' => pht('Gemstone'),
'backdrop' => pht('Driven Snow'),
);
$manifest = PHUIIconView::getSheetManifest(PHUIIconView::SPRITE_PROJECTS);
if ($request->isFormPost()) {
- $icon = $request->getStr('icon');
- $color = $request->getStr('color');
+ $project_phid = $request->getStr('projectPHID');
+ if ($project_phid) {
+ $project = id(new PhabricatorProjectQuery())
+ ->setViewer($viewer)
+ ->withPHIDs(array($project_phid))
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+ if (!$project) {
+ return new Aphront404Response();
+ }
+ $icon = $project->getIcon();
+ $color = $project->getColor();
+ switch ($color) {
+ case 'grey':
+ $color = 'charcoal';
+ break;
+ case 'checkered':
+ $color = 'backdrop';
+ break;
+ }
+ } else {
+ $icon = $request->getStr('icon');
+ $color = $request->getStr('color');
+ }
- if (isset($colors[$color]) && isset($manifest['projects-'.$icon])) {
- $root = dirname(phutil_get_library_root('phabricator'));
- $icon_file = $root.'/resources/sprite/projects_1x/'.$icon.'.png';
- $icon_data = Filesystem::readFile($icon_file);
+ if (!isset($colors[$color]) || !isset($manifest['projects-'.$icon])) {
+ return new Aphront404Response();
+ }
+ $root = dirname(phutil_get_library_root('phabricator'));
+ $icon_file = $root.'/resources/sprite/projects_1x/'.$icon.'.png';
+ $icon_data = Filesystem::readFile($icon_file);
- $data = $this->composeImage($color, $icon_data);
- $file = PhabricatorFile::buildFromFileDataOrHash(
- $data,
- array(
- 'name' => 'project.png',
- 'canCDN' => true,
- ));
+ $data = $this->composeImage($color, $icon_data);
+
+ $file = PhabricatorFile::buildFromFileDataOrHash(
+ $data,
+ array(
+ 'name' => 'project.png',
+ 'canCDN' => true,
+ ));
+
+ if ($project_phid) {
+ $edit_uri = '/project/edit/'.$project->getID().'/';
+ $xactions = array();
+ $xactions[] = id(new PhabricatorProjectTransaction())
+ ->setTransactionType(PhabricatorProjectTransaction::TYPE_IMAGE)
+ ->setNewValue($file->getPHID());
+
+ $editor = id(new PhabricatorProjectTransactionEditor())
+ ->setActor($viewer)
+ ->setContentSourceFromRequest($request)
+ ->setContinueOnMissingFields(true)
+ ->setContinueOnNoEffect(true);
+
+ $editor->applyTransactions($project, $xactions);
+
+ return id(new AphrontRedirectResponse())->setURI($edit_uri);
+ } else {
$content = array(
'phid' => $file->getPHID(),
);
return id(new AphrontAjaxResponse())->setContent($content);
}
}
$value_color = head_key($colors);
$value_icon = head_key($manifest);
$value_icon = substr($value_icon, strlen('projects-'));
require_celerity_resource('people-profile-css');
$buttons = array();
foreach ($colors as $color => $name) {
$buttons[] = javelin_tag(
'button',
array(
'class' => 'grey profile-image-button',
'sigil' => 'has-tooltip compose-select-color',
'style' => 'margin: 0 8px 8px 0',
'meta' => array(
'color' => $color,
'tip' => $name,
),
),
id(new PHUIIconView())
->addClass('compose-background-'.$color));
}
+ $sort_these_first = array(
+ 'projects-fa-briefcase',
+ 'projects-fa-tags',
+ 'projects-fa-folder',
+ 'projects-fa-group',
+ 'projects-fa-bug',
+ 'projects-fa-trash-o',
+ 'projects-fa-calendar',
+ 'projects-fa-flag-checkered',
+ 'projects-fa-envelope',
+ 'projects-fa-truck',
+ 'projects-fa-lock',
+ 'projects-fa-umbrella',
+ 'projects-fa-cloud',
+ 'projects-fa-building',
+ 'projects-fa-credit-card',
+ 'projects-fa-flask',
+ );
+
+ $manifest = array_select_keys(
+ $manifest,
+ $sort_these_first)
+ + $manifest;
+
$icons = array();
$icon_quips = array(
'8ball' => pht('Take a Risk'),
'alien' => pht('Foreign Interface'),
'announce' => pht('Louder is Better'),
'art' => pht('Unique Snowflake'),
'award' => pht('Shooting Star'),
'bacon' => pht('Healthy Vegetables'),
'bandaid' => pht('Durable Infrastructure'),
'beer' => pht('Healthy Vegetable Juice'),
'bomb' => pht('Imminent Success'),
'briefcase' => pht('Adventure Pack'),
'bug' => pht('Costumed Egg'),
'calendar' => pht('Everyone Loves Meetings'),
'cloud' => pht('Water Cycle'),
'coffee' => pht('Half-Whip Nonfat Soy Latte'),
'creditcard' => pht('Expense It'),
'death' => pht('Calcium Promotes Bone Health'),
'desktop' => pht('Magical Portal'),
'dropbox' => pht('Cardboard Box'),
'education' => pht('Debt'),
'experimental' => pht('CAUTION: Dangerous Chemicals'),
'facebook' => pht('Popular Social Network'),
'facility' => pht('Pollution Solves Problems'),
'film' => pht('Actual Physical Film'),
'forked' => pht('You Can\'t Eat Soup'),
'games' => pht('Serious Business'),
'ghost' => pht('Haunted'),
'gift' => pht('Surprise!'),
'globe' => pht('Scanner Sweep'),
'golf' => pht('Business Meeting'),
'heart' => pht('Undergoing a Major Surgery'),
'intergalactic' => pht('Jupiter'),
'lock' => pht('Extremely Secret'),
'mail' => pht('Oragami'),
'martini' => pht('Healthy Olive Drink'),
'medical' => pht('Medic!'),
'mobile' => pht('Cellular Telephone'),
'music' => pht("\xE2\x99\xAB"),
'news' => pht('Actual Physical Newspaper'),
'orgchart' => pht('It\'s Good to be King'),
'peoples' => pht('Angel and Devil'),
'piechart' => pht('Actual Physical Pie'),
'poison' => pht('Healthy Bone Juice'),
'putabirdonit' => pht('Put a Bird On It'),
'radiate' => pht('Radiant Beauty'),
'savings' => pht('Oink Oink'),
'search' => pht('Sleuthing'),
'shield' => pht('Royal Crest'),
'speed' => pht('Slow and Steady'),
'sprint' => pht('Fire Exit'),
'star' => pht('The More You Know'),
'storage' => pht('Stack of Pancakes'),
'tablet' => pht('Cellular Telephone For Giants'),
'travel' => pht('Pretty Clearly an Airplane'),
'twitter' => pht('Bird Stencil'),
'warning' => pht('No Caution Required, Everything Looks Safe'),
'whale' => pht('Friendly Walrus'),
+ 'fa-flask' => pht('Experimental'),
+ 'fa-briefcase' => pht('Briefcase'),
+ 'fa-bug' => pht('Bug'),
+ 'fa-building' => pht('Company'),
+ 'fa-calendar' => pht('Deadline'),
+ 'fa-cloud' => pht('The Cloud'),
+ 'fa-credit-card' => pht('Accounting'),
+ 'fa-envelope' => pht('Communication'),
+ 'fa-flag-checkered' => pht('Goal'),
+ 'fa-folder' => pht('Folder'),
+ 'fa-group' => pht('Team'),
+ 'fa-lock' => pht('Policy'),
+ 'fa-tags' => pht('Tag'),
+ 'fa-trash-o' => pht('Garbage'),
+ 'fa-truck' => pht('Release'),
+ 'fa-umbrella' => pht('An Umbrella'),
);
foreach ($manifest as $icon => $spec) {
$icon = substr($icon, strlen('projects-'));
$icons[] = javelin_tag(
'button',
array(
'class' => 'grey profile-image-button',
'sigil' => 'has-tooltip compose-select-icon',
'style' => 'margin: 0 8px 8px 0',
'meta' => array(
'icon' => $icon,
'tip' => idx($icon_quips, $icon, $icon),
),
),
id(new PHUIIconView())
->setSpriteIcon($icon)
->setSpriteSheet(PHUIIconView::SPRITE_PROJECTS));
}
$dialog_id = celerity_generate_unique_node_id();
$color_input_id = celerity_generate_unique_node_id();;
$icon_input_id = celerity_generate_unique_node_id();
$preview_id = celerity_generate_unique_node_id();
$preview = id(new PHUIIconView())
->setID($preview_id)
->addClass('compose-background-'.$value_color)
->setSpriteIcon($value_icon)
->setSpriteSheet(PHUIIconView::SPRITE_PROJECTS);
$color_input = javelin_tag(
'input',
array(
'type' => 'hidden',
'name' => 'color',
'value' => $value_color,
'id' => $color_input_id,
));
$icon_input = javelin_tag(
'input',
array(
'type' => 'hidden',
'name' => 'icon',
'value' => $value_icon,
'id' => $icon_input_id,
));
Javelin::initBehavior('phabricator-tooltips');
Javelin::initBehavior(
'icon-composer',
array(
'dialogID' => $dialog_id,
'colorInputID' => $color_input_id,
'iconInputID' => $icon_input_id,
'previewID' => $preview_id,
'defaultColor' => $value_color,
'defaultIcon' => $value_icon,
));
$dialog = id(new AphrontDialogView())
->setUser($viewer)
->setFormID($dialog_id)
->setClass('compose-dialog')
->setTitle(pht('Compose Image'))
->appendChild(
phutil_tag(
'div',
array(
'class' => 'compose-header',
),
pht('Choose Background Color')))
->appendChild($buttons)
->appendChild(
phutil_tag(
'div',
array(
'class' => 'compose-header',
),
pht('Choose Icon')))
->appendChild($icons)
->appendChild(
phutil_tag(
'div',
array(
'class' => 'compose-header',
),
pht('Preview')))
->appendChild($preview)
->appendChild($color_input)
->appendChild($icon_input)
->addCancelButton('/')
->addSubmitButton(pht('Save Image'));
return id(new AphrontDialogResponse())->setDialog($dialog);
}
private function composeImage($color, $icon_data) {
$icon_img = imagecreatefromstring($icon_data);
$map = CelerityResourceTransformer::getCSSVariableMap();
$color_string = idx($map, $color, '#ff00ff');
$color_const = hexdec(trim($color_string, '#'));
$canvas = imagecreatetruecolor(50, 50);
imagefill($canvas, 0, 0, $color_const);
imagecopy($canvas, $icon_img, 0, 0, 0, 0, 50, 50);
return PhabricatorImageTransformer::saveImageDataInAnyFormat(
$canvas,
'image/png');
}
}
diff --git a/src/applications/project/controller/PhabricatorProjectEditPictureController.php b/src/applications/project/controller/PhabricatorProjectEditPictureController.php
index 53d5c4cbe1..44a71780d0 100644
--- a/src/applications/project/controller/PhabricatorProjectEditPictureController.php
+++ b/src/applications/project/controller/PhabricatorProjectEditPictureController.php
@@ -1,273 +1,305 @@
<?php
final class PhabricatorProjectEditPictureController
extends PhabricatorProjectController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
$project = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->withIDs(array($this->id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$project) {
return new Aphront404Response();
}
$edit_uri = $this->getApplicationURI('edit/'.$project->getID().'/');
$view_uri = $this->getApplicationURI('view/'.$project->getID().'/');
$supported_formats = PhabricatorFile::getTransformableImageFormats();
$e_file = true;
$errors = array();
if ($request->isFormPost()) {
$phid = $request->getStr('phid');
$is_default = false;
if ($phid == PhabricatorPHIDConstants::PHID_VOID) {
$phid = null;
$is_default = true;
} else if ($phid) {
$file = id(new PhabricatorFileQuery())
->setViewer($viewer)
->withPHIDs(array($phid))
->executeOne();
} else {
if ($request->getFileExists('picture')) {
$file = PhabricatorFile::newFromPHPUpload(
$_FILES['picture'],
array(
'authorPHID' => $viewer->getPHID(),
'canCDN' => true,
));
} else {
$e_file = pht('Required');
$errors[] = pht(
'You must choose a file when uploading a new project picture.');
}
}
if (!$errors && !$is_default) {
if (!$file->isTransformableImage()) {
$e_file = pht('Not Supported');
$errors[] = pht(
'This server only supports these image formats: %s.',
implode(', ', $supported_formats));
} else {
$xformer = new PhabricatorImageTransformer();
$xformed = $xformer->executeProfileTransform(
$file,
$width = 50,
$min_height = 50,
$max_height = 50);
}
}
if (!$errors) {
if ($is_default) {
$new_value = null;
} else {
$new_value = $xformed->getPHID();
}
$xactions = array();
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_IMAGE)
->setNewValue($new_value);
$editor = id(new PhabricatorProjectTransactionEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnMissingFields(true)
->setContinueOnNoEffect(true);
$editor->applyTransactions($project, $xactions);
return id(new AphrontRedirectResponse())->setURI($edit_uri);
}
}
$title = pht('Edit Project Picture');
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($project->getName(), $view_uri);
$crumbs->addTextCrumb(pht('Edit'), $edit_uri);
$crumbs->addTextCrumb(pht('Picture'));
$form = id(new PHUIFormLayoutView())
->setUser($viewer);
$default_image = PhabricatorFile::loadBuiltin($viewer, 'project.png');
$images = array();
$current = $project->getProfileImagePHID();
$has_current = false;
if ($current) {
$files = id(new PhabricatorFileQuery())
->setViewer($viewer)
->withPHIDs(array($current))
->execute();
if ($files) {
$file = head($files);
if ($file->isTransformableImage()) {
$has_current = true;
$images[$current] = array(
'uri' => $file->getBestURI(),
'tip' => pht('Current Picture'),
);
}
}
}
$images[PhabricatorPHIDConstants::PHID_VOID] = array(
'uri' => $default_image->getBestURI(),
'tip' => pht('Default Picture'),
);
require_celerity_resource('people-profile-css');
Javelin::initBehavior('phabricator-tooltips', array());
$buttons = array();
foreach ($images as $phid => $spec) {
$button = javelin_tag(
'button',
array(
'class' => 'grey profile-image-button',
'sigil' => 'has-tooltip',
'meta' => array(
'tip' => $spec['tip'],
'size' => 300,
),
),
phutil_tag(
'img',
array(
'height' => 50,
'width' => 50,
'src' => $spec['uri'],
)));
$button = array(
phutil_tag(
'input',
array(
'type' => 'hidden',
'name' => 'phid',
'value' => $phid,
)),
$button,
);
$button = phabricator_form(
$viewer,
array(
'class' => 'profile-image-form',
'method' => 'POST',
),
$button);
$buttons[] = $button;
}
if ($has_current) {
$form->appendChild(
id(new AphrontFormMarkupControl())
->setLabel(pht('Current Picture'))
->setValue(array_shift($buttons)));
}
$form->appendChild(
id(new AphrontFormMarkupControl())
->setLabel(pht('Use Picture'))
->setValue($buttons));
$launch_id = celerity_generate_unique_node_id();
$input_id = celerity_generate_unique_node_id();
Javelin::initBehavior(
'launch-icon-composer',
array(
'launchID' => $launch_id,
'inputID' => $input_id,
));
$compose_button = javelin_tag(
'button',
array(
'class' => 'grey',
'id' => $launch_id,
'sigil' => 'icon-composer',
),
pht('Choose Icon and Color...'));
$compose_input = javelin_tag(
'input',
array(
'type' => 'hidden',
'id' => $input_id,
'name' => 'phid',
));
$compose_form = phabricator_form(
$viewer,
array(
'class' => 'profile-image-form',
'method' => 'POST',
),
array(
$compose_input,
$compose_button,
));
$form->appendChild(
id(new AphrontFormMarkupControl())
->setLabel(pht('Quick Create'))
->setValue($compose_form));
+ $default_button = javelin_tag(
+ 'button',
+ array(
+ 'class' => 'grey',
+ ),
+ pht('Use Project Icon'));
+
+ $default_input = javelin_tag(
+ 'input',
+ array(
+ 'type' => 'hidden',
+ 'name' => 'projectPHID',
+ 'value' => $project->getPHID(),
+ ));
+
+ $default_form = phabricator_form(
+ $viewer,
+ array(
+ 'class' => 'profile-image-form',
+ 'method' => 'POST',
+ 'action' => '/file/compose/',
+ ),
+ array(
+ $default_input,
+ $default_button,
+ ));
+
+ $form->appendChild(
+ id(new AphrontFormMarkupControl())
+ ->setLabel(pht('Use Default'))
+ ->setValue($default_form));
+
$upload_form = id(new AphrontFormView())
->setUser($viewer)
->setEncType('multipart/form-data')
->appendChild(
id(new AphrontFormFileControl())
->setName('picture')
->setLabel(pht('Upload Picture'))
->setError($e_file)
->setCaption(
pht('Supported formats: %s', implode(', ', $supported_formats))))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($edit_uri)
->setValue(pht('Upload Picture')));
$form_box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setFormErrors($errors)
->setForm($form);
$upload_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Upload New Picture'))
->setForm($upload_form);
return $this->buildApplicationPage(
array(
$crumbs,
$form_box,
$upload_box,
),
array(
'title' => $title,
));
}
}
diff --git a/webroot/rsrc/css/application/people/people-profile.css b/webroot/rsrc/css/application/people/people-profile.css
index bc0e61fbf9..089402b4d7 100644
--- a/webroot/rsrc/css/application/people/people-profile.css
+++ b/webroot/rsrc/css/application/people/people-profile.css
@@ -1,78 +1,82 @@
/**
* @provides people-profile-css
*/
form.profile-image-form {
display: inline-block;
margin: 0 8px 8px 0;
}
button.profile-image-button {
padding: 4px;
margin: 0;
}
.compose-dialog button.profile-image-button-selected {
background-image: none;
background-color: {$lightblue};
border-color: {$blueborder};
}
.compose-header {
color: {$bluetext};
border-bottom: 1px solid {$lightblueborder};
padding: 4px 0;
margin: 0 0 8px;
}
form.compose-dialog {
width: 80%;
}
.compose-dialog .phui-icon-view {
display: block;
position: relative;
width: 50px;
height: 50px;
background-color: {$darkgreytext};
}
.compose-dialog .compose-background-red {
background-color: {$red};
}
.compose-dialog .compose-background-orange {
background-color: {$orange};
}
.compose-dialog .compose-background-yellow {
background-color: {$yellow};
}
.compose-dialog .compose-background-green {
background-color: {$green};
}
.compose-dialog .compose-background-blue {
background-color: {$blue};
}
.compose-dialog .compose-background-sky {
background-color: {$sky};
}
.compose-dialog .compose-background-indigo {
background-color: {$indigo};
}
.compose-dialog .compose-background-violet {
background-color: {$violet};
}
+.compose-dialog .compose-background-pink {
+ background-color: {$pink};
+}
+
.compose-dialog .compose-background-charcoal {
background-color: {$charcoal};
}
.compose-dialog .compose-background-backdrop {
background-color: {$backdrop};
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Nov 5, 10:57 PM (23 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
321311
Default Alt Text
(22 KB)

Event Timeline