function flt_adjust_reqd_caps($reqd_caps, $orig_cap, $user_id, $args) { global $pagenow, $current_user; // Work around WP's occasional use of literal 'cap_name' instead of $post_type_object->cap->$cap_name // note: cap names for "post" type may be customized too if (in_array($pagenow, array('edit.php', 'post.php', 'post-new.php', 'press-this.php', 'admin-ajax.php', 'upload.php', 'media.php')) && in_array('edit_posts', $reqd_caps) && $user_id == $current_user->ID && !$this->doing_admin_menus()) { static $did_admin_init = false; if (!$did_admin_init) { $did_admin_init = did_action('admin_init'); } if ($did_admin_init) { if (!empty($args[0])) { $item_id = is_object($args[0]) ? $args[0]->ID : $args[0]; } else { $item_id = 0; } if ($type_obj = get_post_type_object(pp_find_post_type($item_id))) { $key = array_search('edit_posts', $reqd_caps); if (false !== $key) { $reqd_caps[$key] = $type_obj->cap->edit_posts; } } } } //=============================== return $reqd_caps; }
function add_meta_boxes() { // ========= register WP-rendered metaboxes ============ $post_type = pp_find_post_type(); if (!current_user_can('pp_assign_roles') || apply_filters('pp_disable_exception_ui', false, 'post', 0, $post_type)) { return; } $hidden_types = apply_filters('pp_hidden_post_types', array()); if (!empty($hidden_types[$post_type])) { return; } if (!in_array($post_type, pp_get_enabled_post_types())) { if (!in_array($post_type, array('revision')) && pp_get_option('display_hints')) { $type_obj = get_post_type_object($post_type); if ($type_obj->public) { if (!in_array($post_type, apply_filters('pp_unfiltered_post_types', array()))) { add_meta_box("pp_enable_type", __('Press Permit Settings', 'pp'), array(&$this, 'draw_settings_ui'), $post_type, 'advanced', 'default', array()); } } } return; } //if ( ! $this->_roles_editable( $src_name, $object_type ) ) // return; $ops = _pp_can_set_exceptions('read', $post_type, array('via_item_source' => 'post', 'for_item_source' => 'post')) ? array('read' => true) : array(); $operations = apply_filters('pp_item_edit_exception_ops', $ops, 'post', $post_type); foreach (array_keys($operations) as $op) { if ($op_obj = pp_get_op_object($op, $post_type)) { // $screen = null, $context = 'advanced', $priority = 'default', $callback_args = null add_meta_box("pp_{$op}_{$post_type}_exceptions", sprintf(__('%s Exceptions', 'pp'), $op_obj->noun_label), array(&$this, 'draw_exceptions_ui'), $post_type, 'advanced', 'default', array('op' => $op)); } } }
function pp_item_edit_js($object_type = '') { if (!$object_type) { $object_type = pp_find_post_type(); } if (in_array($object_type, array('revision'))) { return; } $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '.dev' : ''; wp_enqueue_script('pp-item-edit', PP_URLPATH . "/admin/js/pp-item-edit{$suffix}.js", array(), PPC_VERSION); if (taxonomy_exists($object_type)) { $type_obj = get_taxonomy($object_type); } else { $type_obj = get_post_type_object($object_type); } if ($type_obj) { //$arr = array( 'hierarchical' => $type_obj->hierarchical ); //wp_localize_script( 'pp_attributes', 'ppItem', $arr ); ?> <script type="text/javascript"> /* <![CDATA[ */ var pp_hier_type='<?php echo $type_obj->hierarchical; ?> '; /* ]]> */ </script> <?php } }
public function flt_adjacent_post_where($where) { global $wpdb, $query_interceptor, $current_user; $post_type = pp_find_post_type(); $limit_statuses = array_merge(pp_get_post_stati(array('public' => true, 'post_type' => $post_type)), pp_get_post_stati(array('private' => true, 'post_type' => $post_type))); if (!empty($current_user->ID)) { $where = str_replace(" AND p.post_status = 'publish'", " AND p.post_status IN ('" . implode("','", $limit_statuses) . "')", $where); } // get_adjacent_post() function includes 'WHERE ' at beginning of $where $where = str_replace('WHERE ', 'AND ', $where); if ($limit_statuses) { $limit_statuses = array_fill_keys($limit_statuses, true); } $args = array('post_types' => $post_type, 'source_alias' => 'p', 'skip_teaser' => true, 'limit_statuses' => $limit_statuses); $where = 'WHERE 1=1 ' . $query_interceptor->flt_posts_where($where, $args); return $where; }
function flt_posts_listing($results) { $default_type = pp_find_post_type(); // buffer all IDs in the results set foreach ($results as $row) { $post_type = 'revision' == $row->post_type ? $default_type : $row->post_type; if (!isset($this->listed_ids[$post_type])) { $this->listed_ids[$post_type] = array(); } $this->listed_ids[$post_type][$row->ID] = true; } return $results; }
function _flt_user_has_post_cap($wp_sitecaps, $orig_reqd_caps, $args, $pp_args) { // ================= EARLY EXIT CHECKS (if the provided reqd_caps do not need filtering or need special case filtering ================== global $pp_current_user, $pagenow; if (isset($args[1]) && $args[1] != $pp_current_user->ID) { return $wp_sitecaps; } // =================================================== (end early exit checks) ====================================================== // ========================================== ARGUMENT TRANSLATION AND STATUS DETECTION ============================================= $post_id = isset($args[2]) ? $args[2] : pp_get_post_id(); $post_type = pp_find_post_type($post_id); // will be pulled from object $pp_reqd_caps = (array) $args[0]; // already cast to array //=== Allow PP extensions or other plugins to modify some variables // if ($_vars = apply_filters_ref_array('pp_has_post_cap_vars', array(null, $wp_sitecaps, $pp_reqd_caps, array('post_type' => $post_type, 'post_id' => $post_id, 'user_id' => $args[1], 'required_operation' => $pp_args['required_operation']), &$this))) { extract(array_intersect_key($_vars, array_fill_keys(array('post_type', 'post_id', 'pp_reqd_caps', 'return_caps', 'required_operation'), 'true'))); } if (!empty($return_caps)) { return array_merge($wp_sitecaps, $return_caps); } if (!$post_id || !in_array($post_type, pp_get_enabled_post_types())) { return $wp_sitecaps; } extract($pp_args, EXTR_SKIP); // Note: At this point, we have a nonzero post_id... do_action_ref_array('pp_has_post_cap_pre', array($pp_reqd_caps, 'post', $post_type, $post_id, &$this)); // cache clearing / refresh forcing can be applied here $memcache_disabled = $this->flags['memcache_disabled']; // skip the memcache under certain circumstances if (!$memcache_disabled) { if (!empty($_POST) && 'post.php' == $pagenow && pp_get_type_cap($post_type, 'edit_post') == reset($pp_reqd_caps) || !empty($_GET['doaction']) && in_array(reset($pp_reqd_caps), array('delete_post', pp_get_type_cap($post_type, 'delete_post')))) { $this->memcache = array(); $memcache_disabled = true; } } // ============ QUERY for required caps on object id (if other listed ids are known, query for them also). Cache results to static var. =============== $query_args = array('required_operation' => $required_operation, 'post_types' => $post_type, 'skip_teaser' => true); // generate a string key for this set of required caps, for use below in checking, caching the filtered results $cap_arg = 'edit_page' == $args[0] ? 'edit_post' : $args[0]; // minor perf boost on uploads.php, TODO: move to PPCE $capreqs_key = $memcache_disabled ? false : $cap_arg . $this->flags['cache_key_suffix'] . md5(serialize($query_args)); // Check whether this object id was already tested for the same reqd_caps in a previous execution of this function within the same http request if (!isset($this->memcache['tested_ids'][$post_type][$capreqs_key][$post_id]) || !empty($this->flags['force_memcache_refresh'])) { global $pp, $wpdb, $query_interceptor; // If this cap inquiry is for a single item but multiple items are being listed, we will query for the original metacap on all items (mapping it for each applicable status) and buffer the results // // (Perf enhancement when listing display will check caps for each item to determine whether to display an action link) // note: don't use wp_object_cache because it includes posts not present in currently displayed resultset listing page if (isset($pp->listed_ids[$post_type]) && (!is_admin() || 'index.php' != $pagenow)) { // there's too much happening on the dashboard to buffer listed IDs reliably. $listed_ids = array_keys($pp->listed_ids[$post_type]); } else { $listed_ids = array(); } // make sure our current post_id is in the query list $listed_ids[] = (int) $post_id; $listed_ids = array_unique($listed_ids); //if ( ! isset( $this->memcache['request'][$capreqs_key] ) || $this->flags['force_memcache_refresh'] ) { //$query_args['listed_ids'] = $listed_ids; if (count($listed_ids) == 1) { $query_args['limit_statuses'] = array(get_post_field('post_status', $post_id) => true); } $query_args['limit_ids'] = $listed_ids; $query_args['has_cap_check'] = $args[0]; $request = $query_interceptor->construct_posts_request(array('fields' => "{$wpdb->posts}.ID"), $query_args); // update static variable //if ( ! $memcache_disabled ) // $this->memcache['request'][$capreqs_key] = $request; //} else { // $request = $this->memcache['request'][$capreqs_key]; //} // run the query $request .= " AND {$wpdb->posts}.ID IN ('" . implode("', '", $listed_ids) . "')"; $qkey = md5($request); // a different has_cap inquiry may have generated the same query, so check cache before executing the query if (isset($this->memcache['okay_ids'][$qkey]) && !$memcache_disabled) { $okay_ids = $this->memcache['okay_ids'][$qkey]; } else { $okay_ids = $wpdb->get_col($request); if (!$memcache_disabled) { $this->memcache['okay_ids'][$qkey] = $okay_ids; } } // update tested_ids cache to log filtered results for this post id, and possibly also for other listed IDs if (!$memcache_disabled) { foreach ($listed_ids as $_id) { $this->memcache['tested_ids'][$post_type][$capreqs_key][$_id] = in_array($_id, $okay_ids); } } $this_id_okay = in_array($post_id, $okay_ids); } else { // results of this has_cap inquiry are already stored (from another call within current http request) $this_id_okay = $this->memcache['tested_ids'][$post_type][$capreqs_key][$post_id]; } do_action_ref_array('pp_has_post_cap_done', array($this_id_okay, $pp_reqd_caps, 'post', $post_type, $post_id, &$this)); // followup to cache processing can be applied here if ($this_id_okay) { //d_echo( "PASSED for {$orig_reqd_caps[0]}<br />" ); return array_merge($wp_sitecaps, array_fill_keys($orig_reqd_caps, true)); } else { // ================= TEMPORARY DEBUG CODE =================== //dump($args); //dump($orig_reqd_caps); //dump($pp_reqd_caps); //d_echo( "user_has_cap FAILED ($post_id) !!!!!!!" ); //d_echo( '<br />' ); // ============== (end temporary debug code ================== return array_diff_key($wp_sitecaps, array_fill_keys($orig_reqd_caps, true)); // return user's sitewide caps, minus the caps we were checking for } }