]> git.immae.eu Git - github/wallabag/wallabag.git/blob - inc/3rdparty/simplepie/SimplePie/Enclosure.php
Merge pull request #181 from inthepoche/dev
[github/wallabag/wallabag.git] / inc / 3rdparty / simplepie / SimplePie / Enclosure.php
1 <?php
2 /**
3 * SimplePie
4 *
5 * A PHP-Based RSS and Atom Feed Framework.
6 * Takes the hard work out of managing a complete RSS/Atom solution.
7 *
8 * Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without modification, are
12 * permitted provided that the following conditions are met:
13 *
14 * * Redistributions of source code must retain the above copyright notice, this list of
15 * conditions and the following disclaimer.
16 *
17 * * Redistributions in binary form must reproduce the above copyright notice, this list
18 * of conditions and the following disclaimer in the documentation and/or other materials
19 * provided with the distribution.
20 *
21 * * Neither the name of the SimplePie Team nor the names of its contributors may be used
22 * to endorse or promote products derived from this software without specific prior
23 * written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
28 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *
35 * @package SimplePie
36 * @version 1.3-dev
37 * @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
38 * @author Ryan Parman
39 * @author Geoffrey Sneddon
40 * @author Ryan McCue
41 * @link http://simplepie.org/ SimplePie
42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43 * @todo phpDoc comments
44 */
45
46
47 class SimplePie_Enclosure
48 {
49 var $bitrate;
50 var $captions;
51 var $categories;
52 var $channels;
53 var $copyright;
54 var $credits;
55 var $description;
56 var $duration;
57 var $expression;
58 var $framerate;
59 var $handler;
60 var $hashes;
61 var $height;
62 var $javascript;
63 var $keywords;
64 var $lang;
65 var $length;
66 var $link;
67 var $medium;
68 var $player;
69 var $ratings;
70 var $restrictions;
71 var $samplingrate;
72 var $thumbnails;
73 var $title;
74 var $type;
75 var $width;
76
77 // Constructor, used to input the data
78 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)
79 {
80 $this->bitrate = $bitrate;
81 $this->captions = $captions;
82 $this->categories = $categories;
83 $this->channels = $channels;
84 $this->copyright = $copyright;
85 $this->credits = $credits;
86 $this->description = $description;
87 $this->duration = $duration;
88 $this->expression = $expression;
89 $this->framerate = $framerate;
90 $this->hashes = $hashes;
91 $this->height = $height;
92 $this->keywords = $keywords;
93 $this->lang = $lang;
94 $this->length = $length;
95 $this->link = $link;
96 $this->medium = $medium;
97 $this->player = $player;
98 $this->ratings = $ratings;
99 $this->restrictions = $restrictions;
100 $this->samplingrate = $samplingrate;
101 $this->thumbnails = $thumbnails;
102 $this->title = $title;
103 $this->type = $type;
104 $this->width = $width;
105
106 if (class_exists('idna_convert'))
107 {
108 $idn = new idna_convert();
109 $parsed = SimplePie_Misc::parse_url($link);
110 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
111 }
112 $this->handler = $this->get_handler(); // Needs to load last
113 }
114
115 public function __toString()
116 {
117 // There is no $this->data here
118 return md5(serialize($this));
119 }
120
121 public function get_bitrate()
122 {
123 if ($this->bitrate !== null)
124 {
125 return $this->bitrate;
126 }
127 else
128 {
129 return null;
130 }
131 }
132
133 public function get_caption($key = 0)
134 {
135 $captions = $this->get_captions();
136 if (isset($captions[$key]))
137 {
138 return $captions[$key];
139 }
140 else
141 {
142 return null;
143 }
144 }
145
146 public function get_captions()
147 {
148 if ($this->captions !== null)
149 {
150 return $this->captions;
151 }
152 else
153 {
154 return null;
155 }
156 }
157
158 public function get_category($key = 0)
159 {
160 $categories = $this->get_categories();
161 if (isset($categories[$key]))
162 {
163 return $categories[$key];
164 }
165 else
166 {
167 return null;
168 }
169 }
170
171 public function get_categories()
172 {
173 if ($this->categories !== null)
174 {
175 return $this->categories;
176 }
177 else
178 {
179 return null;
180 }
181 }
182
183 public function get_channels()
184 {
185 if ($this->channels !== null)
186 {
187 return $this->channels;
188 }
189 else
190 {
191 return null;
192 }
193 }
194
195 public function get_copyright()
196 {
197 if ($this->copyright !== null)
198 {
199 return $this->copyright;
200 }
201 else
202 {
203 return null;
204 }
205 }
206
207 public function get_credit($key = 0)
208 {
209 $credits = $this->get_credits();
210 if (isset($credits[$key]))
211 {
212 return $credits[$key];
213 }
214 else
215 {
216 return null;
217 }
218 }
219
220 public function get_credits()
221 {
222 if ($this->credits !== null)
223 {
224 return $this->credits;
225 }
226 else
227 {
228 return null;
229 }
230 }
231
232 public function get_description()
233 {
234 if ($this->description !== null)
235 {
236 return $this->description;
237 }
238 else
239 {
240 return null;
241 }
242 }
243
244 public function get_duration($convert = false)
245 {
246 if ($this->duration !== null)
247 {
248 if ($convert)
249 {
250 $time = SimplePie_Misc::time_hms($this->duration);
251 return $time;
252 }
253 else
254 {
255 return $this->duration;
256 }
257 }
258 else
259 {
260 return null;
261 }
262 }
263
264 public function get_expression()
265 {
266 if ($this->expression !== null)
267 {
268 return $this->expression;
269 }
270 else
271 {
272 return 'full';
273 }
274 }
275
276 public function get_extension()
277 {
278 if ($this->link !== null)
279 {
280 $url = SimplePie_Misc::parse_url($this->link);
281 if ($url['path'] !== '')
282 {
283 return pathinfo($url['path'], PATHINFO_EXTENSION);
284 }
285 }
286 return null;
287 }
288
289 public function get_framerate()
290 {
291 if ($this->framerate !== null)
292 {
293 return $this->framerate;
294 }
295 else
296 {
297 return null;
298 }
299 }
300
301 public function get_handler()
302 {
303 return $this->get_real_type(true);
304 }
305
306 public function get_hash($key = 0)
307 {
308 $hashes = $this->get_hashes();
309 if (isset($hashes[$key]))
310 {
311 return $hashes[$key];
312 }
313 else
314 {
315 return null;
316 }
317 }
318
319 public function get_hashes()
320 {
321 if ($this->hashes !== null)
322 {
323 return $this->hashes;
324 }
325 else
326 {
327 return null;
328 }
329 }
330
331 public function get_height()
332 {
333 if ($this->height !== null)
334 {
335 return $this->height;
336 }
337 else
338 {
339 return null;
340 }
341 }
342
343 public function get_language()
344 {
345 if ($this->lang !== null)
346 {
347 return $this->lang;
348 }
349 else
350 {
351 return null;
352 }
353 }
354
355 public function get_keyword($key = 0)
356 {
357 $keywords = $this->get_keywords();
358 if (isset($keywords[$key]))
359 {
360 return $keywords[$key];
361 }
362 else
363 {
364 return null;
365 }
366 }
367
368 public function get_keywords()
369 {
370 if ($this->keywords !== null)
371 {
372 return $this->keywords;
373 }
374 else
375 {
376 return null;
377 }
378 }
379
380 public function get_length()
381 {
382 if ($this->length !== null)
383 {
384 return $this->length;
385 }
386 else
387 {
388 return null;
389 }
390 }
391
392 public function get_link()
393 {
394 if ($this->link !== null)
395 {
396 return urldecode($this->link);
397 }
398 else
399 {
400 return null;
401 }
402 }
403
404 public function get_medium()
405 {
406 if ($this->medium !== null)
407 {
408 return $this->medium;
409 }
410 else
411 {
412 return null;
413 }
414 }
415
416 public function get_player()
417 {
418 if ($this->player !== null)
419 {
420 return $this->player;
421 }
422 else
423 {
424 return null;
425 }
426 }
427
428 public function get_rating($key = 0)
429 {
430 $ratings = $this->get_ratings();
431 if (isset($ratings[$key]))
432 {
433 return $ratings[$key];
434 }
435 else
436 {
437 return null;
438 }
439 }
440
441 public function get_ratings()
442 {
443 if ($this->ratings !== null)
444 {
445 return $this->ratings;
446 }
447 else
448 {
449 return null;
450 }
451 }
452
453 public function get_restriction($key = 0)
454 {
455 $restrictions = $this->get_restrictions();
456 if (isset($restrictions[$key]))
457 {
458 return $restrictions[$key];
459 }
460 else
461 {
462 return null;
463 }
464 }
465
466 public function get_restrictions()
467 {
468 if ($this->restrictions !== null)
469 {
470 return $this->restrictions;
471 }
472 else
473 {
474 return null;
475 }
476 }
477
478 public function get_sampling_rate()
479 {
480 if ($this->samplingrate !== null)
481 {
482 return $this->samplingrate;
483 }
484 else
485 {
486 return null;
487 }
488 }
489
490 public function get_size()
491 {
492 $length = $this->get_length();
493 if ($length !== null)
494 {
495 return round($length/1048576, 2);
496 }
497 else
498 {
499 return null;
500 }
501 }
502
503 public function get_thumbnail($key = 0)
504 {
505 $thumbnails = $this->get_thumbnails();
506 if (isset($thumbnails[$key]))
507 {
508 return $thumbnails[$key];
509 }
510 else
511 {
512 return null;
513 }
514 }
515
516 public function get_thumbnails()
517 {
518 if ($this->thumbnails !== null)
519 {
520 return $this->thumbnails;
521 }
522 else
523 {
524 return null;
525 }
526 }
527
528 public function get_title()
529 {
530 if ($this->title !== null)
531 {
532 return $this->title;
533 }
534 else
535 {
536 return null;
537 }
538 }
539
540 public function get_type()
541 {
542 if ($this->type !== null)
543 {
544 return $this->type;
545 }
546 else
547 {
548 return null;
549 }
550 }
551
552 public function get_width()
553 {
554 if ($this->width !== null)
555 {
556 return $this->width;
557 }
558 else
559 {
560 return null;
561 }
562 }
563
564 public function native_embed($options='')
565 {
566 return $this->embed($options, true);
567 }
568
569 /**
570 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
571 */
572 public function embed($options = '', $native = false)
573 {
574 // Set up defaults
575 $audio = '';
576 $video = '';
577 $alt = '';
578 $altclass = '';
579 $loop = 'false';
580 $width = 'auto';
581 $height = 'auto';
582 $bgcolor = '#ffffff';
583 $mediaplayer = '';
584 $widescreen = false;
585 $handler = $this->get_handler();
586 $type = $this->get_real_type();
587
588 // Process options and reassign values as necessary
589 if (is_array($options))
590 {
591 extract($options);
592 }
593 else
594 {
595 $options = explode(',', $options);
596 foreach($options as $option)
597 {
598 $opt = explode(':', $option, 2);
599 if (isset($opt[0], $opt[1]))
600 {
601 $opt[0] = trim($opt[0]);
602 $opt[1] = trim($opt[1]);
603 switch ($opt[0])
604 {
605 case 'audio':
606 $audio = $opt[1];
607 break;
608
609 case 'video':
610 $video = $opt[1];
611 break;
612
613 case 'alt':
614 $alt = $opt[1];
615 break;
616
617 case 'altclass':
618 $altclass = $opt[1];
619 break;
620
621 case 'loop':
622 $loop = $opt[1];
623 break;
624
625 case 'width':
626 $width = $opt[1];
627 break;
628
629 case 'height':
630 $height = $opt[1];
631 break;
632
633 case 'bgcolor':
634 $bgcolor = $opt[1];
635 break;
636
637 case 'mediaplayer':
638 $mediaplayer = $opt[1];
639 break;
640
641 case 'widescreen':
642 $widescreen = $opt[1];
643 break;
644 }
645 }
646 }
647 }
648
649 $mime = explode('/', $type, 2);
650 $mime = $mime[0];
651
652 // Process values for 'auto'
653 if ($width === 'auto')
654 {
655 if ($mime === 'video')
656 {
657 if ($height === 'auto')
658 {
659 $width = 480;
660 }
661 elseif ($widescreen)
662 {
663 $width = round((intval($height)/9)*16);
664 }
665 else
666 {
667 $width = round((intval($height)/3)*4);
668 }
669 }
670 else
671 {
672 $width = '100%';
673 }
674 }
675
676 if ($height === 'auto')
677 {
678 if ($mime === 'audio')
679 {
680 $height = 0;
681 }
682 elseif ($mime === 'video')
683 {
684 if ($width === 'auto')
685 {
686 if ($widescreen)
687 {
688 $height = 270;
689 }
690 else
691 {
692 $height = 360;
693 }
694 }
695 elseif ($widescreen)
696 {
697 $height = round((intval($width)/16)*9);
698 }
699 else
700 {
701 $height = round((intval($width)/4)*3);
702 }
703 }
704 else
705 {
706 $height = 376;
707 }
708 }
709 elseif ($mime === 'audio')
710 {
711 $height = 0;
712 }
713
714 // Set proper placeholder value
715 if ($mime === 'audio')
716 {
717 $placeholder = $audio;
718 }
719 elseif ($mime === 'video')
720 {
721 $placeholder = $video;
722 }
723
724 $embed = '';
725
726 // Odeo Feed MP3's
727 if ($handler === 'odeo')
728 {
729 if ($native)
730 {
731 $embed .= '<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://adobe.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url=' . $this->get_link() . '"></embed>';
732 }
733 else
734 {
735 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
736 }
737 }
738
739 // Flash
740 elseif ($handler === 'flash')
741 {
742 if ($native)
743 {
744 $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>";
745 }
746 else
747 {
748 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
749 }
750 }
751
752 // Flash Media Player file types.
753 // Preferred handler for MP3 file types.
754 elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== ''))
755 {
756 $height += 20;
757 if ($native)
758 {
759 $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>";
760 }
761 else
762 {
763 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
764 }
765 }
766
767 // QuickTime 7 file types. Need to test with QuickTime 6.
768 // Only handle MP3's if the Flash Media Player is not present.
769 elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === ''))
770 {
771 $height += 16;
772 if ($native)
773 {
774 if ($placeholder !== '')
775 {
776 $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>";
777 }
778 else
779 {
780 $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>";
781 }
782 }
783 else
784 {
785 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
786 }
787 }
788
789 // Windows Media
790 elseif ($handler === 'wmedia')
791 {
792 $height += 45;
793 if ($native)
794 {
795 $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>";
796 }
797 else
798 {
799 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
800 }
801 }
802
803 // Everything else
804 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
805
806 return $embed;
807 }
808
809 public function get_real_type($find_handler = false)
810 {
811 // If it's Odeo, let's get it out of the way.
812 if (substr(strtolower($this->get_link()), 0, 15) === 'http://odeo.com')
813 {
814 return 'odeo';
815 }
816
817 // Mime-types by handler.
818 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
819 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
820 $types_quicktime = array('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
821 $types_wmedia = array('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
822 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
823
824 if ($this->get_type() !== null)
825 {
826 $type = strtolower($this->type);
827 }
828 else
829 {
830 $type = null;
831 }
832
833 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
834 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
835 {
836 switch (strtolower($this->get_extension()))
837 {
838 // Audio mime-types
839 case 'aac':
840 case 'adts':
841 $type = 'audio/acc';
842 break;
843
844 case 'aif':
845 case 'aifc':
846 case 'aiff':
847 case 'cdda':
848 $type = 'audio/aiff';
849 break;
850
851 case 'bwf':
852 $type = 'audio/wav';
853 break;
854
855 case 'kar':
856 case 'mid':
857 case 'midi':
858 case 'smf':
859 $type = 'audio/midi';
860 break;
861
862 case 'm4a':
863 $type = 'audio/x-m4a';
864 break;
865
866 case 'mp3':
867 case 'swa':
868 $type = 'audio/mp3';
869 break;
870
871 case 'wav':
872 $type = 'audio/wav';
873 break;
874
875 case 'wax':
876 $type = 'audio/x-ms-wax';
877 break;
878
879 case 'wma':
880 $type = 'audio/x-ms-wma';
881 break;
882
883 // Video mime-types
884 case '3gp':
885 case '3gpp':
886 $type = 'video/3gpp';
887 break;
888
889 case '3g2':
890 case '3gp2':
891 $type = 'video/3gpp2';
892 break;
893
894 case 'asf':
895 $type = 'video/x-ms-asf';
896 break;
897
898 case 'flv':
899 $type = 'video/x-flv';
900 break;
901
902 case 'm1a':
903 case 'm1s':
904 case 'm1v':
905 case 'm15':
906 case 'm75':
907 case 'mp2':
908 case 'mpa':
909 case 'mpeg':
910 case 'mpg':
911 case 'mpm':
912 case 'mpv':
913 $type = 'video/mpeg';
914 break;
915
916 case 'm4v':
917 $type = 'video/x-m4v';
918 break;
919
920 case 'mov':
921 case 'qt':
922 $type = 'video/quicktime';
923 break;
924
925 case 'mp4':
926 case 'mpg4':
927 $type = 'video/mp4';
928 break;
929
930 case 'sdv':
931 $type = 'video/sd-video';
932 break;
933
934 case 'wm':
935 $type = 'video/x-ms-wm';
936 break;
937
938 case 'wmv':
939 $type = 'video/x-ms-wmv';
940 break;
941
942 case 'wvx':
943 $type = 'video/x-ms-wvx';
944 break;
945
946 // Flash mime-types
947 case 'spl':
948 $type = 'application/futuresplash';
949 break;
950
951 case 'swf':
952 $type = 'application/x-shockwave-flash';
953 break;
954 }
955 }
956
957 if ($find_handler)
958 {
959 if (in_array($type, $types_flash))
960 {
961 return 'flash';
962 }
963 elseif (in_array($type, $types_fmedia))
964 {
965 return 'fmedia';
966 }
967 elseif (in_array($type, $types_quicktime))
968 {
969 return 'quicktime';
970 }
971 elseif (in_array($type, $types_wmedia))
972 {
973 return 'wmedia';
974 }
975 elseif (in_array($type, $types_mp3))
976 {
977 return 'mp3';
978 }
979 else
980 {
981 return null;
982 }
983 }
984 else
985 {
986 return $type;
987 }
988 }
989 }
990