Getting Track Artwork from Spotify using PHP

Posted 14th December 2012

At time of writ­ing, Spo­tify doesn’t pro­vide a track’s art­work via its API.

So, I’ve writ­ten a sim­ple func­tion to get the image; but please note, not only is it quick and dirty, but it’s hor­ri­bly inef­fi­cient and should be used spar­ingly — at the very least, make sure you cache the results somewhere!

You can access a public-​facing web-​page about a par­tic­u­lar track using the fol­low­ing URL:

http://open.spotify.com/track/[TRACK-ID]

…where [TRACK-​ID] is the last part of the track’s URI — so for exam­ple, for the track rep­re­sented by the URI spotify:track:5fpizYGbi5IQoEraj6FP0R, the track ID would be 5fpizYGbi5IQoEraj6FP0R, and thus the URL to the page would be:

Using Laravel's Pagination Class with JQuery Masonry and Infinite Scroll

Posted 25th July 2012

Just a quick one, but it’s some­thing that I got stuck with for a while.

If you try and use Laravel’s pag­i­na­tion class with JQuery Masonry along with Infi­nite Scroll, you may find a prob­lem. When you scroll down beyond what should be the last page, you’ll prob­a­bly find that you keep get­ting the last page over and and over again, caus­ing gen­uinely infi­nite scrolling. The rea­son for this took me some uncovering.

When Inifi­nite Scroll requests an addi­tional page, it incre­ments the page num­ber, but gets the same con­tent back — how­ever, there is no rea­son why it should know that that’s the case. It’s because it keeps get­ting new con­tent back that it keeps try­ing, but the issue is actu­ally in the Lar­avel Paginator.

Targetted Geolocation with Geonames on PHPMaster

Posted 26th December 2011

I haven’t blogged for a while, but I have been writ­ing. I recently wrote an arti­cle for PHP Mas­ter (part of the Site­point fam­ily) on geolo­ca­tion, called Tar­get­ted Geolo­ca­tion with Geon­ames.

The arti­cle looks at how you can use a RESTlike web ser­vice called Geon­ames to take a user’s loca­tion and resolve it to a place name. In the arti­cle, I use the exam­ple of pro­vid­ing a prompt urg­ing the user to go check out the cin­ema list­ings in their local town, what­ever that hap­pens to be.

I’m cur­rently writ­ing another geo-​based arti­cle for the same pub­li­ca­tion, as well as some other arti­cles for here and else­where — stay tuned!

Migrating a Concrete5 Site from Windows to Linux, and MySQL Case Sensitivity Hell

Posted 21st October 2011

If, like me, you often develop on a Win­dows plat­form and then host using a *Nix-​based server, Concrete5 has a gotcha which will prob­a­bly hit you when you come to pub­lish your site. At some point no doubt you’ll reach the point where you’ve copied the code­base to your server, cre­ated a data­base dump and imported it into the MySQL instance on your *Nix-​based server. Try brows­ing to your site at this point, though, and you’ll get a mes­sage a lot like this:

Fatal error: Uncaught exception 'ADODB_Exception' with message 'mysql error: [1146: Table 'mysite.Config' doesn't exist] in EXECUTE("select * from Config where uID = 0 order by cfKey asc") ' in /var/www/mysite/htdocs/concrete/libraries/3rdparty/adodb/adodb-exceptions.inc.php:78 Stack trace: #0 /var/www/mysite/htdocs/concrete/libraries/3rdparty/adodb/adodb.inc.php(1037): adodb_throw('mysql', 'EXECUTE', 1146, 'Table 'mysite...', 'select * from C...', false, Object(ADODB_mysql)) #1 /var/www/mysite/htdocs/concrete/libraries/3rdparty/adodb/adodb.inc.php(1012): ADOConnection->_Execute('select * from C...', false) #2 /var/www/mysite/htdocs/concrete/libraries/database.php(75): ADOConnection->Execute('select * from C...') #3 /var/www/mysite/htdocs/concrete/models/config.php(151): Database->__call('Execute', Array) #4 /var/www/mysite/htdocs/concrete/models/config.php(151): Database->Execute('select * from C...') #5 /var/www/mysite in /var/www/mysite/htdocs/concrete/libraries/3rdparty/adodb/adodb-exceptions.inc.php on line 78

Extending Drupal 7 Block Permissions

Posted 4th September 2011

Dru­pal 7’s block mod­ule can be a lit­tle lim­ited in its per­mis­sions; “Admin­is­ter Blocks” is a rather sweep­ing capa­bil­ity, and often it’s use­ful to be able to make it that bit more gran­u­lar. For exam­ple, you may have a num­ber of blocks through­out the site but once they have been placed in the cor­rect region and the vis­i­bil­ity cor­rectly con­fig­ured (which often isn’t the sim­plest of processes), you don’t want con­tent man­agers to change those set­tings. You do, how­ever, need to allow them to change the title as it appears to site vis­i­tors, and of course the con­tent. This isn’t pos­si­ble out-​of-​the-​box; luck­ily, it’s not that hard to do. Inspired by kiamlaluno’s post on Dru­pal Answers along these lines, I’ve knocked up a sim­ple mod­ule to make per­mis­sions gran­u­lar enough for just a sit­u­a­tion. It’s incred­i­bly sim­ple and some­what lim­ited, but it does enable to you to grant or deny access to each part of a block’s con­fig­u­ra­tion, i.e.:

Using Less, the Dynamic Stylesheet Language, in Concrete5

Posted 2nd September 2011

Less, the dynamic styesheet language

Hav­ing played around with Less for a while, I’m quite taken with it. Espe­cially with use­ful tools such as Twitter’s newly released Boot­strap being opti­mised to work with it. Less works with CSS to pro­vide all sorts of neat fea­tures such as vari­ables, nested rules, func­tions and “mix­ins”, which means less code, and eas­ier to main­tain code. So, for exam­ple, instead of doing this each time you want a rounded corner:

-moz-border-radius: 10px; 
-webkit-border-radius: 10px; 
border-radius: 10px;

Seven Useful Drupal Modules to Enhance Usability for Administrators

Posted 24th August 2011

One of Drupal’s weak­nesses, I feel, is that out-​of-​the-​box usabil­ity for admin­is­tra­tors is a lit­tle poor (the Dru­pal team them­selves would prob­a­bly agree with me, how­ever this is some­thing that’s now being addressed in a big way). There are, how­ever, plenty of ways to make the expe­ri­ence bet­ter through a set of Dru­pal mod­ules which I’ll be cov­er­ing in this post. How­ever before even think­ing about mod­ules, it’s impor­tant you have a good admin theme — and there are a few good options. Root­candy is a peren­nial favourite, and comes in three flavours; stan­dard, fixed (i.e. a fixed width) and dark.

The Rootcandy admin theme for Drupal
The Root­candy admin theme for Drupal

Drupal 6 Install Profile Fail: Call to undefined function db_result() in path.inc

Posted 23rd August 2011

I’ve just spent hours try­ing to get an install pro­file to work, which was giv­ing me this error:

**Fatal error: Call to undefined function db\_result() in [site\_root]/includes/path.inc on line 54** 

Google helped to an extent; the prob­lem, it seemed, cropped up with a num­ber of instal­la­tion pro­files and it’s dur­ing the exe­cu­tion of hook_profile_modules() that it appears. The most com­mon cause, it seemed, was to do with the JQuery UI mod­ule, and in par­tic­u­lar the link to the library itself, which you have to down­load sep­a­rately. I had no such prob­lem, how­ever — thanks to a cou­ple of lines in my (Dush) make file it had already been down­loaded, and remov­ing JQuery Ui from the list of mod­ules to install didn’t fix it. Nor did exclud­ing date_api, another mod­ule with which this prob­lem can occur. In the end I had to go through each of the mod­ules I wanted my instal­la­tion pro­file to enable for me — a lot of them — sys­tem­at­i­cally in order to find the cul­prit. The cul­prit, it turns out, was robot­stxt. Hope this is of some help to some­one — I’ve wasted hours of today! (I should point out, by the way, that this prob­a­bly isn’t the fault of the mod­ule in question!)

Drupal 7: drupal_execute has Gone, Say Hello to drupal_form_submit

Posted 17th August 2011

As has been com­mented else­where, when you’re pro­gram­mat­i­cally insert­ing data the most reli­able way of doing so is often to sim­u­late form sub­mis­sion — that way, any val­i­da­tion rules are applied and other mod­ules have a chance to inter­cept the sub­mis­sion to do what they need to with the data. This was achieved using the func­tion drupal_execute:

$form_state = array();
$form_state['values'] = array();
$form_state['values']['field1'] = $value1;
$form_state['values']['field2'] = $value2;
drupal_execute('your_form_id', $form_state);

How­ever,

drupal_execute has gone alto­gether from Dru­pal 7. Instead, you need sim­ply replace any call to drupal_execute with the new func­tion drupal_form_submit (see the doc­u­men­ta­tion). Oth­er­wise, every­thing (from the point of view of your syn­tax) remains the same. Don’t for­get to use form_get_errors() to ensure that the form has validated.

Using an Additional Database in Drupal 7

Posted 16th August 2011

One of the nice, lesser-​known fea­tures of Dru­pal 7 is the abil­ity to use addi­tional data­bases and switch at ease. This might be use­ful for exter­nal data­bases, or if you have another data­base in an alter­na­tive for­mat — per­haps you have an SQLite data­base that for per­for­mance rea­sons, you don’t wish to migrate. (Yes, Dru­pal 7 now sup­ports SQLite!) The con­fig­u­ra­tion can be a lit­tle con­fus­ing at first, so let’s look at a settings.php file set up to use two data­bases: drupal on Localhost, and db2 sit­u­ated at db.example.com.

$databases = array (
  'default' => 
  array (
    'default' => 
    array (
      'database' => 'drupal',
      'username' => 'username',
      'password' => 'password',
      'host' => 'localhost',
      'port' => '',
      'driver' => 'mysql',
      'prefix' => '',
    ),
  ),
  'external' => 
  array (
    'default' => 
    array (
      'database' => 'db1',
      'username' => 'username2',
      'password' => 'password2',
      'host' => 'db.example.com',
      'port' => '',
      'driver' => 'mysql',
      'prefix' => '',
    ),
  ),
);