Test Sites (Like a Boss) in 5 Minutes with Placecage and devel_image_provider

Posted By Brad Czerniak on Monday, June 17, 2013 - 09:49

devel_generate is a staple of the Drupal developer's toolbox. It allows you to create arbitrary content, users, and more with placeholder text and images automatically. This allows you to QA performance of queries, test wrapping of headings and text, and a lot more.

If you've used devel_generate before, you know that the placeholder images are a bit, well... boring. Luckily, a contrib module called devel_image_provider allows you to spice things up. Out of the box it includes bacon, flickr, manatees, kittens, zombies, and more images.

But are those options really good enough for enterprise-level testing? If you want to be sure that your layout can handle the image-iest of images, that Views can serve awesomeness a la mode, the solution is obvious: Nicolas Cage placeholder images.

PlaceCage to the rescue! This placeholder image site serves up quality random Nicolas Cage images with a simple URL interface (that happens to work like other placeholder image sites). Here's how to Cage it up:

Define a Plugin

A devel_image_provider plugin is just an include file with an array:

  1. $plugin = array(
  2.   'title' => t('Placecage'),
  3.   'class' => 'PlacecageProvider',
  4. );

It tells the module which class handles the plugin named in the title key.

Make a Provider

The code below looks like quite a bit of work. It isn't, though. All the work has been done by the other placeholder image services; just copy/paste the placekitten or other class and augment to suit.

  1. /<strong>
  2.  * @file
  3.  * Placecage support class.
  4.  */
  5.  
  6. /</strong>
  7.  * Add support for placecage.com.
  8.  */
  9. class PlacecageProvider extends DevelImagesProviderBase {
  10.  
  11.   public function __construct($plugin) {
  12.     parent::__construct($plugin);
  13.     $this->provider_base_url = 'http://placecage.com';
  14.   }
  15.  
  16.   public function generateImage($object, $field, $instance, $bundle) {
  17.     static $images = array();
  18.  
  19.     $min_resolution = empty($instance['settings']['min_resolution']) ? '100x100' : $instance['settings']['min_resolution'];
  20.     $max_resolution = empty($instance['settings']['max_resolution']) ? '600x600' : $instance['settings']['max_resolution'];
  21.     $extension = 'jpg';
  22.  
  23.     if (!isset($images[$extension][$min_resolution][$max_resolution]) || count($images[$extension][$min_resolution][$max_resolution]) <= DEVEL_GENERATE_IMAGE_MAX) {
  24.       if ($tmp_file = drupal_tempnam('temporary://', 'imagefield_')) {
  25.         $destination = $tmp_file . '.' . $extension;
  26.         file_unmanaged_move($tmp_file, $destination, FILE_CREATE_DIRECTORY);
  27.  
  28.         $min = explode('x', $min_resolution);
  29.         $max = explode('x', $max_resolution);
  30.         $max[0] = $max[0] < $min[0] ? $min[0] : $max[0];
  31.         $max[1] = $max[1] < $min[1] ? $min[1] : $max[1];
  32.  
  33.         $width = rand((int) $min[0], (int) $max[0]);
  34.         $height = rand((int) $min[1], (int) $max[1]);
  35.  
  36.         $gray = isset($this->settings['devel_image_provider_gray']) ? $this->settings['devel_image_provider_gray'] : NULL;
  37.         $gray_part = $gray ? '/g' : '';
  38.         if ($gray_part === '') {
  39.           $cray_test = rand(0, 1);
  40.           $gray_part = ($cray_test > 0) ? '/c' : '';
  41.         }
  42.  
  43.         $url = "$this->provider_base_url" . $gray_part . "/$width/$height";
  44.  
  45.         $method = isset($this->settings['devel_image_provider_get_method']) ? $this->settings['devel_image_provider_get_method'] : 'file_get_contents';
  46.         $path = devel_image_provider_get_file($url, $destination, $method);
  47.  
  48.         $source = new stdClass();
  49.         $source->uri = $path;
  50.         $source->uid = 1; // TODO: randomize? Use case specific.
  51.         $source->filemime = 'image/jpg';
  52.         $destination_dir = $field['settings']['uri_scheme'] . '://' . $instance['settings']['file_directory'];
  53.         file_prepare_directory($destination_dir, FILE_CREATE_DIRECTORY);
  54.         $destination = $destination_dir . '/' . basename($path);
  55.         $file = file_move($source, $destination, FILE_CREATE_DIRECTORY);
  56.       }
  57.       else {
  58.         return FALSE;
  59.       }
  60.     }
  61.     else {
  62.       // Select one of the images we've already generated for this field.
  63.       $file = new stdClass();
  64.       $file->fid = array_rand($images[$extension][$min_resolution][$max_resolution]);
  65.     }
  66.  
  67.     $object_field['fid'] = $file->fid;
  68.     $object_field['alt'] = devel_create_greeking(4);
  69.     $object_field['title'] = devel_create_greeking(4);
  70.     return $object_field;
  71.   }
  72.  
  73. }

The only part that deviates from the typical placekitten implementation is that placecage has an option for "crazy" cage photos. Rather than implement crazy along with grayscale, I added a randomizer that intermingles crazy color pictures with regular ones.

Voilà!

Put those files in the devel_image_provider plugins directory, select PlaceCage in the configuration settings, and generate some dummy content. That's all there is to it!