You are here

ckeditor_swf.module in CKEditor SWF - Enhanced Flash embedding plugin 6.2

Same filename and directory in other branches
  1. 6 ckeditor_swf.module
  2. 7 ckeditor_swf.module

Written by Henri MEDOT <henri.medot[AT]absyx[DOT]fr> http://www.absyx.fr

File

ckeditor_swf.module
View source
<?php

/**
 * @file
 * Written by Henri MEDOT <henri.medot[AT]absyx[DOT]fr>
 * http://www.absyx.fr
 */
define('CKEDITOR_SWF_CLSID', 'd27cdb6e-ae6d-11cf-96b8-444553540000');

/**
 * Implementation of hook_menu().
 */
function ckeditor_swf_menu() {
  $items['ckeditor_swf/getinfo'] = array(
    'page callback' => 'ckeditor_swf_getinfo',
    'access arguments' => array(
      'access content',
    ),
    'type' => MENU_CALLBACK,
  );
  $items['admin/settings/ckeditor_swf'] = array(
    'title' => 'CKEditor SWF',
    'description' => 'Configure CKEditor SWF.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'ckeditor_swf_admin_form',
    ),
    'access callback' => 'ckeditor_swf_admin_access',
    'file' => 'ckeditor_swf.admin.inc',
  );
  return $items;
}
function ckeditor_swf_admin_access() {
  return user_access('administer filters') || module_exists('ckeditor') && user_access('administer ckeditor');
}
function ckeditor_swf_getinfo() {
  drupal_set_header('Content-Type: text/javascript; charset=utf-8');
  $output = 'null';
  $url = check_url($_REQUEST['src']);

  // Attempt to retrieve info using GD2.
  $info = @getimagesize($url);
  if ($info) {
    if ($info['mime'] == 'application/x-shockwave-flash') {
      $output = '{"mime":"application/x-shockwave-flash", "width":' . $info[0] . ', "height":' . $info[1] . '}';
    }
  }
  else {

    // Attempt to retrieve info using getID3
    $info = ckeditor_swf_getid3_analyze($url);
    if (isset($info['mime_type'], $info['fileformat'])) {
      $mime = $info['mime_type'];
      $format = $info['fileformat'];
      $prefix = substr($mime, 0, 6);
      if (isset($info['video']['resolution_x'], $info['video']['resolution_y']) && ($prefix == 'video/' || ($mime = 'video/' . $format))) {
        $output = '{"mime":"' . $mime . '", "width":' . $info['video']['resolution_x'] . ', "height":' . $info['video']['resolution_y'] . '}';
      }
      elseif (isset($info['audio']) && ($prefix == 'audio/' || ($mime = 'audio/' . $format))) {
        $output = '{"mime":"' . $mime . '"}';
      }
    }
  }
  print $output;
  exit;
}

/**
 * Implementation of hook_elements().
 */
function ckeditor_swf_elements() {
  $type['textarea'] = array(
    '#pre_render' => array(
      'ckeditor_swf_textarea_pre_render',
    ),
  );
  $type['form'] = array(
    '#post_render' => array(
      'ckeditor_swf_form_post_render',
    ),
  );
  return $type;
}
function ckeditor_swf_textarea_pre_render($element) {
  _ckeditor_swf_has_textarea(TRUE);
  return $element;
}
function _ckeditor_swf_has_textarea($set = FALSE) {
  static $has = FALSE;
  if (!$set) {
    return $has;
  }
  $has = TRUE;
}
function ckeditor_swf_form_post_render($content, $element) {
  static $added;
  if (!isset($added) && _ckeditor_swf_has_textarea() && ($js = drupal_add_js()) && isset($js['setting'])) {
    $setting = call_user_func_array('array_merge_recursive', $js['setting']);
    if (isset($setting['ckeditor']) || isset($setting['wysiwyg']['configs']['ckeditor'])) {
      $added = TRUE;
      drupal_add_js(array(
        'ckeditor_swf' => array(
          'module_path' => base_path() . drupal_get_path('module', 'ckeditor_swf'),
          'getinfo_path' => url('ckeditor_swf/getinfo'),
          'players' => ckeditor_swf_players(),
          'lang' => array(
            'name' => t('Name'),
            'value' => t('Value'),
            'remove' => t('Remove'),
            'invalid_width' => t('The specified width is invalid.'),
            'invalid_height' => t('The specified height is invalid.'),
            'preview' => t('Preview'),
          ),
        ),
      ), 'setting');
    }
  }
  return $content;
}

/**
 * Implementation of hook_filter().
 */
function ckeditor_swf_filter($op, $delta = 0, $format = -1, $text = '', $cache_id = 0) {
  switch ($op) {
    case 'list':
      return array(
        0 => t('CKEditor SWF Filter'),
      );
    case 'description':
      return t('Converts SWF content markup generated by CKEditor into standards compliant markup.');
    case 'no cache':
      return FALSE;
    case 'prepare':
      return $text;
    case 'process':
      return _ckeditor_swf_filter_process($text);
    case 'settings':
      return _ckeditor_swf_filter_settings();
    default:
      return $text;
  }
}
function _ckeditor_swf_filter_process($text) {

  // Get object tags.
  unset($matches);
  if (!preg_match_all('`</?object\\b.*?>`is', $text, $matches, PREG_OFFSET_CAPTURE)) {
    return $text;
  }

  // Get object elements, ignoring nested ones.
  $elements = array();
  $i = -1;
  $depth = 0;
  foreach ($matches[0] as $match) {
    if (substr($match[0], 0, 2) != '</') {
      if ($depth == 0) {
        $elements[++$i]['start'] = $match;
      }
      $depth++;
    }
    elseif ($depth > 0) {
      $depth--;
      if ($depth == 0) {
        $elements[$i]['end'] = $match;
        $start = $elements[$i]['start'][1] + strlen($elements[$i]['start'][0]);
        $elements[$i]['inner_html'] = substr($text, $start, $match[1] - $start);
      }
    }
  }

  // Parse object elements.
  foreach ($elements as $i => $element) {

    // Parse attributes.
    $attributes = ckeditor_swf_parse_attributes($element['start'][0]);

    // Ignore non-Flash objects.
    if (!isset($attributes['classid']) && variable_get('ckeditor_swf_skip_no_classid', 0) || isset($attributes['classid']) && strtolower(substr($attributes['classid'], -strlen(CKEDITOR_SWF_CLSID))) != CKEDITOR_SWF_CLSID) {
      unset($elements[$i]);
      continue;
    }

    // HTML Filter might have broken the classid attribute (See http://drupal.org/node/812590)
    // or some filters might have removed it.
    $attributes['classid'] = 'clsid:' . CKEDITOR_SWF_CLSID;
    $elements[$i]['attributes'] = $attributes;

    // Parse param elements.
    $params = array();
    unset($matches);
    if (preg_match_all('`<param\\b.*?>`is', $element['inner_html'], $matches)) {
      foreach ($matches[0] as $match) {
        $attributes = ckeditor_swf_parse_attributes($match);
        $name = strtolower(@$attributes['name']);
        if (!isset($params[$name])) {
          $params[$name] = @$attributes['value'];
        }
      }
    }
    $elements[$i]['params'] = $params;

    // Get alternative content.
    $alt = preg_replace('`</?(?:object|param|embed)\\b.*?>`is', '', $element['inner_html']);
    $alt = preg_replace('`<!--.*?-->`s', '', $alt);
    $alt = ckeditor_swf_trim($alt);
    $elements[$i]['alt'] = $alt;
  }

  // Render elements.
  $js = '';
  if (ckeditor_swf_filter_use_swfobject()) {

    // Render elements as SWFObject placeholders.
    $keys = array(
      'name' => 'name',
      'class' => 'styleclass',
      'align' => 'align',
    );
    $version = variable_get('ckeditor_swf_filter_swfobject_version', '6.0.65');
    foreach ($elements as $i => $element) {
      $element_attributes = $element['attributes'];
      $attributes = array();
      foreach ($keys as $k => $key) {
        if (isset($element_attributes[$k])) {
          $attributes[$key] = $element_attributes[$k];
        }
      }
      $id = isset($element_attributes['id']) ? $element_attributes['id'] : ckeditor_swf_filter_uniqid();
      $output = '<span id="' . $id . '">' . "\n";
      $output .= $element['alt'] . "\n";
      $output .= '</span>';
      $elements[$i]['output'] = $output;
      $params = $element['params'];
      $swf_url = $params['movie'];
      unset($params['movie']);
      $js .= sprintf('swfobject.embedSWF("%s", "%s", "%s", "%s", "%s", null, null, %s, %s);', $swf_url, $id, $element_attributes['width'], $element_attributes['height'], $version, drupal_to_js($params), drupal_to_js($attributes)) . "\n";
    }
  }
  else {

    // Render standards compliant object elements.
    foreach ($elements as $i => $element) {
      $attributes = $element['attributes'];
      $params = $element['params'];
      unset($attributes['codebase']);
      $output = '<object' . ckeditor_swf_attributes($attributes) . '>' . "\n";
      $output .= ckeditor_swf_params($params);
      $attributes['type'] = 'application/x-shockwave-flash';
      $attributes['data'] = @$params['movie'];
      unset($attributes['classid']);
      unset($attributes['id']);
      unset($params['movie']);
      $output .= '<!--[if !IE]>-->' . "\n";
      $output .= '<object' . ckeditor_swf_attributes($attributes) . '>' . "\n";
      $output .= ckeditor_swf_params($params);
      $output .= '<!--<![endif]-->' . "\n";
      $output .= $element['alt'] . "\n";
      $output .= '<!--[if !IE]>-->' . "\n";
      $output .= '</object>' . "\n";
      $output .= '<!--<![endif]-->' . "\n";
      $output .= '</object>';
      $elements[$i]['output'] = $output;
    }
  }

  // Replace text.
  $start = 0;
  $output = '';
  foreach ($elements as $element) {
    $output .= substr($text, $start, $element['start'][1] - $start);
    $output .= $element['output'];
    $start = $element['end'][1] + strlen($element['end'][0]);
  }
  $output .= substr($text, $start);
  if ($js) {
    $output .= "<script type=\"text/javascript\">\n<!--//--><![CDATA[//><!--\n{$js}//--><!]]>\n</script>\n";
  }
  return $output;
}
function ckeditor_swf_parse_attributes($tag) {
  $attributes = array();
  unset($matches);
  if (preg_match_all('`\\b([a-z]+)="(.*?)"`is', $tag, $matches, PREG_SET_ORDER)) {
    foreach ($matches as $match) {
      $attributes[strtolower($match[1])] = decode_entities($match[2]);
    }
  }
  return $attributes;
}
function ckeditor_swf_attributes($attributes) {
  $output = '';
  foreach ($attributes as $name => $value) {
    $output .= ' ' . $name . '="' . check_plain($value) . '"';
  }
  return $output;
}
function ckeditor_swf_params($params) {
  $output = '';
  foreach ($params as $name => $value) {
    $output .= '<param name="' . $name . '" value="' . check_plain($value) . '" />' . "\n";
  }
  return $output;
}
function ckeditor_swf_trim($str) {
  return trim(preg_replace('`\\s+`', ' ', $str));
}
function ckeditor_swf_filename($absolute_url) {
  $prefix = $GLOBALS['base_url'] . '/';
  $len = strlen($prefix);
  if (substr($absolute_url, 0, $len) != $prefix) {
    return FALSE;
  }
  $path = substr($absolute_url, $len);
  if (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PRIVATE) {
    $mode = variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE);
    if ($mode == LANGUAGE_NEGOTIATION_PATH_DEFAULT || $mode == LANGUAGE_NEGOTIATION_PATH) {
      $languages = language_list('enabled');
      $languages = $languages[1];
      $args = explode('/', $path);
      $prefix = array_shift($args);
      foreach ($languages as $language) {
        if (!empty($language->prefix) && $language->prefix == $prefix) {
          $path = implode('/', $args);
          break;
        }
      }
    }
    $prefix = 'system/files/';
    $len = strlen($prefix);
    if (substr($path, 0, $len) != $prefix) {
      return FALSE;
    }
    $path = substr($path, $len);
  }
  return file_create_path($path);
}
function ckeditor_swf_getid3_load() {
  static $success;
  if (!isset($success)) {
    $success = FALSE;

    // Let's rely on the getID3() module to ensure getID3 is properly installed and configured.
    if (module_exists('getid3') && getid3_load(FALSE)) {
      $success = TRUE;
    }
  }
  return $success;
}
function _ckeditor_swf_filter_settings() {
  $form['ckeditor_swf_filter'] = array(
    '#type' => 'fieldset',
    '#title' => t('CKEditor SWF Filter'),
    '#collapsible' => TRUE,
    '#attributes' => array(
      'class' => 'ckeditor-swf-filter-settings',
    ),
  );
  $form['ckeditor_swf_filter']['notice'] = array(
    '#value' => t('<p>These settings are shared by all the input formats where <em>CKEditor SWF Filter</em> is enabled:</p>'),
  );
  $form['ckeditor_swf_filter']['ckeditor_swf_filter_use_swfobject'] = array(
    '#type' => 'checkbox',
    '#title' => t('Use SWFObject'),
    '#default_value' => variable_get('ckeditor_swf_filter_use_swfobject', 0),
    '#description' => t('Check this box if you want SWF content to be embedded using SWFObject instead of the default markup.'),
  );
  $form['ckeditor_swf_filter']['ckeditor_swf_filter_add_swfobject'] = array(
    '#type' => 'checkbox',
    '#title' => t('Add SWFObject'),
    '#default_value' => variable_get('ckeditor_swf_filter_add_swfobject', 0),
    '#description' => t('Check this box if you want <em>CKEditor SWF</em> to add the SWFObject JavaScript file to each page header. Do not check this box if another module is already carrying out this task.'),
  );
  $form['ckeditor_swf_filter']['ckeditor_swf_filter_swfobject_path'] = array(
    '#type' => 'textfield',
    '#title' => t('SWFObject path'),
    '#default_value' => ckeditor_swf_filter_swfobject_path(),
    '#maxlength' => 255,
    '#description' => t('If you checked the box above, enter here the path to the SWFObject JavaScript file. This path must be relative to the Drupal installation directory.'),
    '#after_build' => array(
      'ckeditor_swf_filter_swfobject_path_check',
    ),
  );
  $form['ckeditor_swf_filter']['ckeditor_swf_filter_swfobject_version'] = array(
    '#type' => 'textfield',
    '#title' => t('Flash Player version'),
    '#default_value' => variable_get('ckeditor_swf_filter_swfobject_version', '6.0.65'),
    '#size' => 15,
    '#maxlength' => 15,
    '#description' => t('Enter the Flash Player version your SWFs are published for. Format is <em>major.minor.release</em> or <em>major</em>.'),
  );
  return $form;
}
function ckeditor_swf_filter_swfobject_path_check($form_element, &$form_state) {
  if ($form_state['values']['ckeditor_swf_filter_add_swfobject']) {
    $path = $form_element['#value'];
    if (!file_exists($path)) {
      form_set_error($form_element['#parents'][0], t('The path %path does not exist.', array(
        '%path' => $path,
      )));
    }
  }
  return $form_element;
}
function ckeditor_swf_filter_use_swfobject() {
  return variable_get('ckeditor_swf_filter_use_swfobject', 0) && ckeditor_swf_filter_swfobject_ok();
}
function ckeditor_swf_filter_swfobject_ok() {
  return !variable_get('ckeditor_swf_filter_add_swfobject', 0) || file_exists(ckeditor_swf_filter_swfobject_path());
}
function ckeditor_swf_filter_swfobject_path() {
  return variable_get('ckeditor_swf_filter_swfobject_path', 'sites/all/libraries/swfobject/swfobject.js');
}
function ckeditor_swf_filter_uniqid() {
  return 'swf-' . uniqid(rand());
}

/**
 * Implementation of hook_init().
 */
function ckeditor_swf_init() {
  if (variable_get('ckeditor_swf_filter_add_swfobject', 0) && ckeditor_swf_filter_swfobject_ok()) {
    drupal_add_js(ckeditor_swf_filter_swfobject_path());
  }
}

/**
 * Implementation of hook_ckeditor_plugin().
 */
function ckeditor_swf_ckeditor_plugin() {
  return array(
    'ckeditor_swf' => array(
      'name' => 'swf',
      'desc' => t('CKEditor SWF - Enhanced Flash embedding plugin'),
      'path' => drupal_get_path('module', 'ckeditor_swf') . '/plugins/swf/',
    ),
  );
}

/**
 * Implementation of hook_wysiwyg_plugin().
 */
function ckeditor_swf_wysiwyg_plugin($editor, $version) {
  if ($editor == 'ckeditor') {
    return array(
      'swf' => array(
        'path' => drupal_get_path('module', 'ckeditor_swf') . '/plugins/swf/',
        'load' => TRUE,
        'extensions' => array(
          'Flash' => t('CKEditor SWF'),
        ),
      ),
    );
  }
}
function ckeditor_swf_players() {
  $players = variable_get('ckeditor_swf_players', array());
  foreach ($players as $mime => $player) {
    $path = $player['path'];
    if (file_exists($path)) {
      $players[$mime]['path'] = base_path() . $path;
    }
    else {
      unset($players[$mime]);
    }
  }
  return $players;
}
function ckeditor_swf_getid3_analyze($url) {
  $filename = ckeditor_swf_filename($url);
  if (!$filename) {
    $position = strpos($url, '://');
    $scheme = $position ? substr($url, 0, $position) : FALSE;
    if ($scheme == 'http' || $scheme == 'https') {
      $temp = file_directory_temp();
      $temp_name = tempnam(realpath($temp), 'file');
      $contents = file_get_contents($url, FALSE, NULL, -1, 32768);
      if ($contents && file_put_contents($temp_name, $contents)) {
        $filename = $temp_name;
      }
    }
  }
  if ($filename && ckeditor_swf_getid3_load()) {
    $getid3 = new getID3();
    $info = $getid3
      ->analyze($filename);
  }
  if (isset($temp_name)) {
    file_delete($temp_name);
  }
  return isset($info) ? $info : NULL;
}