Injecting Closures into your Classes

I wanted to reuse a class of mine, which generated a <ul> with links, only this time I wanted to alter the link text using a custom function (closure) in the constructor.

<?= $this->generateUl($existing_arg1, $existing_arg2, function($args){ //do stuff } ); ?>

Inside the class constructor, I set the following:

public function __construct($existing_arg1, $existing_arg2, Callable $closure = null)
    $this->closure = $closure;

And here’s the wee catch: You can’t call it like a normal method, $this->closure($args); You need to assign it to a standard variable for whatever reason.

     *  @param ESOS_Entity_Org $org
     *  @return string
    private Function generateLinkText(ESOS_Entity_Organisation $org)
            // This is my default functionality
            return $org->getName();
        // There are two ways of doing this next bit:
        // $this->closure($args); won't work but $closure($args) will!
        // $closure = $this->closure; 
        // return $closure($org);

                // Here's the better way:
                return call_user_func($this->closure,$org);

Doing this has made me realise just how awesome Callables can be, you could inject in all manner of functionality into a class! Play around with it!

Custom jQuery validator functions

The jQuery validator is really cool, and you can create your own validators. Here’s one that counts the words in a text area, and validates :

$('.word_count').each(function() {
 var input = '#' +;
 var count = input + '_count';
 word_count(input, count);
 $(this).keyup(function() { word_count(input, count) });
function word_count(field, count) {
var number = 0;
 var matches = $(field).val().match(/\b/g);
 if(matches) {
 number = matches.length/2;
 $(count).text( number);
jQuery.validator.addMethod("twentywords", function(value, element, param) { 
 if($(element+'_count').html() > 19){return true;}
 else{return false;}
 }, jQuery.validator.messages.url);

And in the rules section:

rules: {
f_review: {
 twentywords: true
 messages: {
f_review: "Please leave a review of the agent at least 20 words"

I’ve hard coded the name input into the validator, as I’m in work and it needs done quickly, but I’m sure this could be tweaked. Finally there is a hidden element that the word cound gets stored in and the input textarea has a class of word_count:

<div id="f_review_count"style="display:none"></div>
 <textarea name="f_review" id="f_review" rows="8" cols="40" class="text-long word_count"></textarea>

The word count stuff can be used on its own without the validator too. 🙂