Using Flash SWF ExternalInterface

0 comments

Posted on 10th May 2010 by james in Uncategorized

The Flash ExternalInterface feature allows you to send messages to and from a Flash SWF using Javascript. I was using this on a project recently where I wanted an HTML ‘play’ button to start a video playing in a Flash player elsewhere on the page.

The function in my Flash SWF that started the media was called playMedia(), so I needed to make this available to Javascript, which can be done as follows:

// This goes in your actionscript
// We need to export the function so Javascript can access it
import flash.external.ExternalInterface;
ExternalInterface.addCallback("playMedia", null, playMedia);

The parameter in quotes is the name of the function in Javascript, whereas the one without quotes is the function you wish to call in Flash.

So far so good – the playMedia() function should be available to call from Javascript now.

I tried using the JQuery implementation of SWFObject, but I just couldn’t get my function to call in Internet Explorer. It seems that ExternalInterface function calls won’t work unless the flash code is embedded in the HTML, rather than being added at runtime.

So, the solution was to embed the HTML code, using ensuring that the tag had both a name and ID attribute, “swf_1″ in my case.

In order to call the function, you need to grab hold of the OBJECT tag from Javascript, but as with most things in life, the way this is done varies between browsers. I adapted a Javascript function which I found online, but which wouldn’t work in Chrome. As far as I can tell this function works in IE7/8, Firefox, Chrome and Safari (all on Windows):

// This goes in your Javascript
// We need to grab hold of the OBJECT in order to call the exported function
function getFlashMovieObject(movieName) {
  var movie = document.getElementById(movieName);

  if(movie.tagName.toUpperCase() == 'OBJECT')
    return movie;

  if(window.document[movieName])
    return window.document[movieName];

  alert('Error: could not find Flash object ' + movieName);
}

Now the function in the SWF can be called as follows:

// This goes in your Javascript
// You can now access the exported function
getFlashMovieObject('swf_1').playMedia();

Doctrine PHP Merge Function

0 comments

Posted on 12th December 2009 by james in PHP

, ,

If you’ve tried Doctrine PHP, you might get pretty frustrated when using the $Record::synchronizeWithArray() function. Why?


$data = array('name' => 'jimbob');

$User->Doctrine::getTable('User')->find(1);

$User->synchronizeWithArray($data);

$User->save();

If you try this code you will find that the synchronizeWithArray() function deletes everything except the ‘name’ field in the record. I think the name ’synchronize’ is slightly confusing here, as what it really means is “delete everything except what I’m explicitly telling you right now”.

A bit of digging in the API reference turned up a nice function called merge().


$data = array('name' => 'jimbob');

$User->Doctrine::getTable('User')->find(1);

$User->merge($data);

$User->save();

You will find that all the fields except ‘name’ are untouched. Lovely job.

PHPMailer and HTML email

0 comments

Posted on 25th November 2009 by james in PHP

, ,

If you haven’t already tried it, the PHPMailer class is an excellent way of sending email using PHP. It makes all those dreaded email tasks (multiple message parts, encoding, attachments etc.) really nice and easy.

Today however I came across a problem sending HTML formatted email – only occuring when sending via the PHP mail() transport rather than SMTP.

I eventually traced it to a large block of HTML which formed part of the formatted email. This was generated by a WYSIWYG editor and had no newline characters, and so was too long to handle for the mail() function (the SMTP transport was able to resolve the issue, but I didn’t want to use SMTP for this application).

The $mail->WordWrap parameter didn’t seem to help either.

So I rustled up a quick little function to split the HTML at opening tag boundaries, which solved the problem while keeping the code tidy – here it is:

/**
* Function to wrap HTML, but only at opening tag boundaries
* @param    $s            the HTML string to wrap
* @param    $chars  the number of chararacters to allow per line
* @return $s            the modified HTML
*/
function htmlWrap($s, $chars = 40) {
$aChunks = explode('<', $s);

$sLine     = '';
$aLines  = array();

foreach($aChunks as $i => $sChunk) {
$sLine .= ($i == 0 ? '' : '<') . $sChunk;

// Check if line length too long
if(strlen($sLine) + strlen(@$aChunks[$i+1]) + 1 >= $chars) {
$aLines[]    =    $sLine;
$sLine        = '';
}
}

return implode("\n", $aLines);
}

You can use this as so:

$Mail             = new PHPMailer();
$Mail->MsgHTML(htmlWrap('Your HTML email message here...'));
...

Choosing a CMS in 10 Steps

1 comment

Posted on 3rd September 2009 by james in CMS

Picture this: you have a great website contract, a stunning design, and everything is ready to roll. Except for one little problem: which content management system (CMS) should be used?

There’s no real right or wrong answer to this question, but it can certainly cause a lot of grief if you’re battling the technology rather than being assisted by it. So here’s a couple of handy pointers to help with the decision:

1. Blog or CMS?

If the website is primarily going to handle ‘posts’ – journal entries spread out in time – then a blog is more appropriate. If on the other hand you need to organise a quantity of more structured articles, such as sales literature or support documents, a CMS is going to be your best bet.

There’s actually a fair amount of crossover between blogs and CMS systems these days, but you may as well start out with a tool that’s specialised for the task at hand.

Wordpress is becoming fairly ubiquitous for blogging, with a vast range of third-party themes and plugins available.

2. Self-hosted or cloud-hosted

‘CMS as a service’, where the software is pre-installed and ready to use, is becoming increasingly popular. Available at a whole range of price points, from web-builder type software with pre-designed templates (such as Jimdo) right up to fully fledged business solutions. Our own CreationCentre CMS falls within the cloud-hosted CMS category, and can be implemented very rapidly. If you are using a cloud-hosted solution, what data backup procedures are in place?

For blogging, there are popular pre-installed choices such as Wordpress.com and Blogger.com.

If you are planning to write your own modules, in a language such as PHP or ASP.NET, or require bespoke database interaction, you’re probably going to require a self-hosted solution. Popular solutions here include Joomla, Drupal, and Expression Engine.

3. Programming Language

For cloud-hosted solutions this isn’t an issue, but if you’re installing it yourself the language the CMS is written in (as well as the database that persists it) is going to be an important factor – especially if the client already has a server they wish to use.

Popular choices here include PHP, ASP.NET, Java, and Ruby is spreading quickly too.

4. Built-In Features

You might find it useful at this stage to draw a spider diagram with ‘Website’ in the middle, and broad technical requirements on each of the spokes. Keep going out until you’ve exhausted every possible situation.

Which CMS seems to fit the bill most closely? The closer the match, the better.

Here’s a couple of the more obvious features:

  • Allow for easy management of articles, and the publication of new ones
  • Upload and manage images and files
  • Customisation of templates (whether in vanilla HTML or a scripting language such as PHP)
  • Blogging or news-posting
  • RSS feeds
  • Embedding of custom HTML such as YouTube video or Google Maps
  • Contact forms
  • Galleries
  • Website login accounts, with the ability to set user-only content
  • E-commerce facilities
  • Forum
  • SEO tools such as meta and title tag control
  • Permissions – the ability to allow only certain users to control certain articles or features
  • Workflow tools – allowing a logical flow to the creation and approval of content
  • Document lifecycle tools – keeping a record of all revisions made to a particular article

5. Page-centric or content-centric

Some CMSs have the ‘page’ as the unit of content. In others, content exists in units independent of pages, with one or more content items being displayed on a particular page.

The former method is definitely easier to grasp, and works well if the website is relatively small or the end user is not technical. The latter is more powerful, and can support ‘content-reuse’, where blocks of content can be reused on other pages or even websites in multi-site implementations.

6. Usability

Who is going to be using the CMS on a day-to-day basis? If they’re not particularly technical then this is a crucial point, otherwise you will be inundated with support requests.

For example, not all CMS’s allow for WYSIWYG editing, meaning the user is going to have to learn either basic HTML or a similar in order to format their content. Are they capable? How much training will they require, and who’s going to perform that training?

Choose a CMS which is appropriate for the end-user.

7. Support and Documentation

This is a crucial one too – how much support and documentation are available to you as a developer while you build the website? You don’t want to be left high and dry with important deadlines to meet.

What are the ongoing support costs from the vendor, and does this cover software upgrades?

8. Compatibility

Most CMS systems run in the browser – it’s worth checking what operating system the end-user has, and what browser they have installed. Unfortunately some corporate users may not have administrative permission to install the browser you wish they had!

Does the CMS need to interface with any other business software – the most obvious being Customer Relationship Management (CRM) software? It’s definitely a bonus if after filling in an online contact form, the customer’s information is seamlessly imported into their CRM profile.

Thanks to XML and web services, the CMS can work as part of a larger whole rather than being a single silo of information.

9. Accessibility

It’s a legal requirement in many countries that a website is accessible to users with various disabilities such as visual impairment. So be sure that your chosen CMS can publish content meeting relevant accessibility legislation.

Typically this means meeting the WCA guidelines with a double-A rating.

10. Advanced Features

Is your website going to be serving content in different languages, content that is targeted to a particular geographic region, or publishing content to multiple websites? Does the CMS support the character set of all the target languages?

This makes the CMS implementation considerably more complex, and will narrow the choices quite considerably.

“Organica” – a free HTML CSS template

2 comments

Posted on 27th August 2009 by james in HTML + CSS

,

Today I’m launching a new free HTML/CSS template called “Organica”.

It has a fresh blue and green theme inspired by nature, with beautiful nature photography from photos8.com.

It uses transparent PNGs so that it’s easy to customise the images, even though they have curved borders. Transparent PNG support was added for IE6 with the help of the excellent TwinHelix PNG fix which worked nicely.

Feel free to use in your own projects, just please leave the footer link intact – thanks!

Get it now (ZIP archive)

A fresh blue and green theme inspired by nature

A fresh blue and green theme inspired by nature

JQuery Multiple file upload

0 comments

Posted on 2nd August 2009 by james in JQuery | Javascript | PHP

I’ve been on the hunt for many years for a decent way of uploading multiple files at once via a browser-based upload form. Finally there is one that seems to do a great job, and be fairly easy to install – the JQuery Uploadify plugin.

There’s a couple of ‘gotchas’ that I came across and thought I would share.

Firstly, if you use PHP sessions for your authentication, you’ll find that your PHP script that accepts the upload won’t have access to the current session. This is because Flash gets given a different session ID. One way to get around this problem is to manually send your PHP session id as one of the options, something like:


'scriptData'  : {'sessid' : <php echo session_id(); ?>}

Then your script that accepts the file upload would require:


session_id($_REQUEST['sessid']);
session_start();

Secondly, I found that for the ’script’ option, the plugin requires a relative path. I don’t want to have to keep setting paths because they’re different in my development and live environment, so I did this:


var rel_path     = location.href.split(/localhost|\.co\.uk|\.com|index\.php/)[1];
$('#uploadify').uploadify({
'script':         rel_path + 'upload_script.php'

// other options here...

})

This is a brilliant plugin – a big thank-you to the authors!

Update 09/09/2009: after lots of hair-pulling/teeth-grinding/tea-drinking, the PHP sessions problem just couldn’t be resolved quickly on the live server so I adopted a different approach in the end:

  • A singe use ‘upload authentication key’ is generated each time you upload the file, and stored in the database along with the current user
  • Uploadify sends this key via the scriptData option
  • The script that accepts the file upload ignores PHP sessions, and instead looks in the database for the authentication key to verify the user that sent the file has access.

Fancy zapping some baddies? Go ahead…

2 comments

Posted on 1st August 2009 by james in Flash

Check out this simple Flash game I developed below… Use cursor keys to get around and space bar to fire.

Click to open in a new window

Future of web apps 2009

0 comments

Posted on 30th July 2009 by james in Uncategorized

Just spotted the “Future of web apps” conference in London on 30th Sep – 2nd Oct 2009 – looks awesome!

FOWA badge

A noob’s guide to PHP Doctrine

0 comments

Posted on 30th June 2009 by james in PHP

, ,

This week I am a newbie to PHP Doctrine. So I thought I’d share some of the experiences I’ve had with it, not so much in a coding sense but in a “this is the cool stuff you can do with it” sense.

Doctrine is an ‘object relational mapper’ or ORM for short, letting you code your app in terms of the objects you require, without worrying too much about the underlying database table structure. With SQL queries, a simple 2-dimensional table of rows and columns is returned. Using an ORM, a multi-dimensional object or array can be returned with all the relationships between objects prepared for you.

In general I’m a bit of framework-sceptic, but I think this one really deserves a look as there’s some really powerful tools included.

Also the website is nicely designed and has pretty good documentation on it, which makes all the difference.

So here’s a list of 10 things I’ve learned about it this week, in no particular order:

  1. You can define your data structures using a simple YAML file, which while it sounds like some kind of novel pet food, is in fact dead easy to get to grips with and is very quick to type out.
  2. Doctrine will create PHP model objects all ready to go from the YAML file and install the necessary database tables for you.
  3. If you find yourself needing to change the data structure, you can do so in the YAML file and Doctrine will update the PHP scripts and the database tables aswell, while retaining the data – I think this is a great feature.
  4. Doctrine can guess from the YAML file what the relationships are between objects/tables, and so far seems to do a great job of it.
  5. If you don’t want to hand craft your YAML, you can also do various things like build the models from an existing database structure or vice versa
  6. You can fetch data from one object and it fetches all the related data too, eg if I fetch a blog post and it fetches all the related comments at the same time.
  7. You can use “Doctrine Query Language” or DQL, which is has a similar feel to SQL, but selects objects together with their relationships instead of a flat table of results. Gone are the days of laboriously typing out JOIN statements: because you’ve described the data relationships in your YAML file, Doctrine automatically joins things together for you. Nifty.
  8. You can hook into the models that are automatically generated allowing you to, for example, modify queries on the fly before data is requested, or modify data as it’s returned. This lets you reuse business logic efficiently that is always used on particular fields.
  9. There are built-in behaviours such as ‘timestampable’ or ’sluggable’ which automatically generate timestamp fields or URL slugs (eg ‘this-is-a-nice-blog’) for particular tables
  10. It also has the usual suspects such as data validation – but I haven’t got to that yet…

Right, that’s it for now – if I find out anything else interesting I’ll post it here!

Object Oriented Hook Management in PHP5

1 comment

Posted on 22nd June 2009 by james in PHP

, , , ,

One of the nice features of Wordpress is the plugin system, where ‘hooks’ allow custom functionality to be added without monkeying around with the core functionality.

I haven’t played around with this myself yet, but from what I could gather from the documentation, it does this using functions which are all defined in the global scope.

I was wondering today whether similar functionality could be achieved using a more object-oriented approach.

I wanted to be able to extend core functionality of one object by registering ‘hook’ methods on other objects at specific execution points. So I threw together the following code as a demo:


/**
* Binding class - represents a single event binding
*/
class Binding {
var $oObj;
var $sMethod;

/**
* Constructor
* @param object &$oObj     the object on which we wish to call a method, passed by referenct
* @param string $sMethod the method to call
*/
function __construct(&$oObj, $sMethod) {
$this->oObj         = $oObj;
$this->sMethod     = $sMethod;
}

/**
* Trigger the event
* @param $aArgs an array of arguments for the bound function
*/
function trigger($aArgs = array()) {
call_user_func_array(array($this->oObj, $this->sMethod), $aArgs);
}
}

/**
* Singleton class to hold all event bindings
*/
class Hook {
/**
* Stores the static instance of this object - singleton design pattern
* @param object
*/
private static $instance;

/**
* Array of hooks
*/
private $aHooks = array();

/**
* Constructor
*/
private function __construct() {

}

/**
* get instance of this object
*/
public static function getInstance() {
if (!self::$instance)
{
self::$instance = new Hook();
}

return self::$instance;
}

/**
* Bind functionality
* @param string $sEvent     the name of the event to bind
* @param object &$oObj         the object whose method we wish to call
* @param string $sMethod the method to call
*/
function bind($sEvent, &$oObj, $sMethod) {
$this->aHooks[$sEvent][] = new Binding($oObj, $sMethod);
}

/**
* Trigger a bound event
* @param string $sEvent    the event to trigger
* @param array  $aArgs        an array of arguments to pass to the bound function
*/
function trigger($sEvent, $aArgs = array()) {
if(array_key_exists($sEvent, $this->aHooks)) {
foreach($this->aHooks[$sEvent] as $key => $Binding) {
$Binding->trigger($aArgs);
}
}
}
}

class Extend {

function __construct() {
$Hook = Hook::getInstance();
$Hook->bind('pre', $this, 'beforeDoSomething');
$Hook->bind('post',$this,    'afterDoSomething');

}

function beforeDoSomething($arg) {
echo '<li>This before... the calling function wanted to say"' . $arg . '"';
}

function afterDoSomething($arg) {
echo '<li>The calling function said "' . $arg . '"';
}
}

class Extend2 {
function __construct() {
$Hook = Hook::getInstance();
$Hook->bind('post', $this, 'beforeDoSomething');
}

function beforeDoSomething() {
echo '<li>This is done in a second extended object';
}
}

/**
* Class providing base functionality
*/
class Base {

function __construct() {

}

function doSomething() {
$Hook = Hook::getInstance();

$Hook->trigger('pre',    array("I'm about to start doing something..."));
echo '<li>doing the core functionality...';
$Hook->trigger('post', array("Ok I'm all done now!"));
}

}

$Base = new Base();
$Extend = new Extend();
$Extend2 = new Extend2();
$Base->doSomething();

Hopefully someone will find it useful :)