MediaWiki master
LocalUserOptionsStore.php
Go to the documentation of this file.
1<?php
2
4
9
11 private IConnectionProvider $dbProvider;
12
14 private $optionsFromDb;
15
16 public function __construct( IConnectionProvider $dbProvider ) {
17 $this->dbProvider = $dbProvider;
18 }
19
20 public function fetch(
21 UserIdentity $user,
22 int $recency
23 ): array {
24 // In core, only users with local accounts may have preferences
25 if ( !$user->getId() ) {
26 return [];
27 }
28
29 $dbr = DBAccessObjectUtils::getDBFromRecency( $this->dbProvider, $recency );
30 $res = $dbr->newSelectQueryBuilder()
31 ->select( [ 'up_property', 'up_value' ] )
32 ->from( 'user_properties' )
33 ->where( [ 'up_user' => $user->getId() ] )
34 ->recency( $recency )
35 ->caller( __METHOD__ )->fetchResultSet();
36
37 $options = [];
38 foreach ( $res as $row ) {
39 $options[$row->up_property] = (string)$row->up_value;
40 }
41
42 $this->optionsFromDb[$user->getId()] = $options;
43 return $options;
44 }
45
46 public function fetchBatchForUserNames( array $keys, array $userNames ) {
47 if ( !$keys || !$userNames ) {
48 return [];
49 }
50
51 $options = [];
52 $res = $this->dbProvider->getReplicaDatabase()
53 ->newSelectQueryBuilder()
54 ->select( [ 'user_name', 'up_property', 'up_value' ] )
55 ->from( 'user_properties' )
56 ->join( 'user', null, 'user_id=up_user' )
57 ->where( [
58 'up_property' => $keys,
59 'user_name' => $userNames
60 ] )
61 ->caller( __METHOD__ )
62 ->fetchResultSet();
63 foreach ( $res as $row ) {
64 $options[$row->up_property][$row->user_name] = (string)$row->up_value;
65 }
66 return $options;
67 }
68
69 public function store( UserIdentity $user, array $updates ) {
70 // In core, only users with local accounts may have preferences
71 if ( !$user->getId() ) {
72 return false;
73 }
74
75 $oldOptions = $this->optionsFromDb[ $user->getId() ]
76 ?? $this->fetch( $user, IDBAccessObject::READ_LATEST );
77 $newOptions = $oldOptions;
78 $keysToDelete = [];
79 $rowsToInsert = [];
80 foreach ( $updates as $key => $value ) {
82 $value, $oldOptions[$key] ?? null )
83 ) {
84 // Update by deleting and reinserting
85 if ( array_key_exists( $key, $oldOptions ) ) {
86 $keysToDelete[] = $key;
87 unset( $newOptions[$key] );
88 }
89 if ( $value !== null ) {
90 $truncValue = mb_strcut( $value, 0,
92 $rowsToInsert[] = [
93 'up_user' => $user->getId(),
94 'up_property' => $key,
95 'up_value' => $truncValue,
96 ];
97 $newOptions[$key] = $truncValue;
98 }
99 }
100 }
101 if ( !count( $keysToDelete ) && !count( $rowsToInsert ) ) {
102 // Nothing to do
103 return false;
104 }
105
106 // Do the DELETE
107 $dbw = $this->dbProvider->getPrimaryDatabase();
108 if ( $keysToDelete ) {
109 $dbw->newDeleteQueryBuilder()
110 ->deleteFrom( 'user_properties' )
111 ->where( [ 'up_user' => $user->getId() ] )
112 ->andWhere( [ 'up_property' => $keysToDelete ] )
113 ->caller( __METHOD__ )->execute();
114 }
115 if ( $rowsToInsert ) {
116 // Insert the new preference rows
117 $dbw->newInsertQueryBuilder()
118 ->insertInto( 'user_properties' )
119 ->ignore()
120 ->rows( $rowsToInsert )
121 ->caller( __METHOD__ )->execute();
122 }
123
124 // Update cache
125 $this->optionsFromDb[$user->getId()] = $newOptions;
126
127 return true;
128 }
129
130}
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:81
fetchBatchForUserNames(array $keys, array $userNames)
Fetch specific options for multiple users from the store.
store(UserIdentity $user, array $updates)
Process a batch of option updates.
fetch(UserIdentity $user, int $recency)
Fetch all options for a given user from the store.
static isValueEqual( $a, $b)
Determines whether two values are sufficiently similar that the database does not need to be updated ...
Get or change options for a given user in a given backend store.
Interface for objects representing user identity.
getId( $wikiId=self::LOCAL)
Provide primary and replica IDatabase connections.
Interface for database access objects.