PluginProbe
Groups – Memberships and Access Control / trunk
Groups – Memberships and Access Control vtrunk
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 / admin / class-groups-admin-posts.php

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

684 lines 24.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-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 = groups_sanitize_get( 'post_type' ) ?? 'post';
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 = groups_sanitize_get( 'post_type' ) ?? 'post';
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;
136
137 if ( is_admin() ) {
138
139 if ( $pagenow == 'edit.php' ) { // check that we're on the right screen
140
141 $post_type = groups_sanitize_get( 'post_type' ) ?? 'post';
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 $read = groups_sanitize_get( Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ );
158 if ( !is_array( $read ) ) {
159 $read = array();
160 }
161 $output .= sprintf(
162 '<option value="%s" %s >%s</option>', self::NOT_RESTRICTED,
163 esc_attr( in_array( self::NOT_RESTRICTED, $read ) ? ' selected="selected" ' : '' ),
164 esc_attr__( '(none)', 'groups' )
165 );
166 $output .= sprintf(
167 '<option value="%s" %s >%s</option>', self::RESTRICTED,
168 esc_attr( in_array( self::RESTRICTED, $read ) ? ' selected="selected" ' : '' ),
169 esc_attr__( '(any)', 'groups' )
170 );
171
172 $groups = apply_filters(
173 'groups_admin_posts_restrict_manage_posts_get_groups',
174 Groups_Group::get_groups(
175 apply_filters(
176 'groups_admin_posts_restrict_manage_posts_get_groups_options',
177 array( 'order_by' => 'name', 'order' => 'ASC' )
178 )
179 )
180 );
181 foreach ( $groups as $group ) {
182 $selected = in_array( $group->group_id, $read ) ? ' selected="selected" ' : '';
183 $output .= sprintf(
184 '<option value="%s" %s >%s</option>',
185 esc_attr( $group->group_id ),
186 esc_attr( $selected ),
187 $group->name ? stripslashes( wp_filter_nohtml_kses( $group->name ) ) : ''
188 );
189 }
190 $output .= '</select>';
191 $output .= '</div>';
192 $output .= Groups_UIE::render_select( '.select.group' );
193
194 if (
195 function_exists( 'get_term_meta' ) && // >= WordPress 4.4.0 as we query the termmeta table
196 class_exists( 'Groups_Restrict_Categories' ) &&
197 method_exists( 'Groups_Restrict_Categories', 'get_controlled_taxonomies' ) &&
198 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
199 ) {
200 $output .= sprintf( '<label class="groups-read-terms" title="%s">', esc_attr__( 'Also look for groups related to terms', 'groups' ) );
201 $output .= sprintf( '<input type="checkbox" name="groups-read-terms" value="1" %s />', empty( groups_sanitize_get( 'groups-read-terms' ) ) ? '' : ' checked="checked" ' );
202 $output .= esc_html__( 'Terms', 'groups' );
203 $output .= '</label>';
204 }
205 echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
206 }
207
208 }
209 }
210
211 }
212
213 /**
214 * Bulk-edit access restriction groups.
215 *
216 * @param string $column_name
217 * @param string $post_type
218 */
219 public static function bulk_edit_custom_box( $column_name, $post_type ) {
220
221 global $pagenow;
222
223 if ( $column_name == self::GROUPS_READ ) {
224 if ( $pagenow == 'edit.php' ) { // check that we're on the right screen
225
226 $post_type = groups_sanitize_get( 'post_type' ) ?? 'post';
227 $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
228
229 if ( !isset( $post_types_option[$post_type]['add_meta_box'] ) || $post_types_option[$post_type]['add_meta_box'] ) {
230
231 $output = '<fieldset class="inline-edit-col-right">';
232 $output .= '<div class="bulk-edit-groups" style="padding:0 0.5em;">';
233
234 // capability/access restriction bulk actions added through extra_tablenav()
235 $output .= '<div id="group-bulk-actions" class="groups-bulk-container" style="display:inline">';
236
237 $output .= '<label style="display:inline;">';
238 $output .= '<span class="title">';
239 $output .= _x( 'Groups', 'Bulk edit field label', 'groups' );
240 $output .= '</span>';
241 $output .= '<select class="groups-action" name="groups-action">';
242 $output .= '<option selected="selected" value="-1">' . esc_html__( '&mdash; No Change &mdash;', 'groups' ) . '</option>';
243 $output .= '<option value="add-group">' . esc_html__( 'Add restriction', 'groups' ) . '</option>';
244 $output .= '<option value="remove-group">' . esc_html__( 'Remove restriction', 'groups' ) . '</option>';
245 $output .= '</select>';
246 $output .= '</label>';
247
248 $include = Groups_Access_Meta_Boxes::get_user_can_restrict_group_ids( get_current_user_id() );
249 $groups = Groups_Group::get_groups( array( 'order_by' => 'name', 'order' => 'ASC', 'include' => $include ) );
250
251 $output .= '<div class="groups-groups-container">';
252 $output .= sprintf(
253 '<select class="select bulk-group" name="%s[]" multiple="multiple" placeholder="%s" data-placeholder="%s">',
254 esc_attr( Groups_Post_Access::POSTMETA_PREFIX . 'bulk-' . Groups_Post_Access::READ ),
255 esc_attr__( 'Choose access restriction groups &hellip;', 'groups' ),
256 esc_attr__( 'Choose access restriction groups &hellip;', 'groups' )
257 );
258
259 foreach ( $groups as $group ) {
260 $output .= sprintf(
261 '<option value="%s" >%s</option>',
262 esc_attr( $group->group_id ),
263 $group->name ? stripslashes( wp_filter_nohtml_kses( $group->name ) ) : ''
264 );
265 }
266 $output .= '</select>';
267 $output .= '</div>'; // .groups-groups-container
268 $output .= Groups_UIE::render_select( '.select.bulk-group' );
269
270 $output .= '</div>'; // .groups-bulk-container
271
272 $output .= '</div>'; // .bulk-edit-groups
273 $output .= '</fieldset>'; // .inline-edit-col-right
274
275 $output .= wp_nonce_field( 'post-group', 'bulk-post-group-nonce', true, false );
276
277 echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
278 }
279 }
280 }
281 }
282
283 /**
284 * Handles access restriction group modifications from bulk-editing.
285 * This is called once for each post that is included in bulk-editing.
286 * The fields that are handled here are rendered through the
287 * bulk_edit_custom_box() method in this class.
288 *
289 * @param int $post_id
290 */
291 public static function save_post( $post_id ) {
292 if ( isset( $_REQUEST['groups-action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
293 if ( groups_verify_request_nonce( 'bulk-post-group-nonce', 'post-group' ) ) {
294 $read = groups_sanitize_request( Groups_Post_Access::POSTMETA_PREFIX . 'bulk-' . Groups_Post_Access::READ );
295 if ( !empty( $read ) && is_array( $read ) ) {
296 if ( Groups_Access_Meta_Boxes::user_can_restrict() ) {
297 $include = Groups_Access_Meta_Boxes::get_user_can_restrict_group_ids();
298 $groups = Groups_Group::get_groups( array( 'order_by' => 'name', 'order' => 'ASC', 'include' => $include ) );
299 $group_ids = array();
300 foreach ( $groups as $group ) {
301 $group_ids[] = $group->group_id;
302 }
303 foreach ( $read as $group_id ) {
304 if ( $group = Groups_Group::read( $group_id ) ) {
305 if ( in_array( $group->group_id, $group_ids ) ) {
306 switch ( groups_sanitize_request( 'groups-action' ) ) {
307 case 'add-group' :
308 Groups_Post_Access::create( array(
309 'post_id' => $post_id,
310 'group_id' => $group->group_id
311 ) );
312 break;
313 case 'remove-group' :
314 Groups_Post_Access::delete( $post_id, array( 'groups_read' => $group->group_id ) );
315 break;
316 }
317 }
318 }
319 }
320 }
321 }
322 }
323 }
324 }
325
326 /**
327 * Query modifier to take the selected access restriction groups into account.
328 *
329 * @deprecated not used
330 *
331 * @param WP_Query $query query object passed by reference
332 */
333 public static function parse_query( &$query ) {
334
335 global $pagenow;
336
337 if ( is_admin() ) {
338
339 if ( $pagenow == 'edit.php' ) { // check that we're on the right screen
340
341 $post_type = groups_sanitize_get( 'post_type' ) ?? 'post';
342 $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
343
344 if ( !isset( $post_types_option[$post_type]['add_meta_box'] ) || $post_types_option[$post_type]['add_meta_box'] ) {
345
346 $read = groups_sanitize_get( Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ );
347 if ( !is_array( $read ) ) {
348 $read = array();
349 }
350
351 if ( count( $read ) > 0 ) {
352
353 $include_unrestricted = false;
354 if ( in_array( self::NOT_RESTRICTED, $read ) ) {
355 $include_unrestricted = true;
356 }
357
358 $group_ids = array();
359 foreach ( $read as $group_id ) {
360 if ( Groups_Group::read( $group_id ) ) {
361 $group_ids[] = $group_id;
362 }
363 }
364
365 if ( !empty( $group_ids ) ) { // @phpstan-ignore empty.variable
366 if ( $include_unrestricted ) {
367 // meta_query does not handle a conjunction
368 // on the same meta field correctly
369 // (at least not up to WordPress 3.7.1)
370 // $query->query_vars['meta_query'] = array (
371 // 'relation' => 'OR',
372 // array (
373 // 'key' => Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ,
374 // 'value' => $group_ids,
375 // 'compare' => 'IN'
376 // ),
377 // array (
378 // 'key' => Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ,
379 // 'compare' => 'NOT EXISTS'
380 // )
381 // );
382 // we'll limit it to show just unrestricted entries
383 // until the above is solved
384 $query->query_vars['meta_query'] = array ( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
385 array (
386 'key' => Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ,
387 'compare' => 'NOT EXISTS'
388 )
389 );
390 } else {
391 $query->query_vars['meta_query'] = array ( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
392 array (
393 'key' => Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ,
394 'value' => $group_ids,
395 'compare' => 'IN'
396 )
397 );
398 }
399 } else if ( $include_unrestricted ) {
400 $query->query_vars['meta_query'] = array ( //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
401 array (
402 'key' => Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ,
403 'compare' => 'NOT EXISTS'
404 )
405 );
406 }
407 }
408 }
409 }
410
411 }
412
413 }
414
415 /**
416 * Filters out posts by group. This is used when you choose groups on the post admin screen so that
417 * only those posts who are restricted by groups are shown.
418 *
419 * @param string $where
420 * @param WP_Query $query
421 *
422 * @return string
423 */
424 public static function posts_where( $where, $query ) {
425
426 global $wpdb;
427
428 if ( self::extend_for_filter_groups_read( $query ) ) { // also checks that $_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ] is an array
429
430 $post_in = array();
431 $term_in = array();
432
433 $filter_terms = false;
434 if (
435 !empty( $_GET['groups-read-terms'] ) && // phpcs:ignore WordPress.Security.NonceVerification.Recommended
436 function_exists( 'get_term_meta' ) && // >= WordPress 4.4.0 as we query the termmeta table
437 class_exists( 'Groups_Restrict_Categories' ) &&
438 method_exists( 'Groups_Restrict_Categories', 'get_controlled_taxonomies' ) &&
439 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
440 ) {
441 $filter_terms = true;
442 }
443
444 $read = groups_sanitize_get( Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ );
445 if ( !is_array( $read ) ) {
446 $read = array();
447 }
448
449 if ( in_array( self::NOT_RESTRICTED, $read ) ) {
450 $condition =
451 "SELECT ID post_id FROM $wpdb->posts " .
452 "WHERE ID NOT IN (" .
453 "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'groups-read'";
454 if ( $filter_terms ) {
455 $condition .=
456 " UNION ALL " .
457 "SELECT p.ID post_id FROM $wpdb->posts p " .
458 "LEFT JOIN $wpdb->term_relationships tr ON p.ID = tr.object_id " .
459 "LEFT JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id " .
460 "LEFT JOIN $wpdb->termmeta tm ON tt.term_id = tm.term_id " .
461 "WHERE tm.meta_key = 'groups-read'";
462 }
463 $condition .= ")";
464 $post_in[] = $condition;
465 }
466
467 if ( in_array( self::RESTRICTED, $read ) ) {
468 $condition = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'groups-read'";
469 if ( $filter_terms ) {
470 $condition .=
471 " UNION ALL " .
472 "SELECT p.ID post_id FROM $wpdb->posts p " .
473 "LEFT JOIN $wpdb->term_relationships tr ON p.ID = tr.object_id " .
474 "LEFT JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id " .
475 "LEFT JOIN $wpdb->termmeta tm ON tt.term_id = tm.term_id " .
476 "WHERE tm.meta_key = 'groups-read'";
477 }
478 $post_in[] = $condition;
479 }
480
481 $group_ids = array();
482 foreach ( $read as $group_id ) {
483 if ( $group_id = Groups_Utility::id( $group_id ) ) {
484 if ( Groups_Group::read( $group_id ) ) {
485 $group_ids[] = $group_id;
486 }
487 }
488 }
489
490 if ( !empty( $group_ids ) ) { // @phpstan-ignore empty.variable
491 $groups = ' ( ' . implode( ',', esc_sql( $group_ids ) ) . ' ) ';
492 $condition =
493 "SELECT post_id FROM $wpdb->postmeta " .
494 "WHERE meta_key = 'groups-read' AND meta_value IN $groups";
495 if ( $filter_terms ) {
496 $condition .=
497 " UNION ALL " .
498 "SELECT p.ID post_id FROM $wpdb->posts p " .
499 "LEFT JOIN $wpdb->term_relationships tr ON p.ID = tr.object_id " .
500 "LEFT JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id " .
501 "LEFT JOIN $wpdb->termmeta tm ON tt.term_id = tm.term_id " .
502 "WHERE tm.meta_key = 'groups-read' AND tm.meta_value IN $groups";
503 }
504 $post_in[] = $condition;
505 }
506
507 if ( count( $post_in ) > 0 ) {
508 if (
509 !empty( $_GET['groups-read-terms'] ) && // phpcs:ignore WordPress.Security.NonceVerification.Recommended
510 function_exists( 'get_term_meta' ) && // >= WordPress 4.4.0 as we query the termmeta table
511 class_exists( 'Groups_Restrict_Categories' ) &&
512 method_exists( 'Groups_Restrict_Categories', 'get_controlled_taxonomies' ) &&
513 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
514 ) {
515 $post_in = array_merge( $post_in, $term_in );
516 }
517 $id_in = implode( ' UNION ALL ', $post_in );
518 $where .= " AND $wpdb->posts.ID IN ( $id_in ) ";
519 }
520
521 }
522
523 return $where;
524 }
525
526 /**
527 * Adds to the join to allow advanced sorting by group on the admin back end for post tables.
528 *
529 * @param string $join
530 * @param WP_Query $query
531 */
532 public static function posts_join( $join, $query ) {
533 global $wpdb;
534 if ( self::extend_for_orderby_groups_read( $query ) ) {
535 $group_table = _groups_get_tablename( 'group' );
536 if ( function_exists( 'get_term_meta' ) ) { // >= WordPress 4.4.0 as we query the termmeta table
537 $join .= "
538 LEFT JOIN (
539 SELECT p.ID post_id, GROUP_CONCAT(DISTINCT groups_read.group_name ORDER BY groups_read.group_name) groups
540 FROM $wpdb->posts p
541 LEFT JOIN (
542 SELECT post_id, g.name group_name
543 FROM $wpdb->postmeta pm
544 LEFT JOIN $group_table g ON pm.meta_value = g.group_id
545 WHERE pm.meta_key = 'groups-read'
546 UNION ALL
547 SELECT p.ID post_id, g.name group_name
548 FROM $wpdb->posts p
549 LEFT JOIN $wpdb->term_relationships tr ON p.ID = tr.object_id
550 LEFT JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
551 LEFT JOIN $wpdb->termmeta tm ON tt.term_id = tm.term_id
552 LEFT JOIN $group_table g ON tm.meta_value = g.group_id
553 WHERE tm.meta_key = 'groups-read'
554 ) as groups_read ON p.ID = groups_read.post_id
555 GROUP BY p.ID
556 ) groups_tmp ON $wpdb->posts.ID = groups_tmp.post_id
557 ";
558 } else {
559 $join .= "
560 LEFT JOIN (
561 SELECT p.ID post_id, GROUP_CONCAT(DISTINCT groups_read.group_name ORDER BY groups_read.group_name) groups
562 FROM $wpdb->posts p
563 LEFT JOIN (
564 SELECT post_id, g.name group_name
565 FROM $wpdb->postmeta pm
566 LEFT JOIN $group_table g ON pm.meta_value = g.group_id
567 WHERE pm.meta_key = 'groups-read'
568 ) as groups_read ON p.ID = groups_read.post_id
569 GROUP BY p.ID
570 ) groups_tmp ON $wpdb->posts.ID = groups_tmp.post_id
571 ";
572 }
573 }
574 return $join;
575 }
576
577 /**
578 * Extend the orderby clause to sort by groups related to the post and its terms.
579 *
580 * @param $string $orderby
581 * @param WP_Query $query
582 *
583 * @return string
584 */
585 public static function posts_orderby( $orderby, $query ) {
586 if ( self::extend_for_orderby_groups_read( $query ) ) {
587 switch ( $query->get( 'order' ) ) {
588 case 'desc' :
589 case 'DESC' :
590 $order = 'DESC';
591 break;
592 default :
593 $order = 'ASC';
594 }
595 $prefix = ' groups_tmp.groups ' . $order;
596 if ( !empty( $orderby ) ) {
597 $prefix .= ' , ';
598 }
599 $orderby = $prefix . $orderby;
600 }
601 return $orderby;
602 }
603
604 /**
605 * Check if we should apply our posts_join and posts_orderby filters. Used in those.
606 *
607 * @param WP_Query $query
608 *
609 * @return boolean
610 */
611 private static function extend_for_orderby_groups_read( &$query ) {
612 $result = false;
613 if ( is_admin() ) {
614 // check if query is for a post type we handle
615 $post_types = $query->get( 'post_type' );
616 if ( !is_array( $post_types ) ) {
617 $post_types = array( $post_types );
618 }
619 foreach ( $post_types as $post_type ) {
620 $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
621 if (
622 !isset( $post_types_option[$post_type]['add_meta_box'] ) ||
623 $post_types_option[$post_type]['add_meta_box']
624 ) {
625 // only act on post etc. screens
626 $screen = get_current_screen();
627 if (
628 !empty( $screen ) &&
629 !empty( $screen->id ) &&
630 ( $screen->id == 'edit-' . $post_type )
631 ) {
632 if ( $query->get( 'orderby' ) == self::GROUPS_READ ) {
633 $result = true;
634 break;
635 }
636 }
637 }
638 }
639 }
640 return $result;
641 }
642
643 /**
644 * Check if we should apply our posts_where filter. Used in it.
645 *
646 * @param WP_Query $query
647 *
648 * @return boolean
649 */
650 private static function extend_for_filter_groups_read( &$query ) {
651 $result = false;
652 if ( is_admin() ) {
653 // check if query is for a post type we handle
654 $post_types = $query->get( 'post_type' );
655 $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
656 if ( !is_array( $post_types ) ) {
657 $post_types = array( $post_types );
658 }
659 foreach ( $post_types as $post_type ) {
660 if (
661 !isset( $post_types_option[$post_type]['add_meta_box'] ) ||
662 $post_types_option[$post_type]['add_meta_box']
663 ) {
664 // only act on post etc. screens
665 $screen = get_current_screen();
666 if (
667 !empty( $screen ) &&
668 !empty( $screen->id ) &&
669 ( $screen->id == 'edit-' . $post_type )
670 ) {
671 $read = groups_sanitize_get( Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ );
672 if ( !empty( $read ) && is_array( $read ) ) {
673 $result = true;
674 break;
675 }
676 }
677 }
678 }
679 }
680 return $result;
681 }
682 }
683 Groups_Admin_Posts::init();
684