TRUE))); // A generic image for use in certain contexts. // Let other modules know SWF Tools is available define('SWFTOOLS_INSTALLED', TRUE); // Configure some other defaults define('SWFTOOLS_DEFAULT_HTML_ALT', '

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() * swftools_init() is used to force embedding JavaScript on to all pages */ function swftools_init() { if (variable_get('swftools_always_add_js', SWFTOOLS_ALWAYS_ADD_JS)) { swftools_push_js(); } } /** * Implementation of hook_menu(). */ function swftools_menu() { // Initialise array $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', ); } /** * Take an array of play list data and options, and return a markup string. * * @param $playlist_data * A formatted array of data to be used to create the playlist. An appropriate * array can be created from an array of filenames by calling swftools_prepare_playlist_data. * @param $options * An array of options to pass to the call to swf(). * @return * A string of markup to produce the playlist in a flash media player. */ function swf_list($playlist_data, $options = array()) { // Populate methods and othervars with playlist data if (is_array($playlist_data)) { // If action isn't set then set it if (empty($options['methods']['action']) && isset($playlist_data['action'])) { $options['methods']['action'] = $playlist_data['action']; } // If playlist_data isn't set then set it if (empty($options['othervars']['playlist_data'])) { $options['othervars']['playlist_data'] = $playlist_data; } // If playlist filename is set if (isset($playlist_data['filename'])) { $playlist = $playlist_data['filename']; } else { $playlist = ''; } // Produce markup return swf($playlist, $options); } } /** * 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. * If an array is passed then the array will be converted to a playlist automatically. * If the file string is a complete url then SWF Tools will pass it along unaltered. If the string * is a partial path then it will either be resolved to the local file system, or to a remote host, * depending whether the swftools_media_url variable is set. * @param $options=>$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 $options=>$flashvars * An associative array of flashvar variables to set. eg. array('playlist'=>'files/my_playlist.xml') * @param $options=>$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 $options=>$methods * 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()) { // Initialise any $options array elements that weren't passed by the caller $options += array( 'params' => array(), 'flashvars' => array(), 'othervars' => array(), 'methods' => array(), ); // If swf() was called with an array of files, make a playlist and call swf_list() for processing if (is_array($file)) { // Turn the array in to a playlist $playlist_data = swftools_prepare_playlist_data($file); // Call swf_list to process the playlist and create the markup return swf_list($playlist_data, $options); } // Get all the actions, tools and embedding options available to us $all_methods = swftools_methods_available(); // ACTION // Work out what SWF Tools should do with this file // Was an explicit action set in $options['methods']['action'] $action = (isset($options['methods']['action'])) ? $options['methods']['action'] : FALSE; // If an explicit action wasn't set then try to determine an appropriate one using the filename if (!$action) { $action = swftools_get_action($file); } // HTML ALTERNATIVE // If an explicit value wasn't set in $options['othervars']['html_alt'] use a default $html_alt = (isset($options['othervars']['html_alt'])) ? $options['othervars']['html_alt'] : variable_get('swftools_html_alt', SWFTOOLS_DEFAULT_HTML_ALT); // RESOLVE PLAYER AND EMBEDDING // 'resolved' refers to the fact that these are the methods we now intend to use, not /all/ methods available. $resolved_methods = new stdClass(); // PLAYER // Work out what player SWF Tools will need to use for this action // Was an explicit player set in $options['methods']['player'] $player = (isset($options['methods']['player'])) ? $options['methods']['player'] : FALSE; // If an explicit player wasn't set then find out what player is configured for the current action if (!$player) { // Find out what player is assigned to handle the current action $player = swftools_get_player($action); // If still no player assignment then we don't know what to do with this action if (!$player) { // Build an array of descriptions for each possible action $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 we have a matching description for the specified action, create a meaningful message 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'); } // Otherwise we have an action that SWF Tools doesn't understand, so create a fallback message 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 couldn't find a player for this content, so fallback to the alternate markup and return return $html_alt; } } // Check that the action / player combination is valid (it should appear in the array of all methods) if (isset($all_methods[$action][$player])) { // If the combination was found, place player information in to $resolved_methods $resolved_methods->player = $all_methods[$action][$player]; } // If the action / player combination doesn't appear then we need to do something else else { // If the action is display an swf directly then assume we have a custom player if ($action == SWFTOOLS_SWF_DISPLAY_DIRECT) { // Assign SWFTOOLS_CUSTOM data in to $resolved_methods $resolved_methods->player = $all_methods[$action][SWFTOOLS_CUSTOM]; $resolved_methods->player['shared_file'] = $player; } // We couldn't find a player for this content, so fallback to the alternate markup and return else { drupal_set_message(t('Could not find the %player file for embedding.', array('%player' => $player)), 'error', FALSE); return $html_alt; } } // EMBED // Work out what embedding method SWF Tools should use for this content // Was an explicit embedding method set in $options['methods']['embed'] $embed = (isset($options['methods']['embed'])) ? $options['methods']['embed'] : FALSE; // If an explicit embedding method wasn't set then find get the current default if (!$embed) { $embed = variable_get(SWFTOOLS_EMBED_METHOD, SWFTOOLS_NOJAVASCRIPT); } // Place the embedding method information in to $resolved_methods $resolved_methods->embed = $all_methods[SWFTOOLS_EMBED_METHOD][$embed]; // VARIABLES AND PARAMETERS // Put all the variables on a simple object to make internal function calls simpler $vars = new stdClass(); // OTHERVARS // If $options['othervars'] were supplied, add to $vars->othervars $vars->othervars = (is_array($options['othervars'])) ? $options['othervars'] : array(); // PARAMS // $options['params'] could be an associative array, or in 'WIDTHxHEIGHT' format. // If $options were passed to the swf() function then process them if ($options['params']) { // If $options['params'] is an array then just add it to $vars if (is_array($options['params'])) { $vars->params = $options['params']; } // Otherwise see if we can explode the string in to a height and width else { $dimensions = explode('x', $options['params']); if (count($dimensions) == 2) { $vars->params = array( 'width' => $dimensions[0], 'height' => $dimensions[1], ); } } } // FLASHVARS // Flashvars could be passed as an associative array, or as a string in 'a=1&b=2' format // If the flashvars have been passed as an array simply add to $varsa if (is_array($options['flashvars'])) { $vars->flashvars = $options['flashvars']; } // Otherwise parse the flashvars string in to an array else { // Parse the string as if in 'a=1&b=2' format. parse_str($options['flashvars'], $vars->flashvars); } // BASE // Determine a reasonable 'base' directory, if a remote url is set, use that // If file is local, set to the file directory // Was an explicit base path set in $options['params']['base'] $base = (!empty($vars->params['base'])) ? $vars->params['base'] : ''; // If the base path isn't set, or the path is not valid try to find a reasonable alternative if (!$base || !valid_url($base)) { // Use swftools_get_media_url() to obtain either the local path, or the remote media path $base = swftools_get_media_url('', FALSE); } // Strip $base_root if this is a local base path $base = swftools_strip_base_root($base); // Assign the resulting base path in to $vars->params['base'] $vars->params['base'] = $base; // PLAYLIST // Determine if we trying to generate a playlist // If $options['othervars']['playlist_data'] is set then we are processing a playlist if (isset($options['othervars']['playlist_data'])) { // Flag that a playlist is being generated $playlist = TRUE; // Generate a playlist in the files directory $file = swftools_generate_playlist($options['othervars']['playlist_data'], '', $resolved_methods, $vars); // If a file wasn't generated by swftools_generate_playlist then set an error and return alternate markup if (!$file) { drupal_set_message(t('Unable to create playlist.'), 'error'); return $html_alt; } } // CACHING // To try and prevent the xml files from being cached append the time to the filename to try and force it to reload if (variable_get('swftools_playlist_caching', 'here') == 'always') { $nocache = '?nc='. time(); } else { $nocache = ''; } // FILE // Make sure that the file path is $file is valid - we skip this section if $file is already a full url // Otherwise we try to expand it to a full url to the local file system or the remote media directory // If $file isn't already a valid url... // if (!valid_url($file, TRUE)) { // If $file isn't a valid url, and if the file isn't going to be streamed, then try to work out where it is if (!valid_url($file, TRUE) && !isset($vars->othervars['stream'])) { // If we don't have a playlist... if (empty($playlist)) { // TODO : Is it necessary to have swftools_get_media_path() AND swftools_get_media_url() // Then check if files are being sourced locally, and if they are build a file path if (swftools_get_media_path()) { $file = file_create_path($file); } } // Try to turn $file in to a complete url, either local or remote $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; } // We already had a url, so set $file_url to $file else { $file_url = $file; } // Try to strip $base_root if this is a local path $file_url = swftools_strip_base_root($file_url); // Attach file_url to othervars so player modules have access if required $vars->othervars['file_url'] = $file_url; // SRC // 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_strip_base_root(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'] = 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. if (module_hook($resolved_methods->player['module'], 'swftools_flashvars')) { // Get player flashvars $player_flashvars = module_invoke($resolved_methods->player['module'], 'swftools_flashvars', $action, $resolved_methods, $vars); // Merge player flashvars with existing flashvars if (is_array($player_flashvars)) { $vars->flashvars = array_merge($vars->flashvars, $player_flashvars); } } // If the player made a flashvar assignment for the playlist, add it to the flashvars if (!empty($resolved_methods->player['file'])) { $vars->flashvars[$resolved_methods->player['file']] = $vars->othervars['file_url']; } // If the player requires a specific minimum flash version then assign it to the params 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. // The code below was patch to fix notice errors, but it broke flash node autodetect // Flash node has been patched to fix this by changing zero height / width to null // If flashvars are empty, but params are set, populate flashvars with params if (empty($vars->flashvars['width']) && empty($vars->flashvars['height'])) { if (!empty($vars->params['width']) && !empty($vars->params['height'])) { $vars->flashvars['width'] = $vars->params['width']; $vars->flashvars['height'] = $vars->params['height']; } } // If params are empty, but flashvars are set, populate params with flashvars if (empty($vars->params['width']) && empty($vars->params['height'])) { if (!empty($vars->flashvars['width']) && !empty($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. $embed_markup = module_invoke($resolved_methods->embed['module'], 'swftools_embed', $action, $resolved_methods, $vars, $html_alt); // Call theme function to return completed markup, e.g. add containing div return theme('swftools_embed', $embed_markup, $action, $resolved_methods, $vars, $html_alt); } /** * Produce finished markup ready for inserting on the page * * @param $embed_markup * The markup needed to add the swf content to the page * @param $action * The action that is being used, in case the themer wants it * @param $methods * The player and embedding methods being used, in case the themer wants it * @param $vars * The array of othervars, params and flashvars in case the themer wants it * @param $html_alt * The alternate HTML content, in case the themer wants it * @return * An HTML string that generates the output */ function theme_swftools_embed($embed_markup, $action, $methods, $vars, $html_alt) { // Generate a css id if an id was supplied in $vars->othervars $id = (!empty($vars->othervars['id'])) ? ' id="swf-'. $vars->othervars['id'] .'"' : ''; // Prepare an array of classes to include in the wrapper div $classes[] = 'swftools-wrapper'; $classes[] = str_replace('_', '-', $methods->player['name']); // If the user provided class data already then don't over-rule it if (!empty($vars->othervars['class'])) { $classes[] = $vars->othervars['class']; } // Return completed markup return '' . $embed_markup . ''; } /** * Collect information from all modules about the players and embedding methods available. * * @param $action * Optional parameter to retrieve data only about a specific method. * @param $reset * Optional parameter which if TRUE will reset the method cache and rebuild it. * @return * An array of data describing the available methods. */ function swftools_methods_available($action = NULL, $reset = FALSE) { // Cache methods array as it may be called several times static $methods = array(); // If user has requested the cache to be reset then reset it if ($reset) { $methods = array(); } // If the cache isn't populated then build it by calling hook_swftools_methods if (!count($methods)) { $methods = module_invoke_all('swftools_methods'); } // In case no module is presenting a method for the required action the // following line avoids a notice error if ($action) { $methods += array( $action => NULL, ); } // Return results - either for the specific action, or the whole array return ($action) ? $methods[$action] : $methods; } function swftools_json_params(&$params, $attr = 'swftools') { return $attr . "='". drupal_to_js($params) . "'"; } /** * Returns 'true' or 'false' for JavaScript based the supplied value $bool. * * @param $bool * The value that should be cast to true or false. * @return * The string 'true' or 'false' depending on the supplied value. */ 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 most likely SWF Tools action for a file, based on its extension. * * @param $file * The name of the file to be processed. * @return * A string describing an SWF Tools action. */ function swftools_get_action($file) { // Get the path information for this file $path_parts = pathinfo($file); // Select an action based on the file extension 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: // Assume that the configured mediaplayer will handle this file or playlist return SWFTOOLS_MEDIA_DISPLAY_LIST; } } /** * Identify the currently configured player for the specified action. * * @param $action * The SWF Tools action to be performed. * @return * The name of the currently configured player for this action. */ function swftools_get_player($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); // For all other media types the default is FALSE - no player configured 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 path 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. * * @param $dir * Optional parameter that gives the location of flash media players. * @return * String with the path to the media players. */ function swftools_get_player_path($dir = FALSE) { // If a directory parameter wasn't set then return the configured value if (!$dir) { $dir = variable_get('swftools_player_path', SWFTOOLS_PLAYER_PATH); // If the swftools_player_path variable isn't set return the default path if (!$dir) { $dir = drupal_get_path('module', 'swftools') .'/shared'; } } // If $dir starts with / then assume we provided a full path from the web root elseif (substr($dir, 0, 1) == '/') { $dir = ltrim($dir, '/'); } // Otherwise assume the path is in the files directory and build that path else { $dir = file_create_path($dir); } // Return the resulting directory return $dir; } /** * Returns the media path relative to webroot. * There is a setting called 'swftools_media_url'. If this is set, we assume the * media is on a different server. * * @return * A string containing the path to the local files, or empty if the files are remote. */ function swftools_get_media_path() { // Retrieve the media url setting $media_url = trim(variable_get('swftools_media_url', '')); // If no media url is set then return the path to local files if (!$media_url || $media_url == '') { return file_create_path('') . '/'; } // If a media url is set then assume this is a remote path and so we don't know anything // about the path between the base url and the file. Return an empty string. return ''; } /** * Resolve a path to a full url, either on the local file system, or at a remote address * if the swftools_media_url variable has been set. If the path describes a file, is local * and the swftools_check_media variable is set then check if the file exists. * The path must be relative to the webroot. * * @param $path * The file path to check. * @param $is_file * Optional flag to indicate that the path points to a file in which case local files can be tested to see if * they exist (defaults to TRUE). If set to FALSE then it indicates the path doesn't refer to a file and it won't be tested. * @return * A string with the complete url to the file, either locally or using the remote path, or FALSE if the local file doesn't exist */ function swftools_get_media_url($path, $is_file = TRUE) { // Retrieve swftools_media_url to see if a remote path has been set $media_url = trim(variable_get('swftools_media_url', '')); // If a remote path is set simply build the appropriate path and return if ($media_url) { return $media_url . '/' . $path; } // If media checking is active, and the path is a file, check to see if it actually exists if (variable_get('swftools_check_media', TRUE) && $is_file) { // If the file doesn't exist, set an error message and return FALSE to indicate failure if (!file_exists($path)) { drupal_set_message(t('Could not display the flash because %path does not appear to exist.', array('%path' => $path)), 'error'); return FALSE; } } // Return the path 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; } /** * Return an array of default values to use as the swf parameters. * Parameters are described in the Adobe knowledge base TechNote 12701 * http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_12701 * * @return * An array of key/value pairs */ 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', TRUE), '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), 'allowscriptaccess' => variable_get('swftools_params_allowscriptaccess', 'sameDomain'), ); // Ensure that boolean parameters are set to strings 'true' or 'false' $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 the defaults 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, or it is a media player //if (trim(variable_get('swftools_media_url', '')) == '') { if ((trim(variable_get('swftools_media_url', '')) == '') or (strpos($file, swftools_get_player_path()) === 0)) { $info = image_get_info($file); return $info; } return FALSE; } /** * Saves a playlist (xml file) to the playlist directory ready for the swf player to use. * * @param &$playlist_data * A formatted array of playlist data that will be converted to an xml file. NEED TO DOCUMENT THE STRUCTURE. * @param $playlist_name * An optional name for the playlist. If not specified a filename will be created. * @param $method * An array describing the selected player method. * @param &$vars * Array of variables. Not used by this function, but will be passed to the playlist generator functions. * @return * A string containing the path to the playlist, or FALSE if the playlist generation failed. * Note that $playlist_data and $vars can be manipulated by this function. */ function swftools_generate_playlist(&$playlist_data, $playlist_name, &$method, &$vars) { // If no filename is supplied if (!$playlist_name) { // Initialise a string $prename = ''; // Iterate through each element of $playlist_data['playlist'] foreach ($playlist_data['playlist'] AS $data) { // Build a string using all the filenames $prename .= $data['filename']; } // Hash the resulting string of names and use as the filename $playlist_name = md5($method->player['name'] . $prename) . '.xml'; } // Turn the playlist name in to a full path $playlist_name = swftools_get_playlist_path() . '/' . $playlist_name; // If caching of xml playlist files has been disabled then delete the current playlist by this name if (variable_get('swftools_playlist_caching', 'here') == 'always') { file_delete($playlist_name); } // If the playlist already exists then return the path to it elseif (is_file($playlist_name)) { // Return path to the file return file_create_url($playlist_name); } // Determine the name of the relevant hook to output the playlist in the appropriate format $hook = $method->player['name'] . '_swftools_playlist'; // Check that the module implements this hook before trying to call it if (module_hook($method->player['module'], $hook)) { $playlist = module_invoke($method->player['module'], $hook, $playlist_data, $method, $vars); } // If the hook doesn't exist then the player doesn't support playlists else { drupal_set_message(t('@title module does not support xml playlists.', array('@title' => $method->player['title'])), 'error'); } // Try to open the playlist file ready to store the xml playlist 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; } // If the file was opened then try to write the playlist data to it 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; } // Close the file fclose($handle); // Return a url to the playlist return file_create_url($playlist_name); } /** * Add to the page any supporting files required by a given embedding method. * * @param $embed * Optional parameter - if not supplied the files for the current method will be added. * If supplied then the files for the named method will be added. * @return * Nothing */ function swftools_push_js($embed = SWFDEFAULT) { // Get the the currently available methods $all_methods = swftools_methods_available(); // If no specific embedding method was named then get the current default if (!$embed) { $embed = variable_get(SWFTOOLS_EMBED_METHOD, SWFTOOLS_NOJAVASCRIPT); } // 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($all_methods[SWFTOOLS_EMBED_METHOD][$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_strip_base_root(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) { // fileurl is always set, irrespective of what we are passing, so use this to determine extension $path_parts = pathinfo($data['fileurl']); $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('

SWF Tools Filter

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:

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; 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; } } // Get playlist data, but don't determine action if the user specified a player //$playlist_data = swftools_prepare_playlist_data($prepared[$key]['files'], '', !$player); $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', 'allowscriptaccess' => '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)) { if(!isset($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 simply adding JavaScript then no further action is necessary if ($action == 'add_js') { return; } // An id isn't always set, so populate a blank to avoid a notice error later $vars->othervars += array( 'id' => '', ); // 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']) ? ' id="'. $vars->othervars['id'] .'"' : ''; $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"; $html .= '' . "\n"; $html .= '' . "\n"; $html .= $params; $html .= '' . "\n"; $html .= '' . "\n"; $html .= $params; $html .= '' . "\n"; $html .= $html_alt . "\n"; $html .= '' . "\n"; $html .= '' . "\n"; $html .= '' . "\n"; $html .= '' . "\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) { // Determine what operation is being performed and store in $op $op = isset($form_state['values']['op']) ? $form_state['values']['op'] : ''; // Exclude unnecessary elements unset( $form_state['values']['submit'], $form_state['values']['reset'], $form_state['values']['form_id'], $form_state['values']['op'], $form_state['values']['form_token'], $form_state['values']['form_build_id'] ); // Flatten settings for saving $saved = array(); // Process array of parameters that have been passed 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(); } /** * Report the methods that are supported by the SWF Tools module. * * @return * An array of methods and players provided by the default SWF Tools installation. */ function swftools_swftools_methods() { // Initialise array $methods = array(); // 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'), ); // 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.'), ); // Module implements custom embedding of an swf $methods[SWFTOOLS_SWF_DISPLAY_DIRECT][SWFTOOLS_CUSTOM] = array( 'name' => SWFTOOLS_CUSTOM, 'module' => 'swftools', 'shared_file' => '', // Assigned later. 'title' => t('Use custom SWF file.'), ); // Add in the methods from genericplayers.module $methods = array_merge($methods, genericplayers_swftools_methods()); // Return the methods that are native to SWF Tools return $methods; } /** * Return a customised file download url that doesn't include the $base_root * * @param $file * The path of the file for which a download link is return * @return * The path to the file including any $base_path but excluding $base_root */ function swftools_strip_base_root($file) { return str_replace($GLOBALS['base_root'], '', $file); }