You are missing some Flash content that should appear here! Perhaps your browser cannot display it, or maybe it did not initialise correctly.
');
define('SWFTOOLS_PLAYLIST_PATH', 'playlists');
define('SWFTOOLS_PLAYER_PATH', '');
define('SWFTOOLS_GRANT_ACCESS_TO_PRIVATE_FILES', FALSE);
define('SWFTOOLS_GRANT_ACCESS_EXTENSIONS', 'swf flv xml mp3 jpg jpeg png');
define('SWFTOOLS_ALWAYS_ADD_JS', TRUE);
/**
* Implementation of hook_init()
*/
function swftools_init() {
if (variable_get('swftools_always_add_js', SWFTOOLS_ALWAYS_ADD_JS)) {
swftools_push_js();
}
}
/**
* Implementation of hook_menu().
*/
function swftools_menu() {
$items = array();
// Should this be administer swf tools?
$swf_admin = array('administer flash');
$items['admin/settings/swftools'] = array(
'title' => 'SWF Tools',
'description' => 'Settings to control how SWF Tools integrates with Adobe Flash related methods and tools like video players, MP3 players and image viewers.',
'access arguments' => $swf_admin,
'page callback' => 'system_admin_menu_block_page',
'file' => 'system.admin.inc',
'file path' => drupal_get_path('module', 'system'),
);
$items['admin/settings/swftools/handling'] = array(
'title' => 'File handling',
'description' => 'Configure how SWF Tools should handle different types of file.',
'access arguments' => $swf_admin,
'weight' => -1,
'page callback' => 'drupal_get_form',
'page arguments' => array('swftools_admin_handling_form'),
'file' => 'swftools.admin.inc',
);
$items['admin/settings/swftools/embed'] = array(
'title' => 'Embedding settings',
'description' => 'Set the embedding method that SWF Tools should use, and configure embedding defaults.',
'access arguments' => $swf_admin,
'weight' => -2,
'page callback' => 'drupal_get_form',
'page arguments' => array('swftools_admin_embed_form'),
'file' => 'swftools.admin.inc',
);
$items['admin/reports/swftools'] = array(
'title' => 'SWF Tools status',
'description' => 'Get an overview of the status of the SWF Tools module and its supporting files.',
'page callback' => 'swftools_status',
'access arguments' => $swf_admin,
'file' => 'swftools.admin.status.inc',
'weight' => 9,
);
$items = array_merge($items, genericplayers_menu());
return $items;
}
/**
* Implementation of hook_perm().
*/
function swftools_perm() {
return array(
'administer flash',
);
}
/**
* Output a playlist via a flash file. Note that $playlist_data has a specific
* format that will be documented later.
* @param $playlist_data
*
* Not the name of an xml file!
*
*/
function swf_list($playlist_data, $options = array()) {
// For now turn array back in to strings to avoid re-writing rest of code
$params = $options['params'];
$flashvars = $options['flashvars'];
$othervars = $options['othervars'];
$methods = $options['methods'];
if (is_array($playlist_data)) {
if (!$methods) {
$methods = array();
}
$methods['action'] = $playlist_data['action'];
if (!$othervars) {
$othervars = array();
}
$othervars['playlist_data'] = $playlist_data;
if (isset($playlist_data['filename'])) {
$playlist = $playlist_data['filename'];
}
else {
$playlist = '';
}
// Put possibly modified items back in to options array
$options['methods'] = $methods;
$options['othervars'] = $othervars;
//return swf($playlist, $params, $flashvars, $othervars, $methods);
return swf($playlist, $options);
}
else {
// Need to verify the direct xml file method before permitting it.
}
}
/**
* Return output, which might be embed markup, or pre-flash markup
* that includes the appropriate jQuery added to the
*
* @param $file
* The file to be played. If it is a SWF file it will usually be embedded directly.
* Use a full URL, a path relative to webroot, or a path relative to the configured files directory.
* @param $params
* An associative array of variables to set.eg. array('bgcolor'=>'FF00FF')
* To set height and width: array('width'=>'200', 'height'=>'120'). However,
* as a convenient alternative for the common requirement of just height and width
* you can also pass a text string like '200x100'.
* If you pass nothing, and the file to play is a .swf, swftools will try and
* establish a natural width and height from the actual .swf file that you've
* passed into $file.
* @param $flashvars
* An associative array of flashvar variables to set. eg. array('playlist'=>'files/my_playlist.xml')
* @param $othervars
* An associative array of variables that might be required by the $player or $embed technique.
* These values are not output as params or flashvars.
* @param $method
* Explicitly declare an action, player or action by passing an array of
* the form: array('action'=>'dosomething','player'=>'withsomething','embed'=>'withthisjavascript').
* These usually default to the administration settings and also you will
* usually use a CONSTANT which will be documented further at a later stage.
*/
function swf($file, $options = array()) {
// Merge in defaults
$options += array(
'params' => SWFDEFAULT,
'flashvars' => SWFDEFAULT,
'othervars' => SWFDEFAULT,
'methods' => SWFDEFAULT,
);
// For now turn array back in to original strings to avoid re-writing rest of code below
// Can tidy this up later!
$params = $options['params'];
$flashvars = $options['flashvars'];
$othervars = $options['othervars'];
$methods = $options['methods'];
// Get all the actions, tools and embedding options available to us.
$all_methods = swftools_methods_available();
// ACTION
// Explicit action on the $methods parameter?
$action = (isset($methods['action'])) ? $methods['action'] : FALSE;
if (!$action) {
// Still no action?
$action = swftools_get_action($file);
}
// HTML ALTERNATIVE
// Get the html which will be used in case flash cannot be displayed.
$html_alt = ($othervars['html_alt']) ? $othervars['html_alt'] : variable_get('swftools_html_alt', SWFTOOLS_DEFAULT_HTML_ALT);
// 'resolved' refers to the fact that these are the methods we
// intend to use, not /all/ methods available.
$resolved_methods = new stdClass();
// PLAYER
// Explicit player on the $methods parameter?
$player = (isset($methods['player'])) ? $methods['player'] : FALSE;
if (!$player) {
// Still no player?
$player = swftools_get_player($action);
if (!$player) {
$descriptions = array(
SWFTOOLS_IMAGE_DISPLAY_LIST=> 'a series of images',
SWFTOOLS_FLV_DISPLAY=> 'a single flv file',
SWFTOOLS_FLV_DISPLAY_LIST=> 'a series of flv files',
SWFTOOLS_MP3_DISPLAY=> 'a single mp3 file',
SWFTOOLS_MP3_DISPLAY_LIST=> 'a series of mp3 files',
SWFTOOLS_MEDIA_DISPLAY_LIST=> 'a series mixed media files',
);
if (isset($descriptions[$action])) {
drupal_set_message(t('No player is configured to play '.$descriptions[$action].'. Check the SWF Tools file handling settings on the configuration page.'), 'error');
} else {
drupal_set_message(t('No player is configured for the action %action. Check the SWF Tools file handling settings on the configuration page.', array('%action' => $action)), 'error');
}
// We pass back the alternative html to be displayed as is.
return $html_alt;
}
}
// Assign the player info.
if (isset($all_methods[$action][$player])) {
$resolved_methods->player = $all_methods[$action][$player];
}
else {
if ($action == SWFTOOLS_SWF_DISPLAY_DIRECT) {
// We seem to have a custom player. We make the method custom and assign the player.
$resolved_methods->player = $all_methods[$action][SWFTOOLS_CUSTOM];
$resolved_methods->player['shared_file'] = $player; // Don't check existence of player file.
}
else {
// All else fails ...
drupal_set_message(t('Could not find the %player file for embedding.', array('%player' => $player)), 'error', FALSE);
return $html_alt;
}
}
// EMBED
// Explicit embed strategy on the $methods parameter?
$embed = (isset($methods['embed'])) ? $methods['embed'] : FALSE;
if (!$embed) {
// Still not sure?
$embed = variable_get(SWFTOOLS_EMBED_METHOD, SWFTOOLS_NOJAVASCRIPT);
}
// Assign the embed info.
$resolved_methods->embed = $all_methods[SWFTOOLS_EMBED_METHOD][$embed];
// Put all the variables on a simple object to make internal function calls simpler.
$vars = new stdClass();
// OTHERVARS
$vars->othervars = (is_array($othervars)) ? $othervars : array();
// PARAMS
// params could be an associative array, or in 'WIDTHxHEIGHT' format.
if ($params) {
if (is_array($params)) {
$vars->params = $params;
}
else {
$dimensions = explode('x', $params);
if (count($dimensions) == 2) {
$vars->params = array('width' => $dimensions[0], 'height' => $dimensions[1]);
}
}
}
else {
$vars->params = array();
}
// FLASHVARS
// flashvars could be an associative array, or in 'a=1&b=2' format.
if ($flashvars) {
if (is_array($flashvars)) {
$vars->flashvars = $flashvars;
}
else {
// Parse the string as if in 'a=1&b=2' format.
parse_str($flashvars, $vars->flashvars);
}
}
else {
$vars->flashvars = array();
}
// BASE
// Determine a reasonable 'base' directory, if a remote url is set, use that
// If file is local, set to the file directory
$base = ($vars->params['base']) ? $vars->params['base'] : '';
if (!$base || !valid_url($base)) {
// swftools_get_media_url() returns remote path if it is set,
$base = swftools_get_media_url('', FALSE);
}
$vars->params['base'] = $base;
// PLAYLIST
if (isset($othervars['playlist_data'])) {
// Generate a playlist and receive a file path in return.
// This file name will be relative webroot
$playlist = TRUE; // Flag it's a playlist.
$file = swftools_generate_playlist($othervars['playlist_data'], $playlist_name, $resolved_methods, $vars, FALSE);
if (!$file) {
drupal_set_message(t('Unable to create playlist.'), 'error');
return $html_alt;
}
}
$nocache = '';
if (variable_get('swftools_playlist_caching', 'here') == 'always') {
// Not currently working. Sometimes you may see xml caching.
$nocache = '?nc='. time();
}
// FILE
// Process the file if not already a full url
if (!valid_url($file, TRUE)) {
// If we have a file and not a playlist
if (!$playlist) {
// Then if files are local ensure it is a properly formatted path
if (swftools_get_media_path()) {
$file = file_create_path($file);
}
}
// Try to turn $file in to a complete url
$file_url = swftools_get_media_url($file);
// If $file_url was not generated then file doesn't exist so return $html_alt
if (!$file_url) {
return $html_alt;
}
// Append $nocache string to complete the url
$file_url = $file_url . $nocache;
}
else {
// We already had a url, so set $file_url to $file
$file_url = $file;
}
// Attach file_url to othervars so player modules have access if required
$vars->othervars['file_url'] = $file_url;
// Determine the "src" attribute of the embed (also applies to the 'movie' attribute).
// Usually this is the Flash Player, but it can also be a swf file, or a custom file
// passed on othervars['shared_file'].
switch ($player) {
case SWFTOOLS_SWF:
// The original file is the src file.
$vars->params['src_path'] = $file;
$vars->params['src'] = $file_url;
break;
case SWFTOOLS_CUSTOM:
$vars->params['src_path'] = $resolved_methods->player['shared_file']; // May need the local path for dimensions.
$vars->params['src'] = swftools_get_media_url($resolved_methods->player['shared_file']);
break;
default:
$vars->params['src_path'] = swftools_get_player_path() .'/'. $resolved_methods->player['shared_file'];
$vars->params['src'] = $GLOBALS['base_url'] .'/'. swftools_get_player_path() .'/'. $resolved_methods->player['shared_file'];
}
// Merge default and user defined "params".
$vars->params = array_merge(_swftools_params(), $vars->params);
// Ask the module implementing the player what flashvars are required, pass
// all existing values by reference to allow optional override at the player.module level.
$player_flashvars = call_user_func_array($resolved_methods->player['module'] .'_swftools_flashvars', array($action, &$resolved_methods, &$vars));
$vars->flashvars = array_merge($vars->flashvars, $player_flashvars);
// Apply the values as requested by the player.module (if applicable).
if (isset($resolved_methods->player['file'])) {
$vars->flashvars[$resolved_methods->player['file']] = $file_url;
}
if (isset($resolved_methods->player['version'])) {
$vars->params['version'] = $resolved_methods->player['version'];
}
// Not a pretty piece of code, but should be ok for the moment. We are
// purposefully passing the width and height
// if we have them. Unsure if this will cause problems with some players.
// It's an ugly piece of code, but will remain in this form until a clearer
// solution arises.
//
// It may be that, in hook_swftools_methods, the flash player indicates that
// it *want* certain values copied b/t params and flashvars.
//
if (!$vars->flashvars['width'] && !$vars->flashvars['height']) {
if ($vars->params['width'] && $vars->params['height']) {
$vars->flashvars['width'] = $vars->params['width'];
$vars->flashvars['height'] = $vars->params['height'];
}
}
if (!$vars->params['width'] && !$vars->params['height']) {
if ($vars->flashvars['width'] && $vars->flashvars['height']) {
$vars->params['width'] = $vars->flashvars['width'];
$vars->params['height'] = $vars->flashvars['height'];
}
}
// If still empty, we try and get them from the file to be embedded.
if (empty($vars->params['height']) && empty($vars->params['width'])) {
$info = swftools_get_info($vars->params['src_path']);
if ($info) {
$vars->params['height'] = $info['height'];
$vars->params['width'] = $info['width'];
};
}
// Build a string out of the flashvars array.
$vars->params['flashvars'] = _swftools_get_flashvars_string($vars->flashvars);
// Call the embedding code to get the html and set the javascript if necessary.
$output = module_invoke($resolved_methods->embed['module'], 'swftools_embed', $action, $resolved_methods, $vars, $html_alt);
// The $html code is already built, but allow it to be changed.
return theme('swftools_embed', $output, $action, $resolved_methods, $vars, $preview);
}
function theme_swftools_embed($embed_code, $action, $methods, $vars, $html_alt) {
// Generate a css id if possible.
$id = ($vars->othervars['id']) ? ' id="swf-'. $vars->othervars['id'] .'"' : '';
$classes[] = 'swftools-wrapper';
$classes[] = str_replace('_', '-', $methods->player['name']);
$classes[] = $vars->othervars['class'];
return ''. $embed_code .'
';
}
/**
* Collect information from all modules about the Flash players, tools and scripts
* available for various actions.
*
*/
function swftools_methods_available($action = NULL, $reset = FALSE) {
// Cache methods array.
static $methods = array();
if ($reset) {
$methods = array();
}
elseif (count($methods)) {
return ($action) ? $methods[$action] : $methods;
}
// Gather methods.
foreach (module_implements('swftools_methods') AS $mod) {
$methods = array_merge_recursive($methods, call_user_func($mod .'_swftools_methods'));
}
$methods = array_merge_recursive($methods, genericplayers_swftools_methods());
// This module implements a default plain HTML embedding method called 'direct'
$methods[SWFTOOLS_EMBED_METHOD][SWFTOOLS_NOJAVASCRIPT] = array(
'name' => SWFTOOLS_NOJAVASCRIPT,
'module' => 'swftools',
'shared_file' => '',
'title' => t('Direct embedding - do not use JavaScript replacement'),
);
// This module implements swf embedding
$methods[SWFTOOLS_SWF_DISPLAY_DIRECT][SWFTOOLS_SWF] = array(
'name' => SWFTOOLS_SWF,
'module' => 'swftools',
'shared_file' => '',
'title' => t('Use SWF file directly, no streaming through another SWF.'),
);
$methods[SWFTOOLS_SWF_DISPLAY_DIRECT][SWFTOOLS_CUSTOM] = array(
'name' => SWFTOOLS_CUSTOM,
'module' => 'swftools',
'shared_file' => '', // Assigned later.
'title' => t('Use custom SWF file.'),
);
return ($action) ? $methods[$action] : $methods;
}
function swftools_json_params(&$params, $attr = 'swftools') {
return $attr ."='". drupal_to_js($params) ."'";
}
/**
* Implementation of swftools_flashvars hook
* For a random swf file there are no vars to add.
*/
function swftools_swftools_flashvars($action, &$methods, &$vars) {
return $vars->flashvars;
}
/**
* Returns 'true' or 'false' for javascript based on 0,1,TRUE,FALSE etc
*/
function _swftools_tf($bool) {
// String 'false' is treated as TRUE in PHP logic, so force to FALSE
if (strtolower($bool) == 'false') {
$bool = FALSE;
}
// Return 'true' or 'false' now we are sure of result
return $bool ? 'true' : 'false';
}
/**
* Identify the best action based on the file type that is passed
*/
function swftools_get_action($file) {
// Try to determine the action based on the file extension.
$path_parts = pathinfo($file);
switch (strtolower($path_parts['extension'])) {
case 'flv':
return SWFTOOLS_FLV_DISPLAY;
case 'swf':
return SWFTOOLS_SWF_DISPLAY_DIRECT;
case 'mp3':
return SWFTOOLS_MP3_DISPLAY;
case 'jpg': case 'gif': case 'png': case 'jpeg': case 'img':
return SWFTOOLS_IMAGE_DISPLAY_LIST;
default:
// Make a broad assumption that the configured mediaplayer will handle
// this file or playlist.
return SWFTOOLS_MEDIA_DISPLAY_LIST;
}
}
/**
* Identify the best flash player based on the chosen action.
* In a couple of cases we have a built-in default, but FALSE indicates
* that no default player is configured.
*/
function swftools_get_player($action, $part = FALSE) {
$methods = swftools_methods_available($action);
switch ($action) {
case SWFTOOLS_FLV_DISPLAY:
return variable_get(SWFTOOLS_FLV_DISPLAY, GENERIC_FLV);
case SWFTOOLS_MP3_DISPLAY:
return variable_get(SWFTOOLS_MP3_DISPLAY, GENERIC_MP3);
case SWFTOOLS_SWF_DISPLAY_DIRECT:
return variable_get(SWFTOOLS_SWF_DISPLAY_DIRECT, SWFTOOLS_SWF);
default:
return variable_get($action, FALSE);
}
}
/**
* Returns the playlist path relative to webroot.
* This path needs to be writeable, so it is fitting to limit valid
* locations to the files directory.
*
*/
function swftools_get_playlist_path($dir = FALSE) {
// If no directory specified, get the default
if (!$dir) {
$dir = variable_get('swftools_playlist_path', SWFTOOLS_PLAYLIST_PATH);
}
// Ensure we have a path in the file system
$dir = file_create_path($dir);
// Create playlist directory if necessary
if (!file_check_directory($dir, FILE_CREATE_DIRECTORY)) {
drupal_set_message(t('%dir does not exist, or is not writeable.', array('%dir' => $dir)), 'error', FALSE);
}
// Return path to the playlist directory
return $dir;
}
/**
* Returns a flash player path relative to webroot. The default value is
* in the modules/swftools/shared directory.
* It may suit some sites to store flash players in an alternative location, but
* the assumption is the location will be on the same server.
* If the path starts with '/', then we can assume is relative to the webroot.
* Otherwise we assume it's in the files directory.
*
*/
function swftools_get_player_path($dir = FALSE) {
if (!$dir) {
$dir = variable_get('swftools_player_path', SWFTOOLS_PLAYER_PATH);
if (!$dir) {
$dir = drupal_get_path('module', 'swftools') .'/shared';
}
}
elseif (substr($dir, 0, 1) == '/') {
$dir = ltrim($dir, '/');
}
else {
$dir = file_create_path($dir);
}
return $dir;
}
/**
* Returns the media path relative to webroot.
* There is a setting 'swftools_media_url', if this is set, we assume the
* media is on a different server, and we don't change the path or check for the
* existence of the media.
* Otherwise we assume the path is inside the files directory.
*
*/
function swftools_get_media_path() {
$url = trim(variable_get('swftools_media_url', ''));
if (!$url || $url == '') {
return file_create_path('');
}
// A remote server is set, so we do not know anything about
// the path between the base url and the file.
return '';
}
/**
* Resolved a path to a full url. The path must be relative to the webroot.
* We check for the existence if a file is the follow is true:
* - swftools_media_url is empty, and hence the local server is assumed.
* - $is_file is TRUE. (You can set this to FALSE if you know the check will fail, like a dynamic playlist.)
* - swftools_check_media is TRUE
*
*/
function swftools_get_media_url($path, $is_file = TRUE) {
$media_url = trim(variable_get('swftools_media_url', ''));
if ($media_url) {
// We do nothing with a remote media file.
return "$media_url/$path";
}
if (variable_get('swftools_check_media', TRUE) && $is_file) {
if (file_exists($path)) {
return file_create_url($path);
}
else {
drupal_set_message(t('Could not display the flash because %path does not appear to exist.', array('%path' => $path)), 'error');
return FALSE;
}
}
else {
return file_create_url($path);
}
}
/**
* "flashvars" is a parameter like height and width, which are
* passed into the flash player as a=1&b=2&...
*
*/
function _swftools_get_flashvars_string(&$flashvars) {
foreach ($flashvars AS $var => $value) {
$flashvars[$var] = str_replace(array('&', '=', '?'), array('%26', '%3D', '%3F'), $value);
}
$encoded = drupal_query_string_encode($flashvars);
// '#' seems to encode as %2523, reverse this, using a more robust hex prefix..
$encoded = str_replace('%2523', '0x', $encoded);
// Fix encoding per #181998#comment-882293
$encoded = str_replace('%3A', ':', $encoded);
$encoded = str_replace('%252F', '/', $encoded);
return $encoded;
}
/**
* These are the default params.
*
*/
function _swftools_params() {
$defaults = array(
'swliveconnect' => variable_get('swftools_params_swliveconnect', 'default'),
'play' => variable_get('swftools_params_play', TRUE),
'loop' => variable_get('swftools_params_loop', FALSE),
'menu' => variable_get('swftools_params_menu', FALSE),
'quality' => variable_get('swftools_params_quality', 'autohigh'),
'scale' => variable_get('swftools_params_scale', 'showall'),
'align' => variable_get('swftools_params_align', 'l'),
'salign' => variable_get('swftools_params_salign', 'tl'),
'wmode' => variable_get('swftools_params_wmode', 'opaque'),
'bgcolor' => variable_get('swftools_params_bgcolor', '#FFFFFF'),
'version' => variable_get('swftools_params_version', '7'),
'allowfullscreen' => variable_get('swftools_params_allowfullscreen', TRUE),
);
$defaults['menu'] = _swftools_tf($defaults['menu']);
$defaults['play'] = _swftools_tf($defaults['play']);
$defaults['loop'] = _swftools_tf($defaults['loop']);
$defaults['allowfullscreen'] = _swftools_tf($defaults['allowfullscreen']);
return $defaults;
}
/**
* Attempt to return information for the specified file
* Supply the path to the file to be processed, and it return FALSE if no data
* was obtained. The return variable, if successful, is an array that may
* include width, height, extension, file_size, mime_type.
*
*/
function swftools_get_info($file) {
// Only check the file if it is local.
if (trim(variable_get('swftools_media_url', '')) == '') {
$info = image_get_info($file);
return $info;
}
return FALSE;
}
/**
* Saves a playlist/xml file to a directory ready for the browser callback.
* Data must be formatted correctly, see docs (link to come)
*
*/
function swftools_generate_playlist(&$playlist_data, $playlist_name, &$method, &$vars) {
// It pays to pass your own filename, if possible, to avoid too much md5 hashing.
if (!$playlist_name) {
$prename = '';
foreach ($playlist_data['playlist'] AS $data) {
$prename .= $data['filename'];
}
$playlist_name = md5($method->player['name'] . $prename) .'.xml';
}
$playlist_name = swftools_get_playlist_path() ."/$playlist_name";
if (variable_get('swftools_playlist_caching', 'here') == 'always') {
// Settings dictate we should always overwrite the playlist.
file_delete($playlist_name);
}
elseif (is_file($playlist_name)) {
return $playlist_name;
}
// Get the playlist/xml formatted to the player's taste.
$func = 'swftools_'. $method->player['name'] .'_playlist';
if (function_exists($func)) {
$playlist = call_user_func($func, $playlist_data, $method, $vars);
}
else {
drupal_set_message(t('@title module does not support xml playlists.', array('@title' => $method->player['title'])), 'error');
}
// Open file.
if (!$handle = fopen($playlist_name, 'a')) {
drupal_set_message(t('An error occurred trying to create file %playlist_name.', array('%playlist_name' => $playlist_name)), 'error');
return FALSE;
}
// And write to the file.
if (fwrite($handle, $playlist) === FALSE) {
drupal_set_message(t('An error occurred trying to create file %playlist_name.', array('%playlist_name' => $playlist_name)), 'error');
return FALSE;
}
fclose($handle);
return $playlist_name;
}
function swftools_push_js($embed = SWFDEFAULT) {
$all_methods = swftools_methods_available();
if (!$embed) {
$embed = variable_get(SWFTOOLS_EMBED_METHOD, SWFTOOLS_NOJAVASCRIPT);
}
$embed = $all_methods[SWFTOOLS_EMBED_METHOD][$embed];
// Call the module responsible to output the js. Don't pass any additional
// parameters - as we don't want the module to try and return the in-body
// html placeholder for the flash content.
$output = module_invoke($embed['module'], 'swftools_embed');
}
/**
* This function is a work in progress.
*
* Sent through array of files (simple), or an
* If $action is missing then we try to work it out.
*
*/
function swftools_prepare_playlist_data($files, $title = '', $get_action = TRUE, $type_filter = array()) {
$playlist_data = array();
$playlist_data['header']['title'] = $title;
// Run through all $files and and make the data look the same.
$id = 0;
foreach ($files AS $key => $data) {
while (array_key_exists($id, $files)) {
$id++;
}
if (is_object($data)) {
$files[$key] = (array)$data;
}
elseif (!is_array($data)) {
// Move this file name to a new key to give it the structure of a file attachment array
$files[$id]['filepath'] = $data;
if (!is_numeric($key)) {
$files[$id]['filename'] = $key;
}
else {
$files[$id]['filename'] = $data;
}
unset($files[$key]);
}
}
// Check the fileurl element and add generate it if it's missing.
$playlist_data['playlist'] = $files;
foreach ($files AS $key => $data) {
if (!isset($data['fileurl'])) {
if (valid_url($data['filepath'], TRUE)) {
// A full http:// file path has been passed.
$playlist_data['playlist'][$key]['filepath'] = FALSE; // Flag that we don't know the server path.
$playlist_data['playlist'][$key]['fileurl'] = $data['filepath'];
}
elseif (isset($data['fid'])) {
// This is a classes upload module files array.
$playlist_data['playlist'][$key]['filename'] = $data['filename'];
$playlist_data['playlist'][$key]['fileurl'] = swftools_get_media_url($playlist_data['playlist'][$key]['filepath'], FALSE);
}
else {
// Otherwise just complete url path.
$playlist_data['playlist'][$key]['filename'] = $data['filename'];
$playlist_data['playlist'][$key]['filepath'] = swftools_get_media_path() .'/'. $data['filepath'];
$playlist_data['playlist'][$key]['fileurl'] = swftools_get_media_url($playlist_data['playlist'][$key]['filepath']);
}
}
if (!isset($data['filename'])) {
$path_parts = pathinfo($playlist_data['playlist'][$key]['fileurl']);
$playlist_data['playlist'][$key]['filename'] = $path_parts['basename'];
}
if (!isset($data['title'])) {
$playlist_data['playlist'][$key]['title'] = $playlist_data['playlist'][$key]['filename'];
}
// Here is where you might call audio.module or video.module for more.
}
// Note, we want to exit quickly if the caller did not want us to
// dynamically determine the display action by passing $action = FALSE.
if (!$get_action) {
// The caller knows what swftools action to set, so exit here.
return $playlist_data;
}
else {
// Try to work out the action from the files passed.
$first_valid_file_type = FALSE;
$mixed_media = FALSE;
$fids = array();
// Process the files attached to the node to determine the correct action.
foreach ($playlist_data['playlist'] AS $key => $data) {
$path_parts = pathinfo($data['filepath']);
$extension = strtolower($path_parts['extension']);
if (strpos('|jpg|jpeg|gif|png|', $extension)) {
// Treat all types of images as the same file type.
$extension = 'img';
}
// Only process the file if $type_filter is empty (ie. no filter)
// or if the extension is declared in the $file_types array.
if (!count($type_filter) || in_array($extension, $type_filter)) {
// $first_valid_file_type stores the file type of the first valid file.
// This will be compared to subsequent files and if two files
// have different types, the action will be defined as SWFTOOLS_MEDIA_DISPLAY_LIST
// in order to utilize a flexible media player.
if (!$first_valid_file_type) {
$first_valid_file_type = $extension;
}
else {
if ($first_valid_file_type != $extension) {
$mixed_media = TRUE;
}
}
}
else {
// this file is not desired. squash it.
unset($playlist_data['playlist'][$key]);
}
}
// Make a decision based on analysing the file array.
if ($first_valid_file_type == '') {
// No files passed our test.
return FALSE;
}
// Determine the required action.
if ($mixed_media) {
// We have files of multiple types.
$action = SWFTOOLS_MEDIA_DISPLAY_LIST;
}
else {
// We only had one file type, so make up a pretend file name based on
// the discovered file type and find out the default action for this file type.
$action = swftools_get_action('dummy.'. $first_valid_file_type);
}
// Pluralize the action if multiple files, and if not already pluralized.
if (count($playlist_data['playlist']) > 1 && substr($action, -5, 5) != '_list') {
$action = $action .'_list';
}
// Assign the action we've derived.
$playlist_data['action'] = $action;
return $playlist_data;
}
}
/**
* Next three filter related code ported from flash_filter.
*
*/
/*
* Implementation of hook_filter_tips
*
*/
function swftools_filter_tips($delta, $format, $long = false) {
if ($long) {
return t('
The basic syntax for embedding a flash file (.swf), flash movie (.flv) or audio file (.mp3) is:
<swf file="filename.swf">
If you would like to override SWF Tools and flash player default settings,
you can specify additional parameters. For example:
<swf file="song.mp3" flashvars="backcolor=#AABBCC&&forecolor=#11AA11">
If you would like to output a list of files then the format is:
<swf files="image1.jpg&&image2.jpg&&...">
SWF Tools Filter will accept following:
- params : You can specify values for parameters to be passed to Flash
to control the appearance of the output. Typical values are
bgcolor and wmode. Example:
params="wmode=true&&bgcolor="#00FF00"
Alternatively you can supply each parameter individually without using
params
. Example wmode="true" bgcolor="#00FF00"
- flashvars : You can specify values for output as flashvars, which
become available to the Flash movie that is playing. This is often done
to control a media player. Refer to the documentation of the flash player
you are using to know what flashvar options are available.
Example:
flashvars="autostart=true&&volume=80"
- methods : Optional information about how to display the file. The most
common usage is to specify a particular media player and
thus override the default specified on the settings page.
Example:
methods="player=onepixelout_mp3"
WARNING: with params, flashvars and othervars, pass multiple values
separated by &&.
');
}
else {
return t('You may use !swftools_filter_help to display Flash files inline', array("!swftools_filter_help" => l('', "filter/tips/$format", array('query' => 'swftools_filter'))));
}
}
/*
* Implementation of hook_filter
*
*/
function swftools_filter($op, $delta = 0, $format = -1, $text = '') {
switch ($op) {
case 'list':
return array(0 => t('SWF Tools filter'));
case 'no cache':
return FALSE;
//return TRUE;
case 'description':
return t('Substitutes or with embedding code.');
case 'prepare':
// replace with [swf ] to prevent other filters stripping
return (preg_replace('/\<(swflist|swf)\s*(.*)>/sU', '[\1 \2]', $text));
case 'process':
return _swftools_filter_process_text($text);
}
}
/*
* This function processes the filter text that the user has added to the text area.
* If the filter is wrapped in then these are stripped as part of the processing
* This eliminates a validation error in the resulting mark up if SWF Tools filter is
* being used in conjunction with other HTML filters that correct line breaks.
* It won't work in EVERY case, but it will work in MOST cases.
* Filters that are embedded in-line with text will continue to fail validation.
*/
function _swftools_filter_process_text($text) {
$endl = chr(13) ;
if (preg_match_all('@(?:)?\[(swflist|swf) (.*?)\](?:
)?@s', $text, $match)) {
// $match[0][#] .... fully matched string
// $match[1][#] .... matched tag type ( swf | swflist )
// $match[2][#] .... full params string until the closing '>'
$swftools_parameters = array('file', 'params', 'flashvars', 'othervars', 'methods', 'files');
$match_vars = array();
foreach ($match[2] as $key => $passed_parameters) {
preg_match_all('/\s+?(\w*)=[\"](.*?)[\"]#?/', $passed_parameters, $match_vars[$key]);
// $match_vars[0][#] .... fully matched string
// $match_vars[1][#] .... matched parameter, eg flashvars, params
// $match_vars[2][#] .... value after the '='
// Process the parameters onto the $prepared array.
// Search for standard parameters, parse the values out onto the array.
foreach ($match_vars[$key][1] as $vars_key => $vars_name) {
// Switch to swf or swflist, based on file or files
// Need to tidy up this line, probably use switch/case
if ($vars_name == 'file') {
$match[1][$key] = 'swf';
} else {
if ($vars_name == 'files') {
$match[1][$key] = 'swflist';
}
}
if ($vars_name == 'file') {
$prepared[$key][$vars_name] = $match_vars[$key][2][$vars_key];
unset ($match_vars[$key][1][$vars_key]);
}
elseif (in_array($vars_name, $swftools_parameters)) {
$prepared[$key][$vars_name] = swftools_url_parse(str_replace(array('&&', '&&'), '&', $match_vars[$key][2][$vars_key]));
unset ($match_vars[$key][1][$vars_key]);
}
else {
$prepared[$key]['othervars'][$vars_name] = $match_vars[$key][2][$vars_key];
}
}
// Search for remaining parameters, map them as elements of the standard parameters.
if (isset($prepared[$key]['methods']['player'])) {
$player = strtolower($prepared[$key]['methods']['player']);
}
else {
$player_key = array_search('player', $match_vars[$key][1]);
if ($player_key!==FALSE) {
$player = strtolower($match_vars[$key][2][$player_key]);
}
else {
$player = FALSE;
}
}
$prepared[$key]['methods']['player'] = $player;
if (count($match_vars[$key][1])) {
// Find out if a player has been set.
foreach ($match_vars[$key][1] as $vars_key => $vars_name) {
if ($parent = swftools_get_filter_alias($vars_name, $player)) {
if ($parent) {
$prepared[$key][$parent][$vars_name] = $match_vars[$key][2][$vars_key];
}
}
}
}
// Just assigning parameters as false if not already set on the $prepared array.
// Really just to avoid declaration warnings when we call swf and swf_list
if (count($prepared[$key])) {
foreach ($swftools_parameters AS $swfparameter) {
if (!isset($prepared[$key][$swfparameter])) {
$prepared[$key][$swfparameter] = FALSE;
}
}
}
// Assemble in to an array of options ready to pass
$options = array();
$options['params'] = $prepared[$key]['params'];
$options['flashvars'] = $prepared[$key]['flashvars'];
$options['othervars'] = $prepared[$key]['othervars'];
$options['methods'] = $prepared[$key]['methods'];
switch ($match[1][$key]) {
case 'swf':
$replace = swf($prepared[$key]['file'], $options);
break;
case 'swflist':
if ($prepared[$key]['files']) {
foreach ($prepared[$key]['files'] AS $name => $filename) {
if (!$filename) {
$prepared[$key]['files'][$name] = $name;
}
}
$playlist_data = swftools_prepare_playlist_data($prepared[$key]['files']);
$replace = swf_list($playlist_data, $options);
}
else {
$replace = '';
}
break;
}
$matched[] = $match[0][$key];
$rewrite[] = $replace;
}
return str_replace($matched, $rewrite, $text);
}
return $text;
}
/*
* This implements a hook that extends the parameters that can be passed to the filter
* so that myvar="value" can be mapped to flashvars, etc.
*
*/
function swftools_get_filter_alias($var, $player = FALSE) {
static $general_mapping = array();
static $player_mapping = array();
if (!count($general_mapping)) {
// Build up the mapping arrays.
$general_mapping = array(
'action' => 'methods',
'embed' => 'methods',
'width' => 'params',
'height' => 'params',
'swliveconnect' => 'params',
'play' => 'params',
'loop' => 'params',
'menu' => 'params',
'quality' => 'params',
'scale' => 'params',
'align' => 'params',
'salign' => 'params',
'wmode' => 'params',
'bgcolor' => 'params',
'base' => 'params',
'version' => 'params',
'allowfullscreen' => 'params',
);
if (!count($player_mapping)) {
$player_mapping = module_invoke_all('swftools_variable_mapping');
}
$combined = array();
if (count($player_mapping)) {
foreach($player_mapping AS $mapping) {
$combined = array_merge($combined, $mapping);
}
$general_mapping = array_merge($combined, $general_mapping);
}
}
// Return the parent of the variable.
if ($player && isset($player_mapping[$player][$var])) {
return $player_mapping[$player][$var];
}
else {
return (isset($general_mapping[$var])) ? $general_mapping[$var] : FALSE;
}
}
function swftools_url_parse($string) {
$return = array();
$pairs = split("&", $string);
foreach($pairs as $pair) {
$splitpair = split("=", $pair);
if(!$splitpair[1] || array_key_exists($splitpair[0], $return)) {
$return[] = $splitpair[0];
}
else {
$return[$splitpair[0]] = $splitpair[1];
}
}
return $return;
}
/**
* Implementation of hook_theme
*/
function swftools_theme() {
return array(
'swftools_embed' => array(
'arguments' => array('embed_code' => NULL, 'action' => NULL, 'methods' => NULL, 'vars' => array(), 'html_alt' => NULL),
),
);
}
/**
* Implementation of hook_file_download
* Allows SWF Tools to work with a private file system that might include files
* upload outside the control of an upload module, e.g. FTP of large video files
* If the file is in the playlists directory then return a valid header.
* If the file is of a supported type, based on extension, then return a valid header.
* Note: if any other module returns -1 for this file then access will be denied
* even if SWF Tools tries to allow it. See hook_file_download for details.
*/
function swftools_file_download($file) {
// See if we have a playlist - SWF Tools can allow access to those since it creates them
$playlist_path = preg_quote(variable_get('swftools_playlist_path', SWFTOOLS_PLAYLIST_PATH));
if (preg_match('/^'.$playlist_path.'/', $file)) {
return array(
'Content-Type: '. $mime_types[$extension],
'Content-Length: '. filesize(file_create_path($file)),
);
}
// If SWF Tools is allowed to grant access then check to see if access will be allowed
if (variable_get('swftools_grant_access_to_private_files', SWFTOOLS_GRANT_ACCESS_TO_PRIVATE_FILES)) {
// Get extension of file in question
$extension = pathinfo($file, PATHINFO_EXTENSION);
// Get list of extensions that SWF Tools can grant access to
$extensions = variable_get('swftools_grant_access_extensions', SWFTOOLS_GRANT_ACCESS_EXTENSIONS);
// Need access to the user object
global $user;
// Check if SWF Tools should grant access - skip the check for user #1
if ($user->uid != 1) {
$regex = '/\.('. ereg_replace(' +', '|', preg_quote($extensions)) .')$/i';
if (!preg_match($regex, $file)) {
return;
}
}
// Build an array of types that SWF Tools can react to
$mime_types = array(
'swf' => 'application/x-shockwave-flash',
'flv' => 'application/octet-stream',
'xml' => 'text/xml',
'mp3' => 'audio/mpeg',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'png' => 'image/gif',
);
// If file is one of the above types, based on the extension, return headers
if ($mime_types[$extension]) {
return array(
'Content-Type: '. $mime_types[$extension],
'Content-Length: '. filesize(file_create_path($file)),
);
}
}
}
/**
* Implementation of swftools_embed hook
* Returns the markup for the page.
* This method generates standards compliant HTML
*
*/
function swftools_swftools_embed($action = 'add_js', $methods = FALSE, $vars = FALSE, $html_alt = '') {
if ($action == 'add_js') {
// No javascript stuff for this embed method to do.
return;
}
// IE6 says the page has error when using Wijering 4 media player and if the object isn't given an id
// The id must be unique for each player, and must start with letters - it cannot be only numbers
// So let's generate a unique id in the same way we do with SWF Object, and assign it to our object
$wijering_fix = '';
// Initialise a counter to give each div a unique id
static $unique_id = 0;
$unique_id++;
// Construct a unique id for each div by using time() combined with $unique_id
// This is necessary to prevent clashes between cached content
$id = time() . $unique_id;
$wijering_fix = ' id="swf' . $id . '"';
$P = $vars->params; // For legibility.
$width_attr = ($P['width']) ? ' width="'. $P['width'] .'"' : '';
$height_attr = ($P['height']) ? ' height="'. $P['height'] .'"' : '';
$loop = _swftools_tf($P['loop']);
$menu = _swftools_tf($P['menu']);
$play = _swftools_tf($P['play']);
$fullscreen = _swftools_tf($P['allowfullscreen']);
$flashvars = str_replace('&', '&', $P['flashvars']);
$id = ($vars->othervars['id']) ? ''."\n" : '';
$name = ($vars->othervars['id']) ? ' name="'. $vars->othervars['id'] .'"' : '';
$swliveconnect = ($P['swliveconnect']) ? ' swliveconnect="'. $P['swliveconnect'] .'"' : '';
$params = $id;
$params .= ''."\n" ;
$params .= ''."\n" ;
$params .= ''."\n" ;
$params .= ''."\n" ;
$params .= ''."\n" ;
$params .= ''."\n" ;
$params .= ''."\n" ;
$params .= ''."\n" ;
$params .= ''."\n" ;
$params .= ''."\n" ;
$params .= ''."\n" ;
$params .= $flashvars ? ''."\n" : '' ;
$html = '' . "\n";
return $html;
}
/*
* Called by settings pages for players as a custom handler in place of system_settings_form_submit()
* It flattens extensive arrays of settings, and resets the filter cache
*/
function swftools_admin_form_submit($form, &$form_state) {
$op = isset($form_state['values']['op']) ? $form_state['values']['op'] : '';
// Flatten settings for saving
$saved = array();
foreach ($form_state['values'] AS $player => $settings) {
if ($op == t('Reset to defaults')) {
variable_del('swftools_'. $player);
} else {
$flat[$player] = array();
if (is_array($settings)) {
foreach ($settings AS $category => $vars) {
$flat[$player] = array_merge($flat[$player], $vars);
}
variable_set('swftools_'. $player, $flat[$player]);
}
}
}
// Confirmation message
if ($op == t('Reset to defaults')) {
drupal_set_message(t('The configuration options have been reset to their default values.'));
} else {
drupal_set_message(t('The configuration options have been saved.'));
}
// Clear caches
drupal_flush_all_caches();
}