Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/people/cache/PhabricatorUserProfileImageCacheType.php b/src/applications/people/cache/PhabricatorUserProfileImageCacheType.php
index b3f944a3ed..e2a535cdd4 100644
--- a/src/applications/people/cache/PhabricatorUserProfileImageCacheType.php
+++ b/src/applications/people/cache/PhabricatorUserProfileImageCacheType.php
@@ -1,82 +1,120 @@
<?php
final class PhabricatorUserProfileImageCacheType
extends PhabricatorUserCacheType {
const CACHETYPE = 'user.profile';
const KEY_URI = 'user.profile.image.uri.v1';
public function getAutoloadKeys() {
return array(
self::KEY_URI,
);
}
public function canManageKey($key) {
return ($key === self::KEY_URI);
}
public function getDefaultValue() {
return PhabricatorUser::getDefaultProfileImageURI();
}
public function newValueForUsers($key, array $users) {
$viewer = $this->getViewer();
- $file_phids = mpull($users, 'getProfileImagePHID');
- $file_phids = array_filter($file_phids);
+ $file_phids = array();
+ $generate_users = array();
+ foreach ($users as $user) {
+ $user_phid = $user->getPHID();
+ $custom_phid = $user->getProfileImagePHID();
+ $default_phid = $user->getDefaultProfileImagePHID();
+ $version = $user->getDefaultProfileImageVersion();
+
+ if ($custom_phid) {
+ $file_phids[$user_phid] = $custom_phid;
+ continue;
+ }
+ if ($default_phid) {
+ if ($version == PhabricatorFilesComposeAvatarBuiltinFile::VERSION) {
+ $file_phids[$user_phid] = $default_phid;
+ continue;
+ }
+ }
+ $generate_users[] = $user;
+ }
+
+ // Generate Files for anyone without a default
+ foreach ($generate_users as $generate_user) {
+ $generate_user_phid = $generate_user->getPHID();
+ $generate_username = $generate_user->getUsername();
+ $generate_version = PhabricatorFilesComposeAvatarBuiltinFile::VERSION;
+ $generate_file = id(new PhabricatorFilesComposeAvatarBuiltinFile())
+ ->getUserProfileImageFile($generate_username);
+
+ $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
+ $generate_user->setDefaultProfileImagePHID($generate_file->getPHID());
+ $generate_user->setDefaultProfileImageVersion($generate_version);
+ $generate_user->save();
+ unset($unguarded);
+
+ $file_phids[$generate_user_phid] = $generate_file->getPHID();
+ }
if ($file_phids) {
$files = id(new PhabricatorFileQuery())
->setViewer($viewer)
->withPHIDs($file_phids)
->execute();
$files = mpull($files, null, 'getPHID');
} else {
$files = array();
}
$results = array();
foreach ($users as $user) {
$image_phid = $user->getProfileImagePHID();
+ $default_phid = $user->getDefaultProfileImagePHID();
if (isset($files[$image_phid])) {
$image_uri = $files[$image_phid]->getBestURI();
+ } else if (isset($files[$default_phid])) {
+ $image_uri = $files[$default_phid]->getBestURI();
} else {
$image_uri = PhabricatorUser::getDefaultProfileImageURI();
}
$user_phid = $user->getPHID();
$version = $this->getCacheVersion($user);
$results[$user_phid] = "{$version},{$image_uri}";
}
return $results;
}
public function getValueFromStorage($value) {
$parts = explode(',', $value, 2);
return end($parts);
}
public function shouldValidateRawCacheData() {
return true;
}
public function isRawCacheDataValid(PhabricatorUser $user, $key, $data) {
$parts = explode(',', $data, 2);
$version = reset($parts);
return ($version === $this->getCacheVersion($user));
}
private function getCacheVersion(PhabricatorUser $user) {
$parts = array(
PhabricatorEnv::getCDNURI('/'),
PhabricatorEnv::getEnvConfig('cluster.instance'),
$user->getProfileImagePHID(),
);
$parts = serialize($parts);
return PhabricatorHash::digestForIndex($parts);
}
}
diff --git a/src/applications/people/controller/PhabricatorPeopleProfilePictureController.php b/src/applications/people/controller/PhabricatorPeopleProfilePictureController.php
index 1532003122..cff833aa51 100644
--- a/src/applications/people/controller/PhabricatorPeopleProfilePictureController.php
+++ b/src/applications/people/controller/PhabricatorPeopleProfilePictureController.php
@@ -1,313 +1,292 @@
<?php
final class PhabricatorPeopleProfilePictureController
extends PhabricatorPeopleProfileController {
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$id = $request->getURIData('id');
$user = id(new PhabricatorPeopleQuery())
->setViewer($viewer)
->withIDs(array($id))
->needProfileImage(true)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$user) {
return new Aphront404Response();
}
$this->setUser($user);
$name = $user->getUserName();
$done_uri = '/p/'.$name.'/';
$supported_formats = PhabricatorFile::getTransformableImageFormats();
$e_file = true;
$errors = array();
- // Verify install has GD extension, otherwise default to avatar.png
- $gd = function_exists('imagecreatefromstring');
-
if ($request->isFormPost()) {
$phid = $request->getStr('phid');
$is_default = false;
if ($phid == PhabricatorPHIDConstants::PHID_VOID) {
- // Compose the builtin unique image
- if ($gd) {
- $file = id(new PhabricatorFilesComposeAvatarBuiltinFile())
- ->getUserProfileImageFile($name);
- } else {
- $phid = null;
- $is_default = true;
- }
-
+ $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 profile 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 {
$xform = PhabricatorFileTransform::getTransformByKey(
PhabricatorFileThumbnailTransform::TRANSFORM_PROFILE);
$xformed = $xform->executeTransform($file);
}
}
if (!$errors) {
if ($is_default) {
$user->setProfileImagePHID(null);
} else {
$user->setProfileImagePHID($xformed->getPHID());
$xformed->attachToObject($user->getPHID());
}
$user->save();
return id(new AphrontRedirectResponse())->setURI($done_uri);
}
}
$title = pht('Edit Profile Picture');
$form = id(new PHUIFormLayoutView())
->setUser($viewer);
- if ($gd) {
- $unique_default = id(new PhabricatorFilesComposeAvatarBuiltinFile())
- ->getUniqueProfileImage($name);
- $default_image = PhabricatorFile::loadBuiltin(
- $viewer, $unique_default['icon']);
- } else {
- $unique_default = null;
+ $default_image = $user->getDefaultProfileImagePHID();
+ if ($default_image) {
+ $default_image = id(new PhabricatorFileQuery())
+ ->setViewer($viewer)
+ ->withPHIDs(array($default_image))
+ ->executeOne();
+ }
+
+ if (!$default_image) {
$default_image = PhabricatorFile::loadBuiltin($viewer, 'profile.png');
}
$images = array();
$current = $user->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'),
);
}
}
}
$builtins = array(
'user1.png',
'user2.png',
'user3.png',
'user4.png',
'user5.png',
'user6.png',
'user7.png',
'user8.png',
'user9.png',
);
foreach ($builtins as $builtin) {
$file = PhabricatorFile::loadBuiltin($viewer, $builtin);
$images[$file->getPHID()] = array(
'uri' => $file->getBestURI(),
'tip' => pht('Builtin Image'),
);
}
// Try to add external account images for any associated external accounts.
$accounts = id(new PhabricatorExternalAccountQuery())
->setViewer($viewer)
->withUserPHIDs(array($user->getPHID()))
->needImages(true)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute();
foreach ($accounts as $account) {
$file = $account->getProfileImageFile();
if ($account->getProfileImagePHID() != $file->getPHID()) {
// This is a default image, just skip it.
continue;
}
$provider = PhabricatorAuthProvider::getEnabledProviderByKey(
$account->getProviderKey());
if ($provider) {
$tip = pht('Picture From %s', $provider->getProviderName());
} else {
$tip = pht('Picture From External Account');
}
if ($file->isTransformableImage()) {
$images[$file->getPHID()] = array(
'uri' => $file->getBestURI(),
'tip' => $tip,
);
}
}
- $default_style = array();
- if ($unique_default) {
- $border_color = implode(', ', $unique_default['border']);
- $default_style = array(
- 'background-color: '.$unique_default['color'].';',
- 'border: 4px solid rgba('.$border_color.');',
- 'height: 42px;',
- 'width: 42px',
- );
- }
-
$images[PhabricatorPHIDConstants::PHID_VOID] = array(
'uri' => $default_image->getBestURI(),
'tip' => pht('Default Picture'),
- 'style' => implode(' ', $default_style),
);
require_celerity_resource('people-profile-css');
Javelin::initBehavior('phabricator-tooltips', array());
$buttons = array();
foreach ($images as $phid => $spec) {
$style = null;
if (isset($spec['style'])) {
$style = $spec['style'];
}
$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'],
- 'style' => $style,
)));
$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));
$form_box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setFormErrors($errors)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setForm($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($done_uri)
->setValue(pht('Upload Picture')));
$upload_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Upload New Picture'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setForm($upload_form);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Edit Profile Picture'));
$crumbs->setBorder(true);
$nav = $this->getProfileMenu();
$nav->selectFilter(PhabricatorPeopleProfileMenuEngine::ITEM_MANAGE);
$header = $this->buildProfileHeader();
$view = id(new PHUITwoColumnView())
->setHeader($header)
->addClass('project-view-home')
->addClass('project-view-people-home')
->setFooter(array(
$form_box,
$upload_box,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->setNavigation($nav)
->appendChild($view);
}
}
diff --git a/src/applications/people/management/PhabricatorPeopleProfileImageWorkflow.php b/src/applications/people/management/PhabricatorPeopleProfileImageWorkflow.php
index 1e594017ff..358756cecd 100644
--- a/src/applications/people/management/PhabricatorPeopleProfileImageWorkflow.php
+++ b/src/applications/people/management/PhabricatorPeopleProfileImageWorkflow.php
@@ -1,81 +1,87 @@
<?php
final class PhabricatorPeopleProfileImageWorkflow
extends PhabricatorPeopleManagementWorkflow {
protected function didConstruct() {
$this
->setName('profileimage')
->setExamples('**profileimage** --users __username__')
->setSynopsis(pht('Generate default profile images.'))
->setArguments(
array(
array(
'name' => 'all',
'help' => pht(
'Generate default profile images for all users.'),
),
array(
'name' => 'force',
'short' => 'f',
'help' => pht(
'Force a default profile image to be replaced.'),
),
array(
'name' => 'users',
'wildcard' => true,
),
));
}
public function execute(PhutilArgumentParser $args) {
$console = PhutilConsole::getConsole();
$is_force = $args->getArg('force');
$is_all = $args->getArg('all');
$gd = function_exists('imagecreatefromstring');
if (!$gd) {
throw new PhutilArgumentUsageException(
pht(
'GD is not installed for php-cli. Aborting.'));
}
$iterator = $this->buildIterator($args);
if (!$iterator) {
throw new PhutilArgumentUsageException(
pht(
'Either specify a list of users to update, or use `%s` '.
'to update all users.',
'--all'));
}
$version = PhabricatorFilesComposeAvatarBuiltinFile::VERSION;
foreach ($iterator as $user) {
$username = $user->getUsername();
$default_phid = $user->getDefaultProfileImagePHID();
+ $gen_version = $user->getDefaultProfileImageVersion();
- if ($default_phid == null || $is_force) {
+ $generate = false;
+ if ($gen_version != $version) {
+ $generate = true;
+ }
+
+ if ($default_phid == null || $is_force || $generate) {
$file = id(new PhabricatorFilesComposeAvatarBuiltinFile())
->getUserProfileImageFile($username);
$user->setDefaultProfileImagePHID($file->getPHID());
$user->setDefaultProfileImageVersion($version);
$user->save();
$console->writeOut(
"%s\n",
pht(
'Generating profile image for "%s".',
$username));
} else {
$console->writeOut(
"%s\n",
pht(
'Default profile image "%s" already set for "%s".',
$version,
$username));
}
}
}
}
diff --git a/src/applications/people/storage/PhabricatorUserProfile.php b/src/applications/people/storage/PhabricatorUserProfile.php
index edfa24d78e..da447410f5 100644
--- a/src/applications/people/storage/PhabricatorUserProfile.php
+++ b/src/applications/people/storage/PhabricatorUserProfile.php
@@ -1,46 +1,48 @@
<?php
final class PhabricatorUserProfile extends PhabricatorUserDAO {
protected $userPHID;
protected $title;
protected $blurb;
protected $profileImagePHID;
protected $icon;
public static function initializeNewProfile(PhabricatorUser $user) {
$default_icon = PhabricatorPeopleIconSet::getDefaultIconKey();
return id(new self())
->setUserPHID($user->getPHID())
- ->setIcon($default_icon);
+ ->setIcon($default_icon)
+ ->setTitle('')
+ ->setBlurb('');
}
protected function getConfiguration() {
return array(
self::CONFIG_COLUMN_SCHEMA => array(
'title' => 'text255',
'blurb' => 'text',
'profileImagePHID' => 'phid?',
'icon' => 'text32',
),
self::CONFIG_KEY_SCHEMA => array(
'userPHID' => array(
'columns' => array('userPHID'),
'unique' => true,
),
),
) + parent::getConfiguration();
}
public function getDisplayTitle() {
$title = $this->getTitle();
if (strlen($title)) {
return $title;
}
$icon_key = $this->getIcon();
return PhabricatorPeopleIconSet::getIconName($icon_key);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Fri, Mar 14, 11:07 AM (22 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
71815
Default Alt Text
(18 KB)

Event Timeline