View source
<?php
define('MEDIA_WYSIWYG_TOKEN_REGEX', '/\\[\\[\\{.*?"type":"media".*?\\}\\]\\]/s');
function media_wysiwyg_filter($text, $filter = NULL, $format = NULL, $langcode = NULL, $cache = NULL, $cache_id = NULL) {
$replacements = array();
$patterns = array();
$rendered_text = $text;
$count = 1;
preg_match_all(MEDIA_WYSIWYG_TOKEN_REGEX, $text, $matches);
if (!empty($matches[0])) {
foreach ($matches[0] as $match) {
$replacement = media_wysiwyg_token_to_markup(array(
$match,
), FALSE, $langcode);
$rendered_text = str_replace($match, $replacement, $rendered_text, $count);
}
}
return $rendered_text;
}
function _media_filter_paragraph_fix_settings($form, &$form_state, $filter, $format, $defaults) {
$filter->settings += $defaults;
$settings['replace'] = array(
'#type' => 'checkbox',
'#title' => t('Replace paragraph tags with DIV.media-p tags'),
'#default_value' => $filter->settings['replace'],
'#description' => t('Default behaviour is to strip out parent P tags of media elements rather than replacing these.'),
);
return $settings;
}
function media_wysiwyg_filter_paragraph_fix($text, $filter) {
$html_dom = filter_dom_load($text);
$dom_nodes_to_remove = array();
foreach ($html_dom
->getElementsByTagName('p') as $paragraph) {
if (preg_match(MEDIA_WYSIWYG_TOKEN_REGEX, $paragraph->nodeValue)) {
if (empty($filter->settings['replace'])) {
$sibling = $paragraph->firstChild;
do {
$next = $sibling->nextSibling;
$paragraph->parentNode
->insertBefore($sibling, $paragraph);
} while ($sibling = $next);
$dom_nodes_to_remove[] = $paragraph;
}
else {
$div = $html_dom
->createElement('div');
$sibling = $paragraph->firstChild;
do {
$next = $sibling->nextSibling;
$div
->appendChild($sibling);
} while ($sibling = $next);
$classes = array(
'media-p',
);
if ($paragraph
->hasAttributes()) {
foreach ($paragraph->attributes as $attr) {
$name = $attr->nodeName;
$value = $attr->nodeValue;
if (strtolower($name) == 'class') {
$classes[] = $value;
}
else {
@$div
->setAttribute($name, $value);
}
}
}
$div
->setAttribute('class', implode(' ', $classes));
$paragraph->parentNode
->insertBefore($div, $paragraph);
$dom_nodes_to_remove[] = $paragraph;
}
}
}
foreach ($dom_nodes_to_remove as $paragraph) {
$paragraph->parentNode
->removeChild($paragraph);
}
$text = filter_dom_serialize($html_dom);
return $text;
}
function media_wysiwyg_parse_css_declarations($declarations) {
$properties = array();
foreach (array_map('trim', explode(";", $declarations)) as $declaration) {
if ($declaration != '') {
list($name, $value) = array_map('trim', explode(':', $declaration, 2));
$properties[strtolower($name)] = $value;
}
}
return $properties;
}
function media_wysiwyg_token_to_markup($match, $wysiwyg = FALSE, $langcode = NULL) {
static $recursion_stop;
$settings = array();
$match = str_replace("[[", "", $match);
$match = str_replace("]]", "", $match);
$tag = $match[0];
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($tag)) {
throw new Exception('Unable to find matching tag');
}
$tag_info = drupal_json_decode($tag);
if (!isset($tag_info['fid'])) {
throw new Exception('No file Id');
}
if (!isset($tag_info['link_text'])) {
$tag_info['link_text'] = NULL;
}
if (!isset($tag_info['view_mode'])) {
$tag_info['view_mode'] = variable_get('media_wysiwyg_wysiwyg_default_view_mode', 'full');
}
elseif ($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']))) {
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');
}
}
}
$file = file_load($tag_info['fid']);
if (!$file) {
throw new Exception('Could not load media object');
}
if (isset($recursion_stop[$file->fid])) {
return '';
}
$recursion_stop[$file->fid] = TRUE;
$tag_info['file'] = $file;
if (!empty($tag_info['attributes']['class'])) {
$tag_info['attributes']['class'] = explode(" ", $tag_info['attributes']['class']);
}
$fields = media_wysiwyg_filter_field_parser($tag_info);
foreach ($fields as $key => $value) {
$file->{$key} = $value;
}
if (array_key_exists('attributes', $tag_info) && is_array($tag_info['attributes'])) {
$attributes = $tag_info['attributes'];
}
else {
$attributes = array();
}
$attribute_whitelist = media_wysiwyg_allowed_attributes();
$settings['attributes'] = array_intersect_key($attributes, array_flip($attribute_whitelist));
$settings['fields'] = $fields;
if (isset($tag_info['fields']['external_url'])) {
$settings['fields']['external_url'] = $tag_info['fields']['external_url'];
}
if (!empty($tag_info['attributes']) && is_array($tag_info['attributes'])) {
$settings['attributes'] = array_intersect_key($tag_info['attributes'], array_flip($attribute_whitelist));
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];
}
}
if (!empty($css_properties['float'])) {
$settings['float'] = $css_properties['float'];
}
}
foreach (array(
'title',
'alt',
) as $field_type) {
if (isset($settings['attributes'][$field_type])) {
$settings['attributes'][$field_type] = decode_entities($settings['attributes'][$field_type]);
}
}
}
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' => $tag,
'%error' => $e
->getMessage(),
));
return '';
}
if (isset($settings['attributes']['class'])) {
$alignment_classes = array(
'media-wysiwyg-align-left',
'media-wysiwyg-align-right',
'media-wysiwyg-align-center',
);
$settings['attributes']['class'] = array_diff($settings['attributes']['class'], $alignment_classes);
}
if (isset($tag_info['link_text']) && variable_get('media_wysiwyg_use_link_text_for_filename', 1)) {
$file->filename = decode_entities($tag_info['link_text']);
}
if ($wysiwyg) {
$settings['wysiwyg'] = $wysiwyg;
$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);
$data = array(
'type' => 'media',
'fid' => $file->fid,
'view_mode' => $tag_info['view_mode'],
'link_text' => $tag_info['link_text'],
);
drupal_add_js(array(
'mediaDataMap' => array(
$file->fid => $data,
),
), 'setting');
$element['#attributes']['data-fid'] = $file->fid;
$element['#attributes']['data-media-element'] = '1';
if (is_array($element['#attributes']['class'])) {
$element['#attributes']['class'][] = 'media-element';
}
else {
$element['#attributes']['class'] .= 'media-element';
}
}
else {
$element = array();
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);
if (!empty($element['content']['file']['#attributes']['alt'])) {
$element['content']['file']['#alt'] = $element['content']['file']['#attributes']['alt'];
}
if (!empty($element['content']['file']['#attributes']['title'])) {
$element['content']['file']['#title'] = $element['content']['file']['#attributes']['title'];
}
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 (!empty($settings['float'])) {
$element['content']['file']['#attributes']['class'][] = drupal_html_class('media-float-' . $settings['float']);
}
}
if (count(element_children($element['content'])) > 1) {
$element['content']['#type'] = 'container';
$element['content']['#attributes']['class'] = array(
'media',
'media-element-container',
'media-' . $element['content']['file']['#view_mode'],
);
if (!empty($settings['float'])) {
$element['content']['#attributes']['class'][] = drupal_html_class('media-float-' . $settings['float']);
}
if (variable_get('media_wysiwyg_remove_media_class', FALSE)) {
$classes = $element['content']['#attributes']['class'];
$element['content']['#attributes']['class'] = array_diff($classes, array(
'media',
));
}
}
$filters = filter_get_filters();
if (!isset($filters['media_filter']['cache']) || $filters['media_filter']['cache']) {
$element['#pre_render'][] = 'media_wysiwyg_pre_render_cached_filter';
}
}
if (!empty($element['content']) && !empty($tag_info['fields']['alignment'])) {
$alignment = $tag_info['fields']['alignment'];
if (in_array($alignment, array(
'left',
'right',
'center',
))) {
$alignment_class = 'media-wysiwyg-align-' . $alignment;
$element['content']['#attributes']['class'][] = $alignment_class;
}
}
drupal_alter('media_wysiwyg_token_to_markup', $element, $tag_info, $settings, $langcode);
$output = drupal_render($element);
unset($recursion_stop[$file->fid]);
return $output;
}
function media_wysiwyg_filter_field_parser(array $tag_info) {
$fields = array();
if (isset($tag_info['fields'])) {
$url_encoded_fields = array();
foreach ($tag_info['fields'] as $candidate => $field_value) {
if (preg_match('/\\[format\\]$/', $candidate) > 0) {
$url_encoded_fields[] = preg_replace('/\\[format\\]$/', '[value]', $candidate);
}
}
foreach ($tag_info['fields'] as $candidate => $field_value) {
if (strpos($candidate, 'field_') === 0) {
$parsed_field = explode('[', str_replace(']', '', $candidate));
$info = field_info_field($parsed_field[0]);
if (!$info) {
continue;
}
if (count($parsed_field) == 2) {
if ($info && !empty($info['columns'])) {
$parsed_field[] = 0;
$parsed_field[] = key($info['columns']);
}
}
elseif (count($parsed_field) == 3 && (empty($parsed_field[2]) || is_numeric($parsed_field[2]))) {
$parsed_field[3] = key($info['columns']);
}
$ref =& $fields;
foreach ($parsed_field as $key) {
if (!isset($ref[$key])) {
$ref[$key] = array();
}
$ref =& $ref[$key];
}
if (in_array($candidate, $url_encoded_fields)) {
$ref = urldecode(decode_entities($field_value));
}
else {
$ref = decode_entities($field_value);
}
}
}
foreach ($fields as $field_name => $field_languages) {
$info = field_info_field($field_name);
if (isset($field_languages) && is_array($field_languages)) {
foreach ($field_languages as $lang => $items) {
$fields[$field_name][$lang] = _field_filter_items($info, $items);
}
}
}
}
return $fields;
}
function _media_wysiwyg_generate_tagMap($text) {
static $tagmap = array();
preg_match_all("/\\[\\[(?!nid:).*?\\]\\]/s", $text, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
if (empty($tagmap[$match[0]])) {
if ($markup_for_media = media_wysiwyg_token_to_markup($match, TRUE)) {
$tagmap[$match[0]] = $markup_for_media;
}
else {
$missing = file_create_url(drupal_get_path('module', 'media') . '/images/icons/default/image-x-generic.png');
$tagmap[$match[0]] = '<div><img src="' . $missing . '" width="100px" height="100px"/></div>';
}
}
}
return $tagmap;
}
function media_wysiwyg_get_wysiwyg_allowed_view_modes($file) {
$enabled_view_modes =& drupal_static(__FUNCTION__, array());
if (!isset($enabled_view_modes[$file->type])) {
$enabled_view_modes[$file->type] = array();
$enabled_view_modes[$file->type]['default'] = array(
'label' => t('Default'),
'custom settings' => TRUE,
);
$entity_info = entity_get_info('file');
$view_mode_settings = field_view_mode_settings('file', $file->type);
foreach ($entity_info['view modes'] as $view_mode => $view_mode_info) {
if (empty($view_mode_settings[$view_mode]['custom_settings'])) {
continue;
}
$extra_fields = field_extra_fields_get_display('file', $file->type, $view_mode);
if (empty($extra_fields['file']['visible'])) {
continue;
}
$enabled_view_modes[$file->type][$view_mode] = $view_mode_info;
}
}
$view_modes = $enabled_view_modes[$file->type];
media_wysiwyg_wysiwyg_allowed_view_modes_restrict($view_modes, $file);
drupal_alter('media_wysiwyg_allowed_view_modes', $view_modes, $file);
drupal_alter('media_wysiwyg_wysiwyg_allowed_view_modes', $view_modes, $file);
return $view_modes;
}
function media_wysiwyg_wysiwyg_allowed_view_modes_restrict(&$view_modes, &$file) {
$restricted_view_modes = db_query('SELECT display FROM {media_restrict_wysiwyg} WHERE type = :type', array(
':type' => $file->type,
))
->fetchCol();
foreach ($restricted_view_modes as $restricted_view_mode) {
if (array_key_exists($restricted_view_mode, $view_modes)) {
unset($view_modes[$restricted_view_mode]);
}
}
}
function media_wysiwyg_pre_render_cached_filter($element) {
if (isset($element['content']['#contextual_links'])) {
unset($element['content']['#contextual_links']);
}
return $element;
}