PluginProbe
Super RSS Reader – Add attractive RSS Feed Widget / 5.4
Super RSS Reader – Add attractive RSS Feed Widget v5.4
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 5.4, at includes/feed.php

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