Setting cron to be run as root

In Linux based distros, its very simple to setup cron for repeated tasks by using crontab -e for editing the crontab of the current user as you are logged in. You can view the contents of your crontab by crontab -l.

But if you need to call something with root privileges, its as simple as sudo crontab -e. This adds your changes to root user's crontab. To view root user's crontab, you can again do sudo crontab -l and you can see the difference.

Bonus tip: The first time you open crontab for editing, it opens it in vim. Those of you who are hardcore guys, know their way around, but they are not reading this anyway. I am not hardcode, I do know basic vim commands, but I like to use nano. If you are on the same boat as me, use this export EDITOR=nano. Now go get shit done!

Verify sending domain inside Mandrill without email hosting

Mandrill has enforced upon us that the only way to verify a sending-domain (domain used to send emails from) is by getting an email sent by them on an email of the sending-domain in use. So, if you use example.org or something.example.org to send emails, you can now only verify your sending-domain, by receiving an email from them on anyemail@example.org or anyemail@something.example.org in which you have to click on a verification link to validate your ownership of the domain.

Now that's not ideal. Add a TXT record is enough for verification purpose, and that's essentially the step that proves the ownership of domain through this step only but this is how it is.

The only issue with this approach is that one must have email hosting or an email inbox setup to receive emails on that domain. If you already have a working email on the sending-domain, you don't need to read the rest of the post. Simply, enter the working email for verification and get it over with. But if you don't, then instead of setting up email hosting somewhere for just verification purpose, you can utilize this trick I discovered. Its quick enough & free alternative to do so by simply using Inbound emails feature in Mandrill accounts.

Here is how to do it:

Add your domain under "Inbound domains"

screen-shot-2016-11-23-at-12-51-01-am

Now add MX record for your sending domain as per the instructions

screen-shot-2016-11-23-at-12-51-37-am

Add those MX records in your DNS and then validate those records are reflecting by clicking on "Test DNS settings".

Once confirmed, simply setup a route for that domain, by clicking the arrow on the right of "Test DNS settings" link.

screen-shot-2016-11-23-at-12-55-48-am

Configure webhook POST URL to a URL you obtained on https://requestb.in

screen-shot-2016-11-23-at-12-56-07-am

screen-shot-2016-11-23-at-12-57-20-am

Now go to verification of send domains, enter the email address you configured and wait for the email to come at your https://requestb.in/XXXXXXX URL.

screen-shot-2016-11-23-at-12-57-58-am

Find the link, copy and paste it in the browser.

And you are done!

Send & Receive mails to & from localhost

Mails don't work when locally but sometimes it might prove to be very useful in development if one can send & receive mails to & from localhost. It can be setup pretty easily too. Basic idea is to configure postfix for localhost & then use mutt to read local mails. Here is how it is done (should work fine for any UNIX based OS):

Install postfix

sudo apt-get install postfix

Install mutt

sudo apt-get install mutt

To configure postfix for localhost, specify the following in its config file at /etc/postfix/main.cf

myorigin = localhost
mydestination = $myhostname, localhost.$mydomain, localhost
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
relayhost =

Restart postfix

sudo /etc/init.d/postfix restart

Now you can read localhost mails using mutt

mutt

It will read emails from /var/mail/USERNAME

Ubuntu controlling network adapters through terminal

We all know that Ubuntu's network management is quite good but not there yet. One big issue with it is that, on some machines, disabling one type of network adapter, disables the other one too.

Like I use wifi to connect to the internet but my bluetooth is switched on by default all the time. And if I try to disable bluetooth it disables wifi too.

To control them via terminal or command line, you can do this (Atleast from Ubuntu 10.10 onwards):

ashfame@ashfame-xps:~$ rfkill list all
0: phy0: Wireless LAN
Soft blocked: no
Hard blocked: no
4: hci0: Bluetooth
Soft blocked: yes
Hard blocked: no

You see how it says soft blocked & hard blocked. Soft block is a switch in OS & hard block is a hardware switch in your machine.

You can disable the ones you don't want by:

rfkill block bluetooth

and enable the ones you want by:

rfkill unblock wifi

Disabling the ones you don't want will save you some battery if you are on a laptop/notebook/ultrabook.

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! 🙂

WordPress plugin Facebook Like Thumbnail Updates

I have updated my WordPress plugin to fix Facebook Like Thumbnails to version 0.2 which I am sure will make the existing users happy! 🙂

Some of the users who quickly upgraded might be facing issues because of a silly mistake on my part. If the plugin has disappeared from the plugins listing, then you would have to delete the folder "facebook-like-thumbnail" folder in your plugins folder (/wp-content/plugins/) and then reinstall the plugin by typing "Facebook Like Thumbnail" in Add New Plugins screen. I apologise for the issue, please excuse me, I am not used to pushing updates to public repositories.

The plugin now features an options pages which can be found under Settings > Facebook Like Thumbnail. You can specify your default thumbnail image on that page, no more code edits are required. This was a necessary move as the users would have to edit the plugin to specify their default image after every upgrade.

The plugin now supports featured thumbnails and NextGEN galleries (other than the slideshow ones).

The plugin picks the thumbnail in the following order (whichever is found first)

  • If its a post or page
    • Featured Thumbnail
    • First Image in the post
    • Default
  • If its a Front Page or Search Page
    • Default
  • Anything else
    • First image in the first post of the loop
    • Default

Facebook Like Thumbnail

Author: Ashfame, version: 0.4, updated: December 7, 2016,
Requires WP version: 3.1 or higher, tested up to: 4.7.5.
Download (83 374 hits) (5 votes)

Adding the author avatar on author pages to be used as thumbnail and ignoring smilies as a possible match for thumbnail are on my To-do lists. If you have any suggestions, comments section is all yours.

Also the plugin can be totally uninstalled by using the delete option from WordPress dashboard, it won't leave anything behind in the database.

I have tried to keep the plugin as fast as it can be. If any developer can provide any suggestions/improvements, I would love that. If you have any questions or facing any issues because of the early upgrade or need any help, give me a shout in the comments.

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.