PluginProbe
Groups – Memberships and Access Control / 4.7.1
Groups – Memberships and Access Control v4.7.1
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-utility.php

class-groups-utility.php in Groups – Memberships and Access Control 4.7.1, at lib/core/class-groups-utility.php

722 lines 20.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * class-groups-utility.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 * Utility functions.
30 */
31 class Groups_Utility {
32
33 /**
34 * Transient expiration, 1 minute.
35 *
36 * @since 3.0.0
37 *
38 * @var integer
39 */
40 const TREE_TRANSIENT_EXPIRATION = 60;
41
42 /**
43 * Data cache during requests to avoid expensive operations.
44 *
45 * @since 3.7.0
46 *
47 * @var array
48 */
49 private static $cache = array();
50
51 /**
52 * Register action hooks.
53 */
54 public static function boot() {
55 add_action( 'groups_created_group', array( __CLASS__, 'groups_created_group' ) );
56 add_action( 'groups_updated_group', array( __CLASS__, 'groups_updated_group' ) );
57 add_action( 'groups_deleted_group', array( __CLASS__, 'groups_deleted_group' ) );
58 }
59
60 /**
61 * Delete tree transient to refresh when new group is created.
62 *
63 * @param int $group_id
64 */
65 public static function groups_created_group( $group_id ) {
66 delete_transient( 'groups_utility_tree' );
67 }
68
69 /**
70 * Delete tree transient to refresh when a group is updated.
71 *
72 * @param int $group_id
73 */
74 public static function groups_updated_group( $group_id ) {
75 delete_transient( 'groups_utility_tree' );
76 }
77
78 /**
79 * Delete tree transient to refresh when a group is deleted.
80 *
81 * @param int $group_id
82 */
83 public static function groups_deleted_group( $group_id ) {
84 delete_transient( 'groups_utility_tree' );
85 }
86
87 /**
88 * Checks an id (0 is accepted => anonymous).
89 *
90 * @param string|int $id
91 * @return int|boolean if validated, the id as an int, otherwise false
92 */
93 public static function id( $id ) {
94 $result = false;
95 if ( is_numeric( $id ) ) {
96 $id = intval( $id );
97 //if ( $id > 0 ) {
98 if ( $id >= 0 ) { // 0 => anonymous
99 $result = $id;
100 }
101 }
102 return $result;
103 }
104
105 /**
106 * Returns an array of blog_ids for current blogs.
107 *
108 * @return array of int with blog ids
109 */
110 public static function get_blogs() {
111 global $wpdb;
112 $result = array();
113 if ( is_multisite() ) {
114 $blogs = $wpdb->get_results( $wpdb->prepare(
115 "SELECT blog_id FROM $wpdb->blogs WHERE site_id = %d AND archived = '0' AND spam = '0' AND deleted = '0' ORDER BY registered DESC",
116 $wpdb->siteid
117 ) );
118 if ( is_array( $blogs ) ) {
119 foreach ( $blogs as $blog ) {
120 $result[] = $blog->blog_id;
121 }
122 }
123 } else {
124 $result[] = get_current_blog_id();
125 }
126 return $result;
127 }
128
129 /**
130 * Object sort helper, sort by name property.
131 *
132 * @param object $o1
133 * @param object $o2
134 *
135 * @return int
136 */
137 private static function namesort( $o1, $o2 ) {
138 return strcmp( $o1->name, $o2->name );
139 }
140
141 /**
142 * Provide the groups tree.
143 *
144 * @since 3.7.0
145 *
146 * @access private
147 *
148 * @return object[]
149 */
150 public static function get_tree() {
151
152 global $wpdb;
153
154 if ( isset( self::$cache['tree'] ) ) {
155 return self::$cache['tree'];
156 }
157
158 $tree = get_transient( 'groups_utility_tree' );
159 if ( is_array( $tree ) ) {
160 self::$cache['tree'] = $tree;
161 return $tree;
162 }
163
164 $group_table = _groups_get_tablename( 'group' );
165 // Note that ORDER BY name is not necessary as it is done after obtaining the rows during processing below
166 $map = $wpdb->get_results( "SELECT group_id, parent_id, name FROM $group_table" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
167
168 $prune = array();
169
170 $objects = array();
171 foreach ( $map as $entry ) {
172 if ( $entry->parent_id !== null ) {
173 if ( !array_key_exists( $entry->parent_id, $objects ) ) {
174 // create parent entry
175 $p = new stdClass();
176 $p->name = null; // completed below
177 $p->group_id = $entry->parent_id;
178 $p->children = array();
179 $objects[$p->group_id] = $p;
180 }
181 }
182
183 if ( !array_key_exists( $entry->group_id, $objects ) ) {
184 $o = new stdClass();
185 $o->name = $entry->name;
186 $o->group_id = $entry->group_id;
187 $o->children = array();
188 $objects[$o->group_id] = $o;
189 if ( $entry->parent_id !== null ) {
190 $objects[$entry->parent_id]->children[$entry->group_id] = $o;
191 uasort( $objects[$entry->parent_id]->children, array( __CLASS__, 'namesort' ) );
192 }
193 } else {
194 // complete name from parent entry created
195 if ( $objects[$entry->group_id]->name === null ) {
196 $objects[$entry->group_id]->name = $entry->name;
197 }
198 if ( $entry->parent_id !== null ) {
199 $objects[$entry->parent_id]->children[$entry->group_id] = $objects[$entry->group_id];
200 uasort( $objects[$entry->parent_id]->children, array( __CLASS__, 'namesort' ) );
201 }
202 }
203
204 if ( $entry->parent_id !== null ) {
205 $prune[] = $entry->group_id;
206 }
207 }
208
209 foreach ( $prune as $group_id ) {
210 unset( $objects[$group_id] );
211 }
212
213 uasort( $objects, array( __CLASS__, 'namesort' ) );
214
215 set_transient( 'groups_utility_tree', $objects, self::TREE_TRANSIENT_EXPIRATION );
216
217 self::$cache['tree'] = $objects;
218
219 return $objects;
220 }
221
222 /**
223 * Render options from tree for select.
224 *
225 * @since 3.7.0
226 *
227 * @param array $tree
228 * @param string $output
229 * @param int $level
230 */
231 public static function render_tree_options( &$tree, &$output, $level = 0, $selected = array() ) {
232 foreach ( $tree as $group_id => $object ) {
233 $output .= sprintf(
234 '<option class="node" value="%d" %s>',
235 esc_attr( $group_id ),
236 in_array( $group_id, $selected ) ? 'selected' : ''
237 );
238 // If specific filtering is done on the group data, we might need to pass it through this call and use the name of the $group object instead:
239 // $group = Groups_Group::read( $group_id );
240 if ( $level > 0 ) {
241 $output .= str_repeat( "&nbsp;", $level ) . "&llcorner;";
242 }
243 $output .= $object->name ? stripslashes( wp_filter_nohtml_kses( $object->name ) ) : '';
244 $output .= '</option>';
245 if ( !empty( $object->children ) ) {
246 self::render_tree_options( $object->children, $output, $level + 1, $selected );
247 }
248 }
249 }
250
251 /**
252 * Render the group tree to the $output parameter passed by reference.
253 *
254 * @since 3.7.0
255 *
256 * @param array $tree
257 * @param string $output
258 * @param boolean $show_ids
259 */
260 public static function render_tree( &$tree, &$output, $linked = false, $show_ids = false ) {
261 $output .= '<ul class="groups-tree">';
262 foreach ( $tree as $group_id => $object ) {
263 $output .= '<li class="groups-tree-node">';
264 // If specific filtering is done on the group data, we might need to pass it through this call and use the name of the $group object instead:
265 // $group = Groups_Group::read( $group_id );
266 if ( $linked ) {
267 $edit_url = add_query_arg(
268 array(
269 'group_id' => intval( $object->group_id ),
270 'action' => 'edit'
271 ),
272 get_admin_url( null, 'admin.php?page=groups-admin' )
273 );
274 $output .= sprintf( '<a href="%s">', $edit_url );
275 }
276 if ( $show_ids ) {
277 $output .= sprintf(
278 '%s [#%d]',
279 $object->name ? stripslashes( wp_filter_nohtml_kses( $object->name ) ) : '',
280 $group_id
281 );
282 } else {
283 $output .= $object->name ? stripslashes( wp_filter_nohtml_kses( $object->name ) ) : '';
284 }
285 if ( $linked ) {
286 $output .= '</a>';
287 }
288 if ( !empty( $object->children ) ) {
289 self::render_tree( $object->children, $output, $linked, $show_ids );
290 }
291 $output .= '</li>';
292 }
293 $output .= '</ul>';
294 }
295
296 /**
297 * Get the tree hierarchy of groups.
298 *
299 * This method is inefficent. Internal uses replaced by get_tree() as of 3.7.0.
300 *
301 * @deprecated since 3.7.0
302 *
303 * @param array $tree
304 *
305 * @return array
306 */
307 public static function get_group_tree( &$tree = null, $linked = false ) {
308 global $wpdb;
309 $group_table = _groups_get_tablename( 'group' );
310 if ( $tree === null ) {
311 $tree = array();
312 $root_groups = $wpdb->get_results( "SELECT group_id FROM $group_table WHERE parent_id IS NULL ORDER BY name" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
313 if ( $root_groups ) {
314 foreach ( $root_groups as $root_group ) {
315 $group_id = Groups_Utility::id( $root_group->group_id );
316 $tree[$group_id] = array();
317 }
318 }
319 self::get_group_tree( $tree );
320 self::$cache['tree'] = $tree;
321 } else {
322 foreach ( $tree as $group_id => $nodes ) {
323 $children = $wpdb->get_results( $wpdb->prepare(
324 "SELECT group_id FROM $group_table WHERE parent_id = %d ORDER BY name", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
325 Groups_Utility::id( $group_id )
326 ) );
327 foreach ( $children as $child ) {
328 $tree[$group_id][$child->group_id] = array();
329 }
330 self::get_group_tree( $tree[$group_id] );
331 }
332 }
333 return $tree;
334 }
335
336 /**
337 * Render options from tree for select.
338 *
339 * @deprecated since 3.7.0. Internal uses replaced by get_tree_options() as of 3.7.0.
340 *
341 * @since 2.19.0
342 *
343 * @param array $tree
344 * @param string $output
345 * @param int $level
346 */
347 public static function render_group_tree_options( &$tree, &$output, $level = 0, $selected = array() ) {
348 foreach ( $tree as $group_id => $nodes ) {
349 $output .= sprintf(
350 '<option class="node" value="%d" %s>',
351 esc_attr( $group_id ),
352 in_array( $group_id, $selected ) ? 'selected' : ''
353 );
354 $group = Groups_Group::read( $group_id );
355 if ( $group ) {
356 if ( $level > 0 ) {
357 $output .= str_repeat( "&nbsp;", $level ) . "&llcorner;";
358 }
359 $output .= $group->name ? stripslashes( wp_filter_nohtml_kses( $group->name ) ) : '';
360 }
361 $output .= '</option>';
362 if ( !empty( $nodes ) ) {
363 self::render_group_tree_options( $nodes, $output, $level + 1, $selected );
364 }
365 }
366 }
367
368 /**
369 * Render the group tree to the $output parameter passed by reference.
370 *
371 * @deprecated since 3.7.0. Internal uses replaced by render_tree() as of 3.7.0.
372 *
373 * @param array $tree
374 * @param string $output
375 */
376 public static function render_group_tree( &$tree, &$output, $linked = false ) {
377 $output .= '<ul class="groups-tree">';
378 foreach ( $tree as $group_id => $nodes ) {
379 $output .= '<li class="groups-tree-node">';
380 $group = Groups_Group::read( $group_id );
381 if ( $group ) {
382 if ( $linked ) {
383 $edit_url = add_query_arg(
384 array(
385 'group_id' => intval( $group->group_id ),
386 'action' => 'edit'
387 ),
388 get_admin_url( null, 'admin.php?page=groups-admin' )
389 );
390 $output .= sprintf( '<a href="%s">', $edit_url );
391 }
392 $output .= $group->name ? stripslashes( wp_filter_nohtml_kses( $group->name ) ) : '';
393 if ( $linked ) {
394 $output .= '</a>';
395 }
396 }
397 if ( !empty( $nodes ) ) {
398 self::render_group_tree( $nodes, $output, $linked );
399 }
400 $output .= '</li>';
401 }
402 $output .= '</ul>';
403 }
404
405 /**
406 * Compares the two object's names, used for groups and
407 * capabilities, i.e. Groups_Group and Groups_Capability can be compared
408 * if both are of the same class. Otherwise this will return 0.
409 *
410 * @param Groups_Group|Groups_Capability $o1
411 * @param Groups_Group|Groups_Capability $o2 must match the class of $o1
412 *
413 * @return number
414 */
415 public static function cmp( $o1, $o2 ) {
416 $result = 0;
417 if ( $o1 instanceof Groups_Group && $o2 instanceof Groups_Group ) {
418 $result = strcmp( $o1->get_name(), $o2->get_name() );
419 } else if ( $o1 instanceof Groups_Capability && $o2 instanceof Groups_Capability ) {
420 $result = strcmp( $o1->get_capability(), $o2->get_capability() );
421 }
422 return $result;
423 }
424
425 /**
426 * Unslash, sanitize and verify nonce.
427 *
428 * @since 3.11.0
429 *
430 * @see wp_unslash()
431 * @see sanitize_text_field()
432 * @see wp_verify_nonce()
433 *
434 * @param string $nonce nonce value
435 * @param string|number $action
436 *
437 * @return int|boolean
438 */
439 public static function verify_nonce( $nonce, $action = -1 ) {
440 return wp_verify_nonce( sanitize_text_field( wp_unslash( $nonce ) ), $action );
441 }
442
443 /**
444 * Unslash, sanitize and verify named nonce provided via $_POST.
445 *
446 * @param string $name nonce name
447 * @param string|number $action
448 *
449 * @return int|boolean
450 */
451 public static function verify_post_nonce( $name, $action = -1 ) {
452 $result = false;
453 // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
454 if ( isset( $_POST[$name] ) ) {
455 // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
456 $result = self::verify_nonce( $_POST[$name], $action );
457 }
458 return $result;
459 }
460
461 /**
462 * Unslash, sanitize and verify named nonce provided via $_GET.
463 *
464 * @param string $name nonce name
465 * @param string|number $action
466 *
467 * @return int|boolean
468 */
469 public static function verify_get_nonce( $name, $action = -1 ) {
470 $result = false;
471 // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
472 if ( isset( $_GET[$name] ) ) {
473 // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
474 $result = self::verify_nonce( $_GET[$name], $action );
475 }
476 return $result;
477 }
478
479 /**
480 * Unslash, sanitize and verify named nonce provided via $_REQUEST.
481 *
482 * @param string $name nonce name
483 * @param string|number $action
484 *
485 * @return int|boolean
486 */
487 public static function verify_request_nonce( $name, $action = -1 ) {
488 $result = false;
489 // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
490 if ( isset( $_REQUEST[$name] ) ) {
491 // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
492 $result = self::verify_nonce( $_REQUEST[$name], $action );
493 }
494 return $result;
495 }
496
497 /**
498 * Sanitize the given input value, applies wp_unslash() and then sanitize_text_field() while
499 * preserving the original type of the value.
500 *
501 * @since 3.11.0
502 *
503 * @param string|number|boolean|array $value
504 *
505 * @return null|string|boolean|array
506 */
507 public static function sanitize_input( $value ) {
508 $result = null;
509 if ( is_numeric( $value ) || is_string( $value ) ) {
510 $original_value = $value;
511 $result = sanitize_text_field( wp_unslash( $value ) );
512 if ( is_int( $original_value ) ) {
513 $result = intval( $result );
514 } else if ( is_float( $original_value ) ) {
515 $result = floatval( $result );
516 } else if ( is_bool( $original_value ) ) {
517 $result = boolval( $result );
518 }
519 } else if ( is_array( $value ) ) {
520 $result = array_map( array( __CLASS__, 'sanitize_input' ), $value );
521 }
522 return $result;
523 }
524
525 /**
526 * Sanitized form data from $_POST.
527 *
528 * @since 3.11.0
529 *
530 * @param string $name
531 *
532 * @return null|string
533 */
534 public static function sanitize_post( $name ) {
535 $result = null;
536 // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
537 if ( isset( $_POST[$name] ) && ( is_numeric( $_POST[$name] ) || is_string( $_POST[$name] ) || is_array( $_POST[$name] ) ) ) {
538 // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Recommended
539 $result = self::sanitize_input( $_POST[$name] );
540 }
541 return $result;
542 }
543
544 /**
545 * Sanitized form data from $_GET.
546 *
547 * @since 3.11.0
548 *
549 * @param string $name
550 *
551 * @return null|string
552 */
553 public static function sanitize_get( $name ) {
554 $result = null;
555 // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
556 if ( isset( $_GET[$name] ) && ( is_numeric( $_GET[$name] ) || is_string( $_GET[$name] ) || is_array( $_GET[$name] ) ) ) {
557 // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Recommended
558 $result = self::sanitize_input( $_GET[$name] );
559 }
560 return $result;
561 }
562
563 /**
564 * Sanitized form data from $_REQUEST.
565 *
566 * @since 3.11.0
567 *
568 * @param string $name
569 *
570 * @return null|string
571 */
572 public static function sanitize_request( $name ) {
573 $result = null;
574 // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
575 if ( isset( $_REQUEST[$name] ) && ( is_numeric( $_REQUEST[$name] ) || is_string( $_REQUEST[$name] ) || is_array( $_REQUEST[$name] ) ) ) {
576 // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Recommended
577 $result = self::sanitize_input( $_REQUEST[$name] );
578 }
579 return $result;
580 }
581
582 /**
583 * Provide the current URL, sanitized.
584 *
585 * @since 3.11.0
586 *
587 * @return string
588 */
589 public static function get_current_url() {
590 $host = wp_unslash( $_SERVER['HTTP_HOST'] ?? '' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
591 $uri = wp_unslash( $_SERVER['REQUEST_URI'] ?? '' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
592 return sanitize_url( ( is_ssl() ? 'https://' : 'http://' ) . $host . $uri );
593 }
594 }
595
596 /**
597 * Unslash, sanitize and verify nonce.
598 *
599 * @since 3.11.0
600 *
601 * @see Groups_Utility::verify_nonce()
602 *
603 * @param string $nonce
604 * @param string|number $action
605 *
606 * @return int|boolean
607 */
608 function groups_verify_nonce( $nonce, $action = -1 ) {
609 return Groups_Utility::verify_nonce( $nonce, $action );
610 }
611
612 /**
613 * Unslash, sanitize and verify named nonce provided via $_POST.
614 *
615 * @since 3.11.0
616 *
617 * @see Groups_Utility::verify_nonce()
618 *
619 * @param string $name nonce name
620 * @param string|number $action
621 *
622 * @return int|boolean
623 */
624 function groups_verify_post_nonce( $name, $action = -1 ) {
625 return Groups_Utility::verify_post_nonce( $name, $action );
626 }
627
628 /**
629 * Unslash, sanitize and verify named nonce provided via $_GET.
630 *
631 * @since 3.11.0
632 *
633 * @see Groups_Utility::verify_nonce()
634 *
635 * @param string $name nonce name
636 * @param string|number $action
637 *
638 * @return int|boolean
639 */
640 function groups_verify_get_nonce( $name, $action = -1 ) {
641 return Groups_Utility::verify_get_nonce( $name, $action );
642 }
643
644 /**
645 * Unslash, sanitize and verify named nonce provided via $_GET.
646 *
647 * @since 3.11.0
648 *
649 * @see Groups_Utility::verify_nonce()
650 *
651 * @param string $name nonce name
652 * @param string|number $action
653 *
654 * @return int|boolean
655 */
656 function groups_verify_request_nonce( $name, $action = -1 ) {
657 return Groups_Utility::verify_request_nonce( $name, $action );
658 }
659
660 /**
661 * @see Groups_Utility::sanitize_input()
662 *
663 * @param string|number|boolean|array $value
664 *
665 * @return null|string|boolean|array
666 */
667 function groups_sanitize_input( $value ) {
668 return Groups_Utility::sanitize_input( $value );
669 }
670
671 /**
672 * @since 3.11.0
673 *
674 * @see Groups_Utility::sanitize_post()
675 *
676 * @param string $name
677 *
678 * @return null|string
679 */
680 function groups_sanitize_post( $name ) {
681 return Groups_Utility::sanitize_post( $name );
682 }
683
684 /**
685 * @since 3.11.0
686 *
687 * @see Groups_Utility::sanitize_get()
688 *
689 * @param string $name
690 *
691 * @return null|string
692 */
693 function groups_sanitize_get( $name ) {
694 return Groups_Utility::sanitize_get( $name );
695 }
696
697 /**
698 * @since 3.11.0
699 *
700 * @see Groups_Utility::sanitize_request()
701 *
702 * @param string $name
703 *
704 * @return null|string
705 */
706 function groups_sanitize_request( $name ) {
707 return Groups_Utility::sanitize_request( $name );
708 }
709
710 /**
711 * Provide the current URL, sanitized.
712 *
713 * @since 3.11.0
714 *
715 * @return string
716 */
717 function groups_get_current_url() {
718 return Groups_Utility::get_current_url();
719 }
720
721 Groups_Utility::boot();
722