Author Archive

WordPress Tutorial: Inserting Widgets With Shortcodes


  

The shortcode ability of WordPress is extremely underrated. It enables the end user to create intricate elements with a few keystrokes while also modularizing editing tasks. In a new theme we’re developing, I decided to look into adding widgets anywhere with shortcodes, and it turns out that it isn’t that difficult.

Some of the widgets that can be added with shortcodes.
Some of the widgets that can be added with shortcodes.

This tutorial is for experienced WordPress users; we will be looking at the widgets object and shortcodes without delving into too much detail about how and why they work. If you are looking for more information, I suggest reading Mastering WordPress Shortcodes and the Widgets API article in the Codex.

Grabbing A Random Widget

The first thing I looked into was how to output any widget without shortcodes. Once done, implementing a shortcode is a relatively trivial matter. Digging around in the Codex, I found the the_widget() function, which does just what I want.

It takes three parameters:

  • The widget’s class name,
  • The widget’s instance settings,
  • The widget’s sidebar arguments.

Once I saw this, my face lit up. Not only can I output a widget anywhere, but I can pass different sidebar arguments to any widget. This is great because I can specify parameters such as before_widget and after_widget.

This also opens up the possibility of easily changing the style of the widget from within the shortcode, but more on that later.

After applying some CSS, the calendar widget can be added anywhere.
After applying some CSS, the calendar widget can be added anywhere.

Output Buffering

When adding a shortcode, you scan the text for a particular string, do something with it and return the result you want to see. It’s obvious that we will be using the_widget(), but that function only echoes content. To get around this problem we’ll be using output buffering.

Take a look at the following two examples; the result is exactly the same.

the_widget( 'WP_Widget_Archives' ); 
ob_start();
the_widget( 'WP_Widget_Archives' ); 
$contents = ob_get_clean();
echo $contents;

First we start our buffer. From this point on, anything that is echoed goes into our buffer instead of actually being echoed. By using ob_get_clean(), we can pull the contents of the buffer into a variable (and also clear the buffer). Once this is done we can echo that variable, or pass it on by returning it if we’re in a function.

Creating The Shortcode

Now we know everything we need, so let’s create the skeleton of our shortcode. First we need to figure out what arguments we need to pass, and what arguments we want to allow the user to pass via the shortcode tag.

  • Widget type – Which widget do we want to show;
  • Title – The title of the widget (used in the instance parameter);
  • Other instance parameters;
  • Other sidebar arguments.

I’ll admit that this is a bit vague. The reason is that each widget will need a separate set of possible arguments due to the varied functionality they have. For an archive widget, we can specify whether or not we want the post count. For a category widget, we could also specify the hierarchical attribute.

Solving this problem requires a flexible shortcode, and good end-user documentation.

The best way to make sure the shortcode is used properly is to provide good documentation.
The best way to make sure the shortcode is used properly is to provide good documentation.

The Shortcode Skeleton

add_shortcode( 'widget', 'my_widget_shortcode' );
function my_widget_shortcode( $atts ) {

// Configure defaults and extract the attributes into variables
extract( shortcode_atts( 
	array( 
		'type'  => '',
		'title' => '',
	), 
	$atts 
));

$args = array(
	'before_widget' => '<div class="box widget">',
	'after_widget'  => '</div>',
	'before_title'  => '<div class="widget-title">',
	'after_title'   => '</div>',
);

ob_start();
the_widget( $type, $atts, $args ); 
$output = ob_get_clean();

return $output;

There are two common attributes all shortcodes will have. The type is where the user will specify the widget type, and the title is where the user specifies the title (no surprises there).

Once we have our $atts, we figure out the $args — the widget’s sidebar parameters. Since this is a commercial theme, we don’t need to give the user control over these arguments, so they are just hard coded for now.

In the final section we’ll put it all together to create the final widget.

Extending the Shortcode

Once this is done we can get crazy with our shortcode parameters. One example is allowing the user to pick a scheme. For our example, this is dark or light, but you could easily specify an exact color.

All we need to do is add an argument to the shortcode, add a CSS class to our widget based on this argument and let our style sheet do the rest.

add_shortcode( 'widget', 'my_widget_shortcode' );

function my_widget_shortcode( $atts ) {

// Configure defaults and extract the attributes into variables
extract( shortcode_atts( 
	array( 
		'type'   => '',
		'title'  => '',
		'scheme' => 'light'
	), 
	$atts 
));

$args = array(
	'before_widget' => '<div class="box widget scheme-' . $scheme . ' ">',
	'after_widget'  => '</div>',
	'before_title'  => '<div class="widget-title">',
	'after_title'   => '</div>',
);

ob_start();
the_widget( $type, $atts, $args ); 
$output = ob_get_clean();

return $output;

If you need to make this even more flexible, you can allow a background color to be specified, you can add the $args using parameters from the shortcode, and much more.

This solution works perfectly with custom widgets as well. All you need to do is add the class name as the type and accommodate for its specific instance settings

Conclusion

By now you should be on your way to creating wonderful things with this shortcode. It is great for end users and also a very useful tool to test widgets before releasing a theme.

We use this in our themes to make them even more flexible for our users. The ability to put anything anywhere, easily, is one that all themes should have!

(cp)


© Daniel Pataki for Smashing Magazine, 2012.


Essentials: Utilizing User Roles In WordPress


  

Roles have been an integral part of WordPress for quite some time now — many functions associated with managing them have been in place since version 2.0.0. Despite this longevity, they are rarely utilized which is a shame since they allow for the easy setup of custom user types (and also have the ability to micro-manage them). In this article, you’ll learn everything you need to utilize user roles in WordPress and make the most of this incredible built-in functionality.


Large view.

Terminology

The main terms to know are “role” and “capability”. Capabilities are the core of the system, they represent the things you can do. An example of a capability is switch_themes. A user who has this capability is able to change the look of the website using the Appearances section in the admin. Those who do not have this capability will not be able to do so.

Roles are simply a named set of capabilities. Imagine you have capabilities like edit_post, add_user and so on. Instead of listing all 50 of them for each and every user who you’d like to be an admin, simply assign each user the “admin” role and then assign all the capabilities to that role.

The Default Setup

By default, WordPress has six roles and about 57 capabilities. Each role has a different combination of capabilities which endow the user with the appropriate rights and privileges.

For example, a contributor can edit and delete his own posts, but cannot control when these posts are published (and cannot delete those posts once they are published). This is because they have the edit_posts and delete_posts capabilities, but they do not have the publish_post and delete_published_post capabilities.

The default setup offered by WordPress is very well thought out and should not be modified, only added to. If it is changed, you could face difficult problems later on — like a contributor being able to remove posts from your website, or an admin not being able to change the theme.

When New Roles And Capabilities Are Needed

New roles usually come hand-in-hand with new capabilities. Usually, we first create a set of new capabilities, which are held by the admin (and a new role, as well). Let’s look at an example.

If you have a large website, chances are you have a marketing team. This team doesn’t need to be able to edit and publish posts, but they do need access to advertising stats, trending search topics, etc. Perhaps it would also be beneficial to allow them to manage categories and comments for SEO purposes and customer satisfaction, respectively.

Our first order of business is to look at the advertising stats and trending searches. This is not something WordPress offers by default, so let’s presume it has been built as a plugin. Let’s create a capability called view_stats. This will be given to the marketing people and of course to the admin. Other users — like editors and authors — do not need to see the stats (which, in many case, is sensitive data) so they will not receive this capability.

Our second task is to decide what other capabilities our marketing people need. Based on our assumptions above, they will need the read, manage_links, manage_categories and moderate_comments capabilities.

Lastly, we would use some coding chops to create a new role named “Marketing�, and assign the above-mentioned capabilities to it. Once that has been done, we are able to appoint the “Marketing� role to any user within the “Add User� and “Edit Profile� page.

Basic WordPress Functions

To manage roles and capabilities effectively, all you need is five very straightforward functions:

  • add_role() — Enables you to add a custom role
  • remove_role() — Enables you to remove a custom role
  • add_cap() — Enables you to add a custom capability to a role
  • remove_cap() — Enables you to remove a custom capability from a role
  • get_role() — Gets information about a role as well as associated capabilities

If you would like to view the documentation for these functions, you can take a look at the Roles and Capabilities section in the Codex.

Implementing New Roles And Capabilities

The full implementation of roles and capabilities requires more than just the five functions I mentioned. We’ll also need to use functions for checking capabilities, we’ll need features which are only available to certain roles, and so on.

Adding the Roles and Capabilities

$marketing = add_role( 'marketing', 'Marketing', array(
    'read' => true,
		'manage_links', 
    'manage_categories', 
    'moderate_comments',
    'view-stats'
));

$role = get_role( 'administrator' );
$role->add_cap( 'view-stats' );

The function above will add our new “Marketing” role. It adds four capabilities which are already included in WordPress and a fifth one which is a custom capability. As you can see, no special coding is required to add custom caps — just include them in the array when adding the role. Once we add the new role, we make sure to add our new capability to the admin role as well.

Note that the add_role() fuction returns a WP_Role object on success or NULL if the role already exists.

Since the above code will be used in a plugin, the best way to use it is to utilize hooks, and to add the capabilities to the administrator only when we first create the role.

add_action( 'admin_init', 'add_custom_role' );

function add_custom_role() {
    $marketing = add_role( 'marketing', 'Marketing', array(
        'read' => true,
	    	'manage_links', 
        'manage_categories', 
        'moderate_comments',
        'view-stats'
    ));

		if( null !== $marketing ) {
        $role = get_role( 'administrator' );
        $role->add_cap( 'view-stats' );
    }
}

Checking for Capabilities and Roles

Once we have our system in place we can check for capabilities and roles. This allows us to make sure that only users with the right capabilities can do certain things.


add_action('admin_menu', 'register_stats_Page');

function register_stats_Page() {
    add_menu_page( 'Marketing Info', 'Marketing Info', 'view_stats', 'marketing-info', 'show_marketing_info' );
}

function show_marketing_info(){
   if( ! current_user_can( 'view-stats' ) ) {
      die( 'You are not allowed to view this page' );
   }
   echo "

This is the marketing stats page

"; }

The code above will add a top level menu to the admin area for our marketing stats page. The add_menu_page() function allows you to specify a capability (the third argument) which determines whether or not the menu is shown.

Note that even though the add_menu_page() function itself takes the capability as an argument, we still need to check for it in the function which displays the content of the page.

This leads us into our next two functions nicely: current_user_can() and user_can().

If you want to check whether or not the currently logged-in user has a specific capability, simply use the following format:

if( current_user_can( 'any_capability' ) ) {
    // The user has the capability
}
else {
    // The user does not have the capability
}

If you would like to check whether or not an arbitrary user has a specific capability, use the user_can() function:

if( user_can( 45, 'any_capability' ) ) {
    // The user with the ID of 45 has the capability
}
else {
    // The user with the ID of 45 does not have the capability
}

In addition to capabilities, both fucntions can check for roles as well:

if( current_user_can( 'marketing' ) ) {
    // The current user is a marketing person
}
else {
    // The current user is not a marketing person
}

Creating User Types

While not an official term, I call different roles “user types” when they require many different front-end changes. Say you’re building a theme marketplace, for example. Apart from the administrator who oversees all (and the authors who would write in the company blog) you also have buyers and sellers. These are both registered users of your website but would require somewhat differing front-ends.

The profile page of a buyer would most likely show the number of things he’s bought, how frequently he buys stuff and when logged in, he would see a list of downloads.

A seller’s profile would be a portfolio of his work, his most popular items, and so on. When logged in he should probably see sales statistics.

Figuring Out Roles and Permissions

To make things simple, users either buy or sell, and cannot do both. Let’s create the two roles with a set of capabilities (off the top of my head…):

add_action( 'admin_init', 'add_custom_roles' );

function add_custom_roles() {
    $seller = add_role( 'seller', 'Seller', array(
        'read' => true,
	    	'delete_posts' => true,
	    	'edit_posts' => true,
	    	'delete_published_posts' => true,
	    	'publish_posts' => true,
	    	'upload_files' => true,
	    	'edit_published_posts' => true,
        'view_sales' => true,
        'moderate_comments' => true
    ));

    $role = get_role( 'administrator' );

		if( null !== $seller ) {
        $role->add_cap( 'view_sales' );
        $role->add_cap( 'view_others_sales' );
   }

    $buyer = add_role( 'buyer', 'Buyer', array(
        'read' => true,
        'add_payment' => true,
        'download_resources' => true
    ));

		if( null !== $buyer ) {
        $role->add_cap( 'add_payment' );
        $role->add_cap( 'add_others_payment' );
        $role->add_cap( 'download_resources' );
        $role->add_cap( 'download_others_resources' );
   }

}

The idea here is that sellers are like authors, who will store sellable items as posts. Therefore, they receive the capabilities of an author. In addition, they can also view sales stats for their own items.

In addition to viewing items, buyers can also add payments and download files related to items that they buy.

Admins receive all these permissions, but in addition, they may view the statistics of any other user, add payments to any account, and may download resources for any item.

Frontend Implementation

From here on out it’s a matter of using our role and capability checking functions to determine who sees what. Let’s take a look at a couple of examples:

Listing Users

If we list all the users on the website, we could show the items bought for the buyers and the items sold for the sellers. Here’s how:

<!-- 
	User Data comes from a WordPress user object stored in the $user variable 
--> 

<div class='user'>
	<div class='row'>
		<div class='threecol'>
			<?php echo get_avatar( $user->ID, 120 ) ?>
		</div>
		<div class='sixcol'>
			<h1><?php echo $user->display_name ?></h1>
			<?php echo $user->description ?>
		</div>
		<div class='threecol last'>
			<?php if( user_can( $user->ID, 'buyer' ) ) : ?>	
				<div class='counter'>
					<span class='number'><?php get_purchases_count( $user->ID ) ?></span>
					<span class='text'>purchases</span>
				</div>
			<?php else ?>
				<div class='counter'>
					<span class='number'><?php get_sales_count( $user->ID ) ?></span>
					<span class='text'>sales</span>
				</div>			
			<?php endif ?>
		</div>
	</div>
</div>

Most of this is plain old HTML, but the important thing to take away is how the counter is created. Note that the get_purchases_count() and get_sales_count() functions are fictitious (they are not part of WordPress, of course).

Of course, in a real world example we would need to make sure that only buyers and sellers are listed, and we might need to create a separate template for them completely (if the differences are numerous enough).

foreach( $users as $user_id ) {
    $user = get_userdata( $user_id );
    if( user_can( $user->ID, 'buyer' ) ) {
        get_template_part( 'userlist', 'buyer' );
    }
    else {
        get_template_part( 'userlist', 'seller' );
    }
}

When looping through our users above, either userlist-buyer.php or userlist-seller.php will be used, depending on the user’s role.

Conclusion

User roles and capabilities are extremely powerful tools in WordPress. Whenever you build a plugin which requires the implementation of special user-based functions, you should consider using them.

Apart from making your life easier (and more manageable) it will make the processes on your websites easier to follow and easier to backtrack any problems.

(jvb) (il) (jc) (js)


© Daniel Pataki for Smashing Magazine, 2012.


What’s New in WordPress 3.4


  

With WordPress 3.4 set to arrive this week, it’s a great time to familiarize ourselves with the new features and additions. The new version of WordPress brings many improvements, including custom backgrounds and headers, a live theme-customizer, revamped XML-RPC, better support for internationalization, and many bug-fixes and enhancements. Let’s dive in and see what WordPress 3.4 has in store!

wp34featured-500

Custom Headers And Background

When WordPress added featured images as a core feature in 2.9, a new function was added — add_theme_support. It was (and is) obvious that this is a precursor of things to come: the standardization of theme features. Since its introduction, add_theme_support handles post-formats, automatic feed-links, and now in version 3.4, custom backgrounds and headers will be added to the list.

Adding a Custom Background

To use this feature, just call the add_theme_support() function with ‘custom-background’ as the first argument, and a list of default options as the second. Here is an example showing the basic syntax:

	$args = array(
		'default-image'          => get_template_directory_uri() . '/images/bg-default.png',
		'default-color'          => '#fafafa',
		'wp-head-callback'       => '',
		'admin-head-callback'    => '',
		'admin-preview-callback' => ''
	);
	
	add_theme_support( 'custom-background', $args )

Once the code is in place, you’ll see the changes take effect in the WordPress Admin:

The new custom background facility in WordPress 3.4
The new custom background facility in WordPress 3.4

Adding a Custom Header

Adding the custom-header options work in much the same way. In addition to the new way of defining them, you can now make them flexible in height or width, which is a great asset to theme designers.

	$args = array(
		'flex-height'            => true,
		'height'                 => 200,
		'flex-width'             => true,
		'width'                  => 950,
		'default-image'          => get_template_directory_uri() . '/images/headers/header-default.jpg',
		'random-default'         => false,
		'default-text-color'     => '',
		'header-text'            => true,
		'uploads'                => true,
		'wp-head-callback'       => '',
		'admin-head-callback'    => '',
		'admin-preview-callback' => '',
	);
	add_theme_support( 'custom-header', $args );

Once you add this code the relevant controls will show up in the Appearance tab and you will be able to set up your custom header and background-image.

The width and height is now 'suggested'
The width and height is now ‘suggested’ (displayed in bold text)

Thanks to Chip Bennett and Amy Hendrix for their excellent posts on this topic.

Live Theme Customizer

I think one of the best features in recent times is the Live Previews or “The Customizer”. As someone who sells themes on Theme Forest, I welcome this addition because the more I can use default WordPress options, the less support I need to provide. The best way to familiarize yourself with this feature is to watch the following great overview from Otto. I also recommend his article on leveraging the theme customizer in your own themes.

We’ll be taking an in-depth look at this awesome functionality here on Smashing Magazine, but for this article, the live theme-preview feature is too complex to showcase concisely. If you’d like to get started, do read Otto’s article — it has everything you need to get things set up. Here’s the nutshell version for a quick preview.

The preview facility works in an object oriented fashion. To use it you will need to cover the following steps:

  1. Add the customizer (hook it to ‘customize_register’)
  2. Add an area of customization — a section (using add_section())
  3. Add a setting you want to be able to control (using add_setting())
  4. Add the control which is used to modify your setting (using add_control())
  5. Customize the preview functionality to work in real-time

The live preview is brand-spankin’ new, but it’s already a very powerful tool. It will no doubt receive numerous updates and additions, so theme developers will finally have a common and also flexible way of letting users customize their themes.

XML-RPC Revamped

XML-RPC is a specification and a set of tools that allow software running on different platforms to make procedural calls over the Internet. In essence, it allows communication between WordPress and other software. The most apparent use of XML-RPC is the remote blogging services that are offered by apps like Windows Live Writer and mobile apps.

WordPress 3.4 comes with a number of XML-RPC bug-fixes as well as some heavily requested features like support for post thumbnails, custom post types and taxonomies.

Internationalization Changes

Back in the second half of December last year, WP Polyglots (the translation team) announced that they will be pouring a lot of work into the 3.4 release and beyond. As a result there a numerous upgrades in the internationalization functionality of WordPress:

  • Comma-localization (for languages like Chinese and Arabic which do not use the standard comma)
  • Some fields are now forced to be LTR (like password and login names)
  • Translatable spell-checker language
  • Single quotes, apostrophes and primes can be localized
  • Translatable time-zone string
  • Simplification of:
    • Feed-language specification
    • Start of the week
    • RTL language designation
    • Default secret-key text
    • Placeholder text of database constants
    • setup-config.php file translation
    • WP_I18N_* hardcoded translations
  • Translations are now split over three POT files — wordpress.pot, wordpress-admin.pot, and wordpress-admin-network.pot
  • Default WordPress links can be translated
  • Dashboard widgets can be translated

Beginnings Of A New API

While not advertised in the change-logs, Andrew Nacin has been working on a new API which will replace the get_themes() functionality.

For now you won’t notice much, with the main difference being that you can place template files in sub-directories. Under the hood, the new class will bring significant speed increases while searching for themes by reducing the filesystem operations to a bare minimum.

As you can see on the main Trac Ticket (scroll down a bit in the comments), there has been a lot of work done but the class is only scratching the surface of what we will be able to do later on. Flexible theme-management with better performance will help developers and users out a great deal — I can’t wait to see where this goes!

Bugs and Enhancements

With a total of 401 bugs fixed, 116 enhancements added, 3 requested features built and 52 tasks completed (at the time of writing) there is a lot more to this update than just the main features above. The WordPress 3.4 Track Milestone page has all the links and info you need to take a look at all that’s been done, and here’s a quick overview.

  • HTML Support in image captions #18311
  • Twenty Ten and Twenty Eleven themes updated to support new features #20448
  • Theme installer supports child themes #13774
  • WP_Query core performance upgrade #18536
  • Clicking on an empty space in the toolbar will scroll the page to the top #18758
  • Incorrectly displayed author meta fields fixed #20285
  • Failed cURL redirect fixed #20434
  • Spam comments are now excluded from the dashboard #14222
  • Theme editor support for special theme name characters #16507
  • Retina display icons added #20293
  • Already installed themes excluded from theme search #20618
  • Args added to the recent post and comments widget #16159
  • New comments can be added from the editor #15527

Updates Of External Libraries

It’s always worth checking out the external library update for a milestone. This version brings quite a lot, to name just the most important ones:

  • PHPMailer updated to 5.2.1 #19887
  • TinyMCE updated to 3.4.8 #19969
  • jQuery updated to 1.7.2 #20339
  • jQuery UI updated to 1.8.20 #20559
  • SimplePie updated to 1.2.1 #18309
  • hoverIntent updated to r6 #19311

Want To Chip In?

If you’d like to participate there are still a few days left and you can always help out after 3.4 as well. If you have the coding chops take a look at the open tickets for the next major release.

If you’re not a coder, not to worry! Just using and testing the features can be invaluable as well! You can download WordPress 3.4 RC2 or you can install the Beta Tester Plugin to grab all the latest nightlies and be on the bleeding edge!

(JS)


© Daniel Pataki for Smashing Magazine, 2012.


Manage Events Like A Pro With WordPress


  

If you’ve ever tried working with, coding for or just thinking about anything to do with events, you know they are a total nightmare in every possible way. Repeating events, schedules, multiple days, multiple tracks, multiple prices, multiple speakers, multiple organizations, multiple payment options — the list goes on on for quite some time.

Today we’ll show you how to make event management an easy — nay, enjoyable — task by making WordPress do the grunt work for you. We’ll be looking at out-of-the-box WordPress features, plugins and themes and a DIY approach to managing events. Please do let us know if you have more or better ideas.

In A Nutshell

I know some people don’t like to read lengthy reviews, so here are my recommendations in the shortest possible form. We’ll look at all of these recommendations in depth, so read on if you want to know more about them.

If money is not an issue or you just want the best possible combination of products, I recommend using Event Espresso to manage the events and Eventure from ThemeForest to display them. This will set you back at least $125 (more if you need add-ons for Event Espresso), but it will give you one of the most powerful event-management setups you can get without touching any code.

If you don’t need a payment gateway, multiple-day event-specific options or other advanced features or you’re on a budget, you could use Events Manager Free Version, Event Espresso Lite or Events Made Easy. These are all free and easy to use, providing roughly the same functionality. You might also want to purchase a theme to display your events nicely, which will set you back at least $35, but this is in no way required.

Event Management Features

Before we get to specific tools, let’s look at some of the features we get from an event-management system. You might not need all of these, but looking at them is useful when planning your system.

Events

Obviously, our event-management plugin should at least support events. The ability to create events that are separate from your regular posts is a powerful feature, allowing you to add events to your website’s existing content.

Event Taxonomies

Regular posts can be ordered into taxonomies — categories and tags. Having separate taxonomies for events (i.e. event categories and event tags) is useful for separating them from your regular content. If you organize Web development conferences, you might want to differentiate between design- and coding-related ones, or you might want to single out JavaScript- and Ruby-related ones. Your regular content might have nothing to do with Web development, so having separate taxonomies would come in handy.

Registrations

Allowing people to register for events right there on your website can greatly boost attendance. The path a user has to take from discovering your event to participating becomes that much shorter, which translates into a better user experience and more registrants.

You will also need to be able to manage registrations through the back end. Registrants should be listed somewhere, with easy access to their details.

Payment Gateways

The ability to accept payments online breaks down another barrier between your events and potential attendees. A feature that allows you to accept the widest variety of payment methods would be ideal.

Speaker Management

As a software programmer, I don’t like when I enter data somewhere and it’s not stored in an easily reusable way. The ability to manage speakers across your events is a big plus because it opens up access to powerful features later on. This feature should include the ability to add biographies and photos of speakers to the website.

Venue Management

As with speaker management, having all your locations stored properly will make them ease to reuse in future. If you need to schedule another event at the same venue, there’s no need to reenter the details; just select it from a menu, and off you go.

Participating Organizations

Another nice feature is being able to attach companies to events. Companies will often host events, and giving them some recognition for it is a nice thing to do in return.

Sponsors

Almost all major events have sponsors that contribute in some way (usually with money). They often require you to add their logo in various places. Being able to add the names, descriptions and logos of sponsors for an event would be handy.

Notification Management

There are two kinds of notifications we might want to control. On-site notifications are shown to users once they perform specific actions. When a user successfully pays for a ticket or encounters an error while registering, an on-site notification should pop up to let them know what’s going on. Being able to tailor the language of these to your style would be a nice feature.

The second type of notification are email messages to participants. Confirmations, reminders and so on would all be customized to your style.

Form Management

Controlling the information to gather from registrants is key to finding sponsors and making the lives of users easier. Being able to control this on an event-by-event basis would be best. Some events require less information from users, others more.

Coupon Management

Many events offer coupons for promotional purposes. If you want to engage users beyond your website, then giving coupons for third parties to distribute is a great tactic. Creating multiple coupons for various events would enable you to manage a full-blown coupon campaign.

Price Management

Another way to persuade visitors to register is to offer different price options, such as early-bird pricing, student discounts, last-minute offers and so on.

Multiple Day Events

Many events have so much going on that splitting them into multiple days is the only way to go. Being able to control this from the administration section would be a great plus, especially when coupled with price-management options (such as registration for one day only).

Repeating Events

If you are organizing a repeating event, you wouldn’t want to have to create it from scratch a hundred times a year. Scheduling and repeating tools would help minimize your effort.

Powerful Global and Miscellaneous Settings

A great event-management system has to have great global and miscellaneous settings. Settings for creating an events listing page, changing currencies, setting time zones and so on are all part of a complete system.

Complete Solutions

All of the WordPress plugins in this section are paid plugins, but if you’re running a serious operation, then the first two listed here are well worth the money.

The three best plugins around are Events Planner, Events Manager and Event Espresso. Event Espresso is by far the best of the lot, but all three are versatile and under constant development.

Event Espresso

Event Espresso is the cream of the crop. It has built-in support for almost all of the features mentioned above (except perhaps sponsor management) — and much more! It enables you to set up multiple forms of payment, multiple event dates and times, multiple prices, discounts, promotions (coupons), locations (even virtual ones) and emails. It also creates posts for events automatically and does so much more!

Event Espresso also has a free “Lite� version, which gives you a taste of the solution. The lite version is actually pretty robust and can be used for simple situations. It includes event and attendee management, automated emails, customizable registration and PayPal Standard Payment.

You can easily tailor the design of event listings to your current theme. If you are willing to dish out the money for this plugin, I recommend getting a premium website theme as well and modifying that as needed.

Event Espresso is not cheap, but its feature set is top notch, so the price is justified. The basic version costs $89.95, which contains all of the features that 95% of people will need. From there, you can download free and paid add-ons to the basic system. Some free add-ons are for payment gateways, social media and calendars.

MailChimp integration, recurring events management, developer customization options, WordPress integration, Groupon integration, multiple event registration and shopping cart integration (coming soon) is available at between $25 and $35 a pop. Most of these are well worth their money, although getting the WordPress members integration for free would have been nice, because that’s not a huge programming leap.

A gallery will be added here with 3-4 images of how an event is displayed by default, a screenshot from the admin, etc. The images can be found in the images/gallery/ folder of this draft

Events Planner

Events Planner is another well-rounded system. It doesn’t have all of the features of Event Espresso, but it does give you a lot to work with. Event categories, tags, instructors, locations, companies, notifications, payments, registrations and more can be managed with ease.

The main difference between Events Planner and Event Espresso is that the former’s UI is less polished, and some features found in both are not as well implemented in it. Despite this, Events Planner remains extremely flexible and robust. If you don’t want to part with almost a hundred bucks, you’ll be able to grab Events Planner for $39, plus another $24 if you need plugins that supports advanced date- and time-specific functions.

Events Planner does not have a lite version, but you can create a custom installation yourself and test drive the pro version. This is a little unusual for plugins, but it does mean you can fully test it before purchasing.

A gallery will be added here with 3-4 images of how an event is displayed by default, a screenshot from the admin, etc. The images can be found in the images/gallery/ folder of this draft

Events Manager

Events Manager is very similar to Events Planner in many ways. Some features have a better UI in Events Planner, while others are better in Events Manager. Were the price not so different, it would be a matter of preference, but because Events Manager costs a lot more than Events Planner, I would not recommend this solution.

Events Manager will set you back $75, and the price buys you only one year’s worth of upgrades. There are no plugins or add-ons here (which could be a good thing), but the higher price and losing access to updates after a year seems a bit cheeky at this price point.

Events Manager has a free version that gives you a lot of functionality. It supports event and booking management, recurring events, locations and more.

A gallery will be added here with 3-4 images of how an event is displayed by default, a screenshot from the admin, etc. The images can be found in the images/gallery/ folder of this draft

Final Verdict

Of the three, Event Espresso is the clear winner. It supports every feature the other two do and a lot more. It also has handy (albeit slightly expensive) plugins, with more to come. Even at $89, if you run a successful business (or plan to), it isn’t a high price to pay for the features you get.

If you can’t spend that much on a plugin, then Events Planner is a very capable alternative that will not leave you wanting. When all is said and done, it does cost less than half of Event Espresso and still has 80% of its features. I would still heartily recommend it.

If you don’t need payment options, however, and you need a free solution, the free version of this plugin might be your best option. Have a look at the partial solutions below.

Partial Solutions

Quite a few solutions do not offer advanced features such as payment gateways and coupon management but do allow some flexibility and customizations for events.

The best options for a simpler approach are All-in-One Event Calendar, Event Organiser and Events Made Easy, as well as the free versions of Event Espresso and Events Manager. In a showdown, it would be a close call between Event Espresso and Events Manager.

All-in-One Event Calendar creates a new post type for your events, allowing you to keep blog posts and events side by side. It supports event categories, tags and a few other options. Because it allows you to create a calendar page, it’s a great solution if you need something simple and workable in minutes.

Event Organiser has all of the same functions plus a lot more! It has permission settings, permalink settings, importing and exporting options and even venue support. In addition, it has an admin calendar view that gives you a useful overview of your events.

Events Made Easy has all of the features of All-In-One Event Calendar (except event tags), and it supports registrations and locations. If you absolutely need to support on-site registration, this would be the easiest to use. The UI is the least polished, though, so it won’t look as pretty in the administration section, but the features are solid.

Final Verdict

Despite the great features offered by these plugins, I would stick with Event Espresso Lite or the free version of Events Manager. Apart from offering more functionality, they will also ease your transition if you need the full-blown system later on.

Using WordPress Out Of The Box

If you don’t need to manage data for each event, WordPress’s core functionality will do just fine. Here are a few ideas to get you started:

  • Use posts to store events.
  • If you want to be able to have regular posts as well, distinguish them using categories.
  • Create top-level categories for distinguishing organizations, sponsors and venues.
  • Use your website’s registration functionality to manage past attendees, or use it as a master attendee list if separate registration is not required for your events.
  • Create pages for important information such as payment options.
  • Use PayPal buttons in event posts to let people register and pay directly through PayPal.

Many of these features are far from optimal for event-intensive websites, but if you just need something simple that you can set up in 10 minutes, give it a go.

If you do choose this option, pay close attention to consistency. If your goal is expansion, you are guaranteed to want a better system later on, and consistency will ensure that you can make the switch without a hiccup.

Comparing All Of The Options

There is a lot to learn and a lot of options if you want to get started with event management. To make your life easier, here is a table with all of the features discussed, along with the solutions that support them. Click on the image to go to the large version (it’s a bit small to look at here).

Event-Friendly Themes

While the plugins do a nice job of helping you manage events, they are not designed to make your website pretty, which is equally important. No matter which route you take, you will need to do some work to make things fit perfectly, but some premium themes out there will shorten this process.

Eventure

$35 | Large screenshot | Live preview

Diarise

$70 | Large screenshot | Live preview

Events (from Elegant Themes)

Large screenshot | Live preview

Eventure

Large screenshot | Live preview

Conclusion

Whichever solution you choose, you will have to put in a few hours of work to make your website work well and look good. I usually advise using free software whenever possible, but this happens to be one of those areas where I would go with a complete solution. Getting it right from the get-go will save you a lot of headaches in the long run.

If you can afford to spend over $100 on managing events, go for Event Espresso, coupled with one of the premium themes mentioned above.

If you want to spend as little as possible, then try Events Manager Free Version, Event Espresso Lite or Events Made Easy. If you don’t plan on expanding a lot or you need multiple price points, go with Events Made Easy because it is completely free, with no paid version, so supporting the developer by using his product would be a nice gesture.

If you do plan on expanding, go with Event Espresso Lite because the pro version will have everything you need when you’re ready to buy it and you won’t have any migration or data problems.

(al)


© Daniel Pataki for Smashing Magazine, 2012.


Securing Your WordPress Website





 



 


Security has become a foremost concern on the Web in the past few years. Hackers have always been around, but with the increase in computer literacy and the ease of access to virtually any data, the problem has increased exponentially. It is now rare for a new website to not get comment spam within days of its release, even if it is not promoted at all.

securityimage

This increase in naughty behavior, however, has spurred developers to write better code, and framework vendors have implemented many functions to help coders in their battle against the dark side.

Because data validation and sanitization is a big part of both security safeguards and normal user-input processing, by securing our code we will be not only protecting our behinds, but offering a better, more solid user experience.

While a large part of this article is specific to WordPress, a sizeable chunk is about general practices that anyone can use. Even the WordPress-centric sections contain useful logic, so reading them may well be worth it even if you use a different framework.

URL-Based Exploits

With URL-based exploits, hackers try to find weak spots on your website by making requests that would normally return an error but for some reason are completed.

http://mysite.com/trying/to/exploit/%2F/config

The above hypothetical URL is essentially a stab in the dark by a hacker. But if the request is met, even though the URL is clearly not meant to go anywhere, the hacker might be able to make use of it.

Using .htaccess as a Firewall

One of the best methods I’ve found against this kind of threat is an .htaccess firewall. It basically consists of rules that automatically block requests based on strings in the URL.

For example, there is no good reason for an opening bracket ([) to be in a URL. If a request is made using a URL that contains a bracket, then either the user has mistyped something or someone is looking for a security hole. Either way, generating a “403 Forbidden� page is good practice in this case.

RedirectMatch 403 \[

Paste the line above in your .htaccess file to block any request that contains an opening bracket.

To guard against more than just brackets, you will need a more complex ruleset. Luckily, our awesome editor Jeff Starr has gone out of his way to create a great .htaccess ruleset. The latest iteration is called 5G Firewall and is freely available from Perishable Press for your copy-and-pasting pleasure.

The firewall is modular, so you can delete lines from it without breaking the functionality. If something goes wrong when you’re using it, you can usually track down the problem by deleting lines until it starts working again. Once you’ve found the offending line, you can delete it and paste back the rest.

Protecting Directories

On many servers, it is possible to view the contents of a directory simply by typing it in the URL bar.

http://myblog.com/wp-content/uploads/2011/08/

Visiting this typical URL for a WordPress blog will list the contents of that directory, showing all of the uploads from August 2011. You might want this, but you can also disable or fine tune it using the good ol’ .htaccess file.

Options -Indexes

Popping the above line into your .htaccess file will disable directory listings; so, users will get a “403 Forbidden� message if they try to view a directory. While many people seem to be aware of this, far fewer know of the other options besides allowing or disallowing access. You can control which file types are listed using the IndexIgnore directive. Take these three examples:

IndexIgnore *
IndexIgnore *.php
indexIgnore *.jpg *.gif *.png

If directory listing is enabled, then the directory will be displayed in the first example, but no files will be listed because all will be ignored. The second example will list all files except ones with a .php extension. The third example will omit the three image types specified.

Note that some hosts (such as MediaTemple) disable directory browsing by default, so you won’t need to modify the .htaccess file. To verify this, just type a directory location in the URL bar and see what happens.

Additional Server-Level Protection

So far, the measures we have taken have nothing to do with our website’s actual code. However secure your code is, you will still need to implement something like what we did above. We don’t have time to look at all tips and tricks for .htaccess, but you can do quite a few other things:

  • Password-protect directories,
  • Use smart redirects,
  • Deny access based on IP or an IP range,
  • Force downloading of files,
  • Disable hotlinking,
  • The list goes on.

Look at the “Further Reading� section at the end of this article, and become good friends with your .htaccess file. It might seem daunting and confusing at first, but solid knowledge of how to use it will go a long way.

Protecting Against Malicious Users

The second type of problem that can arise is when someone performs an action that they are not supposed to do. This doesn’t necessarily mean that they intended to harm the website, but it could happen.

If users are listed somewhere in the admin part of your website, chances are that a link is displayed to delete each user. The link could point to the script in the following location:

http://mysite.com/admin/scripts/delete_user.php?user_id=5

This link is relatively obscure; that is, a normal user doesn’t have a good chance of stumbling on it. But if directory listings are enabled, then someone naughty could go to http://mysite.com/admin/scripts/, see that you have a delete_user.php file there, and make various requests to try to delete a user.

If the script does not check permission or intent, then anyone who visits the link above could delete user 5.

Authority and Intent

Whenever a user initiates an action, we need to take two things into consideration. Does the user have authority to perform the action (i.e. do they have permission)? If the user does have authority, do they also intend to complete the action (i.e. do they mean to do what they’re doing)?

WordPress has functions to help you make sure that both conditions are met before an action in the script is triggered. We will look at these in detail shortly. If you are building your website from scratch, then you will need to make sure that each user has associated permissions and that you know which action can be performed under which condition.

For example, you would probably want only administrators to be able to delete content from the website. Every time a user tries to delete content, you would need to make sure that they are actually an administrator — this is the “authorityâ€� part.

Intent is best described with an example. Let’s assume you can use the following link to delete a comment:

http://mysite.com/admin/scripts/delete_comment.php?comment_id=5

The script itself will check that the user is currently logged in and is an administrator, so it takes care of the authority check. Could someone still wreak havoc? Sure they could! A sneaky hacker could put a link on their own website pointing to the same location:

<a href="http://mysite.com/admin/scripts/delete_comment.php?comment_id=5">Super-Happy Times Here!</a>

Because everyone likes super-happy times, many users would click the link. In 99% of cases, nothing would happen, because those visitors would not be administrators of mysite.com. But if a logged-in administrator of mysite.com did click on the link, then the action would execute, even though the link was actually clicked from vilehackerperson.com.

You might think that the odds of this happening are astronomical. In a way you’d be right, but remember that a hacker can do this extremely easily and can automate it. Millions of people get spam email saying that Bill Gates will take away the Internet unless they pay $1,000. Most recipients don’t see the email or throw it out or mark it as spam or what have you, but perhaps 1 out of every 2 million people is lured in. A thousand bucks for basically doing nothing is not bad at all. And a hacker probably wouldn’t put the link on their own website; all they would need to do is hack a big website and embed the link there without anyone noticing.

Checking For Authority In WordPress

WordPress has a permissions system built in referred to as “Roles and Permissions.� Capabilities are the basis of the whole system; roles are just a way to group a set of capabilities together.

If a user has the delete_posts capability, then they have the authority to delete posts. If a user has the edit_posts capability, then they can edit their posts. Quite a few capabilities are available, and you can even create your own.

Roles are basically groups of capabilities. A user with the role of “contributor� has three capabilities: read, delete_posts and edit_posts. These give the user the authority to read posts and to edit or delete their own posts. These capabilities could be granted individually to any user, but grouping them into frequently used bundles is much easier and more practical.

With that in mind, let’s look at how to use WordPress functions to ensure that a user has the authority to complete an action that they initiate.

if(current_user_can("delete_users")) {
    wp_delete_user(5);
}
else {
    die("You naughty, naughty person. Of course, you could just be logged out…");
}

Here, we’ve made sure that the user has the delete_users capability before they are able to complete the action. Don’t make premature assumptions when protecting your scripts; in many cases, especially those of authority, the intent is not malicious.

The current_user_can() function takes one argument, which can be a role or a permission. We could let “editors� (who don’t normally have the delete_users capability) delete users in the following way:

if(current_user_can("editor")) {
    wp_delete_user(5);
}
else {
    die("You must be an editor to delete a user");
}

Be careful with the method above because the roles are not inclusive. This function doesn’t require the user to be at least an editor; it requires them to be exactly an editor (if that makes sense). Because of this, I find it preferable to use capabilities, especially if I have modified the default permissions extensively.

Two other similar functions enable you to examine the capabilities of users other than the currently logged-in one.

if(user_can(5, "manage_links")) {
    echo "User 5 is allowed to manage links";
}
else {
    echo "Sadness! User 5 may not manage links";
}
if(author_can(1879, "update_themes")) {
    echo "The author of post #1879 is allowed to update themes";
}
else {
    echo "Oh noes, our friend, the author of post #1879 may not update themes";
}

The user_can() function checks whether a given user has the given capability (or role). The first argument is the user’s ID or a user object; the second argument is the name of the capability or role that we want to check for.

The author_can() function checks whether the author of a given post has the given capability (or role). The first parameter should be a post ID or a post object; the second is the capability or role that we are examining.

Checking For Intent In WordPress

Intent is a bit more difficult to check. In the good ol’ days, a check of $_SERVER['HTTP_REFERER'] was the way to go. This stored the page that the user came from. If the domain name was their own, then the user was probably OK… unless, of course, someone had gotten into their files and inserted a link that deleted the user’s database if they clicked on it as an administrator.

A newer more secure method was implemented in WordPress 2.03 — quite some time ago — called nonces. Nonce stands for “number used onceâ€� and is used frequently in cryptography to secure communications. It is a number that is generated before an action is initialized, then attached to the action’s call, and then checked before the action completes.

In WordPress, you would generally use nonces in one of two places: forms and normal links. Let’s look first at how to generate a nonce in a form.

Nonces in Forms

<form id="myform" method="post" action="myawesomescript.php">
    <h2>Enter an awesome word here</h2>
    <input type='text' name='word'>
    <?php wp_nonce_field( 'awesome_name_nonce') ?>
</form>

This will generate a hidden input field containing your generated nonce, which will be sent along with all of the form’s other data. The wp_nonce_field function takes four parameters:

  1. The first parameter is optional, but recommended because it gives the nonce a unique identifier.
  2. The second parameter is the name of the field. This is also optional and defaults to _wpnonce.
  3. The third parameter is boolean. If set to true, it will also send the referrer for validation.
  4. The fourth parameter is also a boolean and controls whether the field is echoed right then and there.

The resulting hidden field would look something like this:

<input type="hidden" id="_wpnonce" name="_wpnonce" value="d6d71w4664">

Setting all of this up won’t make a huge difference if it isn’t used when the form is actually processed. We need to check for the presence and the value of the nonce before allowing any actions to be performed. Here is one way to do that:

if (!wp_verify_nonce($_POST['_wpnonce'],'awesome_name_nonce') ) {
   die('Oops, your nonce didn't verify. So there.');
}
else {
   awesome_word_inserter($_POST["word"]);
}

Here, we’ve used the wp_verify_nonce() function to make sure that our nonce is correct. This function takes two parameters: the first is the value of the nonce field, and the second is the name of the action that we defined (this was the first parameter for the wp_nonce_field() function). If the nonce is verified, then the function will return true; otherwise, it will return false.

Nonces in Links

In some cases, you will want a link, instead of a form, to perform an action. This would typically look like our previous examples:

http://mysite.com/admin/scripts/deletethatthing.php?thing_id=231

To generate a nonce for a link, we can use the following method:

$base_url = "http://mysite.com/admin/scripts/deletethatthing.php?thing_id=231";
$nonce_url = wp_nonce_url( $base_url, "thingdeleter_nonce");
echo "<a href='".$nonce_url."'>Delete that thing</a>";

The resulting link would be something like this:

http://mysite.com/admin/scripts/deletethatthing.php?thing_id=231&_wpnonce=d6f77f1364

When we actually go to the script, we can check the nonce using the same method as before:

if (!wp_verify_nonce($_GET['_wpnonce'],'thingdeleter_nonce') ) {
   die('Oops, your nonce didn't verify. So there.');
}
else {
   delete_that_thing($_GET["thing_id"]);
}

Checking Authority And Intent At The Same Time

We need to look at both aspects at once; although, now that we’ve looked at all of the components, it won’t exactly be rocket science! Let’s take a simple link that lets the user delete a comment. We would have this on the page that lists comments:

$nonce_url = wp_nonce_url("http://mysite.com/scripts/delete_comment.php?comment_id=1451", "delete_comment_nonce");
echo "<a href='".$nonce_url."'>dispose of this comment</a>";

And here is the script itself:

if (wp_verify_nonce($_GET['_wpnonce'],'delete_comment_nonce') AND current_user_can("edit_comment")) {
   die('Oops, your nonce didn't verify, or you are not permission-endowed enough.');
}
else {
   wp_delete_comment($_GET["comment_id"]);
}

Data Security

Our work might seem to be done, but if you’ve been developing for a while, then you know it never is. An additional layer of security needs to be added to stop insecure data (or erroneous data) from entering our database. Adding this additional layer is called data sanitization.

A quick clarification: data sanitization refers to the process of cleaning up our data to make sure that nothing suspicious gets sent to the database. Validation refers to all of the checks we perform on data to make sure they are the types of data we need; it is typically done to ensure that the user has entered a valid email address, a well-formed URL, etc. The two terms are sometimes used interchangeably, and other methods may be similar, but they are quite different things. For our purposes, sanitization is a bit more important, because it has more to do with security.

The main thing we are trying to protect against is SQL injection. SQL injection is a technique used by hackers to exploit a database’s weaknesses. Take the following example:

// A hacker goes to your search field and searches for elephant' - note the apostrophe at the end. In the script, the following SQL is run:
SELECT ID, post_title FROM wp_posts WHERE post_title LIKE '%elephant'%'

In the example above, the user’s search for elephant' has resulted in unclosed quotes in your script. While the hacker might not be able to do much with this, an error message would be generated, indicating to them that at the very least you are not sanitizing your data.

In some cases, the SQL itself could be harmful or could give the hacker much more information than you’d like. Take the example of an administrator being able to enter a user’s log-in name in a form and getting back the user’s email address.

SELECT user_email FROM wp_users WHERE user_login = 'danielp'

If the hacker manages to perform an SQL injection attack, they could type ' OR 1=1 ' in the form, which would result in the following query:

SELECT user_email FROM wp_users WHERE user_login = '' OR 1=1 ''

This would return all email addresses in the database, because we would be retrieving all addresses for which the user’s log-in name is an empty string, or 1=1, which is always true.

There are two ways to protect against this kind of problem — implementing both is good practice. In round one, we validate the data. If an email address needs to be entered, we can filter out user data that does not conform to the format of email addresses. We simply make sure that the format is right, otherwise we redirect the user, stating that the address is invalid. If the data passes round one, we move to round two, where we remove all characters that could mess up the query. This usually entails escaping quotes so that they can be used only as actual quotes in the SQL query.

When working without a framework, you would typically use addslashes() or something similar, but WordPress offers its own solution…

Data Sanitization In WordPress

When communicating with the database in WordPress, the preferred method is to use the $wpdb class. You can read all about this in “WordPress Essentials: Interacting With the WordPress Database.� The class offers a number of methods to alleviate your SQL injection worries.

Before jumping in, let’s look at some examples to get a basic understanding of how the class works.

// Perform any query
$wpdb->query("DELETE FROM wp_users WHERE user_id = 5");
// Get one column of data
$posts = $wpdb->get_col("SELECT post_title FROM wp_posts WHERE post_status = 'publish' ORDER BY comment_count DESC LIMIT 0,10");
// Get a row of data
$post = $wpdb->get_row("SELECT * FROM wp_posts WHERE ID = 1453");
// Get multiple rows and columns
$posts = $wpdb->get_results("SELECT ID, post_title, post_date FROM wp_posts WHERE post_type = 'publish' ORDER BY post_date DESC LIMIT 0, 12 ");
// Get a single value
$author_id = $wpdb->get_var("SELECT post_author FROM wp_posts WHERE ID = 2563");
// Insert a record
$wpdb->insert("wp_postmeta", array("post_id" => 2323,  "meta_key" => "favorite_count", "meta_value" => 224 ), array("%d", "%s", "%d"));
// Update a record
$wpdb->update("wp_postmeta", array("meta_value" => 225), array("meta_key" => "favorite_count", "post_id" => 2323), array("%d"), array("%s", "%d"));

The insert() and update() methods are helper methods, and they’re great because, apart from modularizing your database interactions a bit, they also take care of sanitization for you. If you want to use the general query() method, though, you will need to take care of it on your own.

The easier way is just to use the escape() method:

$data = $wpdb->escape($_POST[about_me]);
$wpdb->query("UPDATE wp_usermeta SET meta_value = '$data' WHERE meta_key = 'description' AND user_id = 154  ");

A slightly harder but better way to go about this is to use the prepare() method. An example from the WordPress Codex illustrates this perfectly:

$metakey	= "Harriet's Adages";
$metavalue	= "WordPress' database interface is like Sunday Morning: Easy.";
$wpdb->query( $wpdb->prepare(
	"
		INSERT INTO $wpdb->postmeta
		( post_id, meta_key, meta_value )
		VALUES ( %d, %s, %s )
	",
        10,
	$metakey,
	$metavalue
) );

Further Protection Using Sanitization

Sanitization is a fairly big topic and requires quite some time to master. For now, you’ll be busy mostly determining which characters to allow and which to disallow, and then finding ways to parse out the latter. Some common needs are to parse HTML out of addresses, filter numbers out of strings, validate email addresses and so on, but you will need to implement your own solutions for more complex needs. See the “Further Reading� section for more on this topic.

Final Thoughts

The measures needed to secure a website cannot be discussed in a single book, let alone a poor article. There are many methods and topics we did not look at, such as advanced password encryption, salts and so on. But hopefully, by implementing what we’ve discussed, your website will be much safer. Hackers usually go for the weakest link, so if your website is not insanely popular and is fairly secure, you should be OK.

While I have a lot of experience in this field, I am far from being a security expert. If you know of any other or better methods, do share them in the comments. There is always something new to learn about website security.

General Reading

WordPress-Specific Reading

(al)


© Daniel Pataki for Smashing Magazine, 2011.


  •   
  • Copyright © 1996-2010 BlogmyQuery - BMQ. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress