In the second part of this tutorial we will extend the widget with more options. Let’s start by defining what sort of options we want it to have.

  • Show timestamps
  • Discover Hyperlinks
  • Discover @replies
  • Discover avatar
  • Followers count

You can download the extended plug-in here.

Step 1: Getting the form ready for the new options

First of all we need to create the new options in the widget. Find the form() function and add the new form fields to it. Copy the code and add it at the end of the HTML.

<p><label for="<?php echo $this->get_field_id('timestamps'); ?>"><?php _e('Show timestamps:'); ?> <input id="<?php echo $this->get_field_id('timestamps'); ?>" name="<?php echo $this->get_field_name('timestamps'); ?>" type="checkbox" <?php if($timestamps!=""){ echo "checked='checked'"; } ?> /></label></p>
<p><label for="<?php echo $this->get_field_id('hyperlinks'); ?>"><?php _e('Discover Hyperlinks:'); ?> <input id="<?php echo $this->get_field_id('hyperlinks'); ?>" name="<?php echo $this->get_field_name('hyperlinks'); ?>" type="checkbox" <?php if($hyperlinks!=""){ echo "checked='checked'"; } ?> /></label></p>
<p><label for="<?php echo $this->get_field_id('replies'); ?>"><?php _e('Discover @replies:'); ?> <input id="<?php echo $this->get_field_id('replies'); ?>" name="<?php echo $this->get_field_name('replies'); ?>" type="checkbox" <?php if($replies!=""){ echo "checked='checked'"; } ?> /></label></p>
<p><label for="<?php echo $this->get_field_id('avatar'); ?>"><?php _e('Discover avatar:'); ?> <input id="<?php echo $this->get_field_id('avatar'); ?>" name="<?php echo $this->get_field_name('avatar'); ?>" type="checkbox" <?php if($avatar!=""){ echo "checked='checked'"; } ?> /></label></p>

These are all check boxes that will turn on/off the options in the widget.

Step 2: Making Sure Your Form is Saving the new options

To make the form save the new options that we added in the html we need to edit the form() and update() functions.

In the form() function add this in the code before the html of the form.

$timestamps = esc_attr($instance['timestamps']);
$replies = esc_attr($instance['replies']);
$hyperlinks = esc_attr($instance['hyperlinks']);
$avatar = esc_attr($instance['avatar']);

In the update function add this code just before return $instance;

$instance['timestamps']=$new_instance['timestamps'];
$instance['replies']=$new_instance['replies'];
$instance['hyperlinks']=$new_instance['hyperlinks'];
$instance['avatar']=$new_instance['avatar'];

Step 3: Creating the set of functions for the options

To make the new options we need to extend the BS_Twitter class by adding the new set of functions. All of the new functions will be added after the widget() function.

function bs_tweeter_hyperlinks($text) {

$text = preg_replace('/\b([a-zA-Z]+:\/\/[\w_.\-]+\.[a-zA-Z]{2,6}[\/\w\-~.?=&%#+$*!]*)\b/i',"<a href=\"$1\" class=\"twitter-link\">$1</a>", $text);

$text = preg_replace('/\b(?<!:\/\/)(www\.[\w_.\-]+\.[a-zA-Z]{2,6}[\/\w\-~.?=&%#+$*!]*)\b/i',"<a href=\"http://$1\" class=\"twitter-link\">$1</a>", $text);

$text = preg_replace("/\b([a-zA-Z][a-zA-Z0-9\_\.\-]*[a-zA-Z]*\@[a-zA-Z][a-zA-Z0-9\_\.\-]*[a-zA-Z]{2,6})\b/i","<a href=\"mailto://$1\" class=\"twitter-link\">$1</a>", $text);

$text = preg_replace('/([\.|\,|\:|\Ў|\ї|\>|\{|\(]?)#{1}(\w*)([\.|\,|\:|\!|\?|\>|\}|\)]?)\s/i', "$1<a href=\"http://twitter.com/#search?q=$2\" class=\"twitter-link\">#$2</a>$3 ", $text);

return $text;

}

function bs_tweeter_users($text) {

$text = preg_replace('/([\.|\,|\:|\Ў|\ї|\>|\{|\(]?)@{1}(\w*)([\.|\,|\:|\!|\?|\>|\}|\)]?)\s/i', "$1<a href=\"http://twitter.com/$2\" class=\"twitter-user\">@$2</a>$3 ", $text);

$text =  preg_replace('/(^|\s)#(\w+)/', '\1#<a href="http://search.twitter.com/search?q=%23\2">\2</a>', $text);

return $text;

}

function bs_string_remover($tweet, $username) {

$string_length = strlen($username);

$tweet = substr_replace($tweet, '', 0, $string_length+1);

return $tweet;

}

function bs_twitter_followers_counter($username, $cache) {

$cache_file = $cache."/".md5($username);

if (is_file ( $cache_file ) == false) {

$cache_file_time = strtotime ( '1984-01-11 07:15' );

} else {

$cache_file_time = filemtime ( $cache_file );

}

$now = strtotime ( date ( 'Y-m-d H:i:s' ) );

$api_call = $cache_file_time;

$difference = $now - $api_call;

$api_time_seconds = 3600*24;

if ($difference >= $api_time_seconds) {

$api_page = 'http://twitter.com/users/show/' . $username;

$xml = file_get_contents ( $api_page );

$profile = new SimpleXMLElement ( $xml );

$count = $profile->followers_count;

if (is_file ( $cache_file ) == true) {

unlink ( $cache_file );

}

touch ( $cache_file );

file_put_contents ( $cache_file, strval ( $count ) );

return strval ( $count );

} else {

$count = file_get_contents ( $cache_file );

return strval ( $count );

}

}

function bs_relative_time( $timestamp ){

if( !is_numeric( $timestamp ) ){

$timestamp = strtotime( $timestamp );

if( !is_numeric( $timestamp ) ){

return "";

}

}

$difference = time() - $timestamp;

$periods = array( "sec", "min", "hour", "day", "week", "month", "years", "decade" );

$lengths = array( "60","60","24","7","4.35","12","10");

if ($difference > 0) { // this was in the past

$ending = "ago";

}else { // this was in the future

$difference = -$difference;

$ending = "to go";

}

for( $j=0; $difference>=$lengths[$j] and $j < 7; $j++ )

$difference /= $lengths[$j];

$difference = round($difference);

if( $difference != 1 ){

$periods[$j].= "s";

}

$text = "$difference $periods[$j] $ending";

return $text;

}

function bs_cache_avatar($username){

$cache_file =ABSPATH.'wp-content/plugins/bs_twitter/cache/'.md5($username).'.jpg';

if (is_file ( $cache_file ) == false) {

$cache_file_time = strtotime ( '1984-01-11 07:15' );

} else {

$cache_file_time = filemtime ( $cache_file );

}

$now = strtotime ( date ( 'Y-m-d H:i:s' ) );

$api_call = $cache_file_time;

$difference = $now - $api_call;

$api_time_seconds = 3600*24;

if ($difference >= $api_time_seconds) {

$xml = simplexml_load_file("http://twitter.com/users/".$username.".xml");

$ch = curl_init($xml->profile_image_url);

$fp = fopen($cache_file, "w");

curl_setopt($ch, CURLOPT_FILE, $fp);

curl_setopt($ch, CURLOPT_HEADER, 0);

curl_exec($ch);

curl_close($ch);

fclose($fp);

}

return get_bloginfo('url').'/wp-content/plugins/bs_twitter/cache/'.md5($username).'.jpg';

}

Let’s take a look at the functions one by one.

  • bs_tweeter_hyperlinks – will discover the hyperlinks in the content of the tweet and add the link to it.
  • bs_tweeter_users – will discover the users in the tweet content and add the link to the users profile on twitter.
  • bs_string_remover – will remove the users from the content when needed.
  • bs_twitter_followers_counter – is a function that will display the followers number also cache it so we don’t send requests to the twitter api every time we refresh the page on the front end
  • bs_relative_time – shows the tweet time in relative time.
  • bs_cache_avatar – displays your avatar before every tweet and also stores the image locally on your site.

Step 4: Displaying the new set of functionalities on the front end

In the widget function we need to change the code so we can display the new set of options that we created. To do this we will change the function completely. Just copy and paste the new widget function over the existing one.

function widget($args, $instance) {

extract($args);

$title = apply_filters('widget_title', $instance['title']);

if ( empty($title) ) $title = false;

$twitter_username = trim($instance['twitter_username']);

$number = absint( $instance['number'] );

$timestamps = esc_attr($instance['timestamps']);

$replies = esc_attr($instance['replies']);

$hyperlinks = esc_attr($instance['hyperlinks']);

$avatar = esc_attr($instance['avatar']);

$cache_path = ABSPATH.'wp-content/plugins/bs_twitter/cache';

if($title){

echo $before_title;

echo $title;

echo ' - <small>'.$this->bs_twitter_followers_counter($twitter_username, $cache_path)." Followers</small>";

echo $after_title;

}

echo $before_widget;

if (class_exists('SimplePie')) {

$feed = new SimplePie();

$feed->set_feed_url('http://www.twitter.com/statuses/user_timeline/'.$twitter_username.'.rss');

$feed->set_cache_location($cache_path);

$feed->enable_cache(true); //disable caching

$feed->set_cache_duration(1800); //The number of seconds to cache for. 60 is 1 minute, 600 is 10 minutes, 900 is 15 minutes, 1800 is 30 minutes.

$feed->set_timeout(50);

$success = $feed->init();

$feed->handle_content_type();

if ($success):

echo "<ul class='bs_twitter_feed'>";

foreach ($feed->get_items(0, $number) as $item):

if ($item) {

?>

<li>

<?php

$content = $this->bs_string_remover($item->get_title(), $twitter_username);

if($hyperlinks!=""){

$content=$this->bs_tweeter_hyperlinks($content);

}

if($replies!=""){

$content=$this->bs_tweeter_users($content);

}

if($avatar !=""){

echo '<div><a href="'.$item->get_permalink().'"><img src="'.$this->bs_cache_avatar($twitter_username).'" /></a></div>';

}

echo $content;

if($timestamps!=""){

echo '<span><abbr title="'.$item->get_date().'">'.$this->bs_relative_time(strtotime($item->get_date())).'</abbr></span>';

}

?>

</li>

<?php

} // end if there is an item

endforeach;

echo "</ul>";

if($twitter_username !=""){

echo "<a class='follow' href='http://twitter.com/".$twitter_username."'>More ...</a>";

}

endif; //success

}

echo $after_widget;

}

That’s it! You can take a look at the new code and if you have any questions feel free to comment bellow.

Bookmark and Share

There are a lot of Twitter widgets for WordPress but in my experience none of those utilize the powerful SimplePie PHP class that is in the WordPress core. SimplePie is a powerful RSS reader class that has very nice built-in caching system since as we all know the Twitter API is limited to only 150 requests per hour creating problems with high traffic websites.

You can download the plug-in here.

Step 1: Getting the plug-in ready

Create a folder and name it bs_twitter. In that folder, create a PHP file and name it the same as the folder i.e. bs_twitter. Also, in the bs_twitter folder create a folder and name it cache. This will be the main plug-in file. Now, include the SimplePie class and add the activation/deactivation hooks for the plug-in.

register_activation_hook(__FILE__, 'bs_twitter_activate');
register_deactivation_hook(__FILE__, 'bs_twitter_deactivate');
if ( file_exists(ABSPATH . WPINC . '/class-feed.php') ) {
	@require_once (ABSPATH . WPINC . '/class-feed.php');
}
function bs_twitter_activate () {
}
function bs_twitter_deactivate () {
}

Step 2: Have the widget code prepared

Starting from WordPress 2.8, creating a widget has become easier with the widget API. This code needs to be pasted to the widgets.php file:

• BS_Twitter is both the name of the class, as well as the name of the first function (the constructor). The constructor contains the code needed to setup the widget – it’s called Twitter Posts.

• form() generates the form that you see in the widget management page in WordPress.

• update() updates the options you enter in the form when the widget configuration is saved.

• widget() displays the actual output of the widget in the main site.

• The last part of the code hooks into WordPress’ widget initialization and instructs it to register your widget

class BS_Twitter extends WP_Widget {
	function BS_Twitter() {
		$widget_ops = array( 'classname' => 'twitter_widget', 'description' => 'Show your latest Tweets' );
				$this->WP_Widget( 'twitter_widget', 'Twitter Posts', $widget_ops);
	}
	function form($instance) {
	}
	function update($new_instance, $old_instance) {
	}
	function widget($args, $instance) {
	}
}
add_action( 'widgets_init', 'bs_load_widgets' );
function bs_load_widgets() {
	register_widget('BS_Twitter');
}

Step 3: Creating the form

First thing that needs to be done even before you create the form for a widget, you must determine the type of inputs you need. For this specific widget, 3 inputs are needed: title for the widget, Twitter username, and number of tweets to be displayed. If you look at the basic code above, in the form() function you will find a parameter $instance. This basically contains the current values for all inputs in the form (for example, when you save the form with certain values). Therefore, it is needed to pull out the current values of the widgdet and populate the widget input fields with them.

$instance = wp_parse_args( (array) $instance, array('title' => 'Twitter', 'number' => 5, 'twitter_username' => 'abuzz') );
$title = esc_attr($instance['title']);
$twitter_username = $instance['twitter_username'];
$number = absint($instance['number']);
?>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>"> Title: </label>
<input id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('twitter_username'); ?>"> Twitter username: </label>
<input id="<?php echo $this->get_field_id('twitter_username'); ?>" name="<?php echo $this->get_field_name('twitter_username'); ?>" type="text" value="<?php echo $twitter_username; ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('number'); ?>"> Number of twits: </label>
<input id="<?php echo $this->get_field_id('number'); ?>" name="<?php echo $this->get_field_name('number'); ?>" type="text" value="<?php echo $number; ?>" />
</p>
<?php

Maybe this seems as heavy code, but it actually is very simple. It creates a HTML form containing several changes. Instead of using id’s and name’s, you have to use get_field_id(). This needs to be done because if there are multiple instances of a widget and only one single ID, there will be errors. WordPress takes care of it for you if you use the said function. The other thing is that the value of the input fields is generated using PHP.

Step 4: Making Sure Your Form is Saved

To make sure your form updates, you need to configure your update() function. This is very simple. By default, WordPress gives 2 parameters – the old instance, and the new instance. We basically don’t really need the old instance because the old instance is only used if there are values that you may not want to change. Paste in this code into the update() function:

$instance=$old_instance;
$instance['title'] = strip_tags($new_instance['title']);
$instance['twitter_username']=$new_instance['twitter_username'];
$instance['number']=$new_instance['number'];
return $instance;

Step 5: Output the Widget HTML

This is the final step, and it makes sure you widget displays HTML on the front end. Now that we have the user inputs set up, we can just use the inputs to communicate with the Twitter API and display tweets. The first step in the widget() function is to get the values of the user inputs. Copy and paste this code:

extract($args);
$title = apply_filters('widget_title', $instance['title']);
if ( empty($title) ) $title = false;
$twitter_username = $instance['twitter_username'];
$number = absint( $instance['number'] ); 
if ( empty($twitter_username) ) return;

Once this is done, paste this code:

if($title){
echo $before_title;
echo $title;
echo $after_title;
}
echo $before_widget;
if (class_exists('SimplePie')) {
$feed = new SimplePie();
$feed->set_feed_url('http://www.twitter.com/statuses/user_timeline/'.$twitter_username.'.rss');
$feed->set_cache_location(ABSPATH.'wp-content/plugins/bs_twitter/cache');
$feed->enable_cache(true); //disable caching
$feed->set_cache_duration(1800); //The number of seconds to cache for. 60 is 1 minute, 600 is 10 minutes, 900 is 15 minutes, 1800 is 30 minutes.
$feed->set_timeout(50);
$success = $feed->init();
$feed->handle_content_type();
if ($success):
echo "<ul>";
foreach ($feed->get_items(0, $number) as $item):
if ($item) {
?>
<li>
<a href="<?php echo $item->get_permalink(); ?>">
<?php echo $item->get_title() ?>
</a>
</li>
<?php
} // end if there is an item
endforeach;
echo "</ul>";
endif; //success
}
echo $after_widget;

This is a great plug-in for those who have high-traffic websites. This tutorial makes it easier to create customized Twitter widget. Options can be added and change to suite your needs.

This is just the first tutorial of the series that is coming up in the next period. We will explain how to customize this widget and adding more features such as adding the user avatar, discovering hyperlinks and hashtags and much more.

Bookmark and Share

TimThumb 2.0 – Use it to avoid your WordPress from getting hacked

WordPress has been long criticized for security issues although by just applying certain steps one can make it secure and with proper regular backup policy, one need not worry at all.  You must be wondering that why am I talking about security suddenly – well, TimThumb one of the popular library that is used in various WordPress themes has serious security flaws that can be compromised to hack the servers. The flaw was found by Mark Maunder and has started working with the Ben Gillbanks, original developer to come up with TimThumb 2.0. Here’s what Matt has to say about the whole issue around it and how following standards can make life easy in the eco-system -

Because the code is commonly embedded in themes it’s not easy to discretely update like it would be if the code were a plugin, and even when a theme is updated people are hesitant to update because they often customize theme code rather than making child themes, so if they were to overwrite their theme with a new version they’d lose their modifications. That, combined with the severity of the flaw, means that this is one of the more serious issues in the WordPress ecosystem in a while, even more than normal because it wasn’t in core.

Not that it was Ben’s fault – he never would have imagined that TimThumb would grow to such a level and that most of the theme developers  would start using it instead of WordPress API. I’m not the coder kinds, however according to Ashish Saini, WordPress can generate multiple size of the uploaded images, so if one sticks to the WordPress coding standards then this issue is not an issue for them. We ourselves have been using TimThumb and didn’t realize that it had such a serious flaw [our bad]. We’ll be reaching our clients and will apply TimThumb 2.0 on their WordPess setups to avoid such an issue.

Akismet further becomes de-facto as Anti-blogspam!

HubSpot, internet marketing company has announced the integration of Akismet in their blog platform. I wouldn’t say that it was an expected move, however looking at how blog spam has increased it has become really important for blog platform providers to come up with strong anti-spam solutions. Here’s what Hubspot had to say -

Akismet is the best-in-class comment filtering system available today, one that monitors millions of blogs and forums and keeps up to date on the methods and tricks used by spammers in real time. Akismet has prevented over 30 billion spam comments from appearing on websites over the years, and now HubSpot is also offering you this same high level of protection.

Now there are few services like Akismet, although Akismet seems to be the most effective till this point of time. Although, it’ll be fun to test these services at a bigger level. Here’s the list of anti-blogspam services -

Till this time, I’m kind of sold for Akismet & Defensio – do let us know what you think about them.

Varnish + Apache = Is it better than Nginx?

Well, that’s one question whose answer is yet to be figured. I recently managed to setup a VPS of 512 MB RAM with NGINX, PHP, MySQL, APC along with WordPress Multisite + Custom domain mapping and it all works great! The server is running without any issues and handling decent amount of traffic. The setup doesn’t have WP Super Cache, however I reckon that if I throw WP Super Cache in it then it’ll become one ultimate server setup for hosting WordPress sites.

Although I’m wondering if the whole setup can be just be replaced by Varnish + Apache and the reason, it got me thinking was because I recently stumbled across the article by Donncha, Developer of WP Super Cache. He recently installed Varnish along with Apache and has seen good results. Here’s why Donncha did this setup even though he was on NGINX setup a while back -

I have tried Nginx in the past but could not getting it working without causing huge CPU spikes as PHP went a little mad. In comparison, Varnish was simple to install and set up.

One of the reasons, why a developer will prefer this setup over Nginx setup is because Apache has better support available on the internet and works flawlessly with WordPress. Anyway, if you are the one who loves to play around with servers, are using Apache and want to please your server by removing the load on it then follow this article.

I hope you’ll enjoy this roundup. I’ll continue with these kind of roundups from now on to keep you all up to date with the best links and articles from the WordPress community.

Bookmark and Share

visual-wordpress In our last post, we discussed that how you can make a clone of the live location for WordPress Design & Development and in this post we’ll share that how you can bring back the newly developed theme back to the live location.

This process requires some work because at the time of making the test location live, the live location would already have new content. So, its important to ensure that every thing goes live with the updated content. Well, the pain is far less as compared to fixing the bugs in live environment of high traffic blogs. Lets check out the process that we follow at Blog Design Studio to make the test locations live -

Purpose

We want to make the test location (the one we created using the cloning document), go live!

Pre-requisites

  • SSH enabled FTP account. SSH is secure shell that gives access to the linux servers thus making the process a little technical but fast, secure and we face less issues.
  • Domain name access
  • Web host control panel access for access to database.
  • Putty – Windows based software to access SSH. Download here. [choose A Windows Installer]
  • FileZilla – FTP software | Download here.

Example settings

  1. FTP account with ssh
    1. Username: bdstest
    2. Password: bdstest123456
    3. Public folder location – /public_html/
    4. Test folder location – /public_html/test/
  2. CPanel account details
    1. Domain name: http://bdstest.com
    2. Server IP : 202.143.12.34 {this is made up}
    3. CPanel URL: http://202.143.12.34/cpanel/ [not every webhost comes with CPanel, some come with their own control panel – so you’ll have to follow the instructions accordingly or contact web host.
    4. Username : bdscpanel
    5. Password: bdscpanel123

Pointers –

SSH commands are in Italics

Process to follow

  1. Put the site in maintenance mode (if required).
  2. Upgrade WordPress version of the live location
  3. Export the new content (if any).
  4. Import the content in test location (that we are going to make live)
  5. Make the backup of files on test location
  6. Change the URL structure of the new database (i.e. the one we created in the previous documentation)
  7. Extract the backup files of test location at original location
  8. Disable test location

Process Starts

1. Put the site in maintenance mode: The site should be put in maintenance mode to ensure that if the theme breaks because of the next step (upgrading WordPress) then users will not experience any issues. For this install maintenance mode plugin  and activate it.

2. Upgrade WordPress of Live Location: It’s helpful in exporting the content easily.

  • Go to WordPress dashboard·
  • Go to Dashboard->updates
  • Click on Update automatically

3. Export the new content from Live location: In this step we’ll export the content that we’ve put in the new user that we created in the 9th step of previous document.

  • Go to WordPress dashboard of Live location
  • Go to Tools->Export
  • Under Filters, select the new user that we created in last documentation
  • Click Download Export File, save it somewhere on your hard drive.

4. Import the content in Test Location: In this step we’ll import the content to the test location.

  • Go to WordPress dashboard of Live location
  • Go to Tools->Import
  • Select WordPress out of all the options. If it asks you to install the plugin, then do so.
  • Select Activate & Run Importer (if the installation happens) , else it’ll take you directly to importer.
  • Select the exported file and then upload and import.

5. Make the backup of files on test location:

  • Open Putty [enter the ip address of server or domain name at the place shown in picture 1] & click Open
  • Enter the SSH enabled username & password.
  • ls {lists the files & folders}
  • cd /public_html/test/ {change directory from existing to /public_html/test/}
  • tar -cvf testcontent.tar ./ (this will ensure that all the files in the folder gets packed in a file called testcontent.tar)
  • mv testcontent.tar /public_html (if you have troubles in doing so, then simply use filezilla to move the file to public_html folder via simple drag and drop)
  • Keep the putty window open.

6. Change the URL Structure of the database: Since the database we are using has the URL structure of Test location, so we need to change it back to the live location.

  • Go to phpMyAdmin
  • Select the new location database
  • go to SQL tab and run these sql queries one by one –
    • UPDATE wp_options SET option_value = replace(option_value, ‘http://www.old-domain.com’, ‘http://www.new-domain.com’) WHERE option_name = ‘home’ OR option_name = ‘siteurl’;
    • UPDATE wp_posts SET guid = replace(guid, ‘http://www.olddomain.com’,'http://www.newdomain.com’);
    • UPDATE wp_posts SET post_content = replace(post_content, ‘http://www.old-domain.com’, ‘http://www.new-domain.com’);

Note: if you are making the clone in a sub-folder then then URL in the queries should be like this – http://www.new-domain.com/subfolder [there should be no trailing slash at the end]. In our example old domain will be http://bdstest.com/test & the new domain will be http://bdstest.com

7. Extract the test locations’ backup at original location: Since all the changes have been made, by just extracting the files will ensure that the maintenance mode will get deactivated and the new design will get live as well!

  • Switch back to Putty window and type the following commands.
  • Cd .. (this will bring you back to /public_html/ folder)
  • tar –xvf testcontent.tar (this will ensure that all the files will be merged that were added later in the live site so, you’ll not miss a single thing!)
  • keep the window open for the next step

8. Disable Test location: We’ll disable to test location to ensure that it doesn’t get crawled by search engines. Although, the files in the test location aren’t required, still it doesn’t hurt to keep the folder, it can come handy in odd situations.

  • cd test
  • rm wp-config.php

Congrats! The Site is Live!!! Now, go ahead and start testing to ensure that everything is correct and that there are no bugs left.

Bookmark and Share

I’ve written a fair bit on the topic of securing WordPress based sites and blogs however, it seems that no matter how much I write, it still is less. There is hardly any week that goes by where I don’t hear about the horror stories from our clients and various other friends in the trade whose sites get infected with malware. After handling lot of such cases and doing some research about it, I found out that one of the major reasons why the sites get infected is because its webmaster’s own computer was infected with a malware.

I’ll be also listing various resources that can be used to further strengthen the security however, firstly I would like to put forth my views on the topic of why web-masters should use Mac or Linux. I would only list those points that are logical and none of them are influenced by any sorts. So here’s why I suggest so and how its easy to switch too -

1. To keep yourself safe from viruses :  I’ve used all three OSes and I’ve personally experienced that Mac & Linux aren’t prone to viruses as Windows is and the simple fact is that the market share of Windows is more than 90% and thats why almost every virus is targeted towards Windows Users. So, if you are using any of those two OSes you’d be safe from viruses and thus you reduce the chances of getting your website hacked.

2. For keeping others safe : As I’ve said that majority of cases that I’ve dealt are those where the webmaster’s computer was compromised. Moreover, once the sites are infected, they infect those computer who visit that site and that’s how they spread so quickly! Now, if at the first place the webmaster would have been using linux or mac, it would have ensured that at least they are not making the situation worse.

3. Switching is pretty easy – Most of the users give a reason that they won’t be able to switch because of the incompatibility issue and that they think that it would be pain to switch the platforms because of unavailability of ssoftware. I agree at one time it would have been difficult for most of the people, however web-masters specifically won’t find any issues in choosing these two platforms as most of their tasks are done online, else most of the software required have either a worthy alternative or if you are an open-source fan then you’d surely find most of them available for all three platforms. Here are some of the resources -

Try a gradual switch and start using these OSes and if you really want to run a windows software then you can try WineHQ or CrossOver (commercial) and most likely the software will work fine for you. If the software still doesn’t work and you don’t find any alternative then you can simply use VirtualBox or Parallels to run Windows inside Linux or Mac.

So when we know that for web-masters it can be easy to switch to Mac or Linux then why not use either of those two operating systems and keep yourself and the world safe from those malware? Anyway, enough of ranting – as I said that during my research, I did read quite a bit about security websites, so I would like to share that with you :

How to strengthen the security of your WordPress blog?

  1. Don’t forget to read my articles that I wrote a while back on the topic of securing wordpress.
  2. If possible switch your OS as soon as possible – Don’t think it as a stupid suggestion. Consider this one for sure!
  3. Restrict WordPress admin use by IP Address.
  4. Learn to restrict the FTP server access for specific IPs using VSFTPD – I know that not everyone gets a static IP address from their internet service providers, however use of VPN can certainly [I use StrongVPN] help you get over that problem.
  5. More security steps that can be done through htaccess file, here are some 11 more steps that you can use.
  6. Jeff Starr has created wonderful instructions for securing servers via htaccess and blocking the know malware techniques.
  7. Blocking spam is equally important – Chances are that some spam comment will have the URL to a site that is infected, so its important to ensure that no spam comment passes through.

What else can be done other than IP address, Htaccess tricks?

Some of WordPress’ cool features come from allowing some files to be writable by web server. However, letting an application have write access to your files is a dangerous thing, particularly in a public environment. It is best, from a security perspective, to lock down your file permissions as much as possible and to loosen those restrictions on the occasions that you need to allow write access, or to create special folders with more lax restrictions for the purpose of doing things like uploading images. In short we are talking about CHMOD settings of the server.

All files should be owned by your user account, and should be writable by you and any file that needs write access from WordPress should be group-owned by the user account used by the webserver. Of course, learning this can surely take some time, but if you really want to secure your server, then this is one thing you should focus on!

  • / — the root WordPress directory: all files should be writable only by your user account.
    • EXCEPT .htaccess if you want WordPress to automatically generate rewrite rules for you
  • /wp-admin/ — the WordPress administration area: all files should be writable only by your user account.
  • /wp-includes/ — the bulk of WordPress application logic: all files should be writable only by your user account.
  • /wp-images/ — image files used by WordPress: all files should be writable only by your user account.
  • /wp-content/ — variable user-supplied content: intended by Developers to be completely writable by all (owner/user, group, and public).
    • /wp-content/themes/ — theme files. If you want to use the built-in theme editor, all files need to be group writable. If you do not want to use the built-in theme editor, all files can be writable only by your user account
    • /wp-content/plugins/ — plugin files: all files should be writable only by your user account.
    • other directories under /wp-content/ should be documented by whatever plugin / theme requires them. Permissions may vary.

Plugins that I prefer for securing WordPress

1. WordPress File Monitor - Think of it as a watch dog! It monitors your WordPress installation for added/deleted/changed files. When a change is detected an email alert can be sent to a specified address. So even if you add files using FTP, it will let you know. This is a fantastic way to ensure that no compromised file will go on server without going through its nose.

2. WordPress Firewall – I personally love this plugin. Of course, using this plugin means that you’d lose out on WordPress theme/plugin editing capabilities and few things here and there, however this plugin will ensure that everything will be super secure.

3. Block Bad Queries – Another gem from Jeff Starr. This plugin will ensure that your WordPress site will be safe from known vulnerabilities.

Well there have been countless number of posts on the topic of security and the worst part is that things aren’t improving a little bit. Its important to choose the right web-hosts as well. If this post of mine was a request towards web-masters, Mark Jaquith has asked web hosts to become more secure and to help web-masters in understanding the security of blogs/websites. It is one interesting read, so even if you are not a web host,  I would suggest you to read it.

What are your thoughts about changing the OS for ensuring safe and secure website? Do you think that one should go ahead and change their OS to ensure that their site will remain secure from malware to a large extent? Please share your thoughts in comments.

Bookmark and Share

WordPress has been considered as a memory hog and I can agree to that as I’ve faced the issues in the past as well. If you don’t use plug-ins like WP Super Cache or W3 Total Cache, you’d get an email from your shared hosting provider to upgrade the hosting plan pretty soon. As traffic increases you’d have to change the hosting plan and then the question will arise, to go for managed hosting or unmanaged hosting?

Personally I like things under my control where I can change just about anything as that way I don’t have to depend on anyone and things get done much faster as compared to a situation, where I’d have to call the tech support hoping that the support guy will help me in finishing the task and I’d get less than satisfactory answer. Anyway, to cut the story short, I got an email from my fantastic web hosting company i.e. WPWebHost, however as I was looking for cloud based hosting [I definitely like buzz words], I thought that I would rather go for Rackspace Cloud Servers as I get more control over things. Here are few things that you’d have to keep in mind, if you are interested in going for Cloud Servers -

You do get the complete control of the server but that also means that you have to setup everything from the scratch! You just get a server with a vanilla linux installation and that you’d have to install and configure – web server, database server, take care of the security issues and just about everything that you can imagine! So if you are weak heart then you should not read this guide and instead you should carry on your research for other hosting plans that offer managed servers.

However, More control over server means that you’d be able to have to have a much faster running site and that also means that you will get better rankings in Google!

One of the main purpose for getting the cloud server was that I wanted to run WordPress on Nginx, a much better and light alternative to Apache web server and wanted to play around with HipHop for PHP, pure innovation from Facebook! Here’s what HipHop for PHP is all about [I'm still working on this part and will be sharing my experiences in upcoming posts]-

HipHop transforms your PHP source code into highly optimized C++ and then compiles it with g++ to build binary files. You keep coding in simpler PHP, then HipHop executes your source code in a semantically equivalent manner and sacrifices some rarely used features – such as eval() – in exchange for improved performance.

And now lets find out that how can we setup an optimized web server that would handle lots of traffic with minimum amount of resources that would make your blog load faster as well.

Setting up Linux server from scratch!

Note 1- In this case we are using CentOS 5.3 and all the commands will be mentioned step wise, so you can simply copy and paste them one by one and you should be good to go, I will give explanation of all the steps as we go along -

Note 2 - If you are new to these things, then make sure that you should go through this guide properly and should not skip anything.

1. Setting up basic security

When you get a fresh installed Linux box that you want to use as a web server, it can be vulnerable to various attacks and in order to avoid them we will setup basic security settings that a linux web server should have and for that you should connect to your linux server through SSH [ssh root@YOUR SERVER IP ADDRESS] and then run the following commands -

  • passwd [First time you login as Root and we must change the password of the root. Here's a guide for keeping secure password.]
  • adduser wordpress
  • passwd wordpress
  • usermod -a -G wheel wordpress
  • visudo [for newbies - vi is a text editor and here are the commands that will help you operate it.]
  • Find # %wheel  ALL=(ALL)   ALL and remove # from it.

These commands will basically setup a new user called “wordpress” in the Wheel group and will ensure that the user will be able to gain the root privileges at required times. If you want to use a different username then simply replace “wordpress” with your desired name.

Now we’d configure SSH to disable the root access and change the port to ensure that no hacker will be able to easily access the server. For that fun the following commands -

  • nano /etc/ssh/sshd_config

And you need to ensure that the following settings should be in the whole file. Nano is also a text editor and it displays the most basic and useful commands at the bottom so you won’t need to go through a guide. I definitely like it more than vi. Anyhow, here are the settings that you need to keep in SSH’s configuration file -

  • Port 30000  <— change to a port of your choosing
  • Protocol 2
  • PermitRootLogin no
  • X11Forwarding no
  • UsePAM no
  • UseDNS no
  • AllowUsers wordpress  <——- of course, this will be the username that you chose in the first steps.

Once we are done with the SSH configuration, we’d make changes in the IP Tables which is like the firewall settings to only allow certain ports that would be open. Run the following commands to ensure that IP Table settings are as per the way we desire -

  • iptables -L  <—- this will show the current IP Table configuration. Just copy and paste it in a text file.
  • iptables -F  <– this flushes the existing IP table rules. The following commands set desired new rules.
  • iptables -A INPUT -i lo -j ACCEPT
  • iptables -A INPUT -i ! lo -d 127.0.0.0/8 -j REJECT
  • iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
  • iptables -A OUTPUT -j ACCEPT
  • iptables -A INPUT -p tcp –dport 80 -j ACCEPT
  • iptables -A INPUT -p tcp –dport 443 -j ACCEPT
  • iptables -A INPUT -p tcp -m state –state NEW –dport 30000 -j ACCEPT  <— this should be the port that you selected in last settings.
  • iptables -A INPUT -p icmp -m icmp –icmp-type 8 -j ACCEPT
  • iptables -A INPUT -j REJECT
  • iptables -A FORWARD -j REJECT
  • service iptables save
  • /etc/init.d/sshd reload    <— this will reload the new settings.

Now open a new tab of Terminal (Mac Users)/Putty (Windows Users) and try to connect to the server using the new settings that we’ve put all this while. If it connects then everything is fine, else go back to the previous tab, flush the settings again and try the above commands again.

  • ssh -p 30000 wordpress@Your Server’s IP Address

2. More CentOS configuration and setting development tools

In this section we’d configure CentOS to use external repositories, so that installation of various tools becomes easier and that in case you want to install any software then it should be able to find the dependencies without much issues. One of the most known repository other than default one is RPMFORGE and we need to configure our server for that. Please follow this article to install RPMFORGE. Once we are done with that, we will run the following commands -

  • sudo yum update
  • sudo yum groupinstall ‘Development Tools’ ‘Development Libraries’

This will update the YUM and will install most of the development tools and its libraries that you’d need in future. I hope that most of you would not find problems till this point of time as these are some simple steps, however things will start getting a little complicated when we’ll start installing Nginx, WordPress, MySQL, caching systems configuring them for optimum results. So gear up for the fun and awesome challenge that we’ll experience in forthcoming posts.

Bookmark and Share

phpmyadmin.jpg

As we all know that WordPress is powered through PHP & MySql and by far phpMyAdmin is considered to be most adopted way of managing the MySQL databases. Most of the web hosting companies have it installed for their users and most of the users find it pretty intuitive. Same goes with WordPress these days. At times, it looks like a perfect marriage between the two!

When it comes to WordPress, there are various obnoxious situations that we can avoid with the help of phpMyAdmin and its neat little tricks. Thankfully, Many tech savvy and generous bloggers have shared those neat tricks with the world and in this post, I would like to accentuate them.

Tricks related to WordPress Users

1. Reset WordPress user password using phpMyAdmin – by WPBeginner.
2. Change WordPress admin username – by Mahesh Kukreja
3. Disable New User Registration – by Rajesh Patel [I don't see any reason for taking this step as it can be easily done through options under settings, but still you never know when these things can come handy].
4. Change post attribution from one author to another – WpRecepies.

Tricks related to WordPress Posts & Comments

1. Delete all spam comments using phpMyAdmin – by Technofriends
2. Batch delete posts revisions – by WPRecepies
3. Restore commenting back using repair feature of WordPress – by Speed of Creativity [of course, this is more of a troubleshooting trick, but one handy trick that may help you at certain time]

Troubleshooting WordPress using phpMyAdmin when nothing works

There are times, when you might be playing with some broken plugin/theme or not an updated plugin/theme that can cause WordPress to break then it gets little hard to Troubleshoot things if you don’t have the database backup already. However, you can save yourself by ensuring that you can create the database backup or restoring it with the help of phpMyAdmin -

1. Create WordPress database backup using phpMyAdmin.
2. Restore WordPress database backup using phpMyadmin.

Various other useful tricks

1. Move WordPress blog from one domain to another.
2. 12 quick and easy MySql tricks. [This is not through phpMyAdmin, however can come in handy through SSH]
3. Running multiple WordPress blog on single database. [not recommended, however if you are running out of number of database then this is the only solution - else change your hosting provider - Here's the guide to do so]

If you know more tricks, feel free to share it with us as we’ll keep this page up to date with all those wonderful tricks!

Bookmark and Share