WordPress.org

Support

Support » Plugins and Hacks » Hacks » Only Admins and the post author can view a post, is it possible?

Only Admins and the post author can view a post, is it possible?

  • Hello,

    I have a site where my clients click on New Order icon then fill up some form (jquery) and this order will be consider as a post so the orders look like this:

    http://www.mysite.com/order-1
    http://www.mysite.com/order-2
    http://www.mysite.com/order-3
    http://www.mysite.com/order-3

    Now, everyone could see the order details by pasting the links above in their browsers. I want to restrict the post visibility to admins and the client only, I know there’s a way to keep posts password restricted by a password, but I wonder if it’s possible to have only the admin and logged in client see his/her order for example :
    http://www.mysite.com/order-2

    I try to find an available plug in but I could not find any. my question is, is it difficult t make? and how much it would usually cost to make a customized plug in like that.

    Thanks
    A

Viewing 15 replies - 1 through 15 (of 37 total)
  • bcworkz
    Participant

    @bcworkz

    Assuming the clients must be logged in to see anything and their user ID is associated with the post, either as author or stored in postmeta or something, then any template that outputs content just needs to have a conditional statement added so output only occurs if the user matches the data or if the user has a certain capability, such as edit_others_posts. This could also be done by filtering the content from a plugin.

    I don’t know what the going rates are, and I’m not offering to do such work for pay, but I would expect this to take less than hour (even a few minutes!) to achieve basic functionality, though it could take several hours or more to come up with a fully functional and secure system. The time required largely depends on your precise needs, what theme you have and how your forms are currently setup.

    If my assumptions are all correct, I’ll give you a quick and dirty plugin that just blocks the content unless the user ID matches something or has edit_others_posts capability. Just tell me how/where the user ID is stored. No guarantees it’s really secure, but it will resist casual probing.

    Hi Bcworkz …

    Thanks a lot for your thought, really appreciate it. A quick plugin will be gret for the time being, as I plan to update the whole site in 6 months.

    I use Bizway theme, I have 150 Subscribers ( Who can make a post by filling up the form below), and 5 Administrators:
    http://goo.gl/Bc8cpt

    In the site there is ( My Order page ) where every signed-in user can see a list their own posts ( order ), where admins can see all posts ( orders ) if they click in the ( My order Page )

    So, I’m hoping to get the content show if only the member created that post, or is one of the admins.

    I’m not sure if you need more info at this point, but please let me know if so. I’m not sure what you mean by “Just tell me how/where the user ID is stored” did I provide enough info?

    thanks

    bcworkz
    Participant

    @bcworkz

    Thanks for the info. I still need to know exactly where in the DB to find out which user is associated with each post. Are they the post author? Is it by a value stored in postmeta? If so, what is the key and what value is stored? ID? E-mail? Login?

    Sorry if these are difficult questions. Nothing is truly free 🙂 The advantage of hiring someone is they can poke around your site and figure this out. That level of access for complete strangers on this very public forum is very inappropriate here according to forum rules.

    Thank you, let me share some of the code with you that might show who the posts are created. So, in the ( Order.PHP ) page where members fill up a form and converted toa post, the first part of the codes is like this:

    <?php
    /*
      Template Name: Order Page
     */
    nocache_headers();
    global $wpdb, $current_user, $user_ID;
    $wpdb->hide_errors();
    
    // Get current User
    $this_user = wp_get_current_user();
    
    if(!is_user_logged_in()){
    	$author	=	2;
    }else{
    	$author	=	$this_user->ID;
    }
    
    $is_captcha 	= get_post_meta($post->ID, 'captcha', true);
    
    // Recaptcha
    require_once(ABSPATH . '/wp-content/themes/bizway/functions/recaptchalib.php');
    $publickey 	= "6LcUPugSAAAAAAri6obgNlMDYB1l4KTj0DAydZtf";
    $privatekey = "6LcUPugSAAAAAI3Yom_xO4ar2jxBPQJRwBsVwFSv";
    $resp = recaptcha_check_answer($privatekey, $_SERVER["REMOTE_ADDR"], $_POST["recaptcha_challenge_field"], $_POST["recaptcha_response_field"]);
    //echo recaptcha_get_html($publickey);
    
    // secure data
    // $order_id		=	rand();
    $order_name		=	$wpdb->escape(trim(wp_strip_all_tags($_POST['c_name'])));
    $oreder_email	=	$wpdb->escape(trim(wp_strip_all_tags($_POST['c_email'])));
    $oreder_country	=	$wpdb->escape(trim(wp_strip_all_tags($_POST['c_country'])));
    $order_address	=	$wpdb->escape(trim(wp_strip_all_tags($_POST['c_address'])));
    $oreder_info	=	$wpdb->escape(trim(wp_strip_all_tags($_POST['c_info'])));
    $oreder_payement=	$wpdb->escape(trim(wp_strip_all_tags($_POST['c_payement'])));
    
    // Products data

    There is also another order page.php and the first part of the code is:

    <?php
    /**
     * Template Name Posts: Orders Posts
    */
    nocache_headers();
    get_header();
    if (have_posts()) while (have_posts()) : the_post();
    
    			$order_status	= get_post_meta($post->ID, 'order_status', true);
    
    $order_payement_array = array(
    	'bank_transfer'	=> 'تحويل بنكي',
    	'paypal'		=> 'باي بال',
    	'western_union'	=> 'ويسترن يونيون',
    	'moneygram'		=> 'موني جرام',
    );
    $order_status_array = array(
    	0	=> 'بإنتضار التعليمات',
    	1	=> 'جاري التنفيد',
    	2	=> 'تــم التسليم',
    	3	=> 'طلب ملغي',
    );
    
    if (current_user_can('manage_options')){
    	$newstatus	=	intval(abs($_POST['o_status']));
    	if (isset($_POST['status']) && $_POST['status'] == 'update'  ) {
    		if (!array_key_exists($newstatus, $order_status_array)) {
    	         $error	= 'الرجاء إختيار الحالة من القامة المنسدلة أسفله !!';
    		}else{
    			if($order_status ==	''){
    				add_post_meta($post->ID, 'order_status', $newstatus);
    			}
    			update_post_meta($post->ID, 'order_status', $newstatus);
    			// wp_safe_redirect(get_permalink($post->ID));
    			$succee	= 'تم تغيير حالة الطلب بنجاح !';
    		}
    	}
    }
    			$order_id 		= $post->ID;
    			$order_name 	= get_post_meta($post->ID, 'order_name', true);
    			$order_email 	= get_post_meta($post->ID, 'order_email', true);
    			$order_payement = get_post_meta($post->ID, 'order_payement', true);
    			$order_url		= get_post_meta($post->ID, 'order_url', true);
    			$order_quatite	= get_post_meta($post->ID, 'order_quatite', true);
    			$order_info		= get_post_meta($post->ID, 'order_info', true);
    			$order_status	= get_post_meta($post->ID, 'order_status', true);
    
    			// Get Products

    There is ( View My Order ) page, there is a page made by PHP called orders_lists.php

    Here is the the code:

    `<?php
    /*
    Template Name: Orders Lists
    */
    get_header();
    $this_user = wp_get_current_user();

    if(isset($_GET[‘order_query’])){
    if(is_email($_GET[‘order_query’])){
    $get_order_query = $_GET[‘order_query’];
    }else{
    $error = “الرجاء إدخال بريد الإلكتروني صحيح !!”;
    $get_order_query = ‘no_mail’;
    }
    }else{
    $get_order_query = ‘no_mail’;
    }
    // get orders
    if (current_user_can(‘manage_options’)){
    $args = array(
    ‘showposts’ => 15,
    ‘offset’ => 0,
    ‘orderby’ => ‘post_date’,
    ‘order’ => ‘DESC’,
    // ‘author’ => $this_user->ID,
    ‘meta_key’ => ‘custom_post_template’,
    ‘meta_value’ => ‘templates/orders_postes.php’,
    ‘post_type’ => ‘post’,
    ‘paged’ => intval(abs(get_query_var(‘paged’))),
    ‘post_status’ => ‘publish’ );

    $page_title = “Order List Page”;
    // if user logged in
    }elseif(is_user_logged_in()){
    $args = array(
    ‘showposts’ => 10,
    ‘offset’ => 0,
    ‘orderby’ => ‘post_date’,
    ‘order’ => ‘DESC’,
    ‘author’ => $this_user->ID,
    ‘meta_key’ => ‘custom_post_template’,
    ‘meta_value’ => ‘templates/orders_postes.php’,
    ‘post_type’ => ‘post’,
    ‘paged’ => intval(abs(get_query_var(‘paged’))),
    ‘post_status’ => ‘publish’ );

    $page_title = get_the_title();
    // all vistors
    }else{
    $args = array(
    ‘showposts’ => 10,
    ‘offset’ => 0,
    ‘orderby’ => ‘post_date’,
    ‘order’ => ‘DESC’,
    // ‘author’ => $this_user->ID,
    // ‘meta_key’ => ‘custom_post_template’,
    // ‘meta_value’ => ‘templates/orders_postes.php’,
    ‘post_type’ => ‘post’,
    ‘meta_key’ => ‘order_email’,
    ‘meta_value’ => $get_order_query,
    ‘paged’ => intval(abs(get_query_var(‘paged’))),
    ‘post_status’ => ‘publish’ );
    if(isset($get_order_query) && is_email($get_order_query)){
    $page_title = “Orders List for [“.$get_order_query.”]”;
    }else{
    $page_title = “please enter your email: “;
    }
    }
    $order_query = query_posts($args);
    ?>
    <!–Start Page Heading –>
    <div class=”page-heading-container”>
    <div class=”container_24″>
    <div class=”grid_24″>
    <div class=”page-heading”>
    <h1><?php the_title(); ?></h1>
    </div>
    </div>
    <div class=”clear”></div>
    </div>
    </div>
    <!–End Page Heading –>
    <style>
    t_order tr, td{border: 0;}
    .btn_view {border-radius: 8px; color: white; padding: 4px 15px; margin-bottom: 0px; background: #F57B04 url(images/menubg-orange.png) repeat-x; font-weight: bold;}
    .btn_view:hover{opacity: 0.8;}
    </style>
    <!–Start Page Content –>
    <div class=”page-content-container”>
    <div class=”container_24″>
    <div class=”grid_24″>
    <div class=”page-content”>
    <div class=”grid_24 sub_alpha”>
    <h3 class=””><b><?php echo $page_title; ?></b></h3>
    <?php if($error != ”){ ?><h4><span style=”color: red;”><?php echo $error; ?></span></h4><?php } ?>
    <?php if ( have_posts() ) : ?>
    <table style=”width: 100%; clear: none; white-space: nowrap; border: 1px solid #EDEDED” cellspacing=”0″>
    <thead>
    <tr>
    <th scope=’col’ style=”width: 120px; padding:5px” ><center>رقم الطلب</center></th>
    <th scope=’col’ style=”width:; padding:5px” ><center>عنوان الطلب</center></th>
    <th scope=’col’ style=”width: 200px;” class=’manage-column column-title sortable desc’><center>إسم المشتري</center></th>
    <th scope=’col’ style=”width: 150px; text-align:center”>تاريخ الإضافة</center></th>
    <th style=”width: 100px; text-align:center”><center>الحالة</center></th>
    <th scope=’col’ style=”width: 90px;”><center>الخيارات</center></th>
    </tr>
    </thead>
    <tbody id=”the-list”>
    <?php while ( have_posts() ) : the_post();
    $order_id = $post->ID;
    $order_name = get_post_meta($post->ID, “order_name”, true);
    $order_status = get_post_meta($post->ID, “order_status”, true);
    // $order_email = get_post_meta($post->ID, ‘order_email’, true);
    // $order_payement = get_post_meta($post->ID, ‘order_payement’, true);;
    // $order_url = get_post_meta($post->ID, ‘order_url’, true);;
    // $order_quatite = get_post_meta($post->ID, ‘order_quatite’, true);;
    // $order_info = get_post_meta($post->ID, ‘order_info’, true);;

    $order_status_array = array(
    0 => ‘بإنتضار التعليمات’,
    1 => ‘جاري التنفيد’,
    2 => ‘تــم التسليم’,
    3 => ‘طلب ملغي’,
    );
    if(empty($order_status_array[$order_status]) or $order_status_array[$order_status] == ”){ $order_status_array[$order_status] = ‘غير معروف’;}
    ?>
    <tr class=”post-<?php the_ID(); ?>” valign=”top”>
    <td valign=”middle” style=”text-align:center; background: #ebe8da;”><?php echo $order_id;?></td>
    <td class=”post-title page-title column-title”>” target=”_new”><?php the_title(); ?></td>
    <td class=”categories column-categories” style=”text-align:center”><?php echo $order_name;?></td>
    <td class=”date column-date” style=”text-align:center”><?php the_time(get_option(‘date_format’)); ?></td>
    <td style=”text-align:center”><?php echo $order_status_array[$order_status]; ?></td>
    <td style=”text-align:center; padding: 10px 0;”>” class=”btn_view” target=”_new”>مشاهدة</td>
    </tr>
    <?php endwhile; ?>
    </tbody>
    </table>
    <?php else: ?>
    <div class=”content-bar”>
    <div class=”side-search” style=”margin: 20px auto; width: 600px;”>
    <form method=”get” class=”searchform” action=”” style=”background: none; width: 460px;”>
    <div>
    <input type=”text” value=”” name=”order_query” id=”order_query” style=”width: 450px;” />
    <input type=”submit” id=”c_submit” value=”” />
    </div>
    </form>
    </div>
    <div class=”clear”></div>
    </div>
    <?php endif; ?>
    <div class=”navigation clearfix” style=”width: 100%; margin-top:20px”>
    <?php
    if(function_exists(‘wp_pagenavi’)) {
    wp_pagenavi();
    } else {
    ?><div class=”alignleft”><?php next_posts_link( __( ‘<span>«</span> طلبات أقدم’) );?></div>
    <div class=”alignright”><?php previous_posts_link( __( ‘طلبات أحدث <span>»</span>’ ) );?></div><?php
    }
    wp_reset_query();?>

    </div><!– .navigation –>

    </div>
    </div>
    </div>
    <div class=”clear”></div>
    </div>
    </div>

    <?php
    get_footer();
    ?>’

    At the moment everyone can make a post even without registering, and they can check their orders list page by entering their email only. But I think I will restrict making orders for registered users only.

    The guy who developed my site has disappeared months ago, and I’m not able to get back from him. I’m hoping those codes above can show how are the ID stores. Do I need to check the DB of the site?

    Thnx

    bcworkz
    Participant

    @bcworkz

    Yes, users need to be logged in to see orders, it’s the only way we can somewhat ensure the provided data is accurate. I decided to make the content display contingent on the profile email matching the order email, I don’t see a better option.

    One issue would be is if users don’t remember what email they used on the order. The “…email must match your order email” message could be modified with what to do in such a case. You need to be careful with the procedure for recovery to ensure it cannot be gamed by a bad actor.

    Anyway, our quick and dirty plugin code is at pastebin.com. (FYI, this is the correct way to reference long blocks of code in this forum 😉 )

    Create a new plain text file named “restrict-post-content.php” and paste the code into it. Upload the file to your plugins folder, then activate it from your admin panel.

    This plugin will restrict content of ALL posts unless the user has ‘edit_others_posts’ capabilities. If not all posts are orders, this will likely be a problem, in which case we need a way to distinguish order posts from other posts.

    Let me know what problems come up (I’m expecting them, there’s only so much testing I can do on my own site), hopefully there will be an easy fix.

    bcworkz
    Participant

    @bcworkz

    Arrg! Double post due to connectivity issues deleted.

    Thanks a lot mate, I will test it tonight and let you know how it goes.

    cheers

    I added it as a plugin and activate it, all posts are still public and can be viewed by anyone. I’m not really sure why, but I will spend sometime on it to see if I can come up with any thing interesting ..

    Unfortunately, I wasn’t able to spot the problem with the codes. Is there any tip that will help?

    I’m not bad with tech in general but coding is where I always get lost ..!

    bcworkz
    Participant

    @bcworkz

    Uh-oh 🙁
    The problem is I made a bad assumption about how the content is displayed. My apologies, I wasn’t paying enough attention. While it’s still possible to restrict access by filtering, It now appears it’d be better to restrict at the template level.

    As long as there aren’t too many templates involved, this is still an easy fix. One basically needs to use the same if-else logic in my plugin, but apply it to the output portions of each template involved. If you don’t think this is something you’re comfortable doing, I’d be happy to do it for you, but I’ll need accurate copies of each template file involved. You can paste the code into pastebin.com and provide the links here, this forum is not appropriate for conveying pages of code.

    I need any template file that actually outputs order data that is accessible by customers or the public. Whatever is used for “www.mysite.com/order-1” pages is one. If you’re not sure, try placing HTML comments containing the filename on possible candidate templates, then view the actual page’s source HTML. The comment you inserted should be fairly easy to find, then you know for sure what template was used. By HTML comment, I mean something like this:
    ?><!-- ##### template filename ##### --><? php
    Depending on where you insert this, you may need to drop the ?> and <?php parts. The hashes have no special meaning, they just make the comment easier to find.

    Again, sorry for the confusion. We will get this sorted.

    Sorry, I’m not getting notified for new replies ..

    I’m not really comfortable modifying codes at all lol .. but I think I found the page you talking about, it was made by a smart kid who disappear all the sudden, no email, phone , msgs reply at all .. it’s a bit long as it has the order form codes .. it’s called “Order Page Page Template (templates/order.php ) here it is

    http://pastebin.com/jJyTgPny

    By the way, when users are logged in, they can see their list of orders .. if they are not lgged in, a user should enter their email in a search box and all his/her orders will come up in a list. here is the code for that page, it’s called: “Orders Lists Page Template (templates/orders_lists.php), here is the code:

    http://pastebin.com/zybtsTx7

    and there is anohter page called : orders_postes.php (templates/orders_postes.php), this is the page where users fill up the form of the orders, when they click submit, the “Order Page Page Template ” above, will show up. here is the code:

    http://pastebin.com/dYDdxsbj

    Sorry, for providing all those codes, but I’m not sure which one is needed. If it’s not any of those, please let me know and I will find them ..

    thanks for sharing your knowledge ..

    bcworkz
    Participant

    @bcworkz

    Here is the modified version of orders_postes.php:
    http://pastebin.com/CbtMdGrg

    You will need to do the testing for this, I am unable to test your template on my installation. Only admins will be able to see any order with this template, others must be logged in and their profile email must match the order email for them to see the order.

    This does mean visitors will not be able to see their order unless they register and log in. Maybe they should be redirected to the search page where they can enter their email? There is a way to securely allow visitors to view their order and not let anyone else URL hack their way into viewing the order. This would involve a nonce implementation. Unfortunately, adding nonce capability is beyond what I’m willing to donate to the effort. I’m willing to tweak what is displayed when the user is a visitor, but allowing them to securely see their order without logging in is more than I bargained for.

    The order_lists.php template appears to be secure as it is, I did not change anything on it. FYI, the order form is actually on order.php. The form submits to the same template, it detects the POST request and handles adding the order to the DB, then presents a link to what I assume is the orders_postes.php page. The order.php page does not output any order content that I could see.

    If you have any issues besides visitors not seeing their order, let me know, I’ll see what I can do. This should ensure you get a notice of this post: @alisalem

    Thanks for clarifying, I have done the testing but I think there is something missing.

    When uploaded the modified version, the order page become blank no matter if I’m the admin, user who made the post, or even a visitor by simply pasting the order link.

    I’m not sure why, but my guess would be the conditions (I think it’s IF stuff lol )

    <?php
    /**
     * Template Name Posts: Orders Posts
     */
    nocache_headers();
    get_header();
    
    if ( is_user_logged_in()) :
        global $current_user;
        get_currentuserinfo();
    
    if (have_posts()) while (have_posts()) : the_post();
    
            if ( $current_user->user_email != get_post_meta( get_the_ID(), 'order_email', true ) &&
                    !current_user_can('manage_options')) continue;

    Maybe the above ..

    No matter what user I use, the order page e.x. http://www.mysite.com/order-3
    does not show up, and it’s only blank white page.

    Luckily, I’m doing all the testing on a duplicate domain of the site that I use for testing etc.

    I was reading about the nonce implementation, and reading about it alone pop out my eyeball lol ..

    do you see what is the problem with the order page not showing up?

    Gracies

    @bcworkz

    bcworkz
    Participant

    @bcworkz

    @alisalem
    It’s something stupid that I did, though it’s actually a little obscure. Apologies. I basically confused the parser in my use of the colon-end structure instead of curly braces to define the extent of the if logic. I updated the pastebin file, but here’s the changes FYI and in case it’s easier to just directly edit the actual file.

    On line 12, place a colon ‘:’ after if (have_posts()) so the line is:
    if (have_posts()): while (have_posts()) : the_post();

    Between the endwhile; on 477 and the next else : line, insert this line:
    endif;
    so that the result looks like this:

    <?php
    endwhile;
    endif;
    else : //is_user_logged_in()
    ?>

    If you still get a white screen, you should find this line in your wp-config.php file:
    define('WP_DEBUG', false);

    If not, add it. Change false to true and then reload the order page. It will now give you an error message and location. Let me know what that is and I’ll see if I can figure it out.

    I’m also glad this is happening on a test site! That is of course the only proper way to utilize new code. I neglected to realize that some people may not do so, it should have been something to mention, I’m pleased you did the right thing anyway.

    About the nonce thing. Since I’m familiar with it, the nonce code itself is not my hesitation. My issue is I’ve no idea how many ways someone might legitimately end up on this order page. Every single legitimate link needs to include the nonce in the link, meaning the nonce generation code needs to be added to every bit of code that generates links. It is the unknown that gives me pause.

    If the two links I saw on order.php are the only links to this template, then visitor access might still be something I could implement for you. I do realize how important this is. However, if there’s links generated elsewhere, I’ll have to draw the line here and only focus on logged in users. Securely handling unknown users is complicated.

    Almost there, a few points after testing:

    – In general, it works. admin and the user who made the post can see order. a few points are:

    – When a user fills up the order form, they have to enter an email address, if it does not match the one they registered with, they will not be able to see the order and magically only see the header and the footer of the page one above the other ( no even blank space in the middle ) .. but they will see the order number in the orders list one they click on My Orders, but once they click on it, the case above happens. Is it possible to have the ability to view the order connected to the user email ( no matter what email they enter in the order form, they still can see the order? ) so even if they enter a different email in the form they still can see it?

    – when a visitor try to open an order by pasting something like this ( http://www.mysite.com/order-3) a msg shows up saying you must be logged in to view the order, which is perfect.

    – (WP_DEBUG’, false) is False, so no issue with that.

    – Since I’m strict viewing the orders for visitors, is it possible to strict making post for non registered user? and display a msg you need to be registered to make an order (post)

    I really appreciate your support, if that happens to be over than what you willing to contribute on this form, please let me know.

    I’m climbing the ladder of WP a step by step .. thanks for your sharing

Viewing 15 replies - 1 through 15 (of 37 total)
  • The topic ‘Only Admins and the post author can view a post, is it possible?’ is closed to new replies.