Page MenuHomePhabricator

D12826.id.diff
No OneTemporary

D12826.id.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -7,7 +7,7 @@
*/
return array(
'names' => array(
- 'core.pkg.css' => 'ed3d6355',
+ 'core.pkg.css' => '7ac320f1',
'core.pkg.js' => 'ac41c400',
'darkconsole.pkg.js' => 'e7393ebb',
'differential.pkg.css' => 'bb338e4b',
@@ -33,7 +33,7 @@
'rsrc/css/aphront/typeahead-browse.css' => 'd8581d2c',
'rsrc/css/aphront/typeahead.css' => '0e403212',
'rsrc/css/application/almanac/almanac.css' => 'dbb9b3af',
- 'rsrc/css/application/auth/auth.css' => '1e655982',
+ 'rsrc/css/application/auth/auth.css' => '44975d4b',
'rsrc/css/application/base/main-menu-view.css' => '663e3810',
'rsrc/css/application/base/notification-menu.css' => '3c9d8aa1',
'rsrc/css/application/base/phabricator-application-launch-view.css' => '16ca323f',
@@ -47,8 +47,8 @@
'rsrc/css/application/config/unhandled-exception.css' => '37d4f9a2',
'rsrc/css/application/conpherence/durable-column.css' => '8c43d6ac',
'rsrc/css/application/conpherence/menu.css' => 'f389e048',
- 'rsrc/css/application/conpherence/message-pane.css' => '0e75feef',
- 'rsrc/css/application/conpherence/notification.css' => 'd208f806',
+ 'rsrc/css/application/conpherence/message-pane.css' => '5bb4b76d',
+ 'rsrc/css/application/conpherence/notification.css' => '919974b6',
'rsrc/css/application/conpherence/transaction.css' => '42a457f6',
'rsrc/css/application/conpherence/update.css' => '1099a660',
'rsrc/css/application/conpherence/widget-pane.css' => '2af42ebe',
@@ -135,14 +135,14 @@
'rsrc/css/phui/phui-fontkit.css' => 'dd8ddf27',
'rsrc/css/phui/phui-form-view.css' => '94ae3032',
'rsrc/css/phui/phui-form.css' => 'f535f938',
- 'rsrc/css/phui/phui-header-view.css' => 'da4586b1',
+ 'rsrc/css/phui/phui-header-view.css' => '75aaf372',
'rsrc/css/phui/phui-icon.css' => 'bc766998',
'rsrc/css/phui/phui-image-mask.css' => '5a8b09c8',
'rsrc/css/phui/phui-info-panel.css' => '27ea50a1',
'rsrc/css/phui/phui-info-view.css' => 'c6f0aef8',
'rsrc/css/phui/phui-list.css' => '2e25ebfb',
'rsrc/css/phui/phui-object-box.css' => '7d160002',
- 'rsrc/css/phui/phui-object-item-list-view.css' => '9db65899',
+ 'rsrc/css/phui/phui-object-item-list-view.css' => 'f3a22696',
'rsrc/css/phui/phui-pinboard-view.css' => 'eaab2b1b',
'rsrc/css/phui/phui-property-list-view.css' => '5b671934',
'rsrc/css/phui/phui-remarkup-preview.css' => '19ad512b',
@@ -150,7 +150,7 @@
'rsrc/css/phui/phui-status.css' => '888cedb8',
'rsrc/css/phui/phui-tag-view.css' => '402691cc',
'rsrc/css/phui/phui-text.css' => 'cf019f54',
- 'rsrc/css/phui/phui-timeline-view.css' => 'b0fbc4d7',
+ 'rsrc/css/phui/phui-timeline-view.css' => 'a85542c8',
'rsrc/css/phui/phui-workboard-view.css' => '3279cbbf',
'rsrc/css/phui/phui-workpanel-view.css' => 'e495a5cc',
'rsrc/css/sprite-gradient.css' => '4bdb98a7',
@@ -281,22 +281,6 @@
'rsrc/image/icon/fatcow/source/mobile.png' => 'f1321264',
'rsrc/image/icon/fatcow/source/tablet.png' => '49396799',
'rsrc/image/icon/fatcow/source/web.png' => '136ccb5d',
- 'rsrc/image/icon/fatcow/thumbnails/default.p100.png' => '7d490b01',
- 'rsrc/image/icon/fatcow/thumbnails/default160x120.png' => 'f2e8a2eb',
- 'rsrc/image/icon/fatcow/thumbnails/default280x210.png' => '43e8926a',
- 'rsrc/image/icon/fatcow/thumbnails/default60x45.png' => '0118abed',
- 'rsrc/image/icon/fatcow/thumbnails/image.p100.png' => 'da23cf97',
- 'rsrc/image/icon/fatcow/thumbnails/image160x120.png' => '79bb556a',
- 'rsrc/image/icon/fatcow/thumbnails/image280x210.png' => '91ae054a',
- 'rsrc/image/icon/fatcow/thumbnails/image60x45.png' => 'c5e1685e',
- 'rsrc/image/icon/fatcow/thumbnails/pdf.p100.png' => '87d5e065',
- 'rsrc/image/icon/fatcow/thumbnails/pdf160x120.png' => 'ac9edbf5',
- 'rsrc/image/icon/fatcow/thumbnails/pdf280x210.png' => '1c585653',
- 'rsrc/image/icon/fatcow/thumbnails/pdf60x45.png' => 'c0db4143',
- 'rsrc/image/icon/fatcow/thumbnails/zip.p100.png' => '6ea5aae4',
- 'rsrc/image/icon/fatcow/thumbnails/zip160x120.png' => '75f9cd0f',
- 'rsrc/image/icon/fatcow/thumbnails/zip280x210.png' => 'dfda5b8e',
- 'rsrc/image/icon/fatcow/thumbnails/zip60x45.png' => 'af11bf3e',
'rsrc/image/icon/lightbox/close-2.png' => 'cc40e7c8',
'rsrc/image/icon/lightbox/close-hover-2.png' => 'fb5d6d9e',
'rsrc/image/icon/lightbox/left-arrow-2.png' => '8426133b',
@@ -507,15 +491,15 @@
'aphront-tooltip-css' => '7672b60f',
'aphront-two-column-view-css' => '16ab3ad2',
'aphront-typeahead-control-css' => '0e403212',
- 'auth-css' => '1e655982',
+ 'auth-css' => '44975d4b',
'changeset-view-manager' => '58562350',
'conduit-api-css' => '7bc725c4',
'config-options-css' => '7fedf08b',
'config-welcome-css' => '6abd79be',
'conpherence-durable-column-view' => '8c43d6ac',
'conpherence-menu-css' => 'f389e048',
- 'conpherence-message-pane-css' => '0e75feef',
- 'conpherence-notification-css' => 'd208f806',
+ 'conpherence-message-pane-css' => '5bb4b76d',
+ 'conpherence-notification-css' => '919974b6',
'conpherence-thread-manager' => 'b7342ddb',
'conpherence-transaction-css' => '42a457f6',
'conpherence-update-css' => '1099a660',
@@ -787,7 +771,7 @@
'phui-fontkit-css' => 'dd8ddf27',
'phui-form-css' => 'f535f938',
'phui-form-view-css' => '94ae3032',
- 'phui-header-view-css' => 'da4586b1',
+ 'phui-header-view-css' => '75aaf372',
'phui-icon-view-css' => 'bc766998',
'phui-image-mask-css' => '5a8b09c8',
'phui-info-panel-css' => '27ea50a1',
@@ -795,7 +779,7 @@
'phui-inline-comment-view-css' => '2174771a',
'phui-list-view-css' => '2e25ebfb',
'phui-object-box-css' => '7d160002',
- 'phui-object-item-list-view-css' => '9db65899',
+ 'phui-object-item-list-view-css' => 'f3a22696',
'phui-pinboard-view-css' => 'eaab2b1b',
'phui-property-list-view-css' => '5b671934',
'phui-remarkup-preview-css' => '19ad512b',
@@ -803,7 +787,7 @@
'phui-status-list-view-css' => '888cedb8',
'phui-tag-view-css' => '402691cc',
'phui-text-css' => 'cf019f54',
- 'phui-timeline-view-css' => 'b0fbc4d7',
+ 'phui-timeline-view-css' => 'a85542c8',
'phui-workboard-view-css' => '3279cbbf',
'phui-workpanel-view-css' => 'e495a5cc',
'phuix-action-list-view' => 'b5c256b8',
diff --git a/resources/sql/autopatches/20150513.user.cache.1.sql b/resources/sql/autopatches/20150513.user.cache.1.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150513.user.cache.1.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_user.user
+ ADD profileImageCache VARCHAR(255) COLLATE {$COLLATE_TEXT};
diff --git a/src/applications/files/transform/PhabricatorFileImageTransform.php b/src/applications/files/transform/PhabricatorFileImageTransform.php
--- a/src/applications/files/transform/PhabricatorFileImageTransform.php
+++ b/src/applications/files/transform/PhabricatorFileImageTransform.php
@@ -141,14 +141,14 @@
$name = 'default.png';
}
- $name = $this->getTransformKey().'-'.$name;
-
- return PhabricatorFile::newFromFileData(
- $data,
- array(
- 'name' => $name,
- 'canCDN' => true,
- ) + $this->getFileProperties());
+ $defaults = array(
+ 'canCDN' => true,
+ 'name' => $this->getTransformKey().'-'.$name,
+ );
+
+ $properties = $this->getFileProperties() + $defaults;
+
+ return PhabricatorFile::newFromFileData($data, $properties);
}
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
@@ -48,6 +48,7 @@
switch ($this->key) {
case self::TRANSFORM_PROFILE:
$properties['profile'] = true;
+ $properties['name'] = 'profile';
break;
}
return $properties;
@@ -185,8 +186,8 @@
$scale = $scale_y;
}
- $copy_x = $dst_x / $scale_x;
- $copy_y = $dst_y / $scale_x;
+ $copy_x = $dst_x / $scale;
+ $copy_y = $dst_y / $scale;
if (!$scale_up) {
$copy_x = min($src_x, $copy_x);
diff --git a/src/applications/people/query/PhabricatorPeopleQuery.php b/src/applications/people/query/PhabricatorPeopleQuery.php
--- a/src/applications/people/query/PhabricatorPeopleQuery.php
+++ b/src/applications/people/query/PhabricatorPeopleQuery.php
@@ -148,26 +148,55 @@
}
if ($this->needProfileImage) {
- $user_profile_file_phids = mpull($users, 'getProfileImagePHID');
- $user_profile_file_phids = array_filter($user_profile_file_phids);
- if ($user_profile_file_phids) {
- $files = id(new PhabricatorFileQuery())
- ->setParentQuery($this)
- ->setViewer($this->getViewer())
- ->withPHIDs($user_profile_file_phids)
- ->execute();
- $files = mpull($files, null, 'getPHID');
- } else {
- $files = array();
- }
+ $rebuild = array();
foreach ($users as $user) {
- $image_phid = $user->getProfileImagePHID();
- if (isset($files[$image_phid])) {
- $profile_image_uri = $files[$image_phid]->getBestURI();
+ $image_uri = $user->getProfileImageCache();
+ if ($image_uri) {
+ // This user has a valid cache, so we don't need to fetch any
+ // data or rebuild anything.
+
+ $user->attachProfileImageURI($image_uri);
+ continue;
+ }
+
+ // This user's cache is invalid or missing, so we're going to rebuild
+ // it.
+ $rebuild[] = $user;
+ }
+
+ if ($rebuild) {
+ $file_phids = mpull($rebuild, 'getProfileImagePHID');
+ $file_phids = array_filter($file_phids);
+
+ if ($file_phids) {
+ // NOTE: We're using the omnipotent user here because older profile
+ // images do not have the 'profile' flag, so they may not be visible
+ // to the executing viewer. At some point, we could migrate to add
+ // this flag and then use the real viewer, or just use the real
+ // viewer after enough time has passed to limit the impact of old
+ // data. The consequence of missing here is that we cache a default
+ // image when a real image exists.
+ $files = id(new PhabricatorFileQuery())
+ ->setParentQuery($this)
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withPHIDs($file_phids)
+ ->execute();
+ $files = mpull($files, null, 'getPHID');
} else {
- $profile_image_uri = PhabricatorUser::getDefaultProfileImageURI();
+ $files = array();
+ }
+
+ foreach ($rebuild as $user) {
+ $image_phid = $user->getProfileImagePHID();
+ if (isset($files[$image_phid])) {
+ $image_uri = $files[$image_phid]->getBestURI();
+ } else {
+ $image_uri = PhabricatorUser::getDefaultProfileImageURI();
+ }
+
+ $user->writeProfileImageCache($image_uri);
+ $user->attachProfileImageURI($image_uri);
}
- $user->attachProfileImageURI($profile_image_uri);
}
}
diff --git a/src/applications/people/storage/PhabricatorUser.php b/src/applications/people/storage/PhabricatorUser.php
--- a/src/applications/people/storage/PhabricatorUser.php
+++ b/src/applications/people/storage/PhabricatorUser.php
@@ -1,6 +1,7 @@
<?php
/**
+ * @task image-cache Profile Image Cache
* @task factors Multi-Factor Authentication
* @task handles Managing Handles
*/
@@ -24,6 +25,7 @@
protected $passwordSalt;
protected $passwordHash;
protected $profileImagePHID;
+ protected $profileImageCache;
protected $timezoneIdentifier = '';
protected $consoleEnabled = 0;
@@ -142,6 +144,7 @@
'isApproved' => 'uint32',
'accountSecret' => 'bytes64',
'isEnrolledInMultiFactor' => 'bool',
+ 'profileImageCache' => 'text255?',
),
self::CONFIG_KEY_SCHEMA => array(
'key_phid' => null,
@@ -160,6 +163,9 @@
'columns' => array('isApproved'),
),
),
+ self::CONFIG_NO_MUTATE => array(
+ 'profileImageCache' => true,
+ ),
) + parent::getConfiguration();
}
@@ -721,6 +727,72 @@
}
+/* -( Profile Image Cache )------------------------------------------------ */
+
+
+ /**
+ * Get this user's cached profile image URI.
+ *
+ * @return string|null Cached URI, if a URI is cached.
+ * @task image-cache
+ */
+ public function getProfileImageCache() {
+ $version = $this->getProfileImageVersion();
+
+ $parts = explode(',', $this->profileImageCache, 2);
+ if (count($parts) !== 2) {
+ return null;
+ }
+
+ if ($parts[0] !== $version) {
+ return null;
+ }
+
+ return $parts[1];
+ }
+
+
+ /**
+ * Generate a new cache value for this user's profile image.
+ *
+ * @return string New cache value.
+ * @task image-cache
+ */
+ public function writeProfileImageCache($uri) {
+ $version = $this->getProfileImageVersion();
+ $cache = "{$version},{$uri}";
+
+ $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
+ queryfx(
+ $this->establishConnection('w'),
+ 'UPDATE %T SET profileImageCache = %s WHERE id = %d',
+ $this->getTableName(),
+ $cache,
+ $this->getID());
+ unset($unguarded);
+ }
+
+
+ /**
+ * Get a version identifier for a user's profile image.
+ *
+ * This version will change if the image changes, or if any of the
+ * environment configuration which goes into generating a URI changes.
+ *
+ * @return string Cache version.
+ * @task image-cache
+ */
+ private function getProfileImageVersion() {
+ $parts = array(
+ PhabricatorEnv::getCDNURI('/'),
+ PhabricatorEnv::getEnvConfig('cluster.instance'),
+ $this->getProfileImagePHID(),
+ );
+ $parts = serialize($parts);
+ return PhabricatorHash::digestForIndex($parts);
+ }
+
+
/* -( Multi-Factor Authentication )---------------------------------------- */

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 22, 6:24 AM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7708364
Default Alt Text
D12826.id.diff (14 KB)

Event Timeline