PluginProbe
Groups – Memberships and Access Control / 3.9.0
Groups – Memberships and Access Control v3.9.0
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 1.13.1 All 130 releases
groups / lib / admin / class-groups-admin-posts.php

class-groups-admin-posts.php in Groups – Memberships and Access Control 3.9.0, at lib/admin/class-groups-admin-posts.php

683 lines 25.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-admin-posts.php
4 *
5 * Copyright (c) 2013 "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.4.2
20 */
21
22 if ( !defined( 'ABSPATH' ) ) {
23 exit;
24 }
25
26 /**
27 * Additions to post overview admin screens:
28 *
29 * - Filter posts by group.
30 * - Apply bulk actions to add or remove group access restrictions.
31 */
32 class Groups_Admin_Posts {
33
34 /**
35 * Field name.
36 *
37 * @var string
38 */
39 const GROUPS_READ = 'groups-read';
40
41 /**
42 * Constant for not restricted.
43 *
44 * @var string NOT_RESTRICTED
45 */
46 const NOT_RESTRICTED = '#not-restricted#';
47
48 /**
49 * Constant for restricted.
50 *
51 * @var string RESTRICTED
52 */
53 const RESTRICTED = '#restricted#';
54
55 /**
56 * Sets up an admin_init hook where our actions and filters are added.
57 */
58 public static function init() {
59 add_action( 'admin_init', array( __CLASS__, 'admin_init' ) );
60 }
61
62 /**
63 * Adds actions and filters to handle filtering by access restriction
64 * capability.
65 */
66 public static function admin_init() {
67 if ( Groups_User::current_user_can( GROUPS_ACCESS_GROUPS ) ) {
68 add_action( 'admin_enqueue_scripts', array( __CLASS__, 'admin_enqueue_scripts' ) );
69 add_action( 'admin_head', array( __CLASS__, 'admin_head' ) );
70 add_action( 'restrict_manage_posts', array( __CLASS__, 'restrict_manage_posts' ) );
71 // add_filter( 'parse_query', array( __CLASS__, 'parse_query' ) );
72
73 add_filter( 'posts_where', array( __CLASS__, 'posts_where' ), 10, 2 );
74 add_filter( 'posts_join', array( __CLASS__, 'posts_join' ), 10, 2 );
75 add_filter( 'posts_orderby', array( __CLASS__, 'posts_orderby' ), 10, 2 );
76
77 add_action( 'bulk_edit_custom_box', array( __CLASS__, 'bulk_edit_custom_box' ), 10, 2);
78 add_action( 'save_post', array( __CLASS__, 'save_post' ) );
79 }
80 }
81
82 /**
83 * Enqueues the select script.
84 */
85 public static function admin_enqueue_scripts() {
86
87 global $pagenow;
88
89 if ( $pagenow == 'edit.php' ) {
90 $post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : 'post'; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
91 $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
92 if ( !isset( $post_types_option[$post_type]['add_meta_box'] ) || $post_types_option[$post_type]['add_meta_box'] ) {
93 Groups_UIE::enqueue( 'select' );
94 wp_enqueue_style( 'groups_admin_post' );
95 }
96 }
97 }
98
99 /**
100 * Adds CSS rules to display our access restriction filter coherently.
101 */
102 public static function admin_head() {
103
104 global $pagenow;
105
106 if ( $pagenow == 'edit.php' ) {
107 $post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : 'post'; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
108 $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
109 if ( !isset( $post_types_option[$post_type]['add_meta_box'] ) || $post_types_option[$post_type]['add_meta_box'] ) {
110 echo '<style type="text/css">';
111 echo '.groups-groups-container { display: inline-block; line-height: 24px; padding-bottom: 1em; vertical-align: top; margin-left: 4px; margin-right: 4px; }';
112 echo '.groups-groups-container .groups-select-container { display: inline-block; vertical-align: top; }';
113 echo '.groups-groups-container .groups-select-container select, .groups-bulk-container select.groups-action { float: none; margin-right: 4px; vertical-align: top; }';
114 echo '.groups-groups-container .selectize-control { min-width: 128px; }';
115 echo '.groups-groups-container .selectize-control, .groups-bulk-container select.groups-action { margin-right: 4px; vertical-align: top; }';
116 echo '.groups-groups-container .selectize-input { min-height: 30px; font-size: inherit; line-height: 18px; padding: 0 4px; vertical-align: middle; }';
117 echo '.groups-groups-container .selectize-input input[type="text"] { font-size: inherit; vertical-align: middle; }';
118 echo '.groups-groups-container input.button { margin-top: 1px; vertical-align: top; }';
119 echo '.inline-edit-row fieldset .capabilities-bulk-container label span.title { min-width: 5em; padding: 2px 1em; width: auto; }';
120 echo '.tablenav .actions { overflow: visible; }'; // this is important so that the selectize options aren't hidden
121 echo '.wp-list-table td { overflow: visible; }'; // idem for bulk actions
122 echo 'label.groups-read-terms { vertical-align: middle; line-height: 28px; margin-right: 4px; }'; // Terms checkbox label
123 echo 'label.groups-read-terms input[type="checkbox"] { height: 1rem; }'; // Terms checkbox
124 echo 'th.column-groups, th.column-groups-read, th.column-capabilities { width:10%; }';
125 echo '</style>';
126 }
127 }
128 }
129
130 /**
131 * Renders the groups access restriction filter field.
132 */
133 public static function restrict_manage_posts() {
134
135 global $pagenow, $wpdb;
136
137 if ( is_admin() ) {
138
139 if ( $pagenow == 'edit.php' ) { // check that we're on the right screen
140
141 $post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : 'post'; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
142 $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
143
144 if ( !isset( $post_types_option[$post_type]['add_meta_box'] ) || $post_types_option[$post_type]['add_meta_box'] ) {
145
146 $output = '';
147
148 // capabilities select
149 $output .= '<div class="groups-groups-container">';
150 $output .= sprintf(
151 '<select class="select group" name="%s[]" multiple="multiple" placeholder="%s" data-placeholder="%s">',
152 esc_attr( Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ ),
153 esc_attr__( 'Groups &hellip;', 'groups' ),
154 esc_attr__( 'Groups &hellip;', 'groups' )
155 );
156
157 $previous_selected = array();
158 if ( !empty( $_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ] ) ) {
159 $previous_selected = $_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ]; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
160 if ( !is_array( $previous_selected ) ) {
161 $previous_selected = array();
162 }
163 }
164 $output .= sprintf(
165 '<option value="%s" %s >%s</option>', self::NOT_RESTRICTED,
166 esc_attr( in_array( self::NOT_RESTRICTED, $previous_selected ) ? ' selected="selected" ' : '' ),
167 esc_attr__( '(none)', 'groups' )
168 );
169 $output .= sprintf(
170 '<option value="%s" %s >%s</option>', self::RESTRICTED,
171 esc_attr( in_array( self::RESTRICTED, $previous_selected ) ? ' selected="selected" ' : '' ),
172 esc_attr__( '(any)', 'groups' )
173 );
174
175 $groups = apply_filters(
176 'groups_admin_posts_restrict_manage_posts_get_groups',
177 Groups_Group::get_groups(
178 apply_filters(
179 'groups_admin_posts_restrict_manage_posts_get_groups_options',
180 array( 'order_by' => 'name', 'order' => 'ASC' )
181 )
182 )
183 );
184 foreach( $groups as $group ) {
185 $selected = in_array( $group->group_id, $previous_selected ) ? ' selected="selected" ' : '';
186 $output .= sprintf(
187 '<option value="%s" %s >%s</option>',
188 esc_attr( $group->group_id ),
189 esc_attr( $selected ),
190 $group->name ? stripslashes( wp_filter_nohtml_kses( $group->name ) ) : ''
191 );
192 }
193 $output .= '</select>';
194 $output .= '</div>';
195 $output .= Groups_UIE::render_select( '.select.group' );
196
197 if (
198 function_exists( 'get_term_meta' ) && // >= WordPress 4.4.0 as we query the termmeta table
199 class_exists( 'Groups_Restrict_Categories' ) &&
200 method_exists( 'Groups_Restrict_Categories', 'get_controlled_taxonomies' ) &&
201 method_exists( 'Groups_Restrict_Categories', 'get_term_read_groups' ) // >= Groups Restrict Categories 2.0.0, the method isn't used here but it wouldn't make any sense to query unless we're >= 2.0.0
202 ) {
203 $output .= sprintf( '<label class="groups-read-terms" title="%s">', esc_attr__( 'Also look for groups related to terms', 'groups' ) );
204 $output .= sprintf( '<input type="checkbox" name="groups-read-terms" value="1" %s />', empty( $_GET['groups-read-terms'] ) ? '' : ' checked="checked" ' );
205 $output .= esc_html__( 'Terms', 'groups' );
206 $output .= '</label>';
207 }
208 echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
209 }
210
211 }
212 }
213
214 }
215
216 /**
217 * Bulk-edit access restriction groups.
218 *
219 * @param string $column_name
220 * @param string $post_type
221 */
222 public static function bulk_edit_custom_box( $column_name, $post_type ) {
223
224 global $pagenow, $wpdb;
225
226 if ( $column_name == self::GROUPS_READ ) {
227 if ( $pagenow == 'edit.php' ) { // check that we're on the right screen
228
229 $post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : 'post'; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
230 $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
231
232 if ( !isset( $post_types_option[$post_type]['add_meta_box'] ) || $post_types_option[$post_type]['add_meta_box'] ) {
233
234 $output = '<fieldset class="inline-edit-col-right">';
235 $output .= '<div class="bulk-edit-groups" style="padding:0 0.5em;">';
236
237 // capability/access restriction bulk actions added through extra_tablenav()
238 $output .= '<div id="group-bulk-actions" class="groups-bulk-container" style="display:inline">';
239
240 $output .= '<label style="display:inline;">';
241 $output .= '<span class="title">';
242 $output .= _x( 'Groups', 'Bulk edit field label', 'groups' );
243 $output .= '</span>';
244 $output .= '<select class="groups-action" name="groups-action">';
245 $output .= '<option selected="selected" value="-1">' . esc_html__( '&mdash; No Change &mdash;', 'groups' ) . '</option>';
246 $output .= '<option value="add-group">' . esc_html__( 'Add restriction', 'groups' ) . '</option>';
247 $output .= '<option value="remove-group">' . esc_html__( 'Remove restriction', 'groups' ) . '</option>';
248 $output .= '</select>';
249 $output .= '</label>';
250
251 $user = new Groups_User( get_current_user_id() );
252 $include = Groups_Access_Meta_Boxes::get_user_can_restrict_group_ids( get_current_user_id() );
253 $groups = Groups_Group::get_groups( array( 'order_by' => 'name', 'order' => 'ASC', 'include' => $include ) );
254
255 $output .= '<div class="groups-groups-container">';
256 $output .= sprintf(
257 '<select class="select bulk-group" name="%s[]" multiple="multiple" placeholder="%s" data-placeholder="%s">',
258 esc_attr( Groups_Post_Access::POSTMETA_PREFIX . 'bulk-' . Groups_Post_Access::READ ),
259 esc_attr__( 'Choose access restriction groups &hellip;', 'groups' ),
260 esc_attr__( 'Choose access restriction groups &hellip;', 'groups' )
261 );
262
263 foreach( $groups as $group ) {
264 $output .= sprintf(
265 '<option value="%s" >%s</option>',
266 esc_attr( $group->group_id ),
267 $group->name ? stripslashes( wp_filter_nohtml_kses( $group->name ) ) : ''
268 );
269 }
270 $output .= '</select>';
271 $output .= '</div>'; // .groups-groups-container
272 $output .= Groups_UIE::render_select( '.select.bulk-group' );
273
274 $output .= '</div>'; // .groups-bulk-container
275
276 $output .= '</div>'; // .bulk-edit-groups
277 $output .= '</fieldset>'; // .inline-edit-col-right
278
279 $output .= wp_nonce_field( 'post-group', 'bulk-post-group-nonce', true, false );
280
281 echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
282 }
283 }
284 }
285 }
286
287 /**
288 * Handles access restriction group modifications from bulk-editing.
289 * This is called once for each post that is included in bulk-editing.
290 * The fields that are handled here are rendered through the
291 * bulk_edit_custom_box() method in this class.
292 *
293 * @param int $post_id
294 */
295 public static function save_post( $post_id ) {
296 if ( isset( $_REQUEST['groups-action'] ) ) {
297 if ( wp_verify_nonce( $_REQUEST['bulk-post-group-nonce'], 'post-group' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
298 $field = Groups_Post_Access::POSTMETA_PREFIX . 'bulk-' . Groups_Post_Access::READ;
299 if ( !empty( $_REQUEST[$field] ) && is_array( $_REQUEST[$field] ) ) {
300 if ( Groups_Access_Meta_Boxes::user_can_restrict() ) {
301 $include = Groups_Access_Meta_Boxes::get_user_can_restrict_group_ids();
302 $groups = Groups_Group::get_groups( array( 'order_by' => 'name', 'order' => 'ASC', 'include' => $include ) );
303 $group_ids = array();
304 foreach( $groups as $group ) {
305 $group_ids[] = $group->group_id;
306 }
307 foreach( $_REQUEST[$field] as $group_id ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
308 if ( $group = Groups_Group::read( $group_id ) ) {
309 if ( in_array( $group->group_id, $group_ids ) ) {
310 switch( $_REQUEST['groups-action'] ) {
311 case 'add-group' :
312 Groups_Post_Access::create( array(
313 'post_id' => $post_id,
314 'group_id' => $group->group_id
315 ) );
316 break;
317 case 'remove-group' :
318 Groups_Post_Access::delete( $post_id, array( 'groups_read' => $group->group_id ) );
319 break;
320 }
321 }
322 }
323 }
324 }
325 }
326 }
327 }
328 }
329
330 /**
331 * Query modifier to take the selected access restriction groups into
332 * account.
333 *
334 * @deprecated not used
335 *
336 * @param WP_Query $query query object passed by reference
337 */
338 public static function parse_query( &$query ) {
339
340 global $pagenow;
341
342 if ( is_admin() ) {
343
344 if ( $pagenow == 'edit.php' ) { // check that we're on the right screen
345
346 $post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : 'post'; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
347 $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
348
349 if ( !isset( $post_types_option[$post_type]['add_meta_box'] ) || $post_types_option[$post_type]['add_meta_box'] ) {
350
351 if ( !empty( $_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ] ) &&
352 is_array( $_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ] )
353 ) {
354
355 $include_unrestricted = false;
356 if ( in_array( self::NOT_RESTRICTED, $_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ] ) ) {
357 $include_unrestricted = true;
358 }
359
360 $group_ids = array();
361 foreach ( $_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ] as $group_id ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
362 if ( Groups_Group::read( $group_id ) ) {
363 $group_ids[] = $group_id;
364 }
365 }
366
367 if ( !empty( $group_ids ) ) { // @phpstan-ignore empty.variable
368 if ( $include_unrestricted ) {
369 // meta_query does not handle a conjunction
370 // on the same meta field correctly
371 // (at least not up to WordPress 3.7.1)
372 // $query->query_vars['meta_query'] = array (
373 // 'relation' => 'OR',
374 // array (
375 // 'key' => Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ,
376 // 'value' => $group_ids,
377 // 'compare' => 'IN'
378 // ),
379 // array (
380 // 'key' => Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ,
381 // 'compare' => 'NOT EXISTS'
382 // )
383 // );
384 // we'll limit it to show just unrestricted entries
385 // until the above is solved
386 $query->query_vars['meta_query'] = array (
387 array (
388 'key' => Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ,
389 'compare' => 'NOT EXISTS'
390 )
391 );
392 } else {
393 $query->query_vars['meta_query'] = array (
394 array (
395 'key' => Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ,
396 'value' => $group_ids,
397 'compare' => 'IN'
398 )
399 );
400 }
401 } else if ( $include_unrestricted ) {
402 $query->query_vars['meta_query'] = array (
403 array (
404 'key' => Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ,
405 'compare' => 'NOT EXISTS'
406 )
407 );
408 }
409 }
410 }
411 }
412
413 }
414
415 }
416
417 /**
418 * Filters out posts by group. This is used when you choose groups on the post admin screen so that
419 * only those posts who are restricted by groups are shown.
420 *
421 * @param string $where
422 * @param WP_Query $query
423 *
424 * @return string
425 */
426 public static function posts_where( $where, $query ) {
427
428 global $wpdb;
429
430 if ( self::extend_for_filter_groups_read( $query ) ) { // also checks that $_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ] is an array
431
432 $post_in = array();
433 $term_in = array();
434
435 $filter_terms = false;
436 if (
437 !empty( $_GET['groups-read-terms'] ) &&
438 function_exists( 'get_term_meta' ) && // >= WordPress 4.4.0 as we query the termmeta table
439 class_exists( 'Groups_Restrict_Categories' ) &&
440 method_exists( 'Groups_Restrict_Categories', 'get_controlled_taxonomies' ) &&
441 method_exists( 'Groups_Restrict_Categories', 'get_term_read_groups' ) // >= Groups Restrict Categories 2.0.0, the method isn't used here but it wouldn't make any sense to query unless we're >= 2.0.0
442 ) {
443 $filter_terms = true;
444 }
445
446 if ( in_array( self::NOT_RESTRICTED, $_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ] ) ) {
447 $condition =
448 "SELECT ID post_id FROM $wpdb->posts " .
449 "WHERE ID NOT IN (" .
450 "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'groups-read'";
451 if ( $filter_terms ) {
452 $condition .=
453 " UNION ALL " .
454 "SELECT p.ID post_id FROM $wpdb->posts p " .
455 "LEFT JOIN $wpdb->term_relationships tr ON p.ID = tr.object_id " .
456 "LEFT JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id " .
457 "LEFT JOIN $wpdb->termmeta tm ON tt.term_id = tm.term_id " .
458 "WHERE tm.meta_key = 'groups-read'";
459 }
460 $condition .= ")";
461 $post_in[] = $condition;
462 }
463
464 if ( in_array( self::RESTRICTED, $_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ] ) ) {
465 $condition = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'groups-read'";
466 if ( $filter_terms ) {
467 $condition .=
468 " UNION ALL " .
469 "SELECT p.ID post_id FROM $wpdb->posts p " .
470 "LEFT JOIN $wpdb->term_relationships tr ON p.ID = tr.object_id " .
471 "LEFT JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id " .
472 "LEFT JOIN $wpdb->termmeta tm ON tt.term_id = tm.term_id " .
473 "WHERE tm.meta_key = 'groups-read'";
474 }
475 $post_in[] = $condition;
476 }
477
478 $group_ids = array();
479 foreach ( $_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ] as $group_id ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
480 if ( $group_id = Groups_Utility::id( $group_id ) ) {
481 if ( Groups_Group::read( $group_id ) ) {
482 $group_ids[] = $group_id;
483 }
484 }
485 }
486
487 if ( !empty( $group_ids ) ) {
488 $groups = ' ( ' . implode( ',', esc_sql( $group_ids ) ) . ' ) ';
489 $condition =
490 "SELECT post_id FROM $wpdb->postmeta " .
491 "WHERE meta_key = 'groups-read' AND meta_value IN $groups";
492 if ( $filter_terms ) {
493 $condition .=
494 " UNION ALL " .
495 "SELECT p.ID post_id FROM $wpdb->posts p " .
496 "LEFT JOIN $wpdb->term_relationships tr ON p.ID = tr.object_id " .
497 "LEFT JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id " .
498 "LEFT JOIN $wpdb->termmeta tm ON tt.term_id = tm.term_id " .
499 "WHERE tm.meta_key = 'groups-read' AND tm.meta_value IN $groups";
500 }
501 $post_in[] = $condition;
502 }
503
504 if ( count( $post_in ) > 0 ) {
505 if (
506 !empty( $_GET['groups-read-terms'] ) &&
507 function_exists( 'get_term_meta' ) && // >= WordPress 4.4.0 as we query the termmeta table
508 class_exists( 'Groups_Restrict_Categories' ) &&
509 method_exists( 'Groups_Restrict_Categories', 'get_controlled_taxonomies' ) &&
510 method_exists( 'Groups_Restrict_Categories', 'get_term_read_groups' ) // >= Groups Restrict Categories 2.0.0, the method isn't used here but it wouldn't make any sense to query unless we're >= 2.0.0
511 ) {
512 $post_in = array_merge( $post_in, $term_in );
513 }
514 $id_in = implode( ' UNION ALL ', $post_in );
515 $where .= " AND $wpdb->posts.ID IN ( $id_in ) ";
516 }
517
518 }
519
520 return $where;
521 }
522
523 /**
524 * Adds to the join to allow advanced sorting by group on the admin back end for post tables.
525 *
526 * @param string $join
527 * @param WP_Query $query
528 */
529 public static function posts_join( $join, $query ) {
530 global $wpdb;
531 if ( self::extend_for_orderby_groups_read( $query ) ) {
532 $group_table = _groups_get_tablename( 'group' );
533 if ( function_exists( 'get_term_meta' ) ) { // >= WordPress 4.4.0 as we query the termmeta table
534 $join .= "
535 LEFT JOIN (
536 SELECT p.ID post_id, GROUP_CONCAT(DISTINCT groups_read.group_name ORDER BY groups_read.group_name) groups
537 FROM $wpdb->posts p
538 LEFT JOIN (
539 SELECT post_id, g.name group_name
540 FROM $wpdb->postmeta pm
541 LEFT JOIN $group_table g ON pm.meta_value = g.group_id
542 WHERE pm.meta_key = 'groups-read'
543 UNION ALL
544 SELECT p.ID post_id, g.name group_name
545 FROM $wpdb->posts p
546 LEFT JOIN $wpdb->term_relationships tr ON p.ID = tr.object_id
547 LEFT JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
548 LEFT JOIN $wpdb->termmeta tm ON tt.term_id = tm.term_id
549 LEFT JOIN $group_table g ON tm.meta_value = g.group_id
550 WHERE tm.meta_key = 'groups-read'
551 ) as groups_read ON p.ID = groups_read.post_id
552 GROUP BY p.ID
553 ) groups_tmp ON $wpdb->posts.ID = groups_tmp.post_id
554 ";
555 } else {
556 $join .= "
557 LEFT JOIN (
558 SELECT p.ID post_id, GROUP_CONCAT(DISTINCT groups_read.group_name ORDER BY groups_read.group_name) groups
559 FROM $wpdb->posts p
560 LEFT JOIN (
561 SELECT post_id, g.name group_name
562 FROM $wpdb->postmeta pm
563 LEFT JOIN $group_table g ON pm.meta_value = g.group_id
564 WHERE pm.meta_key = 'groups-read'
565 ) as groups_read ON p.ID = groups_read.post_id
566 GROUP BY p.ID
567 ) groups_tmp ON $wpdb->posts.ID = groups_tmp.post_id
568 ";
569 }
570 }
571 return $join;
572 }
573
574 /**
575 * Extend the orderby clause to sort by groups related to the post and its terms.
576 *
577 * @param $string $orderby
578 * @param WP_Query $query
579 *
580 * @return string
581 */
582 public static function posts_orderby( $orderby, $query ) {
583 if ( self::extend_for_orderby_groups_read( $query ) ) {
584 switch( $query->get( 'order' ) ) {
585 case 'desc' :
586 case 'DESC' :
587 $order = 'DESC';
588 break;
589 default :
590 $order = 'ASC';
591 }
592 $prefix = ' groups_tmp.groups ' . $order;
593 if ( !empty( $orderby ) ) {
594 $prefix .= ' , ';
595 }
596 $orderby = $prefix . $orderby;
597 }
598 return $orderby;
599 }
600
601 /**
602 * Check if we should apply our posts_join and posts_orderby filters. Used in those.
603 *
604 * @param WP_Query $query
605 *
606 * @return boolean
607 */
608 private static function extend_for_orderby_groups_read( &$query ) {
609 $result = false;
610 if ( is_admin() ) {
611 // check if query is for a post type we handle
612 $post_types = $query->get( 'post_type' );
613 if ( !is_array( $post_types ) ) {
614 $post_types = array( $post_types );
615 }
616 foreach( $post_types as $post_type ) {
617 $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
618 if (
619 !isset( $post_types_option[$post_type]['add_meta_box'] ) ||
620 $post_types_option[$post_type]['add_meta_box']
621 ) {
622 // only act on post etc. screens
623 $screen = get_current_screen();
624 if (
625 !empty( $screen ) &&
626 !empty( $screen->id ) &&
627 ( $screen->id == 'edit-' . $post_type )
628 ) {
629 if ( $query->get( 'orderby' ) == self::GROUPS_READ ) {
630 $result = true;
631 break;
632 }
633 }
634 }
635 }
636 }
637 return $result;
638 }
639
640 /**
641 * Check if we should apply our posts_where filter. Used in it.
642 *
643 * @param WP_Query $query
644 *
645 * @return boolean
646 */
647 private static function extend_for_filter_groups_read( &$query ) {
648 $result = false;
649 if ( is_admin() ) {
650 // check if query is for a post type we handle
651 $post_types = $query->get( 'post_type' );
652 $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
653 if ( !is_array( $post_types ) ) {
654 $post_types = array( $post_types );
655 }
656 foreach( $post_types as $post_type ) {
657 if (
658 !isset( $post_types_option[$post_type]['add_meta_box'] ) ||
659 $post_types_option[$post_type]['add_meta_box']
660 ) {
661 // only act on post etc. screens
662 $screen = get_current_screen();
663 if (
664 !empty( $screen ) &&
665 !empty( $screen->id ) &&
666 ( $screen->id == 'edit-' . $post_type )
667 ) {
668 if (
669 !empty( $_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ] ) &&
670 is_array( $_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ] )
671 ) {
672 $result = true;
673 break;
674 }
675 }
676 }
677 }
678 }
679 return $result;
680 }
681 }
682 Groups_Admin_Posts::init();
683