Skip to main content

Adding Image Uploads to a Custom Module in Drupal

Back-end Development
Drupal

I recently ran into a situation where I needed a fallback image for pages that didn't have a default header image. To do this I created a custom module that provided a configuration page to upload an image. In retrospect, it would have been cleaner to add this to the theme administration page, but this worked well enough.

First, we add a configuration page using hook_menu:

<?php
/**
 * @file
 * mymodule.module
 */

/**
 * Implements hook_menu().
 */
function mymodule_menu() {
  $items['admin/content/set-default-header-image'] = array(
    'title' => 'Set Default Header Image',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(‘mymodule_set_default_header_image_form'),
    'access arguments' => array('access administration pages'),
    'file' => ‘mymodule.pages.inc',
  );

  return $items;
}

Next, we add the configuration page callback:

<?php
/**
 * @file
 * mymodule.pages.inc
 * Part of the mymodule package.
 */
function mymodule_set_default_header_image_form(){

  // Add a managed file form element for uploading an image
  $form['mymodule_default_header'] = array(
    '#type' => 'managed_file',
    '#title' => t('Default Header Image'),
    '#description' => t('Set the site-wide default header image'),
    '#upload_location' => 'public://files',
    '#default_value' => variable_get('mymodule_default_header', ''),
  );

  // Add custom submit handler to set the file status to permanent
  $form['#submit'][] = 'mymodule_set_default_header_image_form_submit';

  return system_settings_form($form);
}

The managed_file form element is quite handy. It adds an image uploader to your form with minimal effort. Using system_settings_form, we save the file fid for future use. The part that I missed initially is outlined in the managed_file documentation - that you need to set the file status to permanent in your module. Otherwise, it get’s removed on cron. 

To do this, we add an additional submit handler:

/*
 * Additional submit handler for making the file permanent
 */
function mymodule_set_default_header_image_form_submit($form, &$form_state){
  $form['mymodule_default_header']['#file']->status = FILE_STATUS_PERMANENT;
  file_save($form['mymodule_default_header']['#file']);
}

We can then use the image elsewhere on the site:

<?php

// Load image fid
$image_fid = variable_get('mymodule_default_header');

// Load image
$image = file_load($image_fid);

// Get URL
$url = file_create_url($image['uri']);

The result: