Wordpress, filter pages in Admin edit screen - wordpress

Is it possible to 'filter' which pages are shown in the 'edit' screen for pages ( http://cl.ly/6nLC ) in Wordpress? I have looked in the action / hook section of Wordpress for plugin developers but I could not find any.
What I am trying to accomplish is is that certain users can edit certain pages (and child pages) and other persons cannot edit those pages but might be able to edit other pages.
I have allready written a plugin which makes it possible to put different users in differtent groups, which now just needs to have different rights, which user is member of which group is stored in the user_meta table.
However if there is 'any' filter hook / method for this, can someone point this out, I think I will be able to go further from there.
Kind regards.

You can use a posts_where filter to add a condition to the SQL query to filter out some pages. A load-{filename} action can be used to ensure the filter is only applied when managing pages.
add_action('load-edit.php', 'my_load_edit_php_action');
function my_load_edit_php_action() {
if ($_GET['post_type'] !== 'page') return;
add_filter('posts_where', 'my_posts_where_filter');
}
function my_posts_where_filter($sql) {
if (current_user_can('your_capability')) {
global $wpdb;
$sql = " AND $wpdb->posts.ID NOT IN (1,2,3)" . $sql;
}
return $sql;
}

Related

Redirect Custom Admin Role - Wordpress

I've defined a custom role in Woocommerce. This user ONLY needs access to urls to edit shop_orders and inspect individual shop orders. Like:
/wp-admin/edit.php?post_type=shop_order
/wp-admin/post.php?post=124&action=edit
/wp-admin/post-new.php?post_type=shop_order
If they go anywhere else I want to redirect them to:
/wp-admin/edit.php?post_type=shop_order
In effect they should only see orders, modify orders, and create orders. I've added all the right permissions for this, and modified the menus drastically so they can't see 'products', 'my profile', etc. However, if they accessed some links directly they would still load (the 'dashboard' for one and 'my settings'). Removing them from dashboard != removing access to them.
I'm trying to harden my security a bit by redirecting on everything except a few whitelisted routes with wildcards. Any thoughts on how to approach? Thanks.
This sounds like something you may be able to do with this filter:
https://codex.wordpress.org/Plugin_API/Filter_Reference/user_has_cap
My understanding of it is that when wordpress queries whether or not the user has the capability to do something on the site e.g. edit_posts, then you can apply further logic (in your example, checking whether or not their role is the custom role you defined) to decide to restrict or enhance that capability if you wish. In your case, if the user didn't meet your criteria (they are not requesting a pre-defined page), you could redirect.
Quick proof of concept (I think):
function only_let_user100_see( $allcaps, $cap, $args ) {
if($args[0] === 'edit_posts' && is_admin()) {
if(get_current_user_id() !== 100) {
echo "No way";
exit;
}
} else {
return $allcaps;
}
}
add_filter( 'user_has_cap', 'only_let_user100_see', 10, 3 );

Add specific words to WordPress custom type slug

I have a WordPress installation with a custom type (places) wich produces this permalink structure:
http://example.com/places/the-first-site/
And I would like to show all my sites like this:
http://example.com/places/visit-the-first-site-and-enjoy/
where 'visit' and 'and-enjoy' would be always those specific words (constants).
Even better I would like to put a custom taxonomy I have (year) as a metadata
places/visit-the-first-site-and-enjoy-1985/
I can access the DB and modify the post name of all post, but I would have to do for the new post also, and I'm looking for some automated rule, but can't find how to do.
Maybe some rewrite rule, but I don't know how to do it.
Any ideas??
You do not have to edit anything in your database nor any codes in your WordPress installation; you can achieve that directly from your WordPress administration panel.
From your Dashboard, click on the Permalink sub-menu under Settings; there, you will have to select the Custom Structure option and set it as follow in order to achieve your desired effect:
/places/visit-%postname%-and-enjoy-%year%/
Please note: here, we made use of both %postname% and %year% Structure Tags so as to get names of posts with their corresponding year of publication respectively.
Don't forget to click on the Save Changes button on the page in order to effect your changes.
... Read more on Permaklinks (for general knowledge).
For a custom post type and taxonomies as expressed further in comments, you will need a custom solution which will require a little bit of coding and or tweaking, depending on your abilities; you may use this handy plugin (Custom Post Type Permalinks) from the WordPress.org Plugins repository.
This posts should equally be of great help to you, to getting started and understanding further, should you chose to code.
You have différent hook like save_post or pending_to_publish, where you can set or change the "post_name" (that's corresponds to the permalink slug).
To Add specific words to WordPress custom type slug You have to Register custom rewrite rules.
suppose this is Your URL http://example.com/places/the-first-site !
and you have a post type places.
function add_rewrite_rules()
{
$wp_rewrite->add_rewrite_tag('%places%', '([^/]+)', 'places=');
$wp_rewrite->add_rewrite_tag('%state%', '([^/]+)', 'state=');
$wp_rewrite->add_permastruct('places', 'places/visit-%state%-and-enjoy/', false);
}
function permalinks($permalink, $post, $leavename)
{
$no_data = 'no-data';
$post_id = $post->ID;
if($post->post_type != 'story' || empty($permalink) || in_array($post->post_status, array('draft', 'pending', 'auto-draft')))
return $permalink;
$state = get_post_meta($post_id, 'location', true);
if(!$state)
$state = $no_data;
$permalink = str_replace('%state%', $state, $permalink);
return $permalink;
}
add_action('init', 'add_rewrite_rules');
add_filter('post_type_link', 'permalinks', 10, 3);
put this code in your custom post type plugin. and if get page not found error please change your permalink setting. or make a custom template file to show this post.

ACF - Options page Hook (Wordpress)

I am really making a huge use of ACF's options pages and repeater fields.
In order to reduce the amount of queries (from about 500 to 80) I'm caching some field outputs with the help of Wordpress Transient API.
I know the hook for ACF options pages is:
add_action( 'acf/save_post', 'reference_function') );
But the problem for me is, that I have multiple options pages. And I don't want all my functions to run when any options page is saved…
These are my current options pages
add_filter('acf/options_page/settings', 'my_acf_options_page_settings');
if(function_exists("register_options_page")) {
acf_add_options_page();
register_options_page('Spielübersicht');
register_options_page('Mannschaft');
register_options_page('SCHWALBE arena TV');
register_options_page('Sponsoren');
register_options_page('Werbung');
register_options_page('Einstellung');
register_options_page('Fanclubs');
register_options_page('Sidebar');
}
Is there a way to filter the action so that my transients are only created when the related options page is saved?
Luckily I was able to solve my problem!
Have a look at my code in the plugins’ support forum:
http://support.advancedcustomfields.com/forums/topic/acfsave_post-for-specific-options-page/
function clear_advert_main_transient() {
$screen = get_current_screen();
if (strpos($screen->id, "acf-options-adverts") == true) {
delete_transient('advert_main_transient1');
delete_transient('advert_main_transient2');
delete_transient('advert_main_transient3');
}
}
add_action('acf/save_post', 'clear_advert_main_transient', 20);

Remove screen options tab if not admin

As the title suggests, I am looking for a way to remove the screen options tab in the post/page editor screen. I have found the following...
function remove_screen_options(){ __return_false;}
add_filter('screen_options_show_screen', 'remove_screen_options');
...but it removes the tab for all users. I would like to keep it for admins.
Regards,
John
Found the answer after collaboration of all of your efforts. Thank you.
get_currentuserinfo() ;
global $user_level;
function remove_screen_options(){ __return_false;}
if( $user_level <= 8 ) add_filter('screen_options_show_screen', 'remove_screen_options');
If you place the following snippet of code into your functions.php file, the Screen Options tab will disappear across the whole backend for all users except the admin. Having said that, it is a good practice to modify the php file of your child theme.
functions.php code:
function remove_screen_options_tab()
{
return current_user_can('manage_options' );
}
add_filter('screen_options_show_screen', 'remove_screen_options_tab');
You just need to conditionally check if the current user is an admin. If they aren't, then remove the screen options like so:
if ( !is_admin() ) {
function remove_screen_options(){ __return_false;}
add_filter('screen_options_show_screen', 'remove_screen_options');
}
Here are the official Wordpress docs detailing this function: http://codex.wordpress.org/Function_Reference/is_admin
Using capabilities the way Spencer suggests is usually the best method.
I'm thinking most people find roles & capabilities to be overly confusing. Using the actual user role with 'current_user_can' is more often than not your best bet for this or any other similar 'permission' based situation.
More often than not you will eventually end up adding/removing capabilities for a specific role, so if you ever give someone else the 'manage_options' capability, like perhaps the owner of the business, you all of a sudden gave them back the screen options as well (On a side note 'activate_plugins' is usually safe since it is only for someone that has level 10 access). You can check out all permissons on the User Level Capability Table at the bottom of the page to get a better grasp on it all.
Insert this in functions php:
if( !current_user_can('administrator') ) {
// hide screen options for everyone but the admin
add_filter('screen_options_show_screen', 'remove_screen_options_tab');
}
if( current_user_can('administrator') ) {
// code here is shown to the admin
}
Following this format you can do the same thing with other roles. Also you dont have is change administrator to editor, author, contributor and subscriber, or any other roles you create.
Try this
if(!current_user_can('manage_options')) add_filter('screen_options_show_screen', 'remove_screen_options');
Use Adminimize, A WordPress plugin that lets you hide 'unnecessary' items from the WordPress backend.
http://wordpress.org/plugins/adminimize/
You're looking for the function current_user_can:
if( current_user_can( 'manage_options' ) ) {
// executes when user is an Administrator
}
Here's the CSS method for all the designers who rather stay away from php. It hooks into the admin_body_class and adds user-{role} as a body class.
functions.php code:
function hide_using_css_user_role( $classes ) {
global $current_user;
foreach( $current_user->roles as $role )
$classes .= ' user-' . $role;
return trim( $classes );
}
add_filter( 'admin_body_class', 'hide_using_css_user_role' );
Using this you can hide/show anything on the admin side per user role. In this case just use the :not css selector to make sure it's only hidden for non-admins.
function add_my_custom_user_css() {
ob_start(); ?>
<style type="text/css">
:not(.user-administrator) #screen-options-link-wrap,
:not(.user-administrator) #contextual-help-link-wrap  {
display:none !important;
}
</style>
<?php
echo ob_get_clean();
}
add_action ( 'admin_head', 'add_my_custom_user_css', 999);
This is a pretty hacky way to do things but sometimes good for a temporary quick fix when you don't know the correct filter/action to hide or change things in wordpress. Adding the 999 will make sure it gets loaded at the end of the head tag. Note that it's only hiding using css, so don't use this for anything vitally important, because the code is still visible in the source file.
To remove it from the source use jquery instead. Just replace the styles above with the following:
<script type="text/javascript">
jQuery(document).ready(function($)) {
$( ":not(.user-administrator) #screen-options-link-wrap" ).remove();
}
</script>
'admin_body_class' already does us the favor of adding the page to body class, so to target specific pages as well, just check the source code and in the body tag you can see the current page. So for example, the dashboard uses .index-php. Just attach that to .user-administrator or whatever user you're targeting and you can customize the admin for any user just using css and javascript.

How to make a plugin to count visitors for posts under specific category

How to count number of visitors for post under specific category ? Can I make such plugin who can do the whole magic ? I don't want plugin users to modify theme files or add code snippets in other theme files ...
something along the lines of adding to the post meta could do what you're wanting.
<?php
add_action('the_content', 'myplugincb');
function myplugincb() {
global $wp_query;
if (count($wp_query->posts) == 1) { //just do this for individual posts/pages
$pid = $wp_query->posts[0]->ID;
$key = 'myplugin_post_visit_counter';
update_post_meta($pid, $key, get_post_meta($pid, $key)+1);
}
}
function myplugin_show_viewed($post_id) {
return get_post_meta($post_id, 'myplugin_post_visit_counter');
}
You'd have to change that quite a few different ways depending on your desired result. You probably want to use something like Google Analytics if you're wanting to see specifics on pages visited and where the user came from etc.

Resources