here. * Author: MaxBlogPress Revived * Author URI: http://www.maxblogpress.com * * License: GNU General Public License * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Copyright (C) 2009 www.maxblogpress.com * * This is the improved version of "Access by Category" plugin by Joel Rothschild * */ define('ABC_NAME', 'Access By Category'); define('ABC_VERSION', '1.0'); class accessbycategory { function accessbycategory() { // construction of 'abc' plugin object // abc table names global $wpdb; $this->abc_path = preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '', __FILE__); $this->abc_path = str_replace('\\','/',$this->abc_path); $this->abc_siteurl = get_bloginfo('wpurl'); $this->abc_siteurl = (strpos($this->abc_siteurl,'http://') === false) ? get_bloginfo('siteurl') : $this->abc_siteurl; $this->abc_fullpath = $this->abc_siteurl.'/wp-content/plugins/'.substr($this->abc_path,0,strrpos($this->abc_path,'/')).'/'; $this->categories_access_table = $wpdb->prefix . 'categories_access'; $this->posts_access_table = $wpdb->prefix . 'posts_access'; $this->links_access_table = $wpdb->prefix . 'links_access'; // hook functions add_action('activate_'.$this->abc_path, array(&$this, 'install_abc')); add_action('admin_menu', array(&$this, 'admin_menu')); add_action('admin_head', array(&$this, 'admin_head')); $this->abc_activate = get_option('abc_activate'); if ( $this->abc_activate == 2 ) { add_filter('category_save_pre', array(&$this, 'category_save_pre')); // this filter is used when publishing a post add_action('save_post', array(&$this, 'save_post')); add_action('add_category', array(&$this, 'add_category')); add_action('delete_category', array(&$this, 'delete_category')); add_action('restrict_manage_posts', array(&$this, 'restrict_manage_posts')); add_filter('user_has_cap', array(&$this, 'user_has_cap'), 10, 3); add_filter('posts_join', array(&$this, 'posts_join')); add_filter('posts_where', array(&$this, 'posts_where')); add_filter('get_bookmarks', array(&$this, 'get_bookmarks'), 10, 2); add_filter('get_categories', array(&$this, 'get_categories'), 10, 2); } } function current_user_role() { // returns the current user's role // NOTE: accessbycategory currently assumes that each user has exactly one role global $current_user; $current_user_roles_keys = array_keys($current_user->roles); // because roles array may not be indexed from 0 if ( empty($current_user_roles_keys) ) { // user has no roles (i.e. not logged in) return 'not-logged-in'; } else { // return first role we find return $current_user->roles[ $current_user_roles_keys[0] ]; } } /* methods to maintain abc database tables */ function install_abc() { global $wpdb; // create categories_access table if it doesn't exist if ( $wpdb->get_var("SHOW TABLES LIKE '$this->categories_access_table';") != $this->categories_access_table ) { $sql = "CREATE TABLE $this->categories_access_table (" . 'category_ID BIGINT UNSIGNED NOT NULL, ' . 'role VARCHAR(127) NOT NULL, ' . 'inheritence ENUM("Off", "On") NOT NULL, ' . 'postto_default ENUM("Yes", "No") NOT NULL, ' . 'postto ENUM("Yes", "No") NOT NULL, ' . 'read_home ENUM("Yes", "No", "Block") NOT NULL, ' . 'read_list ENUM("Yes", "No", "Block") NOT NULL, ' . 'read_feed ENUM("Yes", "No", "Block") NOT NULL, ' . 'read_single ENUM("Yes", "No", "Block") NOT NULL, ' . 'INDEX (category_ID, role)' . ');' ; require_once(ABSPATH . 'wp-admin/upgrade-functions.php'); dbDelta($sql); } // create posts_access table if it doesn't exist if ( $wpdb->get_var("SHOW TABLES LIKE '$this->posts_access_table';") != $this->posts_access_table ) { $sql = "CREATE TABLE $this->posts_access_table (" . 'post_ID BIGINT UNSIGNED NOT NULL, ' . 'role VARCHAR(127) NOT NULL, ' . 'edit ENUM("Yes", "No") NOT NULL, ' . 'read_home ENUM("Yes", "No") NOT NULL, ' . 'read_list ENUM("Yes", "No") NOT NULL, ' . 'read_feed ENUM("Yes", "No") NOT NULL, ' . 'read_single ENUM("Yes", "No") NOT NULL, ' . 'INDEX (post_ID, role)' . ');' ; require_once(ABSPATH . 'wp-admin/upgrade-functions.php'); dbDelta($sql); } // create links_access table if it doesn't exist if ( $wpdb->get_var("SHOW TABLES LIKE '$this->links_access_table';") != $this->links_access_table ) { $sql = "CREATE TABLE $this->links_access_table (" . 'link_ID BIGINT NOT NULL, ' // why exactly is link_id not UNSIGNED? . 'role VARCHAR(127) NOT NULL, ' . 'edit ENUM("Yes", "No") NOT NULL, ' . 'read_list ENUM("Yes", "No") NOT NULL, ' . 'INDEX (link_ID, role)' . ');' ; require_once(ABSPATH . 'wp-admin/upgrade-functions.php'); dbDelta($sql); } // rebuild posts_access table (in case there are old categories_access rules) $this->build_posts_access(); // rebuild links_access table (for the same reason) $this->build_links_access(); } function build_posts_access($specific_post_id = NULL) { global $wpdb, $wp_version; // nix rows to be replaced if ( isset($specific_post_id) ) { $wpdb->query("DELETE FROM $this->posts_access_table WHERE post_ID=$specific_post_id;"); } else { // nix *every* row if we're rebuilding access rules for all posts $wpdb->query("DELETE FROM $this->posts_access_table;"); } // look up which roles have categories_access rules $sql = "SELECT role FROM $this->categories_access_table GROUP BY role;"; $ruled_roles = (array) $wpdb->get_col($sql); // for each of those roles, derive posts_access rules // note: posts_access.edit is derived from categories_access.postto, treating "No" like "Block" // because it would generally create a mess to allow editing access to a user who only has // posting access in some of the categories where a post has already been placed foreach ($ruled_roles as $this_role) { if ( $wp_version < 2.3 ) { $sql = "INSERT INTO $this->posts_access_table SELECT $wpdb->post2cat.post_id AS post_ID, '$this_role' AS role, IF( BIT_AND( IF(postto IS NULL OR postto='Yes',1,0) ) = 1, 'Yes', 'No' ) AS edit, IF( BIT_AND( IF(read_home IS NULL OR read_home='Yes',1,IF(read_home = 'Block',0,NULL)) ) = 1, 'Yes', 'No' ) AS read_home, IF( BIT_AND( IF(read_list IS NULL OR read_list='Yes',1,IF(read_list = 'Block',0,NULL)) ) = 1, 'Yes', 'No' ) AS read_list, IF( BIT_AND( IF(read_feed IS NULL OR read_feed='Yes',1,IF(read_feed = 'Block',0,NULL)) ) = 1, 'Yes', 'No' ) AS read_feed, IF( BIT_AND( IF(read_single IS NULL OR read_single='Yes',1,IF(read_single = 'Block',0,NULL)) ) = 1, 'Yes', 'No' ) AS read_single FROM $wpdb->post2cat LEFT JOIN $this->categories_access_table ON ( $this->categories_access_table.category_ID = $wpdb->post2cat.category_id AND role = '$this_role' ) WHERE " . ( isset($specific_post_id) ? "$wpdb->post2cat.post_id = '$specific_post_id'" : '1=1' ) . " GROUP BY post_ID;"; } else { $sql = "INSERT INTO $this->posts_access_table SELECT t1.object_id AS post_ID, '$this_role' AS role, IF( BIT_AND( IF(t2.postto IS NULL OR t2.postto='Yes',1,0) ) = 1, 'Yes', 'No' ) AS edit, IF( BIT_AND( IF(t2.read_home IS NULL OR t2.read_home='Yes',1,IF(t2.read_home = 'Block',0,NULL)) ) = 1, 'Yes', 'No' ) AS read_home, IF( BIT_AND( IF(t2.read_list IS NULL OR t2.read_list='Yes',1,IF(t2.read_list = 'Block',0,NULL)) ) = 1, 'Yes', 'No' ) AS read_list, IF( BIT_AND( IF(t2.read_feed IS NULL OR t2.read_feed='Yes',1,IF(t2.read_feed = 'Block',0,NULL)) ) = 1, 'Yes', 'No' ) AS read_feed, IF( BIT_AND( IF(t2.read_single IS NULL OR t2.read_single='Yes',1,IF(t2.read_single = 'Block',0,NULL)) ) = 1, 'Yes', 'No' ) AS read_single FROM $wpdb->term_relationships t1 LEFT JOIN $this->categories_access_table t2 ON ( t2.category_ID = t1.term_taxonomy_id AND t2.role = '$this_role' ) WHERE " . ( isset($specific_post_id) ? "t1.object_id = '$specific_post_id'" : '1=1' ) . " GROUP BY post_ID;"; } $wpdb->query($sql); } // note: It is necessary to generate posts_access rules for *every* post for each role that has any // categories_access rules at all, because it is impossible to predict which posts would be affected by // any given categories_access rule. However, for any role with *no* categories_access rules, there // is no need for any posts_access rules because all posts are assumed to have no restrictions on access // by default. } function build_links_access($specific_link_id = NULL) { global $wpdb, $wp_version; // nix rows to be replaced if ( isset($specific_link_id) ) { $wpdb->query("DELETE FROM $this->links_access_table WHERE link_ID=$specific_link_id;"); } else { // nix *every* row if we're rebuilding access rules for all links $wpdb->query("DELETE FROM $this->links_access_table;"); } // look up which roles have categories_access rules $sql = "SELECT role FROM $this->categories_access_table GROUP BY role;"; $ruled_roles = (array) $wpdb->get_col($sql); // for each of those roles, derive links_access rules (see notes under function build_posts_access) foreach ($ruled_roles as $this_role) { if ( $wp_version < 2.3 ) { $sql = "INSERT INTO $this->links_access_table SELECT $wpdb->link2cat.link_id AS link_ID, '$this_role' AS role, IF( BIT_AND( IF(postto IS NULL OR postto='Yes',1,0) ) = 1, 'Yes', 'No' ) AS edit, IF( BIT_AND( IF(read_list IS NULL OR read_list='Yes',1,IF(read_list = 'Block',0,NULL)) ) = 1, 'Yes', 'No' ) AS read_list FROM $wpdb->link2cat LEFT JOIN $this->categories_access_table ON ( $this->categories_access_table.category_ID = $wpdb->link2cat.category_id AND role = '$this_role' ) WHERE " . ( isset($specific_link_id) ? "$wpdb->link2cat.post_id = '$specific_link_id'" : '1=1' ) . " GROUP BY link_ID;"; } else { $sql = "INSERT INTO $this->links_access_table SELECT t1.object_id AS link_ID, '$this_role' AS role, IF( BIT_AND( IF(t2.postto IS NULL OR t2.postto='Yes',1,0) ) = 1, 'Yes', 'No' ) AS edit, IF( BIT_AND( IF(t2.read_list IS NULL OR t2.read_list='Yes',1,IF(t2.read_list = 'Block',0,NULL)) ) = 1, 'Yes', 'No' ) AS read_list FROM $wpdb->term_relationships t1 LEFT JOIN $this->categories_access_table t2 ON ( t2.category_ID = t1.term_taxonomy_id AND t2.role = '$this_role' ) WHERE " . ( isset($specific_link_id) ? "t1.post_id = '$specific_link_id'" : '1=1' ) . " GROUP BY link_ID;"; } $wpdb->query($sql); } } function endow_category_access($category_id) { // adds categories_access rules for a (new) category, if it has an ancestor with inheritable rules global $wpdb; $ancestor_ids = $this->category_ancestors($category_id); $roles_ruled = array(); // A category may inherit different rules for different roles from different ancestors! // BUT, it may only have one set of rules for any given role $inheritable_rules = array(); $categories_access_inheritable = $wpdb->get_results( "SELECT * FROM $this->categories_access_table WHERE inheritence='On' ORDER BY category_ID, role" ); foreach ($categories_access_inheritable as $inheritable_rule) { if ( !isset($inheritable_rules[$inheritable_rule->category_ID]) ) $inheritable_rules[$inheritable_rule->category_ID] = array() // does PHP actually require me to do this? perhaps not, but I miss Perl anyway ; $inheritable_rules[$inheritable_rule->category_ID][] = $inheritable_rule; } foreach ($ancestor_ids as $ancestor_id) { if ( is_array($inheritable_rules[$ancestor_id]) ) { // this ancestor can be inherited from foreach ($inheritable_rules[$ancestor_id] as $ancestor_category_access) { // foreach inheritable rule of this ancestor category if ( !isset($roles_ruled[$ancestor_category_access->role]) ) { // this role doesn't already have inherited rules $sql = "INSERT INTO $this->categories_access_table SET category_ID = '$category_id', role = '$ancestor_category_access->role', inheritence = 'Off', postto_default = 'No', postto = '$ancestor_category_access->postto', read_home = '$ancestor_category_access->read_home', read_list = '$ancestor_category_access->read_list', read_feed = '$ancestor_category_access->read_feed', read_single = '$ancestor_category_access->read_single' ;" ; $wpdb->query($sql); $roles_ruled[$ancestor_category_access->role] = 1; // just one inherited rule per role, thank you } } } } } function category_ancestors($category_id) { // recursive function to gather all ancestor category_ids in reverse hierarchical order $category_object = get_category($category_id); $category_parent_id = $category_object->category_parent; if ( $category_parent_id > 0 ) { return array_merge( array($category_parent_id), $this->category_ancestors($category_parent_id) ); } else { return array(); } } function destroy_category_access($category_id) { // remove all categories_access rules for given category_id, and rebuild posts_access // note: we can't be selective about rebuilding posts_access, because the only hook // for category deletion comes after post2cat has been updated global $wpdb; $sql = "DELETE FROM $this->categories_access_table WHERE category_ID='$category_id';"; $wpdb->query($sql); // even if there were no access rules for this category_id, it is possible for posts_access // rules to have changed, so we have to rebuild them in any case (same for links_access) $this->build_posts_access(); $this->build_links_access(); } /* end methods to maintain abc database tables */ /* methods to retrieve access rules */ /*function load_auto_tree_access() { // load options for automating access granting to new categories according to their ancestry $abc_auto_tree_access = get_option('abc_auto_tree_access'); $this->auto_tree_access = ( isset($abc_auto_tree_access) ? $abc_auto_tree_access : array() ); }*/ function load_categories_access() { // load categories_access rules for the current user's role if ( isset($this->categories_access) ) // this only needs to be done once return ; global $wpdb; $role = $this->current_user_role(); $categories_access = array(); $sql = "SELECT * FROM $this->categories_access_table WHERE role='$role';"; $r = $wpdb->get_results($sql); foreach ($r as $record) { $categories_access[$record->category_ID] = $record; } $this->categories_access = $categories_access; } function load_posts_access() { // load posts_access rules for the current user's role if ( isset($this->posts_access) ) // this only needs to be done once return ; global $wpdb; $role = $this->current_user_role(); $posts_access = array(); $sql = "SELECT * FROM $this->posts_access_table WHERE role='$role';"; $r = $wpdb->get_results($sql); foreach ($r as $record) { $posts_access[$record->post_ID] = $record; } $this->posts_access = $posts_access; } function load_links_access() { // load links_access rules for the current user's role if ( isset($this->links_access) ) // this only needs to be done once return ; global $wpdb; $role = $this->current_user_role(); $links_access = array(); $sql = "SELECT * FROM $this->links_access_table WHERE role='$role';"; $r = $wpdb->get_results($sql); foreach ($r as $record) { $links_access[$record->link_ID] = $record; } $this->links_access = $links_access; } function load_comments_access() { // load comments_access rules for the current user's role if ( isset($this->comments_access) ) // this only needs to be done once return ; global $wpdb; $role = $this->current_user_role(); $comments_access = array(); $sql = "SELECT * FROM $wpdb->comments LEFT JOIN $this->posts_access_table ON $this->posts_access_table.post_ID=$wpdb->comments.comment_post_ID WHERE $this->posts_access_table.role='$role';" ; $r = $wpdb->get_results($sql); foreach ($r as $record) { $comments_access[$record->comment_ID] = $record; } $this->comments_access = $comments_access; } function get_postto_disallowed() { $this->load_categories_access(); // first, make sure categories access rules have been loaded $postto_disallowed = array(); foreach ($this->categories_access as $category_access) { if ( 'No' == $category_access->postto ) $postto_disallowed[] = $category_access->category_ID ; } return $postto_disallowed; } function load_postto_allowed() { global $wpdb; //$all_category_IDs = (array) $wpdb->get_col("SELECT cat_ID FROM $wpdb->categories GROUP BY cat_ID;"); //$this->postto_allowed = array_diff( $all_category_IDs, $this->get_postto_disallowed() ); $this->postto_allowed = array_diff( get_all_category_ids(), $this->get_postto_disallowed() ); } function get_postto_defaults() { // return an array of any categories that should be checked by default // when this user starts a new post $this->load_categories_access(); // first, make sure categories access rules have been loaded $postto_defaults = array(); foreach ($this->categories_access as $category_access) { if ( 'Yes' == $category_access->postto_default ) $postto_defaults[] = $category_access->category_ID ; } return $postto_defaults; } /* end methods to retrieve access rules */ /* methods for hooks (actions and filters) */ function admin_head($unused) { // because WP lacks hooks for filtering category lists in administrative pages, // we have to buffer the entire page with a callback to search for the categories // list and replace it with a filtered list // buffer this admin page and invoke the appropriate callback if(preg_match('#/wp-admin/(post(-new)?)|(link(-add)?).php#i', $_SERVER['REQUEST_URI'])) { // this page is a post or link editor ob_start(array(&$this, 'ob_callback_editor')); } elseif (preg_match('|/wp-admin/link-manager.php|i', $_SERVER['REQUEST_URI'])) { // this page is Blogroll->Manage Blogroll ob_start(array(&$this, 'ob_callback_link_manager')); } elseif ( preg_match('|/wp-admin/index.php|i', $_SERVER['REQUEST_URI']) || preg_match('|/wp-admin/$|i', $_SERVER['REQUEST_URI']) ) { // this page is Dashboard ob_start(array(&$this, 'ob_callback_dashboard')); } elseif (preg_match('|/wp-admin/edit-comments.php\?mode=edit|i', $_SERVER['REQUEST_URI'])) { // this page is comment mass edit ob_start(array(&$this, 'ob_callback_comment_mass_edit')); } elseif (preg_match('|/wp-admin/edit-comments.php(\?mode=view)?|i', $_SERVER['REQUEST_URI'])) { // this page is comment view ob_start(array(&$this, 'ob_callback_comment_view')); } // output special style rules for admin panel if(preg_match('#/wp-admin/users.php\?page='.$this->abc_path.'#i', $_SERVER['REQUEST_URI'])) { $this->admin_page_style(); } } function admin_menu() { add_submenu_page('users.php', __('Access By Categories'), __('Access By Category'), 'edit_users', $this->plugin_basename(), array(&$this, 'admin_page') ); } function category_save_pre($categories_checked) { // filter checked categories when a post is saved if( !is_array($categories_checked) ) $categories_checked = array(); ; $categories_checked = array_diff( $categories_checked, $this->get_postto_disallowed() ); if ( count($categories_checked) > 0 ) { return($categories_checked); } else { return( $this->get_postto_defaults() ); } } function save_post($post_id) { // post has been created or updated, so we need to (re-)build posts_access rules for its post_id $this->build_posts_access($post_id); return($post_id); } function add_category($category_id) { // new category has been created, so we need to check for categories_access // rules it may automatically inherit from an ancestor $this->endow_category_access($category_id); return($category_id); } function delete_category($category_id) { // category has been removed, so we need to update access rules accordingly $this->destroy_category_access($category_id); return($category_id); } function restrict_manage_posts($unused = NULL) { // screen out posts from Manage->Posts global $posts; $this->load_posts_access(); $posts = is_array($posts) ? array_values($posts) : array(); for ($i = 0; $i < count($posts); $i++) { if ( isset( $this->posts_access[ $posts[$i]->ID ] ) && $this->posts_access[ $posts[$i]->ID ]->read_list != 'Yes' ) { // this post is not supposed to be listed for this user array_splice($posts, $i, 1); // so hide it $i--; // set index back, now that array has been spliced } } return($unused); } function user_has_cap() { // give specific answers to user-capability questions with respect to post/category access $role = $this->current_user_role(); list($caps_user_has, $caps_user_needs, $args) = func_get_args(); if ( 'edit_post' == $args[0] || 'delete_post' == $args[0] ) { // Q: can current user edit or delete a particular post? $this->load_posts_access(); // make sure posts_access rules are loaded $post_id_in_question = $args[2]; if ( isset($this->posts_access[$post_id_in_question]) && 'Yes' != $this->posts_access[$post_id_in_question]->edit ) { // this user is not permitted to edit the post in question return array(); // so disempower the user (strip all capabilities) in this case } } elseif ( 'read_post' == $args[0] ) { // Q: can current user read a particular post? $this->load_posts_access(); // make sure posts_access rules are loaded $post_id_in_question = $args[2]; if ( isset($this->posts_access[$post_id_in_question]) && 'Yes' != $this->posts_access[$post_id_in_question]->read_single ) { // this user is not permitted to read the post in question return array(); // so disempower the user (strip all capabilities) in this case } } elseif ( 'read_category' == $args[0] ) { // Q: can current user read from a particular category? $this->load_categories_access(); // make sure categories_access rules are loaded $category_id_in_question = $args[2]; if ( !isset($this->categories_access[$category_id_in_question]) || 'Yes' == $this->categories_access[$category_id_in_question]->read_list ) { // this user *is* permitted to list the category in question $caps_user_has['read_category'] = 1; // so add 'read_category' to user's capabilities } } elseif ( 'post_to_category' == $args[0] ) { // Q: can current user post to a particular category? $this->load_categories_access(); // make sure categories_access rules are loaded $category_id_in_question = $args[2]; if ( !isset($this->categories_access[$category_id_in_question]) || 'Yes' == $this->categories_access[$category_id_in_question]->postto ) { // this user *is* permitted to post to the category in question $caps_user_has['post_to_category'] = 1; // so add 'post_to_category' to user's capabilities } } return $caps_user_has; } function posts_join($sql_join) { // when querying posts, we need to join in posts_access rules global $wpdb, $pagenow; $role = $this->current_user_role(); if ( 'edit.php' == $pagenow || 'edit-pages.php' == $pagenow || 'upload.php' == $pagenow ) return $sql_join // we don't mess with the query for admin pages ; $sql_join .= " LEFT JOIN $this->posts_access_table ON ($this->posts_access_table.post_ID=$wpdb->posts.ID AND $this->posts_access_table.role='$role')"; return $sql_join; } function posts_where($sql_where) { // filter out access-denied posts from query global $pagenow; if ( 'edit.php' == $pagenow || 'edit-pages.php' == $pagenow || 'upload.php' == $pagenow ) return $sql_where // we don't mess with the query for admin pages ; $sql_where_common .= "$this->posts_access_table.post_ID IS NULL"; $sql_where_staticpage .= "post_status='static'"; if ( is_archive() || is_search() ) { $sql_where .= " AND ($this->posts_access_table.read_list='Yes' OR $sql_where_common OR $sql_where_staticpage)"; } elseif ( is_single() ) { $sql_where .= " AND ($this->posts_access_table.read_single='Yes' OR $sql_where_common OR $sql_where_staticpage)"; } elseif ( is_feed() ) { $sql_where .= " AND ($this->posts_access_table.read_feed='Yes' OR $sql_where_common)"; } elseif ( is_home() ) { $sql_where .= " AND ($this->posts_access_table.read_home='Yes' OR $sql_where_common OR $sql_where_staticpage)"; } return $sql_where; } function get_bookmarks($bookmarks, $display_options) { // filter bookmarks list by links_access rules for this user if ( !is_array($bookmarks) ) return $bookmarks ; $this->load_links_access(); // make sure links_access rules are loaded $bookmarks = array_values($bookmarks); // reset numerical keys for ($i = 0; $i < count($bookmarks); $i++) { $link_id = $bookmarks[$i]->link_id; if ( isset( $this->links_access[$link_id] ) && $this->links_access[$link_id]->read_list != 'Yes' ) { // this user is not supposed to see this link/bookmark array_splice($bookmarks, $i, 1); // so remove it $i--; // set index back, now that array has been spliced } } return $bookmarks; } function get_categories($categories, $options) { // filter categories listby categories_access rules for this user if ( !is_array($categories) ) return $categories ; global $pagenow; $this->load_categories_access(); // make sure categories_access rules are loaded $categories = array_values($categories); // reset numerical keys for ($i = 0; $i < count($categories); $i++) { $category_id = $categories[$i]->cat_ID; $category_access = $this->categories_access[$category_id]; if ( isset($category_access) && ( ( 'link-import.php' == $pagenow && 'Yes' != $category_access->postto ) // for link-import page we're concerned with which categories can be posted to || 'Yes' != $category_access->read_list ) ) { // this user is not supposed to see this category array_splice($categories, $i, 1); // so remove it $i--; // set index back, now that array has been spliced } } return $categories; } /* end methods for hooks (actions and filters) */ /* methods for post/link editor */ function ob_callback_editor($content) { $content = preg_replace_callback('/