Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14765331
D15991.id38497.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
17 KB
Referenced Files
None
Subscribers
None
D15991.id38497.diff
View Options
diff --git a/resources/sql/autopatches/20160531.pref.01.xaction.sql b/resources/sql/autopatches/20160531.pref.01.xaction.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160531.pref.01.xaction.sql
@@ -0,0 +1,19 @@
+CREATE TABLE {$NAMESPACE}_user.user_preferencestransaction (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ phid VARBINARY(64) NOT NULL,
+ authorPHID VARBINARY(64) NOT NULL,
+ objectPHID VARBINARY(64) NOT NULL,
+ viewPolicy VARBINARY(64) NOT NULL,
+ editPolicy VARBINARY(64) NOT NULL,
+ commentPHID VARBINARY(64) DEFAULT NULL,
+ commentVersion INT UNSIGNED NOT NULL,
+ transactionType VARCHAR(32) COLLATE {$COLLATE_TEXT} NOT NULL,
+ oldValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ newValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ metadata LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+ UNIQUE KEY `key_phid` (`phid`),
+ KEY `key_object` (`objectPHID`)
+) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
diff --git a/resources/sql/autopatches/20160531.pref.02.datecreatecol.sql b/resources/sql/autopatches/20160531.pref.02.datecreatecol.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160531.pref.02.datecreatecol.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_user.user_preferences
+ ADD dateCreated INT UNSIGNED NOT NULL;
diff --git a/resources/sql/autopatches/20160531.pref.03.datemodcol.sql b/resources/sql/autopatches/20160531.pref.03.datemodcol.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160531.pref.03.datemodcol.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_user.user_preferences
+ ADD dateModified INT UNSIGNED NOT NULL;
diff --git a/resources/sql/autopatches/20160531.pref.04.datecreateval.sql b/resources/sql/autopatches/20160531.pref.04.datecreateval.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160531.pref.04.datecreateval.sql
@@ -0,0 +1,2 @@
+UPDATE {$NAMESPACE}_user.user_preferences
+ SET dateCreated = UNIX_TIMESTAMP() WHERE dateCreated = 0;
diff --git a/resources/sql/autopatches/20160531.pref.05.datemodval.sql b/resources/sql/autopatches/20160531.pref.05.datemodval.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160531.pref.05.datemodval.sql
@@ -0,0 +1,2 @@
+UPDATE {$NAMESPACE}_user.user_preferences
+ SET dateModified = UNIX_TIMESTAMP() WHERE dateModified = 0;
diff --git a/resources/sql/autopatches/20160531.pref.06.phidcol.sql b/resources/sql/autopatches/20160531.pref.06.phidcol.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160531.pref.06.phidcol.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_user.user_preferences
+ ADD phid VARBINARY(64) NOT NULL;
diff --git a/resources/sql/autopatches/20160531.pref.07.phidval.php b/resources/sql/autopatches/20160531.pref.07.phidval.php
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160531.pref.07.phidval.php
@@ -0,0 +1,17 @@
+<?php
+
+$table = new PhabricatorUserPreferences();
+$conn_w = $table->establishConnection('w');
+
+foreach (new LiskMigrationIterator($table) as $row) {
+ if ($row->getPHID() !== '') {
+ continue;
+ }
+
+ queryfx(
+ $conn_w,
+ 'UPDATE %T SET phid = %s WHERE id = %d',
+ $table->getTableName(),
+ $table->generatePHID(),
+ $row->getID());
+}
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -3592,6 +3592,9 @@
'PhabricatorUserLogView' => 'applications/people/view/PhabricatorUserLogView.php',
'PhabricatorUserPHIDResolver' => 'applications/phid/resolver/PhabricatorUserPHIDResolver.php',
'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php',
+ 'PhabricatorUserPreferencesPHIDType' => 'applications/settings/phid/PhabricatorUserPreferencesPHIDType.php',
+ 'PhabricatorUserPreferencesQuery' => 'applications/settings/query/PhabricatorUserPreferencesQuery.php',
+ 'PhabricatorUserPreferencesTransaction' => 'applications/settings/storage/PhabricatorUserPreferencesTransaction.php',
'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php',
'PhabricatorUserProfileEditor' => 'applications/people/editor/PhabricatorUserProfileEditor.php',
'PhabricatorUserRealNameField' => 'applications/people/customfield/PhabricatorUserRealNameField.php',
@@ -8342,7 +8345,15 @@
),
'PhabricatorUserLogView' => 'AphrontView',
'PhabricatorUserPHIDResolver' => 'PhabricatorPHIDResolver',
- 'PhabricatorUserPreferences' => 'PhabricatorUserDAO',
+ 'PhabricatorUserPreferences' => array(
+ 'PhabricatorUserDAO',
+ 'PhabricatorPolicyInterface',
+ 'PhabricatorDestructibleInterface',
+ 'PhabricatorApplicationTransactionInterface',
+ ),
+ 'PhabricatorUserPreferencesPHIDType' => 'PhabricatorPHIDType',
+ 'PhabricatorUserPreferencesQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+ 'PhabricatorUserPreferencesTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorUserProfile' => 'PhabricatorUserDAO',
'PhabricatorUserProfileEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorUserRealNameField' => 'PhabricatorUserCustomField',
diff --git a/src/applications/conpherence/editor/ConpherenceEditor.php b/src/applications/conpherence/editor/ConpherenceEditor.php
--- a/src/applications/conpherence/editor/ConpherenceEditor.php
+++ b/src/applications/conpherence/editor/ConpherenceEditor.php
@@ -533,13 +533,20 @@
protected function getMailTo(PhabricatorLiskDAO $object) {
$to_phids = array();
+
$participants = $object->getParticipants();
- if (empty($participants)) {
+ if (!$participants) {
return $to_phids;
}
- $preferences = id(new PhabricatorUserPreferences())
- ->loadAllWhere('userPHID in (%Ls)', array_keys($participants));
+
+ $participant_phids = mpull($participants, 'getParticipantPHID');
+
+ $preferences = id(new PhabricatorUserPreferencesQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withUserPHIDs($participant_phids)
+ ->execute();
$preferences = mpull($preferences, null, 'getUserPHID');
+
foreach ($participants as $phid => $participant) {
$default = ConpherenceSettings::EMAIL_ALWAYS;
$preference = idx($preferences, $phid);
@@ -557,6 +564,7 @@
$to_phids[] = $phid;
}
}
+
return $to_phids;
}
diff --git a/src/applications/feed/PhabricatorFeedStoryPublisher.php b/src/applications/feed/PhabricatorFeedStoryPublisher.php
--- a/src/applications/feed/PhabricatorFeedStoryPublisher.php
+++ b/src/applications/feed/PhabricatorFeedStoryPublisher.php
@@ -207,9 +207,10 @@
$tags = $this->getMailTags();
if ($tags) {
- $all_prefs = id(new PhabricatorUserPreferences())->loadAllWhere(
- 'userPHID in (%Ls)',
- $phids);
+ $all_prefs = id(new PhabricatorUserPreferencesQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withUserPHIDs($phids)
+ ->execute();
$all_prefs = mpull($all_prefs, null, 'getUserPHID');
}
diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php
--- a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php
+++ b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php
@@ -940,9 +940,10 @@
}
}
- $all_prefs = id(new PhabricatorUserPreferences())->loadAllWhere(
- 'userPHID in (%Ls)',
- $actor_phids);
+ $all_prefs = id(new PhabricatorUserPreferencesQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withUserPHIDs($actor_phids)
+ ->execute();
$all_prefs = mpull($all_prefs, null, 'getUserPHID');
$value_email = PhabricatorUserPreferences::MAILTAG_PREFERENCE_EMAIL;
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
@@ -494,9 +494,10 @@
$preferences = null;
if ($this->getPHID()) {
- $preferences = id(new PhabricatorUserPreferences())->loadOneWhere(
- 'userPHID = %s',
- $this->getPHID());
+ $preferences = id(new PhabricatorUserPreferencesQuery())
+ ->setViewer($this)
+ ->withUsers(array($this))
+ ->executeOne();
}
if (!$preferences) {
@@ -1293,11 +1294,12 @@
$external->delete();
}
- $prefs = id(new PhabricatorUserPreferences())->loadAllWhere(
- 'userPHID = %s',
- $this->getPHID());
+ $prefs = id(new PhabricatorUserPreferencesQuery())
+ ->setViewer($engine->getViewer())
+ ->withUsers(array($this))
+ ->execute();
foreach ($prefs as $pref) {
- $pref->delete();
+ $engine->destroyObject($pref);
}
$profiles = id(new PhabricatorUserProfile())->loadAllWhere(
diff --git a/src/applications/settings/phid/PhabricatorUserPreferencesPHIDType.php b/src/applications/settings/phid/PhabricatorUserPreferencesPHIDType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/settings/phid/PhabricatorUserPreferencesPHIDType.php
@@ -0,0 +1,40 @@
+<?php
+
+final class PhabricatorUserPreferencesPHIDType extends PhabricatorPHIDType {
+
+ const TYPECONST = 'PSET';
+
+ public function getTypeName() {
+ return pht('Settings');
+ }
+
+ public function newObject() {
+ return new PhabricatorUserPreferences();
+ }
+
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorSettingsApplication';
+ }
+
+ protected function buildQueryForObjects(
+ PhabricatorObjectQuery $query,
+ array $phids) {
+
+ return id(new PhabricatorUserPreferencesQuery())
+ ->withPHIDs($phids);
+ }
+
+ public function loadHandles(
+ PhabricatorHandleQuery $query,
+ array $handles,
+ array $objects) {
+
+ $viewer = $query->getViewer();
+ foreach ($handles as $phid => $handle) {
+ $preferences = $objects[$phid];
+
+ $handle->setName(pht('Settings %d', $preferences->getID()));
+ }
+ }
+
+}
diff --git a/src/applications/settings/query/PhabricatorUserPreferencesQuery.php b/src/applications/settings/query/PhabricatorUserPreferencesQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/settings/query/PhabricatorUserPreferencesQuery.php
@@ -0,0 +1,118 @@
+<?php
+
+final class PhabricatorUserPreferencesQuery
+ extends PhabricatorCursorPagedPolicyAwareQuery {
+
+ private $ids;
+ private $phids;
+ private $userPHIDs;
+ private $users = array();
+
+ public function withIDs(array $ids) {
+ $this->ids = $ids;
+ return $this;
+ }
+
+ public function withPHIDs(array $phids) {
+ $this->phids = $phids;
+ return $this;
+ }
+
+ public function withUserPHIDs(array $phids) {
+ $this->userPHIDs = $phids;
+ return $this;
+ }
+
+ public function withUsers(array $users) {
+ assert_instances_of($users, 'PhabricatorUser');
+ $this->users = mpull($users, null, 'getPHID');
+ $this->withUserPHIDs(array_keys($this->users));
+ return $this;
+ }
+
+ public function newResultObject() {
+ return new PhabricatorUserPreferences();
+ }
+
+ protected function loadPage() {
+ return $this->loadStandardPage($this->newResultObject());
+ }
+
+ protected function willFilterPage(array $prefs) {
+ $user_phids = mpull($prefs, 'getUserPHID');
+ $user_phids = array_filter($user_phids);
+
+ // If some of the preferences are attached to users, try to use any objects
+ // we were handed first. If we're missing some, load them.
+
+ if ($user_phids) {
+ $users = $this->users;
+
+ $user_phids = array_fuse($user_phids);
+ $load_phids = array_diff_key($user_phids, $users);
+ $load_phids = array_keys($load_phids);
+
+ if ($load_phids) {
+ $load_users = id(new PhabricatorPeopleQuery())
+ ->setViewer($this->getViewer())
+ ->withPHIDs($load_phids)
+ ->execute();
+ $load_users = mpull($load_users, null, 'getPHID');
+ $users += $load_users;
+ }
+ } else {
+ $users = array();
+ }
+
+ foreach ($prefs as $key => $pref) {
+ $user_phid = $pref->getUserPHID();
+ if (!$user_phid) {
+ $pref->attachUser(null);
+ continue;
+ }
+
+ $user = idx($users, $user_phid);
+ if (!$user) {
+ $this->didRejectResult($pref);
+ unset($prefs[$key]);
+ continue;
+ }
+
+ $pref->attachUser($user);
+ }
+
+ return $prefs;
+ }
+
+ protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
+ $where = parent::buildWhereClauseParts($conn);
+
+ if ($this->ids !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'id IN (%Ld)',
+ $this->ids);
+ }
+
+ if ($this->phids !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'phid IN (%Ls)',
+ $this->phids);
+ }
+
+ if ($this->userPHIDs !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'userPHID IN (%Ls)',
+ $this->userPHIDs);
+ }
+
+ return $where;
+ }
+
+ public function getQueryApplicationClass() {
+ return 'PhabricatorSettingsApplication';
+ }
+
+}
diff --git a/src/applications/settings/storage/PhabricatorUserPreferences.php b/src/applications/settings/storage/PhabricatorUserPreferences.php
--- a/src/applications/settings/storage/PhabricatorUserPreferences.php
+++ b/src/applications/settings/storage/PhabricatorUserPreferences.php
@@ -1,6 +1,11 @@
<?php
-final class PhabricatorUserPreferences extends PhabricatorUserDAO {
+final class PhabricatorUserPreferences
+ extends PhabricatorUserDAO
+ implements
+ PhabricatorPolicyInterface,
+ PhabricatorDestructibleInterface,
+ PhabricatorApplicationTransactionInterface {
const PREFERENCE_MONOSPACED = 'monospaced';
const PREFERENCE_DARK_CONSOLE = 'dark_console';
@@ -51,12 +56,14 @@
protected $userPHID;
protected $preferences = array();
+ private $user = self::ATTACHABLE;
+
protected function getConfiguration() {
return array(
+ self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'preferences' => self::SERIALIZATION_JSON,
),
- self::CONFIG_TIMESTAMPS => false,
self::CONFIG_KEY_SCHEMA => array(
'userPHID' => array(
'columns' => array('userPHID'),
@@ -66,6 +73,11 @@
) + parent::getConfiguration();
}
+ public function generatePHID() {
+ return PhabricatorPHID::generateNewPHID(
+ PhabricatorUserPreferencesPHIDType::TYPECONST);
+ }
+
public function getPreference($key, $default = null) {
return idx($this->preferences, $key, $default);
}
@@ -115,4 +127,107 @@
return preg_replace('([^a-z0-9 ,"./]+)i', '', $monospaced);
}
+ public function attachUser(PhabricatorUser $user = null) {
+ $this->user = $user;
+ return $this;
+ }
+
+ public function getUser() {
+ return $this->assertAttached($this->user);
+ }
+
+ public function hasManagedUser() {
+ $user_phid = $this->getUserPHID();
+ if (!$user_phid) {
+ return false;
+ }
+
+ $user = $this->getUser();
+ if ($user->getIsSystemAgent() || $user->getIsMailingList()) {
+ return true;
+ }
+
+ return false;
+ }
+
+
+/* -( PhabricatorPolicyInterface )----------------------------------------- */
+
+
+ public function getCapabilities() {
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ );
+ }
+
+ public function getPolicy($capability) {
+ switch ($capability) {
+ case PhabricatorPolicyCapability::CAN_VIEW:
+ $user_phid = $this->getUserPHID();
+ if ($user_phid) {
+ return $user_phid;
+ }
+
+ return PhabricatorPolicies::getMostOpenPolicy();
+ case PhabricatorPolicyCapability::CAN_EDIT:
+ if ($this->hasManagedUser()) {
+ return PhabricatorPolicies::POLICY_ADMIN;
+ }
+
+ $user_phid = $this->getUserPHID();
+ if ($user_phid) {
+ return $user_phid;
+ }
+
+ return PhabricatorPolicies::POLICY_ADMIN;
+ }
+ }
+
+ public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
+ if ($this->hasManagedUser()) {
+ if ($viewer->getIsAdmin()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function describeAutomaticCapability($capability) {
+ return null;
+ }
+
+
+/* -( PhabricatorDestructibleInterface )----------------------------------- */
+
+
+ public function destroyObjectPermanently(
+ PhabricatorDestructionEngine $engine) {
+ $this->delete();
+ }
+
+
+/* -( PhabricatorApplicationTransactionInterface )------------------------- */
+
+
+ public function getApplicationTransactionEditor() {
+ // TODO: Implement.
+ throw new PhutilMethodNotImplementedException();
+ }
+
+ public function getApplicationTransactionObject() {
+ return $this;
+ }
+
+ public function getApplicationTransactionTemplate() {
+ return new PhabricatorUserPreferencesTransaction();
+ }
+
+ public function willRenderTimeline(
+ PhabricatorApplicationTransactionView $timeline,
+ AphrontRequest $request) {
+ return $timeline;
+ }
+
}
diff --git a/src/applications/settings/storage/PhabricatorUserPreferencesTransaction.php b/src/applications/settings/storage/PhabricatorUserPreferencesTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/settings/storage/PhabricatorUserPreferencesTransaction.php
@@ -0,0 +1,18 @@
+<?php
+
+final class PhabricatorUserPreferencesTransaction
+ extends PhabricatorApplicationTransaction {
+
+ public function getApplicationName() {
+ return 'user';
+ }
+
+ public function getApplicationTransactionCommentObject() {
+ return null;
+ }
+
+ public function getApplicationTransactionType() {
+ return PhabricatorUserPreferencesPHIDType::TYPECONST;
+ }
+
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 24, 3:29 PM (59 m, 6 s)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7038605
Default Alt Text
D15991.id38497.diff (17 KB)
Attached To
Mode
D15991: Prepare UserPreferences for transactions
Attached
Detach File
Event Timeline
Log In to Comment