Skip to content

Commit b256f2d

Browse files
author
epriestley
committedMay 31, 2016
Prepare UserPreferences for transactions
Summary: Ref T4103. This give preferences a PHID, policy/transaction interfaces, a transaction table, and a Query class. This doesn't actually change how they're edited, yet. Test Plan: - Ran migrations. - Inspected database for date created, date modified, PHIDs. - Changed some of my preferences. - Deleted a user's preferences, verified they reset properly. - Set some preferences as a new user, got a new row. - Destroyed a user, verified their preferences were destroyed. - Sent Conpherence messages. - Send mail. - Tried to edit another user's settings. - Tried to edit a bot's settings as a non-admin. - Edited a bot's settings as an admin (technically, none of the editable settings are actually stored in the settings table, currently). Reviewers: chad Reviewed By: chad Maniphest Tasks: T4103 Differential Revision: https://secure.phabricator.com/D15991
1 parent b23c85b commit b256f2d

16 files changed

+379
-19
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
CREATE TABLE {$NAMESPACE}_user.user_preferencestransaction (
2+
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
3+
phid VARBINARY(64) NOT NULL,
4+
authorPHID VARBINARY(64) NOT NULL,
5+
objectPHID VARBINARY(64) NOT NULL,
6+
viewPolicy VARBINARY(64) NOT NULL,
7+
editPolicy VARBINARY(64) NOT NULL,
8+
commentPHID VARBINARY(64) DEFAULT NULL,
9+
commentVersion INT UNSIGNED NOT NULL,
10+
transactionType VARCHAR(32) COLLATE {$COLLATE_TEXT} NOT NULL,
11+
oldValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
12+
newValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
13+
contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
14+
metadata LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
15+
dateCreated INT UNSIGNED NOT NULL,
16+
dateModified INT UNSIGNED NOT NULL,
17+
UNIQUE KEY `key_phid` (`phid`),
18+
KEY `key_object` (`objectPHID`)
19+
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ALTER TABLE {$NAMESPACE}_user.user_preferences
2+
ADD dateCreated INT UNSIGNED NOT NULL;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ALTER TABLE {$NAMESPACE}_user.user_preferences
2+
ADD dateModified INT UNSIGNED NOT NULL;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
UPDATE {$NAMESPACE}_user.user_preferences
2+
SET dateCreated = UNIX_TIMESTAMP() WHERE dateCreated = 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
UPDATE {$NAMESPACE}_user.user_preferences
2+
SET dateModified = UNIX_TIMESTAMP() WHERE dateModified = 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ALTER TABLE {$NAMESPACE}_user.user_preferences
2+
ADD phid VARBINARY(64) NOT NULL;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
$table = new PhabricatorUserPreferences();
4+
$conn_w = $table->establishConnection('w');
5+
6+
foreach (new LiskMigrationIterator($table) as $row) {
7+
if ($row->getPHID() !== '') {
8+
continue;
9+
}
10+
11+
queryfx(
12+
$conn_w,
13+
'UPDATE %T SET phid = %s WHERE id = %d',
14+
$table->getTableName(),
15+
$table->generatePHID(),
16+
$row->getID());
17+
}

‎src/__phutil_library_map__.php

+12-1
Original file line numberDiff line numberDiff line change
@@ -3592,6 +3592,9 @@
35923592
'PhabricatorUserLogView' => 'applications/people/view/PhabricatorUserLogView.php',
35933593
'PhabricatorUserPHIDResolver' => 'applications/phid/resolver/PhabricatorUserPHIDResolver.php',
35943594
'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php',
3595+
'PhabricatorUserPreferencesPHIDType' => 'applications/settings/phid/PhabricatorUserPreferencesPHIDType.php',
3596+
'PhabricatorUserPreferencesQuery' => 'applications/settings/query/PhabricatorUserPreferencesQuery.php',
3597+
'PhabricatorUserPreferencesTransaction' => 'applications/settings/storage/PhabricatorUserPreferencesTransaction.php',
35953598
'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php',
35963599
'PhabricatorUserProfileEditor' => 'applications/people/editor/PhabricatorUserProfileEditor.php',
35973600
'PhabricatorUserRealNameField' => 'applications/people/customfield/PhabricatorUserRealNameField.php',
@@ -8342,7 +8345,15 @@
83428345
),
83438346
'PhabricatorUserLogView' => 'AphrontView',
83448347
'PhabricatorUserPHIDResolver' => 'PhabricatorPHIDResolver',
8345-
'PhabricatorUserPreferences' => 'PhabricatorUserDAO',
8348+
'PhabricatorUserPreferences' => array(
8349+
'PhabricatorUserDAO',
8350+
'PhabricatorPolicyInterface',
8351+
'PhabricatorDestructibleInterface',
8352+
'PhabricatorApplicationTransactionInterface',
8353+
),
8354+
'PhabricatorUserPreferencesPHIDType' => 'PhabricatorPHIDType',
8355+
'PhabricatorUserPreferencesQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
8356+
'PhabricatorUserPreferencesTransaction' => 'PhabricatorApplicationTransaction',
83468357
'PhabricatorUserProfile' => 'PhabricatorUserDAO',
83478358
'PhabricatorUserProfileEditor' => 'PhabricatorApplicationTransactionEditor',
83488359
'PhabricatorUserRealNameField' => 'PhabricatorUserCustomField',

‎src/applications/conpherence/editor/ConpherenceEditor.php

+11-3
Original file line numberDiff line numberDiff line change
@@ -533,13 +533,20 @@ protected function buildMailTemplate(PhabricatorLiskDAO $object) {
533533

534534
protected function getMailTo(PhabricatorLiskDAO $object) {
535535
$to_phids = array();
536+
536537
$participants = $object->getParticipants();
537-
if (empty($participants)) {
538+
if (!$participants) {
538539
return $to_phids;
539540
}
540-
$preferences = id(new PhabricatorUserPreferences())
541-
->loadAllWhere('userPHID in (%Ls)', array_keys($participants));
541+
542+
$participant_phids = mpull($participants, 'getParticipantPHID');
543+
544+
$preferences = id(new PhabricatorUserPreferencesQuery())
545+
->setViewer(PhabricatorUser::getOmnipotentUser())
546+
->withUserPHIDs($participant_phids)
547+
->execute();
542548
$preferences = mpull($preferences, null, 'getUserPHID');
549+
543550
foreach ($participants as $phid => $participant) {
544551
$default = ConpherenceSettings::EMAIL_ALWAYS;
545552
$preference = idx($preferences, $phid);
@@ -557,6 +564,7 @@ protected function getMailTo(PhabricatorLiskDAO $object) {
557564
$to_phids[] = $phid;
558565
}
559566
}
567+
560568
return $to_phids;
561569
}
562570

‎src/applications/feed/PhabricatorFeedStoryPublisher.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,10 @@ private function filterSubscribedPHIDs(array $phids) {
207207

208208
$tags = $this->getMailTags();
209209
if ($tags) {
210-
$all_prefs = id(new PhabricatorUserPreferences())->loadAllWhere(
211-
'userPHID in (%Ls)',
212-
$phids);
210+
$all_prefs = id(new PhabricatorUserPreferencesQuery())
211+
->setViewer(PhabricatorUser::getOmnipotentUser())
212+
->withUserPHIDs($phids)
213+
->execute();
213214
$all_prefs = mpull($all_prefs, null, 'getUserPHID');
214215
}
215216

‎src/applications/metamta/storage/PhabricatorMetaMTAMail.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -940,9 +940,10 @@ private function loadActors(array $actor_phids) {
940940
}
941941
}
942942

943-
$all_prefs = id(new PhabricatorUserPreferences())->loadAllWhere(
944-
'userPHID in (%Ls)',
945-
$actor_phids);
943+
$all_prefs = id(new PhabricatorUserPreferencesQuery())
944+
->setViewer(PhabricatorUser::getOmnipotentUser())
945+
->withUserPHIDs($actor_phids)
946+
->execute();
946947
$all_prefs = mpull($all_prefs, null, 'getUserPHID');
947948

948949
$value_email = PhabricatorUserPreferences::MAILTAG_PREFERENCE_EMAIL;

‎src/applications/people/storage/PhabricatorUser.php

+9-7
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,10 @@ public function loadPreferences() {
494494

495495
$preferences = null;
496496
if ($this->getPHID()) {
497-
$preferences = id(new PhabricatorUserPreferences())->loadOneWhere(
498-
'userPHID = %s',
499-
$this->getPHID());
497+
$preferences = id(new PhabricatorUserPreferencesQuery())
498+
->setViewer($this)
499+
->withUsers(array($this))
500+
->executeOne();
500501
}
501502

502503
if (!$preferences) {
@@ -1293,11 +1294,12 @@ public function destroyObjectPermanently(
12931294
$external->delete();
12941295
}
12951296

1296-
$prefs = id(new PhabricatorUserPreferences())->loadAllWhere(
1297-
'userPHID = %s',
1298-
$this->getPHID());
1297+
$prefs = id(new PhabricatorUserPreferencesQuery())
1298+
->setViewer($engine->getViewer())
1299+
->withUsers(array($this))
1300+
->execute();
12991301
foreach ($prefs as $pref) {
1300-
$pref->delete();
1302+
$engine->destroyObject($pref);
13011303
}
13021304

13031305
$profiles = id(new PhabricatorUserProfile())->loadAllWhere(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
final class PhabricatorUserPreferencesPHIDType extends PhabricatorPHIDType {
4+
5+
const TYPECONST = 'PSET';
6+
7+
public function getTypeName() {
8+
return pht('Settings');
9+
}
10+
11+
public function newObject() {
12+
return new PhabricatorUserPreferences();
13+
}
14+
15+
public function getPHIDTypeApplicationClass() {
16+
return 'PhabricatorSettingsApplication';
17+
}
18+
19+
protected function buildQueryForObjects(
20+
PhabricatorObjectQuery $query,
21+
array $phids) {
22+
23+
return id(new PhabricatorUserPreferencesQuery())
24+
->withPHIDs($phids);
25+
}
26+
27+
public function loadHandles(
28+
PhabricatorHandleQuery $query,
29+
array $handles,
30+
array $objects) {
31+
32+
$viewer = $query->getViewer();
33+
foreach ($handles as $phid => $handle) {
34+
$preferences = $objects[$phid];
35+
36+
$handle->setName(pht('Settings %d', $preferences->getID()));
37+
}
38+
}
39+
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
3+
final class PhabricatorUserPreferencesQuery
4+
extends PhabricatorCursorPagedPolicyAwareQuery {
5+
6+
private $ids;
7+
private $phids;
8+
private $userPHIDs;
9+
private $users = array();
10+
11+
public function withIDs(array $ids) {
12+
$this->ids = $ids;
13+
return $this;
14+
}
15+
16+
public function withPHIDs(array $phids) {
17+
$this->phids = $phids;
18+
return $this;
19+
}
20+
21+
public function withUserPHIDs(array $phids) {
22+
$this->userPHIDs = $phids;
23+
return $this;
24+
}
25+
26+
public function withUsers(array $users) {
27+
assert_instances_of($users, 'PhabricatorUser');
28+
$this->users = mpull($users, null, 'getPHID');
29+
$this->withUserPHIDs(array_keys($this->users));
30+
return $this;
31+
}
32+
33+
public function newResultObject() {
34+
return new PhabricatorUserPreferences();
35+
}
36+
37+
protected function loadPage() {
38+
return $this->loadStandardPage($this->newResultObject());
39+
}
40+
41+
protected function willFilterPage(array $prefs) {
42+
$user_phids = mpull($prefs, 'getUserPHID');
43+
$user_phids = array_filter($user_phids);
44+
45+
// If some of the preferences are attached to users, try to use any objects
46+
// we were handed first. If we're missing some, load them.
47+
48+
if ($user_phids) {
49+
$users = $this->users;
50+
51+
$user_phids = array_fuse($user_phids);
52+
$load_phids = array_diff_key($user_phids, $users);
53+
$load_phids = array_keys($load_phids);
54+
55+
if ($load_phids) {
56+
$load_users = id(new PhabricatorPeopleQuery())
57+
->setViewer($this->getViewer())
58+
->withPHIDs($load_phids)
59+
->execute();
60+
$load_users = mpull($load_users, null, 'getPHID');
61+
$users += $load_users;
62+
}
63+
} else {
64+
$users = array();
65+
}
66+
67+
foreach ($prefs as $key => $pref) {
68+
$user_phid = $pref->getUserPHID();
69+
if (!$user_phid) {
70+
$pref->attachUser(null);
71+
continue;
72+
}
73+
74+
$user = idx($users, $user_phid);
75+
if (!$user) {
76+
$this->didRejectResult($pref);
77+
unset($prefs[$key]);
78+
continue;
79+
}
80+
81+
$pref->attachUser($user);
82+
}
83+
84+
return $prefs;
85+
}
86+
87+
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
88+
$where = parent::buildWhereClauseParts($conn);
89+
90+
if ($this->ids !== null) {
91+
$where[] = qsprintf(
92+
$conn,
93+
'id IN (%Ld)',
94+
$this->ids);
95+
}
96+
97+
if ($this->phids !== null) {
98+
$where[] = qsprintf(
99+
$conn,
100+
'phid IN (%Ls)',
101+
$this->phids);
102+
}
103+
104+
if ($this->userPHIDs !== null) {
105+
$where[] = qsprintf(
106+
$conn,
107+
'userPHID IN (%Ls)',
108+
$this->userPHIDs);
109+
}
110+
111+
return $where;
112+
}
113+
114+
public function getQueryApplicationClass() {
115+
return 'PhabricatorSettingsApplication';
116+
}
117+
118+
}

0 commit comments

Comments
 (0)
Failed to load comments.