You are here

function media_wysiwyg_token_to_markup in D7 Media 7.4

Same name and namespace in other branches
  1. 7.2 modules/media_wysiwyg/includes/media_wysiwyg.filter.inc \media_wysiwyg_token_to_markup()
  2. 7.3 modules/media_wysiwyg/includes/media_wysiwyg.filter.inc \media_wysiwyg_token_to_markup()

Convert a media token into HTML markup.

Parameters

string $token: Media token with surrounding double brackets ('[[…]]').

bool $wysiwyg: Set to TRUE if called from within the WYSIWYG text area editor.

Return value

string The HTML markup representation of the token, or an empty string on failure.

See also

media_wysiwyg_get_file_without_label()

hook_media_wysiwyg_token_to_markup_alter()

2 calls to media_wysiwyg_token_to_markup()
media_wysiwyg_filter in modules/media_wysiwyg/includes/media_wysiwyg.filter.inc
Filter callback for media markup filter.
_media_wysiwyg_generate_tagmap in modules/media_wysiwyg/includes/media_wysiwyg.filter.inc
Creates map of inline media tags.

File

modules/media_wysiwyg/includes/media_wysiwyg.filter.inc, line 276
Functions related to the WYSIWYG editor and the media input filter.

Code

function media_wysiwyg_token_to_markup($token, $wysiwyg = FALSE, $langcode = NULL) {
  static $recursion_stop;
  $json = str_replace("[[", "", $token);
  $json = str_replace("]]", "", $json);

  // Drupal modules with email support often include site name in the subject line
  // wrapped in brackets. With a token, this is rendered as "[[site:name]]". Such a
  // format will cause a conflict with media_wysiwyg, which is looking for the same.
  if (module_exists('token_filter')) {
    $token_filter = _token_filter_filter_tokens('[' . $tag . ']', '', '', $langcode, NULL, NULL);
    if ($token_filter != '[' . $tag . ']') {
      return '[[' . $tag . ']]';
    }
  }
  try {
    if (!is_string($json)) {
      throw new Exception('Unable to find matching tag');
    }
    $tag_info = drupal_json_decode($json);
    media_wysiwyg_validate_instance_settings($tag_info);
    if ($tag_info['view_mode'] != 'default') {
      $file_entity_info = entity_get_info('file');
      if (!in_array($tag_info['view_mode'], array_keys($file_entity_info['view modes']))) {

        // Media 1.x defined some old view modes that have been superseded by
        // more semantically named ones in File Entity. The media_update_7203()
        // function updates field settings that reference the old view modes,
        // but it's impractical to update all text content, so adjust
        // accordingly here.
        static $view_mode_updates = array(
          'media_preview' => 'preview',
          'media_small' => 'teaser',
          'media_large' => 'full',
        );
        if (isset($view_mode_updates[$tag_info['view_mode']])) {
          $tag_info['view_mode'] = $view_mode_updates[$tag_info['view_mode']];
        }
        else {
          throw new Exception('Invalid view mode');
        }
      }
    }
    if (!($file = file_load($tag_info['fid']))) {
      throw new Exception('Could not load media object');
    }

    // Check if we've got a recursion. Happens because a file_load() may
    // triggers file_entity_is_page() which then again triggers a file load.
    if (isset($recursion_stop[$file->fid])) {
      return '';
    }
    $recursion_stop[$file->fid] = TRUE;
    $tag_info['file'] = $file;
    if ($tag_info['instance_fields'] == 'override') {

      // Grab the potentially overridden fields from the file.
      $settings = media_wysiwyg_filter_field_parser($tag_info);
      foreach ($settings as $key => $value) {
        $file->{$key} = $value;
      }
    }
    else {
      $settings = array();
    }
    if (isset($tag_info['external_url'])) {
      $settings['external_url'] = $tag_info['external_url'];
    }

    // Analyze and filter attributes from token.
    $settings['attributes'] = array();
    if (!empty($tag_info['attributes']) && is_array($tag_info['attributes'])) {

      // The class attributes is a string, but drupal requires it to be an
      // array, so we fix it here.
      if (!empty($tag_info['attributes']['class'])) {
        $tag_info['attributes']['class'] = explode(' ', $tag_info['attributes']['class']);
      }
      $attribute_whitelist = media_wysiwyg_allowed_attributes();
      $settings['attributes'] = array_intersect_key($tag_info['attributes'], array_flip($attribute_whitelist));

      // Many media formatters will want to apply width and height independently
      // of the style attribute or the corresponding HTML attributes, so pull
      // these two out into top-level settings. Different WYSIWYG editors have
      // different behavior with respect to whether they store user-specified
      // dimensions in the HTML attributes or the style attribute - check both.
      // Per http://www.w3.org/TR/html5/the-map-element.html#attr-dim-width, the
      // HTML attributes are merely hints: CSS takes precedence.
      if (isset($settings['attributes']['style'])) {
        $css_properties = media_wysiwyg_parse_css_declarations($settings['attributes']['style']);
        foreach (array(
          'width',
          'height',
        ) as $dimension) {
          if (isset($css_properties[$dimension]) && substr($css_properties[$dimension], -2) == 'px') {
            $settings[$dimension] = substr($css_properties[$dimension], 0, -2);
          }
          elseif (isset($settings['attributes'][$dimension])) {
            $settings[$dimension] = $settings['attributes'][$dimension];
          }
        }
      }
      foreach (array(
        'title',
        'alt',
      ) as $field_type) {
        if (isset($settings['attributes'][$field_type])) {
          $settings['attributes'][$field_type] = decode_entities($settings['attributes'][$field_type]);
        }
      }
    }

    // Update file metadata from the potentially overridden tag info.
    foreach (array(
      'width',
      'height',
    ) as $dimension) {
      if (isset($settings['attributes'][$dimension])) {
        $file->metadata[$dimension] = $settings['attributes'][$dimension];
      }
    }
  } catch (Exception $e) {
    watchdog('media', 'Unable to render media from %tag. Error: %error', array(
      '%tag' => $token,
      '%error' => $e
        ->getMessage(),
    ));
    return '';
  }

  // If the tag has link text stored with it, override the filename with it for
  // the rest of this function, so that if the file is themed as a link, the
  // desired text will be used (see, for example, theme_file_link()).
  // @todo: Try to find a less hacky way to do this.
  if (isset($tag_info['link_text']) && variable_get('media_wysiwyg_use_link_text_for_filename', 1)) {

    // The link text will have characters such as "&" encoded for HTML, but the
    // filename itself needs the raw value when it is used to build the link,
    // in order to avoid double encoding.
    $file->filename = decode_entities($tag_info['link_text']);
  }
  if ($wysiwyg) {
    media_wysiwyg_fid_type_map_add($file->fid, $file->type);
    $settings['wysiwyg'] = $wysiwyg;

    // Render file in WYSIWYG using appropriate view mode.
    $view_mode = db_query('SELECT view_mode FROM {media_view_mode_wysiwyg} WHERE type = :type', array(
      ':type' => $file->type,
    ))
      ->fetchField();
    if (empty($view_mode)) {
      $view_mode = $tag_info['view_mode'];
    }
    $element = media_wysiwyg_get_file_without_label($file, $view_mode, $settings, $langcode);
  }
  else {

    // Display the field elements.
    $element = array();

    // Render the file entity, for sites using the file_entity rendering method.
    if (variable_get('media_wysiwyg_default_render', 'file_entity') == 'file_entity') {
      $element['content'] = file_view($file, $tag_info['view_mode'], $langcode);
    }
    $element['content']['file'] = media_wysiwyg_get_file_without_label($file, $tag_info['view_mode'], $settings, $langcode);

    // Overwrite or set the file #alt attribute if it has been set in this
    // instance.
    if (!empty($element['content']['file']['#attributes']['alt'])) {
      $element['content']['file']['#alt'] = $element['content']['file']['#attributes']['alt'];
    }

    // Overwrite or set the file #title attribute if it has been set in this
    // instance.
    if (!empty($element['content']['file']['#attributes']['title'])) {
      $element['content']['file']['#title'] = $element['content']['file']['#attributes']['title'];
    }

    // For sites using the legacy field_attach rendering method, attach fields.
    if (variable_get('media_wysiwyg_default_render', 'file_entity') == 'field_attach') {
      field_attach_prepare_view('file', array(
        $file->fid => $file,
      ), $tag_info['view_mode'], $langcode);
      entity_prepare_view('file', array(
        $file->fid => $file,
      ), $langcode);
      $element['content'] += field_attach_view('file', $file, $tag_info['view_mode'], $langcode);
    }
    if (count(element_children($element['content'])) > 1) {

      // Add surrounding divs to group them together.
      // We don't want divs when there are no additional fields to allow files
      // to display inline with text, without breaking p tags.
      $element['content']['#type'] = 'container';
      $element['content']['#attributes']['class'] = array(
        'media',
        'media-element-container',
        'media-' . $element['content']['file']['#view_mode'],
      );
      if (variable_get('media_wysiwyg_remove_media_class', FALSE)) {
        $classes = $element['content']['#attributes']['class'];
        $element['content']['#attributes']['class'] = array_diff($classes, array(
          'media',
        ));
      }
    }
    if (!empty($tag_info['alignment']) && !empty($element['content'])) {
      $element['content']['#attributes']['class'][] = 'media-wysiwyg-align-' . $tag_info['alignment'];
    }

    // Conditionally add a pre-render if the media filter output is be cached.
    $filters = filter_get_filters();
    if (!isset($filters['media_filter']['cache']) || $filters['media_filter']['cache']) {
      $element['#pre_render'][] = 'media_wysiwyg_pre_render_cached_filter';
    }
  }
  drupal_alter('media_wysiwyg_token_to_markup', $element, $tag_info, $settings, $langcode);
  $output = drupal_render($element);
  unset($recursion_stop[$file->fid]);
  return $output;
}