Latest Tweets

Implementing Drush Commands

Drush is really cool, pretty much everyone knows that already. It is not only a great help with administrative stuff (install/uninstall modules, update them, dump databases... you name it!), but we can also use it to make our own modules more powerful.  In a nutshell, we can expose our functionalities through Drush. This could be desirable not only from a usability point of view, but also as a way to overcome Apache limits. 

Ok, now, how do we do this?

First, we need to create the file that Drush will use to know that there is a new command for him to run (bear with me thinking about Drush as a guy. I just can't imagine a girl being this obedient Laughing ) .

For this Drush uses a name convention: {module-name}.drush.inc
In this file we have to implement a couple of hooks:

hook_drush_help

This is a very simple one. It makes our command to show up when you run drush without arguments within the site. Like this:

See our command in Drush help 

The code is straightforward:

/**
 * Provide help for Drush method
 * @param  $section
 * @return 
 */
function ignite_drush_help($section) {
    switch ($section) {
        case 'drush:youtube-sync':
            return dt('synchronize videos with YouTube.');
    }
}

hook_drush_command

This hook has the magic. Here is where we declare the command for Drush.
Let's see a real example:

/**
 * Implementation of hook_drush_command().
 */
function ignite_drush_command() {

    $help_batch = 'Without arguments, this command will update a batch of videos.' . "\n".
        'The videos will be selected from the ones that were updated the longest ago, '. 
        'starting from a configured limit in the past (currently is set to '. variable_get('ignite_update_time_limit', '4 hours') . ' ago). '. 
        'The maximum number of videos that the batch can contain is also configured (currently is set to '. variable_get('ignite_update_batch_limit', 60) .'). '. 
         'Configurations are done in "Site configuration, Ignite settings"'."\n";

    $items['youtube-sync'] = array(
        'description' => 'synchronize videos with YouTube. It has two modes: update one specific video, or process in a batch mode. ',
        'examples' => array(
            'drush youtube-sync' => $help_batch,
            'drush youtube-sync nid' => 'If a specific node id is provided as argument, the command will update only that specific video.',
        )
    );

    return $items;
}

The function is not very complicated. Besides declaring the command, it provides examples of use of your command. In this particular case, most of the code is just assembling those help texts. 

The highlighted line shows the tricky part. It declares the name of the command. Based on that, we need to create a function that will do the job. This function must have a very precise name:

drush_{the-name-of-the-module}_{the-name-of-the-command} ... but, in the name of the command, you have to change the "-" for "_"

My module is called "ignite", therefore this is the function I created to actually do the job:


/**
 * Implementation of the YT batch synchronization command
 */
function drush_ignite_youtube_sync($nid = null) {

    drush_set_option('user', 1);
    drush_bootstrap(DRUSH_BOOTSTRAP_DRUPAL_LOGIN);

    if (is_null($nid)) {
        synchronize_videos_batch();
    } else {
        process_video_update($nid);
    }
}


Well, yeah, this is also calling other functions... but that's the same old story. Here we are in our module, and we just implement whatever we need to implement.

So that's it regarding Drush! let's see what we have:

Running drush help youtube-sync, we get:

2.png 

And running the specific command, we get:

3.png

All good!

I hope you find this useful... Until the next post! 

Author

Managing Partner
Aldo works as a general mentor for the development teams, keeping in direct contact with programming and design.

Comments

Excellent! I did not find before that dark trick about the name. Thanks!

Add comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.