Quickest way to get timestamp of a time in a particular timezone in PHP

Playing with timezone conversions can be crazy, it still confuses me every time and I have to wait a minute to run some test code to figure out what's it that I am trying to do here.

Anyway, the quickest way I have to get timestamp of a time in particular time zone is

DateTime and DateTimeZone classes are what you need to know when dealing with timezones, ditch any other method of doing conversions in PHP. Seriously, there are no better ways of doing it.

And just a tip, if you already don't know, timestamp from different timezones for a single point of time is same. It doesn't depend on the timezone. Did you know? ๐Ÿ™‚

Let me know in the comments if you have a question.

Fetch comments of a specific category in WordPress

WordPress already provides an easy function for fetching the comments get_comments() but the function only supports fetching comments of a particular user, or for a particular post and not fetching comments of a particular category. The code for the former two cases, is pretty simple but the last one is not so simple. Here are the code snippets as examples:

Fetching Comments of a particular user

$args = array( 'number' => 10, 'status' => 'approve', 'user_id' => 1 );
$comments_list_by_user = get_comments( $args );
print_r ( $comments_list_by_user );

Fetching Comments of a particular post

$args = array( 'number' => 10, 'status' => 'approve', 'post_id' => 30 );
$comments_list_post = get_comments( $args );
print_r ( $comments_list_post );

Fetching Comments of a particular category

Here is how you can fetch comments for a specific category:

// Posts per page setting
$ppp = get_option('posts_per_page'); // either use the WordPress global Posts per page setting or set a custom one like $ppp = 10;
$custom_offset = 0; // If you are dealing with your custom pagination, then you can calculate the value of this offset using a formula

// category (can be a parent category)
$category_parent = 3;

// lets fetch sub categories of this category and build an array
$categories = get_terms( 'category', array( 'child_of' => $category_parent, 'hide_empty' => false ) );
$category_list =  array( $category_parent );
foreach( $categories as $term ) {
 $category_list[] = (int) $term->term_id;
}

// fetch posts in all those categories
$posts = get_objects_in_term( $category_list, 'category' );

$sql = "SELECT comment_ID, comment_date, comment_content, comment_post_ID
 FROM {$wpdb->comments} WHERE
 comment_post_ID in (".implode(',', $posts).") AND comment_approved = 1
 ORDER by comment_date DESC LIMIT $ppp OFFSET $custom_offset";

$comments_list = $wpdb->get_results( $sql );

if ( count( $comments_list ) > 0 ) {
 $date_format = get_option( 'date_format' );
 echo '<ul>';
 foreach ( $comments_list as $comment ) {
 echo '<li>Comment: '.substr( $comment->comment_content, 0, 50 ).'..<br />'.date( $date_format, strtotime( $comment->comment_date ) ).'<br />Post: <a href="'.get_permalink( $comment->comment_post_ID ).'">'.get_the_title( $comment->comment_post_ID ).'</a></li>';
 }
 echo '</ul>';
} else {
 echo '<p>No comments</p>';
}
?>

What we have done here is that, first we fetch sub categories of the category specified so as to include comments on those posts too which are under a sub-category of the specified category. Then we build an array of all these categories, where we need to look up for comments. Then we fetch the posts ID under those categories and then we use a query to fetch the comments on those posts. Finally, we display them as per our need by iterating $comments_list.

In case you want to fetch the comments of aย  particular user under a specific category, then you can just change the SQL query in the above code to this:

$user_id = 1; // change this to the user ID either manually or let it come from some other code
$sql = "SELECT comment_ID, comment_date, comment_content, comment_post_ID
 FROM {$wpdb->comments} WHERE
 comment_post_ID in (".implode(',', $posts).") AND comment_approved = 1 AND user_id = $user_id
 ORDER by comment_date DESC LIMIT $ppp OFFSET $custom_offset";

I have used simple names for variables here to make it easy to understand. Always take care to provide your code in its own namespace, choose unique (non-generic) names. Read prefix everything in WordPress.

Need help? Got questions? Comment section is all yours! ๐Ÿ™‚

Pagination approach using get_posts() in WordPress

Yesterday, I talk about using WP_query or query_posts or get_posts and today I am going to explain the approach I use to have pagination using get_posts(). The other two methods take care of the pagination by them self by just passing the paged parameter along with the function call. But get_posts() is more of a raw function which I used to create paginated data on the basis of already existing pagination.

Here for the sake of explanation of approach, I am making the content paginated where content is already paginated. We will make our extra content work in order to the global $paged variable.

<?php
// Posts Per Page option
$ppp = get_option('posts_per_page');

if (!is_paged()) {
    $custom_offset = 0;
} else {
    $custom_offset = $ppp*($paged-1);
}

// Lets suppose we are querying for posts of a certain author in a particular category
$args = array(
'numberposts' => $ppp,
'offset' => $custom_offset,
'category' => 7, // Category ID of category 'Articles'
'author' => $author_id
);

$posts_data = get_posts( $args );

if ( count( $posts_data ) > 0 ) {
    echo '<ul>';
    foreach ( $posts_data as $post ) {
        echo '<li><a href="'.get_permalink( $post->ID ).'">'.$post->post_title.'</a></li>';
    }
    echo '</ul>';
} else {
    echo '<p>No articles by this user</p>';
}
?>

This way the code make use of the global $paged variable to see which page it is on, and set the value of offset accordingly making the fetched content using get_posts itself paginated. On Page 1, the offset will be zero, it will fetch the posts limited by the posts per page value and on Page 2, the offset will be calculated to leave the posts already shown on previous page and query further posts limited by the posts per page value.

Got questions? Comment section is down below.

Pomodoro Timer in Ubuntu

I finally decided to try Pomodoro technique to see how well it can improve my productivity as I am a lot disorganised, lazy sorta geek (well who isn't?). So I built up a small script which acts as a Pomodoro timer for me using Ubuntu notification system (Do read it if you haven't, you need to install lib-notify package for this script to work).

I have created a launcher in my top panel, with which I start a new pomodori (name for a new period of time, lets call it a Pomodoro anyway). It calls up the script which alerts me that a new Pomodoro (time period) has started and then alert me again when the timer ends and I should take a small break.

Here is the script:

DISPLAY=:0 notify-send -t 1000 -i /home/ashfame/Dropbox/Ubuntu/icons/pomodoro.png "New Pomodoro starts" "You have 25 minutes to work."
# 25 minutes timer
sleep 1500
DISPLAY=:0 notify-send -t 1000 -i /home/ashfame/Dropbox/Ubuntu/icons/pomodoro.png "Pomodoro ends" "Take a break!"

As soon as I click the launcher, the first notification appears telling me that a new Pomodoro has started.

pomodoro starts

Then it sleeps for 1500 secs = 25 minutes. And after that the second notification appears telling me that the Pomodoro has ended.

pomodoro ends

I just take a 3-5 minutes break or even longer (I am the boss!), and then I again click on the launcher starting another Pomodoro and I work for another 25 minutes. You can use the same tomato icon, if you want.

pomodoro

Enjoy the awesomeness of Ubuntu and ditch Windows, yes I am an Ubuntu advocate and will push you to switch all the time ๐Ÿ˜›

Have your say in the comments!

WordPress Evil Post Series

Yeah! That sounded right. This is a post series where I will show you how to use WordPress to do evil, unethical things which surely doesn't mean WordPress is a bad piece of software. Its really a great one considering every thing has its share of Pros & Cons. Remember, just like we say, Technology is neither good or bad, its the use which can be classified as good or bad. Similarly, I will be using a technology product (WordPress), to do things for fun and educative purposes. You better be aware to avoid that happening with you, or sometimes use it ๐Ÿ˜‰

You are welcome for the following:

  • Comment anything relevant! You can criticise my series too, I won't mind!
  • Tip me for the next Evil Post.
  • Write a Guest Post for WP Evil Series (Decision of accepting it as a qualified WordPress Evil Post Series will be totally on me, though)

That said, first post in the series will be up in a few minutes.

Show recent comments of a particular user in WordPress

A friend asked for a help in his project where he required to list all the comments a registered user made on the site. So just for play, I created a small plugin which provides you with a shortcode which you can use on a page link example.com/my-comments/ or whatever.

I am zipping it up as a plugin but you can copy paste the code inside your functions.php file and you should be fine.

<?php
/*
Plugin Name: Show Recent Comments by a particular user
Plugin URI: http://blog.ashfame.com/?p=876
Description: Provides a shortcode which you can use to show recent comments by a particular user
Author: Ashfame
Author URI: http://blog.ashfame.com/
License: GPL
Usage: 
*/

add_shortcode ( 'show_recent_comments', 'show_recent_comments_handler' );

function show_recent_comments_handler( $atts, $content = null )
{
    extract( shortcode_atts( array( 
        "count" => 10,
        "pretty_permalink" => 0
        ), $atts ));

    $output = ''; // this holds the output
    
    if ( is_user_logged_in() )
    {
        global $current_user;
        get_currentuserinfo();

        $args = array(
            'user_id' => $current_user->ID,
            'number' => $count, // how many comments to retrieve
            'status' => 'approve'
            );

        $comments = get_comments( $args );
        if ( $comments )
        {
            $output.= "<ul>\n";
            foreach ( $comments as $c )
            {
            $output.= '<li>';
            if ( $pretty_permalink ) // uses a lot more queries (not recommended)
                $output.= '<a href="'.get_comment_link( $c->comment_ID ).'">';
            else
                $output.= '<a href="'.get_settings('siteurl').'/?p='.$c->comment_post_ID.'#comment-'.$c->comment_ID.'">';         
            $output.= $c->comment_content;
            $output.= '</a>';
            $output.= "</li>\n";
            }
            $output.= '</ul>';
        }
    }
    else
    {
        $output.= "<h2>You should be logged in to see your comments. Make sense?</h2>";
        $output.= '<h2><a href="'.get_settings('siteurl').'/wp-login.php?redirect_to='.get_permalink().'">Login Now &rarr;</a></h2>';
    }
    return $output;
}
?>

You can use in a post or page as follows:

[show_recent_comments]

This will show last 10 comments of the current user.

[show_recent_comments count=15]

You can change the number of comments you want by providing it with the value of count.

Now, if you notice, they do link to the respective comments but links are not pretty permalinks. I don't recommend you do this (because it increases the query count), but if you really want to have pretty permalinks, you can use the shortcode as follows:

[show_recent_comments count=15 pretty_permalink=1]

or just with the default count of 10 as follows:

[show_recent_comments pretty_permalink=1]

I should highlight the fact that the current user (registered member) will see the comments he or she has made. If you are not logged in, it asks you to login and after login brings you back on the post or page where you are using this shortcode.

You can use this code to make changes as per your need. You can use this shortcode anywhere in your theme by calling it as follows:

<?php echo do_shortcode( '[show_recent_comments count=15]' ); ?>

And I think if you use it like that outside the loop, it won't bring the user back to the previous page. You will need to change the get_permalink() call near the end of the plugin.

Good thing is that it works correctly with cache plugins such as WP Super Cache or W3 Total Cache because logged in users are served live pages instead of cached pages. Correct me if I am wrong.

Download Show Recent Comments plugin

Other than that, if you have any questions, comment section is all yours!

Adding a custom user profile field to registration in WordPress

Sometime back a friend of mine asked me how can he add a custom registration field to the WordPress registration page, I asked him to google it as I have come across a lot of such tutorials but he was unable to do so and then I found the issue that either the tutorial is for adding a custom user profile field or adding an existing field to the registration form and even coupling up the two wonโ€™t do it and requires some change of code and that can be hard for someone who doesnโ€™t swim in code at all. Pun intended!

First, I would write create a custom user field so that it can be operated from the WordPress profile page and then add that field in the registration form. To keep it general and useful for everyone, I would be adding a simple Twitter handle field.

Adding a custom user profile field

/**
 * Add additional custom field
 */

add_action ( 'show_user_profile', 'my_show_extra_profile_fields' );
add_action ( 'edit_user_profile', 'my_show_extra_profile_fields' );

function my_show_extra_profile_fields ( $user )
{
?>
    <h3>Extra profile information</h3>
    <table class="form-table">
        <tr>
            <th><label for="twitter">Twitter</label></th>
            <td>
                <input type="text" name="twitter" id="twitter" value="<?php echo esc_attr( get_the_author_meta( 'twitter', $user->ID ) ); ?>" class="regular-text" /><br />
                <span class="description">Please enter your Twitter username.</span>
            </td>
        </tr>
    </table>
<?php
}

add_action ( 'personal_options_update', 'my_save_extra_profile_fields' );
add_action ( 'edit_user_profile_update', 'my_save_extra_profile_fields' );

function my_save_extra_profile_fields( $user_id )
{
    if ( !current_user_can( 'edit_user', $user_id ) )
        return false;
    /* Copy and paste this line for additional fields. Make sure to change 'twitter' to the field ID. */
    update_usermeta( $user_id, 'twitter', $_POST['twitter'] );
}

Adding a field on the registration form / registration page

/**
 * Add cutom field to registration form
 */

add_action('register_form','show_first_name_field');
add_action('register_post','check_fields',10,3);
add_action('user_register', 'register_extra_fields');

function show_first_name_field()
{
?>
    <p>
    <label>Twitter<br/>
    <input id="twitter" type="text" tabindex="30" size="25" value="<?php echo $_POST['twitter']; ?>" name="twitter" />
    </label>
    </p>
<?php
}

function check_fields ( $login, $email, $errors )
{
    global $twitter;
    if ( $_POST['twitter'] == '' )
    {
        $errors->add( 'empty_realname', "<strong>ERROR</strong>: Please Enter your twitter handle" );
    }
    else
    {
        $twitter = $_POST['twitter'];
    }
}

function register_extra_fields ( $user_id, $password = "", $meta = array() )
{
    update_user_meta( $user_id, 'twitter', $_POST['twitter'] );
}

If you are using this on before WordPress 3.1, then your input box will not be styled like that of username and email. Its fixed in WP 3.1 though. For earlier versions, change the id of the input field on Line 14 to user_email

    <input id="user_email" type="text" tabindex="30" size="25" value="<?php echo $_POST['twitter']; ?>" name="twitter" />

To get this custom field, you can use get_the_author_meta() to return its value or the_author_meta() for displaying it.

the_author_meta( $meta_key, $user_id ); // $meta_key = 'twitter' in our case

I am also attaching the whole code as a plugin that you can activate on your WordPress installation.

Download Plugin

This concludes the tutorial for adding an Custom user profile field which is an input text box but there may be certain cases where you would like to use select dropdowns, radio buttons or checkboxes. Right? I will cover that in the next post.

If you have any questions, use the comment section & I will try to help.