예제 #1
0
 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);
 }
예제 #2
0
 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);
     }
 }
예제 #3
0
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);
     }
 }
예제 #5
0
 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;
 }