1<?php
2
3declare(strict_types=1);
4/**
5 * SimplePie
6 *
7 * A PHP-Based RSS and Atom Feed Framework.
8 * Takes the hard work out of managing a complete RSS/Atom solution.
9 *
10 * Copyright (c) 2004-2022, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without modification, are
14 * permitted provided that the following conditions are met:
15 *
16 * 	* Redistributions of source code must retain the above copyright notice, this list of
17 * 	  conditions and the following disclaimer.
18 *
19 * 	* Redistributions in binary form must reproduce the above copyright notice, this list
20 * 	  of conditions and the following disclaimer in the documentation and/or other materials
21 * 	  provided with the distribution.
22 *
23 * 	* Neither the name of the SimplePie Team nor the names of its contributors may be used
24 * 	  to endorse or promote products derived from this software without specific prior
25 * 	  written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
28 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
29 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
30 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 * @package SimplePie
38 * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
39 * @author Ryan Parman
40 * @author Sam Sneddon
41 * @author Ryan McCue
42 * @link http://simplepie.org/ SimplePie
43 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
44 */
45
46namespace SimplePie;
47
48/**
49 * Handles everything related to enclosures (including Media RSS and iTunes RSS)
50 *
51 * Used by {@see \SimplePie\Item::get_enclosure()} and {@see \SimplePie\Item::get_enclosures()}
52 *
53 * This class can be overloaded with {@see \SimplePie\SimplePie::set_enclosure_class()}
54 *
55 * @package SimplePie
56 * @subpackage API
57 */
58class Enclosure
59{
60    /**
61     * @var string
62     * @see get_bitrate()
63     */
64    public $bitrate;
65
66    /**
67     * @var array
68     * @see get_captions()
69     */
70    public $captions;
71
72    /**
73     * @var array
74     * @see get_categories()
75     */
76    public $categories;
77
78    /**
79     * @var int
80     * @see get_channels()
81     */
82    public $channels;
83
84    /**
85     * @var \SimplePie\Copyright
86     * @see get_copyright()
87     */
88    public $copyright;
89
90    /**
91     * @var array
92     * @see get_credits()
93     */
94    public $credits;
95
96    /**
97     * @var string
98     * @see get_description()
99     */
100    public $description;
101
102    /**
103     * @var int
104     * @see get_duration()
105     */
106    public $duration;
107
108    /**
109     * @var string
110     * @see get_expression()
111     */
112    public $expression;
113
114    /**
115     * @var string
116     * @see get_framerate()
117     */
118    public $framerate;
119
120    /**
121     * @var string
122     * @see get_handler()
123     */
124    public $handler;
125
126    /**
127     * @var array
128     * @see get_hashes()
129     */
130    public $hashes;
131
132    /**
133     * @var string
134     * @see get_height()
135     */
136    public $height;
137
138    /**
139     * @deprecated
140     * @var null
141     */
142    public $javascript;
143
144    /**
145     * @var array
146     * @see get_keywords()
147     */
148    public $keywords;
149
150    /**
151     * @var string
152     * @see get_language()
153     */
154    public $lang;
155
156    /**
157     * @var string
158     * @see get_length()
159     */
160    public $length;
161
162    /**
163     * @var string
164     * @see get_link()
165     */
166    public $link;
167
168    /**
169     * @var string
170     * @see get_medium()
171     */
172    public $medium;
173
174    /**
175     * @var string
176     * @see get_player()
177     */
178    public $player;
179
180    /**
181     * @var array
182     * @see get_ratings()
183     */
184    public $ratings;
185
186    /**
187     * @var array
188     * @see get_restrictions()
189     */
190    public $restrictions;
191
192    /**
193     * @var string
194     * @see get_sampling_rate()
195     */
196    public $samplingrate;
197
198    /**
199     * @var array
200     * @see get_thumbnails()
201     */
202    public $thumbnails;
203
204    /**
205     * @var string
206     * @see get_title()
207     */
208    public $title;
209
210    /**
211     * @var string
212     * @see get_type()
213     */
214    public $type;
215
216    /**
217     * @var string
218     * @see get_width()
219     */
220    public $width;
221
222    /**
223     * Constructor, used to input the data
224     *
225     * For documentation on all the parameters, see the corresponding
226     * properties and their accessors
227     *
228     * @uses idna_convert If available, this will convert an IDN
229     */
230    public function __construct($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null)
231    {
232        $this->bitrate = $bitrate;
233        $this->captions = $captions;
234        $this->categories = $categories;
235        $this->channels = $channels;
236        $this->copyright = $copyright;
237        $this->credits = $credits;
238        $this->description = $description;
239        $this->duration = $duration;
240        $this->expression = $expression;
241        $this->framerate = $framerate;
242        $this->hashes = $hashes;
243        $this->height = $height;
244        $this->keywords = $keywords;
245        $this->lang = $lang;
246        $this->length = $length;
247        $this->link = $link;
248        $this->medium = $medium;
249        $this->player = $player;
250        $this->ratings = $ratings;
251        $this->restrictions = $restrictions;
252        $this->samplingrate = $samplingrate;
253        $this->thumbnails = $thumbnails;
254        $this->title = $title;
255        $this->type = $type;
256        $this->width = $width;
257
258        if (class_exists('idna_convert')) {
259            $idn = new \idna_convert();
260            $parsed = \SimplePie\Misc::parse_url($link);
261            $this->link = \SimplePie\Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
262        }
263        $this->handler = $this->get_handler(); // Needs to load last
264    }
265
266    /**
267     * String-ified version
268     *
269     * @return string
270     */
271    public function __toString()
272    {
273        // There is no $this->data here
274        return md5(serialize($this));
275    }
276
277    /**
278     * Get the bitrate
279     *
280     * @return string|null
281     */
282    public function get_bitrate()
283    {
284        if ($this->bitrate !== null) {
285            return $this->bitrate;
286        }
287
288        return null;
289    }
290
291    /**
292     * Get a single caption
293     *
294     * @param int $key
295     * @return \SimplePie\Caption|null
296     */
297    public function get_caption($key = 0)
298    {
299        $captions = $this->get_captions();
300        if (isset($captions[$key])) {
301            return $captions[$key];
302        }
303
304        return null;
305    }
306
307    /**
308     * Get all captions
309     *
310     * @return array|null Array of {@see \SimplePie\Caption} objects
311     */
312    public function get_captions()
313    {
314        if ($this->captions !== null) {
315            return $this->captions;
316        }
317
318        return null;
319    }
320
321    /**
322     * Get a single category
323     *
324     * @param int $key
325     * @return \SimplePie\Category|null
326     */
327    public function get_category($key = 0)
328    {
329        $categories = $this->get_categories();
330        if (isset($categories[$key])) {
331            return $categories[$key];
332        }
333
334        return null;
335    }
336
337    /**
338     * Get all categories
339     *
340     * @return array|null Array of {@see \SimplePie\Category} objects
341     */
342    public function get_categories()
343    {
344        if ($this->categories !== null) {
345            return $this->categories;
346        }
347
348        return null;
349    }
350
351    /**
352     * Get the number of audio channels
353     *
354     * @return int|null
355     */
356    public function get_channels()
357    {
358        if ($this->channels !== null) {
359            return $this->channels;
360        }
361
362        return null;
363    }
364
365    /**
366     * Get the copyright information
367     *
368     * @return \SimplePie\Copyright|null
369     */
370    public function get_copyright()
371    {
372        if ($this->copyright !== null) {
373            return $this->copyright;
374        }
375
376        return null;
377    }
378
379    /**
380     * Get a single credit
381     *
382     * @param int $key
383     * @return \SimplePie\Credit|null
384     */
385    public function get_credit($key = 0)
386    {
387        $credits = $this->get_credits();
388        if (isset($credits[$key])) {
389            return $credits[$key];
390        }
391
392        return null;
393    }
394
395    /**
396     * Get all credits
397     *
398     * @return array|null Array of {@see \SimplePie\Credit} objects
399     */
400    public function get_credits()
401    {
402        if ($this->credits !== null) {
403            return $this->credits;
404        }
405
406        return null;
407    }
408
409    /**
410     * Get the description of the enclosure
411     *
412     * @return string|null
413     */
414    public function get_description()
415    {
416        if ($this->description !== null) {
417            return $this->description;
418        }
419
420        return null;
421    }
422
423    /**
424     * Get the duration of the enclosure
425     *
426     * @param bool $convert Convert seconds into hh:mm:ss
427     * @return string|int|null 'hh:mm:ss' string if `$convert` was specified, otherwise integer (or null if none found)
428     */
429    public function get_duration($convert = false)
430    {
431        if ($this->duration !== null) {
432            if ($convert) {
433                $time = \SimplePie\Misc::time_hms($this->duration);
434                return $time;
435            }
436
437            return $this->duration;
438        }
439
440        return null;
441    }
442
443    /**
444     * Get the expression
445     *
446     * @return string Probably one of 'sample', 'full', 'nonstop', 'clip'. Defaults to 'full'
447     */
448    public function get_expression()
449    {
450        if ($this->expression !== null) {
451            return $this->expression;
452        }
453
454        return 'full';
455    }
456
457    /**
458     * Get the file extension
459     *
460     * @return string|null
461     */
462    public function get_extension()
463    {
464        if ($this->link !== null) {
465            $url = \SimplePie\Misc::parse_url($this->link);
466            if ($url['path'] !== '') {
467                return pathinfo($url['path'], PATHINFO_EXTENSION);
468            }
469        }
470        return null;
471    }
472
473    /**
474     * Get the framerate (in frames-per-second)
475     *
476     * @return string|null
477     */
478    public function get_framerate()
479    {
480        if ($this->framerate !== null) {
481            return $this->framerate;
482        }
483
484        return null;
485    }
486
487    /**
488     * Get the preferred handler
489     *
490     * @return string|null One of 'flash', 'fmedia', 'quicktime', 'wmedia', 'mp3'
491     */
492    public function get_handler()
493    {
494        return $this->get_real_type(true);
495    }
496
497    /**
498     * Get a single hash
499     *
500     * @link http://www.rssboard.org/media-rss#media-hash
501     * @param int $key
502     * @return string|null Hash as per `media:hash`, prefixed with "$algo:"
503     */
504    public function get_hash($key = 0)
505    {
506        $hashes = $this->get_hashes();
507        if (isset($hashes[$key])) {
508            return $hashes[$key];
509        }
510
511        return null;
512    }
513
514    /**
515     * Get all credits
516     *
517     * @return array|null Array of strings, see {@see get_hash()}
518     */
519    public function get_hashes()
520    {
521        if ($this->hashes !== null) {
522            return $this->hashes;
523        }
524
525        return null;
526    }
527
528    /**
529     * Get the height
530     *
531     * @return string|null
532     */
533    public function get_height()
534    {
535        if ($this->height !== null) {
536            return $this->height;
537        }
538
539        return null;
540    }
541
542    /**
543     * Get the language
544     *
545     * @link http://tools.ietf.org/html/rfc3066
546     * @return string|null Language code as per RFC 3066
547     */
548    public function get_language()
549    {
550        if ($this->lang !== null) {
551            return $this->lang;
552        }
553
554        return null;
555    }
556
557    /**
558     * Get a single keyword
559     *
560     * @param int $key
561     * @return string|null
562     */
563    public function get_keyword($key = 0)
564    {
565        $keywords = $this->get_keywords();
566        if (isset($keywords[$key])) {
567            return $keywords[$key];
568        }
569
570        return null;
571    }
572
573    /**
574     * Get all keywords
575     *
576     * @return array|null Array of strings
577     */
578    public function get_keywords()
579    {
580        if ($this->keywords !== null) {
581            return $this->keywords;
582        }
583
584        return null;
585    }
586
587    /**
588     * Get length
589     *
590     * @return float Length in bytes
591     */
592    public function get_length()
593    {
594        if ($this->length !== null) {
595            return $this->length;
596        }
597
598        return null;
599    }
600
601    /**
602     * Get the URL
603     *
604     * @return string|null
605     */
606    public function get_link()
607    {
608        if ($this->link !== null) {
609            return $this->link;
610        }
611
612        return null;
613    }
614
615    /**
616     * Get the medium
617     *
618     * @link http://www.rssboard.org/media-rss#media-content
619     * @return string|null Should be one of 'image', 'audio', 'video', 'document', 'executable'
620     */
621    public function get_medium()
622    {
623        if ($this->medium !== null) {
624            return $this->medium;
625        }
626
627        return null;
628    }
629
630    /**
631     * Get the player URL
632     *
633     * Typically the same as {@see get_permalink()}
634     * @return string|null Player URL
635     */
636    public function get_player()
637    {
638        if ($this->player !== null) {
639            return $this->player;
640        }
641
642        return null;
643    }
644
645    /**
646     * Get a single rating
647     *
648     * @param int $key
649     * @return \SimplePie\Rating|null
650     */
651    public function get_rating($key = 0)
652    {
653        $ratings = $this->get_ratings();
654        if (isset($ratings[$key])) {
655            return $ratings[$key];
656        }
657
658        return null;
659    }
660
661    /**
662     * Get all ratings
663     *
664     * @return array|null Array of {@see \SimplePie\Rating} objects
665     */
666    public function get_ratings()
667    {
668        if ($this->ratings !== null) {
669            return $this->ratings;
670        }
671
672        return null;
673    }
674
675    /**
676     * Get a single restriction
677     *
678     * @param int $key
679     * @return \SimplePie\Restriction|null
680     */
681    public function get_restriction($key = 0)
682    {
683        $restrictions = $this->get_restrictions();
684        if (isset($restrictions[$key])) {
685            return $restrictions[$key];
686        }
687
688        return null;
689    }
690
691    /**
692     * Get all restrictions
693     *
694     * @return array|null Array of {@see \SimplePie\Restriction} objects
695     */
696    public function get_restrictions()
697    {
698        if ($this->restrictions !== null) {
699            return $this->restrictions;
700        }
701
702        return null;
703    }
704
705    /**
706     * Get the sampling rate (in kHz)
707     *
708     * @return string|null
709     */
710    public function get_sampling_rate()
711    {
712        if ($this->samplingrate !== null) {
713            return $this->samplingrate;
714        }
715
716        return null;
717    }
718
719    /**
720     * Get the file size (in MiB)
721     *
722     * @return float|null File size in mebibytes (1048 bytes)
723     */
724    public function get_size()
725    {
726        $length = $this->get_length();
727        if ($length !== null) {
728            return round($length/1048576, 2);
729        }
730
731        return null;
732    }
733
734    /**
735     * Get a single thumbnail
736     *
737     * @param int $key
738     * @return string|null Thumbnail URL
739     */
740    public function get_thumbnail($key = 0)
741    {
742        $thumbnails = $this->get_thumbnails();
743        if (isset($thumbnails[$key])) {
744            return $thumbnails[$key];
745        }
746
747        return null;
748    }
749
750    /**
751     * Get all thumbnails
752     *
753     * @return array|null Array of thumbnail URLs
754     */
755    public function get_thumbnails()
756    {
757        if ($this->thumbnails !== null) {
758            return $this->thumbnails;
759        }
760
761        return null;
762    }
763
764    /**
765     * Get the title
766     *
767     * @return string|null
768     */
769    public function get_title()
770    {
771        if ($this->title !== null) {
772            return $this->title;
773        }
774
775        return null;
776    }
777
778    /**
779     * Get mimetype of the enclosure
780     *
781     * @see get_real_type()
782     * @return string|null MIME type
783     */
784    public function get_type()
785    {
786        if ($this->type !== null) {
787            return $this->type;
788        }
789
790        return null;
791    }
792
793    /**
794     * Get the width
795     *
796     * @return string|null
797     */
798    public function get_width()
799    {
800        if ($this->width !== null) {
801            return $this->width;
802        }
803
804        return null;
805    }
806
807    /**
808     * Embed the enclosure using `<embed>`
809     *
810     * @deprecated Use the second parameter to {@see embed} instead
811     *
812     * @param array|string $options See first parameter to {@see embed}
813     * @return string HTML string to output
814     */
815    public function native_embed($options='')
816    {
817        return $this->embed($options, true);
818    }
819
820    /**
821     * Embed the enclosure using Javascript
822     *
823     * `$options` is an array or comma-separated key:value string, with the
824     * following properties:
825     *
826     * - `alt` (string): Alternate content for when an end-user does not have
827     *    the appropriate handler installed or when a file type is
828     *    unsupported. Can be any text or HTML. Defaults to blank.
829     * - `altclass` (string): If a file type is unsupported, the end-user will
830     *    see the alt text (above) linked directly to the content. That link
831     *    will have this value as its class name. Defaults to blank.
832     * - `audio` (string): This is an image that should be used as a
833     *    placeholder for audio files before they're loaded (QuickTime-only).
834     *    Can be any relative or absolute URL. Defaults to blank.
835     * - `bgcolor` (string): The background color for the media, if not
836     *    already transparent. Defaults to `#ffffff`.
837     * - `height` (integer): The height of the embedded media. Accepts any
838     *    numeric pixel value (such as `360`) or `auto`. Defaults to `auto`,
839     *    and it is recommended that you use this default.
840     * - `loop` (boolean): Do you want the media to loop when it's done?
841     *    Defaults to `false`.
842     * - `mediaplayer` (string): The location of the included
843     *    `mediaplayer.swf` file. This allows for the playback of Flash Video
844     *    (`.flv`) files, and is the default handler for non-Odeo MP3's.
845     *    Defaults to blank.
846     * - `video` (string): This is an image that should be used as a
847     *    placeholder for video files before they're loaded (QuickTime-only).
848     *    Can be any relative or absolute URL. Defaults to blank.
849     * - `width` (integer): The width of the embedded media. Accepts any
850     *    numeric pixel value (such as `480`) or `auto`. Defaults to `auto`,
851     *    and it is recommended that you use this default.
852     * - `widescreen` (boolean): Is the enclosure widescreen or standard?
853     *    This applies only to video enclosures, and will automatically resize
854     *    the content appropriately.  Defaults to `false`, implying 4:3 mode.
855     *
856     * Note: Non-widescreen (4:3) mode with `width` and `height` set to `auto`
857     * will default to 480x360 video resolution.  Widescreen (16:9) mode with
858     * `width` and `height` set to `auto` will default to 480x270 video resolution.
859     *
860     * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
861     * @param array|string $options Comma-separated key:value list, or array
862     * @param bool $native Use `<embed>`
863     * @return string HTML string to output
864     */
865    public function embed($options = '', $native = false)
866    {
867        // Set up defaults
868        $audio = '';
869        $video = '';
870        $alt = '';
871        $altclass = '';
872        $loop = 'false';
873        $width = 'auto';
874        $height = 'auto';
875        $bgcolor = '#ffffff';
876        $mediaplayer = '';
877        $widescreen = false;
878        $handler = $this->get_handler();
879        $type = $this->get_real_type();
880        $placeholder = '';
881
882        // Process options and reassign values as necessary
883        if (is_array($options)) {
884            extract($options);
885        } else {
886            $options = explode(',', $options);
887            foreach ($options as $option) {
888                $opt = explode(':', $option, 2);
889                if (isset($opt[0], $opt[1])) {
890                    $opt[0] = trim($opt[0]);
891                    $opt[1] = trim($opt[1]);
892                    switch ($opt[0]) {
893                        case 'audio':
894                            $audio = $opt[1];
895                            break;
896
897                        case 'video':
898                            $video = $opt[1];
899                            break;
900
901                        case 'alt':
902                            $alt = $opt[1];
903                            break;
904
905                        case 'altclass':
906                            $altclass = $opt[1];
907                            break;
908
909                        case 'loop':
910                            $loop = $opt[1];
911                            break;
912
913                        case 'width':
914                            $width = $opt[1];
915                            break;
916
917                        case 'height':
918                            $height = $opt[1];
919                            break;
920
921                        case 'bgcolor':
922                            $bgcolor = $opt[1];
923                            break;
924
925                        case 'mediaplayer':
926                            $mediaplayer = $opt[1];
927                            break;
928
929                        case 'widescreen':
930                            $widescreen = $opt[1];
931                            break;
932                    }
933                }
934            }
935        }
936
937        $mime = explode('/', $type, 2);
938        $mime = $mime[0];
939
940        // Process values for 'auto'
941        if ($width === 'auto') {
942            if ($mime === 'video') {
943                if ($height === 'auto') {
944                    $width = 480;
945                } elseif ($widescreen) {
946                    $width = round((intval($height)/9)*16);
947                } else {
948                    $width = round((intval($height)/3)*4);
949                }
950            } else {
951                $width = '100%';
952            }
953        }
954
955        if ($height === 'auto') {
956            if ($mime === 'audio') {
957                $height = 0;
958            } elseif ($mime === 'video') {
959                if ($width === 'auto') {
960                    if ($widescreen) {
961                        $height = 270;
962                    } else {
963                        $height = 360;
964                    }
965                } elseif ($widescreen) {
966                    $height = round((intval($width)/16)*9);
967                } else {
968                    $height = round((intval($width)/4)*3);
969                }
970            } else {
971                $height = 376;
972            }
973        } elseif ($mime === 'audio') {
974            $height = 0;
975        }
976
977        // Set proper placeholder value
978        if ($mime === 'audio') {
979            $placeholder = $audio;
980        } elseif ($mime === 'video') {
981            $placeholder = $video;
982        }
983
984        $embed = '';
985
986        // Flash
987        if ($handler === 'flash') {
988            if ($native) {
989                $embed .= "<embed src=\"" . $this->get_link() . "\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"$type\" quality=\"high\" width=\"$width\" height=\"$height\" bgcolor=\"$bgcolor\" loop=\"$loop\"></embed>";
990            } else {
991                $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
992            }
993        }
994
995        // Flash Media Player file types.
996        // Preferred handler for MP3 file types.
997        elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== '')) {
998            $height += 20;
999            if ($native) {
1000                $embed .= "<embed src=\"$mediaplayer\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" quality=\"high\" width=\"$width\" height=\"$height\" wmode=\"transparent\" flashvars=\"file=" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "&autostart=false&repeat=$loop&showdigits=true&showfsbutton=false\"></embed>";
1001            } else {
1002                $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
1003            }
1004        }
1005
1006        // QuickTime 7 file types.  Need to test with QuickTime 6.
1007        // Only handle MP3's if the Flash Media Player is not present.
1008        elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === '')) {
1009            $height += 16;
1010            if ($native) {
1011                if ($placeholder !== '') {
1012                    $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" href=\"" . $this->get_link() . "\" src=\"$placeholder\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"false\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
1013                } else {
1014                    $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" src=\"" . $this->get_link() . "\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"true\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
1015                }
1016            } else {
1017                $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
1018            }
1019        }
1020
1021        // Windows Media
1022        elseif ($handler === 'wmedia') {
1023            $height += 45;
1024            if ($native) {
1025                $embed .= "<embed type=\"application/x-mplayer2\" src=\"" . $this->get_link() . "\" autosize=\"1\" width=\"$width\" height=\"$height\" showcontrols=\"1\" showstatusbar=\"0\" showdisplay=\"0\" autostart=\"0\"></embed>";
1026            } else {
1027                $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
1028            }
1029        }
1030
1031        // Everything else
1032        else {
1033            $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
1034        }
1035
1036        return $embed;
1037    }
1038
1039    /**
1040     * Get the real media type
1041     *
1042     * Often, feeds lie to us, necessitating a bit of deeper inspection. This
1043     * converts types to their canonical representations based on the file
1044     * extension
1045     *
1046     * @see get_type()
1047     * @param bool $find_handler Internal use only, use {@see get_handler()} instead
1048     * @return string MIME type
1049     */
1050    public function get_real_type($find_handler = false)
1051    {
1052        // Mime-types by handler.
1053        $types_flash = ['application/x-shockwave-flash', 'application/futuresplash']; // Flash
1054        $types_fmedia = ['video/flv', 'video/x-flv','flv-application/octet-stream']; // Flash Media Player
1055        $types_quicktime = ['audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video']; // QuickTime
1056        $types_wmedia = ['application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx']; // Windows Media
1057        $types_mp3 = ['audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg']; // MP3
1058
1059        if ($this->get_type() !== null) {
1060            $type = strtolower($this->type);
1061        } else {
1062            $type = null;
1063        }
1064
1065        // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
1066        if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3))) {
1067            $extension = $this->get_extension();
1068            if ($extension === null) {
1069                return null;
1070            }
1071
1072            switch (strtolower($extension)) {
1073                // Audio mime-types
1074                case 'aac':
1075                case 'adts':
1076                    $type = 'audio/acc';
1077                    break;
1078
1079                case 'aif':
1080                case 'aifc':
1081                case 'aiff':
1082                case 'cdda':
1083                    $type = 'audio/aiff';
1084                    break;
1085
1086                case 'bwf':
1087                    $type = 'audio/wav';
1088                    break;
1089
1090                case 'kar':
1091                case 'mid':
1092                case 'midi':
1093                case 'smf':
1094                    $type = 'audio/midi';
1095                    break;
1096
1097                case 'm4a':
1098                    $type = 'audio/x-m4a';
1099                    break;
1100
1101                case 'mp3':
1102                case 'swa':
1103                    $type = 'audio/mp3';
1104                    break;
1105
1106                case 'wav':
1107                    $type = 'audio/wav';
1108                    break;
1109
1110                case 'wax':
1111                    $type = 'audio/x-ms-wax';
1112                    break;
1113
1114                case 'wma':
1115                    $type = 'audio/x-ms-wma';
1116                    break;
1117
1118                // Video mime-types
1119                case '3gp':
1120                case '3gpp':
1121                    $type = 'video/3gpp';
1122                    break;
1123
1124                case '3g2':
1125                case '3gp2':
1126                    $type = 'video/3gpp2';
1127                    break;
1128
1129                case 'asf':
1130                    $type = 'video/x-ms-asf';
1131                    break;
1132
1133                case 'flv':
1134                    $type = 'video/x-flv';
1135                    break;
1136
1137                case 'm1a':
1138                case 'm1s':
1139                case 'm1v':
1140                case 'm15':
1141                case 'm75':
1142                case 'mp2':
1143                case 'mpa':
1144                case 'mpeg':
1145                case 'mpg':
1146                case 'mpm':
1147                case 'mpv':
1148                    $type = 'video/mpeg';
1149                    break;
1150
1151                case 'm4v':
1152                    $type = 'video/x-m4v';
1153                    break;
1154
1155                case 'mov':
1156                case 'qt':
1157                    $type = 'video/quicktime';
1158                    break;
1159
1160                case 'mp4':
1161                case 'mpg4':
1162                    $type = 'video/mp4';
1163                    break;
1164
1165                case 'sdv':
1166                    $type = 'video/sd-video';
1167                    break;
1168
1169                case 'wm':
1170                    $type = 'video/x-ms-wm';
1171                    break;
1172
1173                case 'wmv':
1174                    $type = 'video/x-ms-wmv';
1175                    break;
1176
1177                case 'wvx':
1178                    $type = 'video/x-ms-wvx';
1179                    break;
1180
1181                // Flash mime-types
1182                case 'spl':
1183                    $type = 'application/futuresplash';
1184                    break;
1185
1186                case 'swf':
1187                    $type = 'application/x-shockwave-flash';
1188                    break;
1189            }
1190        }
1191
1192        if ($find_handler) {
1193            if (in_array($type, $types_flash)) {
1194                return 'flash';
1195            } elseif (in_array($type, $types_fmedia)) {
1196                return 'fmedia';
1197            } elseif (in_array($type, $types_quicktime)) {
1198                return 'quicktime';
1199            } elseif (in_array($type, $types_wmedia)) {
1200                return 'wmedia';
1201            } elseif (in_array($type, $types_mp3)) {
1202                return 'mp3';
1203            }
1204
1205            return null;
1206        }
1207
1208        return $type;
1209    }
1210}
1211
1212class_alias('SimplePie\Enclosure', 'SimplePie_Enclosure');
1213