Archive for September, 2008

SACK of AJAX

September 30th, 2008

For those of you that don’t know what AJAX is, please read my simple tutorial here. For those of you that do, carry on reading…

I wanted to use some AJAX within a wordpress plugin i’m writing called Your Responder to handle a form submission and feedback without having to refresh the page.

I was reading through the Codex looking for anything AJAX related and came across a bundled script called SACK. It actually stands for Simple Ajax Code Kit and i’m happy to say it does exactly what it says on the tin. I haven’t even looked at the advanced features yet but a basic ajax request can be made in a few small lines of easy to follow code.

The full wordpress example is here but I thought I would give a explanation of my own…

The first stage is to incorporate the SACK library. Of course there is a special way to do this in wordpress but it’s very simple:

wp_print_scripts(array('sack'));

Copy that somewhere into your plugin and it does the same as putting a ‘<script src=”" />’ into the head of the html page.

Next comes the actual call:

  var mysack = new sack("www.yoursite.com/wp-content/plugins/myplugin_ajax.php");    

  mysack.execute = 1;
  mysack.method = 'POST';
  mysack.setVar("vote", vote_field.value);
  mysack.onError = function() { alert('Ajax error in voting'); };
  mysack.runAJAX();

  return true;

Does it look complicated? If your answer is yes then I urge you to have a look at the actual AJAX code to accomplish a POST request. I shall go through this line by line to help it make a little more sense:

The first line sets up a new variable called mysack which is actually an occurence of the mysack object. It allows you to call any function from the library and set up variables within it without interfering with any other SACK requests on the same page. The url in the call is an absolute link (I have yet to test with relative links) to the PHP script that the request will be sent to, much like the ‘<form action=”">’ tag.

Ignore the execute line. For a simple example just appreciate it has to be there. The method line is directly the same as ‘<form action=”">’ so can accept, to my knowlege,  either GET or POST.

The next line ’setVar’ you can duplicate for each field you want to send to your back end script. So if you wanted to send something that will appear to the server as $_POST['field1'], you simply write:

mysack.setVar("field1", document.getElementById("input_field_id").value);

Remember this is a JS function so where I put my document.getElement… call, you can write anything that javascript understands (although to keep it tidy, it’s probably best to sort it out earlier and store in a variable).

On error is probably best to leave empty unless you want to show a div on the screen saying something like ‘invalid request’. Remember this will be shown to your site users to an alert box probably isn’t the best approach.

Finally we fire off the request using runAJAX().

The PHP backend

At this stage your user is looking at your site and has, in some way or another, fired off an AJAX request. If the request was intentional (ie: not triggered by something passive) then they most likely expect something like a message back from the server or event to occur.

In the above example we declared a new instance of the SACK library with the url we want to send a request to (www.yoursite.com/wp-content/plugins/myplugin_ajax.php). The PHP script we need to write obviously needs to be at this location.

There are two things you really need to remember with this:

  1. AJAX requests accept anything echoed as it’s response and will throw an error if it’s not sent proper JS code.
  2. Use a PHP ‘die’ statement to send your response to the client.

All the first one means is that, when testing, a print_r($_POST); will not work properly and if you can see AJAX/JS errors (via Firefox and Firebug or similar) then you will most likely be prompted to fix your code.

The second one is simply a recommendation from the Wordpress development team which I agree with. If you concatenate your response JS code into a variable and then run a ‘die’ with your variable as the argument then it’s likely to work.

See the following example of what would be your ‘myplugin_ajax.php’ file:

<?php
if (isset($_POST['vote']) {
    //Perform some DB bits here
    $feedback = 'alert("Your vote was successfully recorded");';
    die($feedback);
}
?>

If you now understand what to do then I recommend trying it before reading the next section because it will only confuse matters if you are just getting to know either AJAX or Wordpress.

We are checking in $_POST for a variable called ‘vote’ and notice there is no ‘else’ statement. We don’t need an else unless you want to report error messages back to the server which in this case I don’t.

Wordpress doesn’t allow immediate access to any files inside it’s directory structure so things like Database access and shared function usage won’t be possible. The only way we can make this work is to incorporate the handing code into the main plugin itself. Simply add your version of this code to your main plugin PHP file which will be called from within wordpress.

This also means that your setup URL for SACK will simply be the homepage of your blog. This will work because wordpress scans it’s plugin directory when it initiates its framework looking for hooks. As long as your plugin is active it will run your logic. The die statement will also stop that instance of the script from running hence the if statement with no else.

Good luck and let me know if you need any help, spot a mistake or just want to say something :)

Newmedias Progress

September 24th, 2008

I have been working with Tim from Newmedias for a while now with great success. You will already be aware for Your Members, the popular Wordpress membership plugin and more recently Your Minder, a Wordpress account sharing prevention tool.

Now we have been working on Your Responder and Your Classifieds which are both very nearly ready to see the light of day (at least in a beta capacity).

Your Responder is an autoresponder plugin for wordpress that we have been writing that allows users to sign up to an email series or an email list.

your Classifieds is a classified adverts plugin that does what it says on the tin. Initially we will be writing it so simply allow people to host classified advert sites but eventually we will incorporate both paid advertising for both paid directories and preferential placement.

Watch this space! See www.newmedias.co.uk for more information

IE Annoyance when downloading PDFs

September 24th, 2008

I came across this error at work and it took me a good three hours to fix! The problem was when a user tried to download a pdf file from one of our sites in internet explorer. It worked fine in Firefox though! The error message was:

The file could not be written to the cache

Luckily a far low down on Google had a sensible answer which was to add the following code (PHP) before the call to session_start();

if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) {
    session_cache_limiter("public");
}

Other sites were talking about security settings in versions of IE below 6 but they didn’t really help. I thought I would post this in the hope that it helps anyone else that has the same problem.

bbPress Email notification on post

September 9th, 2008

At Newmedias, we use bbPress and have been using the email notification plugin written by thomasklaiber. It sends an email to those registered for forum notifications every time a post is left on a thread that they had registered for.

http://bbpress.org/plugins/topic/post-notification/

I often look at my emails when im away from home on my pda/phone and find it a real pain to have to open the web link in each email to read it. This also means that I can’t download them in my email client for reading later.

My solution to this was blindingly simple,

Put the body of the most recent post into the email itself!

This feature was not available at the time of writing and works very well. The mod is very simple, here’s how i did it.

note: Before doing this to your version of the plugin, make sure that the original author hasn’t added his own version of the same thing!

1) Open notification.php and find the notification_new_post function
2) Paste the following code after the get_topic() call but before the $message=… call

$posts = get_thread($topic_id, 1, 1);
$posts = array_reverse($posts);
$last = array_pop($posts);
$last_text = strip_tags($last->post_text);

3) Overwrite the $message variable to include the new string at the end as follows:

$message = __("There is a new post on: %1\$s \nReply by: %2\$s \n\n%3\$s \n\n%4\$s");

4) Overwrite the sprintf call to the following:

sprintf($message, $topic->topic_title, get_user_name($bb_current_user->ID), get_topic_link($topic_id), $last_text)

(if you are more familiar with php and sprintf then just add the $last_text variable to the end of the list of variables within the existing call)

5) Save, Backup, Upload and test! It should now send the post body with the email

Optionally you can improve the code within this function somewhat…

1) The get_topic call doesn’t need to be in the foreach loop because the topic_id doesn’t change anywhere in the function. Although bbPress uses cacheing, it would still be best practise to move that line and the lines from my step 2 to the line before the foreach loop.

2) Convert the email to HTML by adding the content-type header and setting it to text/html. If you do this then the \n’s will also need to be changed to <br /> and you can optionally remove the strip_tags() from the last line in my step 2

Good luck and let me know about any problems you may have.