PageRenderTime 102ms CodeModel.GetById 27ms RepoModel.GetById 3ms app.codeStats 0ms

/application/protected/extensions/widgets/audioplayer/AiiAudioPlayer.php

https://bitbucket.org/dinhtrung/yiicorecms/
PHP | 479 lines | 224 code | 38 blank | 217 comment | 21 complexity | ec0daea90839471b5a4c91599caf1c23 MD5 | raw file
Possible License(s): GPL-3.0, BSD-3-Clause, CC0-1.0, BSD-2-Clause, GPL-2.0, LGPL-2.1, LGPL-3.0
  1. <?php
  2. /**
  3. * This Widget is using Audio Player Wordpress plugin from 1 pixel out
  4. * {@link http://www.1pixelout.net/code/audio-player-wordpress-plugin/}
  5. * This widget concerns using aforementioned player for non-Wordpress projects
  6. *
  7. * To see more information about using aforementioned player for non-Wordpress project,
  8. * please visit {@link http://wpaudioplayer.com/standalone}
  9. *
  10. * To see more inormation about options of Audio Player Wordpress plugin
  11. * read tutorial "Customizing Audio Player"
  12. * {@link http://www.macloo.com/examples/audio_player/options.html}
  13. *
  14. * This extension requires {@link AiiJsAndCssPublishRegisterBehavior}
  15. * for publishing assets
  16. *
  17. * @author Tomasz Suchanek <tomasz.suchanek@gmail.com>
  18. * @copyright Copyright &copy; 2008-2010 Tomasz "Aztech" Suchanek
  19. * @license http://www.yiiframework.com/license/
  20. * @package aii.extensions
  21. * @version 0.1.0
  22. * @uses {@link AiiJsAndCssPublishRegisterBehavior}
  23. */
  24. require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . "AiiPublishRegisterBehavior.php");
  25. class AiiAudioPlayer extends CWidget
  26. {
  27. const OPTION_TRACK = 'track';
  28. const OPTION_PLAYER = 'player';
  29. const OPTION_FLASH = 'flashplayer';
  30. const OPTION_COLOUR = 'colourscheme';
  31. const OPTION_SEM = 'semantic';
  32. /**
  33. * @var string - Player Id (needed when using multiple players on one site)
  34. * default to 'audioplayer'
  35. */
  36. public $playerID = 'audioplayer';
  37. /**
  38. *
  39. * @var boolean, true if only one player appears on page
  40. */
  41. public $singlePlayer = false;
  42. /**
  43. * @var array - list of mp3 files {@link mp3Folder}
  44. * It's an array with 4 entries
  45. * - soundFile - required, comma-delimited list of mp3 files
  46. * - alternative - required, alternative content if player will not be displayed
  47. * - titles - optional, comma-delimited list of titles (overrides ID3 information)
  48. * - artists - optional, comma-delimited list of artists, overrides ID3 information
  49. * with this way of declaration you will get one player with one or multiple mp3s.
  50. * Example:
  51. * <code>
  52. * array(
  53. * 'soundFile' => "example.mp3, interview.mp3",
  54. * 'titles' => "Example MP3 , My latest interview",
  55. * 'artists' => "Artist name 1, artist name 2"
  56. * 'alternative' => "sorry, no file found"
  57. * );
  58. * </code>
  59. * If you wan't to create more than one player,
  60. * please pass to this property array of aforementioned options
  61. * with player ids. I
  62. * Example:
  63. * <code>
  64. * array(
  65. * 'player1' => array(
  66. * 'soundFile' => "poker_face-lady_gaga.mp3",
  67. * 'alternative' => "sorry, no file found"
  68. * ),
  69. * 'player2' => array(
  70. * 'soundFile' => "example.mp3, interview.mp3",
  71. * 'titles' => "Example MP3 , My latest interview",
  72. * 'artists' => "Artist name 1, artist name 2"
  73. * 'alternative' => "sorry, no file found"
  74. * );
  75. * );
  76. * </code>
  77. */
  78. public $trackOptions = array( );
  79. /**
  80. *
  81. * @var array list of player options
  82. * Below code shows also default values
  83. * <code>
  84. * array (
  85. * 'autostart' => "no", //if yes, player starts automatically
  86. * 'loop' => "no", //if yes, player loops
  87. * 'animation' => "yes", //if no, player is always open
  88. * 'remaining' => "no", //if yes, shows remaining track time rather than ellapsed time
  89. * 'noinfo' => "no", //if yes, disables the track information display
  90. * 'initialvolume' => 60, //initial volume level (from 0 to 100)
  91. * 'buffer' => 5, //buffering time in seconds
  92. * 'encode' => "no", //indicates that the mp3 file urls are encoded
  93. * 'checkpolicy' => "no" //tells Flash to look for a policy file when loading mp3 files
  94. * (this allows Flash to read ID3 tags from files hosted on a different domain)
  95. * 'rtl' => "no" //switches the layout to RTL (right to left) for Hebrew and Arabic languages
  96. * );
  97. * </code>
  98. *
  99. * If you would like to specify different options to each player
  100. * please pass array of array options here, where key in first array is player id
  101. * Example:
  102. * <code>
  103. * array(
  104. * 'player1' => array ( ... ), //header options for 1st player
  105. * 'player2' => array ( ... ), //header options for 2nd player
  106. * ...
  107. * 'playerN' => array ( ... ), //header options for Nth player
  108. * );
  109. * </code>
  110. */
  111. public $playerOptions = array( );
  112. /**
  113. *
  114. * @var array list of flash player options
  115. * <code>
  116. * array(
  117. * 'width' => 290, //required, width of the player. e.g. 290 (290 pixels) or 100%
  118. * 'transparentpagebg' => "no", //if yes, the player background is transparent (matches the page background)
  119. * 'pagebg' => NA, //player background color (set it to your page background when transparentbg is set to â&#x20AC;&#x2DC;noâ&#x20AC;&#x2122;)
  120. * );
  121. * </code>
  122. *
  123. * If you would like to specify different options to each player
  124. * please pass array of array options here, where key in first array is player id
  125. * Example:
  126. * <code>
  127. * array(
  128. * 'player1' => array ( ... ), //header options for 1st player
  129. * 'player2' => array ( ... ), //header options for 2nd player
  130. * ...
  131. * 'playerN' => array ( ... ), //header options for Nth player
  132. * );
  133. * </code>
  134. */
  135. public $flashPlayerOptions = array( );
  136. /**
  137. *
  138. * @var array of colour scheme options
  139. * <code>
  140. * array(
  141. * 'bg' => "E5E5E5", //Background
  142. * 'leftbg' => "CCCCCC", //Speaker icon/Volume control background
  143. * 'lefticon' => "333333", //Speaker icon
  144. * 'voltrack' => "F2F2F2", //Volume track
  145. * 'volslider' => "666666", //Volume slider
  146. * 'rightbg' => "B4B4B4" //Play/Pause button background
  147. * 'rightbghover' => "999999" //Play/Pause button background (hover state)
  148. * 'righticon' => "333333" //Play/Pause icon
  149. * 'righticonhover' => "FFFFFF" //Play/Pause icon (hover state)
  150. * 'loader' => "009900", //Loading bar
  151. * 'track' => "FFFFFF" //Loading/Progress bar track backgrounds
  152. * 'tracker' => "DDDDDD", //Progress track
  153. * 'border' => "CCCCCC", //Progress bar border
  154. * 'skip' => "666666", //Previous/Next skip buttons
  155. * 'text' => "333333", //Text
  156. * );
  157. * </code>
  158. *
  159. * If you would like to specify different options to each player
  160. * please pass array of array options here, where key in first array is player id
  161. * Example:
  162. * <code>
  163. * array(
  164. * 'player1' => array ( ... ), //header options for 1st player
  165. * 'player2' => array ( ... ), //header options for 2nd player
  166. * ...
  167. * 'playerN' => array ( ... ), //header options for Nth player
  168. * );
  169. * </code>
  170. */
  171. public $colourSchemeOptions = array( );
  172. /**
  173. * Options used to initialize all players. The are overwritten
  174. * options set via {@link playerOptions}, {@link flashPlayerOptions} ,
  175. * <code>
  176. * array(
  177. * AiiAudioPlayer::OPTION_PLAYER = array (
  178. * ... here options like in {@link playerOptions}
  179. * ),
  180. * AiiAudioPlayer::OPTION_FLASH = array (
  181. * ... here options like in {@link flashOptions}
  182. * ),
  183. * AiiAudioPlayer::OPTION_COLOUR = array (
  184. * ... here options like in {@link colourOptions}
  185. * ),
  186. * );
  187. * </code>
  188. *
  189. * {@link colourSchemeOptions}
  190. * @var array
  191. */
  192. public $setupOptions = array( );
  193. /**
  194. *
  195. * @var string - Publised folder with mp3 files
  196. * Default to null, which means that standard '{basepath}/mp3' folder under
  197. * extension directory will be published
  198. */
  199. public $mp3Folder = null;
  200. /**
  201. * @var array
  202. */
  203. private $_setup = array( );
  204. /**
  205. *
  206. * @var array players
  207. */
  208. private $_players = array( );
  209. private static $_allowedKeys = array(
  210. self::OPTION_TRACK => array(
  211. 'soundFile' => true,
  212. 'titles' => false,
  213. 'artists' => false,
  214. ),
  215. self::OPTION_SEM => array(
  216. 'alternative' => true,
  217. ),
  218. self::OPTION_PLAYER => array(
  219. 'autostart' => false,
  220. 'loop' => false,
  221. 'animation' => false,
  222. 'remaining' => false,
  223. 'noinfo' => false,
  224. 'initialvolume' => false,
  225. 'buffer' => false,
  226. 'encode' => false,
  227. 'checkpolicy' => false,
  228. 'rtl' => false,
  229. ),
  230. self::OPTION_FLASH => array(
  231. 'width' => false,
  232. 'transparentpagebg' => false,
  233. 'pagebg' => false,
  234. ),
  235. self::OPTION_COLOUR => array(
  236. 'bg' => false,
  237. 'leftbg' => false,
  238. 'lefticon' => false,
  239. 'voltrack' => false,
  240. 'volslider' => false,
  241. 'rightbg' => false,
  242. 'rightbghover' => false,
  243. 'righticon' => false,
  244. 'righticonhover' => false,
  245. 'loader' => false,
  246. 'track' => false,
  247. 'tracker' => false,
  248. 'border' => false,
  249. 'skip' => false,
  250. 'text' => false,
  251. ),
  252. );
  253. /**
  254. * (non-PHPdoc)
  255. * @see web/widgets/CWidget#init()
  256. */
  257. public function init()
  258. {
  259. parent::init( );
  260. if ( $this->mp3Folder === null )
  261. $this->mp3Folder = '{basePath}{/}mp3';
  262. $this->attachBehavior( 'pubMan', #publishManager
  263. array(
  264. 'class' => 'AiiPublishRegisterBehavior',
  265. 'cssPath' => false,
  266. 'jsToRegister' => array( 'audio-player.js' ),
  267. 'basePath' => dirname( __FILE__ ),
  268. 'jsPath' => '{assets}/js',
  269. 'otherResToPublish' => array( 'mp3Folder' => $this->mp3Folder ),
  270. ) );
  271. $this->publishAll( );
  272. $this->registerAll( );
  273. }
  274. protected function addOption( $option , $value , $type, $playerId = null )
  275. {
  276. $id = $playerId === null ? $this->playerID : $playerId;
  277. if ( isset( $this->_players[$id] ) )
  278. {
  279. if ( $this->checkOptionName( $option , $type ) )
  280. $this->_players[$id]['options'][$option] = $value;
  281. }
  282. else
  283. throw new CException( 'aii-audio-player' , Yii::t( 'Player with id {id} dosn\'t exist!' , array ( '{id}' => $id ) ) );
  284. }
  285. public function addTrack( $playerId , $mp3 )
  286. {
  287. $this->_players[$player_id][] = $mp3;
  288. }
  289. public function addPlayerOption( )
  290. {
  291. $this->addOption( $option , $value , self::OPTION_PLAYER , $player_id );
  292. }
  293. public function addFlashPlayerOption( )
  294. {
  295. $this->addOption( $option , $value , self::OPTION_FLASH , $player_id );
  296. }
  297. public function addSemanticOption( )
  298. {
  299. $this->addOption( $option , $value , self::OPTION_SEM , $player_id );
  300. }
  301. public function checkOptionName( $name , $type )
  302. {
  303. if ( isset( self::$_allowedKeys[$type][$name] ) )
  304. return true;
  305. else
  306. {
  307. throw new CException( Yii::t( 'aii-audio-player' , 'Unknown option name {name}.' , array ( '{name}' => $name ) ) );
  308. }
  309. }
  310. protected function processOptions( )
  311. {
  312. foreach ( $this->setupOptions as $setupOption )
  313. foreach ( array( self::OPTION_PLAYER , self::OPTION_FLASH , self::OPTION_COLOUR ) as $option )
  314. if ( isset ( $this->setupOptions[$option] ) )
  315. $this->addSetupOptions( $this->setupOptions[$option] );
  316. #do we have one or more players to create?
  317. if ( is_array ( current( $this->trackOptions ) ) )
  318. foreach ( $this->trackOptions as $playerId => $tracks )
  319. $this->processTrackOptions( $playerId , $tracks );
  320. else
  321. $this->processTrackOptions( $this->playerID , $this->trackOptions );
  322. foreach ( $this->_players as $playerId => $player )
  323. {
  324. #do we have player-based player options?
  325. if ( isset( $this->playerOptions[$playerId] ) )
  326. if ( is_array( $this->playerOptions[$playerId] ) )
  327. $this->addOptions( $playerId , $this->playerOptions[$playerId] , self::OPTION_PLAYER );
  328. else
  329. throw new CException( Yii::t( 'aii-audio-player' , 'Player options for player "{player}" need to be specified via array.' , array ( '{player}' => $playerId ) ) );
  330. elseif ( $this->singlePlayer === true )
  331. $this->addSetupOptions( $this->playerOptions );
  332. elseif ( is_array( $this->playerOptions ) )
  333. $this->addOptions( $playerId , $this->playerOptions , self::OPTION_PLAYER );
  334. #do we have player-based flash options?
  335. if ( isset ( $this->flashPlayerOptions[$playerId] ) )
  336. if ( is_array( $this->flashPlayerOptions[$playerId] ) )
  337. $this->addOptions( $playedId , $this->flashPlayerOptions[$playerId] , self::OPTION_FLASH );
  338. else
  339. throw new CException( Yii::t( 'aii-audio-player' , 'Flash player options for player "{player}" need to be specified via array.' , array ( '{player}' => $playerId ) ) );
  340. elseif ( $this->singlePlayer === true )
  341. $this->addSetupOptions( $this->flashPlayerOptions );
  342. elseif ( is_array( $this->flashPlayerOptions ) )
  343. $this->addOptions( $playedId , $this->flashPlayerOptions , self::OPTION_FLASH );
  344. #do we have player-based colour scheme options?
  345. if ( isset ( $this->colourSchemeOptions[$playerId] ) )
  346. if ( is_array( $this->colourSchemeOptions[$playerId] ) )
  347. $this->addOptions( $playedId , $this->colourSchemeOptions[$playerId] , self::OPTION_COLOUR );
  348. else
  349. throw new CException( Yii::t( 'aii-audio-player' , 'Colour scheme player options for player "{player}" need to be specified via array.' , array ( '{player}' => $playerId ) ) );
  350. elseif ( $this->singlePlayer === true )
  351. $this->addSetupOptions( $this->colourSchemeOptions );
  352. elseif ( is_array( $this->colourSchemeOptions ) )
  353. $this->addOptions( $playedId , $this->colourSchemeOptions , self::OPTION_COLOUR );
  354. }
  355. }
  356. /**
  357. * Process single track options
  358. * Track options should
  359. * @param string $playerId player ID
  360. * @param array $options definition of mp3 files to publish
  361. */
  362. protected function processTrackOptions( $playerId , array $options )
  363. {
  364. #mp3 file need to be specified
  365. if ( !isset( $options['soundFile'] ) )
  366. throw new CException( Yii::t( 'aii-audio-player' , 'Mp3 file name is missing. Please set it via track option "soundFile".') );
  367. #alternative content need to be specified
  368. if ( isset( $options['alternative'] ) )
  369. {
  370. $this->_players[$playerId]['alternative'] = $options['alternative'];
  371. unset($options['alternative']);
  372. }
  373. else
  374. throw new CException( Yii::t( 'aii-audio-player' , 'Please specify alternative content for player {player}' , array( 'player' => $playerId ) ) );
  375. $this->_players[$playerId]['tracks'] = $options;
  376. }
  377. /**
  378. *
  379. * @param string $playerId player ID
  380. * @param array $options options to add
  381. */
  382. protected function addOptions( $playerId , array $options , $type )
  383. {
  384. if ( isset( $this->_players[$playerId] ) )
  385. if ( YII_DEBUG )
  386. foreach ( $options as $option => $value )
  387. $this->addOption( $option , $value , $type , $playerId );
  388. else
  389. $this->_players[$playerId]['options'] = array_merge( $this->_players[$playerId]['options'] , $playerId );
  390. else
  391. if ( YII_DEBUG )
  392. foreach ( $options as $option => $value )
  393. $this->addOption( $option , $value , $type , $playerId );
  394. else
  395. $this->_players[$playerId]['options'] = $options;
  396. }
  397. protected function addSetupOptions( $options )
  398. {
  399. $this->_setup = array_merge( $this->_setup , $options );
  400. }
  401. /**
  402. *
  403. */
  404. public function run( )
  405. {
  406. if ( ( $assets = $this->getPublished( '{assets}' ) ) === false )
  407. throw new CException( Yii::t( 'aii-audio-player' , 'Can\'t find published assets for Aii Audio Player extension.' ) );
  408. #create all options
  409. $this->processOptions();
  410. #templates to be used to generate audio player
  411. $setupScriptTemplate = 'AudioPlayer.setup("{swf}"{comma}{options})';
  412. $embedScriptTemplate = 'AudioPlayer.embed("{playerId}", {options})';
  413. #publish head JS with audio player setup
  414. $setupTr['{swf}'] = $this->getPublished( '{assets}' ).'/player.swf';
  415. if ( !empty( $this->_setup ) )
  416. {
  417. $setupTr['{comma}'] = ',';
  418. $setupTr['{options}'] = CJavaScript::encode( $this->_setup );
  419. }
  420. else
  421. {
  422. $setupTr['{comma}'] = '';
  423. $setupTr['{options}'] = '';
  424. }
  425. Yii::app()->getClientScript( )->registerScript( 'aiiaudioplayer' , strtr( $setupScriptTemplate , $setupTr ) , CClientScript::POS_HEAD );
  426. #echoes each players
  427. foreach ( $this->_players as $id => $player )
  428. {
  429. $embedTr = array( );
  430. $player['tracks']['soundFile'] = $this->getPublished( 'mp3Folder' ).'/'.$player['tracks']['soundFile'];
  431. if ( isset( $player['options'] ) )
  432. $embedTr['{options}'] = CJavaScript::encode( array_merge( $player['tracks'] , $player['options'] ) );
  433. else
  434. $embedTr['{options}'] = CJavaScript::encode( $player['tracks'] );
  435. $embedTr['{playerId}'] = $id;
  436. echo CHtml::openTag( 'p', array( 'id' => $id ) ).$player['alternative'].CHtml::closeTag( 'p' );
  437. echo CHtml::script( strtr( $embedScriptTemplate , $embedTr ) );
  438. }
  439. }
  440. }
  441. ?>