public static function inherit_parent_exceptions($item_id, $args = array()) { $defaults = array('via_item_source' => '', 'via_item_type' => '', 'set_parent' => '', 'last_parent' => '', 'is_new' => true); extract(array_merge($defaults, $args), EXTR_SKIP); $is_new_term = 'term' != $via_item_source ? false : !empty($_REQUEST['action']) && 'add-tag' == $_REQUEST['action']; // don't execute this action handler more than one per post save (may be called directly on pre-save cap check) static $did_items; if ('post' == $via_item_source) { if (!isset($did_items)) { $did_items = array(); } if (isset($did_items[$item_id])) { return; } $did_items[$item_id] = 1; } if (!apply_filters('pp_do_inherit_parent_exceptions', true, $item_id, $args)) { return; } // Inherit exceptions from new parent post/term, but only for new items or if parent is changed if (isset($set_parent) && $set_parent != $last_parent || $is_new_term) { // retain all explicitly selected exceptions global $wpdb; $descendant_ids = pp_get_descendant_ids($via_item_source, $item_id); if ($descendant_ids && 'term' == $via_item_source) { $descendant_ids = pp_termid_to_ttid($descendant_ids, $via_item_type); } // clear previously propagated role assignments for this item and its branch of sub-items if (!$is_new) { _pp_clear_exceptions($via_item_source, $item_id, array('inherited_only' => true)); _pp_clear_exceptions($via_item_source, $descendant_ids, array('inherited_only' => true)); } // assign propagating exceptions from new parent if ($set_parent) { $id_clause = "AND i.item_id IN ('" . implode("','", array_merge($descendant_ids, (array) $item_id)) . "')"; $retain_exceptions = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->ppc_exception_items} AS i INNER JOIN {$wpdb->ppc_exceptions} AS e ON e.exception_id = i.exception_id WHERE i.assign_for = 'item' AND i.inherited_from = '0' AND e.via_item_source = %s {$id_clause}", $via_item_source)); if ('term' == $via_item_source) { $parent_term = get_term($set_parent, $via_item_type); $set_parent = $parent_term->term_taxonomy_id; } // propagate exception from new parent to this item and its branch of sub-items $_args = compact('retain_exceptions', 'force_for_item_type'); $_args['parent_exceptions'] = _pp_get_parent_exceptions($via_item_source, $item_id, $set_parent); $any_inserts = _pp_inherit_parent_exceptions($via_item_source, $item_id, $set_parent, $_args); foreach ($descendant_ids as $_descendant_id) { $any_inserts = $any_inserts || _pp_inherit_parent_exceptions($via_item_source, $_descendant_id, $set_parent, $_args); } } } // endif new parent selection (or new item) return !empty($any_inserts); }
function custom_column($val, $column_name, $id) { if ('pp_exceptions' != $column_name) { return; } static $got_data; if (empty($got_data)) { $this->log_term_data(); $got_data = true; } global $taxonomy; $id = pp_termid_to_ttid($id, $taxonomy); if (!empty($this->exceptions[$id])) { global $typenow; $op_names = array(); foreach ($this->exceptions[$id] as $op) { if ($op_obj = pp_get_op_object($op, $typenow)) { $op_names[] = $op_obj->label; } } uasort($op_names, 'strnatcasecmp'); echo implode(", ", $op_names); } }
function _pp_edit_agent_exceptions($agent_id, $agent_type) { if (!current_user_can('pp_assign_roles') || !pp_bulk_roles_enabled()) { return; } $type_objs = array(); if (isset($_POST['pp_add_exception'])) { // note: group editing capability already verified at this point foreach ($_POST['pp_add_exception'] as $exception) { $exception = apply_filters('pp_add_exception', $exception); extract($exception); $args = compact('mod_type', 'item_id', 'operation'); $args['for_item_status'] = $attrib_cond; if (taxonomy_exists($via_type)) { $args['via_item_source'] = 'term'; $args['via_item_type'] = $via_type; $args['item_id'] = pp_termid_to_ttid($item_id, $via_type); } elseif (!$via_type || post_type_exists($via_type)) { $args['via_item_source'] = 'post'; $args['via_item_type'] = ''; } else { $args['via_item_source'] = $via_type; $args['via_item_type'] = ''; } if (taxonomy_exists($for_type)) { $args['for_item_source'] = 'term'; } elseif (!$for_type || post_type_exists($for_type) || '(all)' == $for_type) { $args['for_item_source'] = 'post'; } else { $args['for_item_source'] = $for_type; } $args['for_item_type'] = '(all)' == $for_type ? '' : $for_type; $agents = array(); // also support bulk-assignment of user exceptions $agent_ids = 'user' == $agent_type && !$agent_id && isset($_REQUEST['member_csv']) ? explode(',', $_REQUEST['member_csv']) : array($agent_id); foreach ($agent_ids as $_agent_id) { if ($_agent_id) { foreach (array('item' => $for_item, 'children' => $for_children) as $assign_for => $is_assigned) { if ($is_assigned) { $agents[$assign_for][$_agent_id] = true; } } } } ppc_assign_exceptions($agents, $agent_type, $args); } } }
function act_prep_metaboxes() { global $tag_ID; if (empty($tag_ID)) { return; } static $been_here; if (isset($been_here)) { return; } $been_here = true; global $typenow; // pp_find_post_type(); $post_type = !empty($_REQUEST['pp_universal']) ? '' : $typenow; $taxonomy = isset($_REQUEST['taxonomy']) ? pp_sanitize_key($_REQUEST['taxonomy']) : ''; //$is_administrator = pp_is_user_administrator(); //$can_admin_object = $is_administrator || $pp_admin->user_can_admin_object('post', $object_id, $object_type); if (current_user_can('pp_assign_roles')) { $this->init_item_exceptions_ui(); $tt_id = pp_termid_to_ttid($tag_ID, $taxonomy); $args = array('for_item_type' => $post_type, 'hierarchical' => is_taxonomy_hierarchical($post_type)); // via_src, for_src, via_type, item_id, args $this->item_exceptions_ui->data->load_exceptions('term', 'post', $taxonomy, $tt_id, $args); do_action('pp_prep_metaboxes', 'term', $taxonomy, $tt_id); } }
public static function insert_exceptions($mod_type, $operation, $via_item_source, $via_item_type, $for_item_source, $for_item_type, $item_id, $agent_type, $agents, $args) { $defaults = array('assign_for' => 'item', 'remove_assignments' => false, 'for_item_status' => '', 'mod_type' => '', 'inherited_from' => array(), 'is_auto_insertion' => false); // auto_insertion arg set for propagation from parent objects $args = array_merge($defaults, (array) $args); extract($args, EXTR_SKIP); if (!$agents) { return; } global $wpdb, $current_user; $updated_items = array(); // for use with do_action hook $updated_items[] = $item_id; $assigner_id = $current_user->ID; $operation = pp_sanitize_key($operation); $via_item_source = pp_sanitize_key($via_item_source); $for_item_source = pp_sanitize_key($for_item_source); $for_item_type = pp_sanitize_key($for_item_type); $item_id = (int) $item_id; $agent_type = pp_sanitize_key($agent_type); $mod_type = pp_sanitize_key($mod_type); $via_item_type = pp_sanitize_key($via_item_type); $for_item_status = pp_sanitize_csv($for_item_status); $assign_for = pp_sanitize_key($assign_for); if ('children' == $assign_for) { if ('term' == $via_item_source) { $descendant_ids = array(); if ($_term = $wpdb->get_row("SELECT term_id, taxonomy FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = '{$item_id}' LIMIT 1")) { if ($_term_ids = pp_get_descendant_ids('term', $_term->term_id)) { $descendant_ids = pp_termid_to_ttid($_term_ids, $_term->taxonomy); } } } else { $descendant_ids = pp_get_descendant_ids($via_item_source, $item_id, array('include_attachments' => false)); // don't propagate page exceptions to attachments } if ($descendant_ids) { // TODO: reinstate this? /* global $pp_admin; if ( ! $is_auto_insertion ) { // don't allow a page parent change to modify role assignments for a descendant object which the current user can't administer $remove_ids = array(); foreach ( $descendant_ids as $id ) { if ( 'term' == $scope ) { if ( ! $pp_admin->user_can_admin_terms($item_source, $id) ) // TODO: add $args with 'taxonomy' $remove_ids []= $id; } else { if ( ! $pp_admin->user_can_admin_object( $item_source, $id ) ) $remove_ids []= $id; } } $descendant_ids = array_diff( $descendant_ids, $remove_ids ); } */ $descendant_id_csv = implode("','", $descendant_ids); } } // Before inserting an exception, delete any overlooked old exceptions for the same src/type/status. $match_cols = compact('mod_type', 'for_item_source', 'for_item_status', 'operation', 'agent_type', 'via_item_source', 'via_item_type'); $_clauses = array(); foreach ($match_cols as $col => $val) { $_clauses[] = "{$col} = '{$val}'"; } $qry_exc_select_base = "SELECT * FROM {$wpdb->ppc_exceptions} WHERE " . implode(' AND ', $_clauses); $qry_exc_select_type_base = "SELECT for_item_type, exception_id FROM {$wpdb->ppc_exceptions} WHERE " . implode(' AND ', $_clauses); $insert_exc_data = $match_cols; $insert_exc_data['assigner_id'] = $assigner_id; $qry_item_select_base = "SELECT eitem_id FROM {$wpdb->ppc_exception_items} WHERE assign_for = '{$assign_for}' AND item_id = '{$item_id}'"; $qry_item_delete_base = "SELECT eitem_id FROM {$wpdb->ppc_exception_items} WHERE 1=1"; foreach (array_keys($agents) as $agent_id) { $agent_id = (int) $agent_id; // first, retrieve or create the pp_exceptions record for this user/group and src,type,status if (!($exc = $wpdb->get_row("{$qry_exc_select_base} AND for_item_type = '{$for_item_type}' AND agent_id = '{$agent_id}'"))) { $insert_exc_data['agent_id'] = $agent_id; $insert_exc_data['for_item_type'] = $for_item_type; $wpdb->insert($wpdb->ppc_exceptions, $insert_exc_data); $exception_id = $wpdb->insert_id; } else { $exception_id = $exc->exception_id; } $this_inherited_from = isset($inherited_from[$agent_id]) ? $inherited_from[$agent_id] : 0; // delete any existing items for this exception_id if ($eitem_ids = $wpdb->get_col($qry_item_select_base . " AND exception_id = '{$exception_id}'")) { self::remove_exception_items_by_id($eitem_ids); } // insert exception items $item_data = compact('item_id', 'assign_for', 'exception_id', 'assigner_id'); $item_data['inherited_from'] = $this_inherited_from; $wpdb->insert($wpdb->ppc_exception_items, $item_data); do_action('pp_inserted_exception_item', array_merge((array) $exc, $item_data)); $assignment_id = $wpdb->insert_id; // insert exception for all descendant items if ('children' == $assign_for && $descendant_ids) { if (!$this_inherited_from) { $this_inherited_from = (int) $assignment_id; //$role_arr['inherited_from'] = $this_inherited_from; } $exceptions_by_type = array(); $_results = $wpdb->get_results("{$qry_exc_select_type_base} AND for_item_type = '{$for_item_type}' AND agent_id = '{$agent_id}'"); foreach ($_results as $row) { $exceptions_by_type[$row->for_item_type] = $row->exception_id; } if ('term' == $via_item_source && taxonomy_exists($for_item_type)) { // need to allow for descendants of a different post type than parent $descendant_types = $wpdb->get_results("SELECT term_taxonomy_id, taxonomy AS for_item_type FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id IN ('" . implode("','", $descendant_ids) . "')", OBJECT_K); } elseif ('post' == $via_item_source) { $descendant_types = $wpdb->get_results("SELECT ID, post_type AS for_item_type FROM {$wpdb->posts} WHERE ID IN ('" . implode("','", $descendant_ids) . "')", OBJECT_K); } else { $descendant_types = array(); } foreach ($descendant_ids as $id) { if ($for_item_type) { // allow for descendants with post type different from parent if (!isset($descendant_types[$id])) { $child_for_item_type = $for_item_type; // if child type could not be determined, assume parent type } elseif ('revision' == $descendant_types[$id]->for_item_type) { continue; } else { $child_for_item_type = $descendant_types[$id]->for_item_type; } } else { $child_for_item_type = ''; } if (!isset($exceptions_by_type[$child_for_item_type])) { $insert_exc_data['agent_id'] = $agent_id; $insert_exc_data['for_item_type'] = $child_for_item_type; $wpdb->insert($wpdb->ppc_exceptions, $insert_exc_data); $exceptions_by_type[$child_for_item_type] = $wpdb->insert_id; } $child_exception_id = $exceptions_by_type[$child_for_item_type]; // Don't overwrite an explicitly assigned exception with a propagated exception if (!defined('PP_FORCE_EXCEPTION_OVERWRITE') || !PP_FORCE_EXCEPTION_OVERWRITE) { $have_direct_assignments = $wpdb->get_col("SELECT item_id FROM {$wpdb->ppc_exception_items} WHERE exception_id = '{$child_exception_id}' AND inherited_from = '0' AND item_id IN ('{$descendant_id_csv}')"); if (in_array($id, $have_direct_assignments)) { continue; } } if ($eitem_ids = $wpdb->get_col($qry_item_delete_base . " AND exception_id = '{$child_exception_id}' AND item_id = '{$id}'")) { self::remove_exception_items_by_id($eitem_ids); } // note: Propagated roles will be converted to direct-assigned roles if the parent object/term is deleted. //$role_arr['item_id'] = $id; $item_data = array('item_id' => $id, 'assign_for' => 'item', 'exception_id' => $child_exception_id, 'inherited_from' => $this_inherited_from, 'assigner_id' => $assigner_id); $wpdb->insert($wpdb->ppc_exception_items, $item_data); do_action('pp_inserted_exception_item', array_merge((array) $exc, $item_data)); //if ( $role_hooks ) { // $assignment_id = $wpdb->insert_id; // $role_arr['assign_for'] = 'item'; //} $item_data['assign_for'] = 'children'; $wpdb->insert($wpdb->ppc_exception_items, $item_data); do_action('pp_inserted_exception_item', array_merge((array) $exc, $item_data)); //if ( $role_hooks ) { // $assignment_id = $wpdb->insert_id; // $role_arr['assign_for'] = 'children'; //} $updated_items[] = $id; } } } // end foreach agent_id return $updated_items; }