Page MenuHomePhabricator

D15991.id38497.diff
No OneTemporary

D15991.id38497.diff

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

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)

Event Timeline