Drupal, Flickr and a photo gallery part 3 altering the node edit form

In parts one and two I described the problem and how to set up the flickr module and a content type which make the member's gallery page.

The resulting node edit form is far too complex for most users, it is asking for information it doesn't need (the body, comments etc.) and for flickr information which is awkward to obtain (the set id) and to cap all of that the set id has to be entered twice.

The way to fix this is to alter the node edit form to:

  • Remove all but the title field
  • Add in a select box containing a list of the user's sets

We need to implement hook_form_alter.

function quickgallery_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'member_gallery_node_form') {
    global $user;
    $userid = $user->uid;
    if ($form['nid']['#value']) { // Editing a gallery, use the creator's flickr id.
      $userid = $form['uid']['#value'];
    }
    $user_info = user_load($userid);

This finds the node edit form for the member_gallery content type. Next it gets information about the logged in user, or, if editing a gallery the user who created the gallery (which allows an admin to edit galleries created by someone else).

The next stage needs a helper function to get the user's flickr sets.

function quickgallery_get_nsid_sets($uid, &$nsid, &$sets) {
  $user_info = user_load($uid);
  $nsid = $user_info->flickr['nsid'];
  if (!$nsid) {
    // Try to find it using the user's e-mail address.
    $nsid = flickr_user_find_by_identifier($user_info->mail);
    if ($nsid) {
      // Found it! Set it in the user profile.
      $edit['flickr_identifier'] = $user_info->mail;
      flickr_user('update', $edit, $user_info);
    }
  }
  $sets = NULL;
  if ($nsid) {
    $sets = flickr_photoset_get_list($nsid);
  }
}

This function does two things, first it determines the user's flickr id. It does that by looking at the field the flickr module add to the user's profile. If that isn't set it tries to find the user using the e-mail address from the user's profile, and, if that works writes it into the flick id field. If all goes well the user's sets are retrieved from flickr. If not NULL is returned.

This code defaults the title to the user's name and removed all of the rest of the form fields apart from the submit buttons. It does this by denying access, that way the default values survive and are used when the node is saved.

    $form['title']['#default_value'] = 
         check_plain($user_info->profile_firstname) . '
       . check_plain($user_info->profile_surname);
    $form['body_field']['#access'] = FALSE;
    $form['menu']['#access'] = FALSE;
    $form['revision_information']['#access'] = FALSE;
    $form['author']['#access'] = FALSE;
    $form['options']['#access'] = FALSE;
    $form['path']['#access'] = FALSE;
    $form['comment_settings']['#access'] = FALSE;
    $form['field_flickr_photos']['#access'] = FALSE;
    $form['field_flickr_photoset']['#access'] = FALSE;

Here's the rest of the hook, it adds the gallery fields.

    if ($nsid) {
      $form['nsid'] = array(
          '#type' => 'value',
          '#value' => $nsid
      );
      $sets = flickr_photoset_get_list($nsid);
      if ($sets) {
        $opts = array();
        foreach ($sets as $set) {
          $opts[$set['id']] = $set['title']['_content'];
        }
        $form['sets'] = array(
            '#type' => 'select',
            '#title' => 'Photoset',
            '#options' => $opts,
            '#default_value' => $form['field_flickr_photos'][0]['#default_value']['id'],
            '#description' => t('Select the Flickr photoset you wish to use as your gallery.')
        );
      }
      else {
        $form['nosets'] = array(
            '#type' => 'markup',
            '#prefix' => '<div>',
            '#value' =>
'You haven\'t created any sets on Flickr so you cannot create a gallery.'
. ' <a href="/gallery/add">Instructions are here</a>.',
            '#suffix' => '</div>' );
        $form['buttons']['submit']['#access'] = FALSE;
        $form['buttons']['preview']['#access'] = FALSE;
      }
      $form['#validate'][] = 'quickgallery_edit_form_validate';
    }
    else {
      $form['nosets'] = array(
            '#type' => 'markup',
            '#prefix' => '<div>',
            '#value' =>
'You haven\'t added your Flickr id to your profile so you cannot create a gallery.'
. ' <a href="/gallery/add">Instructions are here</a>.',
            '#suffix' => '</div>' );
        );
        $form['buttons']['submit']['#access'] = FALSE;
        $form['buttons']['preview']['#access'] = FALSE;
    }
  }

This adds a select list of the available photosets. If the user has no photosets instructions are given to create one, and if the user can't be found he is directed to another page which gives instructions on how to set up flickr.

The next stage is to make sure that the Drupal form handler for node edit gets the correct data. So far the title has been filled in and there is the photoset field which it knows nothing about. This is fixed by adding a validate function which moves the photoset and flickr user data into the hidden form elements which the Drupal form processing hook does understand.

/**
 * Move the collected member gallery data into the correct places so the node is
 * properly created or edited.
 */
function quickgallery_edit_form_validate($form, &$form_state) {
   // Check for multiple identical galleries.
  quickgallery_add_form_validate($form, $form_state);
  $form_state['values']['field_flickr_photos'][0]['id'] = $form_state['values']['sets'];
  $form_state['values']['field_flickr_photos'][0]['nsid'] = $form_state['values']['nsid'];
  $form_state['values']['field_flickr_photos'][0]['type'] = 'set_id';
  $form_state['values']['field_flickr_photoset'][0]['flickrid']
      = $form_state['values']['sets'];
}

That's it, the form will now work for adding and editing existing gallery nodes.

Site Section: