} $checked = ' checked="checked"'; $html = '<p class="pp-checkbox">' . '<input type="checkbox" id="pp_select_x_cond_post_status_" name="pp_select_x_cond[]" value=""' . $checked . ' /> ' . '<label for="pp_select_x_cond_post_status_">' . __('(all)', 'pp') . '</label>' . '</p>'; if ('post' != $for_src_name || $mod_type != 'additional') { break; } if ('term' == $via_src_name) { if ('forum' != $for_type) { $pvt_obj = get_post_status_object('private'); $html .= '<p class="pp-checkbox pp_select_private_status">' . '<input type="checkbox" id="pp_select_x_cond_post_status_private" name="pp_select_x_cond[]" value="post_status:private" /><label for="pp_select_x_cond_post_status_private"> ' . sprintf(__('%s Visibility', 'pp'), $pvt_obj->label) . '</label>' . '</p>'; } } $type_obj = get_post_type_object($for_type); $var = "{$operation}_{$for_type}"; $type_caps = isset($type_obj->cap->{$var}) ? (array) $type_obj->cap->{$var} : array(); $html = apply_filters('pp_permission_status_ui', $html, $for_type, $type_caps); $html = apply_filters('pp_exceptions_status_ui', $html, $for_type, compact('via_src_name', 'operation', 'type_caps')); break; case 'get_item_path': require_once PPC_ABSPATH . '/lib/ancestry_lib_pp.php'; if ('term' == $via_src_name) { $html = $item_id . chr(13) . PP_Ancestry::get_term_path($item_id, $via_type); } else { $html = $item_id . chr(13) . PP_Ancestry::get_post_path($item_id); } break; } // end switch if ($html) { echo $html; }
public static function flt_get_pages($results, $args = array()) { $results = (array) $results; global $wpdb; // === BEGIN PP ADDITION: global var; various special case exemption checks === // global $pp, $current_user; // buffer titles in case they were filtered previously $titles = pp_get_property_array($results, 'ID', 'post_title'); // depth is not really a get_pages arg, but remap exclude arg to exclude_tree if wp_list_terms called with depth=1 if (!empty($args['exclude']) && empty($args['exclude_tree']) && !empty($args['depth']) && 1 == $args['depth']) { if (0 !== strpos($args['exclude'], ',')) { // work around wp_list_pages() bug of attaching leading comma if a plugin uses wp_list_pages_excludes filter $args['exclude_tree'] = $args['exclude']; } } // // === END PP ADDITION === // ================================= $defaults = array('child_of' => 0, 'sort_order' => 'ASC', 'sort_column' => 'post_title', 'hierarchical' => 1, 'exclude' => array(), 'include' => array(), 'meta_key' => '', 'meta_value' => '', 'authors' => '', 'parent' => -1, 'exclude_tree' => '', 'number' => '', 'offset' => 0, 'post_type' => 'page', 'post_status' => 'publish', 'depth' => 0, 'suppress_filters' => 0, 'required_operation' => '', 'alternate_operation' => ''); // PP arguments added above // === BEGIN PP ADDITION: support front-end optimization $post_type = isset($args['post_type']) ? $args['post_type'] : $defaults['post_type']; $enabled_post_types = pp_get_enabled_post_types(); if (defined('PP_UNFILTERED_FRONT')) { if (defined('PP_UNFILTERED_FRONT_TYPES')) { $unfiltered_types = str_replace(' ', '', PP_UNFILTERED_FRONT_TYPES); $unfiltered_types = explode(',', constant($unfiltered_types)); $enabled_post_types = array_diff($enabled_post_types, $unfiltered_types); } else { return $results; } } if (!in_array($post_type, $enabled_post_types)) { return $results; } if (pp_is_front()) { if ('page' == $post_type && defined('PP_GET_PAGES_LEAN')) { // custom types are likely to have custom fields $defaults['fields'] = "{$wpdb->posts}.ID, {$wpdb->posts}.post_title, {$wpdb->posts}.post_parent, {$wpdb->posts}.post_date, {$wpdb->posts}.post_date_gmt, {$wpdb->posts}.post_status, {$wpdb->posts}.post_name, {$wpdb->posts}.post_modified, {$wpdb->posts}.post_modified_gmt, {$wpdb->posts}.guid, {$wpdb->posts}.menu_order, {$wpdb->posts}.comment_count"; } else { $defaults['fields'] = "{$wpdb->posts}.*"; } } else { // required for xmlrpc getpagelist method $defaults['fields'] = "{$wpdb->posts}.*"; } // === END PP MODIFICATION === $r = wp_parse_args($args, $defaults); $args['number'] = (int) $r['number']; $args['offset'] = absint($r['offset']); $args['child_of'] = (int) $r['child_of']; extract(apply_filters('pp_get_pages_args', $r), EXTR_SKIP); // PPE filter modifies append_page, exclude_tree // workaround for CMS Tree Page View (passes post_parent instead of parent) if (-1 == $parent && isset($args['post_parent'])) { $args['parent'] = $args['post_parent']; $parent = $args['post_parent']; } // Make sure the post type is hierarchical $hierarchical_post_types = get_post_types(array('public' => true, 'hierarchical' => true)); if (!in_array($post_type, $hierarchical_post_types)) { return $results; } // Make sure we have a valid post status if (is_admin() && 'any' === $post_status) { $post_status = ''; } if ($post_status) { if (!is_array($post_status) && strpos($post_status, ',')) { $post_status = explode(',', $post_status); } if (array_diff((array) $post_status, get_post_stati())) { return $results; } } $intercepted_pages = apply_filters('pp_get_pages_intercept', false, $results, $args); if (is_array($intercepted_pages)) { return $intercepted_pages; } //$pp->last_get_pages_args = $r; // don't copy entire args array unless it proves necessary $pp->last_get_pages_depth = $depth; $pp->last_get_pages_suppress_filters = $suppress_filters; if ($suppress_filters) { return $results; } $orderby_array = array(); $allowed_keys = array('author', 'post_author', 'date', 'post_date', 'title', 'post_title', 'name', 'post_name', 'modified', 'post_modified', 'modified_gmt', 'post_modified_gmt', 'menu_order', 'parent', 'post_parent', 'ID', 'rand', 'comment_count'); foreach (explode(',', $sort_column) as $orderby) { $orderby = trim($orderby); if (!in_array($orderby, $allowed_keys)) { continue; } switch ($orderby) { case 'menu_order': break; case 'ID': $orderby = "{$wpdb->posts}.ID"; break; case 'rand': $orderby = 'RAND()'; break; case 'comment_count': $orderby = "{$wpdb->posts}.comment_count"; break; default: if (0 === strpos($orderby, 'post_')) { $orderby = "{$wpdb->posts}." . $orderby; } else { $orderby = "{$wpdb->posts}.post_" . $orderby; } } $orderby_array[] = $orderby; } $sort_column = !empty($orderby_array) ? implode(',', $orderby_array) : "{$wpdb->posts}.post_title"; // $args can be whatever, only use the args defined in defaults to compute the key $key = md5(serialize(compact(array_keys($defaults)))); $last_changed = wp_cache_get('last_changed', 'posts'); if (!$last_changed) { $last_changed = microtime(); wp_cache_set('last_changed', $last_changed, 'posts'); } $cache_key = "pp_get_pages:{$key}:{$last_changed}"; if ($cache = wp_cache_get($cache_key, 'posts')) { // Convert to WP_Post instances $pages = array_map('get_post', $cache); $pages = apply_filters('pp_get_pages', $pages, $r); return $pages; } $inclusions = ''; if (!empty($include)) { $child_of = 0; //ignore child_of, parent, exclude, meta_key, and meta_value params if using include $parent = -1; $exclude = ''; $meta_key = ''; $meta_value = ''; $hierarchical = false; $incpages = wp_parse_id_list($include); if (!empty($incpages)) { foreach ($incpages as $incpage) { if (empty($inclusions)) { $inclusions = ' AND ( ID = ' . intval($incpage) . ' '; } else { $inclusions .= ' OR ID = ' . intval($incpage) . ' '; } } } } if (!empty($inclusions)) { $inclusions .= ')'; } $exclusions = ''; if (!empty($exclude)) { $expages = wp_parse_id_list($exclude); if (!empty($expages)) { foreach ($expages as $expage) { if (empty($exclusions)) { $exclusions = ' AND ( ID <> ' . intval($expage) . ' '; } else { $exclusions .= ' AND ID <> ' . intval($expage) . ' '; } } } } if (!empty($exclusions)) { $exclusions .= ')'; } $author_query = ''; if (!empty($authors)) { $post_authors = wp_parse_id_list($authors); if (!empty($post_authors)) { foreach ($post_authors as $post_author) { //Do we have an author id or an author login? if (0 == intval($post_author)) { $post_author = get_user_by('login', $post_author); if (empty($post_author)) { continue; } if (empty($post_author->ID)) { continue; } $post_author = $post_author->ID; } if ('' == $author_query) { $author_query = ' post_author = ' . intval($post_author) . ' '; } else { $author_query .= ' OR post_author = ' . intval($post_author) . ' '; } } if ('' != $author_query) { $author_query = " AND ({$author_query})"; } } } $join = ''; $where = "{$exclusions} {$inclusions} "; if (!empty($meta_key) || !empty($meta_value)) { $join = " INNER JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id"; // PP MODIFICATION: was LEFT JOIN in WP 3.0 core // meta_key and meta_value might be slashed $meta_key = stripslashes($meta_key); $meta_value = stripslashes($meta_value); if (!empty($meta_key)) { $where .= $wpdb->prepare(" AND {$wpdb->postmeta}.meta_key = %s", $meta_key); } if (!empty($meta_value)) { $where .= $wpdb->prepare(" AND {$wpdb->postmeta}.meta_value = %s", $meta_value); } } if ($parent >= 0) { $where .= $wpdb->prepare(' AND ' . apply_filters('pp_get_pages_parent', 'post_parent = %d ', $args), $parent); } // === BEGIN PP MODIFICATION: // allow pages of multiple statuses to be displayed (requires default status=publish to be ignored) // $where_post_type = $wpdb->prepare("post_type = %s", $post_type); $where_status = ''; global $current_user; $is_front = pp_is_front(); if ($is_front && !empty($current_user->ID)) { $frontend_list_private = !defined('PP_SUPPRESS_PRIVATE_PAGES'); } else { $frontend_list_private = false; } $force_publish_status = !$frontend_list_private && 'publish' == $post_status; if ($is_front) { // since we will be applying status clauses based on content-specific roles, only a sanity check safeguard is needed when post_status is unspecified or defaulted to "publish" $safeguard_statuses = array(); foreach (pp_get_post_stati(array('internal' => false, 'post_type' => $post_type), 'object') as $status_name => $status_obj) { if (!$is_front || $status_obj->private || $status_obj->public) { $safeguard_statuses[] = $status_name; } } } // WP core does not include private pages in query. Include private statuses in anticipation of user-specific filtering if (is_array($post_status)) { $where_status = "AND post_status IN ('" . implode("','", $post_status) . "')"; } elseif ($post_status && ('publish' != $post_status || $is_front && !$frontend_list_private)) { $where_status = $wpdb->prepare("AND post_status = %s", $post_status); } elseif ($is_front) { $where_status = "AND post_status IN ('" . implode("','", $safeguard_statuses) . "')"; } else { $where_status = "AND post_status NOT IN ('" . implode("','", get_post_stati(array('internal' => true))) . "')"; } $where_id = ''; global $pagenow; if (is_admin() && in_array($pagenow, array('post.php', 'post-new.php'))) { global $post; if ($post) { $where_id = "AND ID != {$post->ID}"; } } $where = "AND {$where_post_type} AND ( 1=1 {$where_status} {$where} {$author_query} {$where_id} )"; $orderby = "ORDER BY {$sort_column} {$sort_order}"; $limits = !empty($number) ? ' LIMIT ' . $offset . ',' . $number : ''; $query = "SELECT {$fields} FROM {$wpdb->posts} {$join} WHERE 1=1 {$where} {$orderby} {$limits}"; if (pp_is_front() && apply_filters('pp_teaser_enabled', false, 'post', $post_type) && !defined('PP_TEASER_HIDE_PAGE_LISTING')) { // We are in the front end and the teaser is enabled for pages // TODO: move to PPTX $query = str_replace("post_status = 'publish'", " post_status IN ('" . implode("','", $safeguard_statuses) . "')", $query); $pages = $wpdb->get_results($query); // execute unfiltered query // Pass results of unfiltered query through the teaser filter. // If listing private pages is disabled, they will be omitted completely, but restricted published pages // will still be teased. This is a slight design compromise to satisfy potentially conflicting user goals without yet another option $pages = apply_filters('pp_posts_teaser', $pages, $post_type, array('request' => $query, 'force_teaser' => true)); $tease_all = true; } else { $_args = array('skip_teaser' => true, 'retain_status' => $force_publish_status); $groupby = $distinct = ''; global $pagenow; if (in_array($pagenow, array('post.php', 'post-new.php'))) { $clauses = apply_filters('pp_get_pages_clauses', compact('distinct', 'fields', 'join', 'where', 'groupby', 'orderby', 'limits'), $post_type, $args); } else { // Pass query through the request filter $_args['post_types'] = $post_type; if ($required_operation) { $_args['required_operation'] = $required_operation; } else { $_args['required_operation'] = pp_is_front() && !is_preview() ? 'read' : 'edit'; } if ('edit' == $_args['required_operation'] && isset($args['post_parent']) || 'associate' == $alternate_operation) { // workaround for CMS Page View $_args['alternate_required_ops'] = array('associate'); } $clauses = apply_filters('pp_posts_clauses', compact('distinct', 'fields', 'join', 'where', 'groupby', 'orderby', 'limits'), $_args); } // Execute the filtered query $pages = $wpdb->get_results("SELECT {$distinct} {$clauses['fields']} FROM {$wpdb->posts} {$clauses['join']} WHERE 1=1 {$clauses['where']} {$clauses['orderby']} {$clauses['limits']}"); } if (empty($pages)) { // alternate hook name (WP core already applied get_pages filter) return apply_filters('pp_get_pages', array(), $r); } if ($child_of) { $pages = get_page_children($child_of, $pages); } // restore buffered titles in case they were filtered previously pp_restore_property_array($pages, $titles, 'ID', 'post_title'); // // === END PP MODIFICATION === // ==================================== $num_pages = count($pages); for ($i = 0; $i < $num_pages; $i++) { $pages[$i] = sanitize_post($pages[$i], 'raw'); } // Press Permit note: WP core get_pages has already updated wp_cache and pagecache with unfiltered results. update_post_cache($pages); // === BEGIN PP MODIFICATION: Support a disjointed pages tree with some parents hidden ======== if ($child_of || empty($tease_all)) { // if we're including all pages with teaser, no need to continue thru tree remapping $ancestors = PP_Ancestry::get_page_ancestors(); // array of all ancestor IDs for keyed page_id, with direct parent first $orderby = $sort_column; $remap_args = compact('child_of', 'parent', 'exclude', 'depth', 'orderby'); // one or more of these args may have been modified after extraction PP_Ancestry::remap_tree($pages, $ancestors, $remap_args); } // === END PP MODIFICATION === // ==================================== if (!empty($exclude_tree)) { $exclude = array(); $exclude = (int) $exclude_tree; $children = get_page_children($exclude, $pages); // PP note: okay to use unfiltered WP function here since it's only used for excluding $excludes = array(); foreach ($children as $child) { $excludes[] = $child->ID; } $excludes[] = $exclude; $total = count($pages); for ($i = 0; $i < $total; $i++) { if (isset($pages[$i]) && in_array($pages[$i]->ID, $excludes)) { unset($pages[$i]); } } } if (!empty($append_page) && !empty($pages)) { $found = false; foreach (array_keys($pages) as $key) { if ($append_page->ID == $pages[$key]->ID) { $found = true; break; } } if (empty($found)) { $pages[] = $append_page; } } // re-index the array, just in case anyone cares $pages = array_values($pages); $page_structure = array(); foreach ($pages as $page) { $page_structure[] = $page->ID; } wp_cache_set($cache_key, $page_structure, 'posts'); // Convert to WP_Post instances $pages = array_map('get_post', $pages); // alternate hook name (WP core already applied get_pages filter) return apply_filters('pp_get_pages', $pages, $r); }
public static function flt_get_terms($terms, $taxonomies, $args) { if (!is_array($terms)) { return $terms; } if (empty($terms)) { return array(); } global $terms_interceptor; if ($terms_interceptor->skip_filtering($taxonomies, $args)) { return $terms; } extract($args, EXTR_SKIP); if ('ids' == $fields) { return $terms; } // if some args were forced to prevent core post-processing, restore actual values now if (!empty($args['actual_args'])) { extract($args['actual_args']); } if ('all' == $fields) { // buffer term names in case they were filtered previously $term_names = pp_get_property_array($terms, 'term_id', 'name'); } if (!empty($child_of)) { $children = _get_term_hierarchy(reset($taxonomies)); if (!empty($children)) { $terms = _get_term_children($child_of, $terms, reset($taxonomies)); } } // Replace DB-stored term counts with actual number of posts this user can read. // In addition, without the pp_tally_term_counts() call, WP will hide terms that have no public posts (even if this user can read some of the pvt posts). // Post counts will be incremented to include child terms only if $pad_counts is true if (!defined('XMLRPC_REQUEST') && 1 == count($taxonomies)) { global $pagenow; if (!is_admin() || !in_array($pagenow, array('post.php', 'post-new.php'))) { if ($hide_empty || !empty($args['actual_args']['hide_empty'])) { // need to tally for all terms in case some were hidden by core function due to lack of public posts $all_terms = get_terms(reset($taxonomies), array('fields' => 'all', 'pp_no_filter' => true, 'hide_empty' => false)); PP_TermsQueryLib::tally_term_counts($all_terms, reset($taxonomies), compact('pad_counts', 'skip_teaser', 'post_type')); foreach (array_keys($terms) as $k) { foreach (array_keys($all_terms) as $key) { if ($all_terms[$key]->term_taxonomy_id == $terms[$k]->term_taxonomy_id) { $terms[$k]->count = $all_terms[$key]->count; break; } } } } else { PP_TermsQueryLib::tally_term_counts($terms, reset($taxonomies), compact('pad_counts', 'skip_teaser', 'post_type')); } } } if ($hide_empty || !empty($args['actual_args']['hide_empty'])) { if ($hierarchical) { foreach ($taxonomies as $taxonomy) { if (empty($all_terms) || count($taxonomies) > 1) { $all_terms = get_terms($taxonomy, array('fields' => 'all', 'pp_no_filter' => true, 'hide_empty' => false)); } // Remove empty terms, but only if their descendants are all empty too. foreach ($terms as $k => $term) { if (!$term->count) { if ($descendants = _get_term_children($term->term_id, $all_terms, $taxonomy)) { foreach ($descendants as $child) { if ($child->count) { continue 2; } } } // It really is empty unset($terms[$k]); } } } } else { foreach ($terms as $key => $term) { if (!$term->count) { unset($terms[$key]); } } } } if ($hierarchical && !$parent && count($taxonomies) == 1) { require_once PPC_ABSPATH . '/lib/ancestry_lib_pp.php'; $ancestors = PP_Ancestry::get_term_ancestors(reset($taxonomies)); // array of all ancestor IDs for keyed term_id, with direct parent first $remap_args = array_merge(compact('child_of', 'parent', 'exclude'), array('orderby' => 'name', 'col_id' => 'term_id', 'col_parent' => 'parent')); PP_Ancestry::remap_tree($terms, $ancestors, $remap_args); } reset($terms); // === Standard WP post-processing for include, fields, number args === // $_terms = array(); if ('id=>parent' == $fields) { while ($term = array_shift($terms)) { $_terms[$term->term_id] = $term->parent; } $terms = $_terms; } elseif ('ids' == $fields) { while ($term = array_shift($terms)) { $_terms[] = $term->term_id; } $terms = $_terms; } elseif ('names' == $fields) { while ($term = array_shift($terms)) { $_terms[] = $term->name; } $terms = $_terms; } if (0 < $number && intval(@count($terms)) > $number) { $terms = array_slice($terms, $offset, $number); } // === end standard WP block === // restore buffered term names in case they were filtered previously if ('all' == $fields) { pp_restore_property_array($terms, $term_names, 'term_id', 'name'); } return $terms; }
public static function _current_exceptions_ui($exc_results, $args = array()) { global $pp_admin, $pp_role_defs, $pp_data_sources; $defaults = array('read_only' => false, 'class' => 'pp-group-roles', 'item_links' => false, 'caption' => '', 'link' => '', 'agent_type' => ''); $args = array_merge($defaults, $args); extract($args); if (!$exc_results) { return; } if (!$caption) { $caption = 'user' == $agent_type ? sprintf(__('Exceptions %1$s(for user)%2$s', 'pp'), '<small>', '</small>') : __('Exceptions', 'pp'); } require_once PPC_ABSPATH . '/lib/ancestry_lib_pp.php'; $can_assign = current_user_can('pp_assign_roles') && pp_bulk_roles_enabled(); $exceptions = array_fill_keys(array_merge(array('term', 'post'), pp_get_group_types()), array()); $item_paths = array_fill_keys(array_keys($exceptions), array(__('(none)', 'pp'))); // support imported include exception with no items included $post_types = pp_get_enabled_post_types(array(), 'names'); $taxonomies = pp_get_enabled_taxonomies(array('object_type' => false), 'names'); foreach ($exc_results as $row) { // object_type not strictly necessary here, included for consistency with term role array switch ($row->via_item_source) { case 'term': if ($row->item_id) { $taxonomy = ''; $term_id = (int) pp_ttid_to_termid($row->item_id, $taxonomy); if ($row->item_id) { $item_paths['term'][$row->item_id] = PP_Ancestry::get_term_path($term_id, $taxonomy); } $via_type = $taxonomy; } else { $via_type = $row->via_item_type; } break; case 'post': if ($row->item_id) { $item_paths['post'][$row->item_id] = PP_Ancestry::get_post_path($row->item_id); } // no break // no break default: if (pp_group_type_exists($row->via_item_source)) { static $groups_by_id; if (!isset($groups_by_id)) { $groups_by_id = array(); } if (!isset($groups_by_id[$row->via_item_source])) { $groups_by_id[$row->via_item_source] = array(); foreach (pp_get_groups($row->via_item_source, array('skip_meta_types' => 'wp_role')) as $group) { $groups_by_id[$row->via_item_source][$group->ID] = $group->name; } } if (isset($groups_by_id[$row->via_item_source][$row->item_id])) { $item_paths[$row->via_item_source][$row->item_id] = $groups_by_id[$row->via_item_source][$row->item_id]; } $via_type = $row->via_item_source; } else { $via_type = $row->via_item_type ? $row->via_item_type : $row->for_item_type; } } if (!isset($exceptions[$row->via_item_source][$via_type])) { $exceptions[$row->via_item_source][$via_type] = array(); } if (!isset($exceptions[$row->via_item_source][$via_type][$row->for_item_type])) { $exceptions[$row->via_item_source][$via_type][$row->for_item_type] = array(); } if (!isset($exceptions[$row->via_item_source][$via_type][$row->for_item_type][$row->operation])) { $exceptions[$row->via_item_source][$via_type][$row->for_item_type][$row->operation] = array(); } if (!isset($exceptions[$row->via_item_source][$via_type][$row->for_item_type][$row->operation][$row->mod_type])) { $exceptions[$row->via_item_source][$via_type][$row->for_item_type][$row->operation][$row->mod_type] = array(); } if (!isset($exceptions[$row->via_item_source][$via_type][$row->for_item_type][$row->operation][$row->mod_type][$row->for_item_status])) { $exceptions[$row->via_item_source][$via_type][$row->for_item_type][$row->operation][$row->mod_type][$row->for_item_status] = array(); } if (!isset($exceptions[$row->via_item_source][$via_type][$row->for_item_type][$row->operation][$row->mod_type][$row->for_item_status][$row->item_id])) { $exceptions[$row->via_item_source][$via_type][$row->for_item_type][$row->operation][$row->mod_type][$row->for_item_status][$row->item_id] = array(); } $exceptions[$row->via_item_source][$via_type][$row->for_item_type][$row->operation][$row->mod_type][$row->for_item_status][$row->item_id][$row->assign_for] = $row->eitem_id; if (!empty($row->inherited_from)) { $exceptions[$row->via_item_source][$via_type][$row->for_item_type][$row->operation][$row->mod_type][$row->for_item_status][$row->item_id]['inherited_from'] = $row->inherited_from; } } echo '<div style="clear:both;"></div>' . "<div id='pp_current_exceptions' class='pp-group-box {$class}'>" . '<h3>'; if ($link) { echo "<a href='{$link}'>{$caption}</a>"; } else { echo $caption; } echo '</h3>'; echo '<div>'; echo '<div id="pp_current_exceptions_inner">'; //ksort( $type_roles ); if (empty($_REQUEST['all_types']) && !empty($exceptions['post'])) { $all_types = array_fill_keys(array_merge($post_types, $taxonomies, array('')), true); $all_types = array_diff_key($all_types, array('topic' => true, 'reply' => true)); // hide topic, reply assignments even if they are somehow saved/imported without inherited_from value $exceptions['post'] = array_intersect_key($exceptions['post'], $all_types); foreach (array_keys($exceptions['post']) as $key) { $exceptions['post'][$key] = array_intersect_key($exceptions['post'][$key], $all_types); } } foreach (array_keys($exceptions) as $via_src) { ksort($exceptions[$via_src]); foreach (array_keys($exceptions[$via_src]) as $via_type) { if ($via_type_obj = pp_get_type_object($via_src, $via_type)) { $via_type_caption = $via_type_obj->labels->singular_name; } else { continue; } $any_redundant = false; echo "<div id='pp_current_{$via_src}_{$via_type}_roles' class='pp-current-exceptions'>"; /* if ( 'term' == $via_src ) echo '<h4>' . __( 'Per-Term:', 'pp' ) . '</h4>'; else { if ( $object_type ) echo '<h4>' . sprintf( __( 'Per-%s:', 'pp' ), $type_caption ) . '</h4>'; else echo '<h4>' . sprintf( __( 'Per-object:', 'pp' ), $type_caption ) . '</h4>'; } echo '<h4>' . sprintf( __( '%s Exceptions', 'pp' ), $via_type_caption ) . '</h4>'; */ ksort($exceptions[$via_src][$via_type]); foreach (array_keys($exceptions[$via_src][$via_type]) as $for_type) { if (pp_group_type_exists($for_type)) { $for_src = $for_type; } else { $for_src = taxonomy_exists($for_type) || !$for_type ? 'term' : 'post'; } if (!$for_type) { $for_type_obj = (object) array('labels' => (object) array('singular_name' => __('(all post types)', 'pp'))); } elseif (!($for_type_obj = pp_get_type_object($for_src, $for_type))) { continue; } foreach (array_keys($exceptions[$via_src][$via_type][$for_type]) as $operation) { if (!($operation_obj = pp_get_op_object($operation, $for_type))) { continue; } if ('assign' == $operation) { $op_caption = $for_type ? sprintf(__('%1$s (%2$s: %3$s)', 'pp'), $operation_obj->label, $for_type_obj->labels->singular_name, $via_type_caption) : sprintf(__('%1$s %2$s %3$s', 'pp'), $operation_obj->label, $via_type_caption, $for_type_obj->labels->singular_name); } elseif (in_array($operation, array('manage', 'associate'))) { $op_caption = sprintf(__('%1$s %2$s', 'pp'), $operation_obj->label, $via_type_caption); } else { $op_caption = sprintf(__('%1$s %2$s', 'pp'), $operation_obj->label, $for_type_obj->labels->singular_name); } echo "<div class='type-roles-wrapper'>"; echo '<h4>' . $op_caption . '</h4>'; echo "<div class='pp-current-type-roles'>"; echo '<div class="pp-current-roles-tbl-wrapper"><table>'; // fill table body (item assignments for each role) echo '<tbody>'; foreach (array_keys($exceptions[$via_src][$via_type][$for_type][$operation]) as $mod_type) { if (!($mod_type_obj = pp_get_mod_object($mod_type))) { continue; } foreach (array_keys($exceptions[$via_src][$via_type][$for_type][$operation][$mod_type]) as $status) { if ($status) { $_status = explode(':', $status); if (count($_status) > 1) { $attrib = $_status[0]; $_status = $_status[1]; } else { $attrib = 'post_status'; $_status = $status; } if ('post_status' == $attrib) { if ($status_obj = get_post_status_object($_status)) { $status_label = $status_obj->label; } elseif ('{unpublished}' == $_status) { // @todo: API $status_label = __('unpublished', 'pp'); } else { $status_label = $status; } } else { $status_label = $status; } $mod_caption = sprintf(__('%1$s (%2$s)', 'pp'), $mod_type_obj->label, $status_label); } else { $mod_caption = $mod_type_obj->label; } if ('exclude' == $mod_type && !empty($exceptions[$via_src][$via_type][$for_type][$operation]['include'])) { $tr_class = ' class="pp_faded"'; $mod_caption = sprintf(__('* %s', 'pp'), $mod_caption); $any_faded = true; } else { $tr_class = ''; } echo "<tr{$tr_class}><td class='pp_item_role_caption'>{$mod_caption}</td>"; echo '<td>'; //if ( $item_links ) { // if ( 'term' != $scope ) // $edit_url_base = $pp_data_sources->member_property( $item_source, '_edit_link' ); //} echo "<div class='pp-role-terms-wrapper pp-role-terms-{$via_type}'>"; if ('term' == $via_src && !in_array($operation, array('manage', 'associate'))) { if (taxonomy_exists($via_type)) { // "Categories:" $tx_obj = get_taxonomy($via_type); $tx_caption = $tx_obj->labels->name; } else { $tx_caption = ''; } echo '<div class="pp-taxonomy-caption">' . sprintf(__('%s:', 'pp'), $tx_caption) . '</div>'; //$edit_url_base = ( isset($tx_obj->_edit_link) ) ? $tx_obj->_edit_link : ''; } echo '<div class="pp-role-terms">'; $tx_item_paths = array_intersect_key($item_paths[$via_src], $exceptions[$via_src][$via_type][$for_type][$operation][$mod_type][$status]); uasort($tx_item_paths, 'strnatcasecmp'); // sort by array values, but maintain keys ); foreach ($tx_item_paths as $item_id => $item_path) { //$assignment = $roles[$scope][$role_name][$item_source][$item_type][$item_id]; $assignment = $exceptions[$via_src][$via_type][$for_type][$operation][$mod_type][$status][$item_id]; $classes = array(); if (isset($assignment['children'])) { if (isset($assignment['item'])) { $ass_id = $assignment['item'] . ',' . $assignment['children']; $classes[] = 'role_both'; $any_both = true; } else { $ass_id = '0,' . $assignment['children']; $classes[] = 'role_ch'; $any_child_only = true; } } else { $ass_id = $assignment['item']; } $class = $classes ? "class='" . implode(' ', $classes) . "'" : ''; if ($read_only) { if ($item_links) { //$item_edit_url = sprintf($edit_url_base, $item_id); $item_edit_url = ''; echo "<div><a href='{$item_edit_url}' {$class}>{$item_path}</a></div>"; } else { echo "<div><span {$class}>{$item_path}</span></div>"; } } else { $cb_id = 'pp_edit_exception_' . str_replace(',', '_', $ass_id); if (!empty($assignment['inherited_from'])) { $classes[] = 'inherited'; $classes[] = "from_{$assignment['inherited_from']}"; } if ($tr_class) { // apply fading for redundantly stored exclusions $classes[] = $tr_class; } $lbl_class = $classes ? "class='" . implode(' ', $classes) . "'" : ''; if ('term' == $via_src) { $edit_url = admin_url("edit-tags.php?taxonomy={$via_type}&action=edit&tag_ID=" . pp_ttid_to_termid($item_id, $via_type) . "&post_type={$for_type}"); } else { $edit_url = admin_url("post.php?post={$item_id}&action=edit"); } echo "<div><label for='{$cb_id}' {$lbl_class}><input id='{$cb_id}' type='checkbox' name='pp_edit_exception[]' value='{$ass_id}' {$class}> " . $item_path . '</label><a href="' . $edit_url . '">' . __('edit') . '</a></div>'; } } // end foreach item if (count($tx_item_paths) > 3 && !$read_only) { $cb_id = "pp_check_all_{$via_src}_{$via_type}_{$for_type}_{$operation}_{$status}"; echo "<div><label for='{$cb_id}'><input type='checkbox' id='{$cb_id}' class='pp_check_all'> " . __('(all)', 'pp') . '</label></div>'; } echo '</div></div>'; // pp-role-terms, pp-role-terms-wrapper echo '</td></tr>'; } // end foreach status } // end foreach mod_type echo '</tbody>'; echo '</table></div>'; // pp-current-roles-tbl-wrapper echo '<div class="pp-exception-bulk-edit" style="display:none">'; echo "<select><option value=''>" . __ppw('Bulk Actions', 'pp') . "</option><option value='remove'>" . __ppw('Remove', 'pp') . '</option>'; if ('post' == $via_src && (!$via_type || $via_type_obj->hierarchical)) { echo "<option value='propagate'>" . sprintf(__('Assign for selected and sub-%s', 'pp'), $via_type_obj->labels->name) . '</option>'; echo "<option value='unpropagate'>" . sprintf(__('Assign for selected %s only', 'pp'), $via_type_obj->labels->singular_name) . '</option>'; echo "<option value='children_only'>" . sprintf(__('Assign for sub-%s only', 'pp'), $via_type_obj->labels->name) . '</option>'; } elseif ('term' == $via_src && $via_type_obj->hierarchical) { echo "<option value='propagate'>" . __('Assign for selected and sub-terms', 'pp') . '</option>'; echo "<option value='unpropagate'>" . __('Assign for selected term only', 'pp') . '</option>'; echo "<option value='children_only'>" . __('Assign for sub-terms only', 'pp') . '</option>'; } echo '</select>'; //submit_button( __ppw('Apply'), 'button-secondary submit-edit-item-exception', '', false ); ?> <input type="submit" name="" class="button submit-edit-item-exception" value="<?php _e('Apply', 'pp'); ?> " /> <?php echo '<img class="waiting" style="display:none;" src="' . esc_url(admin_url('images/wpspin_light.gif')) . '" alt="" />'; echo '</div>'; // pp-exception-bulk-edit echo '</div></div>'; // type-roles-wrapper, pp-current-type-roles } // end foreach operation } // end foreach for_type if ($any_redundant) { echo '<div class="pp-current-roles-note">' . __('* = exceptions redundant due to a corresponding "only these" entry', 'pp') . '</div>'; } if (!empty($via_type_obj->hierarchical)) { $_caption = strtolower($via_type_obj->labels->name); if (!empty($any_both) || !empty($any_child_only)) { ?> <div class="pp-current-roles-note"> <?php if (!empty($any_both)) { echo '<span class="role_both" style="padding-right:20px">' . sprintf(__('... = assigned for %1$s and sub-%1$s', 'pp'), $_caption) . '</span>'; } if (!empty($any_child_only)) { echo '<span>' . sprintf(__('* = assigned for sub-%s only', 'pp'), $_caption) . '</span>'; } ?> </div> <?php } $show_all_url = esc_url(add_query_arg('show_propagated', '1', $_SERVER['REQUEST_URI'])); $show_all_link = " <a href='{$show_all_url}'>"; if (empty($_REQUEST['show_propagated'])) { if ('term' == $via_src) { echo '<div class="pp-current-roles-note">' . sprintf(__('note: Exceptions inherited from parent %1$s are not displayed. %2$sshow all%3$s', 'pp'), $_caption, $show_all_link, '</a>') . '</div>'; } else { echo '<div class="pp-current-roles-note">' . sprintf(__('note: Exceptions inherited from parent %1$s or terms are not displayed. %2$sshow all%3$s', 'pp'), $_caption, $show_all_link, '</a>') . '</div>'; } } } echo '</div>'; // pp-current-exceptions } // end foreach via_type } // end foreach via_src echo '</div>'; // pp_current_exceptions_inner echo '</div>'; // no class echo '</div>'; // pp_current_exceptions }