You are here

function flickr_album in Flickr 7

Render multiple photos as an album.

6 calls to flickr_album()
flickr_block_view in block/flickr_block.module
Implements hook_block_view().
flickr_filter_callback_album in filter/flickr_filter.module
Filter callback for a user or set.
flickr_filter_callback_favorites in filter/flickr_filter.module
Filter callback for a user's favorites.
flickr_filter_callback_gallery in filter/flickr_filter.module
Filter callback for a gallery.
flickr_filter_callback_group in filter/flickr_filter.module
Filter callback for a group.

... See full list

File

./flickr.inc, line 584
The Flickr API functions.

Code

function flickr_album($type = 'user', $id = '39873962@N08', $show_n = NULL, $size = NULL, $media = 'photos', $tags = '', $tags_user = '', $delta = 'true', $sort = 'unsorted', $heading = 'p', $min_title = NULL, $min_metadata = NULL, $vocab_isset = 0, $filter = NULL, $lat = NULL, $lon = NULL, $radius = NULL, $datefrom = NULL, $dateto = NULL, $extend = 1, $tag_mode = 'context', $class = NULL, $style = NULL, $page = 1) {

  // If no API key is set, break.
  if (!variable_get('flickr_api_key', NULL)) {
    return FALSE;
  }

  // Also Flickr converts tags to lowercase, removes spaces and the ampersand.
  $tags = strtolower(str_replace(array(
    ' ',
    '&',
  ), '', $tags));

  // drupal_is_front_page() is added because it also can have arg(0) == 'node'.
  $cache = cache_get('flickr_block_' . $delta . '_' . $id . '_' . $tags . '_' . $lat . '_' . $datefrom . '_' . $dateto . '_' . arg(0) . '_' . drupal_is_front_page() . '_' . $page);

  // If $delta is a number it is a block that could be cached.
  if ($cache && is_numeric($delta)) {
    $output = $cache->data;
  }
  else {

    // As variables might change during processing, we set a fixed version of it
    // to use for the key to set the block cache after processing at the end.
    $idfix = $id;
    $datefromfix = $datefrom;
    $datetofix = $dateto;
    $tagsfix = $tags;
    $latfix = $lat;
    $pagefix = $page;

    // Turn GPS coordinates from degrees / minutes / seconds to decimal format.
    if (isset($lat)) {
      $dmslat = preg_match_all('/[\\-(\\.|,)0-9]+/', $lat, $matches);
      $deg = isset($matches[0][0]) ? $matches[0][0] : $lat;
      $min = isset($matches[0][1]) ? $matches[0][1] : 0;
      $sec = isset($matches[0][2]) ? $matches[0][2] : 0;
      $lat = $deg + ($min * 60 + $sec) / 3600;
      $dmslon = preg_match_all('/[\\-(\\.|,)0-9]+/', $lon, $matches);
      $deg = isset($matches[0][0]) ? $matches[0][0] : $lon;
      $min = isset($matches[0][1]) ? $matches[0][1] : 0;
      $sec = isset($matches[0][2]) ? $matches[0][2] : 0;
      $lon = $deg + ($min * 60 + $sec) / 3600;
    }
    if (!isset($dateto)) {
      $dateto = $datefrom;
    }
    $datestart = strtotime($datefrom);
    $dateend = strtotime($dateto);

    // Try again but turning DD/MM/YYYY to DD-MM-YYYY.
    // See http://www.hashbangcode.com/node/702 (first part only).
    if (!empty($datefrom) && ($datestart === FALSE || $dateend === FALSE || $datestart > $dateend)) {
      $datestart = strtotime(str_replace('/', '-', $datefrom));
      $dateend = strtotime(str_replace('/', '-', $dateto));
      $ambiguous = l(t('ambiguous'), 'http://php.net/manual/en/function.strtotime.php#100144', array(
        'attributes' => array(
          'title' => t('PHP: strtotime - Manual'),
          'target' => '_blank',
        ),
      ));
      $dateformat = l(t('accepted date format'), 'http://php.net/manual/en/datetime.formats.date.php/', array(
        'attributes' => array(
          'title' => t('PHP: Date Formats - Manual'),
          'target' => '_blank',
        ),
      ));
      drupal_set_message(t("You used the date format DD/MM/YYYY (starting with the day). As some dates are !ambiguous (e.g. is 04/05/2013 5 April or 4 May?) it is recommended to use dashes when you start with the day (DD-MM-YYYY), slashes when you start with the month (MM/DD/YYYY) or use any other !dateformat (e.g. 11 Jan 2015).", array(
        '!ambiguous' => $ambiguous,
        '!dateformat' => $dateformat,
      )), 'warning', FALSE);
    }
    if (!empty($datefrom) && ($datestart === FALSE || $dateend === FALSE)) {
      drupal_set_message(t("Invalid date provided."), 'error', FALSE);
    }
    $datefrom = empty($datefrom) ? '' : date("Y-m-d", $datestart);
    $dateto = empty($dateto) ? '' : date("Y-m-d", $dateend);
    $datefrom = isset($datefrom) ? $datefrom . ' 00:00:00' : '';
    $dateto = isset($dateto) ? $dateto . ' 23:59:59' : '';

    // Remove tags to exclude (preceded by a minus symbol) for album titles.
    $tagsfixnoexclude = preg_replace('/,(^|\\s)*-(\\w+)/', '', $tags);

    // Set the default tag mode appropriate.
    if ($tag_mode == 'context') {
      $tag_mode = empty($id) || $id == 'public' || $id == '39873962@N08' ? 'all' : 'any';
    }
    if ($extend && $tag_mode == 'all' && strpos($tags, ',') !== FALSE) {
      $tag_mode = 'any';
      drupal_set_message(t("The tag mode has been forced to 'any' (OR) for extended text matching (tags, titles and description). To use 'all' (AND) put 'extend=false' in Flickr's text filter code."), 'warning', FALSE);
    }
    $sizes = flickr_photo_sizes();
    $show_n = is_null($show_n) ? variable_get('flickr_photos_per_page', 6) : $show_n;
    $size = is_null($size) ? variable_get('flickr_default_size_album', 's') : $size;
    $min_title = is_null($min_title) ? variable_get('flickr_title_suppress_on_small', '100') : $min_title;
    $min_metadata = is_null($min_metadata) ? variable_get('flickr_metadata_suppress_on_small', '150') : $min_metadata;
    if ($show_n > 1 || is_numeric($delta)) {
      $output = '<div class="flickr-photoset">';
    }
    else {
      $output = '<span class="flickr-photoset-single">';
    }

    // The text to prepend to an album title.
    switch ($sort) {
      case 'added':
        $order = t('Latest added');
        break;
      case 'date-taken-desc':
        $order = t('Latest taken');
        break;
      case 'date-posted-desc':
        $order = t('Latest uploaded');
        break;
      case 'views':
        $order = t('Most viewed');
        break;
      case 'random':
        $order = t('Random');
        break;
      case 'unsorted':
        $order = '';
        break;

      // In case 'id'.
      default:
        $order = t('Latest');
        break;
    }
    if ($type == 'user' || $type == 'group') {
      switch ($filter) {
        case 'interestingness-desc':
          if (empty($order)) {
            $order = t('Most interesting') . ' ';
          }
          else {
            $order .= t(', most interesting') . ' ';
          }
          break;
        case 'relevance':
          if (empty($order)) {
            $order = t('Most relevant') . ' ';
          }
          else {
            $order .= t(', most relevant') . ' ';
          }
          break;
        default:
          $order .= ' ';
          break;
      }
    }
    else {
      $order .= ' ';
    }

    // Merge the user profile terms with the terms from the node.
    $tags_user_string = is_array($tags_user) ? implode(",", $tags_user) : $tags_user;
    $tags_combined = trim($tags . ',' . $tags_user_string, ',');

    // Get information about the album, including the owner if needed later on.
    switch ($type) {
      case "photoset":
        $info = flickr_photosets_getinfo($id);
        $people = flickr_get_user_info($info['owner']);
        if (!$info) {
          return;
        }
        $total = $media == 'videos' ? $info['count_videos'] : $info['count_photos'] + $info['count_videos'];
        break;
      case "group":
        $info = flickr_groups_getinfo($id);
        if (!$info) {
          return;
        }
        $id = $info['group']['id'];
        $total = $info['group']['pool_count']['_content'];
        break;
      case "gallery":
        $info = is_numeric($delta) ? flickr_galleries_getinfo($id) : flickr_galleries_getinfo('6065-' . $id);
        if ($info['stat'] == 'ok') {
          $gallery_id = $info['gallery']['id'];
          $people = flickr_get_user_info($info['gallery']['owner']);
        }
        else {
          return;
        }
        $total = $media == 'videos' ? $info['gallery']['count_videos'] : $info['gallery']['count_photos'] + $info['gallery']['count_videos'];
        break;
      default:
        $id = empty($id) || $id == 'public' ? '39873962@N08' : $id;
        $people = flickr_get_user_info($id);
        if (!$people) {
          return;
        }
        $total = $people['count'];
        break;
    }

    // Set some variables for all album types.
    if ($show_n > 1) {
      $media_type = $media == 'videos' ? t('videos') : t('photos');
    }
    else {
      $media_type = $media == 'videos' ? t('video') : t('photo');
    }
    $people['photosurl'] = isset($people['photosurl']) ? $people['photosurl'] : 'https://www.flickr.com/groups/' . $idfix . '/';
    $people['photosurl'] = $id == '39873962@N08' ? 'https://www.flickr.com/search/?sort=relevance&text=' : $people['photosurl'];
    $photos = $order . l(t('Flickr'), $people['photosurl'], array(
      'attributes' => array(
        'title' => t("View the @type's Flickr photostream.", array(
          '@type' => $type,
        )),
        'target' => '_blank',
      ),
    )) . ' ' . $media_type;

    // The used tags with a space forced after the comma and the last
    // one replaced by 'or' or 'and'.
    $conjunction = $tag_mode == 'all' ? t('and') : t('or');
    $tags1 = preg_replace('/(.*),/', '$1 ' . $conjunction, str_replace(',', ', ', $tagsfixnoexclude));
    $flickr = flickr_album_link_construct(' ' . t('tagged') . ' <span class="flickr-tags">' . $tags1 . '</span></span>', $type, $id, $show_n, $media, $tags, $filter, $lat, $lon, $radius, $datefrom, $dateto, $extend, $tag_mode);
    $tagged = empty($tags) || $size == 'x' || $size == 'y' ? '' : '<span class="flickr-tags-wrap">' . $flickr;

    // A single date.
    $format = empty($datefrom) ? 'none' : variable_get('flickr_date_format_album_title', 'short');
    switch ($format) {
      case 'interval':
        $formated_datefrom = format_interval(time() - strtotime(substr($datefrom, 0, 10)), 1);
        $formated_dateto = format_interval(time() - strtotime(substr($dateto, 0, 10)), 1);
        break;
      default:
        $formated_datefrom = format_date(strtotime(substr($datefrom, 0, 10)), $format, '', NULL);
        $formated_dateto = format_date(strtotime(substr($dateto, 0, 10)), $format, '', NULL);
    }
    if ((empty($datetofix) || $datetofix == $datefromfix || $formated_datefrom == $formated_dateto) && !empty($datefromfix)) {

      // Remove the time by capturing anything preceding one or more digits
      // followed by a colon. See http://rubular.com/r/7IJhj19P9K
      $match1 = preg_match('/^(.*?)[-|\\s].\\d*:/', $formated_datefrom, $match);

      // Only use the match if there is one (date with time).
      $date1 = isset($match[1]) ? $match[1] : $formated_datefrom;
      $taken = $format == 'interval' ? ' ' . t('taken') . ' ' . $formated_datefrom . ' ' . t('ago') : ' ' . t('taken on') . ' ' . $date1;
    }
    elseif (!empty($datefromfix)) {

      // Remove the times.
      $match1 = preg_match('/^(.*?)[-|\\s].\\d*:/', $formated_datefrom, $matchfrom);
      if (isset($matchfrom[1])) {
        preg_match('/^(.*?)[-|\\s].\\d*:/', $formated_dateto, $matchto);
        $date1 = $matchfrom[1];
        $date2 = $matchto[1];
      }
      else {
        $date1 = $formated_datefrom;
        $date2 = $formated_dateto;
      }
      switch ($format) {
        case 'interval':
          $taken = ' ' . t('taken') . ' ' . $formated_datefrom . ' ' . t('to') . ' ' . $formated_dateto . ' ' . t('ago');
          break;
        default:
          $taken = ' ' . t('taken from') . ' ' . $date1 . ' ' . t('to') . ' ' . $date2;
      }
    }
    else {
      $taken = '';
      $datefrom = '';
      $dateto = '';
    }
    $taken = $format == 'none' ? '' : $taken;

    // Generate an album heading depending on type.
    switch ($type) {
      case "photoset":
        $set = l($info['title']['_content'], $people['photosurl'] . 'sets/' . $id, array(
          'attributes' => array(
            'title' => t('View set on Flickr.'),
            'target' => '_blank',
          ),
        ));
        $map = variable_get('flickr_maps', 0) ? '(' . l(t('map'), $people['photosurl'] . 'sets/' . $id . '/map/', array(
          'attributes' => array(
            'title' => t('View set on Flickr map.'),
            'target' => '_blank',
          ),
        )) . ')' : '';
        $flickr = l(t('on Flickr'), $people['photosurl'] . 'sets/' . $id, array(
          'attributes' => array(
            'title' => t("@set by @name.", array(
              '@set' => strip_tags($set),
              '@name' => strip_tags($people['name']),
            )),
            'target' => '_blank',
          ),
        ));
        $output .= $heading == 'none' || $show_n == 1 && !is_numeric($delta) ? '' : '<' . $heading . ' class="flickr-album-heading">' . t("!photos !tagsfrom the album !set by !username !map", array(
          '!photos' => $photos,
          '!tags' => $tagged . ' ',
          '!set' => $set,
          '!username' => $people['name'],
          '!map' => $map,
        )) . '</' . $heading . '>';
        if ($heading == 'h1') {
          $title_bar = t("@photos @tagsfrom the album @set by @username", array(
            '@photos' => strip_tags($photos),
            '@tags' => strip_tags($tagged) . ' ',
            '@set' => strip_tags($set),
            '@username' => strip_tags($people['name']),
          ));
          drupal_set_title($title_bar);
        }
        break;
      case "gallery":
        $set = l($info['gallery']['title']['_content'], $people['photosurl'] . 'galleries/' . preg_replace('/^[^,]*-\\s*/', '', $id), array(
          'attributes' => array(
            'title' => t('View gallery on Flickr.'),
            'target' => '_blank',
          ),
        ));
        $flickr = l(t('on Flickr'), $people['photosurl'] . 'galleries/' . preg_replace('/^[^,]*-\\s*/', '', $id), array(
          'attributes' => array(
            'title' => t("@set curated by @name.", array(
              '@set' => strip_tags($set),
              '@name' => strip_tags($people['name']),
            )),
            'target' => '_blank',
          ),
        ));
        $tagged = is_numeric($delta) ? '' : $tagged;
        $output .= $heading == 'none' || $show_n == 1 && !is_numeric($delta) ? '' : '<' . $heading . ' class="flickr-album-heading">' . t("!photos !tagsfrom the gallery !set curated by !username", array(
          '!photos' => strip_tags($photos),
          '!tags' => strip_tags($tagged . ' '),
          '!set' => $set,
          '!username' => $people['name'],
        )) . '</' . $heading . '>';
        break;
      case "favorites":
        $flickr = l(t('on Flickr'), $people['photosurl'] . 'favorites/', array(
          'attributes' => array(
            'title' => t("View favorites of @name made by others.", array(
              '@name' => strip_tags($people['name']),
            )),
            'target' => '_blank',
          ),
        ));
        $favorites = l(t('favorites'), $people['photosurl'] . 'favorites/', array(
          'attributes' => array(
            'title' => t("View favorites of @name made by others.", array(
              '@name' => strip_tags($people['name']),
            )),
            'target' => '_blank',
          ),
        ));
        $tags1 = !empty($tags) ? '<span class="flickr-tags-wrap">' . t('tagged') . ' <span class="flickr-tags">' . $tags1 . '</span> </span>' : '';
        $output .= $heading == 'none' || $show_n == 1 && !is_numeric($delta) ? '' : '<' . $heading . ' class="flickr-album-heading">' . t("!photos !tags from the !favorites of !username", array(
          '!photos' => strip_tags($photos),
          '!tags' => $tags1,
          '!favorites' => $favorites,
          '!username' => $people['name'],
        )) . '</' . $heading . '>';
        break;

      // User and group albums.
      default:
        if (!empty($tags) && strpos($tags, ',') == FALSE) {
          $map = variable_get('flickr_maps', 0) ? '(' . l(t('map'), $people['photosurl'] . 'tags/' . $tags . '/map/', array(
            'attributes' => array(
              'title' => t('View tagged photos on Flickr map.'),
              'target' => '_blank',
            ),
          )) . ')' : '';
        }
        else {
          $map = variable_get('flickr_maps', 0) ? '(' . l(t('map'), $people['photosurl'] . 'map/', array(
            'attributes' => array(
              'title' => t('View user photos on Flickr map.'),
              'target' => '_blank',
            ),
          )) . ')' : '';
        }
        if ($type == 'user') {
          $username = $id == '39873962@N08' || empty($id) ? '' : ' ' . t('by') . ' ' . $people['name'];
        }
        else {
          $username = ' ' . t('from the group') . ' ' . strip_tags($info['group']['name']['_content']);
        }
        $flickr = flickr_album_link_construct(t('on Flickr'), $type, $id, $show_n, $media, $tags, $filter, $lat, $lon, $radius, $datefrom, $dateto, $extend, $tag_mode);
        $map = $id == '39873962@N08' || empty($id) ? '' : $map;
        if (isset($lat)) {
          $place_id = flickr_places_findbylatlon($lat, $lon);
          $place_name = $place_id['places']['place'][0]['name'];
          $geophp = variable_get('flickr_geophp', array(
            'title' => 'title',
            'caption' => 0,
          ));
          if (gettype($geophp['title']) != 'integer') {
            $google = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' . $lat . ',' . $lon;
            if ((variable_get('flickr_curl2', 0) || !function_exists('stream_socket_client')) && function_exists('curl_version')) {
              $result = flickr_curl_http_request($google);
            }
            elseif (function_exists('stream_socket_client')) {
              $result = drupal_http_request($google);
            }
            $json = json_decode($result->data);
            if ($json->status == 'ZERO_RESULTS') {
              $location_name = $place_name;
            }
            else {
              $location_name = $json->results[0]->formatted_address;

              // Remove the postal code from the string.
              // Usually the last component of the returned address by Google.
              $location_components = $json->results[0]->address_components;
              $location_pc = end($location_components);
              if (strpos($location_pc->types[0], 'postal_code') !== FALSE) {
                $location_name = str_replace($location_pc->long_name, '', $location_name);
              }
              else {
                $location_name = $place_name;
              }
            }
          }
          else {
            $location_name = $place_name;
          }
          if ($id == '39873962@N08' || empty($id)) {
            $place_name = !is_array($place_name) ? l($location_name, 'https://www.flickr.com/map?&location=' . $place_name, array(
              'attributes' => array(
                'title' => t('View photos on Flickr map.'),
                'target' => '_blank',
                'class' => array(
                  'flickr-location',
                ),
              ),
            )) : $place_name;
          }
          else {
            if ($type == 'user') {
              $place_name = !is_array($place_name) ? l($location_name, 'https://www.flickr.com/photos/' . $id . '/map?&location=' . $place_name, array(
                'attributes' => array(
                  'title' => t('View photos on Flickr map.'),
                  'target' => '_blank',
                  'class' => array(
                    'flickr-location',
                  ),
                ),
              )) : $place_name;
            }
            else {
              $place_name = !is_array($place_name) ? l($location_name, 'https://www.flickr.com/groups/' . $id . '/map?&location=' . $place_name, array(
                'attributes' => array(
                  'title' => t('View photos on Flickr map.'),
                  'target' => '_blank',
                  'class' => array(
                    'flickr-location',
                  ),
                ),
              )) : $place_name;
            }
          }
          if (is_array($place_name)) {
            drupal_set_message(t("Temporarily the album location could not be retrieved from Flickr and is therefore omitted in the album title."), 'warning', FALSE);
          }
        }
        $place = isset($lat) && !is_array($place_name) ? t('near') . ' ' . $place_name . ' ' : '';
        $pre_output = $id == '39873962@N08' || empty($id) ? strip_tags($photos) . ' ' . $tagged . ' ' . $place . $username . ' ' . $map . $taken : $photos . ' ' . $tagged . ' ' . $place . $username . ' ' . $map . $taken;
        $block_config = l(t('exclude the block'), 'admin/structure/block/manage/flickr/' . $delta . '/configure/', array(
          'attributes' => array(
            'title' => t('Block visibility settings'),
          ),
        ));
        $config = l(t('set empty blocks to remain hidden'), 'admin/config/media/flickr/', array(
          'attributes' => array(
            'title' => t('Go to Flickr configuration page'),
          ),
        ));
        if (($id == '39873962@N08' || empty($id)) && empty($tags) && !isset($lat)) {
          $pre_output .= '<div class="messages warning">' . t('Provide some tags or a location for public photos for the node on this page<br />- OR -<br />!block_config on this page<br />- OR -<br />!config.', array(
            '!block_config' => $block_config,
            '!config' => $config,
          )) . '</div>';
          $show_n = 0;
        }
        $output .= $heading == 'none' || $show_n == 1 && !is_numeric($delta) ? '' : '<' . $heading . ' class="flickr-album-heading">' . $pre_output . '</' . $heading . '>';
        break;
    }

    // Generate the album itself, depending on size and type.
    switch ($size) {
      case "x":
        switch ($type) {
          case "favorites":
          case "gallery":
            $output .= '<div class="messages error">' . t("You cannot choose a slideshow for '@type'. Select another size.", array(
              '@type' => $type,
            )) . '</div>';
            drupal_set_message(t("You cannot choose a slideshow for '@type'. Select another size.", array(
              '@type' => $type,
            )), 'error', FALSE);
            break;
          default:

            // Info about set and owner is displayed in slideshow itself. If you
            // don't want a header, don't use concatenation (.=) but equals (=).
            $output .= theme('flickr_flickrcomslideshow', array(
              'id' => $id,
              'class' => $class,
              'style' => $style,
            ));
            drupal_set_message(t("Note that slideshows show in reverse chronological order (newest first) and ignore number, filter, tags, location and media settings."), 'warning', FALSE);
            break;
        }
        break;
      case "y":
        switch ($type) {
          case "favorites":
          case "gallery":
            $output .= '<div class="messages error">' . t("You cannot choose a slideshow for '@type'. Select another size.", array(
              '@type' => $type,
            )) . '</div>';
            drupal_set_message(t("You cannot choose a slideshow for '@type'. Select another size.", array(
              '@type' => $type,
            )), 'error', FALSE);
            break;
          case "group":
            $output .= '<div class="messages error">' . t('Choose the slideshow for group pool albums (size = x).') . '</div>';
            drupal_set_message(t('Choose the slideshow for group pool albums (size = x).'), 'error', FALSE);
            break;
          default:
            $output .= theme('flickr_flickrcomslideshow_simple', array(
              'id' => $id,
              'class' => $class,
              'style' => $style,
            ));
            drupal_set_message(t("Note that slideshows show in reverse chronological order (newest first) and ignore number, filter, tags, location and media settings."), 'warning', FALSE);
            break;
        }
        break;
      default:
        $output .= '<div class="flickr-album ' . $class . '" style="' . $style . '">';

        // Make API request quicker by limiting the number of photos to return.
        // For recent sorted photos this is 4 x the displayed number to provide
        // a sufficient distinction between recently uploaded and recently
        // taken.
        $per_page = $sort == 'random' || $sort == 'views' ? variable_get('flickr_per_page', 100) : 4 * $show_n;

        // ...but if unsorted or user/date, limit it more (except size 'n')...
        $per_page = ($sort == 'unsorted' || $type == 'user' && ($sort == 'date-taken-desc' || $sort == 'date-posted-desc') && empty($filter)) && $size != 'n' ? $show_n : $per_page;

        // When we have a photoset, gallery or favorites, use the maximum...
        $per_page = ($type == 'favorites' || $type == 'photoset' || $type == 'gallery') && (!empty($tags) || ($sort == 'date-taken-desc' || $sort == 'date-posted-desc')) ? $total : $per_page;

        // ...but when filtering on muiltiple tags in groups, use the maximum.
        $per_page = strpos($tags, ',') !== FALSE && $type == 'group' || $id == '39873962@N08' && $sort == 'date-taken-desc' && empty($filter) ? $total : $per_page;

        // Fallback: Avoid that $page can be empty or 0.
        $per_page = isset($page) && $per_page > 0 ? $per_page : variable_get('flickr_per_page', 100);

        // If we could have a response of over [variable_get('flickr_per_page',
        // 100)] photos, we want a random sort to take a random page first, so
        // any photos could be taken (not only from the most recent batch).
        // The amount in the last page has to be sufficient to draw a random.
        $rest_ok = $total % variable_get('flickr_per_page', 100) > 3 * $show_n ? 1 : 0;
        $page = $sort == 'random' && isset($total) && $total > variable_get('flickr_per_page', 100) && empty($tags) ? mt_rand(1, floor($total / variable_get('flickr_per_page', 100)) + $rest_ok) : $page;

        // Debug info.
        if (variable_get('flickr_debug', 0) == 2 && function_exists('dpm')) {
          dpm("Arguments passed to 'function flickr_album()': " . '$type=' . $type . ' $delta=' . $delta . ' $id=' . $id . ' $sort=' . $sort . ' $filter=' . $filter . ' $page=' . $page . ' $per_page=' . $per_page . ' $tags=' . $tags . ' $vocab_isset=' . $vocab_isset . ' $total=' . $total . ' $lat=' . $lat . ' $lon=' . $lon . ' $radius=' . $radius . '$datefrom=' . $datefrom . ' $dateto=' . $dateto . ' $extend=' . $extend . ' $tag_mode=' . $tag_mode . ' $class=' . $class . ' $style=' . $style . ' $page=' . $page);
        }

        // Get a list of "all" the photos. This is cached.
        switch ($type) {
          case "photoset":
            $response = flickr_photosets_getphotos($id, array(
              'per_page' => $per_page,
              'extras' => 'date_upload,date_taken,license,geo,tags,views,media',
              'media' => $media,
            ), $page);
            if (!$response) {
              return;
            }
            $photos = $response['photoset']['photo'];
            break;
          case "gallery":
            $response = flickr_galleries_getphotos($gallery_id, $page, array(
              'per_page' => $per_page,
              'extras' => 'date_upload,date_taken,license,geo,tags,views,media',
              'media' => $media,
            ), $page);
            if (!$response) {
              return;
            }
            $photos = $response['photos']['photo'];
            break;
          case "favorites":
            $response = flickr_favorites_getpubliclist($id, 1, array(
              'per_page' => $per_page,
              'extras' => 'date_upload,date_taken,license,geo,tags,views,media',
            ));
            if (!$response) {
              return;
            }
            $photos = $response['photo'];
            break;

          // User and group albums.
          default:
            $valid_sort = $sort == 'date-taken-desc' || $sort == 'date-posted-desc' ? $sort : '';

            // Filter gets priority. Date sorting will be done anyway later.
            $valid_sort = $filter == 'interestingness-desc' || $filter == 'relevance' ? $filter : $valid_sort;
            $textext = array();
            if ($type == 'group') {
              $group_id = $id;
              $id = '';
              $tags_combined = $tags;
              $texts[0] = $tagsfix;
              $license = '';
            }

            // On public photos we want to match all tags (AND).
            if ($type == 'user') {
              $group_id = '';
              if ($id == 'public' || $id == '39873962@N08' || empty($id)) {
                $texts[0] = $tagsfix;
                $id = '39873962@N08';
                $license = '1,2,3,4,5,6,7';
              }
              else {
                $texts = is_array($tagsfix) ? $tagsfix : explode(",", $tagsfix);
                $license = '';
              }
            }

            // With OR operator we remove exclusion strings.
            if ($tag_mode == 'any') {

              // Produce an array of all exlusion tags to use later on.
              preg_match_all('/(,-\\w+)/', $tags_combined, $excludestrings);

              // Remove sub key.
              $excludestrings = $excludestrings[0];

              // We need the tags themselves, without comma and minus sign.
              $excludestrings = str_replace(',-', '', $excludestrings);
              $tags_combined = preg_replace('/(,-\\w+)/', '', $tags_combined);
            }
            if (isset($lat)) {

              // Start with a circle of 14 meter.
              $radius = empty($radius) ? 0.014 : $radius;
              do {
                if (variable_get('flickr_restrict', 1) < 2) {
                  $response = flickr_photos_search($id, $page, array(
                    'group_id' => $group_id,
                    'tags' => $tags_combined,
                    'tag_mode' => $tag_mode,
                    'min_taken_date' => $datefrom,
                    'max_taken_date' => $dateto,
                    'sort' => $valid_sort,
                    'per_page' => $per_page,
                    'extras' => 'date_upload,date_taken,license,geo,tags,views,media',
                    'media' => $media,
                    'lat' => $lat,
                    'lon' => $lon,
                    'radius' => $radius,
                    'license' => $license,
                  ));
                  foreach ($texts as $tagsfiks) {
                    $textextension = flickr_photos_search($id, $page, array(
                      'group_id' => $group_id,
                      'text' => '"' . $tagsfiks . '"',
                      'tag_mode' => $tag_mode,
                      'min_taken_date' => $datefrom,
                      'max_taken_date' => $dateto,
                      'sort' => $valid_sort,
                      'per_page' => $per_page,
                      'extras' => 'date_upload,date_taken,license,geo,tags,views,media',
                      'media' => $media,
                      'lat' => $lat,
                      'lon' => $lon,
                      'radius' => $radius,
                      'license' => $license,
                    ));
                    $textext = array_merge($textext, $textextension['photo']);
                  }
                }

                // No results, to extend the search on license.
                if ((empty($response['photo']) || variable_get('flickr_restrict', 1) == 2) && variable_get('flickr_restrict', 1) != 0) {
                  $response = flickr_photos_search($id, $page, array(
                    'group_id' => $group_id,
                    'tags' => $tags_combined,
                    'tag_mode' => $tag_mode,
                    'min_taken_date' => $datefrom,
                    'max_taken_date' => $dateto,
                    'sort' => $valid_sort,
                    'per_page' => $per_page,
                    'extras' => 'date_upload,date_taken,license,geo,tags,views,media',
                    'media' => $media,
                    'lat' => $lat,
                    'lon' => $lon,
                    'radius' => $radius,
                    'license' => '',
                  ));
                  foreach ($texts as $tagsfiks) {
                    $textextension = flickr_photos_search($id, $page, array(
                      'group_id' => $group_id,
                      'text' => '"' . $tagsfiks . '"',
                      'tag_mode' => $tag_mode,
                      'min_taken_date' => $datefrom,
                      'max_taken_date' => $dateto,
                      'sort' => $valid_sort,
                      'per_page' => $per_page,
                      'extras' => 'date_upload,date_taken,license,geo,tags,views,media',
                      'media' => $media,
                      'lat' => $lat,
                      'lon' => $lon,
                      'radius' => $radius,
                      'license' => '',
                    ));
                    $textext = array_merge($textext, $textextension['photo']);
                  }
                }

                // Extend the search geo radius gradually to 32 km if there are
                // not enough results.
                $radius = $radius * 3;
              } while (count($response['photo']) + count($textext) < $show_n && $radius <= 32);
            }
            else {
              if (variable_get('flickr_restrict', 1) < 2) {
                $response = flickr_photos_search($id, $page, array(
                  'group_id' => $group_id,
                  'tags' => $tags_combined,
                  'tag_mode' => $tag_mode,
                  'min_taken_date' => $datefrom,
                  'max_taken_date' => $dateto,
                  'sort' => $valid_sort,
                  'per_page' => $per_page,
                  'extras' => 'date_upload,date_taken,license,geo,tags,views,media',
                  'media' => $media,
                  'license' => $license,
                ));
                foreach ($texts as $tagsfiks) {
                  $textextension = flickr_photos_search($id, $page, array(
                    'group_id' => $group_id,
                    'text' => '"' . $tagsfiks . '"',
                    'tag_mode' => $tag_mode,
                    'min_taken_date' => $datefrom,
                    'max_taken_date' => $dateto,
                    'sort' => $valid_sort,
                    'per_page' => $per_page,
                    'extras' => 'date_upload,date_taken,license,geo,tags,views,media',
                    'media' => $media,
                    'license' => $license,
                  ));
                  $textext = array_merge($textext, $textextension['photo']);
                }
              }
              if ((empty($response['photo']) || variable_get('flickr_restrict', 1) == 2) && variable_get('flickr_restrict', 1) != 0) {
                $response = flickr_photos_search($id, $page, array(
                  'group_id' => $group_id,
                  'tags' => $tags_combined,
                  'tag_mode' => $tag_mode,
                  'min_taken_date' => $datefrom,
                  'max_taken_date' => $dateto,
                  'sort' => $valid_sort,
                  'per_page' => $per_page,
                  'extras' => 'date_upload,date_taken,license,geo,tags,views,media',
                  'media' => $media,
                  'license' => '',
                ));
                foreach ($texts as $tagsfiks) {
                  $textextension = flickr_photos_search($id, $page, array(
                    'group_id' => $group_id,
                    'text' => '"' . $tagsfiks . '"',
                    'tag_mode' => $tag_mode,
                    'min_taken_date' => $datefrom,
                    'max_taken_date' => $dateto,
                    'sort' => $valid_sort,
                    'per_page' => $per_page,
                    'extras' => 'date_upload,date_taken,license,geo,tags,views,media',
                    'media' => $media,
                    'license' => '',
                  ));
                  $textext = array_merge($textext, $textextension['photo']);
                }
              }
            }
            if (!$response) {
              return;
            }
            $photos = $extend ? array_merge($response['photo'], $textext) : $response['photo'];

            // Remove duplicates on the key 'id'.
            $temp = array();
            $new = array();
            foreach ($photos as $value) {
              if (!in_array($value['id'], $temp)) {
                $temp[] = $value['id'];
                $new[] = $value;
              }
            }
            $photos = $new;

            // With OR operator we remove results that match exclusion strings.
            if ($tag_mode == 'any') {
              $photos = array_filter($photos, function ($photo) use ($excludestrings) {
                return flickr_excludestrings($photo, $excludestrings);
              });
            }
        }
        switch ($sort) {
          case 'id':
            usort($photos, 'flickr_sortByID');
            break;
          case 'date-taken-desc':
            if ($type != 'user' || !empty($filter)) {
              usort($photos, 'flickr_sortByTaken');
            }
            break;
          case 'date-posted-desc':
            if ($type != 'user' || !empty($filter)) {
              usort($photos, 'flickr_sortByUpload');
            }
            break;

          // Only for group albums.
          case 'added':
            usort($photos, 'flickr_sortByAdded');
            break;
          case 'views':
            usort($photos, 'flickr_sortByPopularity');
            break;
          case 'random':
            shuffle($photos);
            break;

          // In any other case as ordered by the Flickr API response.
          default:
            break;
        }

        // Skip photos taken in the future (date set incorrectly on the camera).
        if ($sort == 'date-taken-desc') {
          $skipped = 0;
          foreach ($photos as $key => $photo) {
            $date = time() - strtotime($photo['datetaken']);
            if ($date < 0) {
              unset($photos[$key]);
              $skipped++;
            }
          }
          if ($skipped > 0) {
            drupal_set_message(t("Skipped !number photos because dated in the future (probably due to a wrong date on the used camera).", array(
              '!number' => '<em>' . $skipped . '</em>',
            )), 'warning');
          }
        }

        // We shouldn't try to return more than the total number of photos.
        $to = min($show_n, count($photos));
        $i = 0;
        $j = 0;
        $k = 0;

        // A (too complex) series of conditions to loop through to generate the
        // photos of an album. TODO: Implement simplification and better logic.
        // No Flickr tags specified and on a node page.
        if ($vocab_isset == -1 && empty($tags) && empty($lat) && (arg(0) == 'node' && is_numeric(arg(1)) && (arg(2) == '' || arg(2) == 'view'))) {
          $vocab_name = taxonomy_vocabulary_load($vocab_isset)->name;
          $output .= t("Post has no !vocab_name or location specified.", array(
            '!vocab_name' => '<em>' . $vocab_name . '</em>',
          ));
        }
        elseif (empty($tags) && empty($tags_user) || $type == 'gallery' && is_numeric($delta)) {
          foreach ($photos as $photo) {
            if ($i < $show_n && ($media == 'all' || $media == $photo['media'] . 's')) {

              // Insert owner into $photo because theme_flickr_photo needs it.
              $photo['owner'] = $type == 'photoset' ? $info['owner'] : $photo['owner'];
              $photo['owner'] = $type == 'gallery' ? $info['gallery']['owner'] : $photo['owner'];

              // Check if the requested size is available on Flickr.
              if (flickr_in_array_r($sizes[$size]['label'], flickr_photos_getsizes($photo['id']))) {
                $output .= theme('flickr_photo', array(
                  'photo' => $photo,
                  'size' => $size,
                  'min_title' => $min_title,
                  'min_metadata' => $min_metadata,
                ));
                $i++;
              }
              else {
                $output .= '';
                $k++;
              }
              $j++;
            }
          }
        }
        elseif (empty($tags) && $type == 'user' && !empty($id) && $id != 'public') {
          foreach ($photos as $key => $photo) {
            $tags_user = !is_array($tags_user) ? explode(",", $tags_user) : $tags_user;
            foreach ($tags_user as $term) {
              if ($i >= $show_n && stripos($photo['tags'], $term) !== FALSE) {
                $j++;
              }
              elseif (stripos($photo['tags'], $term) !== FALSE && ($media == 'all' || $media == $photo['media'] . 's')) {

                // Check if the requested size is available on Flickr.
                if (flickr_in_array_r($sizes[$size]['label'], flickr_photos_getsizes($photo['id']))) {
                  $output .= theme('flickr_photo', array(
                    'photo' => $photo,
                    'size' => $size,
                    'min_title' => $min_title,
                    'min_metadata' => $min_metadata,
                  ));
                  $i++;
                }
                else {
                  $output .= '';
                  $k++;
                }

                // Avoid this image gets repeated by removing it from the
                // array.
                unset($photos[$key]);
                $j++;
              }
            }
          }
        }
        elseif (empty($tags_user) || empty($id)) {
          $taxs = is_array($tags) ? $tags : explode(",", $tags);
          $texts = is_array($tagsfix) ? $tagsfix : explode(",", $tagsfix);
          $terms = array_merge($taxs, $texts);
          $done = 0;
          foreach ($photos as $key => $photo) {
            $phototags = (variable_get('flickr_extend', 1) || $extend) && $extend ? $photo['tags'] . ' ' . strtolower($photo['title']) : $photo['tags'];
            foreach ($terms as $term) {
              if ($i >= $show_n && (stripos($phototags, $term) !== FALSE || $type == 'user') || $photo['id'] == $done && (stripos($phototags, $term) !== FALSE || $type == 'user')) {
                $j++;
              }
              elseif (($media == 'all' || $media == $photo['media'] . 's') && (stripos($phototags, $term) !== FALSE || $type == 'user')) {

                // Insert owner into $photo because theme_flickr_photo needs it.
                $photo['owner'] = $type == 'photoset' ? $info['owner'] : $photo['owner'];
                $photo['owner'] = $type == 'gallery' ? $info['gallery']['owner'] : $photo['owner'];

                // Check if the requested size is available on Flickr.
                if (flickr_in_array_r($sizes[$size]['label'], flickr_photos_getsizes($photo['id']))) {
                  $output .= theme('flickr_photo', array(
                    'photo' => $photo,
                    'size' => $size,
                    'min_title' => $min_title,
                    'min_metadata' => $min_metadata,
                  ));
                  $i++;
                }
                else {
                  $output .= '';
                  $k++;
                }

                // Avoid this image gets repeated by removing it from the
                // array AND "remembering" the processed photo ID if it is twice
                // in the array (public photos with multiple tags).
                unset($photos[$key]);
                $done = $photo['id'];
                $j++;
              }
            }
          }
        }
        else {
          $terms = is_array($tags) ? $tags : explode(",", $tags);
          foreach ($photos as $key => $photo) {
            foreach ($tags_user as $tag) {
              foreach ($terms as $term) {
                if ($i >= $show_n && stripos($photo['tags'], $term) !== FALSE && stripos($photo['tags'], $tag) !== FALSE) {
                  $j++;
                }
                elseif (stripos($photo['tags'], $term) !== FALSE && stripos($photo['tags'], $tag) !== FALSE && ($media == 'all' || $media == $photo['media'] . 's')) {

                  // Insert owner into $photo because theme_flickr_photo needs
                  // it.
                  $photo['owner'] = $type == 'photoset' ? $info['owner'] : $photo['owner'];

                  // TODO: In theory we don't get here if a gallery. Remove?
                  $photo['owner'] = $type == 'gallery' ? $info['gallery']['owner'] : $photo['owner'];

                  // Check if the requested size is available on Flickr.
                  if (flickr_in_array_r($sizes[$size]['label'], flickr_photos_getsizes($photo['id']))) {
                    $output .= theme('flickr_photo', array(
                      'photo' => $photo,
                      'size' => $size,
                      'min_title' => $min_title,
                      'min_metadata' => $min_metadata,
                    ));
                    $i++;
                  }
                  else {
                    $output .= '';
                    $k++;
                  }

                  // Avoid this image gets repeated by removing it from the
                  // array.
                  unset($photos[$key]);
                  $j++;
                }
              }
            }
          }
        }
        if ($k > 0) {
          drupal_set_message(t("!number photos were skipped because the requested image size is not available on Flickr. They were uploaded when this size was not offered yet. To include them, use another size or re-upload your photos on Flickr.", array(
            '!number' => '<em>' . $k . '</em>',
          )), 'warning');
        }
        $output .= '</div>';
        if ($i == 0 && variable_get('flickr_block_hide_empty', 0)) {
          $output = '';
          if (is_numeric($delta) && module_exists('flickr_block')) {
            $refresh = $sort == 'random' ? variable_get('flickr_block_refresh_random', 23) : variable_get('flickr_block_refresh_others', 31);

            // drupal_is_front_page() is added because it also can have
            // arg(0) == 'node'.
            cache_set('flickr_block_' . $delta . '_' . $idfix . '_' . $tags . '_' . $lat . '_' . $datetofix . '_' . $datefromfix . '_' . arg(0) . '_' . drupal_is_front_page(), $output, 'cache', time() + $refresh * 60 * 60);
          }
          return $output;
        }

        // A counter if set to show.
        if (isset($response['total']) || isset($response['photos']['total'])) {
          $response['total'] = !isset($response['total']) && isset($response['photos']['total']) ? $response['photos']['total'] : $response['total'];
          $response['total'] = isset($textextension['total']) ? $response['total'] + $textextension['total'] : $response['total'];
        }
        $total = isset($response['total']) ? $response['total'] : $total;
        $total = $type == 'favorites' && !empty($tags) ? $j : $total;
        $total = empty($tags) || isset($response['total']) ? (int) $total : $j;
        $total = isset($response['total']) && !empty($tags) && $j == $show_n * 4 ? $response['total'] : $total;
        $total = $total < $i ? $i : $total;
        $total = $i < $show_n ? $i : $total;
        $total = number_format($total, 0, '.', variable_get('flickr_thousands_sep', ','));
        if (!empty($radius)) {
          $radius = $radius / 3;
          $km = floor($radius);
          $mt = ltrim(str_replace(".", "", number_format($radius - $km, 3)), '0');
          $mt = empty($mt) ? '' : $mt . ' ' . t('mt');
          $km = $radius >= 1 ? $km . ' ' . t('km') : '';
          $separator = empty($km) || empty($mt) ? '' : ' ' . t('and') . ' ';
          $range = ' ' . t('in a radius of') . ' ' . $km . $separator . $mt;
        }
        else {
          $range = '';
        }
        $count = t('@number out of @total !flickr@range', array(
          '@number' => $i,
          '@total' => $total,
          '!flickr' => $flickr,
          '@range' => $range,
        ));

        // Note the $delta value is 'abused' for counter override from filter.
        // If the total found > max query ($per_page), omit the counter if tags
        // are applied.
        $terms = isset($terms) ? $terms : 1;
        $output .= (variable_get('flickr_counter', 1) && $delta != 'false' || $delta == 'true') && (isset($response['total']) || ($j < $per_page * count($terms) || empty($tags))) && ($show_n > 1 || is_numeric($delta)) ? '<div class="flickr-album-counter">' . $count . '</div>' : '';
    }
    if ($show_n > 1 || is_numeric($delta)) {
      $output .= '</div>';
    }
    else {
      $output .= '</span>';
    }
    if (is_numeric($delta) && module_exists('flickr_block')) {
      $refresh = $sort == 'random' ? variable_get('flickr_block_refresh_random', 23) : variable_get('flickr_block_refresh_others', 31);

      // drupal_is_front_page() is added because it also can have
      // arg(0) == 'node'.
      cache_set('flickr_block_' . $delta . '_' . $idfix . '_' . $tagsfix . '_' . $latfix . '_' . $datefromfix . '_' . $datetofix . '_' . arg(0) . '_' . drupal_is_front_page() . '_' . $pagefix, $output, 'cache', time() + $refresh * 60 * 60);
    }
  }
  return $output;
}