PluginProbe
Friends / 2.8.9
Friends v2.8.9
4.3.2 4.3.1 4.3.0 4.2.2 4.2.1 4.2.0 4.1.0 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.0 2.9.1 All 88 releases
friends / feed-parsers / class-feed-parser-simplepie.php

class-feed-parser-simplepie.php in Friends 2.8.9, at feed-parsers/class-feed-parser-simplepie.php

309 lines 8.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Friends SimplePie Parser Wrapper
4 *
5 * With this parser, we can import RSS and Atom Feeds for a friend.
6 *
7 * @package Friends
8 */
9
10 namespace Friends;
11
12 /**
13 * This is the class for the feed part of the Friends Plugin.
14 *
15 * @since 1.0
16 *
17 * @package Friends
18 * @author Alex Kirk
19 */
20 class Feed_Parser_SimplePie extends Feed_Parser_V2 {
21 const NAME = 'SimplePie';
22 const URL = 'http://simplepie.org';
23 const SLUG = 'simplepie';
24 /**
25 * Determines if this is a supported feed and to what degree we feel it's supported.
26 *
27 * @param string $url The url.
28 * @param string $mime_type The mime type.
29 * @param string $title The title.
30 * @param string|null $content The content, it can't be assumed that it's always available.
31 *
32 * @return int Return 0 if unsupported, a positive value representing the confidence for the feed, use 10 if you're reasonably confident.
33 */
34 public function feed_support_confidence( $url, $mime_type, $title, $content = null ) {
35 $rewritten = $this->rewrite_known_url( $url );
36 if ( $rewritten ) {
37 $mime_type = $rewritten['type'];
38 }
39
40 switch ( $mime_type ) {
41 case 'application/rss+xml':
42 case 'application/atom+xml':
43 return 10;
44 }
45
46 switch ( $mime_type ) {
47 case 'application/xml':
48 return 5;
49 }
50
51 return 0;
52 }
53
54 /**
55 * Rewrite known URLs to their RSS feeds.
56 *
57 * @param string $url The url.
58 *
59 * @return array An equivalent link array.
60 */
61 public function rewrite_known_url( $url ) {
62 $host = parse_url( strtolower( $url ), PHP_URL_HOST );
63
64 switch ( $host ) {
65 case 'www.youtube.com':
66 case 'youtube.com':
67 if ( preg_match( '#/channel/([^?&$]+)#i', $url, $m ) ) {
68 return array(
69 'title' => 'Youtube',
70 'rel' => 'alternate',
71 'type' => 'application/rss+xml',
72 'url' => 'https://www.youtube.com/feeds/videos.xml?channel_id=' . $m[1],
73 'post-format' => 'video',
74 );
75 }
76 if ( preg_match( '#/user/([^?&$]+)#i', $url, $m ) ) {
77 return array(
78 'title' => 'Youtube',
79 'rel' => 'alternate',
80 'type' => 'application/rss+xml',
81 'url' => 'https://www.youtube.com/feeds/videos.xml?user=' . $m[1],
82 'post-format' => 'video',
83 );
84 }
85 return array();
86 case 'github.com':
87 return array(
88 'rel' => 'alternate',
89 'type' => 'application/atom+xml',
90 'url' => $url,
91 'post-format' => 'aside',
92 );
93 }
94
95 return array();
96 }
97
98 /**
99 * Format the feed title and autoselect the posts feed.
100 *
101 * @param array $feed_details The feed details.
102 *
103 * @return array The (potentially) modified feed details.
104 */
105 public function update_feed_details( $feed_details ) {
106 $rewritten = $this->rewrite_known_url( $feed_details['url'] );
107 if ( $rewritten ) {
108 $feed_details = $rewritten;
109 }
110
111 foreach ( get_post_format_strings() as $format => $title ) {
112 if ( preg_match( '/\b' . preg_quote( $format, '/' ) . '\b/i', $feed_details['url'] ) ) {
113 $feed_details['post-format'] = $format;
114 break;
115 }
116 }
117
118 return $feed_details;
119 }
120
121 /**
122 * Instanciate SimplePie the same way WordPress does it.
123 *
124 * @return SimplePie A simplepie instance.
125 */
126 private function get_simplepie() {
127 if ( ! class_exists( 'SimplePie', false ) ) {
128 require_once ABSPATH . WPINC . '/class-simplepie.php';
129 }
130
131 require_once ABSPATH . WPINC . '/class-wp-feed-cache-transient.php';
132 require_once ABSPATH . WPINC . '/class-wp-simplepie-file.php';
133 require_once __DIR__ . '/SimplePie/class-simplepie-file-accept-only-rss.php';
134 require_once __DIR__ . '/SimplePie/class-simplepie-misc.php';
135 require_once ABSPATH . WPINC . '/class-wp-simplepie-sanitize-kses.php';
136
137 $feed = new \SimplePie();
138
139 $feed->set_sanitize_class( '\WP_SimplePie_Sanitize_KSES' );
140 // We must manually overwrite $feed->sanitize because SimplePie's
141 // constructor sets it before we have a chance to set the sanitization class.
142 $feed->sanitize = new \WP_SimplePie_Sanitize_KSES();
143
144 \SimplePie_Cache::register( 'wp_transient', '\WP_Feed_Cache_Transient' );
145 $feed->set_cache_location( 'wp_transient' );
146
147 $registry = $feed->get_registry();
148 $registry->register( 'Misc', __NAMESPACE__ . '\SimplePie_Misc' );
149
150 return $feed;
151 }
152
153 /**
154 * Discover the feeds available at the URL specified.
155 *
156 * @param string $content The content for the URL is already provided here.
157 * @param string $url The url to search.
158 *
159 * @return array A list of supported feeds at the URL.
160 */
161 public function discover_available_feeds( $content, $url ) {
162 $feed = $this->get_simplepie();
163 do_action_ref_array( 'wp_feed_options', array( &$feed, $url ) );
164
165 $feed->set_raw_data( $content );
166
167 $feed->set_output_encoding( get_option( 'blog_charset' ) );
168
169 $feed->init();
170
171 if ( $feed->error() ) {
172 return array();
173 }
174
175 $discovered_feeds = array();
176
177 $items = $feed->get_items();
178 if ( count( $items ) ) {
179 // This is a feed.
180 $mime_type = false;
181 if ( $feed->get_type() & SIMPLEPIE_TYPE_RSS_ALL ) {
182 $mime_type = 'application/rss+xml';
183 } elseif ( $feed->get_type() & SIMPLEPIE_TYPE_ATOM_ALL ) {
184 $mime_type = 'application/atom+xml';
185 }
186
187 if ( $mime_type ) {
188 $feed_url = $feed->subscribe_url();
189 if ( ! $feed_url ) {
190 $feed_url = $url;
191 }
192
193 $discovered_feeds[ $feed_url ] = array(
194 'type' => $mime_type,
195 'title' => $feed->get_title(),
196 'parser' => 'simplepie',
197 'rel' => 'self',
198 'autoselect' => true,
199 );
200 }
201 }
202
203 return $discovered_feeds;
204 }
205
206 /**
207 * Fetches a feed and returns the processed items.
208 *
209 * @param string $url The url.
210 * @param User_Feed $user_feed The user feed.
211 *
212 * @return array An array of feed items.
213 */
214 public function fetch_feed( $url, User_Feed $user_feed = null ) {
215 // Use SimplePie which is bundled with WordPress.
216 $feed = $this->get_simplepie();
217
218 $host = parse_url( strtolower( $url ), PHP_URL_HOST );
219
220 switch ( $host ) {
221 case 'github.com':
222 $feed->set_file_class( __NAMESPACE__ . '\SimplePie_File_Accept_Only_RSS' );
223 break;
224 }
225
226 $feed->set_feed_url( $url );
227 $feed->set_cache_duration( apply_filters( 'wp_feed_cache_transient_lifetime', HOUR_IN_SECONDS - 600, $url ) );
228
229 do_action_ref_array( 'wp_feed_options', array( &$feed, $url ) );
230
231 $feed->init();
232
233 $feed->set_output_encoding( get_option( 'blog_charset' ) );
234
235 if ( $feed->error() ) {
236 return new \WP_Error( 'simplepie-error', $feed->error() );
237 }
238
239 return $this->process_items( $feed->get_items(), $url );
240 }
241
242 /**
243 * Process the feed items.
244 *
245 * @param array $items The items.
246 * @param string $url The url.
247 *
248 * @return array The processed feed items.
249 */
250 public function process_items( $items, $url ) {
251 $feed_items = array();
252 foreach ( $items as $item ) {
253 $feed_item = new Feed_Item(
254 array(
255 'permalink' => $item->get_permalink(),
256 'title' => $item->get_title(),
257 'content' => $this->convert_relative_urls_to_absolute_urls( $item->get_content(), $url ),
258 )
259 );
260
261 foreach ( array(
262 'gravatar' => 'gravatar',
263 'comment_count' => 'comments',
264 'status' => 'post-status',
265 'format' => 'post-format',
266 'id' => 'post-id',
267 ) as $key => $lookup_key ) {
268 foreach ( array( Feed::XMLNS, 'com-wordpress:feed-additions:1' ) as $xmlns ) {
269 if ( ! isset( $item->data['child'][ $xmlns ][ $lookup_key ][0]['data'] ) ) {
270 continue;
271 }
272
273 $feed_item->{$key} = $item->data['child'][ $xmlns ][ $lookup_key ][0]['data'];
274 break;
275 }
276 }
277
278 foreach ( array(
279 'http://purl.org/rss/1.0/modules/slash/' => array(
280 'comment_count' => 'comments',
281 ),
282 'http://wellformedweb.org/CommentAPI/' => array(
283 'comments_feed' => 'commentRss',
284 ),
285 ) as $xmlns => $keys ) {
286 foreach ( $keys as $key => $lookup_key ) {
287 if ( ! isset( $item->data['child'][ $xmlns ][ $lookup_key ][0]['data'] ) ) {
288 continue;
289 }
290
291 $feed_item->{$key} = $item->data['child'][ $xmlns ][ $lookup_key ][0]['data'];
292 break;
293 }
294 }
295
296 if ( is_object( $item->get_author() ) ) {
297 $feed_item->author = $item->get_author()->name;
298 }
299
300 $feed_item->date = $item->get_gmdate( 'U' );
301 $feed_item->updated_date = $item->get_updated_gmdate( 'U' );
302
303 $feed_items[] = $feed_item;
304 }
305
306 return $feed_items;
307 }
308 }
309