PluginProbe
Groups – Memberships and Access Control / 4.7.0
Groups – Memberships and Access Control v4.7.0
4.7.1 4.7.0 4.6.0 4.5.0 4.4.0 4.3.0 trunk 1.0.0-beta-1 1.0.0-beta-2 1.0.0-beta-3 1.0.0-beta-3b 1.0.0-beta-3c 1.0.0-beta-3d 1.1.4 1.1.5 1.10.0 1.10.1 1.10.2 1.10.3 1.11.0 1.11.1 1.11.2 1.11.3 1.12.0 1.13.0 All 131 releases
groups / lib / core / class-groups-user-group.php

class-groups-user-group.php in Groups – Memberships and Access Control 4.7.0, at lib/core/class-groups-user-group.php

317 lines 9.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * class-groups-user-group.php
4 *
5 * Copyright (c) "kento" Karim Rahimpur www.itthinx.com
6 *
7 * This code is released under the GNU General Public License.
8 * See COPYRIGHT.txt and LICENSE.txt.
9 *
10 * This code is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * This header and all notices must be kept intact.
16 *
17 * @author Karim Rahimpur
18 * @package groups
19 * @since groups 1.0.0
20 */
21
22 if ( !defined( 'ABSPATH' ) ) {
23 exit;
24 }
25
26 // phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
27
28 /**
29 * User Group OPM.
30 */
31 class Groups_User_Group {
32
33 /**
34 * @var object persisted object
35 *
36 * @access private - do not access this property directly, the visibility will be made private in the future
37 */
38 public $user_group = null;
39
40 /**
41 * Hook into appropriate actions.
42 *
43 * @see wp_delete_user()
44 * @see remove_user_from_blog()
45 */
46 public static function init() {
47 // when a user is deleted, it must be removed from all groups it
48 // belongs to - triggered by wp_delete_user() and wpmu_delete_user()
49 add_action( 'deleted_user', array( __CLASS__, 'deleted_user' ) );
50
51 // when a user is removed from a blog, the user must be removed
52 // from all groups in that blog that it belongs to
53 add_action( 'remove_user_from_blog', array( __CLASS__, 'remove_user_from_blog' ), 10, 2 );
54 }
55
56 /**
57 * Create by user and group id.
58 * Must have been persisted.
59 *
60 * @param int $user_id
61 * @param int $group_id
62 */
63 public function __construct( $user_id, $group_id ) {
64 $this->user_group = self::read( $user_id, $group_id );
65 if ( $this->user_group === false ) {
66 $this->user_group = null;
67 }
68 }
69
70 /**
71 * Provide the user ID related to this object.
72 *
73 * @return int|null
74 */
75 public function get_user_id() {
76 return $this->user_id; // @phpstan-ignore property.notFound
77 }
78
79 /**
80 * Provide the group ID related to this object.
81 *
82 * @return int|null
83 */
84 public function get_group_id() {
85 return $this->group_id; // @phpstan-ignore property.notFound
86 }
87
88 /**
89 * Retrieve a property by name.
90 *
91 * Possible properties:
92 * - user_id
93 * - group_id
94 *
95 * @param string $name property's name
96 *
97 * @return mixed property value, will return null if property does not exist
98 */
99 public function __get( $name ) {
100 $result = null;
101 if ( $this->user_group !== null ) {
102 switch ( $name ) {
103 case 'user_id' :
104 case 'group_id' :
105 $result = $this->user_group->$name;
106 break;
107 }
108 }
109 return $result;
110 }
111
112 /**
113 * Persist a user-group relation.
114 *
115 * As of Groups 2.2.0, this is not invoked when entries for existing users are created on
116 * plugin activation, thus the 'groups_created_user_group' action is not called for these.
117 *
118 * @param array $map attributes - must provide user_id and group_id
119 *
120 * @return true on success, otherwise false
121 */
122 public static function create( $map ) {
123
124 global $wpdb;
125
126 $result = false;
127
128 $group_id = isset( $map['group_id'] ) ? $map['group_id'] : null;
129 $user_id = isset( $map['user_id'] ) ? $map['user_id'] : null;
130
131 // avoid nonsense requests
132 if ( !empty( $group_id ) ) {
133 // make sure user and group exist
134 if (
135 ( false !== Groups_Utility::id( $user_id ) ) &&
136 ( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(ID) FROM $wpdb->users WHERE ID = %d", $user_id ) ) > 0 ) &&
137 ( $group = Groups_Group::read( $group_id ) )
138 ) {
139 // only allow to add users to groups if they belong to the
140 // group's blog or we have the anonymous user
141 if ( is_user_member_of_blog( Groups_Utility::id( $user_id ) ) || ( Groups_Utility::id( $user_id ) === 0 ) ) {
142 $user_group_table = _groups_get_tablename( 'user_group' );
143 // don't try to create duplicate entries
144 // also it would raise an error for duplicate PK
145 if ( 0 === intval( $wpdb->get_var( $wpdb->prepare(
146 "SELECT COUNT(*) FROM $user_group_table WHERE user_id = %d AND group_id = %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
147 Groups_Utility::id( $user_id ),
148 Groups_Utility::id( $group_id ) ) ) )
149 ) {
150 $data = array(
151 'user_id' => Groups_Utility::id( $user_id ),
152 'group_id' => Groups_Utility::id( $group_id )
153 );
154 $formats = array( '%d', '%d' );
155 if ( $wpdb->insert( $user_group_table, $data, $formats ) ) {
156 $result = true;
157 do_action( 'groups_created_user_group', $user_id, $group_id );
158 }
159 }
160 }
161 }
162 }
163 return $result;
164 }
165
166 /**
167 * Retrieve a user-group relation.
168 *
169 * @param int $user_id user's id
170 * @param int $group_id group's id
171 *
172 * @return object upon success, otherwise false
173 */
174 public static function read( $user_id, $group_id ) {
175 global $wpdb;
176 $result = false;
177
178 $user_group_table = _groups_get_tablename( 'user_group' );
179 $user_group = $wpdb->get_row( $wpdb->prepare(
180 "SELECT * FROM $user_group_table WHERE user_id = %d AND group_id = %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
181 Groups_Utility::id( $user_id ),
182 Groups_Utility::id( $group_id )
183 ) );
184 if ( $user_group !== null ) {
185 $result = $user_group;
186 }
187 return $result;
188 }
189
190 /**
191 * Update user-group relation.
192 *
193 * As the relation has no properties that could be updated, this method does nothing and will return false.
194 *
195 * @param array $map
196 *
197 * @return true on success, otherwise false
198 */
199 public static function update( $map ) {
200 $result = false;
201 // @since 2.20.0 do not process
202 if ( false ) {
203 $group_id = isset( $map['group_id'] ) ? $map['group_id'] : null;
204 $user_id = isset( $map['user_id'] ) ? $map['user_id'] : null;
205 if ( $group_id !== null && $user_id !== null ) {
206 // make sure user and group exist
207 if ( ( false !== Groups_Utility::id( $user_id ) ) && get_user_by( 'id', $user_id ) && Groups_Group::read( $group_id ) ) {
208 $result = true;
209 do_action( 'groups_updated_user_group', $user_id, $group_id );
210 }
211 }
212 }
213 return $result;
214 }
215
216 /**
217 * Remove user-group relation.
218 *
219 * @param int $user_id
220 * @param int $group_id
221 *
222 * @return true if successful, false otherwise
223 */
224 public static function delete( $user_id, $group_id ) {
225
226 global $wpdb;
227 $result = false;
228
229 // avoid nonsense requests
230 if ( !empty( $group_id ) ) {
231 // to allow deletion of an entry after a user has been deleted,
232 // we don't check if the user exists
233 $user_group_table = _groups_get_tablename( 'user_group' );
234 // get rid of it
235 $rows = $wpdb->query( $wpdb->prepare(
236 "DELETE FROM $user_group_table WHERE user_id = %d AND group_id = %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
237 Groups_Utility::id( $user_id ),
238 Groups_Utility::id( $group_id )
239 ) );
240 // must have affected a row, otherwise no great success
241 $result = ( $rows !== false ) && ( $rows > 0 );
242 if ( $result ) {
243 do_action( 'groups_deleted_user_group', $user_id, $group_id );
244 }
245 }
246 return $result;
247 }
248
249 /**
250 * Hooks into the deleted_user action to remove the deleted user from
251 * all groups it belongs to.
252 *
253 * @param int $user_id
254 */
255 public static function deleted_user( $user_id ) {
256 global $wpdb;
257
258 $user_group_table = _groups_get_tablename( 'user_group' );
259 $rows = $wpdb->get_results( $wpdb->prepare(
260 "SELECT * FROM $user_group_table WHERE user_id = %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
261 Groups_Utility::id( $user_id )
262 ) );
263 if ( $rows ) {
264 foreach ( $rows as $row ) {
265 // don't optimize that in preference of a standard deletion
266 // process (trigger actions ...)
267 self::delete( $row->user_id, $row->group_id );
268 }
269 }
270 }
271
272 /**
273 * Hooks into the remove_user_from_blog action to remove the user
274 * from groups that belong to that blog.
275 *
276 * Note that this is preemptive as there is no
277 * removed_user_from_blog action.
278 *
279 * @param int $user_id
280 * @param int $blog_id
281 */
282 public static function remove_user_from_blog( $user_id, $blog_id ) {
283
284 if ( is_multisite() ) {
285 Groups_Controller::switch_to_blog( $blog_id );
286 }
287
288 global $wpdb;
289
290 $group_table = _groups_get_tablename( 'group' );
291 $user_group_table = _groups_get_tablename( 'user_group' );
292 // We can end up here while a blog is being deleted, in that case,
293 // the tables have already been deleted.
294 if ( ( $wpdb->get_var( "SHOW TABLES LIKE '" . $group_table . "'" ) == $group_table ) && // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
295 ( $wpdb->get_var( "SHOW TABLES LIKE '" . $user_group_table . "'" ) == $user_group_table ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
296 ) {
297
298 $rows = $wpdb->get_results( $wpdb->prepare(
299 "SELECT * FROM $user_group_table LEFT JOIN $group_table ON $user_group_table.group_id = $group_table.group_id WHERE $user_group_table.user_id = %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
300 Groups_Utility::id( $user_id )
301 ) );
302 if ( $rows ) {
303 foreach ( $rows as $row ) {
304 // don't optimize that, favour standard deletion
305 self::delete( $row->user_id, $row->group_id );
306 }
307 }
308
309 }
310
311 if ( is_multisite() ) {
312 Groups_Controller::restore_current_blog();
313 }
314 }
315 }
316 Groups_User_Group::init();
317