PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.1-a.5
Jetpack – WP Security, Backup, Speed, & Growth v16.1-a.5
16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / _inc / lib / class-jetpack-podcast-feed-locator.php
jetpack / _inc / lib Last commit date
admin-pages 3 weeks ago core-api 2 weeks ago debugger 3 weeks ago markdown 8 months ago class-jetpack-ai-helper.php 3 weeks ago class-jetpack-application-password-extras.php 4 months ago class-jetpack-blog-stats-helper.php 8 months ago class-jetpack-currencies.php 2 years ago class-jetpack-instagram-gallery-helper.php 2 months ago class-jetpack-mapbox-helper.php 3 years ago class-jetpack-newsletter-category-helper.php 8 months ago class-jetpack-podcast-feed-locator.php 2 months ago class-jetpack-podcast-helper.php 6 months ago class-jetpack-recommendations.php 2 months ago class-jetpack-spinner.php 3 months ago class-jetpack-top-posts-helper.php 1 month ago class.color.php 1 year ago class.core-rest-api-endpoints.php 2 weeks ago class.jetpack-automatic-install-skin.php 2 years ago class.jetpack-iframe-embed.php 3 years ago class.jetpack-password-checker.php 8 months ago class.jetpack-search-performance-logger.php 4 years ago class.media-extractor.php 2 months ago class.media-summary.php 1 month ago class.media.php 8 months ago components.php 3 weeks ago debugger.php 2 months ago icalendar-reader.php 2 months ago markdown.php 8 months ago plans.php 4 years ago plugins.php 4 years ago tonesque.php 8 months ago widgets.php 4 months ago
class-jetpack-podcast-feed-locator.php
125 lines
1 <?php
2 /**
3 * Extension of the SimplePie\Locator class, to detect podcast feeds
4 *
5 * @package automattic/jetpack
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit( 0 );
10 }
11
12 /**
13 * Class Jetpack_Podcast_Feed_Locator
14 */
15 class Jetpack_Podcast_Feed_Locator extends SimplePie\Locator {
16
17 /**
18 * Overrides the locator is_feed function to check for
19 * appropriate podcast elements.
20 *
21 * @param SimplePie\HTTP\Response $file The file being checked.
22 * @param boolean $check_html Adds text/html to the mimetypes checked.
23 */
24 public function is_feed( $file, $check_html = false ) {
25 return parent::is_feed( $file, $check_html ) &&
26 $file instanceof SimplePie\File &&
27 $this->is_podcast_feed( $file );
28 }
29
30 /**
31 * Checks the contents of the file for elements that make
32 * it a podcast feed.
33 *
34 * @param SimplePie\File $file The file being checked.
35 */
36 private function is_podcast_feed( $file ) {
37 // If we can't read the DOM assume it's a podcast feed, we'll work
38 // it out later.
39 if ( ! class_exists( 'DOMDocument' ) ) {
40 return true;
41 }
42
43 // @todo Drop is_callable check once Simple gets the SimplePie update that came with WordPress 6.9.
44 if ( is_callable( array( $file, 'get_body_content' ) ) ) {
45 $feed_dom = $this->safely_load_xml( $file->get_body_content() );
46 } else {
47 // @phan-suppress-next-line PhanDeprecatedProperty -- For compatibility only.
48 $feed_dom = $this->safely_load_xml( (string) $file->body );
49 }
50
51 // Do this as either/or but prioritise the itunes namespace. It's pretty likely
52 // that it's a podcast feed we've found if that namespace is present.
53 return $feed_dom && $this->has_itunes_ns( $feed_dom ) && $this->has_audio_enclosures( $feed_dom );
54 }
55
56 /**
57 * Safely loads an XML file
58 *
59 * @param string $xml A string of XML to load.
60 * @return DOMDocument|false A resulting DOM document or `false` if there is an error.
61 */
62 private function safely_load_xml( $xml ) {
63 if ( empty( $xml ) ) {
64 return false;
65 }
66
67 $disable_entity_loader = PHP_VERSION_ID < 80000;
68
69 if ( $disable_entity_loader ) {
70 // This function has been deprecated in PHP 8.0 because in libxml 2.9.0, external entity loading
71 // is disabled by default, so this function is no longer needed to protect against XXE attacks.
72 // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated, PHPCompatibility.FunctionUse.RemovedFunctions.libxml_disable_entity_loaderDeprecated
73 $loader = libxml_disable_entity_loader( true );
74 }
75
76 $errors = libxml_use_internal_errors( true );
77
78 $return = new DOMDocument();
79 if ( ! $return->loadXML( $xml ) ) {
80 return false;
81 }
82
83 libxml_use_internal_errors( $errors );
84
85 if ( $disable_entity_loader && isset( $loader ) ) {
86 // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated, PHPCompatibility.FunctionUse.RemovedFunctions.libxml_disable_entity_loaderDeprecated
87 libxml_disable_entity_loader( $loader );
88 }
89
90 return $return;
91 }
92
93 /**
94 * Checks the RSS feed for the presence of the itunes podcast namespace.
95 * It's pretty loose and just checks the URI for itunes.com
96 *
97 * @param DOMDocument $dom The XML document to check.
98 * @return boolean Whether the itunes namespace is defined.
99 */
100 private function has_itunes_ns( $dom ) {
101 $xpath = new DOMXPath( $dom );
102 foreach ( $xpath->query( 'namespace::*' ) as $node ) {
103 // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
104 // nodeValue is not valid, but it's part of the DOM API that we don't control.
105 if ( strstr( $node->nodeValue, 'itunes.com' ) ) {
106 return true;
107 }
108 // phpcs:enable
109 }
110 return false;
111 }
112
113 /**
114 * Checks the RSS feed for the presence of enclosures with an audio mimetype.
115 *
116 * @param DOMDocument $dom The XML document to check.
117 * @return boolean Whether enclosures were found.
118 */
119 private function has_audio_enclosures( $dom ) {
120 $xpath = new DOMXPath( $dom );
121 $enclosures = $xpath->query( "//enclosure[starts-with(@type,'audio/')]" );
122 return ! $enclosures ? false : $enclosures->length > 0;
123 }
124 }
125