This is not duplicated post!
I working on the custom theme and have 2 taxonomies: bezirk
and ortsgruppen
.
bezirk
acts like main group and ortsgruppen
is the sub group under bezirk
. I need to asign for each ortsgruppen
in which bezirk
belong.
Both taxonomy are included in the post
and custom post types dabei-gsi
, homepage-slider
, team
, travel
All custom posts can have multiple bezirk
and ortsgruppen
or non, that depends where user want to place it.
I create new user role bezirk_admins
and need to setup user roles by bezirk
and ortsgruppen
.
Here is the complete role setup:
add_role( 'bezirk_admins', __( 'Bezirk Admins', 'mitdabei' ),
array(
'read_private_dabeis' => true,
'edit_dabeis' => true,
'edit_others_dabeis' => true,
'edit_private_dabeis' => true,
'edit_published_dabeis' => true,
'upload_files' => true,
'read_dabei' => false,
'edit_dabei' => false,
'edit_others_dabei' => true,
'publish_dabeis' => true,
'delete_dabei' => false,
'delete_others_dabei' => true,
'delete_private_dabei' => true,
'delete_published_dabei' => true,
'assign_bezirk' => true,
'assign_ortsgruppe' => true,
'publish_dabei' => true,
'publish_slider' => true,
'publish_sliders' => true,
'publish_team' => true,
'publish_teams' => true,
'publish_travel' => true,
'publish_travels' => true,
'delete_dabeis' => true,
'delete_slider' => false,
'delete_sliders' => true,
'delete_team' => false,
'delete_teams' => true,
'delete_travel' => false,
'delete_travels' => true,
'delete_others_dabeis' => true,
'delete_others_slider' => true,
'delete_others_sliders' => true,
'delete_others_team' => true,
'delete_others_teams' => true,
'delete_others_travel' => true,
'delete_others_travels' => true,
'delete_private_dabeis' => true,
'delete_private_slider' => true,
'delete_private_sliders' => true,
'delete_private_team' => true,
'delete_private_teams' => true,
'delete_private_travel' => true,
'delete_private_travels' => true,
'delete_published_dabeis' => true,
'delete_published_slider' => true,
'delete_published_sliders' => true,
'delete_published_team' => true,
'delete_published_teams' => true,
'delete_published_travel' => true,
'delete_published_travels' => true,
'edit_slider' => false,
'edit_sliders' => true,
'edit_team' => false,
'edit_teams' => true,
'edit_travel' => false,
'edit_travels' => true,
'edit_others_slider' => true,
'edit_others_sliders' => true,
'edit_others_team' => true,
'edit_others_teams' => true,
'edit_others_travel' => true,
'edit_others_travels' => true,
'edit_private_dabei' => true,
'edit_private_slider' => true,
'edit_private_sliders' => true,
'edit_private_team' => true,
'edit_private_teams' => true,
'edit_private_travel' => true,
'edit_private_travels' => true,
'edit_published_dabei' => true,
'edit_published_slider' => true,
'edit_published_sliders' => true,
'edit_published_team' => true,
'edit_published_teams' => true,
'edit_published_travel' => true,
'edit_published_travels' => true,
'read_private_dabei' => true,
'read_private_slider' => true,
'read_private_sliders' => true,
'read_private_team' => true,
'read_private_teams' => true,
'read_private_travel' => true,
'read_private_travels' => true,
'publish_post' => true,
'publish_posts' => true,
'delete_post' => false,
'delete_posts' => true,
'delete_others_post' => true,
'delete_others_posts' => true,
'delete_private_post' => true,
'delete_private_posts' => true,
'delete_published_post' => true,
'delete_published_posts' => true,
'edit_post' => false,
'edit_posts' => true,
'edit_others_post' => true,
'edit_others_posts' => true,
'edit_private_post' => true,
'edit_private_posts' => true,
'edit_published_post' => true,
'edit_published_posts' => true,
'read_private_post' => true,
'read_private_posts' => true,
'edit_comment' => false,
'manage_categories' => true,
'manage_post_tags' => true,
'level_0' => true,
'edit_files' => true,
'read' => true,
'edit_categories' => true,
'assign_categories' => true,
'edit_post_tags' => true,
'assign_post_tags' => true,
'assign_funktions' => true,
'manage_media_categories' => true,
'edit_media_categories' => true,
'assign_media_categories' => true,
'delete_categories' => true,
'delete_post_tags' => true,
'delete_media_categories' => true,
'edit_media' => true,
'delete_media' => true,
'manage_place' => true,
'edit_place' => true,
'delete_place' => true,
'edit_others_media' => true,
'delete_others_media' => true,
'unfiltered_upload' => true,
'read_post' => true
)
);
Request is that inside WP Admin I need to limit access to all post types based on the bezirk
and ortsgruppen
and all views must follow that.
I writte class like this:
if(!class_exists('Mitdabei_User_Restrictions')) :
class Mitdabei_User_Restrictions extends Mitdabei
{
// WordPress database (object)
private $wpdb = NULL;
// Current post type (string)
private $post_type = NULL;
// Current user data (object)
private $user = false;
// User capabilities (array)
private $capabilities = array();
function __construct()
{
global $wpdb;
$this->wpdb = $wpdb;
$this->post_type = $this->post_type();
$this->user = $this->check_user();
// Join proper tables for the post where search
$this->add_action('posts_join', 'posts_join');
// Filter admin posts by bezirk and ortsgruppe
$this->add_action('posts_where', 'posts_where');
// Set group by posts ID
$this->add_action('posts_groupby', 'posts_groupby');
// Post Request
$this->add_action('posts_request', 'posts_request');
// Filter admin posts by bezirk and ortsgruppe
$this->add_action('save_post', 'save_post', 99, 2);
// Filter Bezirk
$this->add_action('get_bezirk', 'get_bezirk');
// Filter Ortsgruppe
$this->add_action('get_ortsgruppe', 'get_ortsgruppe');
}
/* Filter admin posts by bezirk and ortsgruppe
=======================================================*/
function save_post ( $post_id, $post ) {
if(false !== ($user = $this->check_user()) && in_array($post->post_type, array('dabei-gsi', 'post', 'homepage-slider', 'team', 'travel'), true) !== false)
{
$defaults = array(
'bezirk' => array(),
'ortsgruppe' => array(),
);
if($bezirks = get_user_meta( $user->ID, 'ipm_mitdabei_bezirk', true ))
{
$data_terms = array();
foreach($bezirks as $bezirk)
{
$term = get_term_by('id', $bezirk, 'bezirk');
$defaults['bezirk'][] = $term->slug;
}
}
if($ortsgruppes = get_user_meta( $user->ID, 'ipm_mitdabei_ortsgruppe', true ))
{
foreach($ortsgruppes as $ortsgruppe)
{
$term = get_term_by('id', $ortsgruppe, 'ortsgruppe');
$defaults['ortsgruppe'][] = $term->slug;
}
}
/*
$taxonomies = get_object_taxonomies( $post->post_type );
foreach ( (array) $taxonomies as $taxonomy ) {
$terms = wp_get_post_terms( $post_id, $taxonomy );
if ( empty( $terms ) && array_key_exists( $taxonomy, $defaults ) ) {
wp_set_object_terms( $post_id, $defaults[$taxonomy], $taxonomy );
}
}
*/
}
}
/* Filter admin posts by bezirk and ortsgruppe
=======================================================*/
function posts_where ( $where ) {
global $pagenow;
if(false !== ($user = $this->check_user()) && in_array($this->post_type, array('dabei-gsi', 'post', 'homepage-slider', 'team', 'travel'), true) !== false)
{
$terms = array();
$i=0;
$bezirks = get_user_meta( $user->ID, 'ipm_mitdabei_bezirk', true );
$ortsgruppes = get_user_meta( $user->ID, 'ipm_mitdabei_ortsgruppe', true );
if(!empty($bezirks))
{
$data_terms = array();
foreach($bezirks as $bezirk)
{
$data_terms[]="tt{$i}.term_taxonomy_id IN ({$bezirk})";
}
if($data_terms)
{
$terms[$i] = '(' . join("\n OR \n", $data_terms) . ')';
++$i;
}
}
if(!empty($ortsgruppes))
{
$data_terms = array();
foreach($ortsgruppes as $ortsgruppe)
{
$data_terms[]="tt{$i}.term_taxonomy_id IN ({$ortsgruppe})";
}
if($data_terms)
{
$terms[$i] = '(' . join("\n OR \n", $data_terms) . ')';
++$i;
}
}
if(isset($_REQUEST['bezirk']) && $bezirk = get_term_by('slug', $_REQUEST['bezirk'], 'bezirk'))
{
$terms[$i]="tt{$i}.term_taxonomy_id IN ({$bezirk->term_id})";
++$i;
}
if(isset($_REQUEST['ortsgruppe']) && $ortsgruppe = get_term_by('slug', $_REQUEST['ortsgruppe'], 'ortsgruppe'))
{
$terms[$i]="tt{$i}.term_taxonomy_id IN ({$ortsgruppe->term_id})";
++$i;
}
if(preg_match('/('.$this->wpdb->prefix.'term_relationships\.term_taxonomy_id IN \((.*?)\))/i', $where, $tax_match))
{
if(isset($tax_match[2]))
{
$terms[$i]="tt{$i}.term_taxonomy_id IN ({$tax_match[2]})";
++$i;
}
if(!empty($terms))
{
$where = preg_replace(
'/('.$this->wpdb->prefix.'term_relationships\.term_taxonomy_id IN \(.*?\))/i',
'(' . join("\n AND \n", $terms) . ')',
$where);
}
}
else
{
if(empty($ortsgruppes))
{
$where = preg_replace(
'/(^\s?AND)/i',
' AND (' . join("\n AND \n", $terms) . ') AND',
$where);
}
else
{
$where = preg_replace(
'/(^\s?AND)/i',
' AND (' . join("\n OR \n", $terms) . ') AND',
$where);
}
}
$where = str_replace('tt0', $this->wpdb->term_relationships, $where);
}
return $where;
}
/* Join proper tables for the post where search
=======================================================*/
function posts_join ( $join ) {
if(false !== ($user = $this->check_user()) && in_array($this->post_type, array('dabei-gsi', 'post', 'homepage-slider', 'team', 'travel'), true) !== false)
{
$terms = array();
$i=0;
if($bezirks = get_user_meta( $user->ID, 'ipm_mitdabei_bezirk', true ))
{
foreach($bezirks as $bezirk)
{
$terms[$i]="INNER JOIN {$this->wpdb->term_relationships} AS tt{$i} ON ({$this->wpdb->posts}.ID = tt{$i}.object_id)";
++$i;
}
}
if($ortsgruppes = get_user_meta( $user->ID, 'ipm_mitdabei_ortsgruppe', true ))
{
foreach($ortsgruppes as $ortsgruppe)
{
$terms[$i]="INNER JOIN {$this->wpdb->term_relationships} AS tt{$i} ON ({$this->wpdb->posts}.ID = tt{$i}.object_id)";
++$i;
}
}
if(isset($_REQUEST['bezirk']) && get_term_by('slug', $_REQUEST['bezirk'], 'bezirk'))
{
$terms[$i]="INNER JOIN {$this->wpdb->term_relationships} AS tt{$i} ON ({$this->wpdb->posts}.ID = tt{$i}.object_id)";
++$i;
}
if(isset($_REQUEST['ortsgruppe']) && get_term_by('slug', $_REQUEST['ortsgruppe'], 'ortsgruppe'))
{
$terms[$i]="INNER JOIN {$this->wpdb->term_relationships} AS tt{$i} ON ({$this->wpdb->posts}.ID = tt{$i}.object_id)";
++$i;
}
if($terms) $join = ' ' . join(" \n", $terms);
$join = str_replace('tt0', $this->wpdb->term_relationships, $join);
}
return $join;
}
/* Set group by posts ID
=======================================================*/
function posts_groupby ( $groupby ) {
if(false !== ($user = $this->check_user()) && in_array($this->post_type, array('dabei-gsi', 'post', 'homepage-slider', 'team', 'travel'), true) !== false)
{
if(empty($groupby))
{
$groupby = " {$this->wpdb->posts}.ID";
}
}
return $groupby;
}
/* Filter Bezirk
=======================================================*/
function get_bezirk ($prepared_args){
if(false !== ($user = $this->check_user()))
{
if($bezirks = get_user_meta( $user->ID, 'ipm_mitdabei_bezirk', true ))
{
foreach($bezirks as $bezirk)
{
if($bezirk == $prepared_args->term_id)
{
return $prepared_args;
}
}
}
}
else return $prepared_args;
}
/* Filter Ortsgruppe
=======================================================*/
function get_ortsgruppe ($prepared_args){
if(false !== ($user = $this->check_user()))
{
if($ortsgruppes = get_user_meta( $user->ID, 'ipm_mitdabei_ortsgruppe', true ))
{
foreach($ortsgruppes as $ortsgruppe)
{
if($ortsgruppe == $prepared_args->term_id)
{
return $prepared_args;
}
}
}
}
else return $prepared_args;
}
/* Check user permission and set data
=======================================================*/
private function check_user() {
global $current_user;
if(is_admin() && is_user_logged_in())
{
if($this->user !== false) return $this->user;
$user = NULL;
if($current_user)
$user = $current_user;
else if(function_exists('wp_get_current_user'))
$user = wp_get_current_user();
else if(function_exists('get_currentuserinfo'))
$user = get_currentuserinfo();
if (NULL !== $user && property_exists($user, 'roles') && in_array('bezirk_admins', $user->roles) )
{
if(empty($this->capabilities))
{
if(property_exists($user, 'allcaps'))
$this->capabilities = $user->allcaps;
else
$this->capabilities = get_role( 'bezirk_admins' )->capabilities;
}
if(property_exists($user, 'data'))
return $user->data;
else if(property_exists($user, 'ID'))
return $user;
}
}
return false;
}
/* Get current post type
=======================================================*/
private function post_type () {
global $post, $parent_file, $typenow, $current_screen, $pagenow;
$post_type = NULL;
if($post && (property_exists($post, 'post_type') || method_exists($post, 'post_type')))
$post_type = $post->post_type;
if(empty($post_type) && !empty($current_screen) && (property_exists($current_screen, 'post_type') || method_exists($current_screen, 'post_type')) && !empty($current_screen->post_type))
$post_type = $current_screen->post_type;
if(empty($post_type) && !empty($typenow))
$post_type = $typenow;
if(empty($post_type) && function_exists('get_current_screen'))
$post_type = get_current_screen();
if(empty($post_type) && isset($_REQUEST['post']) && !empty($_REQUEST['post']) && function_exists('get_post_type') && $get_post_type = get_post_type((int)$_REQUEST['post']))
$post_type = $get_post_type;
if(empty($post_type) && isset($_REQUEST['post_type']) && !empty($_REQUEST['post_type']))
$post_type = sanitize_key($_REQUEST['post_type']);
if(empty($post_type) && 'edit.php' == $pagenow)
$post_type="post";
return $post_type;
}
}
new Mitdabei_User_Restrictions();
endif;
The main problem is that one bezirk_admin can have a one or more bezirk
and only posts that have bezirk
with no ortsgruppen
can be displayed.
For now in my solution bezirk
“admin” can manage also all ortsgruppen
under bezirk
what is not good.
I don’t need plugin solution. I need explanation how to limit posts in the loops, and taxonomies based on the 2 taxonomy rules and what hooks to use for this.
Thanks!