1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
<?php /** * Data object persisted as a WordPress user meta entry under the loco_prefs key * * @property string $credit Last-Translator credit, defaults to current display name * @property string[] $locales List of locales user wants to be restricted to seeing. */ class Loco_data_Preferences extends Loco_data_Serializable {
/** * User preference singletons * @var Loco_data_Preferences[] */ private static $current = [];
/** * ID of the currently operational user * @var int */ private $user_id = 0;
/** * Available options and their defaults * @var array */ private static $defaults = [ 'credit' => '', 'locales' => [], ];
/** * Get current user's preferences * @return Loco_data_Preferences */ public static function get(){ $id = get_current_user_id(); if( ! $id ){ // allow null return only on command line. All web users must be logged in if( 'cli' === PHP_SAPI || defined('LOCO_TEST') ){ return null; } throw new Exception( 'No current user' ); // @codeCoverageIgnore } if( isset(self::$current[$id]) ){ return self::$current[$id]; } $prefs = self::create($id); self::$current[$id] = $prefs; $prefs->fetch(); return $prefs; }
/** * Create default settings instance * @param int User ID * @return Loco_data_Preferences */ public static function create( $id ){ $prefs = new Loco_data_Preferences( self::$defaults ); $prefs->user_id = $id; return $prefs; }
/** * Destroy current user's preferences * @return void */ public static function clear(){ get_current_user_id() && self::get()->remove(); }
/** * Persist object in WordPress usermeta table * @return bool */ public function persist(){ return update_user_meta( $this->user_id, 'loco_prefs', $this->getSerializable() ) ? true : false; }
/** * Retrieve and unserialize this object from WordPress usermeta table * @return bool whether object existed in cache */ public function fetch(){ $data = get_user_meta( $this->user_id, 'loco_prefs', true ); // See comments in Loco_data_Settings if( is_array($data) ){ $copy = new Loco_data_Preferences; $copy->setUnserialized($data); $data = $copy->getArrayCopy() + $this->getArrayCopy(); $this->exchangeArray($data); $this->clean(); return true; } return false; }
/** * Delete usermeta entry from WordPress * return bool */ public function remove(){ $id = $this->user_id; self::$current[$id] = null; return delete_user_meta( $id, 'loco_prefs' ); }
/** * Populate all settings from raw postdata. * @param array * @return Loco_data_Preferences */ public function populate( array $data ){ // set all keys present in array foreach( $data as $prop => $value ){ try { $this->offsetSet( $prop, $value ); } catch( InvalidArgumentException $e ){ // skipping invalid key } } return $this; }
/** * {@inheritdoc} */ public function offsetSet( $prop, $value ){ $value = parent::cast($prop,$value,self::$defaults); parent::offsetSet( $prop, $value ); }
/** * Get default Last-Translator credit * @return string */ public function default_credit(){ $user = wp_get_current_user(); $name = (string) $user->get('display_name'); if( $user->get('user_login') === $name ){ $name = ''; } return $name; } /** * Check if user wants to know about this locale * @param Loco_Locale locale to match in whitelist * @return bool */ public function has_locale( Loco_Locale $locale ){ $haystack = $this->locales; if( $haystack ){ foreach( $haystack as $tag ){ $tag = strtolower($tag); // allow language wildcard. en_GB allowed by "en" if( $locale->lang === $tag ){ return true; } // else normalize whitelist before comparison if( Loco_Locale::parse($tag)->__toString() === $locale->__toString() ){ return true; } } return false; } return true; }
}
|