Posts in: WordPress

Wordpress comments meta data: Adding a checkbox

Posted in WordPress, comments, hack

Recently at work, there was a need to ask for additional data in the comments section of a WordPress site. A checkbox needed to be added to the comments form asking a question.

This sounded like a good use for WordPress comments meta data. There isn’t a lot of information out on the interwebs about how to use it, so I had to more or less figure this out…

So, what needed to be done was:

  • add a check box to the comments form
  • show in the WordPress comments admin whether or not the checkbox was selected
  • indicate in the comment notification email whether or not the checkbox was selected

Adding the checkbox to the comments form is the easiest part. To add the checkbox to the comments form open up your themes comments.php file and paste this into the area where you need it:

<p><label><input name="publishc" type="checkbox" id="publishc" value="this is the value I want to capture" tabindex="90" /> Whatever sentence that you want commenters to use the checkbox for</label></p>

Now that the checkbox is in place, we need to make sure that the data (the checkbox value) is saved to the database. We also want that data to be visible when viewing the comments from within the WordPress admin. So, paste this in your theme’s functions.php file:

// allow the saving of comment meta data
function fpo_allow_show_comment ( $post_id ) {
$allow_show_comment = $_POST['publishc'];
if ( $allow_show_comment ) {
add_comment_meta( $post_id, 'publishc', $allow_show_comment, true );
}}
add_action( 'comment_post', 'fpo_allow_show_comment', 1 );

// display meta in the edit comments admin page
function show_commeta() {
if (is_admin()) {
   echo get_comment_text(), '<br/><br/><strong>', get_comment_meta(get_comment_ID(), 'publishc',1), '<strong>';
   }}
add_action('comment_text', 'show_commeta');

The first function will allow comments meta data to be collected and to save it to the database. The second functions will show it in the comments admin pages.

Adding the comments meta data to the notification email proved to be the hardest to figure out – I couldn’t figure out a way to do it via plugin or editing functions.php. So, I decided to do this the least desirable way, which is to edit the WordPress core files, namely wp-includes/pluggable.php.

So find the function wp_notify_postauthor and look for the part that says if (‘comment’ == $comment_type) {. Paste these lines of code in whatever area of the notification email where you would like the comment meta to be included:

$notify_message .= __('Comment meta: ') ;
$notify_message .= sprintf( get_comment_meta($comment->comment_ID, 'publishc',1)) . "\r\n\r\n";

And that is that, hours and hours worth of trial and error. Hope you find it useful!

Leave a Comment more...

WordPress: make posts expire or auto-delete

Posted in WordPress, hack

While working on a website, the client needed the homepage to function differently from other websites and blogs.

Rather than having the home page show the last x number of posts or editing the loop through query_posts to only show posts within a certain timeframe, the posts would either need to appear on the homepage until:

  • a specific date – and then the post will either be archived or deleted
  • or if no date is set, the post should appear for a month

I knew that there was a way to makes posts “expire” by setting a date and time as a custom field and editing the loop. A search on Google reveals several articles (all of which are identical – exactly the same, so I don’t know the original article which I could link to). I then also found an article that edited the expire posts code so that the post would auto delete rather than expire: Modify you WordPress theme to enable an expiration date for your posting.

There a few drawbacks to the methods I found:

  • they needed post custom fields, which aren’t the most user friendly interface for end users to employ
  • custom fields do not look nice
  • the custom field entry needed to be in the format mm/dd/yyyy 00:00:00 not exactly user friendly nor easy to understand (is 17:00:00 7pm or 5pm??)
  • posts would either only expire (be archived) or be deleted

So now I needed to put on my PHP hat and find a way to get what needed to be done and avoid the drawbacks listed above. I knew right away that I would need to use custom write panels to make everything easy to look at and use. I wrote about using them here, WordPress Custom Write Panels & prioritizing what to display and used this as my reference, Revisited: Creating Custom Write Panels in WordPress

In the end, this is what my WordPress custom write panel looked like:
WordPress make posts expire or auto-delete

Obviously, this is for posts in the “announcements” category. Anyway, open up your themes functions.php (or make one) and add this code in:

<?php
//start  post meta box
$key = "Announcements";
$meta_boxes = array(

"expimo" => array(
"name" => "expimo",
"title" => "Expiration Month",
"description" => "Select a date in the future for this post to expire.  Default date is one month into the future",
"option" => array('01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12')),

"expida" => array(
"name" => "expida",
"title" => "Expiration Day",
"description" => "Select Day",
"options" => array('-', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31')),

"expiye" => array(
"name" => "expiye",
"title" => "Expiration Year",
"description" => "Select Month",
"options" => array('-', '2013', '2012', '2011', '2010')),

"expiti" => array(
"name" => "expiti",
"title" => "Expiration Time",
"description" => "Select Time",
"options" => array('00:00:00', '01:00:00', '02:00:00', '03:00:00', '04:00:00', '05:00:00', '06:00:00', '07:00:00', '08:00:00', '09:00:00', '10:00:00', '11:00:00', '12:00:00', '13:00:00', '14:00:00', '15:00:00', '16:00:00', '17:00:00', '18:00:00', '19:00:00', '20:00:00', '21:00:00', '22:00:00', '23:00:00')),

"autodelp" => array(
"name" => "autodelp",
"title" => "Delete Post On Expiration",
"description" => "Choose if a post should be deleted after expiration.  Choosing NO will remove the post from the homepage and archive it upon expiration",
"options" => array('no', 'yes')),

);

function create_meta_box() {
global $key;

if( function_exists( 'add_meta_box' ) ) {
add_meta_box( 'new-meta-boxes', ucfirst( $key ) . ' Post Options', 'display_meta_box', 'post', 'normal', 'high' );
}
}

function display_meta_box() {
global $post, $meta_boxes, $key;
?>

<div class="form-wrap">

<?php

wp_nonce_field( plugin_basename( __FILE__ ), $key . '_wpnonce', false, true );

foreach($meta_boxes as $meta_box) {
$data = get_post_meta($post->ID, $key, true);

?>
<?php if($meta_box[ 'name'] != 'expimo' &&
         $meta_box[ 'name'] != 'expida' &&
         $meta_box[ 'name'] != 'expiye' &&
		 $meta_box[ 'name'] != 'autodep' &&
		 $meta_box[ 'name'] != 'expiti' &&
		 $meta_box[ 'name'] != 'autodelp'
) { ?>
<div class="form-field form-required">

<label for="<?php echo $meta_box[ 'name' ]; ?>"><?php echo $meta_box[ 'title' ]; ?></label>

<input type="text" name="<?php echo $meta_box[ 'name' ]; ?>" value="<?php echo htmlspecialchars( $data[ $meta_box[ 'name' ] ] ); ?>" />  

<p><?php echo $meta_box[ 'description' ]; ?></p></div>
<?php } elseif ($meta_box[ 'name'] == 'expimo') {

echo '<div class="form-field form-required"><label for="Post Expiration Date">Post Expiration Date</label>';
echo '<select name="expimo" id="expimo">';
	foreach ($meta_boxes['expimo']['option'] as $option) {
	if ($option == '01') {$optionez = 'January';
} elseif ($option == '02') {$optionez = 'February';
} elseif ($option == '03') {$optionez = 'March';
} elseif ($option == '04') {$optionez = 'April';
} elseif ($option == '05') {$optionez = 'May';
} elseif ($option == '06') {$optionez = 'June';
} elseif ($option == '07') {$optionez = 'July';
} elseif ($option == '08') {$optionez = 'August';
} elseif ($option == '09') {$optionez = 'September';
} elseif ($option == '10') {$optionez = 'August';
} elseif ($option == '11') {$optionez = 'November';
} else {$optionez = 'December';}
		echo '<option', ' value="', $option, '"', $data[ 'expimo' ] == $option ? ' selected="selected"' : '', '>', $optionez, '</option>';
                }
                echo '</select>';
echo '<select name="expida" id="expida">';
	foreach ($meta_boxes['expida']['options'] as $option) {
		echo '<option', ' value="', $option, '"', $data[ 'expida' ] == $option ? ' selected="selected"' : '', '>', $option, '</option>';
                }
                echo '</select>';
echo '<select name="expiye" id="expiye">';
	foreach ($meta_boxes['expiye']['options'] as $option) {
		echo '<option', $data[ 'expiye' ] == $option ? ' selected="selected"' : '', '>', $option, '</option>';
                }
                echo '</select>';
echo '<select name="expiti" id="expiti">';
	foreach ($meta_boxes['expiti']['options'] as $option) {
if ($option == '00:00:00') {$optionez = '12MN';
} elseif ($option == '01:00:00') {$optionez = '1AM';
} elseif ($option == '02:00:00') {$optionez = '2AM';
} elseif ($option == '03:00:00') {$optionez = '3AM';
} elseif ($option == '04:00:00') {$optionez = '4AM';
} elseif ($option == '05:00:00') {$optionez = '5AM';
} elseif ($option == '06:00:00') {$optionez = '6AM';
} elseif ($option == '07:00:00') {$optionez = '7AM';
} elseif ($option == '08:00:00') {$optionez = '8AM';
} elseif ($option == '09:00:00') {$optionez = '9AM';
} elseif ($option == '10:00:00') {$optionez = '10AM';
} elseif ($option == '11:00:00') {$optionez = '11AM';
} elseif ($option == '12:00:00') {$optionez = '12NN';
} elseif ($option == '13:00:00') {$optionez = '1PM';
} elseif ($option == '14:00:00') {$optionez = '2PM';
} elseif ($option == '15:00:00') {$optionez = '3PM';
} elseif ($option == '16:00:00') {$optionez = '4PM';
} elseif ($option == '17:00:00') {$optionez = '5PM';
} elseif ($option == '18:00:00') {$optionez = '6PM';
} elseif ($option == '19:00:00') {$optionez = '7PM';
} elseif ($option == '20:00:00') {$optionez = '8PM';
} elseif ($option == '21:00:00') {$optionez = '9PM';
} elseif ($option == '22:00:00') {$optionez = '10PM';
} else {$optionez = '11PM';}
		echo '<option', ' value="', $option, '"',$data[ 'expiti' ] == $option ? ' selected="selected"' : '', '>', $optionez, '</option>';
                }
                echo '</select>';
echo '<p>Select a date in the future for this post to expire.  Default date is one month into the future</p></div>';
} elseif ($meta_box[ 'name'] == 'autodelp') {
echo '<label for="Auto Delete">Auto Delete?</label>';
echo '<select name="autodelp" id="autodelp">';
                foreach ($meta_boxes['autodelp']['options'] as $option) {
                    echo '<option', $data[ 'autodelp' ] == $option ? ' selected="selected"' : '', '>', $option, '</option>';
                }
                echo '</select><p>', $meta_box[ 'description' ], '</p></div>';
} else {}
?>

<?php
}; ?>

<?php
if (get_the_time('m') == 12) {$mononet = 1;
} else {$mononet = 1 + get_the_time('m');}
$slashhh = '/';
      $spaceeee = ' ';
if ( $data[ 'expida'] == '-') {$datarr = $mononet.$slashhh.get_the_time('d/Y').$spaceeee.$data[ 'expiti' ];
} else {$datarr = $data[ 'expimo' ].$slashhh.$data[ 'expida' ].$slashhh.$data[ 'expiye' ].$spaceeee.$data[ 'expiti' ];} ?>
<?php update_post_meta($post->ID, 'expiration', $datarr); ?>
</div>
<?php
}
function save_meta_box( $post_id ) {
global $post, $meta_boxes, $key;

foreach( $meta_boxes as $meta_box ) {
$data[ $meta_box[ 'name' ] ] = $_POST[ $meta_box[ 'name' ] ];
}

if ( !wp_verify_nonce( $_POST[ $key . '_wpnonce' ], plugin_basename(__FILE__) ) )
return $post_id;

if ( !current_user_can( 'edit_post', $post_id ))
return $post_id;

update_post_meta( $post_id, $key, $data );
}

add_action( 'admin_menu', 'create_meta_box' );
add_action( 'save_post', 'save_meta_box' );
//end  post meta box
?>

It’s a bit lengthy, but it does what it needs to.

Now open up your index.php or whichever file has the loop which you will need to edit and modify your loop between the while (have_posts()) and endwhile statements as such:

<?php while (have_posts()) : the_post(); $data = get_post_meta( $post->ID, 'Announcements', true );
	$expirationtime = get_post_custom_values('expiration');
if (is_array($expirationtime)) {
$expirestring = implode($expirationtime);
}
$secondsbetween = strtotime($expirestring)-time() + 14400;
if ( $secondsbetween <= 0 && $data[ 'autodelp'] == 'yes') {
wp_delete_post($post->ID, false);
} elseif ( $secondsbetween <= 0 && $data[ 'autodelp'] == 'no') {
} elseif ( $secondsbetween > 0) {
	?>
<!--start your loop contents here. For example...-->
	<h2><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h2>
<p>Posted on <?php the_time('M.d, Y') ?></p>
<?php the_content('Read more &raquo;'); ?>
<!--end your loop contents here-->
	<?php } else {}
	endwhile; ?>

Please note that 14400on line 06 is to change the time to my current time zone, US Eastern Time. For best results, you should change this number to reflect your current timezone. To calculate the number you would use for your timezone, use this from Modify you WordPress theme to enable an expiration date for your posting:

Let say, you are in GMT +7 time zone, you are ahead of time, so instead of “+”, you will need to “-” the difference, 7 hours = 7 * 60 *60 = 25200.

Don’t forget to save and upload your changes. To use the panel, while writing or editing a post, in the custom write panel named Announcements Post Options, simply select the date and time which you would like the post to expire under the Post Expiration Date section. If you want the post to be deleted upon expiration, select yes in the Auto Delete section. If no date is chosen, the post will automatically expire one month from the “publish date” of the post.

Hope you like that and find it useful.

Leave a Comment more...

How to display the number of users in a WordPress site

Posted in WordPress, hack

Recently at work I needed to display the number of users registered in a WordPress blog.

Searching the web gave me the following PHP and mySQL code to display the number of registered users:

<?php $users = $wpdb->get_var("SELECT COUNT(ID) FROM $wpdb->users");
echo $users." registered users."; ?>

But we were using the Register Plus plugin with user moderation. Register Plus adds the prefix unverified__ to all unverified WordPress usernames (so they can’t log in). Needless to say, we wanted to not include these unverified users from the count – so I changed the code to this:

<?php $users = $wpdb->get_var("SELECT COUNT(ID) FROM $wpdb->users WHERE user_login NOT LIKE 'unverified__%'");
echo $users." registered users."; ?>

Lastly, we wanted to not include the 3 WordPress administrators we have from the user count. So, I modified the code further like this:

<?php $users = $wpdb->get_var("SELECT COUNT(ID) FROM $wpdb->users WHERE user_login NOT LIKE 'unverified__%'");
$admins = 3;
echo $users - $admins ." registered users."; ?&>

You can change the number in the line that says $admins = 3; to whatever number you want subtracted from the count.

And there you have it, an accurate WordPress registered user count.

Leave a Comment more...