Support » How-To and Troubleshooting » Modify ViewLevel Plugin

Modify ViewLevel Plugin

  • How hard is to modify the ViewLevel Plugin to work with WP1.5
    I think the author of the pluging is not updating it anymore.


Viewing 13 replies - 1 through 13 (of 13 total)
  • I second that motion. Also for the next version of wordpress(1.6?) I’d like to see it integrated in a clean manner (into the user interface, use it on categories as well as posts, etc.).

    Tried out just throwing the old viewlevel and wordpress 1.5 together.

    Sorta works. You have to not be using a calender (as I don’t know how to fix that).

    For some reason it hides the post but displays the “Sorry, you need to be logged in to see this post” message regardless of what I set $private_message variable to.

    The fact it hides the post is encouraging.

    I’d love to see this.

    Has anyone tried contacting the woman that made it?

    There is no news on this subject so far. May be someone can pickup the work.

    I’ve gotten the thing working.
    I’d post the updated file somewhere, but I’m not certain of the original license on the plugin. Here’s the changes
    1. The ‘filter_posts…’ line is no longer needed in wp-blog-header.php
    2. Replace the ‘wp_head’ filter with ‘the_posts’
    3. Replace the filter_posts function with this one:

    function filter_posts($allposts){
    global $show_private_message, $feed;
    if (!empty($feed) || !$show_private_message){
    if (is_array($allposts)){
    foreach ($allposts as $post){
    if (!should_be_hidden($post))
    return $goodposts;
    return $allposts;

    The only questionable part of this code is that WP is updating the post caches after the posts are filtered. Perhaps the caching should be done afterwards, or perhaps a second filter should be added after caches are generated.

    When you say “Replace the ‘wp_head’ filter with ‘the_posts’,” do you mean simply change this line in viewlevel.php:





    After making that change and replacing the filter_posts function, the protected entries disappear even from people who should be able to see them.

    If would be nice if someone has the experience modify the View Level plug-in and submit the plug-in for the community.


    You got the filter_posts part right. Given that the original author’s site is still down, I have no way to contact her with my updates. Furthermore, I no longer have the original file, so I might have left a few of the changes out. Specifically, I don’t remember if the “get_currentuserinfo();” line (in should_be_hidden()) was in the original or not, now that I think of it.

    Since other and I haven’t been able to contact the original author, I’ll post the complete file here:


    Plugin Name: View Levels v.1.1.2
    Plugin URI: http://www.furbona.org/viewlevel.html
    Description: When posts have a custom field called "viewlevel" set, only lets users with that user level or above see the post.
    Author: Kendra Burbank
    Author URI: http://www.furbona.org
    global $show_private_message, $private_message;
    global $vl_default, $show_viewlevel, $padlock_filename;

    // Configuration
    $show_private_message=1; // Set this to 1 if you want to show a message instead of hiding private posts completely from unauthorized viewers
    $private_message="Sorry, you need to be logged in to see this post."; // The message that unauthorized viewers will see if $show_private_posts is set to 1

    $vl_default=0; // The userlevel required to see posts that don't have any viewlevel specified. If set to 1 or above, unregistered users won't be
    // able to see posts unless you specify vl=0 within the post.

    $show_viewlevel=0; // Set this to 1 if you want to show the viewlevel you've set next to the padlock icon.
    //Thanks to Dave Disser!
    $padlock_filename="padlock.gif"; // Name of the padlock icon file (should be stored in wp-images/)


    function filter_posts($allposts){
    global $show_private_message, $feed;
    if (!empty($feed) || !$show_private_message){
    if (is_array($allposts)){
    foreach ($allposts as $post){
    if (!should_be_hidden($post))
    return $goodposts;
    return $allposts;

    function post_padlock($text){
    global $show_viewlevel, $padlock_filename;
    if ($show_viewlevel)
    $leveltext='<sup>'.intval(viewlevel()).'</sup> ';
    } else {
    $leveltext=" "; }
    if (viewlevel()){
    $text='<img src=''.$site_root.'/wp-images/'.$padlock_filename.'' border='0'/>'.$leveltext.$text;
    return $text;

    function hide_text($text){
    if (should_be_hidden()){
    return $text;

    function error_text($text){
    global $private_message, $user_level;
    if (should_be_hidden()){
    // $text = post_padlock($text);
    return $text;

    function should_be_hidden($post=0){
    if(!$post) global $post;
    global $user_level, $comment;

    if ($ul<$vl) return 1;
    if ($ul<$vl) return 1;
    return 0;

    function viewlevel($id=0){
    global $wpdb, $tablepostmeta,$vl_default;
    if (!$id) global $id;
    if ($id) $vl= $wpdb->get_var("SELECT meta_value FROM $tablepostmeta WHERE post_id = $id AND meta_key = 'viewlevel'");
    if ($vl=="") $vl=$vl_default;
    return $vl;

    function find_tag($id){
    // This is the function that looks for the vl tag in the posts you publish.
    global $tablepostmeta, $wpdb,$tableposts,$post_meta_cache;
    $content = $wpdb->get_var("SELECT post_content FROM $tableposts WHERE ID = '$id'");
    if (preg_match('/vl=([d]*)/i',$content,$match)){
    $results=$wpdb->query("UPDATE $tableposts SET post_content = '$content' WHERE ID = $id");
    if($wpdb->get_var("SELECT meta_value FROM $tablepostmeta WHERE post_id = $id AND meta_key = 'viewlevel'")){
    $results= $wpdb->query("UPDATE $tablepostmeta SET meta_value = $match[1] WHERE post_id = '$id' AND meta_key = 'viewlevel'");
    } else {
    $results = $wpdb->query("INSERT INTO $tablepostmeta (post_id,meta_key,meta_value)
    VALUES ('$id','viewlevel',$match[1])");
    return $id;

    function get_calendar_vl_safe($daylength = 1) {

    // Stolen from the main calendar code

    global $wpdb, $m, $monthnum, $year, $timedifference, $month, $month_abbrev, $weekday, $weekday_initial, $weekday_abbrev, $tableposts, $posts;
    global $tablepostmeta,$user_level,$vl_default;

    if(!$ul) $ul=0;

    $addtoquery="AND (meta_key IS NULL OR (meta_key = 'viewlevel' AND meta_value <= $ul))";
    } else {
    $addtoquery="AND (meta_key = 'viewlevel' AND meta_value <= $ul)";

    // Quick check. If we have no posts at all, abort!
    if (!$posts) {
    $gotsome = $wpdb->get_var("SELECT ID from $tableposts LEFT JOIN $tablepostmeta on ID=post_id WHERE post_status = 'publish' $addtoquery ORDER BY post_date DESC LIMIT 1");
    if (!$gotsome)

    if (isset($_GET['w'])) {
    $w = ''.intval($_GET['w']);

    $add_hours = intval(get_settings('gmt_offset'));
    $add_minutes = intval(60 * (get_settings('gmt_offset') - $add_hours));

    // Let's figure out when we are
    if (!empty($monthnum) && !empty($year)) {
    $thismonth = ''.zeroise(intval($monthnum), 2);
    $thisyear = ''.intval($year);
    } elseif (!empty($w)) {
    // We need to get the month from MySQL
    $thisyear = ''.intval(substr($m, 0, 4));
    $d = (($w - 1) * 7) + 6; //it seems MySQL's weeks disagree with PHP's
    $thismonth = $wpdb->get_var("SELECT DATE_FORMAT((DATE_ADD('${thisyear}0101', INTERVAL $d DAY) ), '%m')");
    } elseif (!empty($m)) {
    $calendar = substr($m, 0, 6);
    $thisyear = ''.intval(substr($m, 0, 4));
    if (strlen($m) < 6) {
    $thismonth = '01';
    } else {
    $thismonth = ''.zeroise(intval(substr($m, 4, 2)), 2);
    } else {
    $thisyear = gmdate('Y', current_time('timestamp') + get_settings('gmt_offset') * 3600);
    $thismonth = gmdate('m', current_time('timestamp') + get_settings('gmt_offset') * 3600);

    $unixmonth = mktime(0, 0 , 0, $thismonth, 1, $thisyear);

    // Get the next and previous month and year with at least one post
    $previous = $wpdb->get_row("SELECT DISTINCT MONTH(post_date) AS month, YEAR(post_date) AS year
    FROM $tableposts LEFT JOIN $tablepostmeta on ID=post_id
    WHERE post_date < '$thisyear-$thismonth-01'
    AND post_status = 'publish' $addtoquery
    ORDER BY post_date DESC
    LIMIT 1");
    $next = $wpdb->get_row("SELECT DISTINCT MONTH(post_date) AS month, YEAR(post_date) AS year
    FROM $tableposts LEFT JOIN $tablepostmeta on ID=post_id
    WHERE post_date > '$thisyear-$thismonth-01'
    AND MONTH( post_date ) != MONTH( '$thisyear-$thismonth-01' )
    AND post_status = 'publish' $addtoquery
    ORDER BY post_date ASC
    LIMIT 1");

    echo '<table id="wp-calendar">
    <caption>' . $month[zeroise($thismonth, 2)] . ' ' . date('Y', $unixmonth) . '</caption>

    $day_abbrev = $weekday_initial;
    if ($daylength > 1) {
    $day_abbrev = $weekday_abbrev;

    foreach ($weekday as $wd) {
    echo "ntt<th abbr=\"$wd\" scope=\"col\" title=\"$wd\">" . $day_abbrev[$wd] . '</th>';

    echo '


    if ($previous) {
    echo "ntt".'<td abbr="' . $month[zeroise($previous->month, 2)] . '" colspan="3" id="prev"><a href="' .
    get_month_link($previous->year, $previous->month) . '" title="' . sprintf(__('View posts for %1$s %2$s'), $month[zeroise($previous->month, 2)], date('Y', mktime(0, 0 , 0, $previous->month, 1, $previous->year))) . '">&laquo; ' . $month_abbrev[$month[zeroise($previous->month, 2)]] . '</a></td>';
    } else {
    echo "ntt".'<td colspan="3" id="prev" class="pad">&nbsp;</td>';

    echo "ntt".'<td class="pad">&nbsp;</td>';

    if ($next) {
    echo "ntt".'<td abbr="' . $month[zeroise($next->month, 2)] . '" colspan="3" id="next"><a href="' .
    get_month_link($next->year, $next->month) . '" title="View posts for ' . $month[zeroise($next->month, 2)] . ' ' .
    date('Y', mktime(0, 0 , 0, $next->month, 1, $next->year)) . '">' . substr($month[zeroise($next->month, 2)], 0, 3) . ' &raquo;</a></td>';
    } else {
    echo "ntt".'<td colspan="3" id="next" class="pad">&nbsp;</td>';

    echo '


    // Get days with posts
    $dayswithposts = $wpdb->get_results("SELECT DISTINCT DAYOFMONTH(post_date)
    FROM $tableposts LEFT JOIN $tablepostmeta on ID=post_id WHERE MONTH(post_date) = $thismonth
    AND YEAR(post_date) = $thisyear
    AND post_status = 'publish' $addtoquery
    AND post_date < '" . current_time('mysql') . ''', ARRAY_N);
    if ($dayswithposts) {
    foreach ($dayswithposts as $daywith) {
    $daywithpost[] = $daywith[0];
    } else {
    $daywithpost = array();

    if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') ||
    strstr(strtolower($_SERVER['HTTP_USER_AGENT']), 'camino') ||
    strstr(strtolower($_SERVER['HTTP_USER_AGENT']), 'safari')) {
    $ak_title_separator = "n";
    } else {
    $ak_title_separator = ', ';

    $ak_titles_for_day = array();
    $ak_post_titles = $wpdb->get_results("SELECT post_title, DAYOFMONTH(post_date) as dom "
    ."FROM $tableposts LEFT JOIN $tablepostmeta on ID=post_id "
    ."WHERE YEAR(post_date) = '$thisyear' "
    ."AND MONTH(post_date) = '$thismonth' "
    ."AND post_date < '".current_time('mysql')."' "
    ."AND post_status = 'publish' $addtoquery"
    if ($ak_post_titles) {
    foreach ($ak_post_titles as $ak_post_title) {
    if (empty($ak_titles_for_day['day_'.$ak_post_title->dom])) {
    $ak_titles_for_day['day_'.$ak_post_title->dom] = '';
    if (empty($ak_titles_for_day["$ak_post_title->dom"])) { // first one
    $ak_titles_for_day["$ak_post_title->dom"] = htmlspecialchars(stripslashes($ak_post_title->post_title));
    } else {
    $ak_titles_for_day["$ak_post_title->dom"] .= $ak_title_separator . htmlspecialchars(stripslashes($ak_post_title->post_title));

    // See how much we should pad in the beginning
    $pad = intval(date('w', $unixmonth));
    if (0 != $pad) echo "ntt".'<td colspan="'.$pad.'" class="pad">&nbsp;</td>';

    $daysinmonth = intval(date('t', $unixmonth));
    for ($day = 1; $day <= $daysinmonth; ++$day) {
    if (isset($newrow) && $newrow)
    echo "nt</tr>nt<tr>ntt";
    $newrow = false;

    if ($day == gmdate('j', (time() + (get_settings('gmt_offset') * 3600))) && $thismonth == gmdate('m', time()+(get_settings('gmt_offset') * 3600)))
    echo '<td id="today">';
    echo '<td>';

    if (in_array($day, $daywithpost)) { // any posts today?
    echo '<a href="' . get_day_link($thisyear, $thismonth, $day) . "\" title=\"$ak_titles_for_day[$day]\">$day</a>";
    } else {
    echo $day;
    echo '</td>';

    if (6 == date('w', mktime(0, 0 , 0, $thismonth, $day, $thisyear)))
    $newrow = true;

    $pad = 7 - date('w', mktime(0, 0 , 0, $thismonth, $day, $thisyear));
    if ($pad != 0 && $pad != 7)
    echo "ntt".'<td class="pad" colspan="'.$pad.'">&nbsp;</td>';

    echo "nt</tr>nt</tbody>nt</table>";


    Well, that turned out worse than expected. bbPress dropped some character escapes and otherwise messed up formating. I’m able to post the file here for a few days until somebody else can pick up on development (fix the calender problem and other bugs that I haven’t had to deal with yet.)

    Thanks for that, theprog, but is there a way to make it so that locked posts are totally hidden? They still show the “You must be logged in to view this post” message.

    I am amazed I can answer this one for Scottish.

    Line 13 you need to change “$show_private_message=1” to “$show_private_message=0” as instructed in the file. The rest of it is mostly Greek to me 🙂

    You could also try looking at a new plugin, which can be found here: http://fortes.com/projects/wordpress/postlevels


    I have ViewLevel working and I am thrilled. I have a slightly related question. ViewLevel seems to keep my private threads out of my RSS feed via FeedBurner and BlogLines, but it still posts through to my Bloglet email digest because Bloglet accesses http://www.blognessie.com/xmlrpc.php to work because of an invalid date issue Bloglet has with the RSS feed.

    I probably need to start a new thread, but just thought I would ask here and see if you had a “quick” answer.

Viewing 13 replies - 1 through 13 (of 13 total)
  • The topic ‘Modify ViewLevel Plugin’ is closed to new replies.
Skip to toolbar