Pastebin is 300% more awesome when you are logged in. Sign Up, it's FREE!
Guest

Wordpress Audio Player plugin modified for HTML5 fallback

By: upekshapriya on Feb 7th, 2013  |  syntax: PHP  |  size: 33.77 KB  |  hits: 111  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. <?php
  2. /*
  3. Plugin Name: Audio player
  4. Plugin URI: http://wpaudioplayer.com
  5. Description: Audio Player is a highly configurable but simple mp3 player for all your audio needs. You can customise the player's colour scheme to match your blog theme, have it automatically show track information from the encoded ID3 tags and more. Go to your Settings page to start configuring it.
  6. Version: 2.0.4.6a
  7. Author: Martin Laine mod for html5 player for iDevices http://davidmeharey.com/blog/coding/iphone-html5-audio/
  8. Author URI: http://www.1pixelout.net
  9.  
  10. License:
  11.  
  12. Copyright (c) 2010 Martin Laine
  13.  
  14. Permission is hereby granted, free of charge, to any person obtaining a copy
  15. of this software and associated documentation files (the "Software"), to deal
  16. in the Software without restriction, including without limitation the rights
  17. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  18. copies of the Software, and to permit persons to whom the Software is
  19. furnished to do so, subject to the following conditions:
  20.  
  21. The above copyright notice and this permission notice shall be included in
  22. all copies or substantial portions of the Software.
  23.  
  24. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  25. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  26. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  27. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  28. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  29. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  30. THE SOFTWARE.
  31. */
  32.  
  33. // Pre-2.6 compatibility
  34. if ( ! defined( 'WP_CONTENT_URL' ) )
  35.       define( 'WP_CONTENT_URL', get_option( 'siteurl' ) . '/wp-content' );
  36. if ( ! defined( 'WP_CONTENT_DIR' ) )
  37.       define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' );
  38. if ( ! defined( 'WP_PLUGIN_URL' ) )
  39.       define( 'WP_PLUGIN_URL', WP_CONTENT_URL. '/plugins' );
  40. if ( ! defined( 'WP_PLUGIN_DIR' ) )
  41.       define( 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins' );
  42.  
  43. if (!class_exists('AudioPlayer')) {
  44.     class AudioPlayer {
  45.                 // Name for serialized options saved in database
  46.                 var $optionsName = "AudioPlayer_options";
  47.  
  48.                 var $version = "2.0.4.6";
  49.  
  50.                 var $docURL = "http://wpaudioplayer.com/";
  51.  
  52.                 // Internationalisation
  53.                 var $textDomain = "audio-player";
  54.                 var $languageFileLoaded = false;
  55.  
  56.                 // Various path variables
  57.                 var $pluginURL = "";
  58.                 var $pluginPath = "";
  59.                 var $playerURL = "";
  60.                 var $audioRoot = "";
  61.                 var $audioAbsPath = "";
  62.                 var $isCustomAudioRoot = false;
  63.  
  64.                 // Options page name
  65.                 var $optionsPageName = "audio-player-options";
  66.  
  67.                 // Colour scheme keys
  68.                 var $colorKeys = array(
  69.                         "bg",
  70.                         "leftbg",
  71.                         "lefticon",
  72.                         "voltrack",
  73.                         "volslider",
  74.                         "rightbg",
  75.                         "rightbghover",
  76.                         "righticon",
  77.                         "righticonhover",
  78.                         "text",
  79.                         "track",
  80.                         "border",
  81.                         "loader",
  82.                         "tracker",
  83.                         "skip"
  84.                 );
  85.  
  86.                 // Default colour scheme
  87.                 var $defaultColorScheme = array(
  88.                         "bg" => "E5E5E5",
  89.                         "text" => "333333",
  90.                         "leftbg" => "CCCCCC",
  91.                         "lefticon" => "333333",
  92.                         "volslider" => "666666",
  93.                         "voltrack" => "FFFFFF",
  94.                         "rightbg" => "B4B4B4",
  95.                         "rightbghover" => "999999",
  96.                         "righticon" => "333333",
  97.                         "righticonhover" => "FFFFFF",
  98.                         "track" => "FFFFFF",
  99.                         "loader" => "009900",
  100.                         "border" => "CCCCCC",
  101.                         "tracker" => "DDDDDD",
  102.                         "skip" => "666666",
  103.                         "pagebg" => "FFFFFF",
  104.                         "transparentpagebg" => true
  105.                 );
  106.  
  107.                 // Declare instances global variable
  108.                 var $instances = array();
  109.  
  110.                 // Used to track what needs to be inserted in the footer
  111.                 var $footerCode = "";
  112.  
  113.                 // Initialise playerID (each instance gets unique ID)
  114.                 var $playerID = 0;
  115.  
  116.                 // Flag for dealing with excerpts
  117.                 var $inExcerpt = false;
  118.  
  119.                 /**
  120.                  * Constructor
  121.                  */
  122.                 function AudioPlayer() {
  123.                         // Get plugin URL and absolute path
  124.                         $this->pluginPath = WP_PLUGIN_DIR . "/" . plugin_basename(dirname(__FILE__));
  125.                         $this->pluginURL = WP_PLUGIN_URL . "/" . plugin_basename(dirname(__FILE__));
  126.  
  127.                         if ($_SERVER["HTTPS"] == "on" || $_SERVER["SERVER_PORT_SECURE"] == "1") {
  128.                                 $this->pluginURL = str_replace("http", "https", $this->pluginURL);
  129.                         }
  130.  
  131.                         $this->playerURL = $this->pluginURL . "/assets/player.swf";
  132.  
  133.                         // Load options
  134.                         $this->options = $this->getOptions();
  135.  
  136.                         // Set audio root from options
  137.                         $this->setAudioRoot();
  138.  
  139.                         // Add action and filter hooks to WordPress
  140.  
  141.                         add_action("init", array(&$this, "optionsPanelAction"));
  142.  
  143.                         add_action("admin_menu", array(&$this, "addAdminPages"));
  144.                         add_filter("plugin_action_links", array(&$this, "addConfigureLink"), 10, 2);
  145.  
  146.                         add_action("wp_head", array(&$this, "addHeaderCode"));
  147.                         add_action("wp_footer", array(&$this, "addFooterCode"));
  148.  
  149.                         add_filter("the_content", array(&$this, "processContent"), 2);
  150.                         if (in_array("comments", $this->options["behaviour"])) {
  151.                                 add_filter("comment_text", array(&$this, "processContent"));
  152.                         }
  153.                         add_filter("get_the_excerpt", array(&$this, "inExcerpt"), 1);
  154.                         add_filter("get_the_excerpt", array(&$this, "outOfExcerpt"), 12);
  155.                         add_filter("the_excerpt", array(&$this, "processContent"));
  156.                         add_filter("the_excerpt_rss", array(&$this, "processContent"));
  157.  
  158.                         add_filter("attachment_fields_to_edit", array(&$this, "insertAudioPlayerButton"), 10, 2);
  159.                         add_filter("media_send_to_editor", array(&$this, "sendToEditor"));
  160.  
  161.                         if ($this->options["disableEnclosures"]) {
  162.                                 add_filter("rss_enclosure", array(&$this, "removeEnclosures"));
  163.                                 add_filter("atom_enclosure", array(&$this, "removeEnclosures"));
  164.                         }
  165.  
  166.                         add_shortcode("audio", array(&$this, "insertPlayer"));
  167.                 }
  168.  
  169.                 /**
  170.                  * Removes all enclosures from feeds
  171.                  * @return empty string
  172.                  */
  173.                 function removeEnclosures() {
  174.                         return "";
  175.                 }
  176.  
  177.                 /**
  178.                  * Adds Audio Player options tab to admin menu
  179.                  */
  180.                 function addAdminPages() {
  181.                         global $wp_version;
  182.                         $pageName = add_options_page("Audio player options", "Audio Player", 8, $this->optionsPageName, array(&$this, "outputOptionsSubpanel"));
  183.                         add_action("admin_head-" . $pageName, array(&$this, "addAdminHeaderCode"), 12);
  184.                         // Use the bundled jquery library if we are running WP 2.5 or above
  185.                         if (version_compare($wp_version, "2.5", ">=")) {
  186.                                 wp_enqueue_script("jquery", false, false, "1.2.3");
  187.                         }
  188.                 }
  189.  
  190.                 /**
  191.                  * Adds a settings link next to Audio Player on the plugins page
  192.                  */
  193.                 function addConfigureLink($links, $file) {
  194.                         static $this_plugin;
  195.                         if (!$this_plugin) {
  196.                                 $this_plugin = plugin_basename(__FILE__);
  197.                         }
  198.                         if ($file == $this_plugin) {
  199.                                 $settings_link = '<a href="options-general.php?page=' . $this->optionsPageName . '">' . __('Settings') . '</a>';
  200.                                 array_unshift($links, $settings_link);
  201.                         }
  202.                         return $links;
  203.                 }
  204.  
  205.                 /**
  206.                  * Adds subtle plugin credits to WP footer
  207.                  */
  208.                 function addFooterCredits() {
  209.                         $plugin_data = get_plugin_data(__FILE__);
  210.                         printf('%1$s plugin | Version %2$s<br />', $plugin_data['Name'], $plugin_data['Version']);
  211.                 }
  212.  
  213.                 /**
  214.                  * Loads language files according to locale (only does this once per request)
  215.                  */
  216.                 function loadLanguageFile() {
  217.                         if(!$this->languageFileLoaded) {
  218.                                 load_plugin_textdomain($this->textDomain, "wp-content/plugins/audio-player/languages", dirname( plugin_basename( __FILE__ ) ) . "/languages");
  219.                                 $this->languageFileLoaded = true;
  220.                         }
  221.                 }
  222.  
  223.                 /**
  224.                  * Retrieves options from DB. Also sets defaults if options not set
  225.                  * @return array of options
  226.                  */
  227.                 function getOptions() {
  228.                         // Set default options array to make sure all the necessary options
  229.                         // are available when called
  230.                         $options = array(
  231.                                 "audioFolder" => "/audio",
  232.                                 "playerWidth" => "290",
  233.                                 "enableAnimation" => true,
  234.                                 "showRemaining" => false,
  235.                                 "encodeSource" => true,
  236.                                 "behaviour" => array("default"),
  237.                                 "enclosuresAtTop" => false,
  238.                                 "flashAlternate" => "",
  239.                                 "rssAlternate" => "nothing",
  240.                                 "rssCustomAlternate" => __("[Audio clip: view full post to listen]", $this->textDomain),
  241.                                 "excerptAlternate" => __("[Audio clip: view full post to listen]", $this->textDomain),
  242.                                 "introClip" => "",
  243.                                 "outroClip" => "",
  244.                                 "initialVolume" => "60",
  245.                                 "bufferTime" => "5",
  246.                                 "noInfo" => false,
  247.                                 "checkPolicy" => false,
  248.                                 "rtl" => false,
  249.                                 "disableEnclosures" => false,
  250.  
  251.                                 "colorScheme" => $this->defaultColorScheme
  252.                         );
  253.  
  254.                         $savedOptions = get_option($this->optionsName);
  255.                         if (!empty($savedOptions)) {
  256.                                 foreach ($savedOptions as $key => $option) {
  257.                                         $options[$key] = $option;
  258.                                 }
  259.                         }
  260.  
  261.                         // 1.x version upgrade
  262.                         if (!array_key_exists("version", $options)) {
  263.                                 if (get_option("audio_player_web_path")) $options["audioFolder"] = get_option("audio_player_web_path");
  264.                                 if (get_option("audio_player_behaviour")) $options["behaviour"] = explode(",", get_option("audio_player_behaviour"));
  265.                                 if (get_option("audio_player_rssalternate")) $options["rssAlternate"] = get_option("audio_player_rssalternate");
  266.                                 if (get_option("audio_player_rsscustomalternate")) $options["rssCustomAlternate"] = get_option("audio_player_rsscustomalternate");
  267.                                 if (get_option("audio_player_prefixaudio")) $options["introClip"] = get_option("audio_player_prefixaudio");
  268.                                 if (get_option("audio_player_postfixaudio")) $options["outroClip"] = get_option("audio_player_postfixaudio");
  269.  
  270.                                 if (get_option("audio_player_transparentpagebgcolor")) {
  271.                                         $options["colorScheme"]["bg"] = str_replace("0x", "", get_option("audio_player_bgcolor"));
  272.                                         $options["colorScheme"]["text"] = str_replace("0x", "", get_option("audio_player_textcolor"));
  273.                                         $options["colorScheme"]["skip"] = str_replace("0x", "", get_option("audio_player_textcolor"));
  274.                                         $options["colorScheme"]["leftbg"] = str_replace("0x", "", get_option("audio_player_leftbgcolor"));
  275.                                         $options["colorScheme"]["lefticon"] = str_replace("0x", "", get_option("audio_player_lefticoncolor"));
  276.                                         $options["colorScheme"]["volslider"] = str_replace("0x", "", get_option("audio_player_lefticoncolor"));
  277.                                         $options["colorScheme"]["rightbg"] = str_replace("0x", "", get_option("audio_player_rightbgcolor"));
  278.                                         $options["colorScheme"]["rightbghover"] = str_replace("0x", "", get_option("audio_player_rightbghovercolor"));
  279.                                         $options["colorScheme"]["righticon"] = str_replace("0x", "", get_option("audio_player_righticoncolor"));
  280.                                         $options["colorScheme"]["righticonhover"] = str_replace("0x", "", get_option("audio_player_righticonhovercolor"));
  281.                                         $options["colorScheme"]["track"] = str_replace("0x", "", get_option("audio_player_trackcolor"));
  282.                                         $options["colorScheme"]["loader"] = str_replace("0x", "", get_option("audio_player_loadercolor"));
  283.                                         $options["colorScheme"]["border"] = str_replace("0x", "", get_option("audio_player_bordercolor"));
  284.                                         $options["colorScheme"]["transparentpagebg"] = (bool) get_option("audio_player_transparentpagebgcolor");
  285.                                         $options["colorScheme"]["pagebg"] = str_replace("#", "", get_option("audio_player_pagebgcolor"));
  286.                                 }
  287.                         } else if (version_compare($options["version"], $this->version) == -1) {
  288.                                 // Upgrade code
  289.                                 $options["colorScheme"]["transparentpagebg"] = (bool) $options["colorScheme"]["transparentpagebg"];
  290.                         }
  291.  
  292.                         // Record current version in DB
  293.                         $options["version"] = $this->version;
  294.  
  295.                         // Update DB if necessary
  296.                         update_option($this->optionsName, $options);
  297.  
  298.                         return $options;
  299.                 }
  300.  
  301.                 /**
  302.                  * Writes options to DB
  303.                  */
  304.                 function saveOptions() {
  305.                         update_option($this->optionsName, $this->options);
  306.                 }
  307.  
  308.                 /**
  309.                  * Sets the real audio root from the audio folder option
  310.                  */
  311.                 function setAudioRoot() {
  312.                         $this->audioRoot = $this->options["audioFolder"];
  313.  
  314.                         $this->audioAbsPath = "";
  315.                         $this->isCustomAudioRoot = true;
  316.  
  317.                         if (!$this->isAbsoluteURL($this->audioRoot)) {
  318.                                 $sysDelimiter = '/';
  319.                                 if (strpos(ABSPATH, '\\') !== false) $sysDelimiter = '\\';
  320.                                 $this->audioAbsPath = preg_replace('/[\\\\\/]+/', $sysDelimiter, ABSPATH . $this->audioRoot);
  321.  
  322.                                 $this->isCustomAudioRoot = false;
  323.                                 $this->audioRoot = get_option('siteurl') . $this->audioRoot;
  324.                         }
  325.                 }
  326.  
  327.                 /**
  328.                  * Detects if the user agent is an iPhone or iPod
  329.                  * returns true or false
  330.                  */
  331.                 function detectAppleMobile($query = '') {
  332.                         $container = $_SERVER['HTTP_USER_AGENT'];
  333.                                 $useragents = array(        
  334.                                 "iphone",                // Apple iPhone
  335.                                 "ipod",                      // Apple iPod touch
  336.                                 "ipad",                      // Apple iPad
  337.                                 "aspen",                 // iPhone simulator
  338.                                 "incognito",             // Other iPhone browser
  339.                                 "webmate"            // Other iPhone browser
  340.                         );
  341.                         $applemobile = false;
  342.                         foreach ( $useragents as $useragent ) {
  343.                                 if ( eregi( $useragent, $container ) || file_exists($devfile) ) {
  344.                                         $applemobile = true;
  345.                                 }  
  346.                         }
  347.                          
  348.                         return $applemobile;
  349.                 }
  350.  
  351.  
  352.                 /**
  353.                  * Builds and returns array of options to pass to Flash player
  354.                  * @return array
  355.                  */
  356.                 function getPlayerOptions() {
  357.                         $playerOptions = array();
  358.  
  359.                         $playerOptions["width"] = $this->options["playerWidth"];
  360.  
  361.                         $playerOptions["animation"] = $this->options["enableAnimation"];
  362.                         $playerOptions["encode"] = $this->options["encodeSource"];
  363.                         $playerOptions["initialvolume"] = $this->options["initialVolume"];
  364.                         $playerOptions["remaining"] = $this->options["showRemaining"];
  365.                         $playerOptions["noinfo"] = $this->options["noInfo"];
  366.                         $playerOptions["buffer"] = $this->options["bufferTime"];
  367.                         $playerOptions["checkpolicy"] = $this->options["checkPolicy"];
  368.                         $playerOptions["rtl"] = $this->options["rtl"];
  369.  
  370.                         return array_merge($playerOptions, $this->options["colorScheme"]);
  371.                 }
  372.  
  373.                 // ------------------------------------------------------------------------------
  374.                 // Excerpt helper functions
  375.                 // Sets a flag so we know we are in an automatically created excerpt
  376.                 // ------------------------------------------------------------------------------
  377.  
  378.                 /**
  379.                  * Sets a flag when getting an excerpt
  380.                  * @return excerpt text
  381.                  * @param $text String[optional] unchanged excerpt text
  382.                  */
  383.                 function inExcerpt($text = '') {
  384.                         // Only set the flag when the excerpt is empty and WP creates one automatically)
  385.                         if('' == $text) $this->inExcerpt = true;
  386.  
  387.                         return $text;
  388.                 }
  389.  
  390.                 /**
  391.                  * Resets a flag after getting an excerpt
  392.                  * @return excerpt text
  393.                  * @param $text String[optional] unchanged excerpt text
  394.                  */
  395.                 function outOfExcerpt($text = '') {
  396.                         $this->inExcerpt = false;
  397.  
  398.                         return $text;
  399.                 }
  400.  
  401.                 /**
  402.                  * Filter function (inserts player instances according to behaviour option)
  403.                  * @return the parsed and formatted content
  404.                  * @param $content String[optional] the content to parse
  405.                  */
  406.                 function processContent($content = '') {
  407.                         global $comment;
  408.  
  409.                         $this->loadLanguageFile();
  410.  
  411.                         // Reset instance array (this is so we don't insert duplicate players)
  412.                         $this->instances = array();
  413.  
  414.                         // Replace mp3 links (don't do this in feeds and excerpts)
  415.                         if ( !is_feed() && !$this->inExcerpt && in_array( "links", $this->options["behaviour"] ) ) {
  416.                                 $pattern = "/<a ([^=]+=['\"][^\"']+['\"] )*href=['\"](([^\"']+\.mp3))['\"]( [^=]+=['\"][^\"']+['\"])*>([^<]+)<\/a>/i";
  417.                                 $content = preg_replace_callback( $pattern, array(&$this, "parseCallback"), $content );
  418.                         }
  419.  
  420.                         // Replace [audio syntax]
  421.                         if( in_array( "default", $this->options["behaviour"] ) ) {
  422.                                 $pattern = "/(<p>)?\[audio:(([^]]+))\](<\/p>)?/i";
  423.                                 $content = preg_replace_callback( $pattern, array(&$this, "parseCallback"), $content );
  424.                         }
  425.  
  426.                         // Enclosure integration (don't do this for feeds, excerpts and comments)
  427.                         if( !is_feed() && !$this->inExcerpt && !$comment && in_array( "enclosure", $this->options["behaviour"] ) ) {
  428.                                 $enclosure = get_enclosed($post_id);
  429.  
  430.                                 // Insert intro and outro clips if set
  431.                                 $introClip = $this->options["introClip"];
  432.                                 if( $introClip != "" ) $introClip .= ",";
  433.                                 $outroClip = $this->options["outroClip"];
  434.                                 if( $outroClip != "" ) $outroClip = "," . $outroClip;
  435.  
  436.                                 if( count($enclosure) > 0 ) {
  437.                                         for($i = 0;$i < count($enclosure);$i++) {
  438.                                                 // Make sure the enclosure is an mp3 file and it hasn't been inserted into the post yet
  439.                                                 if( preg_match( "/.*\.mp3$/", $enclosure[$i] ) == 1 && !in_array( $enclosure[$i], $this->instances ) ) {
  440.                                                         if ($this->options["enclosuresAtTop"]) {
  441.                                                                 $content = $this->getPlayer( $introClip . $enclosure[$i] . $outroClip, null, $enclosure[$i] ) . "\n\n" . $content;
  442.                                                         } else {
  443.                                                                 $content .= "\n\n" . $this->getPlayer( $introClip . $enclosure[$i] . $outroClip, null, $enclosure[$i] );
  444.                                                         }
  445.                                                 }
  446.                                         }
  447.                                 }
  448.                         }
  449.  
  450.                         return $content;
  451.                 }
  452.  
  453.                 /**
  454.                  * Callback function for preg_replace_callback
  455.                  * @return string to replace matches with
  456.                  * @param $matches Array
  457.                  */
  458.                 function parseCallback($matches) {
  459.                         $atts = explode("|", $matches[3]);
  460.                         $data[0] = $atts[0];
  461.                         for ($i = 1; $i < count($atts); $i++) {
  462.                                 $pair = explode("=", $atts[$i]);
  463.                                 $data[trim($pair[0])] = trim($pair[1]);
  464.                         }
  465.                         return $this->insertPlayer($data);
  466.                 }
  467.  
  468.                 /**
  469.                  * Inserts player
  470.                  * @return string to replace matches with
  471.                  * @param $data Array
  472.                  */
  473.                 function insertPlayer($data) {
  474.                         $files = array();
  475.  
  476.                         // Alternate content for excerpts (don't do this for feeds)
  477.                         if($this->inExcerpt && !is_feed()) {
  478.                                 return $this->options["excerptAlternate"];
  479.                         }
  480.  
  481.                         if (!is_feed()) {
  482.                                 // Insert intro clip if set
  483.                                 if ( $this->options["introClip"] != "" ) {
  484.                                         $afile = $this->options["introClip"];
  485.                                         if (!$this->isAbsoluteURL($afile)) {
  486.                                                 $afile = $this->audioRoot . "/" . $afile;
  487.                                         }
  488.                                         array_push( $files, $afile );
  489.                                 }
  490.                         }
  491.  
  492.                         $actualFiles = array();
  493.                         $actualFile = "";
  494.  
  495.                         // Create an array of files to load in player
  496.                         foreach ( explode( ",", trim($data[0]) ) as $afile ) {
  497.                                 $afile = trim($afile);
  498.  
  499.                                 // Get absolute URLs for relative ones
  500.                                 if (!$this->isAbsoluteURL($afile)) {
  501.                                         $afile = $this->audioRoot . "/" . $afile;
  502.                                 }
  503.  
  504.                                 array_push( $actualFiles, $afile );
  505.  
  506.                                 array_push( $files, $afile );
  507.  
  508.                                 // Add source file to instances already added to the post
  509.                                 array_push( $this->instances, $afile );
  510.                         }
  511.  
  512.                         if (count($actualFiles) == 1) {
  513.                                 $actualFile = $actualFiles[0];
  514.                         }
  515.  
  516.                         if (!is_feed()) {
  517.                                 // Insert outro clip if set
  518.                                 if ( $this->options["outroClip"] != "" ) {
  519.                                         $afile = $this->options["outroClip"];
  520.                                         if (!$this->isAbsoluteURL($afile)) {
  521.                                                 $afile = $this->audioRoot . "/" . $afile;
  522.                                         }
  523.                                         array_push( $files, $afile );
  524.                                 }
  525.                         }
  526.  
  527.                         // Build runtime options array
  528.                         array_splice($data, 0, 1);
  529.  
  530.                         // Return player instance code
  531.                         return $this->getPlayer( implode( ",", $files ), $data, $actualFile );
  532.                 }
  533.  
  534.                 /**
  535.                  * Generic player instance function (returns player widget code to insert)
  536.                  * @return String the html code to insert
  537.                  * @param $source String list of mp3 file urls to load in player
  538.                  * @param $playerOptions Object[optional] options to load in player
  539.                  * @param $actualFile String[optional] url of main single file (empty if multiple files)
  540.                  */
  541.                 function getPlayer($source, $playerOptions = array(), $actualFile = "") {
  542.                         // Decode HTML entities in file names
  543.                         if (function_exists("html_entity_decode")) {
  544.                                 $source = html_entity_decode($source);
  545.                         }
  546.  
  547.                         // Add source to options and encode if necessary
  548.  
  549.                         if ($this->options["encodeSource"]) {
  550.                                 $playerOptions["soundFile"] = $this->encodeSource($source);
  551.                         } else {
  552.                                 $playerOptions["soundFile"] = $source;
  553.                         }
  554.  
  555.                         if (is_feed()) {
  556.                                 // We are in a feed so use RSS alternate content option
  557.                                 switch ( $this->options["rssAlternate"] ) {
  558.                                         case "download":
  559.                                                 // Get filenames from path and output a link for each file in the sequence
  560.                                                 $files = explode(",", $source);
  561.                                                 $links = "";
  562.                                                 for ($i = 0; $i < count($files); $i++) {
  563.                                                         $fileparts = explode("/", $files[$i]);
  564.                                                         $fileName = $fileparts[count($fileparts)-1];
  565.                                                         $links .= '<a href="' . $files[$i] . '">' . __('Download audio file', $this->textDomain) . ' (' . $fileName . ')</a><br />';
  566.                                                 }
  567.                                                 return $links;
  568.                                                 break;
  569.  
  570.                                         case "nothing":
  571.                                                 return "";
  572.                                                 break;
  573.  
  574.                                         case "custom":
  575.                                                 return $this->options["rssCustomAlternate"];
  576.                                                 break;
  577.                                 }
  578.                         } else {
  579.                                 if($this->detectAppleMobile()){  
  580.                                         $iphone_player = '';
  581.                          
  582.                                         foreach ( explode( ",", $source) as $afilename ) {
  583.                                                 $afilename = trim($afilename);
  584.                                                 $iphone_player .= '<audio src="'.$afilename.'" controls="controls">Your browser does not support the html5 audio element.</audio><br />';
  585.                                         }
  586.                                         return $iphone_player;
  587.                                 } else {
  588.                                         // Not in a feed so return player widget
  589.                                         $playerElementID = "audioplayer_" . ++$this->playerID;
  590.                                         if (strlen($this->options["flashAlternate"]) > 0) {
  591.                                                 $playerCode = str_replace(array("%playerID%", "%downloadURL%"), array($playerElementID, $actualFile), $this->options["flashAlternate"]);
  592.                                         } else {
  593.                                                 $playerCode = '<p class="audioplayer_container"><span style="display:block;padding:5px;border:1px solid #dddddd;background:#f8f8f8" id="' . $playerElementID . '">' . sprintf(__('Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version <a href="%s" title="Download Adobe Flash Player">here</a>. You also need to have JavaScript enabled in your browser.', $this->textDomain), 'http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash&amp;promoid=BIOW') . '</span></p>';
  594.                                         }
  595.                                          
  596.                                         $this->footerCode .= 'AudioPlayer.embed("' . $playerElementID . '", ' . $this->php2js($playerOptions) . ');';
  597.                                         $this->footerCode .= "\n";
  598.                          
  599.                                         return $playerCode;
  600.                                 }
  601.                         }
  602.                 }
  603.  
  604.                 /**
  605.                  * Outputs the options sub panel
  606.                  */
  607.                 function outputOptionsSubpanel() {
  608.                         $this->loadLanguageFile();
  609.  
  610.                         add_action("in_admin_footer", array(&$this, "addFooterCredits"));
  611.  
  612.                         // Include options panel
  613.                         include($this->pluginPath . "/php/options-panel.php");
  614.                 }
  615.  
  616.                 /**
  617.                  * Handles submitted options (validates and saves modified options)
  618.                  */
  619.                 function optionsPanelAction() {
  620.                         if( isset($_POST['AudioPlayerReset']) && $_POST['AudioPlayerReset'] == "1" ) {
  621.                                 if( function_exists('current_user_can') && !current_user_can('manage_options') ) {
  622.                                         wp_die(__('You do not have sufficient permissions to access this page.'));
  623.                                 }
  624.  
  625.                                 // Reset colour scheme back to default values
  626.                                 $this->options["colorScheme"] = $this->defaultColorScheme;
  627.                                 $this->saveOptions();
  628.  
  629.                                 $goback = add_query_arg("updated", "true", "options-general.php?page=" . $this->optionsPageName);
  630.                                 wp_redirect($goback);
  631.                                 exit();
  632.                         } else  if( isset($_POST['AudioPlayerSubmit']) ) {
  633.                                 if( function_exists('current_user_can') && !current_user_can('manage_options') ) {
  634.                                         wp_die(__('You do not have sufficient permissions to access this page.'));
  635.                                 }
  636.  
  637.                                 if ( function_exists('check_admin_referer') ) {
  638.                                         check_admin_referer('audio-player-action');
  639.                                 }
  640.  
  641.                                 // Set audio web path
  642.                                 $_POST['ap_audiowebpath'] = trim($_POST['ap_audiowebpath']);
  643.                                 if ($_POST["ap_audiowebpath_iscustom"] != "true") {
  644.                                         if ( substr( $_POST['ap_audiowebpath'], -1, 1 ) == "/" ) {
  645.                                                 $_POST['ap_audiowebpath'] = substr( $_POST['ap_audiowebpath'], 0, strlen( $_POST['ap_audiowebpath'] ) - 1 );
  646.                                         }
  647.                                         if ( substr( $_POST['ap_audiowebpath'], 0, 1 ) != "/" ) {
  648.                                                 $_POST['ap_audiowebpath'] = "/" . $_POST['ap_audiowebpath'];
  649.                                         }
  650.                                         $this->options["audioFolder"] = $_POST['ap_audiowebpath'];
  651.                                 } else if ($this->isAbsoluteURL($_POST['ap_audiowebpath'])) {
  652.                                         $this->options["audioFolder"] = $_POST['ap_audiowebpath'];
  653.                                 }
  654.  
  655.                                 // Update behaviour and rss alternate content options
  656.                                 $this->options["encodeSource"] = isset( $_POST["ap_encodeSource"] );
  657.                                 $this->options["enableAnimation"] = !isset( $_POST["ap_disableAnimation"] );
  658.                                 $this->options["showRemaining"] = isset( $_POST["ap_showRemaining"] );
  659.                                 $this->options["noInfo"] = isset( $_POST["ap_disableTrackInformation"] );
  660.                                 $this->options["checkPolicy"] = isset( $_POST["ap_checkPolicy"] );
  661.                                 $this->options["rtl"] = isset( $_POST["ap_rtlMode"] );
  662.                                 $this->options["enclosuresAtTop"] = isset( $_POST["ap_enclosuresAtTop"] );
  663.                                 $this->options["disableEnclosures"] = isset( $_POST["ap_disableEnclosures"] );
  664.  
  665.                                 if (isset($_POST['ap_behaviour'])) {
  666.                                         $this->options["behaviour"] = $_POST['ap_behaviour'];
  667.                                 } else {
  668.                                         $this->options["behaviour"] = array();
  669.                                 }
  670.  
  671.                                 //$this->options["flashAlternate"] = trim(stripslashes($_POST['ap_flashalternate']));
  672.                                 $this->options["excerptAlternate"] = trim(stripslashes($_POST['ap_excerptalternate']));
  673.                                 $this->options["rssAlternate"] = $_POST['ap_rssalternate'];
  674.                                 $this->options["rssCustomAlternate"] = trim(stripslashes($_POST['ap_rsscustomalternate']));
  675.                                 $this->options["introClip"] = trim($_POST['ap_audioprefixwebpath']);
  676.                                 $this->options["outroClip"] = trim($_POST['ap_audiopostfixwebpath']);
  677.  
  678.                                 $_POST['ap_player_width'] = trim($_POST['ap_player_width']);
  679.                                 if ( preg_match("/^[0-9]+%?$/", $_POST['ap_player_width']) == 1 ) {
  680.                                         $this->options["playerWidth"] = $_POST['ap_player_width'];
  681.                                 }
  682.  
  683.                                 $_POST['ap_initial_volume'] = trim($_POST['ap_initial_volume']);
  684.                                 if ( preg_match("/^[0-9]+$/", $_POST['ap_initial_volume']) == 1 ) {
  685.                                         $_POST['ap_initial_volume'] = intval($_POST['ap_initial_volume']);
  686.                                         if ($_POST['ap_initial_volume'] <= 100) {
  687.                                                 $this->options["initialVolume"] = $_POST['ap_initial_volume'];
  688.                                         }
  689.                                 }
  690.  
  691.                                 $_POST['ap_buffertime'] = trim($_POST['ap_buffertime']);
  692.                                 if ( preg_match("/^[0-9]+$/", $_POST['ap_buffertime']) == 1 ) {
  693.                                         $_POST['ap_buffertime'] = intval($_POST['ap_buffertime']);
  694.                                         if ($_POST['ap_buffertime'] > 0) {
  695.                                                 $this->options["bufferTime"] = $_POST['ap_buffertime'];
  696.                                         }
  697.                                 }
  698.  
  699.                                 // Update colour options
  700.                                 foreach ( $this->colorKeys as $colorKey ) {
  701.                                         // Ignore missing or invalid color values
  702.                                         if ( isset( $_POST["ap_" . $colorKey . "color"] ) && preg_match( "/^#[0-9A-Fa-f]{6}$/", $_POST["ap_" . $colorKey . "color"] ) == 1 ) {
  703.                                                 $this->options["colorScheme"][$colorKey] = str_replace( "#", "", $_POST["ap_" . $colorKey . "color"] );
  704.                                         }
  705.                                 }
  706.  
  707.                                 if ( isset( $_POST["ap_pagebgcolor"] ) && preg_match( "/^#[0-9A-Fa-f]{6}$/", $_POST["ap_pagebgcolor"] ) == 1 ) {
  708.                                         $this->options["colorScheme"]["pagebg"] = str_replace( "#", "", $_POST['ap_pagebgcolor']);
  709.                                 }
  710.                                 $this->options["colorScheme"]["transparentpagebg"] = isset( $_POST["ap_transparentpagebg"] );
  711.  
  712.                                 $this->saveOptions();
  713.  
  714.                                 $goback = add_query_arg("updated", "true", "options-general.php?page=" . $this->optionsPageName);
  715.                                 wp_redirect($goback);
  716.                                 exit();
  717.                         }
  718.                 }
  719.  
  720.                 /**
  721.                  * Inserts Audio Player button into media library popup
  722.                  * @return the amended form_fields structure
  723.                  * @param $form_fields Object
  724.                  * @param $post Object
  725.                  */
  726.                 function insertAudioPlayerButton($form_fields, $post) {
  727.                         global $wp_version;
  728.  
  729.                         $file = wp_get_attachment_url($post->ID);
  730.  
  731.                         // Only add the extra button if the attachment is an mp3 file
  732.                         if ($post->post_mime_type == 'audio/mpeg') {
  733.                                 $form_fields["url"]["html"] .= "<button type='button' class='button urlaudioplayer audio-player-" . $post->ID . "' value='[audio:" . attribute_escape($file) . "]' title='[audio:" . attribute_escape($file) . "]'>Audio Player</button>";
  734.  
  735.                                 if (version_compare($wp_version, "2.7", "<")) {
  736.                                         $form_fields["url"]["html"] .= "<script type='text/javascript'>
  737.                                         jQuery('button.audio-player-" . $post->ID . "').bind('click', function(){jQuery(this).siblings('input').val(this.value);});
  738.                                         </script>\n";
  739.                                 }
  740.                         }
  741.  
  742.                         return $form_fields;
  743.                 }
  744.  
  745.                 /**
  746.                  * Format the html inserted when the Audio Player button is used
  747.                  * @param $html String
  748.                  * @return String
  749.                  */
  750.                 function sendToEditor($html) {
  751.                         if (preg_match("/<a ([^=]+=['\"][^\"']+['\"] )*href=['\"](\[audio:([^\"']+\.mp3)])['\"]( [^=]+=['\"][^\"']+['\"])*>([^<]*)<\/a>/i", $html, $matches)) {
  752.                                 $html = $matches[2];
  753.                                 if (strlen($matches[5]) > 0) {
  754.                                         $html = preg_replace("/]$/i", "|titles=" . $matches[5] . "]", $html);
  755.                                 }
  756.                         }
  757.                         return $html;
  758.                 }
  759.  
  760.                 /**
  761.                  * Output necessary stuff to WP head section
  762.                  */
  763.                 function addHeaderCode() {
  764.                         echo '<script type="text/javascript" src="' . $this->pluginURL . '/assets/audio-player.js?ver=' . $this->version . '"></script>';
  765.                         echo "\n";
  766.                         echo '<script type="text/javascript">';
  767.                         $jsFormattedOptions = $this->php2js($this->getPlayerOptions());
  768.                         echo 'AudioPlayer.setup("' . $this->playerURL . '?ver=' . $this->version . '", ' . $jsFormattedOptions . ');';
  769.                         echo '</script>';
  770.                         echo "\n";
  771.                 }
  772.  
  773.                 /**
  774.                  * Output necessary stuff to WP footer section (JS calls to embed players)
  775.                  */
  776.                 function addFooterCode() {
  777.                         if (strlen($this->footerCode) > 0) {
  778.                                 echo '<script type="text/javascript">';
  779.                                 echo "\n";
  780.                                 echo $this->footerCode;
  781.                                 echo '</script>';
  782.                                 echo "\n";
  783.  
  784.                                 // Reset it now
  785.                                 $this->footerCode = "";
  786.                         }
  787.                 }
  788.  
  789.                 /**
  790.                  * Override media-upload script to handle Audio Player inserts from media library
  791.                  */
  792.                 function overrideMediaUpload() {
  793.                         echo '<script type="text/javascript" src="' . $this->pluginURL . '/assets/media-upload.js?ver=' . $this->version . '"></script>';
  794.                         echo "\n";
  795.                 }
  796.  
  797.                 /**
  798.                  * Output necessary stuff to WP admin head section
  799.                  */
  800.                 function addAdminHeaderCode() {
  801.                         global $wp_version;
  802.                         echo '<link href="' . $this->pluginURL . '/assets/audio-player-admin.css?ver=' . $this->version . '" rel="stylesheet" type="text/css" />';
  803.                         echo "\n";
  804.                         echo '<link href="' . $this->pluginURL . '/assets/cpicker/colorpicker.css?ver=' . $this->version . '" rel="stylesheet" type="text/css" />';
  805.                         echo "\n";
  806.  
  807.                         // Include jquery library if we are not running WP 2.5 or above
  808.                         if (version_compare($wp_version, "2.5", "<")) {
  809.                                 echo '<script type="text/javascript" src="' . $this->pluginURL . '/assets/lib/jquery.js?ver=' . $this->version . '"></script>';
  810.                                 echo "\n";
  811.                         }
  812.  
  813.                         echo '<script type="text/javascript" src="' . $this->pluginURL . '/assets/cpicker/colorpicker.js?ver=' . $this->version . '"></script>';
  814.                         echo "\n";
  815.                         echo '<script type="text/javascript" src="' . $this->pluginURL . '/assets/audio-player-admin.js?ver=' . $this->version . '"></script>';
  816.                         echo "\n";
  817.                         echo '<script type="text/javascript" src="' . $this->pluginURL . '/assets/audio-player.js?ver=' . $this->version . '"></script>';
  818.                         echo "\n";
  819.                         echo '<script type="text/javascript">';
  820.                         echo "\n";
  821.                         echo 'var ap_ajaxRootURL = "' . $this->pluginURL . '/php/";';
  822.                         echo "\n";
  823.                         echo 'AudioPlayer.setup("' . $this->playerURL . '?ver=' . $this->version . '", ' . $this->php2js($this->getPlayerOptions()) . ');';
  824.                         echo "\n";
  825.                         echo '</script>';
  826.                         echo "\n";
  827.                 }
  828.  
  829.                 /**
  830.                  * Verifies that the given audio folder exists on the server (Ajax call)
  831.                  */
  832.                 function checkAudioFolder() {
  833.                         $audioRoot = $_POST["audioFolder"];
  834.  
  835.                         $sysDelimiter = '/';
  836.                         if (strpos(ABSPATH, '\\') !== false) $sysDelimiter = '\\';
  837.                         $audioAbsPath = preg_replace('/[\\\\\/]+/', $sysDelimiter, ABSPATH . $audioRoot);
  838.  
  839.                         if (!file_exists($audioAbsPath)) {
  840.                                 echo $audioAbsPath;
  841.                         } else {
  842.                                 echo "ok";
  843.                         }
  844.                 }
  845.  
  846.                 /**
  847.                  * Parses theme style sheet
  848.                  * @return array of colors from current theme
  849.                  */
  850.                 function getThemeColors() {
  851.                         $current_theme_data = get_theme(get_current_theme());
  852.  
  853.                         $theme_css = implode('', file( get_theme_root() . "/" . $current_theme_data["Stylesheet"] . "/style.css"));
  854.  
  855.                         preg_match_all('/:[^:,;\{\}].*?#([abcdef1234567890]{3,6})/i', $theme_css, $matches);
  856.  
  857.                         return array_unique($matches[1]);
  858.                 }
  859.  
  860.                 /**
  861.                  * Formats a php associative array into a javascript object
  862.                  * @return formatted string
  863.                  * @param $object Object containing the options to format
  864.                  */
  865.                 function php2js($object) {
  866.                         $js_options = '{';
  867.                         $separator = "";
  868.                         $real_separator = ",";
  869.                         foreach($object as $key=>$value) {
  870.                                 // Format booleans
  871.                                 if (is_bool($value)) $value = $value?"yes":"no";
  872.                                 else if (in_array($key, array("soundFile", "titles", "artists"))) {
  873.                                         if (in_array($key, array("titles", "artists"))) {
  874.                                                 // Decode HTML entities in titles and artists
  875.                                                 if (function_exists("html_entity_decode")) {
  876.                                                         $value = html_entity_decode($value);
  877.                                                 }
  878.                                         }
  879.  
  880.                                         $value = rawurlencode($value);
  881.                                 }
  882.                                 $js_options .= $separator . $key . ':"' . $value .'"';
  883.                                 $separator = $real_separator;
  884.                         }
  885.                         $js_options .= "}";
  886.  
  887.                         return $js_options;
  888.                 }
  889.  
  890.                 /**
  891.                  * @return true if $path is absolute
  892.                  * @param $path Object
  893.                  */
  894.                 function isAbsoluteURL($path) {
  895.                         if (strpos($path, "http://") === 0) {
  896.                                 return true;
  897.                         }
  898.                         if (strpos($path, "https://") === 0) {
  899.                                 return true;
  900.                         }
  901.                         if (strpos($path, "ftp://") === 0) {
  902.                                 return true;
  903.                         }
  904.                         return false;
  905.                 }
  906.  
  907.                 /**
  908.                  * Encodes the given string
  909.                  * @return the encoded string
  910.                  * @param $string String the string to encode
  911.                  */
  912.                 function encodeSource($string) {
  913.                         $source = utf8_decode($string);
  914.                         $ntexto = "";
  915.                         $codekey = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
  916.                         for ($i = 0; $i < strlen($string); $i++) {
  917.                                 $ntexto .= substr("0000".base_convert(ord($string{$i}), 10, 2), -8);
  918.                         }
  919.                         $ntexto .= substr("00000", 0, 6-strlen($ntexto)%6);
  920.                         $string = "";
  921.                         for ($i = 0; $i < strlen($ntexto)-1; $i = $i + 6) {
  922.                                 $string .= $codekey{intval(substr($ntexto, $i, 6), 2)};
  923.                         }
  924.  
  925.                         return $string;
  926.                 }
  927.         }
  928. }
  929.  
  930. // Instantiate the class
  931. if (class_exists('AudioPlayer')) {
  932.         global $AudioPlayer;
  933.         if (!isset($AudioPlayer)) {
  934.                 if (version_compare(PHP_VERSION, '5.0.0', '<')) {
  935.                         $AudioPlayer = &new AudioPlayer();
  936.                 } else {
  937.                         $AudioPlayer = new AudioPlayer();
  938.                 }
  939.         }
  940. }
  941.  
  942. /**
  943.  * Experimental "tag" function for inserting players anywhere (yuk)
  944.  * @return
  945.  * @param $source Object
  946.  */
  947. function insert_audio_player($source) {
  948.         global $AudioPlayer;
  949.         echo $AudioPlayer->processContent($source);
  950. }
  951.  
  952. ?>