<?php

/**
 * @file
 *
 * Tokens include file
 * Defines tokens from Media field files
 */

/**
 * Returns metadata describing supported tokens.
 */
function media_token_info() {

  $info['types']['file_field'] = array(
    'name' => t('Media'),
    'description' => t('Tokens related to a media field.'),
    'hidden' => TRUE,
  );

  $default_text = ' ' . t('Defaults to first value.');

  $info['tokens']['file_field'] = array(
    'field' => array(
      'name' => t('Field token value'),
      'description' => t('Default: The value returned by the token field formatter.') . $default_text,
    ),
    'url' => array(
      'name' => t('URL'),
      'description' => t('URL of the media resource.') . $default_text,
      'type' => 'array',
    ),
    'filename' => array(
      'name' => t('Filename'),
      'description' => t('Filename the media resource.') . $default_text,
      'type' => 'array',
    ),
    'filemime' => array(
      'name' => t('MIME type'),
      'description' => t('MIME type of the media resource.') . $default_text,
      'type' => 'array',
    ),
    'type' => array(
      'name' => t('File type'),
      'description' => t('File type of the media resource.') . $default_text,
      'type' => 'array',
    ),
    'image' => array(
      'name' => t('Image'),
      'description' => t('URL of a representative image for the media resource, e.g. a video thumbnail.') . $default_text,
      'type' => 'array',
    ),
    'height' => array(
      'name' => t('Height'),
      'description' => t('Height of the media resource, for videos or images.') . $default_text,
      'type' => 'array',
    ),
    'width' => array(
      'name' => t('Width'),
      'description' => t('Width of the media resource, for videos or images.') . $default_text,
      'type' => 'array',
    ),
    'https-url' => array(
      'name' => t('Secure URL'),
      'description' => t('URL of the media resource using HTTPS.') . $default_text,
      'type' => 'array',
    ),
    'https-image' => array(
      'name' => t('Secure image'),
      'description' => t('URL of a representative image for the media resource using HTTPS, usually for videos.') . $default_text,
      'type' => 'array',
    ),
  );


  $all_fields = field_info_field_map();
  foreach ($all_fields as $field_name => $field) {
    if ($field['type'] == 'file') {
      $field_info = _token_field_info($field_name);
      foreach (array_keys($field['bundles']) as $entity_type) {
        $info['tokens'][$entity_type][$field_name] = array(
          'name' => $field_info['label'],
          'description' => $field_info['description'],
          'type' => 'file_field',
          'module' => 'media',
        );
      }
    }
  }

  return $info;
}

/**
 * Provide replacement values for placeholder tokens.
 */
function media_tokens($type, $tokens, $data = array(), $options = array()) {
  $replacements = array();

  // Check that this token call contains the data we need
  if ($type == 'entity' && !empty($data['entity_type']) && !empty($data['entity']) && !empty($data['token_type'])) {

    foreach ($tokens as $name => $original) {

      // Split out the token into its parts
      $parts = explode(':', $name, 3);

      $field_name    = $parts[0];
      $property      = (isset($parts[1])) ? $parts[1] : '';
      $array_handler = (isset($parts[2])) ? $parts[2] : '';

      // Check that the field has content and that we should handle it
      if (!empty($data['entity']->$field_name) && _token_module($data['token_type'], $field_name) == 'media') {

        // Get basic information
        $entity_type = $data['entity_type'];
        $langcode = isset($options['language']) ? $options['language']->language : NULL;
        $entity = clone $data['entity'];

        // If we are looking for the field output, let field module handle it
        if (empty($property) || $property == 'field') {
          unset($entity->_field_view_prepared);
          $field_output = field_view_field($entity_type, $entity, $field_name, 'token', $langcode);
          $field_output['#token_options'] = $options;
          $field_output['#prerender'][] = 'token_pre_render_field_token';
          $replacements[$original] = drupal_render($field_output);
        }
        else {
          $items = field_get_items($entity_type, $entity, $field_name);
          $return = _media_tokens_get_property($items, $property, $array_handler);

          // We may get a single value or an array.
          // Handle array with the array function from token module.
          if (is_array($return)) {
            $search_tokens = token_find_with_prefix($tokens, $field_name);
            if ($array_tokens = token_find_with_prefix($search_tokens, $property)) {
              $replacements += token_generate('array', $array_tokens, array('array' => $return), $options);
            }
          }
          else {
            $replacements[$original] = $return;
          }
        }

        // Unset clone of entity
        unset($entity);
      }
    }
  }
  return $replacements;
}

/**
 * This helper function gets file properties for token replacement.
 *
 * @param array $files
 * An array of files that are values for the field.
 *
 * @param string $property
 * The property to retrieve from the file info. See media_token_info() for
 * a list of properties.
 *
 * @param string $array_handler
 * The optional array modifier, e.g. "count" or "join:,".
 *
 * @return mixed
 * Either a single value, the first of the array, or an array of values.
 */
function _media_tokens_get_property($files, $property, $array_handler = 'first') {

  // If we only need the first variable
  $return_first = ($array_handler == 'first' || empty($array_handler) || $array_handler == 'value:0');

  // This static variable stores image info
  $info = &drupal_static(__FUNCTION__);

  foreach ($files as $file) {
    $file['url'] = file_create_url($file['uri']);
    $file['https-url'] = str_replace('http://', 'https://', $file['url']);

    // If values are: filename, filemime, type, url, https-url
    if (isset($file[$property])) {
      $value = $file[$property];
    }

    // If values are: image, height, width, https-image
    elseif (!empty($info[$file['fid']])) {
      $value = $info[$file['fid']][$property] ?: NULL;
    }
    // If values are files types
    else {

      // If file type is image
      if ($file['type'] == 'image') {
        $imageuri = $file['uri'];
      }

      // If file type is video
      elseif ($file['type'] == 'video') {
        list($provider, $filename) = explode('://v/', $file['uri']);
        $imageuri = "public://media-$provider/$filename.jpg";
      }

      // Do nothing for other file types
      // @todo: Other file types may need handling
      else {
        $imageuri = FALSE;
      }

      if ($info[$file['fid']] = image_get_info($imageuri)) {
        $info[$file['fid']]['image'] = file_create_url($imageuri);
        $info[$file['fid']]['https-image'] = str_replace('http://', 'https://', $info[$file['fid']]['image']);
      }

      $value = $info[$file['fid']][$property] ?: NULL;
    }

    if ($return_first) {
      return $value;
    }
    $values[] = $value;
  }

  return $values;
}
