WordPress Hacking and Cleanup

There’s a brute force attack underway on a global scale. Massive. The attack vector? Keep attempting user/pass combos in an automated way until a breakin happens.

If your WordPress site gets hacked, I am available for cleanup and an audit.

Aaron@technosailor.com

It absolutely will cost you a minor fortune. That’s the way it goes. Don’t complain or whine, just get your credit card out.

It would be cheaper to have a strong password and install a plugin that limits failed login attempts though.

But if you don’t, rest assured I can help you despite you having to postpone a vacation in St. Thomas.

Do the right thing.

I Fired Myself

If we’re friends on Facebook or Twitter, you know about my new job in Baltimore. Technically, it’s not a new job yet, as I don’t start until February 4. However, it’s a new job and a return, for the first time since 2006, to a more corporate (if laid back) working environment. I’ve only worked for one company in that period of time, and I was a founder. That, of course, is the hugely successful WP Engine. However, I left that role in October of 2011. I still didn’t have the motivation to not work for myself.

A little about this new role, however, since I brought it up. I feel it’s necessary in proving the point I want to make.

Corporate Culture

Agora Financial, as a division of Agora, Inc. was named the 2nd best place to work in Baltimore in 2011 by the Baltimore Sun. As an adopted Austinite, that label carries a high standard. In Austin, “business casual” is cutoff jean shorts (“jorts”) and a tech swag tee shirt with sandals. In Austin, the chic commuter rides a scooter or bicycle. Maybe even walks. In Austin, drinking a beer is not something simply saved for off-hours. In fact, many companies keep a refrigerator stocked with beer because, hey, the workforce can be more relaxed, efficient and productive if given certain leeway. Thankfully, none of us are drunks… maybe.

At Agora, I found a company that matched this sort of comfort level I’ve come to expect. When I flew up for an interview (and job interviews have been something I’ve not really had to do seriously since 2002), I emailed Mark, the Art Director and my point of contact, and very politely suggested I wouldn’t be arriving at their headquarters in a tie. Manage expectations, and such. Mark’s response was simply, “That’s fine. Business casual works”.

Business casual can mean many things. It’s sort of a catch all phrase that means different things to different people based on different companies policy ideas. So I wore some decent dress pants, a button up shirt and a vest with no tie. The team had sandals, jeans with holes, and hoodies and plaid-pattern button up shirts. I felt like I was in Austin!

Ideology

But company culture was just one aspect. The work they do perfectly fits who I am practically and ideologically.

You see, Agora is a publishing company first and foremost. I’m a publisher. I’ve written a book and worked with traditional book publishers. My first startup was a publishing company with, at our peak, 350 blogs. Agora’s model is different than those models, but they’re publishing. They are creating content that, hopefully, long outlives us.

They are a policy research publishing company. Those who know me know that I love policy, I hate politics. When I engage in politics, it’s usually from the lens of policy. Agora provides research analysis and white papers based on their policy research in a subscription format. So there’s also a revenue model. And they’ve been highly successful at doing this, historically through newsletters, for years. It’s a proven model, and they are a proven company.

In addition, their policy analysis generally comes from a libertarian (small “l”) perspective. As a left-leaning small-l libertarian, I enjoy this aspect of what they do (even though I suspect most of my colleagues and most libertarians as a whole are right-leaning small-l libertarians, I suspect that we all agree on a framework of responsibility and limited government in individuals life, and diverge on other less-important minutiae).

I was hungry for this job. It was a dream job for me. Join a company doing things I loved, in areas I loved, with tools (WordPress) I loved, with a style of corporate culture that I loved. When they made me an offer, I didn’t hesitate to accept and fire myself from my own company.

I fired myself!

Having the Balls to Fire Myself

Most people aspire to stop working for the man, and start working for themselves. There are entire classes at universities and colleges about entrepreneurship, and to be sure, entrepreneurship is the mode of decade.

The other night, I had the opportunity to guest lecture for an capstone course on digital entrepreneurship for American University. It was online and you can hear my story and lecture here. This course is a culmination of all the classwork done in this program and is largely a practicum of everything learned to that point. The lectures are a series of lectures from guests that give the students inspiration and motivation about their futures while they work on their individual projects.

During this talk, I spoke specifically about the time I left corporate America and went out on a limb. It was 2006. I had been working on a side-project basis for over a year building up a WordPress-powered content network and when we finally took funding, I was employee #1 or #2, depending on who you ask. I couldn’t wait to leave my computer-fixing job and go do something I really, really wanted to do instead and get paid for.

I’ve heard stories like that from hundreds of entrepreneurs. Most never look back with any regret, despite the struggles and sometime-economic instability.

I have a view that whatever I do, I do it because I want to. It’s very easy to look and say that running a startup, building a product, starting a company or, in general, working for yourself is, in fact, the holy grail.

From Happiness to Happiness

My view is that the holy grail should be happiness and motivation derived from what you do. Sometimes that means taking a more unorthodox step and saying, you know what… being an entrepreneur is awesome, but it’s a vehicle to happiness, not happiness itself.

So effective February 4, 2013, Aaron Brazell has been terminated by Aaron Brazell.

I don’t know if I would have fired myself to go be a developer in some developer-happy company that segregates the developer from the product line. In other words, a lot of developer-oriented companies have developers as a means to an end. Product managers go talk to customers, develop goals, milestones, wireframes or storyboards, make decisions on initiatives with corporate executives and the developers exist to make that shit happen.

Some people like that. Some people don’t want to be a part of the politics and roadmapping. They work better with a framework that defines what their role and deliverables are. For them, that’s happiness.

For me, happiness is seeing the vision, talking about what it means – the pros, cons, feedback – iterating, being a part of the process of both scoping and building and then allowing the idea to flourish. It means building something toward an end. In the idea of a startup, it means building a product and moving it toward acquisition, IPO or even failure.

As a consultant, there was no viable end. Unless I’m committed to building out a team (I’m not), increasing a production pipeline (without a team, I can’t), or other such motivations, a consultancy looks exactly the way it does in 10 years as it did on day 1 – find clients, build something for them, collect money, wash, rinse, repeat. There’s no glorious ending. To me, that makes for an unhappy Aaron.

Agora provides an exciting platform, an an innate sense of entrepreneurship internally, that makes me happy. If I have an idea, I can try it. If I think something could really work well, I’ve got a green light to work on it. All within a good developer situation where I also have deliverables, and things to look at and solve. The combination of such makes Aaron a very happy person.

For Photographers, Instagram Square Photos are Worse than a TOS Update

I’m a photographer and I use both my iPhone 4S and my Digital SLR to take photos.

There’s a difference between taking pictures and taking photos, however, and the nuance is an important thing to understand. When you raise a camera and snap a photo, unless you’re paying attention to things like composition, lighting, depth of field, aperture, shutter speed and ISO, you’re taking a picture. If you’re doing all of those things (or reasonably close to all those things), you are safely in the category of “doing photography”.

One is casual. The other is intentionally art (whether good art or not is a subjective matter that shouldn’t be handled in this post).

Art doesn’t have to be Pablo Picasso or Ansel Adams or John Lennon. It doesn’t have to have a philisophical meaning or intent. Art is the expression of the Artist on an outward medium. Or in the case of photography, it is more simply the interpretation of what the eyes sees into a likeness in film or in digital media. Photography as art cannot be done haphazardly. That’s how people get caught in the trap of buying a $2000 camera and wondering why their photos suck. Because there is no context of movement, sound, smell or touch, the essence of a point in time must be captured entirely visually. If it’s done right, it’s art because care, intent and a degree of skill are needed to translate the moment into a snapshot.

Photographers work hard to get this right. It takes a perceptive eye, a knowledge of the equipment, lighting and composition to make a great piece of art in the form of a photograph.

I thought this was about Instagram?

This is about Instagram. Instagram’s app used to allow the user to upload a photo that did not fit a strict “square” format and pinch and squeeze to resize and get an entire photo in. While this was not as aesthetically pleasing as it could have been, it gave the photographer the ability to use the entirety of a photo and the composition nuances in it.

The new app does not allow for this zoom and strictly enforces a square model. The Next Web covers some of the pushback and takes the opposite side as me – that it’s high time Instagram enforce a square photo.

Take this photo as an example. I love this photo of Downtown Austin from across the S. Lamar St Bridge. The composition here is extremely important. The reflection of the bridge in the water, the trees and of course the kayaker under the bridge make this photo what it is. Here is my post-production piece.

Austin, Texas

However, what happens with Instagram? I have to scroll to one side or the other or find a happy medium in the middle for this photo.

Austin, Tx - iPhone

I realize, of course, that many users hate to see black bars across the top of the Instagram photo, as it was the day I posted my photo to Instagram!

Austin, Tx - Old InstagramHowever, this is the balancing act that Instagram has to consider. While creating a photography app for the masses, the need to keep photographers on board is essential. The new app takes away the artistic prerogative and choice from the artist and puts discretion in the hands of the masses. Last time I checked, the masses don’t shoot my photos, edit my photos, make artistic choices about my photos or have the same skills or style that I possess as an artist.

choose what my photos look like. I use Instagram to publish because it has two things: an audience and a distribution vehicle. When I post to Instagram, I push my photos to both Twitter and Facebook. I chose this even with the artistic limitations that it offered before this app update (namely the “letterbox” that goes with the photos that don’t fit into a square format).

One can argue that Instagram had to make a business decision, perhaps inline with the desires of their Facebook overlords. I guess that argument can be made. But removing artistic license abilities of artists who are using the platform is a terrible idea. Imagine if Twitter had said, back in 2007, that they had this platform that could only be used with 140 characters because it was built for use over text message and, since that was their original idea, and the colonial approach to the short message service was the only appropriate way of consumption, then text messages would be the only method of use allowed.

That is, in fact, exactly what Instagram has said indirectly, and what the Next Web article (linked above) advocates. Hey, photography used to be limited to a square format because it was the cheapest way to do it. Yeah… and then we got 35mm film which opened up a 4:3 ratio. And then we got digital that opened photographers to new technologies to create different formats, styles and use different concepts to create art.

Imagine if all our music sounded exactly the same way as the Beatles did in the 60s. Would there be any evolution to music? Of course not, because every artist would sound exactly the same way, use exactly the same cadence, write lyrics that epiphanize the exact same mindset that existed in the 60s and generally would be boring today – and I’m a big Beatles fan!

Returning to a square format is not a bad thing. There are vintage schools of thought in every format of art, fashion, music and culture. But that doesn’t mean that every artist should be forced to adopt such styles. That makes photography boring and conformist. That’s not why we do photography!

Contest: 3 free copies of the WordPress Bible [UPDATE]

Today marked the drop of WordPress 3.5 and I want to celebrate.

Tomorrow, I’m going to give away three autographed copies of the WordPress Bible. You have to be on Twitter. I apologize to those who have chosen to abandon Twitter, or have chosen not to participate, but it is the defacto communications medium of the 21st century and how I operate.

The book is a mix of advanced and beginner content. Therefore, I will do trivia. Trivia will have a beginner round, an advanced round and an intermediate round. All WordPress oriented. The winner is in my sole discretion and you will be required to provide your mailing address if you are selected.

WordPress core contributors are not allowed to participate in the beginner or intermediate round. If your name is on “the list” of 3.5 contributors, you cannot win those rounds. You can, however, participate in the advanced round.

The beginner round will consist of questions surrounding theme and plugin management with possible questions around usability and interface.

The advanced round (the only round open to core contributors) will be based on WordPress APIs, hooks and advanced WordPress development.

The intermediate round will mix both but the developer-oriented questions will be more common and basic and user questions will be more difficult.

You must hashtag your answers with #wpbibletrivia. Failure to do so disqualifies you for an answer.

The first answer I see that is correct is a correct answer. My judgement solely.

There will be 10 questions per round so pay attention.

The beginner round begins at 11am Central Time.

Share this on Facebook, Twitter or whatever your social media channel of choice is. The questions will be asked on my Twitter feed: @technosailor.

Good luck!

Update

The winners of the trivia contest were David Peralty for the beginner round, Kim Parsell for the intermediate round and Kailey Lampert for the Advance round. Well done, everyone!

TUTORIAL: Building Custom Rewrite Endpoints in WordPress

Recently I concluded a sizable project that involved deep integration with an external API. I was responsible for creating content pages based outside of WordPress. To be clear, the pages would use an internal WP template, but all the content was generated using this external API.

In order to make this work within the WordPress Rewrite system and serve pages that WordPress knew how to handle in a non-traditional way, I had to tackle this in a multi-prong way: using the template_redirect as well as the built in Rewrite API.

Note: I’m not giving away the full sauce here as the project is non-open source. As well, I’ll be abstracting some stuff a bit. If you’re smart, you can fill in all the blanks regarding how to fully implement this.

First we need a base class:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

class Base_Class {

  public function __construct() {
    $this->hooks();
  }

  public function hooks() {
  }
}

new Base_Class;

This is the base of pretty much every class I write as part of a plugin in WordPress. If you don’t follow Object Oriented coding practices, start now.

The next step is to register some variables with WordPress. Because WordPress is using the template_redirect hook to get the proper template files, you will often lose necessary query string variables, and you definitely can’t use them in an endpoint (i.e. /foo/bar) without WordPress knowing about them.

So let’s register them using the query_vars filter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
class Base_Class {

  public function __construct() {
    $this->hooks();
  }

  public function hooks() {
    add_filter( 'query_vars', array( $this, 'query_vars' ) );
  }

  public function query_vars( $qv )
  {
    $qv[] = 'foo';
    $qv[] = 'bar';
    return $qv;
  }
}

new Base_Class;

After this, we want to actually create some rewrite endpoints. In this example, I want to allow permalinks like /foo/content-slug/ and /bar/content-slug. With the following code that adds a rewrites() method to the class, and hooks on the generate_rewrite_rules filter, we can create these two endpoints. In our imaginary template, we would use get_query_var() function to handle logic for display purposes, but that’s outside of this article scope.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
class Base_Class {

  public function __construct() {
    $this->hooks();
  }

  public function hooks() {
    add_filter( 'query_vars', array( $this, 'query_vars' ) );
    add_filter( 'generate_rewrite_rules', array( $this, 'rewrites' ) );
  }

  public function query_vars( $qv )
  {
    $qv[] = 'foo';
    $qv[] = 'bar';
    return $qv;
  }

  public function rewrites( $rules )
  {
    global $wp_rewrite;

    $new_rules = array(
        'foo/([a-z]+)/?$' => 'index.php?pagename=wppage-holder&foo=' . $wp_rewrite->preg_index(1),
        'bar/([a-z]+)/?$' => 'index.php?pagename=wppage-holder&bar=' . $wp_rewrite->preg_index(1),
    );
   
    $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
    return $wp_rewrite->rules;
  }
}

new Base_Class;

Specifically, note the new rewrite rules and how they are structured. If those permalink structures identified above match these new rules, then we will pass the request on and use the template file designated for a page (that you do have to create in WordPress, by the way) with the slug ‘wppage-holder’. This can be done by designating a template file on the page edit screen or by naming the template as page-wppage-holder.php in your theme – again, outside the scope of this article.

If the permalink matches foo, we pass the foo variable on. If it matches bar, we pass the bar variable on. Logic on the other end left to you.

This is where I have to stop using this example, for client confidentiality purposes, but imagine what is possible now if you extend this and use the template_redirect hook to handle some custom redirects leveraging wp_redirect()?

Imagine. :)

My Three Tiered System to Job Searching

Photo used under Creative Commons and taken by photologue_np
Over the past months, since I parted with WP Engine, I have entertained many inquiries about my availability for other full-time roles. And I literally mean many. It’s been a great problem to have, frankly, and I consider myself blessed to have these inquiries while so many others continue to struggle to find work.

I also consider myself blessed to work in a specialty field. WordPress consulting, you would think, is something that is extremely saturated. To a degree you’d be right. As a consultant, I turn away a great number of projects because, frankly, they amount to building sites with WordPress. There is certainly nothing wrong with that kind of work, but I’ve found over years of consulting that it’s important to be a specialist. To not be a specialist means to compete with everyone else on the same level and that reduces the quality and quantity of projects I can work on.

Instead, I focus on high-end WordPress integrations and plugin development. Complex things. I make a reasonable living doing things that there are only a proverbial handful of people who have the ability to do.

At the same time, I continue to entertain full-time job offers. There are some great ones out there, but many just don’t interest me. I have a three-tier (God, as a beer advocate, I hate that term but in this case it fits) filtering process I go through when entertaining job offers. I think this three-tier system should apply to anyone and everyone looking to work in any field, and so I’ve decided to share it.

Is the money right?

We all need to live, and I’m not one who believes the starving artist mantra is necessary a healthy one. If you’re good at what you do, you should be compensated appropriately. Personally, I don’t think anyone would have an argument in this area. A seasoned DBA should not be making $50k, for instance.

As a consultant, I’ve come to have a lifestyle that I’ve worked very hard to achieve. I’m going to be 36 soon and I’ve been married, had a kid, worked on startups, lived in expensive areas of the country and cheaper areas of the country. I’ve built a lifestyle that no job should ever take away.

We all have our “number”. Know for yourself what that number is and stick to your guns when determining if you want to work for someone. Simply not enjoying your current job is not a valid reason to take less than what you’re worth.

Does the job make you want to jump out of your chair and SQUEEEE?

IF it doesn’t, walk away. You should love every minute of what you do and jump out of bed in the morning (after a reasonable period of off-time) eager to see what new innovations, products, ideas and relationships can be achieved.

To do less is selling yourself short. Never settle for anything less than awesome. Some inquiries, for me, have been awesome on the money side but I feel so dull and want to pull each fingernail out of it’s socket just thinking about it. Read my lips! I will never work in a cubicle again! Ever! Don’t ask!

Recently, I spoke with a company who demoed some of their products (WordPress-based) they were working on. They showed me tools that they had built in that allowed their 300some entities they managed to do amazing things (things I tried at b5media years ago [and failed]) in easy, intuitive ways. All I wanted to do was scream “OMGYESPLEASE!” through the phone.

If you don’t have that reaction, think really hard about whether you want to commit.

What’s the social impact?

I’m not a tree-hugger, but one thing I can say is that consulting is both awesome and terrible. I get a lot of benefits by working for myself. But that’s kind of it. I get lots of benefits from working for myself. No one else does. Just me. My world isn’t a better place because of my work. My wallet is happier, but the world around me still sucks.

So when I talk to companies about working for them, I want to know that my work has a positive effect on the world around me. Whether it’s education or environmental; sustainability or fitness; empowering others or enabling positive social change – it’s an important facet in what I look for.

Does the company reward employees for not wasting energy and taking the bus or riding a bike to work? Does the company offer some sort of subsidy or reward for green energy consumption? How many women are employed as engineers?

How does working for Company X positively affect the world around me?

I think these three things are co-equally important for anyone, not just me. I hope so, anyway. We shouldn’t hate what we do, ever. We choose what we do. Choose wisely.

Science is King

I’m a scientist.

I don’t have a degree from Stanford or Carnegie Mellon… But I’m a scientist.

I hypothesize, test and prove.

If the result doesn’t meet my supposition, I accept that and move on.

Science required known, provable facts. Or in computer science, constants.

To prove, you need to test. To test, you need constants. You need to know with 100% certainty that the factors in your experiment are known and 100% objectively provable.

Obama isn’t an American, while a supposition, cannot be proven as fact. There are records showing otherwise.

That men are pigs, while an okay assumption, does not rely on provable facts. Any proof relies on subjective experience.

That WordPress is the best CMS on the planet? While it may control ~20% of the web, assumes that 20% thinks its the right choice and avoids supporting evidence toward other CMSes.

I can get more explicit about suppositions assumed as fact, but you get the idea.

Work with what you know. Make assumptions but allow yourself to be wrong. Data is the only thing that matters.

WordPress Plugin: Easy Graphs

Everyone likes data visualizations so I wrote a plugin that will make the quick and secure creation of Pie Charts, Bar Charts and Line Charts easy. The answer is: Easy Graphs.

Easy graphs is very simple to use. It’s a shortcode – [easy_graphs]

Not just like that. The shortcode also requires one parameter “data”. This parameter is a comma separated list of number values “1,2,3,4,5,6,7”.

You can also add a “type” parameter. The “type” can be “line”, “bar” or “pie”. “bar” is the default.

For a Bar graph, you can optionally pass additional parameters: width, height, and color.

Example: [easy_graphs height="200" type="bar" data="30,70,65"]
[easy_graphs height=”200″ type=”bar” data=”30,70,65″]

By default, width and height are populated from your media embed sizes that are set in your Settings > Media menu inside WordPress. Color should be a hex color code.

For a line graph, the options are similar: color1, color2, height and width.

If you will: [easy_graphs height="200" type="line" data="200,150,175,260"]
[easy_graphs height=”200″ type=”line” data=”200,150,175,260″]

In this case, color1 is the “fill” color and color2 is the line color. Both should be hex.

For Pie charts, there are some additional limitations but fewer parameters: color1, color2 and diameter.

Try this: [easy_graphs diameter="150" data="40,60" type="pie"]
[easy_graphs diameter=”350″ data=”40,60″ type=”pie”]

Diameter should be an integer represented in pixels. Color1 and color2 are the fill colors of the pie slices. The limitation is the pie chart, at this time, can only take 2 values. I’ll work on that.

On the roadmap are other things. Make the pie chart take more values than just 2. Maybe include other graph types. Labels so the data can be more easily understood.

What would you add to this?

Download Easy Graphs

TUTORIAL: Using WordPress’ Ajax API

WordPress has tons of APIs to do tons of things. It really does. One of the cool ones that I’ve been using a lot lately, has been around for a bit. It’s the Ajax API. Sure, you could write your own Ajaxy thing but why do that when WordPress lets you do it all very simply.

This tutorial will show you how to replicate the functionality that is presented in the “Like” button at Facebook. It assumes that you have WordPress set to require users to be logged in to take such actions. It wouldn’t make much sense for someone to not be logged in for such functionality. Obviously, you could do something else with Ajax (polls? Loading new content?) that doesn’t have the same assumption, but in this case… we’re assuming a user is logged in and the $current_user global is set.

Getting Started

Let’s start with the basic PHP class (you do write good object-oriented code, right?)

1
2
3
4
5
6
7
8
class My_Like_Button {

    function __construct()
    {
    }
}

$my_like_button = new My_Like_Button;

This code is just a basic skeleton that provides a constructor (the __construct() method, which I’ll use later. It also instantiates a new My_Like_Button object and assigns it to the $my_like_button variable for use in the global scope. Obviously, you can use whatever strikes your fancy for the class name or the global variable.

Building the HTML for the Like Button

Next, we need the basic HTML structure that will be used in our theme for the Like button. For the sake of simplicity, I’m not providing any CSS, but feel free to do as you wish. We need to add this as a new method in our class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function like_button()
{
    if( !is_user_logged_in() )
        return false;
       
    global $current_user;
       
    $html = '<form action="" method="post">
        <input type="hidden" name="like_post_id" id="like_post_id" value="'
. get_the_ID() .'">
        <input type="hidden" name="like_user_id" id="like_user_id" value="'
. $current_user->ID . '">
        <input type="button" name="like_this_post" id="like_this_post" value="Like" />
    </form>'
;
    return $html;
}

This form provides two hidden form fields using get_the_ID() and the $current_user object. Having done this (and after ensuring there is a logged in user), we can now drop this into our theme in the Loop as a template tag:

1
<?php echo $my_like_button->like_button(); ?>

Sending the Ajax Request with jQuery

This is useless by itself. We need something to handle the Ajax. But before we get there, we need to understand how Ajax works within the WordPress context.

All requests must go to wp-admin/admin-ajax.php. Forget the confusion about why you would send a front-end Ajax request to the back-end. You just do.

On the back-end, you’ll have to define functions that will hook into the Ajax API to let WordPress know how to handle the request. More on that in a minute. Let’s build some jQuery to send this to admin-ajax.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function js()
{
    wp_enqueue_script( 'jquery' );
    wp_print_scripts();
    ?>
    <script>
    jQuery(document).ready(function(){
           
        jQuery('#like_this_post').click(function(){
            var like_post_id = jQuery('#like_post_id').val();
            var like_user_id = jQuery('#like_user_id').val();
           
            jQuery.post(
                '<?php echo get_option('siteurl') . '/wp-admin/admin-ajax.php' ?>',
                {
                    action      : 'register_like',
                    user_id     : like_user_id,
                    post_id     : like_post_id,
                    _wpnonce    : '<?php echo wp_create_nonce('nonce-register_like'); ?>',
                },
                function(response) {   
                    alert(response);
                }
            );
               
        });
    });
    </script>
    <?php
}

This is just a PHP function that we can use to throw some jQuery (using the .post() method for our Ajax call) into the head. Note the nonce. You must include this for security. Additionally, you must have an action set. The action is used by WordPress to route the Ajax request.

Finally, we’re passing two extra pieces of data – user_id which is the WordPress user ID and the post_id which is the WordPress post ID of the current $post object inside the Loop. Both of these are supplied in the hidden form fields we created earlier.

Let’s add a new method for hooks and call it in our constructor, so that hooks are executed when the object is instantiated:

1
2
3
4
5
6
7
8
9
function __construct()
{
    $this->hooks();
}
   
function hooks()
{
    add_action( 'wp_head', array( $this, 'js' ) );
}

Supplying the Ajax Handler

Having hooked the jQuery into WordPress, we now need something on the other end to handle the request and return something back to our page. For this, let’s create a method called handle_like().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function handle_like()
{
    global $wpdb;
    $user_id = (int) $_POST['user_id'];
    $post_id = (int) $_POST['post_id'];
       
    if( !is_user_logged_in() )
        return false;
       
    if( !wp_verify_nonce( $_POST['_wpnonce'], 'nonce-register_like' ) )
        die( 'Go away, asshole!' );
       
    /*
        Here is where we do some sort of database operation to associate
        the Like of the given post with the user who performed the action
       
        Make sure you check for errors. In order to return data, you must
        echo something that the originating page can see. True or false
        only makes sense on this page and not back there.
           
        Typically, you'd output some sort of JSON, XML or plain text.
    */

    $meta_id = add_post_meta( $post_id, 'user_liked', $user_id );
    if( !$meta_id )
        echo "Like not recorded";
    else
        echo "Like recorded";
    exit;
}

In this method, it’s important that all data be sanitized to avoid security problems. I’m performing the most basic of data security here by casting the $_POST variables for the users ID and the post ID to integers.

We’re also checking to make sure the user is logged in. This is why using the built in WordPress Ajax API is actually kind of important. If you build your own Ajax handler, there’s no way to reliable tie in to WordPress to use other APIs like the User API.

Finally, make sure you verify the nonce so you know the request is coming from a legitimate source.

The three security procedures I just listed will largely prevent SQL Injection, ensure authenticated users and eliminate the possibility of Cross Site Request Forgery (CSRF) and generally should be used in all WordPress plugin development.

Simply though, the above method takes the post ID, the user ID and creates a new record in the postmeta table. On success, it will print a success method readable by the original sending page and vica versa on failure.

Note: You must use die() or exit() at the end of the method to make sure the Ajax response exits properly.

Tying the Handler into WordPress

Now that we have a handler method to do our bidding, we need to make sure WordPress knows about it so it routes Ajax requests to the proper place. To do this, we leverage the wp_ajax_{$action} hook.

Remember earlier, while building the jQuery Ajax request, I mentioned that an action POST variable had to be set? WordPress looks to this variable to create a dynamic hook that we can use our new Ajax callback to hook into.

1
add_action( 'wp_ajax_register_like', array( $this, 'handle_like' ) );

Because our action in the js() method was set to register_like, the hook WordPress creates dynamically is wp_ajax_register_like and we can use that to hook our Ajax handler onto.

Wrapping it all Together

Easy right? Use jQuery to send data, wp-admin/admin-ajax.php to receive the Ajax request and pass it on to an appropriate handler function, and send data back to the original page. On the receiving end, you can use normal means to handle the returned data as you wish.

You can download the full code used here at Github.

Blackouts, Boycotts and Regressing From Progress

A couple of weeks ago, the United States, and in fact, the world saw the internet grow up. Namely, through the use of blackouts – a previously unused tactic of protest and grassroots organizing – we saw the evil Stop Online Privacy Act (SOPA) and it’s evil twin Protect IP (PIPA) anti-piracy legislation fail in what seemed like an instant.

Back in December, it became clear that Congress would hearken to their corporate sugar daddys and shove these two pieces of legislation through the Congress without so much as a minimal amount of input from the technology world that would be devastated by their provisions. After votes on these bills were delayed until after the new year, the Internet – led by Wikipedia, Google, Craigslist, and hundreds of thousands of other sites, including this one – self-organized a protest that would involve “blackouts” of sites (and in some cases, very pronounced messaging in he case where blackouts were not feasible.

Despite defensive posturing by the Motion Picture Association of America (MPAA) and others who served to benefit from the legislation, Congressmen and Senators began fleeing the bills en masse. We had successfully made our mark on Washington.

But then a funny thing happened. Twitter made some changes to it’s infrastructure to make it possible for them to operate transparently and legally inside countries that have stricter laws on free speech. It’s a necessary problem that companies have had to face for decades in places like China where speech is censored. I’ll let you read their blog post on the topic.

A small portion of the internet cried foul, claiming censorship. They looked at Twitter as anti-free speech and attempted – unsuccessfully – to self-organize a boycott of Twitter. It failed.

A very specific truth is at play and this is the crux of things. We matured on SOPA blackout day. We decided we wouldn’t be independent and fractioned, which is our nature as independent organizations and people. We had a desired goal (the defeat of SOPA/PIPA) and very specific actions and messaging that needed to happen.

The Twitter boycott (and most boycotts like it) cannot be effective in the same way. The Twitter boycott was a regression in our maturity. We didn’t have the same goal with surgical precision. We didn’t have any ground-swell of support. We had no stated goal or desirable outcome. We can’t use the same tactic every time. We regressed.

And by we, I don’t mean me. I knew it would be a failure.

Grassroots organizing is important and there will be other necessary flexing of muscle. But we can’t just cry foul because we don’t like a decision a company has made. We need to be selective about the fights we engage in and do them tactfully, strategically and surgically. That is maturity.