[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/swftools/ -> swftools.module (source)

   1  <?php
   2  // $Id: swftools.module,v 1.20.2.16 2009/04/18 23:30:52 stuartgreenfield Exp $
   3  
   4  // Include the generic player module for basic mp3 and flv support
   5  include_once(drupal_get_path('module', 'swftools') .'/genericplayers.module');
   6  
   7  // This is the Flash embed method, other constants are usually defined in other Flash replace providers.
   8  define('SWFTOOLS_EMBED_METHOD', 'swftools_embed_method'); // Using JavaScript to replace HTML with Flash embedding code.
   9  
  10  // The following are actions, what to do with the passed file.
  11  define('SWFTOOLS_IMAGE_DISPLAY_LIST',  'swftools_image_display_list'); // Display list of images
  12  define('SWFTOOLS_FLV_DISPLAY',         'swftools_flv_display');        // Display .flv format file
  13  define('SWFTOOLS_FLV_DISPLAY_LIST',    'swftools_flv_display_list');   // Display list of .flv format files
  14  define('SWFTOOLS_MP3_DISPLAY',         'swftools_mp3_display');        // Display .mp3 format file
  15  define('SWFTOOLS_MP3_DISPLAY_LIST',    'swftools_mp3_display_list');   // Display list of .mp3 format files
  16  define('SWFTOOLS_MEDIA_DISPLAY',       'swftools_media_display');      // Display an unspecified file format
  17  define('SWFTOOLS_MEDIA_DISPLAY_LIST',  'swftools_media_display_list'); // Display list of mixed files
  18  define('SWFTOOLS_SWF_DISPLAY_DIRECT',  'swftools_swf_display_direct'); // Display .swf format file, not inside any player
  19  define('SWFTOOLS_SWF_DISPLAY',         'swftools_swf_display');        // Display .swf format inside a player
  20  
  21  // These are for user convenience, most common parameters for casual users using the api.
  22  define('SWFDEFAULT', FALSE);
  23  define('SWFTOOLS_SWF', 'swftools_swf');                     // This is a 'player' method implemented by swftools.module itself.
  24  define('SWFTOOLS_CUSTOM', 'swftools_custom');               // An unknown media/file player.
  25  define('SWFTOOLS_NOJAVASCRIPT', 'swftools_nojavascript');   // This is an 'embed' method implemented by swftools.module itself.
  26  //define('SWFTOOLS_DEFAULT_BG', $GLOBALS['base_url'] .'/'. drupal_get_path('module', 'swftools') .'/shared/swftools-default.jpg');       // A generic image for use in certain contexts.
  27  define('SWFTOOLS_DEFAULT_BG', url(drupal_get_path('module', 'swftools') . '/shared/swftools-default.jpg', array('absolute' => TRUE)));   // A generic image for use in certain contexts.
  28  
  29  // Let other modules know SWF Tools is available
  30  define('SWFTOOLS_INSTALLED', TRUE);
  31  
  32  // Configure some other defaults
  33  define('SWFTOOLS_DEFAULT_HTML_ALT', '<p>You are missing some Flash content that should appear here! Perhaps your browser cannot display it, or maybe it did not initialize correctly.</p>');
  34  define('SWFTOOLS_PLAYLIST_PATH', 'playlists');
  35  define('SWFTOOLS_PLAYER_PATH', '');
  36  define('SWFTOOLS_GRANT_ACCESS_TO_PRIVATE_FILES', FALSE);
  37  define('SWFTOOLS_GRANT_ACCESS_EXTENSIONS', 'swf flv xml mp3 jpg jpeg png');
  38  define('SWFTOOLS_ALWAYS_ADD_JS', TRUE);
  39  
  40  /**
  41   * Implementation of hook_init()
  42   * swftools_init() is used to force embedding JavaScript on to all pages
  43   */
  44  function swftools_init() {
  45    if (variable_get('swftools_always_add_js', SWFTOOLS_ALWAYS_ADD_JS)) {
  46      swftools_push_js();
  47    }
  48  }
  49  
  50  /**
  51   * Implementation of hook_menu().
  52   */
  53  function swftools_menu() {
  54  
  55    // Reset methods cache
  56    $methods = swftools_methods_available('', TRUE);
  57    
  58    // Initialise array
  59    $items = array();
  60  
  61    // Should this be administer swf tools?
  62    $swf_admin = array('administer flash');
  63  
  64    $items['admin/settings/swftools'] = array(
  65      'title' => 'SWF Tools',
  66      'description' => 'Settings to control how SWF Tools integrates with Adobe Flash related methods and tools like video players, MP3 players and image viewers.',
  67      'access arguments' => $swf_admin,
  68      'page callback' => 'system_admin_menu_block_page',
  69      'file' => 'system.admin.inc',
  70      'file path' => drupal_get_path('module', 'system'),
  71    );
  72  
  73    $items['admin/settings/swftools/handling'] = array(
  74      'title' => 'File handling',
  75      'description' => 'Configure how SWF Tools should handle different types of file.',
  76      'access arguments' => $swf_admin,
  77      'weight' => -1,
  78      'page callback' => 'drupal_get_form',
  79      'page arguments' => array('swftools_admin_handling_form'),
  80      'file' => 'swftools.admin.inc',
  81    );
  82  
  83    $items['admin/settings/swftools/embed'] = array(
  84      'title' => 'Embedding settings',
  85      'description' => 'Set the embedding method that SWF Tools should use, and configure embedding defaults.',
  86      'access arguments' => $swf_admin,
  87      'weight' => -2,
  88      'page callback' => 'drupal_get_form',
  89      'page arguments' => array('swftools_admin_embed_form'),
  90      'file' => 'swftools.admin.inc',
  91    );
  92    
  93    // If CCK is active then add a link to the CCK formatters
  94    if (module_exists('content')) {
  95      $items['admin/settings/swftools/cck'] = array(
  96        'title' => 'CCK formatters',
  97        'description' => 'Additional settings to control how SWF Tools should interact with CCK.',
  98        'access arguments' => $swf_admin,
  99        'page callback' => 'drupal_get_form',
 100        'page arguments' => array('swftools_admin_cck_form'),
 101        'file' => 'swftools.admin.inc',
 102      );
 103    }
 104  
 105    $items['admin/reports/swftools'] = array(
 106      'title' => 'SWF Tools status',
 107      'description' => 'Get an overview of the status of the SWF Tools module and its supporting files.',
 108      'page callback' => 'swftools_status',
 109      'access arguments' => $swf_admin,
 110      'file' => 'swftools.admin.status.inc',
 111      'weight' => 9,
 112    );
 113  
 114    $items = array_merge($items, genericplayers_menu());
 115  
 116    return $items;
 117  }
 118  
 119  
 120  /**
 121   * Implementation of hook_perm().
 122   */
 123  function swftools_perm() {
 124    return array(
 125      'administer flash',
 126    );
 127  }
 128  
 129  
 130  /**
 131   * Take an array of play list data and options, and return a markup string.
 132   * 
 133   * @param $playlist_data
 134   *   A formatted array of data to be used to create the playlist. An appropriate
 135   *   array can be created from an array of filenames by calling swftools_prepare_playlist_data.
 136   * @param $options
 137   *   An array of options to pass to the call to swf().
 138   * @return
 139   *   A string of markup to produce the playlist in a flash media player.
 140   */
 141  function swf_list($playlist_data, $options = array()) {
 142  
 143    // Populate methods and othervars with playlist data
 144    if (is_array($playlist_data)) {
 145  
 146      // If action isn't set then set it
 147      if (empty($options['methods']['action']) && isset($playlist_data['action'])) {
 148        $options['methods']['action'] = $playlist_data['action'];
 149      }
 150      
 151      // If playlist_data isn't set then set it
 152      if (empty($options['othervars']['playlist_data'])) {
 153        $options['othervars']['playlist_data'] = $playlist_data;
 154      }
 155        
 156      // If playlist filename is set
 157      if (isset($playlist_data['filename'])) {
 158        $playlist = $playlist_data['filename'];
 159      }
 160      else {
 161        $playlist = '';
 162      }
 163  
 164      // Produce markup
 165      return swf($playlist, $options);
 166    }
 167  }
 168  
 169  /**
 170   * Return output, which might be embed markup, or pre-flash markup
 171   * that includes the appropriate jQuery added to the <head>
 172   *
 173   * @param $file
 174   *   The file to be played. If it is a SWF file it will usually be embedded directly.
 175   *   Use a full URL, a path relative to webroot, or a path relative to the configured files directory.
 176   *   If an array is passed then the array will be converted to a playlist automatically.
 177   *   If the file string is a complete url then SWF Tools will pass it along unaltered. If the string
 178   *   is a partial path then it will either be resolved to the local file system, or to a remote host,
 179   *   depending whether the swftools_media_url variable is set.
 180   * @param $options=>$params
 181   *   An associative array of <param> variables to set.eg. array('bgcolor'=>'FF00FF')
 182   *   To set height and width: array('width'=>'200', 'height'=>'120'). However,
 183   *   as a convenient alternative for the common requirement of just height and width
 184   *   you can also pass a text string like '200x100'.
 185   *   If you pass nothing, and the file to play is a .swf, swftools will try and
 186   *   establish a natural width and height from the actual .swf file that you've
 187   *   passed into $file.
 188   * @param $options=>$flashvars
 189   *   An associative array of flashvar variables to set. eg. array('playlist'=>'files/my_playlist.xml')
 190   * @param $options=>$othervars
 191   *   An associative array of variables that might be required by the $player or $embed technique.
 192   *   These values are not output as params or flashvars.
 193   * @param $options=>$methods
 194   *   Explicitly declare an action, player or action by passing an array of
 195   *   the form: array('action'=>'dosomething','player'=>'withsomething','embed'=>'withthisjavascript').
 196   *   These usually default to the administration settings and also you will
 197   *   usually use a CONSTANT which will be documented further at a later stage.
 198   */
 199  function swf($file, $options = array()) {
 200    
 201    // Initialise any $options array elements that weren't passed by the caller
 202    $options += array(
 203      'params' => array(),
 204      'flashvars' => array(),
 205      'othervars' => array(),
 206      'methods' => array(),
 207    );
 208    
 209    // If swf() was called with an array of files, make a playlist and call swf_list() for processing
 210    if (is_array($file)) {
 211  
 212      // Turn the array in to a playlist
 213      $playlist_data = swftools_prepare_playlist_data($file);
 214  
 215      // Call swf_list to process the playlist and create the markup
 216      return swf_list($playlist_data, $options);
 217    }
 218  
 219    // Get all the actions, tools and embedding options available to us
 220    $all_methods = swftools_methods_available();
 221  
 222    
 223    // ACTION
 224    // Work out what SWF Tools should do with this file
 225  
 226    // Was an explicit action set in $options['methods']['action']
 227    $action = (isset($options['methods']['action'])) ? $options['methods']['action'] : FALSE;
 228  
 229    // If an explicit action wasn't set then try to determine an appropriate one using the filename
 230    if (!$action) {
 231      $action = swftools_get_action($file);
 232    }
 233  
 234    
 235    // HTML ALTERNATIVE
 236    // If an explicit value wasn't set in $options['othervars']['html_alt'] use a default
 237    $html_alt = (isset($options['othervars']['html_alt'])) ? $options['othervars']['html_alt'] : variable_get('swftools_html_alt', SWFTOOLS_DEFAULT_HTML_ALT);
 238  
 239    
 240    // RESOLVE PLAYER AND EMBEDDING
 241    // 'resolved' refers to the fact that these are the methods we now intend to use, not /all/ methods available.
 242    $resolved_methods = new stdClass();
 243  
 244    
 245    // PLAYER
 246    // Work out what player SWF Tools will need to use for this action
 247    
 248    // Was an explicit player set in $options['methods']['player']
 249    $player = (isset($options['methods']['player'])) ? $options['methods']['player'] : FALSE;
 250    
 251    // If an explicit player wasn't set then find out what player is configured for the current action
 252    if (!$player) {
 253  
 254      // Find out what player is assigned to handle the current action
 255      $player = swftools_get_player($action);
 256      
 257      // If still no player assignment then we don't know what to do with this action
 258      if (!$player) {
 259        
 260        // Build an array of descriptions for each possible action
 261        $descriptions = array(
 262          SWFTOOLS_IMAGE_DISPLAY_LIST=> 'a series of images',
 263          SWFTOOLS_FLV_DISPLAY=> 'a single flv file',
 264          SWFTOOLS_FLV_DISPLAY_LIST=> 'a series of flv files',
 265          SWFTOOLS_MP3_DISPLAY=> 'a single mp3 file',
 266          SWFTOOLS_MP3_DISPLAY_LIST=> 'a series of mp3 files',
 267          SWFTOOLS_MEDIA_DISPLAY_LIST=> 'a series mixed media files',
 268        );
 269        
 270        // If we have a matching description for the specified action, create a meaningful message
 271        if (isset($descriptions[$action])) {
 272          drupal_set_message(t('No player is configured to play '.$descriptions[$action].'. Check the SWF Tools file handling settings on the configuration page.'), 'error');
 273        }
 274        
 275        // Otherwise we have an action that SWF Tools doesn't understand, so create a fallback message
 276        else {
 277          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');
 278        }
 279  
 280        // We couldn't find a player for this content, so fallback to the alternate markup and return
 281        return $html_alt;
 282      }
 283    }
 284    
 285    // Check that the action / player combination is valid (it should appear in the array of all methods)
 286    if (isset($all_methods[$action][$player])) {
 287      
 288      // If the combination was found, place player information in to $resolved_methods
 289      $resolved_methods->player = $all_methods[$action][$player];
 290    
 291    }
 292    
 293    // If the action / player combination doesn't appear then we need to do something else
 294    else {
 295      
 296      // If the action is display an swf directly then assume we have a custom player
 297      if ($action == SWFTOOLS_SWF_DISPLAY_DIRECT) {
 298  
 299        // Assign SWFTOOLS_CUSTOM data in to $resolved_methods
 300        $resolved_methods->player = $all_methods[$action][SWFTOOLS_CUSTOM];
 301        $resolved_methods->player['shared_file'] = $player;
 302      }
 303  
 304      // We couldn't find a player for this content, so fallback to the alternate markup and return
 305      else {
 306        drupal_set_message(t('Could not find the %player file for embedding.', array('%player' => $player)), 'error', FALSE);
 307        return $html_alt;
 308      }
 309    }
 310  
 311    
 312    // EMBED
 313    // Work out what embedding method SWF Tools should use for this content
 314    
 315    // Was an explicit embedding method set in $options['methods']['embed']
 316    $embed = (isset($options['methods']['embed'])) ? $options['methods']['embed'] : FALSE;
 317    
 318    // If an explicit embedding method wasn't set then find get the current default
 319    if (!$embed) {
 320      $embed = variable_get(SWFTOOLS_EMBED_METHOD, SWFTOOLS_NOJAVASCRIPT);
 321    }
 322  
 323    // Place the embedding method information in to $resolved_methods
 324    $resolved_methods->embed = $all_methods[SWFTOOLS_EMBED_METHOD][$embed];
 325  
 326  
 327    // VARIABLES AND PARAMETERS
 328    // Put all the variables on a simple object to make internal function calls simpler
 329    $vars = new stdClass();
 330  
 331    
 332    // OTHERVARS
 333    // If $options['othervars'] were supplied, add to $vars->othervars
 334    $vars->othervars = (is_array($options['othervars'])) ? $options['othervars'] : array();
 335  
 336    
 337    // PARAMS
 338    // $options['params'] could be an associative array, or in 'WIDTHxHEIGHT' format.
 339  
 340    // If $options were passed to the swf() function then process them
 341    if ($options['params']) {
 342      
 343      // If $options['params'] is an array then just add it to $vars
 344      if (is_array($options['params'])) {
 345        $vars->params = $options['params'];
 346      }
 347      
 348      // Otherwise see if we can explode the string in to a height and width
 349      else {
 350        $dimensions = explode('x', $options['params']);
 351        if (count($dimensions) == 2) {
 352          $vars->params = array(
 353            'width' => $dimensions[0],
 354            'height' => $dimensions[1],
 355          );
 356        }
 357      }
 358    }
 359  
 360    
 361    // FLASHVARS
 362    // Flashvars could be passed as an associative array, or as a string in 'a=1&b=2' format
 363    
 364    // If the flashvars have been passed as an array simply add to $varsa
 365    if (is_array($options['flashvars'])) {
 366      $vars->flashvars = $options['flashvars'];
 367    }
 368    
 369    // Otherwise parse the flashvars string in to an array
 370    else {
 371  
 372      // Parse the string as if in 'a=1&b=2' format.
 373      parse_str($options['flashvars'], $vars->flashvars);
 374    }
 375  
 376    
 377    // BASE
 378    // Determine a reasonable 'base' directory, if a remote url is set, use that
 379    // If file is local, set to the file directory
 380    
 381    // Was an explicit base path set in $options['params']['base']
 382    $base = (!empty($vars->params['base'])) ? $vars->params['base'] : '';
 383    // If the base path isn't set, or the path is not valid try to find a reasonable alternative
 384    if (!$base || !valid_url($base)) {
 385  
 386      // Use swftools_get_media_url() to obtain either the local path, or the remote media path
 387      $base = swftools_get_media_url('', FALSE);
 388    }
 389  
 390    // Strip $base_root if this is a local base path
 391    $base = swftools_strip_base_root($base);
 392    
 393    // Assign the resulting base path in to  $vars->params['base']
 394    $vars->params['base'] = $base;
 395  
 396    
 397    // PLAYLIST
 398    // Determine if we trying to generate a playlist
 399    
 400    // If $options['othervars']['playlist_data'] is set then we are processing a playlist
 401    if (isset($options['othervars']['playlist_data'])) {
 402  
 403      // Flag that a playlist is being generated
 404      $playlist = TRUE;
 405  
 406      // Generate a playlist in the files directory
 407      $file = swftools_generate_playlist($options['othervars']['playlist_data'], '', $resolved_methods, $vars);
 408  
 409      // If a file wasn't generated by swftools_generate_playlist then set an error and return alternate markup
 410      if (!$file) {
 411        drupal_set_message(t('Unable to create playlist.'), 'error');
 412        return $html_alt;
 413      }
 414    }
 415  
 416    
 417    // CACHING
 418    // To try and prevent the xml files from being cached append the time to the filename to try and force it to reload
 419    if (variable_get('swftools_playlist_caching', 'here') == 'always') {
 420      $nocache = '?nc='. time();
 421    }
 422    else {
 423      $nocache = '';
 424    }
 425  
 426    
 427    // FILE
 428    // Make sure that the file path is $file is valid - we skip this section if $file is already a full url
 429    // Otherwise we try to expand it to a full url to the local file system or the remote media directory
 430  
 431    // If $file isn't already a valid url...
 432  //  if (!valid_url($file, TRUE)) {
 433      
 434    // 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
 435    if (!valid_url($file, TRUE) && !isset($vars->othervars['stream'])) {
 436      // If we don't have a playlist...
 437      if (empty($playlist)) {
 438        
 439        // TODO : Is it necessary to have swftools_get_media_path() AND swftools_get_media_url()
 440        // Then check if files are being sourced locally, and if they are build a file path
 441        if (swftools_get_media_path()) {
 442          $file = file_create_path($file);
 443        }
 444      }
 445  
 446      // Try to turn $file in to a complete url, either local or remote
 447      $file_url = swftools_get_media_url($file);
 448  
 449      // If $file_url was not generated then file doesn't exist so return $html_alt
 450      if (!$file_url) {
 451        return $html_alt;
 452      }
 453  
 454      // Append $nocache string to complete the url
 455      //$file_url = $file_url . $nocache;
 456    }
 457    
 458    // We already had a url, or this is a stream, so set $file_url to $file
 459    else {
 460      $file_url = $file;
 461    }
 462    
 463  //  // Try to strip $base_root if this is a local path
 464  //  $file_url = swftools_strip_base_root($file_url);
 465    
 466    // Attach file_url to othervars so player modules have access if required
 467    $vars->othervars['file_url'] = $file_url;
 468    
 469    // SRC
 470    // Determine the "src" attribute of the embed (also applies to the 'movie' attribute).
 471    // Usually this is the Flash Player, but it can also be a swf file, or a custom file
 472    // passed on othervars['shared_file'].
 473    switch ($player) {
 474      case SWFTOOLS_SWF:
 475        $vars->params['src_path'] = $file;
 476        $vars->params['src'] = $file_url;
 477        break;
 478      case SWFTOOLS_CUSTOM:
 479        $vars->params['src_path'] = $resolved_methods->player['shared_file']; // May need the local path for dimensions.
 480          $vars->params['src'] = swftools_get_media_url($vars->params['src_path']);
 481        break;
 482      default:
 483        $vars->params['src_path'] = swftools_get_player_path() . '/' . $resolved_methods->player['shared_file'];
 484        $vars->params['src'] = $GLOBALS['base_url'] . '/' . $vars->params['src_path'];
 485    }
 486    
 487    // Try to strip $base_root if this is a local path
 488    $vars->params['src'] = swftools_strip_base_root($vars->params['src']);
 489    
 490    // Merge default and user defined "params".
 491    $vars->params = array_merge(_swftools_params(), $vars->params);
 492  
 493    // Ask the module implementing the player what flashvars are required, pass
 494    // all existing values by reference to allow optional override at the player.module level.
 495    if (module_hook($resolved_methods->player['module'], 'swftools_flashvars')) {
 496  
 497      // Get player flashvars
 498      $player_flashvars = module_invoke($resolved_methods->player['module'], 'swftools_flashvars', $action, $resolved_methods, $vars);
 499      
 500      // Merge player flashvars with existing flashvars
 501      if (is_array($player_flashvars)) {
 502        $vars->flashvars = array_merge($vars->flashvars, $player_flashvars);
 503      }
 504    }
 505    
 506    // If the player made a flashvar assignment for the playlist, add it to the flashvars
 507    if (!empty($resolved_methods->player['file'])) {
 508      $vars->flashvars[$resolved_methods->player['file']] = $vars->othervars['file_url'];
 509    }
 510  
 511    // If the player requires a specific minimum flash version then assign it to the params
 512    if (isset($resolved_methods->player['version'])) {
 513      $vars->params['version'] = $resolved_methods->player['version'];
 514    }
 515  
 516    // Call function to set the size of the content
 517    swftools_set_size($vars, $resolved_methods->player);
 518    
 519    // Build a string out of the flashvars array.
 520    $vars->params['flashvars'] = _swftools_get_flashvars_string($vars->flashvars);
 521  
 522    // Call the embedding code to get the HTML and set the JavaScript if necessary.
 523    $embed_markup = module_invoke($resolved_methods->embed['module'], 'swftools_embed', $action, $resolved_methods, $vars, $html_alt);
 524  
 525    // Call theme function to return completed markup, e.g. add containing div
 526    return theme('swftools_embed', $embed_markup, $action, $resolved_methods, $vars, $html_alt);
 527  }
 528  
 529  
 530  /**
 531   * Produce finished markup ready for inserting on the page
 532   *
 533   * @param $embed_markup
 534   *   The markup needed to add the swf content to the page
 535   * @param $action
 536   *   The action that is being used, in case the themer wants it
 537   * @param $methods
 538   *   The player and embedding methods being used, in case the themer wants it
 539   * @param $vars
 540   *   The array of othervars, params and flashvars in case the themer wants it
 541   * @param $html_alt
 542   *   The alternate HTML content, in case the themer wants it
 543   * @return
 544   *   An HTML string that generates the output
 545   */
 546  function theme_swftools_embed($embed_markup, $action, $methods, $vars, $html_alt) {
 547  
 548    // Generate a css id if an id was supplied in $vars->othervars
 549    $id = (!empty($vars->othervars['id'])) ? ' id="swf-' . $vars->othervars['id'] . '"' : '';
 550  
 551    // Prepare an array of classes to include in the wrapper div
 552    $classes[] = 'swftools-wrapper';
 553    $classes[] = str_replace('_', '-', $methods->player['name']);
 554  
 555    // If the user provided class data already then don't over-rule it
 556    if (!empty($vars->othervars['class'])) {
 557      $classes[] = $vars->othervars['class'];
 558    }
 559    
 560    // Return completed markup
 561    return '<div' . $id . ' class="' . implode(' ', $classes) . '">' . $embed_markup . '</div>';
 562  }
 563  
 564  
 565  /**
 566   * Collect information from all modules about the players and embedding methods available.
 567   * 
 568   * @param $action
 569   *   Optional parameter to retrieve data only about a specific method.
 570   * @param $reset
 571   *   Optional parameter which if TRUE will reset the method cache and rebuild it.
 572   * @return
 573   *   An array of data describing the available methods.
 574   */
 575  function swftools_methods_available($action = NULL, $reset = FALSE) {
 576  
 577    // Cache methods array as it may be called several times
 578    static $methods;
 579  
 580    // If user has requested the cache to be reset then reset it
 581    if (!isset($methods) || $reset) {
 582      if (!$reset && ($cache = cache_get('swftools:methods')) && !empty($cache->data)) {
 583        $methods = $cache->data;
 584      }
 585      else {
 586        $methods = module_invoke_all('swftools_methods');
 587        cache_set('swftools:methods', $methods, 'cache', CACHE_PERMANENT);
 588      }
 589    }
 590    
 591    // In case no module is presenting a method for the required action the
 592    // following line avoids a notice error
 593    if ($action) {
 594      $methods += array(
 595        $action => NULL,
 596      );
 597    }
 598  
 599    // Return results - either for the specific action, or the whole array
 600    return ($action) ? $methods[$action] : $methods;
 601  
 602  }
 603  
 604  
 605  function swftools_json_params(&$params, $attr = 'swftools') {
 606    return $attr . "='" . drupal_to_js($params) . "'";
 607  }
 608  
 609  
 610  /**
 611   * Returns 'true' or 'false' for JavaScript based the supplied value $bool.
 612   * 
 613   * @param $bool
 614   *   The value that should be cast to true or false.
 615   * @return
 616   *   The string 'true' or 'false' depending on the supplied value.
 617   */
 618  function _swftools_tf($bool) {
 619  
 620    // String 'false' is treated as TRUE in PHP logic, so force to FALSE
 621    if (strtolower($bool) == 'false') {
 622      $bool = FALSE;
 623    }
 624  
 625    // Return 'true' or 'false' now we are sure of result
 626    return $bool ? 'true' : 'false';
 627  
 628  }
 629  
 630  
 631  /**
 632   * Identify the most likely SWF Tools action for a file, based on its extension.
 633   * 
 634   * @param $file
 635   *   The name of the file to be processed.
 636   * @return
 637   *   A string describing an SWF Tools action.
 638   */
 639  function swftools_get_action($file) {
 640  
 641    // Get the path information for this file
 642    $path_parts = pathinfo($file);
 643    
 644    // Select an action based on the file extension
 645    switch (strtolower($path_parts['extension'])) {
 646      case 'flv':
 647        return SWFTOOLS_FLV_DISPLAY;
 648      case 'swf':
 649        return SWFTOOLS_SWF_DISPLAY_DIRECT;
 650      case 'mp3':
 651        return SWFTOOLS_MP3_DISPLAY;
 652      case 'jpg': case 'gif': case 'png': case 'jpeg': case 'img':
 653        return SWFTOOLS_IMAGE_DISPLAY_LIST;
 654      default:
 655        // Assume that the configured mediaplayer will handle this file or playlist
 656        return SWFTOOLS_MEDIA_DISPLAY_LIST;
 657    }
 658  }
 659  
 660  
 661  /**
 662   * Identify the currently configured player for the specified action.
 663   *
 664   * @param $action
 665   *   The SWF Tools action to be performed.
 666   * @return
 667   *   The name of the currently configured player for this action.
 668   */
 669  function swftools_get_player($action) {
 670  
 671    switch ($action) {
 672      case SWFTOOLS_FLV_DISPLAY:
 673        return variable_get(SWFTOOLS_FLV_DISPLAY, GENERIC_FLV);
 674  
 675      case SWFTOOLS_MP3_DISPLAY:
 676        return variable_get(SWFTOOLS_MP3_DISPLAY, GENERIC_MP3);
 677  
 678      case SWFTOOLS_SWF_DISPLAY_DIRECT:
 679        return variable_get(SWFTOOLS_SWF_DISPLAY_DIRECT, SWFTOOLS_SWF);
 680  
 681      // For all other media types the default is FALSE - no player configured
 682      default:
 683        return variable_get($action, FALSE);
 684    }
 685  }
 686  
 687  /**
 688   * Returns the playlist path relative to webroot.
 689   * This path needs to be writeable, so it is fitting to limit valid
 690   * locations to the files directory.
 691   *
 692   */
 693  function swftools_get_playlist_path($dir = FALSE) {
 694  
 695    // If no directory specified, get the default
 696    if (!$dir) {
 697      $dir = variable_get('swftools_playlist_path', SWFTOOLS_PLAYLIST_PATH);
 698    }
 699  
 700    // Ensure we have a path in the file system
 701    $dir = file_create_path($dir);
 702  
 703    // Create playlist directory if necessary
 704    if (!file_check_directory($dir, FILE_CREATE_DIRECTORY)) {
 705      drupal_set_message(t('%dir does not exist, or is not writeable.', array('%dir' => $dir)), 'error', FALSE);
 706    }
 707  
 708    // Return path to the playlist directory
 709    return $dir;
 710  
 711  }
 712  
 713  
 714  /**
 715   * Returns a flash player path relative to webroot.
 716   * The default path is in the modules/swftools/shared directory.
 717   * It may suit some sites to store flash players in an alternative location, but
 718   * the assumption is the location will be on the same server.
 719   * If the path starts with '/', then we can assume is relative to the webroot.
 720   * Otherwise we assume it's in the files directory.
 721   * 
 722   * @param $dir
 723   *   Optional parameter that gives the location of flash media players.
 724   * @return
 725   *   String with the path to the media players.
 726   */
 727  function swftools_get_player_path($dir = FALSE) {
 728  
 729    // If a directory parameter wasn't set then return the configured value
 730    if (!$dir) {
 731      $dir = variable_get('swftools_player_path', SWFTOOLS_PLAYER_PATH);
 732      
 733      // If the swftools_player_path variable isn't set return the default path
 734      if (!$dir) {
 735        $dir = drupal_get_path('module', 'swftools') .'/shared';
 736      }
 737    }
 738    
 739    // If $dir starts with / then assume we provided a full path from the web root
 740    elseif (substr($dir, 0, 1) == '/') {
 741      $dir = ltrim($dir, '/');
 742    }
 743    
 744    // Otherwise assume the path is in the files directory and build that path
 745    else {
 746      $dir = file_create_path($dir);
 747    }
 748    
 749    // Return the resulting directory
 750    return $dir;
 751  }
 752  
 753  
 754  /**
 755   * Returns the media path relative to webroot.
 756   * There is a setting called 'swftools_media_url'. If this is set, we assume the
 757   * media is on a different server.
 758   * 
 759   * @return
 760   *   A string containing the path to the local files, or empty if the files are remote.
 761   */
 762  function swftools_get_media_path() {
 763  
 764    // Retrieve the media url setting
 765    $media_url = trim(variable_get('swftools_media_url', ''));
 766    // If no media url is set then return the path to local files
 767    if (!$media_url || $media_url == '') {
 768      return file_create_path('') . '/';
 769    }
 770  
 771    // If a media url is set then assume this is a remote path and so we don't know anything
 772    // about the path between the base url and the file. Return an empty string.
 773    return '';
 774  }
 775  
 776  
 777  /**
 778   * Resolve a path to a full url, either on the local file system, or at a remote address
 779   * if the swftools_media_url variable has been set. If the path describes a file, is local
 780   * and the swftools_check_media variable is set then check if the file exists.
 781   * The path must be relative to the webroot.
 782   * 
 783   * @param $path
 784   *   The file path to check.
 785   * @param $is_file
 786   *   Optional flag to indicate that the path points to a file in which case local files can be tested to see if
 787   *   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.
 788   * @return
 789   *   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
 790   */
 791  function swftools_get_media_url($path, $is_file = TRUE) {
 792  
 793    // Retrieve swftools_media_url to see if a remote path has been set
 794    $media_url = trim(variable_get('swftools_media_url', ''));
 795  
 796    // If a remote path is set simply build the appropriate path and return
 797    if ($media_url) {
 798      return $media_url . '/' . $path;
 799    }
 800    
 801    // If media checking is active, and the path is a file, check to see if it actually exists
 802    if (variable_get('swftools_check_media', TRUE) && $is_file) {
 803      
 804      // If the file doesn't exist, set an error message and return FALSE to indicate failure
 805      if (!file_exists($path)) {
 806        drupal_set_message(t('Could not display the flash because %path does not appear to exist.', array('%path' => $path)), 'error');
 807        return FALSE;
 808      }
 809    }
 810  
 811    // Return the path
 812    return file_create_url($path);
 813  
 814  }
 815  
 816  
 817  /**
 818   * "flashvars" is a parameter like height and width, which are
 819   * passed into the flash player as a=1&b=2&...
 820   *
 821   */
 822  function _swftools_get_flashvars_string(&$flashvars) {
 823  
 824    foreach ($flashvars AS $var => $value) {
 825      $flashvars[$var] = str_replace(array('&', '=', '?'), array('%26', '%3D', '%3F'), $value);
 826    }
 827    $encoded = drupal_query_string_encode($flashvars);
 828  
 829    // '#' seems to encode as %2523, reverse this, using a more robust hex prefix..
 830    $encoded = str_replace('%2523', '0x', $encoded);
 831  
 832    // Fix encoding per #181998#comment-882293
 833    $encoded = str_replace('%3A', ':', $encoded);
 834    $encoded = str_replace('%252F', '/', $encoded);
 835  
 836    return $encoded;
 837  }
 838  
 839  
 840  /**
 841   * Return an array of default values to use as the swf parameters.
 842   * Parameters are described in the Adobe knowledge base TechNote 12701
 843   * http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_12701
 844   * 
 845   * @return
 846   *   An array of key/value pairs
 847   */
 848  function _swftools_params() {
 849  
 850    $defaults = array(
 851      'swliveconnect'     => variable_get('swftools_params_swliveconnect', 'default'),
 852      'play'              => variable_get('swftools_params_play', TRUE),
 853      'loop'              => variable_get('swftools_params_loop', TRUE),
 854      'menu'              => variable_get('swftools_params_menu', FALSE),
 855      'quality'           => variable_get('swftools_params_quality', 'autohigh'),
 856      'scale'             => variable_get('swftools_params_scale', 'showall'),
 857      'align'             => variable_get('swftools_params_align', 'l'),
 858      'salign'            => variable_get('swftools_params_salign', 'tl'),
 859      'wmode'             => variable_get('swftools_params_wmode', 'opaque'),
 860      'bgcolor'           => variable_get('swftools_params_bgcolor', '#FFFFFF'),
 861      'version'           => variable_get('swftools_params_version', '7'),
 862      'allowfullscreen'   => variable_get('swftools_params_allowfullscreen', TRUE),
 863      'allowscriptaccess' => variable_get('swftools_params_allowscriptaccess', 'sameDomain'), 
 864    );
 865  
 866    // Ensure that boolean parameters are set to strings 'true' or 'false'
 867    $defaults['menu'] = _swftools_tf($defaults['menu']);
 868    $defaults['play'] = _swftools_tf($defaults['play']);
 869    $defaults['loop'] = _swftools_tf($defaults['loop']);
 870    $defaults['allowfullscreen'] = _swftools_tf($defaults['allowfullscreen']);
 871  
 872    // Return the defaults
 873    return $defaults;
 874  }
 875  
 876  
 877  /**
 878   * Attempt to return information for the specified file
 879   * Supply the path to the file to be processed, and it return FALSE if no data
 880   * was obtained. The return variable, if successful, is an array that may
 881   * include width, height, extension, file_size, mime_type.
 882   *
 883   */
 884  function swftools_get_info($file) {
 885  
 886    // Only check the file if it is local, or it is a media player
 887    //if (trim(variable_get('swftools_media_url', '')) == '') {
 888    if ((trim(variable_get('swftools_media_url', '')) == '') or (strpos($file, swftools_get_player_path()) === 0)) {
 889      $info = image_get_info($file);
 890      return $info;
 891    }
 892    return FALSE;
 893  }
 894  
 895  
 896  /**
 897   * Saves a playlist (xml file) to the playlist directory ready for the swf player to use.
 898   * 
 899   * @param &$playlist_data
 900   *   A formatted array of playlist data that will be converted to an xml file. NEED TO DOCUMENT THE STRUCTURE.
 901   * @param $playlist_name
 902   *   An optional name for the playlist. If not specified a filename will be created.
 903   * @param $method
 904   *   An array describing the selected player method.
 905   * @param &$vars
 906   *   Array of variables. Not used by this function, but will be passed to the playlist generator functions.
 907   * @return
 908   *   A string containing the path to the playlist, or FALSE if the playlist generation failed.
 909   *   Note that $playlist_data and $vars can be manipulated by this function.
 910   */
 911  function swftools_generate_playlist(&$playlist_data, $playlist_name, &$method, &$vars) {
 912  
 913    // If no filename is supplied
 914    if (!$playlist_name) {
 915      
 916      // Initialise a string
 917      $prename = '';
 918      
 919      // Iterate through each element of $playlist_data['playlist']
 920      foreach ($playlist_data['playlist'] AS $data) {
 921        
 922        // Build a string using all the filenames
 923        $prename .= $data['filename'];
 924      }
 925      
 926      // Hash the resulting string of names and use as the filename
 927      $playlist_name = md5($method->player['name'] . $prename) . '.xml';
 928    }
 929  
 930    // Turn the playlist name in to a full path
 931    $playlist_name = swftools_get_playlist_path() . '/' . $playlist_name;
 932  
 933    // If caching of xml playlist files has been disabled then delete the current playlist by this name
 934    if (variable_get('swftools_playlist_caching', 'here') == 'always') {
 935      file_delete($playlist_name);
 936    }
 937  
 938    // If the playlist already exists then return the path to it
 939    elseif (is_file($playlist_name)) {
 940      
 941      // Return path to the file
 942      return file_create_url($playlist_name);
 943    }
 944  
 945    // Determine the name of the relevant hook to output the playlist in the appropriate format
 946    $hook = $method->player['name'] . '_swftools_playlist';
 947    
 948    // Check that the module implements this hook before trying to call it
 949    if (module_hook($method->player['module'], $hook)) {
 950      $playlist = module_invoke($method->player['module'], $hook, $playlist_data, $method, $vars);
 951    }
 952    
 953    // If the hook doesn't exist then the player doesn't support playlists
 954    else {
 955      drupal_set_message(t('@title module does not support xml playlists.', array('@title' => $method->player['title'])), 'error');
 956    }
 957  
 958    // Try to open the playlist file ready to store the xml playlist
 959    if (!$handle = fopen($playlist_name, 'a')) {
 960      drupal_set_message(t('An error occurred trying to create file %playlist_name.', array('%playlist_name' => $playlist_name)), 'error');
 961      return FALSE;
 962    }
 963  
 964    // If the file was opened then try to write the playlist data to it
 965    if (fwrite($handle, $playlist) === FALSE) {
 966      drupal_set_message(t('An error occurred trying to create file %playlist_name.', array('%playlist_name' => $playlist_name)), 'error');
 967      return FALSE;
 968    }
 969    
 970    // Close the file
 971    fclose($handle);
 972  
 973    // Return a url to the playlist
 974    return file_create_url($playlist_name);
 975  }
 976  
 977  
 978  /**
 979   * Add to the page any supporting files required by a given embedding method.
 980   * 
 981   * @param $embed
 982   *   Optional parameter - if not supplied the files for the current method will be added.
 983   *   If supplied then the files for the named method will be added.
 984   * @return
 985   *   Nothing
 986   */
 987  function swftools_push_js($embed = SWFDEFAULT) {
 988  
 989    // Get the the currently available methods
 990    $all_methods = swftools_methods_available();
 991    
 992    // If no specific embedding method was named then get the current default
 993    if (!$embed) {
 994      $embed = variable_get(SWFTOOLS_EMBED_METHOD, SWFTOOLS_NOJAVASCRIPT);
 995    }
 996  
 997    // Call the module responsible to output the js. Don't pass any additional
 998    // parameters - as we don't want the module to try and return the in-body
 999    // html placeholder for the flash content.
1000    $output = module_invoke($all_methods[SWFTOOLS_EMBED_METHOD][$embed]['module'], 'swftools_embed');
1001  }
1002  
1003  /**
1004   * Take an array of filenames and prepare them to be used as a playlist
1005   * 
1006   * @param $files
1007   *   An array of files that will be added to the playlist.
1008   * @param $title
1009   *   Optional playlist title
1010   * @param $get_action
1011   *   Optional parameter indicating if the function should determine an appropriate action. Default is TRUE.
1012   * @param $type_filter
1013   *   Optional parameter - an array of file extensions that are permitted
1014   * @param $stream
1015   *   Option parameter to indicate if this is going to be a streamed playlist, in which case checks for the
1016   *   existence of files should be skipped
1017   * @return unknown_type
1018   */
1019  function swftools_prepare_playlist_data($files, $title = '', $get_action = TRUE, $type_filter = array(), $stream = FALSE) {
1020    
1021    // Initialise an array to return the results in
1022    $playlist_data = array();
1023    $playlist_data['header']['title'] = $title;
1024  
1025    // Run through all $files and and make the data look the same.
1026    $id = 0;
1027    foreach ($files AS $key => $data) {
1028      while (array_key_exists($id, $files)) {
1029        $id++;
1030      }
1031      if (is_object($data)) {
1032        $files[$key] = (array)$data;
1033      }
1034      elseif (!is_array($data)) {
1035  
1036        // Move this file name to a new key to give it the structure of a file attachment array
1037        $files[$id]['filepath'] = $data;
1038        if (!is_numeric($key)) {
1039          $files[$id]['filename'] = $key;
1040        }
1041        else {
1042          $files[$id]['filename'] = $data;
1043        }
1044        unset($files[$key]);
1045      }
1046    }
1047  
1048    // Check the fileurl element and add generate it if it's missing.
1049    $playlist_data['playlist'] = $files;
1050    foreach ($files AS $key => $data) {
1051      if (!isset($data['fileurl'])) {
1052  
1053        if (valid_url($data['filepath'], TRUE)) {
1054          // A full http:// file path has been passed.
1055          $playlist_data['playlist'][$key]['filepath'] = FALSE; // Flag that we don't know the server path.
1056          $playlist_data['playlist'][$key]['fileurl'] = $data['filepath'];
1057        }
1058        elseif (isset($data['fid'])) {
1059          // This is a classes upload module files array.
1060          $playlist_data['playlist'][$key]['filename'] = $data['filename'];
1061          $playlist_data['playlist'][$key]['fileurl'] = swftools_get_media_url($playlist_data['playlist'][$key]['filepath'], FALSE);
1062        }
1063        else {
1064          // Otherwise just complete url path.
1065          $playlist_data['playlist'][$key]['filename'] = $data['filename'];
1066          if (!$stream) {
1067  
1068  //          This code was building the wrong path when used with CCK filefield, so it may have been
1069  //          causing problems in other circumstances when partial paths were sent to a playlist
1070  //          $playlist_data['playlist'][$key]['filepath'] = swftools_get_media_path() . $data['filepath'];
1071  //          $playlist_data['playlist'][$key]['fileurl'] = swftools_strip_base_root(swftools_get_media_url($playlist_data['playlist'][$key]['filepath']));
1072  //          The code below is taken from the main swf() function, and uses file_create_path first
1073            
1074            // Then check if files are being sourced locally, and if they are build a file path
1075            if (swftools_get_media_path()) {
1076              $file = file_create_path($data['filepath']);
1077            }
1078            else {
1079              $file = $data['filepath'];
1080            }
1081  
1082            // Build a filepath and url 
1083            $playlist_data['playlist'][$key]['filepath'] = $file;
1084            $playlist_data['playlist'][$key]['fileurl'] = swftools_strip_base_root(swftools_get_media_url($file));
1085          
1086          }
1087          else {
1088            $playlist_data['playlist'][$key]['filepath'] = $data['filepath'];
1089                $playlist_data['playlist'][$key]['fileurl'] = $data['filepath'];          
1090              }
1091        }
1092      }
1093      if (!isset($data['filename'])) {
1094        $path_parts = pathinfo($playlist_data['playlist'][$key]['fileurl']);
1095        $playlist_data['playlist'][$key]['filename'] = $path_parts['basename'];
1096      }
1097  
1098      if (!isset($data['title'])) {
1099        $playlist_data['playlist'][$key]['title'] = $playlist_data['playlist'][$key]['filename'];
1100      }
1101      // Here is where you might call audio.module or video.module for more.
1102    }
1103  
1104    // Note, we want to exit quickly if the caller did not want us to
1105    // dynamically determine the display action by passing $get_action = FALSE.
1106    if (!$get_action) {
1107      // The caller knows what swftools action to set, so exit here.
1108      return $playlist_data;
1109    }
1110  
1111    // Try to work out the action from the files passed.
1112    $first_valid_file_type = FALSE;
1113    $mixed_media = FALSE;
1114  
1115    // Process the files attached to the node to determine the correct action.
1116    foreach ($playlist_data['playlist'] AS $key => $data) {
1117  
1118      // fileurl is always set, irrespective of what we are passing, so use this to determine extension
1119      $path_parts = pathinfo($data['fileurl']);
1120      
1121      // Get the extension for the file
1122      $extension = strtolower($path_parts['extension']);
1123  
1124      // Only try to determine actions if there's an extension to work with
1125      if ($extension) {
1126      
1127        // Determine if this is an image type
1128        if (strpos('|jpg|jpeg|gif|png|', $extension)) {
1129          // Treat all types of images as the same file type
1130          $extension = 'img';
1131        }
1132    
1133        // Only process the file if $type_filter is empty (ie. no filter)
1134        // or if the extension is declared in the $type_filter array.
1135        if (!count($type_filter) || in_array($extension, $type_filter)) {
1136          // $first_valid_file_type stores the file type of the first valid file.
1137          // This will be compared to subsequent files and if two files
1138          // have different types, the action will be defined as SWFTOOLS_MEDIA_DISPLAY_LIST
1139          // in order to utilize a flexible media player.
1140          if (!$first_valid_file_type) {
1141            $first_valid_file_type = $extension;
1142          }
1143          else {
1144            if ($first_valid_file_type != $extension) {
1145              $mixed_media = TRUE;
1146            }
1147          }
1148        }
1149        else {
1150          // This file is not desired so remove it
1151          unset($playlist_data['playlist'][$key]);
1152        }
1153      }
1154    }
1155      
1156    // Make a decision based on analysing the file array.
1157    if ($first_valid_file_type == '') {
1158      // No files passed our test.
1159      return FALSE;
1160    }
1161  
1162    // Determine the required action.
1163    if ($mixed_media) {
1164      // We have files of multiple types.
1165      $action = SWFTOOLS_MEDIA_DISPLAY_LIST;
1166    }
1167    else {
1168      // We only had one file type, so discover the action for that type by
1169      // calling swftools_get_action() with a dummy filename
1170      $action = swftools_get_action('dummy.' . $first_valid_file_type);
1171    }
1172  
1173    // Pluralize the action for multiple files if not already pluralized
1174    if (count($playlist_data['playlist']) > 1 && substr($action, -5, 5) != '_list') {
1175      $action = $action . '_list';
1176    }
1177  
1178    // Assign the action to the playlist data ready for return
1179    $playlist_data['action'] = $action;
1180  
1181    // Return the resulting playlist data
1182    return $playlist_data;
1183  }
1184  
1185  
1186  /**
1187   * Next three filter related code ported from flash_filter.
1188   *
1189   */
1190  
1191  /*
1192   * Implementation of hook_filter_tips
1193   *
1194   */
1195  function swftools_filter_tips($delta, $format, $long = false) {
1196    if ($long) {
1197      return t('
1198      <h3 id="swftools_filter">SWF Tools Filter</h3>
1199      <p>The basic syntax for embedding a flash file (.swf), flash movie (.flv) or audio file (.mp3) is:</p>
1200      <blockquote><code>[swf file="filename.swf"]</code></blockquote>
1201  
1202      <p>If you would like to override SWF Tools and flash player default settings,
1203         you can specify additional parameters. For example:</p>
1204      <blockquote><code>[swf file="song.mp3" flashvars="backcolor=#AABBCC&&forecolor=#11AA11"]</code></blockquote>
1205      <p>If you would like to output a list of files then the format is:</p>
1206      <blockquote><code>[swf files="image1.jpg&&image2.jpg&&..."]</code></blockquote>
1207      SWF Tools Filter will accept following:
1208      <ul>
1209        <li><b>params</b> : You can specify values for parameters to be passed to Flash
1210                             to control the appearance of the output. Typical values are
1211                             bgcolor and wmode. Example: <code>params="wmode=true&&bgcolor="#00FF00"</code>
1212                             Alternatively you can supply each parameter individually without using
1213                             <code>params</code>. Example <code>wmode="true" bgcolor="#00FF00"</code></li>
1214        <li><b>flashvars</b> : You can specify values for output as flashvars, which
1215                             become available to the Flash movie that is playing. This is often done
1216                             to control a media player. Refer to the documentation of the flash player
1217                             you are using to know what flashvar options are available.
1218                             Example: <code>flashvars="autostart=true&&volume=80"</code></li>
1219        <li><b>methods</b> : Optional information about how to display the file. The most
1220                             common usage is to specify a particular media player and
1221                             thus override the default specified on the settings page.
1222                             Example: <code>methods="player=onepixelout_mp3"</code></li>
1223         </ul>
1224        <p><strong>WARNING</strong>: with params, flashvars and othervars, pass multiple values
1225                        separated by <strong>&amp;&amp;</strong>.</p>');
1226    }
1227    else {
1228      return t('You may use !swftools_filter_help to display Flash files inline', array("!swftools_filter_help" => l('<swf file="song.mp3">', "filter/tips/$format", array('query' => 'swftools_filter'))));
1229    }
1230  }
1231  
1232  /*
1233   * Implementation of hook_filter
1234   *
1235   */
1236  function swftools_filter($op, $delta = 0, $format = -1, $text = '') {
1237    switch ($op) {
1238      case 'list':
1239        return array(0 => t('SWF Tools filter'));
1240      case 'no cache':
1241        return FALSE;
1242      case 'description':
1243        return t('Substitutes [swf file="filename.flv"] or [swf files="file1.jpg&&file2.jpg"] with embedding code.');
1244      case 'prepare':
1245          // replace <swf > with [swf ] to prevent other filters stripping
1246          return (preg_replace('/\<(swflist|swf)\s*(.*)>/sU', '[\1 \2]', $text));
1247      case 'process':
1248        return _swftools_filter_process_text($text);
1249    }
1250  }
1251  
1252  /*
1253   * This function processes the filter text that the user has added to the text area.
1254   * If the filter is wrapped in <p></p> then these are stripped as part of the processing
1255   * This eliminates a validation error in the resulting mark up if SWF Tools filter is
1256   * being used in conjunction with other HTML filters that correct line breaks.
1257   * It won't work in EVERY case, but it will work in MOST cases.
1258   * Filters that are embedded in-line with text will continue to fail validation.
1259   */
1260  function _swftools_filter_process_text($text) {
1261    $endl = chr(13) ;
1262    if (preg_match_all('@(?:<p>)?\[(swflist|swf)\s*(.*?)\](?:</p>)?@s', $text, $match)) {
1263      // $match[0][#] .... fully matched string <swf|swflist parm_0="value_0" parm_1="value_1" parm_2="value_2">
1264      // $match[1][#] .... matched tag type ( swf | swflist )
1265      // $match[2][#] .... full params string until the closing '>'
1266      
1267      $swftools_parameters = array('file', 'params', 'flashvars', 'othervars', 'methods', 'files');
1268      $match_vars = array();
1269      foreach ($match[2] as $key => $passed_parameters) {
1270        //preg_match_all('/(\w*)=\"(.*?)\"/', $passed_parameters, $match_vars[$key]);
1271        preg_match_all('/(\w*)=(?:\"|&quot;)(.*?)(?:\"|&quot;)/', $passed_parameters, $match_vars[$key]);
1272        // $match_vars[0][#] .... fully matched string
1273        // $match_vars[1][#] .... matched parameter, eg flashvars, params
1274        // $match_vars[2][#] .... value after the '='
1275        
1276        // Process the parameters onto the $prepared array.
1277        // Search for standard parameters, parse the values out onto the array.
1278        foreach ($match_vars[$key][1] as $vars_key => $vars_name) {
1279  
1280          // Switch to swf or swflist, based on file or files
1281          // Need to tidy up this line, probably use switch/case
1282          if ($vars_name == 'file') {
1283            $match[1][$key] = 'swf';
1284          }
1285          else {
1286            if ($vars_name == 'files') {
1287              $match[1][$key] = 'swflist';
1288            }
1289          }
1290  
1291          if ($vars_name == 'file') {
1292            $prepared[$key][$vars_name] = $match_vars[$key][2][$vars_key];
1293            unset ($match_vars[$key][1][$vars_key]);
1294          }
1295          elseif (in_array($vars_name, $swftools_parameters)) {
1296            $prepared[$key][$vars_name] = swftools_url_parse(str_replace(array('&amp;&amp;', '&&'), '&', $match_vars[$key][2][$vars_key]));
1297            unset ($match_vars[$key][1][$vars_key]);
1298          }
1299          else {
1300            $prepared[$key]['othervars'][$vars_name] = $match_vars[$key][2][$vars_key];
1301          }
1302        }
1303  
1304        // Search for remaining parameters, map them as elements of the standard parameters.
1305        if (isset($prepared[$key]['methods']['player'])) {
1306          $player = strtolower($prepared[$key]['methods']['player']);
1307        }
1308        else {
1309          $player_key = array_search('player', $match_vars[$key][1]);
1310          if ($player_key!==FALSE) {
1311            $player = strtolower($match_vars[$key][2][$player_key]);
1312          }
1313          else {
1314            $player = FALSE;
1315          }
1316        }
1317        $prepared[$key]['methods']['player'] = $player;
1318  
1319        if (count($match_vars[$key][1])) {
1320          // Find out if a player has been set.
1321          foreach ($match_vars[$key][1] as $vars_key => $vars_name) {
1322            if ($parent = swftools_get_filter_alias($vars_name, $player)) {
1323              if ($parent) {
1324                $prepared[$key][$parent][$vars_name] = $match_vars[$key][2][$vars_key];
1325              }
1326            }
1327          }
1328        }
1329  
1330        // Just assigning parameters as false if not already set on the $prepared array.
1331        // Really just to avoid declaration warnings when we call swf and swf_list
1332        if (count($prepared[$key])) {
1333          foreach ($swftools_parameters AS $swfparameter) {
1334            if (!isset($prepared[$key][$swfparameter])) {
1335              $prepared[$key][$swfparameter] = FALSE;
1336            }
1337          }
1338        }
1339  
1340        // Assemble in to an array of options ready to pass
1341        $options = array();
1342        $options['params'] = $prepared[$key]['params'];
1343        $options['flashvars'] = $prepared[$key]['flashvars'];
1344        $options['othervars'] = $prepared[$key]['othervars'];
1345        $options['methods'] = $prepared[$key]['methods'];
1346  
1347        // Set a flag to show if we need to determine an action, or if one was provided
1348        $get_action = TRUE;
1349        if (isset($options['methods']['action'])) {
1350          $get_action = FALSE;
1351        }
1352        
1353        switch ($match[1][$key]) {
1354          case 'swf':
1355            $replace = swf($prepared[$key]['file'], $options);
1356            break;
1357          case 'swflist':
1358            if ($prepared[$key]['files']) {
1359              foreach ($prepared[$key]['files'] AS $name => $filename) {
1360                if (!$filename) {
1361                  $prepared[$key]['files'][$name] = $name;
1362                }
1363              }
1364              
1365              // Work out if this is a streamed playlist (in which case we will skip file existence checks)
1366              $stream = FALSE;
1367              if (isset($options['othervars']['stream'])) {
1368                $stream = TRUE;
1369              }
1370  
1371              // Get playlist data, but don't determine action if the user specified a player
1372              //$playlist_data = swftools_prepare_playlist_data($prepared[$key]['files'], '', !$player, array(), $stream);
1373              $playlist_data = swftools_prepare_playlist_data($prepared[$key]['files'], '', $get_action, array(), $stream);
1374              $replace = swf_list($playlist_data, $options);
1375            }
1376            else {
1377              $replace = '<!-- No files passed to the playlist -->';
1378            }
1379            break;
1380        }
1381        $matched[] = $match[0][$key];
1382        $rewrite[] = $replace;
1383      }
1384      return str_replace($matched, $rewrite, $text);
1385    }
1386    return $text;
1387  }
1388  
1389  /*
1390   * This implements a hook that extends the parameters that can be passed to the filter
1391   * so that myvar="value" can be mapped to flashvars, etc.
1392   *
1393   */
1394  function swftools_get_filter_alias($var, $player = FALSE) {
1395  
1396    static $general_mapping = array();
1397    static $player_mapping = array();
1398  
1399    if (!count($general_mapping)) {
1400      // Build up the mapping arrays.
1401      $general_mapping = array(
1402        'action'            => 'methods',
1403        'embed'             => 'methods',
1404        'width'             => 'params',
1405        'height'            => 'params',
1406        'swliveconnect'     => 'params',
1407        'play'              => 'params',
1408        'loop'              => 'params',
1409        'menu'              => 'params',
1410        'quality'           => 'params',
1411        'scale'             => 'params',
1412        'align'             => 'params',
1413        'salign'            => 'params',
1414        'wmode'             => 'params',
1415        'bgcolor'           => 'params',
1416        'base'              => 'params',
1417        'version'           => 'params',
1418        'allowfullscreen'   => 'params',
1419        'allowscriptaccess' => 'params',
1420      );
1421      if (!count($player_mapping)) {
1422        $player_mapping = module_invoke_all('swftools_variable_mapping');
1423      }
1424      $combined = array();
1425      if (count($player_mapping)) {
1426        foreach($player_mapping AS $mapping) {
1427          $combined = array_merge($combined, $mapping);
1428        }
1429        $general_mapping = array_merge($combined, $general_mapping);
1430      }
1431    }
1432    // Return the parent of the variable.
1433    if ($player && isset($player_mapping[$player][$var])) {
1434        return $player_mapping[$player][$var];
1435    }
1436    else {
1437      return (isset($general_mapping[$var])) ? $general_mapping[$var] : FALSE;
1438    }
1439  }
1440  
1441  function swftools_url_parse($string) {
1442    $return = array();
1443    $pairs = split("&", $string);
1444    foreach($pairs as $pair) {
1445      $splitpair = split("=", $pair);
1446      //if(!$splitpair[1] || array_key_exists($splitpair[0], $return)) {
1447      if(!isset($splitpair[1]) || array_key_exists($splitpair[0], $return)) {
1448        $return[] = $splitpair[0];
1449      }
1450      else {
1451        $return[$splitpair[0]] = $splitpair[1];
1452      }
1453    }
1454    return $return;
1455  }
1456  
1457  /**
1458   * Implementation of hook_theme
1459   */
1460  function swftools_theme() {
1461    return array(
1462      'swftools_embed' => array(
1463        'arguments' => array('embed_code' => NULL, 'action' => NULL, 'methods' => NULL, 'vars' => array(), 'html_alt' => NULL),
1464      ),
1465      'swftools_formatter_swftools' => array(
1466        'arguments' => array('element' => NULL),
1467        'function' => 'theme_swftools_formatter_swftools',
1468      ),
1469      'swftools_formatter_swftools_no_file' => array(
1470        'arguments' => array('element' => NULL),
1471        'function' => 'theme_swftools_formatter_swftools',
1472      ),
1473      'swftools_formatter_swftools_playlist' => array(
1474        'arguments' => array('element' => NULL),
1475        'function' => 'theme_swftools_formatter_playlist',
1476      ),
1477    );
1478  }
1479  
1480  
1481  /**
1482   * Implementation of hook_file_download
1483   * Allows SWF Tools to work with a private file system that might include files
1484   * upload outside the control of an upload module, e.g. FTP of large video files
1485   * If the file is in the playlists directory then return a valid header.
1486   * If the file is of a supported type, based on extension, then return a valid header.
1487   * Note: if any other module returns -1 for this file then access will be denied
1488   * even if SWF Tools tries to allow it. See hook_file_download for details.
1489   */
1490  function swftools_file_download($file) {
1491  
1492    // See if we have a playlist - SWF Tools can allow access to those since it creates them
1493    $playlist_path = preg_quote(variable_get('swftools_playlist_path', SWFTOOLS_PLAYLIST_PATH));
1494    if (preg_match('/^'.$playlist_path.'/', $file)) {
1495      return array(
1496        'Content-Type: '. $mime_types[$extension],
1497        'Content-Length: '. filesize(file_create_path($file)),
1498      );
1499    }
1500  
1501    // If SWF Tools is allowed to grant access then check to see if access will be allowed
1502    if (variable_get('swftools_grant_access_to_private_files', SWFTOOLS_GRANT_ACCESS_TO_PRIVATE_FILES)) {
1503  
1504      // Get extension of file in question
1505      $extension = pathinfo($file, PATHINFO_EXTENSION);
1506  
1507      // Get list of extensions that SWF Tools can grant access to
1508      $extensions = variable_get('swftools_grant_access_extensions', SWFTOOLS_GRANT_ACCESS_EXTENSIONS);
1509  
1510      // Need access to the user object
1511      global $user;
1512  
1513      // Check if SWF Tools should grant access - skip the check for user #1
1514      if ($user->uid != 1) {
1515        $regex = '/\.('. ereg_replace(' +', '|', preg_quote($extensions)) .')$/i';
1516        if (!preg_match($regex, $file)) {
1517          return;
1518        }
1519      }
1520  
1521      // Build an array of types that SWF Tools can react to
1522      $mime_types = array(
1523        'swf'  => 'application/x-shockwave-flash',
1524        'flv'  => 'application/octet-stream',
1525        'xml'  => 'text/xml',
1526        'mp3'  => 'audio/mpeg',
1527        'jpg'  => 'image/jpeg',
1528        'jpeg' => 'image/jpeg',
1529        'png'  => 'image/gif',
1530      );
1531  
1532      // If file is one of the above types, based on the extension, return headers
1533      if ($mime_types[$extension]) {
1534        return array(
1535          'Content-Type: '. $mime_types[$extension],
1536          'Content-Length: '. filesize(file_create_path($file)),
1537        );
1538      }
1539    }
1540  }
1541  
1542  
1543  /**
1544   * Implementation of swftools_embed hook
1545   * Returns the markup for the page.
1546   * This method generates standards compliant HTML
1547   *
1548   */
1549  function swftools_swftools_embed($action = 'add_js', $methods = FALSE, $vars = FALSE, $html_alt = '') {
1550  
1551    // If simply adding JavaScript then no further action is necessary
1552    if ($action == 'add_js') {
1553      return;
1554    }
1555  
1556    // An id isn't always set, so populate a blank to avoid a notice error later
1557    $vars->othervars += array(
1558      'id' => '',
1559    );
1560  
1561    // IE6 says the page has error when using Wijering 4 media player and if the object isn't given an id
1562    // The id must be unique for each player, and must start with letters - it cannot be only numbers
1563    // So let's generate a unique id in the same way we do with SWF Object, and assign it to our object
1564    $wijering_fix = '';
1565  
1566    // Initialise a counter to give each div a unique id
1567    static $unique_id = 0;
1568    $unique_id++;
1569  
1570    // Construct a unique id for each div by using time() combined with $unique_id
1571    // This is necessary to prevent clashes between cached content
1572    $id = time() . $unique_id;
1573  
1574    $wijering_fix = ' id="swf' . $id . '"';
1575  
1576    $P = $vars->params; // For legibility.
1577  
1578    $width_attr = ($P['width']) ? ' width="'. $P['width'] .'"' : '';
1579    $height_attr = ($P['height']) ? ' height="'. $P['height'] .'"' : '';
1580    $loop = _swftools_tf($P['loop']);
1581    $menu = _swftools_tf($P['menu']);
1582    $play = _swftools_tf($P['play']);
1583    $fullscreen = _swftools_tf($P['allowfullscreen']);
1584    $flashvars = str_replace('&', '&amp;', $P['flashvars']);
1585  
1586    $id = ($vars->othervars['id']) ? ' id="'. $vars->othervars['id'] .'"' : '';
1587    $name = ($vars->othervars['id']) ? ' name="'. $vars->othervars['id'] .'"' : '';
1588    $swliveconnect = ($P['swliveconnect']) ? ' swliveconnect="'. $P['swliveconnect'] .'"' : '';
1589  
1590    $params  = $id;
1591    $params .= '<param name="allowScriptAccess" value="' . $P['allowscriptaccess'] . '" />' . "\n";
1592    $params .= '<param name="wmode"             value="' . $P['wmode']   . '" />' . "\n";
1593    $params .= '<param name="bgcolor"           value="' . $P['bgcolor'] . '" />' . "\n";
1594    $params .= '<param name="scale"             value="' . $P['scale']  . '" />' . "\n";
1595    $params .= '<param name="quality"           value="' . $P['quality'] . '" />' . "\n";
1596    $params .= '<param name="align"             value="' . $P['align'] . '" />' . "\n";
1597    $params .= '<param name="allowfullscreen"   value="' . $P['allowfullscreen'] . '" />' . "\n";
1598    $params .= '<param name="base"              value="' . $P['base'] . '" />' . "\n";
1599    $params .= '<param name="play"              value="' . $play . '" />' . "\n";
1600    $params .= '<param name="menu"              value="' . $menu . '" />' . "\n";
1601    $params .= '<param name="loop"              value="' . $loop . '" />' . "\n";
1602    $params .= $flashvars ? '<param name="flashvars"  value="' . $flashvars . '" />' . "\n" : '' ;
1603  
1604    $html  = '<div class="swftools">' . "\n";
1605    $html .= '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' . $width_attr . $height_attr . $wijering_fix . '>' . "\n";
1606    $html .= '<param name="movie" value="' . $P['src'] . '" />' . "\n";
1607    $html .= $params;
1608    $html .= '<!--[if gte IE 7]>-->' . "\n";
1609    $html .= '<object type="application/x-shockwave-flash" data="' . $P['src'] . '"' . $width_attr . $height_attr . '>' . "\n";
1610    $html .= $params;
1611    $html .= '<!--<![endif]-->' . "\n";
1612    $html .= $html_alt . "\n";
1613    $html .= '<!--[if gte IE 7]>-->' . "\n";
1614    $html .= '</object>' . "\n";
1615    $html .= '<!--<![endif]-->' . "\n";
1616    $html .= '</object>' . "\n";
1617    $html .= '</div>' . "\n";
1618  
1619    return $html;
1620  }
1621  
1622  
1623  /*
1624   * Called by settings pages for players as a custom handler in place of system_settings_form_submit()
1625   * It flattens extensive arrays of settings, and resets the filter cache
1626   */
1627  function swftools_admin_form_submit($form, &$form_state) {
1628  
1629    // Determine what operation is being performed and store in $op
1630    $op = isset($form_state['values']['op']) ? $form_state['values']['op'] : '';
1631  
1632    // Exclude unnecessary elements
1633    unset(
1634      $form_state['values']['submit'],
1635      $form_state['values']['reset'],
1636      $form_state['values']['form_id'],
1637      $form_state['values']['op'],
1638      $form_state['values']['form_token'],
1639      $form_state['values']['form_build_id']
1640    );
1641    
1642    // Flatten settings for saving
1643    $saved = array();
1644    
1645    // Process array of parameters that have been passed
1646    foreach ($form_state['values'] AS $player => $settings) {
1647  
1648      if ($op == t('Reset to defaults')) {
1649        variable_del('swftools_'. $player);
1650      }
1651      else {
1652        $flat[$player] = array();
1653        if (is_array($settings)) {
1654          foreach ($settings AS $category => $vars) {
1655            $flat[$player] = array_merge($flat[$player], $vars);
1656          }
1657          variable_set('swftools_'. $player, $flat[$player]);
1658        }
1659      }
1660    }
1661  
1662    // Confirmation message
1663    if ($op == t('Reset to defaults')) {
1664      drupal_set_message(t('The configuration options have been reset to their default values.'));
1665    }
1666    else {
1667      drupal_set_message(t('The configuration options have been saved.'));
1668    }
1669  
1670    // Clear caches
1671    drupal_flush_all_caches();
1672  
1673  }
1674  
1675  
1676  /**
1677   * Report the methods that are supported by the SWF Tools module.
1678   * 
1679   * @return
1680   *   An array of methods and players provided by the default SWF Tools installation.
1681   */
1682  function swftools_swftools_methods() {
1683  
1684    // Initialise array
1685    $methods = array();
1686  
1687    // Module implements a default plain HTML embedding method called 'direct'
1688    $methods[SWFTOOLS_EMBED_METHOD][SWFTOOLS_NOJAVASCRIPT] = array(
1689      'name'        => SWFTOOLS_NOJAVASCRIPT,
1690      'module'      => 'swftools',
1691      'shared_file' => '',
1692      'title'       => t('Direct embedding - do not use JavaScript replacement'),
1693    );
1694  
1695    // Module implements swf embedding
1696    $methods[SWFTOOLS_SWF_DISPLAY_DIRECT][SWFTOOLS_SWF] = array(
1697      'name'        => SWFTOOLS_SWF,
1698      'module'      => 'swftools',
1699      'shared_file' => '',
1700      'title'       => t('Use SWF file directly, no streaming through another SWF.'),
1701    );
1702  
1703    // Module implements custom embedding of an swf
1704    $methods[SWFTOOLS_SWF_DISPLAY_DIRECT][SWFTOOLS_CUSTOM] = array(
1705      'name'        => SWFTOOLS_CUSTOM,
1706      'module'      => 'swftools',
1707      'shared_file' => '', // Assigned later.
1708      'title'       => t('Use custom SWF file.'),
1709    );
1710  
1711    // Add in the methods from genericplayers.module
1712    $methods = array_merge($methods, genericplayers_swftools_methods());
1713    
1714    // Return the methods that are native to SWF Tools
1715    return $methods;
1716  }
1717  
1718  
1719  /**
1720   * Return a customised file download url that doesn't include the $base_root
1721   * 
1722   * @param $file
1723   *   The path of the file for which a download link is return
1724   * @return
1725   *   The path to the file including any $base_path but excluding $base_root
1726   */
1727  function swftools_strip_base_root($file) {
1728    
1729    // Temporarily disable this feature - it may be causing some issues
1730    return $file;
1731    
1732    // Only produce relative url if using clean urls
1733    return str_replace($GLOBALS['base_root'], '', $file);
1734    
1735  }
1736  
1737  
1738  /**
1739   * Helper function to set the size of the swf content in to $vars->params
1740   * 
1741   * @param $vars
1742   *   $vars arrays that is being assembled by SWF Tools.
1743   * @param $player
1744   *   The array of player data for the player that will be used.
1745   * @return
1746   *   Nothing - function directly sets $vars.
1747   */
1748  function swftools_set_size(&$vars, $player = array()) {
1749    
1750    // Not a pretty piece of code, but should be ok for the moment. We are
1751    // purposefully passing the width and height
1752    // if we have them. Unsure if this will cause problems with some players.
1753    // It's an ugly piece of code, but will remain in this form until a clearer
1754    // solution arises.
1755    //
1756    // It may be that, in hook_swftools_methods, the flash player indicates that
1757    // it *want* certain values copied b/t params and flashvars.
1758    // The code below was patch to fix notice errors, but it broke flash node autodetect
1759    // Flash node has been patched to fix this by changing zero height / width to null
1760  
1761    // TODO : Is it really necessary to set the height and width in to the flashvars?
1762    
1763    // If flashvars are empty, but params are set, populate flashvars with params
1764    if (empty($vars->flashvars['width']) && empty($vars->flashvars['height'])) {
1765      if (!empty($vars->params['width']) && !empty($vars->params['height'])) {
1766        $vars->flashvars['width'] = $vars->params['width'];
1767        $vars->flashvars['height'] = $vars->params['height'];
1768        return;
1769      }
1770    }
1771    
1772    // If params are empty, but flashvars are set, populate params with flashvars
1773    if (empty($vars->params['width']) && empty($vars->params['height'])) {
1774      if (!empty($vars->flashvars['width']) && !empty($vars->flashvars['height'])) {
1775        $vars->params['width'] = $vars->flashvars['width'];
1776        $vars->params['height'] = $vars->flashvars['height'];
1777        return;
1778      }
1779    }
1780  
1781    // If still empty we try and get them from the file to be embedded
1782    if (empty($vars->params['height']) || empty($vars->params['width'])) {
1783      $info = swftools_get_info($vars->params['src_path']);
1784      if ($info) {
1785        $vars->params['height'] = $info['height'];
1786        $vars->params['width'] = $info['width'];
1787        return;
1788      };
1789    }
1790    
1791    // If we STILL don't have a width after all this, try to use fallback player defaults
1792    if (empty($vars->params['width']) && isset($player['width'])) {
1793      $vars->params['width'] = $player['width'];
1794    }
1795  
1796    // If we STILL don't have a height after all this, try to use fallback player defaults
1797    if (empty($vars->params['height']) && isset($player['height'])) {
1798      $vars->params['height'] = $player['height'];
1799    }
1800    
1801  }
1802  
1803  
1804  /**
1805   * Implementation of hook_field_formatter_info().
1806   */
1807  function swftools_field_formatter_info() {
1808    return array(
1809      'swftools_no_file' => array('label' => t('SWF Tools - no download link'),
1810        'field types' => array('filefield', 'link'),
1811        'multiple values' => CONTENT_HANDLE_CORE,
1812      ),
1813      'swftools_playlist' => array('label' => t('SWF Tools - playlist'),
1814        'field types' => array('filefield'),
1815        'multiple values' => CONTENT_HANDLE_MODULE,
1816      ),
1817      'swftools' => array('label' => t('SWF Tools - with download link'),
1818        'field types' => array('filefield', 'link'),
1819        'multiple values' => CONTENT_HANDLE_CORE,
1820      ),    
1821    );
1822  }
1823  
1824  
1825  /**
1826   * Theme function to turn CCK filefield or link in to flash content.
1827   * 
1828   * @param $element
1829   *   The element to render.
1830   * @return
1831   *   A string of markup to produce the flash content, or nothing if the element was empty.
1832   */
1833  function theme_swftools_formatter_swftools($element) {
1834    // Check if this is a filefield, link or neither
1835    if (!empty($element['#item']['fid'])) {
1836      $is_filefield = true;
1837      $media_url = $element['#item']['filepath'];
1838    }
1839    elseif (!empty($element['#item']['url'])) {
1840      $is_link = true;
1841      $media_url = $element['#item']['url'];
1842      
1843      // add the query to the base url, if necessary
1844      if (strlen($element['#item']['query']) > 0) {
1845        $media_url .= "?" . ($element['#item']['query']);
1846      }
1847      
1848      // add the fragment to the url, if necessary
1849      if (strlen($element['#item']['fragment']) > 0) {
1850        $media_url .= "#" . ($element['#item']['fragment']);
1851      }
1852    }
1853    else {
1854      return '';
1855    }
1856    
1857    // Get the markup for the flash content from swf()
1858    $return = swf($media_url);
1859    
1860    // Add the download link if required
1861    if ($element['#formatter'] == 'swftools') {
1862      if ($is_filefield) {
1863        $return .= "\n" . theme('filefield_formatter_default', $element);
1864      }
1865      else if ($is_link) {
1866          $return .= "\n" . theme('link_formatter_default', $element);
1867      }
1868    }
1869  
1870    // Return the resulting markup
1871    return $return;
1872  }
1873  
1874  
1875  /**
1876   * Theme function to turn multiple value CCK filefield in to a playlist.
1877   * 
1878   * @param $element
1879   *   The element to render.
1880   * @return
1881   *   A string of markup to produce the flash content, or nothing if the element was empty.
1882   */
1883  function theme_swftools_formatter_playlist($element) {
1884    
1885    // Initialise an array for results
1886    $files = array();
1887    
1888    // Get the children
1889    $children = element_children($element);
1890    
1891    // If there is only one child then maybe we don't want a playlist
1892    if (count($children) == 1) {
1893  
1894      // Pop the first value of the children array
1895      $_children = $children;
1896      $child = array_pop($_children);
1897          
1898      // Get the name of the alternate formatter for this content type
1899      $formatter_name = variable_get('swftools_' . $element['#type_name'] . '_' . $element['#field_name'], 'swftools_playlist');
1900  
1901      // What happens next depends on the formatter name
1902      
1903      switch ($formatter_name) {
1904        
1905        case 'hidden':      
1906      
1907          // If the format is set to hidden then return nothing
1908          if ($formatter_name == 'hidden') {
1909            return;
1910          }
1911          
1912        case 'swftools_playlist':
1913          
1914          // If swftools_playlist don't do anything different
1915          break;
1916  
1917        default:
1918  
1919          // Find out what the alternate formatter should be
1920          if ($formatter = _content_get_formatter($formatter_name, 'filefield')) {
1921            $theme = $formatter['module'] .'_formatter_'. $formatter_name;
1922      
1923            // Theme the element according to the alternate formatter
1924            return theme($theme, $element[$child]);
1925            
1926          }
1927      }
1928    }
1929  
1930    // Cycle through the file elements
1931    foreach ($children as $key) {
1932  
1933      // If nothing has been uploaded then there are items, but they are empty, so check they are set
1934      if (isset($element[$key]['#item']['filepath'])) {
1935        $files[] = $element[$key]['#item']['filepath'];
1936      }
1937    }
1938    
1939    // If files array is empty then there is nothing to be rendered
1940    if (empty($files)) {
1941      return;
1942    }
1943    
1944    // But if we got something then we can call swf() now to render it
1945    return swf($files);
1946    
1947  }


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7