PluginProbe
Super RSS Reader – Add attractive RSS Feed Widget / trunk
Super RSS Reader – Add attractive RSS Feed Widget vtrunk
trunk 0.8 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 3.0 3.1 3.2 4.0 4.0.1 4.1 4.2 4.3 4.4 4.4.1 4.5 4.6 4.7 4.8 All 33 releases
super-rss-reader / includes / feed.php

feed.php in Super RSS Reader – Add attractive RSS Feed Widget trunk, at includes/feed.php

435 lines 18.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Prepares the feed HTML
4 *
5 */
6
7 if( ! defined( 'ABSPATH' ) ) exit;
8
9 class SRR_Feed{
10
11 public $options = array();
12
13 public function __construct( $options ){
14
15 $this->options = wp_parse_args( $options, SRR_Options::defaults() );
16
17 }
18
19 public function html(){
20
21 $urls = trim( $this->options['urls'] );
22 $tab_titles = $this->options['tab_titles'];
23 $count = intval( $this->options['count'] );
24
25 $show_title = intval( $this->options['show_title'] );
26 $show_date = intval( $this->options['show_date'] );
27 $show_desc = intval( $this->options['show_desc'] );
28 $show_author = intval( $this->options['show_author'] );
29 $show_thumb = intval( $this->options['show_thumb'] );
30 $open_newtab = intval( $this->options['open_newtab'] );
31 $add_nofollow = intval( $this->options['add_nofollow'] );
32 $strip_desc = intval( $this->options['strip_desc'] );
33 $strip_title = intval( $this->options['strip_title'] );
34 $offset = intval( $this->options['offset'] );
35 $date_format = $this->options['date_format'];
36 $date_timezone = $this->options['date_timezone'];
37 $order_by = $this->options['order_by'];
38 $read_more = $this->options['read_more'];
39 $rich_desc = intval( $this->options['rich_desc'] );
40 $link_desc = intval( $this->options['link_desc'] );
41 $desc_type = $this->options['desc_type'];
42 $thumbnail_position = $this->options['thumbnail_position'];
43 $thumbnail_crop_position = $this->options['thumbnail_crop_position'];
44 $thumbnail_size = $this->options['thumbnail_size'];
45 $thumbnail_default = $this->options['thumbnail_default'];
46 $thumbnail_type = $this->options['thumbnail_type'];
47 $no_feed_text = $this->options['no_feed_text'];
48
49 $color_theme = $this->options['color_style'];
50 $display_type = $this->options['display_type'];
51 $visible_items = intval( $this->options['visible_items'] );
52 $ticker_speed = intval( $this->options['ticker_speed'] ) * 1000;
53 $scroll_height = $this->options['scroll_height'];
54
55 if( empty( $urls ) ){
56 return '';
57 }
58
59 $count = ( $offset > 0 ) ? $count + $offset : $count;
60
61 $url_delim = strpos( $urls, ',' ) !== false ? ',' : "\n";
62 $tab_title_delim = strpos( $tab_titles, ',' ) !== false ? ',' : "\n";
63
64 $urls = explode( $url_delim, $urls );
65 $tab_titles = explode( $tab_title_delim, $tab_titles );
66 $url_count = count( $urls );
67
68 $feeds = array();
69 $html = '';
70 $no_feed_html = '<div>' . wp_kses_post( $no_feed_text ) . '</div>';
71
72 $classes = array( 'srr-wrap', 'srr-style-' . $color_theme );
73 if( $display_type == 'vertical_ticker' ) array_push( $classes, 'srr-vticker' );
74 if( $display_type == 'scroll' ) array_push( $classes, 'srr-scroll' );
75 $class = implode( ' ', $classes );
76
77 $style = '';
78 if( $display_type == 'scroll' ){
79 $style .= '--srr-height: ' . $scroll_height;
80 }
81 if( !empty( $style ) ) $style = 'style="' . esc_attr( $style ) . '"';
82
83 // Fetch the feed
84 for( $i=0; $i < $url_count; $i++ ){
85 $feed_url = trim( $urls[$i] );
86
87 // Skip if the RSS feed URL is same as the site URL
88 if ( in_array( untrailingslashit( $feed_url ), array( site_url(), home_url() ), true ) ) {
89 continue;
90 }
91
92 $feed = fetch_feed( $feed_url );
93
94 if( is_wp_error( $feed ) ){
95 $feed_title = __( 'Error' );
96 }else{
97 $feed_title = ( isset( $tab_titles[$i] ) && !empty( $tab_titles[$i] ) ) ? $tab_titles[$i] : strip_tags( $feed->get_title() ?? '' );
98 }
99
100 $feeds[ $feed_url ] = array(
101 'id' => rand( 100, 999 ),
102 'feed' => $feed,
103 'title' => $feed_title
104 );
105 }
106
107 // Generate tabs
108 if( $url_count > 1 ){
109 $html .= '<ul class="srr-tab-wrap srr-tab-style-' . esc_attr( $color_theme ) . ' srr-clearfix">';
110 foreach( $feeds as $url => $data ){
111 $id = $data[ 'id' ];
112 $feed = $data[ 'feed' ];
113 $html .= '<li data-tab="srr-tab-' . esc_attr( $id ) . '">' . wp_kses_post( $data[ 'title' ] ) . '</li>';
114 }
115 $html .= '</ul>';
116 }
117
118 // Generate feed items
119 foreach( $feeds as $url => $data ){
120
121 $id = $data[ 'id' ];
122 $feed = $data[ 'feed' ];
123
124 // Check for feed errors
125 if ( is_wp_error( $feed ) ){
126 $html .= '<div class="srr-wrap srr-style-' . esc_attr( $color_theme ) .'" data-id="srr-tab-' . esc_attr( $id ) . '"><p>RSS Error: ' . wp_kses_post( $feed->get_error_message() ) . '</p></div>';
127 continue;
128 }
129
130 if( method_exists( $feed, 'enable_order_by_date' ) ){
131 if( in_array( $order_by, array( 'date', 'date_reverse' ) ) ){
132 $feed->enable_order_by_date( true );
133 }else{
134 $feed->enable_order_by_date( false );
135 }
136 }
137
138 // Outer wrap start
139 $html .= '<div class="' . esc_attr( $class ) . '" data-visible="' . esc_attr( $visible_items ) . '" data-speed="' . esc_attr( $ticker_speed ) . '" data-id="srr-tab-' . esc_attr( $id ) . '" ' . $style . '>';
140 $html .= '<div class="srr-inner">';
141
142 $max_items = $feed->get_item_quantity();
143
144 // Check feed items
145 if ( $max_items == 0 ){
146 $html .= $no_feed_html;
147 }else{
148
149 $feed_items = $feed->get_items();
150 $feed_items = $this->process_items( $feed_items, $count, $order_by );
151 $j=1;
152
153 // Loop through each feed item
154 foreach( $feed_items as $item ){
155
156 // Offset items
157 if( $j <= $offset ){
158 $j++;
159 continue;
160 }
161
162 // Link
163 $link = $item->get_link();
164 while ( stristr( $link, 'http' ) != $link ){ $link = substr( $link, 1 ); }
165 $link = strip_tags($link);
166
167 // Title
168 $title = strip_tags( $item->get_title() ?? '' );
169 $title_full = $title;
170
171 if ( empty( $title ) ){
172 $title = __( 'No Title', 'super-rss-reader' );
173 }
174
175 if( $strip_title > 0 && strlen( $title ) > $strip_title ){
176 $title = wp_trim_words( $title, $strip_title );
177 }
178
179 // Open links in new tab
180 $new_tab = $open_newtab ? ' target="_blank"' : '';
181
182 // Add no follow attribute
183 $no_follow = $add_nofollow ? ' rel="nofollow noopener noreferrer"' : '';
184
185 if( empty( $link ) ){
186 $link = '#';
187 $new_tab = '';
188 }
189
190 // Date
191 $date = '';
192 $date_full = strip_tags( $item->get_date() ?? '' );
193
194 if( strtolower( $date_format ) == 'relative' ){
195 $item_date = $item->get_date( 'U' );
196 if( $item_date ){
197 $date = human_time_diff( $item_date, current_time( 'U' ) ) . ' ' . __( 'ago', 'super-rss-reader' );
198 }else{
199 $date = __( 'Today', 'super-rss-reader' );
200 }
201 }else{
202 $date = SRR_Utilities::date_i18n( $date_format, $item->get_date( 'U' ), $date_timezone );
203 }
204
205 // Thumbnail
206 $thumb = '';
207 if ( $show_thumb == 1 ){
208 $thumb_url = $this->get_thumbnail_url( $item, $thumbnail_default, $thumbnail_type );
209 $thumb_url = apply_filters( 'srr_mod_thumbnail_url', $thumb_url, $item, $feed, $thumbnail_default, $thumbnail_type );
210 if( !empty( $thumb_url ) ){
211 if( strpos( $thumbnail_size, ',' ) ){
212 $thumb_size_split = explode( ',', $thumbnail_size );
213 $thumb_width = $thumb_size_split[0];
214 $thumb_height = $thumb_size_split[1];
215 }else{
216 $thumb_width = $thumb_height = $thumbnail_size;
217 }
218 $crop_positions = array(
219 'center' => 'center center',
220 'top' => 'center top',
221 'bottom' => 'center bottom',
222 'left' => 'left center',
223 'right' => 'right center',
224 'top_left' => 'left top',
225 'top_right' => 'right top',
226 'bottom_left' => 'left bottom',
227 'bottom_right' => 'right bottom',
228 );
229 $thumb_crop_position = array_key_exists( $thumbnail_crop_position, $crop_positions ) ? $thumbnail_crop_position : 'center';
230 $thumb_styles = array(
231 'width' => $thumb_width,
232 'height' => $thumb_height,
233 '--srr-thumb-position' => $crop_positions[ $thumb_crop_position ]
234 );
235 $thumb_style = '';
236 foreach( $thumb_styles as $prop => $val ){
237 $thumb_style .= "$prop:$val;";
238 }
239 $thumb = '<a href="' . esc_url( $link ) . '" class="srr-thumb srr-thumb-' . esc_attr( $thumbnail_position ) . '" style="' . esc_attr( $thumb_style ) . '" ' . $new_tab . $no_follow . '><img src="' . esc_url( $thumb_url ) . '" alt="' . esc_attr( $title_full ) . '" align="left"' . ( wp_lazy_loading_enabled( 'img', 'srr-thumbnail' ) ? ' loading="lazy"' : '' ) . ' /></a>';
240 }
241 }
242
243 // Description
244 $desc = '';
245 if( $show_desc ){
246 $desc_content = ( $desc_type == 'summary' ) ? ( $item->get_description() ?? '') : ( $item->get_content() ?? '' );
247 if( $rich_desc ){
248 $desc = wp_kses_post( strip_tags( $desc_content, '<p><a><img><em><strong><font><strike><s><u><b><i><br>' ) );
249 }else{
250 $desc = str_replace( array( "\n", "\r" ), ' ', strip_tags( @html_entity_decode( $desc_content, ENT_QUOTES, get_option('blog_charset') ) ) );
251
252 if( $strip_desc != 0 ){
253 $desc = wp_trim_words( $desc, $strip_desc );
254 if ( '[...]' == substr( $desc, -5 ) ){
255 $desc = substr( $desc, 0, -5 );
256 }else if ( '&hellip;' == substr( $desc, -8 ) ){
257 $desc = substr( $desc, 0, -8 );
258 }else if ( '...' == substr( $desc, -3 ) ){
259 $desc = substr( $desc, 0, -3 );
260 }elseif ( '[&hellip;]' != substr( $desc, -10 ) ){
261 $desc .= '';
262 }
263 }
264
265 $desc = trim( esc_html( $desc ) );
266 if( !empty( $desc ) ){
267 if( $link_desc ){
268 $desc = '<a href="' . esc_url( $link ) . '"' . $new_tab . $no_follow . ' class="srr-desc-link">' . $desc . '</a>';
269 }
270 $read_more_link = !empty( $read_more ) ? ' <a href="' . esc_url( $link ) . '" title="' . esc_attr__( 'Read more', 'super-rss-reader' ) . '"' . $new_tab . $no_follow . ' class="srr-read-more">' . esc_html( $read_more ) . '</a>' : '';
271 $desc = $desc . $read_more_link;
272 }
273
274 }
275 }
276
277 // Author
278 $author = '';
279 if( $show_author ){
280 $author = $item->get_author();
281 if ( is_object( $author ) && $author->get_name() ) {
282 $author = strip_tags( $author->get_name() );
283 }
284 }
285
286 $t_title = '';
287 $t_meta = '';
288 $t_thumb = '';
289 $t_desc = '';
290
291 if( $show_title ){
292 $t_title .= '<div class="srr-title"><a href="' . esc_url( $link ) . '"' . $new_tab . $no_follow . ' title="' . esc_attr( $title_full ) . '">' . esc_html( $title ) . '</a></div>';
293 }
294
295 // Metadata
296 if( $show_date || $show_author ){
297 $t_meta .= '<div class="srr-meta">';
298 if( $show_date && !empty( $date ) ){
299 $t_meta .= '<time class="srr-date" title="' . esc_attr( $date_full ) . ' UTC">' . esc_html( $date ) . '</time>';
300 }
301
302 if( $show_author && !empty( $author ) ){
303 $t_meta .= ' - <cite class="srr-author">' . esc_html( $author ) . '</cite>';
304 }
305 $t_meta .= '</div>'; // End meta
306 }
307
308 if ( $show_thumb ){
309 $t_thumb .= $thumb;
310 }
311
312 if( $show_desc && !empty( $desc ) ){
313 $t_desc .= '<div class="srr-summary srr-clearfix">';
314 $t_desc .= $rich_desc ? $desc : ( '<p>' . $desc . '</p>' );
315 $t_desc .= '</div>'; // End summary
316 }
317
318 $f_data = apply_filters( 'srr_mod_item_html', array(
319 'title' => $t_title,
320 'meta' => $t_meta,
321 'thumbnail' => $t_thumb,
322 'description' => $t_desc,
323 'before' => '',
324 'after' => ''
325 ), $url, $item );
326
327 $f_title = !isset( $f_data[ 'title' ] ) ? '' : $f_data[ 'title' ];
328 $f_meta = !isset( $f_data[ 'meta' ] ) ? '' : $f_data[ 'meta' ];
329 $f_thumb = !isset( $f_data[ 'thumbnail' ] ) ? '' : $f_data[ 'thumbnail' ];
330 $f_desc = !isset( $f_data[ 'description' ] ) ? '' : $f_data[ 'description' ];
331 $f_before = !isset( $f_data[ 'before' ] ) ? '' : $f_data[ 'before' ];
332 $f_after = !isset( $f_data[ 'after' ] ) ? '' : $f_data[ 'after' ];
333
334 // Display the feed items
335 $html .= '<div class="srr-item ' . ( ( $j%2 == 0 ) ? 'srr-stripe' : '') . '">';
336 $html .= '<div class="srr-item-in srr-clearfix">';
337 $html .= $f_before;
338 $html .= $f_title . $f_meta . $f_thumb . $f_desc;
339 $html .= $f_after;
340 $html .= '</div>'; // End item inner clearfix
341 $html .= '</div>'; // End feed item
342
343 $j++;
344 }
345
346 if( $j == 1 ){
347 $html .= $no_feed_html;
348 }
349
350 }
351
352 // Outer wrap end
353 $html .= '</div></div>' ;
354
355 if( !is_wp_error( $feed ) )
356 $feed->__destruct();
357
358 unset( $feed );
359
360 }
361
362 $html = '<div class="srr-main">' . $html . '</div>';
363
364 return $html;
365
366 }
367
368 function process_items( $items, $count, $order_by ){
369
370 if( count( $items ) == 0 ){
371 return $items;
372 }
373
374 // For shuffle order - Shuffle first and then slice as per count
375 if( $order_by == 'random' ){
376 shuffle( $items );
377 return array_slice( $items, 0, $count );
378 }
379
380 if( $order_by == 'date_reverse' ){
381 $items = array_reverse( $items );
382 }
383
384 // For date based order - slice first and then order
385 $items = array_slice( $items, 0, $count );
386
387 return $items;
388
389 }
390
391 function get_thumbnail_url( $item, $thumbnail_default, $thumbnail_type ){
392
393 if ( !is_object( $item ) ) {
394 return trim( $thumbnail_default );
395 }
396
397 // Try to get from the item enclosure
398 $enclosure = $item->get_enclosure();
399 $enclosure_image = '';
400
401 if ( is_object( $enclosure ) ) {
402 if ( $enclosure->get_thumbnail() && $enclosure->get_link() ){
403 $enclosure_image = ( $thumbnail_type == 'thumbnail' ) ? $enclosure->get_thumbnail() : $enclosure->get_link();
404 } elseif ( $enclosure->get_thumbnail() ) {
405 $enclosure_image = $enclosure->get_thumbnail();
406 } elseif ( $enclosure->get_link() ) {
407 $enclosure_image = $enclosure->get_link();
408 }
409
410 if( $enclosure_image && SRR_Utilities::is_valid_image_url( $item, $enclosure_image ) ){
411 return trim( $enclosure_image );
412 }
413 }
414
415 // Try to get from item content
416 $content = $item->get_content();
417 $image = SRR_Utilities::parse_image_url( $item, $content );
418
419 if( !empty( $image ) ){
420 return trim( $image );
421 }
422
423 // Try to get the image tag finally if available
424 $image = $item->get_item_tags( '', 'image' );
425
426 if( isset( $image[0]['data'] ) ){
427 return trim( $image[0]['data'] );
428 }
429
430 return trim( $thumbnail_default );
431 }
432
433 }
434
435 ?>