Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm working on new project and I want to let users have access to create pages on the site. To prevent users from "spamming" a lot of pages, I'd like to set a daily upload limit for each user. I've posted the code I'm using below but I'm not able to cancel the page upload because the event is being fired after a page has been created and added to the database. Worst case scenario, I can search the database and delete the document they just created but I don't think that that's the best solution. Is there a hook similar to pre_post_update that I can use to check and or cancel the page from being uploaded? If there isn't a hook I can use, is there a better way to solve this problem?

add_action( 'save_post', 'check_post_limit' );

function check_post_limit( $post_id ) {
global $userdata;
global $post_type;
global $wpdb;
if( $userdata->ID != 1) {
    $post_count = $wpdb->get_var( "SELECT count(*) FROM $wpdb->posts WHERE DATE(post_modified) = DATE(NOW()) AND post_author = $userdata->ID" );
}
if( $post_count > 3 ) {
    wp_die(); //will not work because page is already in the database
}
}
share|improve this question
    
My initial thoughts go to changing their roles somehow. Why let them "add new page" at all if their limit has been met? Look into maybe trying to make them fail the check for current_user_can('publish_pages'). Is it dirty to edit a user's permissions frequently? Plugin like Role Scoper might be worth investigating. –  GhostToast Jun 2 '13 at 18:31

2 Answers 2

up vote 0 down vote accepted

You will need to interrupt the post submission process much sooner. Your code hooked to admin_init stands a pretty good chance of working, with a modification or two, and wp_die is pretty harsh. I'd just redirect back to the originating page without saving, if it were me.

Something like (untested)...

function check_post_limit() {
  if (!isset($_POST['ID'])) return;

  global $wpdb;

  if( $userdata->ID != 1) {
    $post_count = $wpdb->get_var( "SELECT count(*) FROM $wpdb->posts WHERE   DATE(post_modified) = DATE(NOW()) AND post_author = $userdata->ID" );
  }

  if( isset($post_count) && $post_count > 3 ) {
    wp_safe_redirect(admin_url('post.php?post='.$_POST['post_ID'].'&action=edit'));
    exit;
  }
}

A couple of notes:

  1. Your code as written would have thrown a notice for the user with ID == 1 because $post_count would not be set.
  2. Checking for user ID == 1 is questionable. Suppose your admin (which is what I assume you want) has some other ID (and for security it is probably a good idea to have your admin have some other ID). I'd write the check based on user role instead.
share|improve this answer
    
Thanks for the heads up on the ID == 1 check. I really appreciate the code sample. Why is it a bad idea for security if your admin ID is 1? –  Jordan Jun 2 '13 at 20:31
    
Because even an amateur hacker would know that the first user is ID == 1, and that that user is the one created by WordPress at installation and so would be an admin, at least when it was first created. That provides a little bit of leverage when trying to exploit the database. You don't have to guess at a username if you can find a way to use the user ID instead. It may not be much but it could be something. –  s_ha_dum Jun 2 '13 at 20:41
    
Okay thanks. I just wanted to make sure that there wasn't any major security risk for it. Security through obscurity :) –  Jordan Jun 2 '13 at 20:46
    
"Security through obscurity" is depending upon secrecy for security. It is not to be confused with Defense in depth. –  s_ha_dum Jun 2 '13 at 23:38
    
True. Thanks again for the help! –  Jordan Jun 3 '13 at 21:10

maybe you could do it via user roles, like this:

function check_post_limit() {
  global $wpdb;

$author = wp_get_current_user();    

$post_count = $wpdb->get_var( "SELECT count(*) FROM $wpdb->posts WHERE   DATE(post_modified) = DATE(NOW()) AND post_author = $userdata->ID" );

  if( isset($post_count) && $post_count > 3  && current_user_can('contributor') ) {
   $author->remove_role( 'contributor' );
   $author->add_role( 'subscriber' );
  }

  if( isset($post_count) && $post_count < 3  && current_user_can('subscriber') ) {
   $author->remove_role( 'subscriber' );
   $author->add_role( 'contributor' );
  }

}

add_action('publish_post', 'check_post_limit');
add_action('wp_login', 'check_post_limit');

note: this is absolutely untested.

the idea is pretty much from here: http://stackoverflow.com/questions/9181440/wordpress-change-user-role-conditionally

share|improve this answer
    
Thank you for your post. I think I'm going to combine the role change with s_ha_dum's answer. –  Jordan Jun 2 '13 at 20:35

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.