WP RSS Aggregator - Version 4.21

Version Description

(2022-07-13) = Changed - Updated Twig to v1.42.2, to support PHP 8 or later. - Optimized feed item date processing when an item is being imported. - Permalink and GUID checks are now done across all feed sources when an item is being imported.

Fixed - Various PHP 8 errors and deprecations compatibility. - The classic editor button was generating incorrect shortcodes.

Download this release

Release Info

Developer Mekku
Plugin Icon 128x128 WP RSS Aggregator
Version 4.21
Comparing to
See all releases

Code changes from version 4.20 to 4.21

Files changed (41) hide show
  1. CHANGELOG.md +10 -0
  2. includes/admin-editor.php +6 -4
  3. includes/admin-options.php +1 -1
  4. includes/feed-importing-new.php +1 -1
  5. includes/feed-importing.php +44 -45
  6. includes/feed-processing.php +6 -39
  7. js/editor.js +1 -1
  8. readme.txt +13 -2
  9. src/Data/ArrayDataSet.php +5 -17
  10. src/Entities/Collections/FeedItemCollection.php +4 -3
  11. src/Entities/Collections/WpEntityCollection.php +0 -30
  12. src/ErrorHandler.php +0 -8
  13. src/Templates/Feeds/LegacyDisplayTemplate.php +2 -13
  14. src/Templates/Feeds/MasterFeedsTemplate.php +4 -21
  15. src/Templates/Feeds/TemplateTypeTemplate.php +2 -13
  16. src/Templates/Feeds/Types/AbstractFeedTemplateType.php +4 -20
  17. src/Templates/TwigTemplate.php +0 -8
  18. src/Util/Normalize.php +34 -0
  19. src/Util/ParseArgsWithSchemaCapableTrait.php +1 -1
  20. vendor/composer/autoload_classmap.php +19 -0
  21. vendor/composer/autoload_static.php +19 -0
  22. vendor/composer/installed.json +12 -8
  23. vendor/composer/installed.php +5 -5
  24. vendor/twig/twig/composer.json +2 -2
  25. vendor/twig/twig/src/Environment.php +4 -4
  26. vendor/twig/twig/src/ExpressionParser.php +7 -1
  27. vendor/twig/twig/src/Extension/CoreExtension.php +5 -5
  28. vendor/twig/twig/src/Extension/DebugExtension.php +1 -1
  29. vendor/twig/twig/src/Loader/FilesystemLoader.php +0 -1
  30. vendor/twig/twig/src/Node/MacroNode.php +7 -1
  31. vendor/twig/twig/src/Node/SetNode.php +5 -1
  32. vendor/twig/twig/src/Node/SpacelessNode.php +7 -1
  33. vendor/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php +1 -1
  34. vendor/twig/twig/src/Parser.php +12 -4
  35. vendor/twig/twig/src/Template.php +15 -3
  36. vendor/twig/twig/src/TemplateWrapper.php +5 -1
  37. vendor/twig/twig/src/TokenParser/ExtendsTokenParser.php +4 -2
  38. vendor/twig/twig/src/TokenParser/FromTokenParser.php +4 -3
  39. vendor/twig/twig/src/TokenParser/ImportTokenParser.php +1 -1
  40. vendor/twig/twig/src/TokenStream.php +3 -2
  41. wp-rss-aggregator.php +2 -2
CHANGELOG.md CHANGED
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
  and this project adheres to [Semantic Versioning](http://semver.org/).
6
 
 
 
 
 
 
 
 
 
 
 
7
  ## [4.20] - 2022-01-18
8
  ### Added
9
  * New option to use feed item GUIDs instead of permalinks to detect duplicate items.
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
  and this project adheres to [Semantic Versioning](http://semver.org/).
6
 
7
+ ## [4.21] - 2022-07-13
8
+ ### Change
9
+ * Updated Twig to v1.42.2, to support PHP 8 or later.
10
+ * Optimized feed item date processing when an item is being imported.
11
+ * Permalink and GUID checks are now done across all feed sources when an item is being imported.
12
+
13
+ ### Fixed
14
+ * Various PHP 8 errors and deprecations compatibility.
15
+ * The classic editor button was generating incorrect shortcodes.
16
+
17
  ## [4.20] - 2022-01-18
18
  ### Added
19
  * New option to use feed item GUIDs instead of permalinks to detect duplicate items.
includes/admin-editor.php CHANGED
@@ -82,21 +82,23 @@ function wprss_return_dialog_contents()
82
  'posts_per_page' => -1,
83
  'no_found_rows' => true,
84
  ]);
85
- $feed_sources_names = [];
 
86
  foreach ($feed_sources as $source) {
87
- $feed_sources_names[$source->ID] = $source->post_title;
 
88
  }
89
  $feed_sources_select = wprss_settings_render_select(
90
  'wprss-dialog-feed-source-list',
91
  '',
92
- $feed_sources_names,
93
  '',
94
  ['multiple' => 'multiple', 'class' => 'widefat']
95
  );
96
  $feed_sources_exclude_select = wprss_settings_render_select(
97
  'wprss-dialog-exclude-list',
98
  '',
99
- $feed_sources_names,
100
  '',
101
  ['multiple' => 'multiple', 'class' => 'widefat']
102
  );
82
  'posts_per_page' => -1,
83
  'no_found_rows' => true,
84
  ]);
85
+ $feed_sources_by_id = [];
86
+ $feed_sources_by_slug = [];
87
  foreach ($feed_sources as $source) {
88
+ $feed_sources_by_id[$source->ID] = $source->post_title;
89
+ $feed_sources_by_slug[$source->post_name] = $source->post_title;
90
  }
91
  $feed_sources_select = wprss_settings_render_select(
92
  'wprss-dialog-feed-source-list',
93
  '',
94
+ $feed_sources_by_slug,
95
  '',
96
  ['multiple' => 'multiple', 'class' => 'widefat']
97
  );
98
  $feed_sources_exclude_select = wprss_settings_render_select(
99
  'wprss-dialog-exclude-list',
100
  '',
101
+ $feed_sources_by_id,
102
  '',
103
  ['multiple' => 'multiple', 'class' => 'widefat']
104
  );
includes/admin-options.php CHANGED
@@ -785,7 +785,7 @@ function wprss_settings_render_select($id, $name, $items, $selected = null, $att
785
  $_item = (string) $_item;
786
 
787
  $html .= sprintf(
788
- '<option name="%s" %s>%s</option>',
789
  esc_attr($_key),
790
  selected($selected, $_key, false),
791
  esc_html($_item)
785
  $_item = (string) $_item;
786
 
787
  $html .= sprintf(
788
+ '<option value="%s" %s>%s</option>',
789
  esc_attr($_key),
790
  selected($selected, $_key, false),
791
  esc_html($_item)
includes/feed-importing-new.php CHANGED
@@ -77,7 +77,7 @@ function fetchNewItems($feedId)
77
 
78
  // Gather the titles and permalinks of the items that are being fetched
79
  $existingTitles = [];
80
- $existingPermalinks = wprss_get_existing_permalinks($feedId);
81
 
82
  $newItems = [];
83
  foreach ($items as $item) {
77
 
78
  // Gather the titles and permalinks of the items that are being fetched
79
  $existingTitles = [];
80
+ $existingPermalinks = wprss_get_existing_permalinks();
81
 
82
  $newItems = [];
83
  foreach ($items as $item) {
includes/feed-importing.php CHANGED
@@ -112,8 +112,8 @@ function wprss_fetch_insert_single_feed_items( $feed_ID ) {
112
  $useGuids = get_post_meta($feed_ID, 'wprss_use_guids', true);
113
  $useGuids = filter_var($useGuids, FILTER_VALIDATE_BOOLEAN);
114
  $existingIds = $useGuids
115
- ? wprss_get_existing_guids($feed_ID)
116
- : wprss_get_existing_permalinks($feed_ID);
117
 
118
  // Generate a list of items fetched, that are not already in the DB
119
  $new_items = array();
@@ -527,8 +527,8 @@ function wprss_tracking_url_fix( $permalink, $patterns, $argName = 'url' ) {
527
  * into embedded video player urls.
528
  * If the permalink is not a video url, the permalink is returned as is.
529
  *
530
- * @param $permalink The string permalink url to convert.
531
- * @return A string, with the convert permalink, or the same permalink passed as parameter if
532
  * not a video url.
533
  * @since 4.0
534
  */
@@ -550,8 +550,8 @@ function wprss_convert_video_permalink( $permalink ) {
550
  $host = $matches[2];
551
  switch( $host ) {
552
  case 'youtube':
553
- preg_match( '/(&|\?)v=([^&]+)/', $permalink, $yt_matches );
554
- $permalink = 'https://www.youtube.com/embed/' . $yt_matches[2];
555
  break;
556
  case 'vimeo':
557
  preg_match( '/(\d*)$/i', $permalink, $vim_matches );
@@ -584,6 +584,16 @@ function wprss_items_insert_post( $items, $feed_ID ) {
584
  // Count of items inserted
585
  $items_inserted = 0;
586
 
 
 
 
 
 
 
 
 
 
 
587
  foreach ( $items as $i => $item ) {
588
  $permalink = $item->get_permalink();
589
  $permalink = wprss_normalize_permalink($permalink, $item, $feed_ID);
@@ -624,51 +634,43 @@ function wprss_items_insert_post( $items, $feed_ID ) {
624
  $item = apply_filters( 'wprss_insert_post_item_conditionals', $item, $feed_ID, $permalink );
625
  /* @var $item SimplePie_Item */
626
 
627
- // Check if the imported count should still be updated, even if the item is NULL
628
- $still_update_count = apply_filters( 'wprss_still_update_import_count', FALSE );
629
-
630
  // If the item is not NULL, continue to inserting the feed item post into the DB
631
  if ( $item !== NULL && !is_bool($item) ) {
632
  $logger->debug('Resuming insertion into DB');
633
 
634
  $post_status = 'publish';
635
 
636
- // Get the date and GMT date and normalize if not valid or not given by the feed
637
- $format = 'Y-m-d H:i:s';
638
  $timestamp = $item->get_date( 'U' );
639
- $has_date = $timestamp ? true : false;
640
 
641
  if ($has_date) {
642
- $logger->debug('Feed item "{0}" date: {1}', [$item->get_title(), $item->get_date($format)]);
643
 
644
  if ($timestamp > time()) {
645
  // Item has a future timestamp ...
646
  $logger->debug('Item "{0}" has a future date', [$item->get_title()]);
647
 
648
- $schedule_items_filter = apply_filters('wpra/importer/allow_scheduled_items', false);
649
- $schedule_items_option = wprss_get_general_setting('schedule_future_items');
650
-
651
- if ($schedule_items_filter || $schedule_items_option) {
652
- // If can schedule future items, set the post status to "future" (aka scheduled)
653
- $post_status = 'future';
654
-
655
  $logger->debug('Setting future status');
 
656
  } else {
657
- // If cannot schedule future items, clamp the timestamp to the current time minus
658
- // 1 second for each iteration done so far
659
- $timestamp = min(time() - $i, $timestamp);
660
-
661
  $logger->debug('Date was clamped to present time');
 
662
  }
663
  }
664
  } else {
665
- // Item has no date ...
666
  $logger->debug('Item "{0}" has no date. Using current time', [$item->get_title()]);
667
  $timestamp = time();
668
  }
669
 
670
- $date = date( $format, $timestamp );
671
- $date_gmt = gmdate( $format, $item->get_gmdate( 'U' ) );
672
 
673
  $logger->debug('Date for "{0}" will be {1}', [$item->get_title(), $date]);
674
 
@@ -879,7 +881,7 @@ function wprss_get_feed_fetch_time_limit() {
879
  *
880
  * This function is used by the cron job or the debugging functions to get all feeds from all feed sources
881
  *
882
- * @param $all If set to TRUE, the function will pull from all feed sources, regardless of their individual
883
  * update interval. If set to FALSE, only feed sources using the global update system will be updated.
884
  * (Optional) Default: TRUE.
885
  * @since 3.0
@@ -966,13 +968,13 @@ function wprss_detect_exec_timeout() {
966
  *
967
  * @since 4.11.2
968
  *
969
- * @param \SimplePie_Item|mixed $item The item to validate.
970
  *
971
- * @return \SimplePie_Item|null The item, if it passes; otherwise, null.
972
  */
973
  function wprss_item_filter_valid($item)
974
  {
975
- return $item instanceof \SimplePie_Item
976
  ? $item
977
  : null;
978
  }
@@ -985,8 +987,8 @@ function wprss_item_filter_valid($item)
985
  *
986
  * @since 4.11.2
987
  *
988
- * @param \SimplePie_Item[] $items The items list.
989
- * @param \WP_Post $feedSource The feed source, for which to sort, if any.
990
  */
991
  function wprss_sort_items(&$items, $feedSource = null)
992
  {
@@ -1017,8 +1019,8 @@ function wprss_sort_items(&$items, $feedSource = null)
1017
  *
1018
  * @since 4.11.2
1019
  *
1020
- * @param \SimplePie_Item|mixed $itemA The item being compared;
1021
- * @param \SimplePie_Item|mixed $itemB The item being compared to;
1022
  * @param callable[] $comparators A list of functions for item comparison.
1023
  *
1024
  * @return int A result usable as a return value for {@see usort()}.
@@ -1050,13 +1052,13 @@ function wprss_items_sort_compare_items($itemA, $itemB, $comparators, $feedSourc
1050
  * @since 4.11.2
1051
  *
1052
  * @param string $key The key of the field or setting.
1053
- * @param \WP_Post|null $feedSource The feed source, if any.
1054
- * @return type
1055
  */
1056
  function wprss_get_source_meta_or_setting($key, $feedSource = null)
1057
  {
1058
  $value = null;
1059
- if ($feedSource instanceof \WP_Post) {
1060
  $value = $feedSource->{$key};
1061
  }
1062
 
@@ -1072,9 +1074,9 @@ function wprss_get_source_meta_or_setting($key, $feedSource = null)
1072
  *
1073
  * @since 4.11.2
1074
  *
1075
- * @param \SimplePie_Item|mixed $itemA The first item.
1076
- * @param \SimplePie_Item|mixed $itemB The second item.
1077
- * @param \WP_Post|null $feedSource The feed source for which the items are being compared, if any.
1078
  * @return int A comparison result for {@see usort()}.
1079
  */
1080
  function wprss_item_comparator_date($itemA, $itemB, $feedSource = null)
@@ -1097,16 +1099,13 @@ function wprss_item_comparator_date($itemA, $itemB, $feedSource = null)
1097
  return null;
1098
  }
1099
  return $aDate > $bDate ? -1 : 1;
1100
- break;
1101
 
1102
  case 'oldest':
1103
  return $aDate < $bDate ? -1 : 1;
1104
- break;
1105
 
1106
  case '':
1107
  default:
1108
  return 0;
1109
- break;
1110
  }
1111
  }
1112
 
@@ -1115,7 +1114,7 @@ function wprss_item_comparator_date($itemA, $itemB, $feedSource = null)
1115
  *
1116
  * @since 4.11.2
1117
  *
1118
- * @param \WP_Post|null $feedSource The feed source, for which to get comparators, if any.
1119
  *
1120
  * @return callable[] The list of comparators.
1121
  */
112
  $useGuids = get_post_meta($feed_ID, 'wprss_use_guids', true);
113
  $useGuids = filter_var($useGuids, FILTER_VALIDATE_BOOLEAN);
114
  $existingIds = $useGuids
115
+ ? wprss_get_existing_guids()
116
+ : wprss_get_existing_permalinks();
117
 
118
  // Generate a list of items fetched, that are not already in the DB
119
  $new_items = array();
527
  * into embedded video player urls.
528
  * If the permalink is not a video url, the permalink is returned as is.
529
  *
530
+ * @param string $permalink The string permalink url to convert.
531
+ * @return string A string, with the convert permalink, or the same permalink passed as parameter if
532
  * not a video url.
533
  * @since 4.0
534
  */
550
  $host = $matches[2];
551
  switch( $host ) {
552
  case 'youtube':
553
+ preg_match( '/([&?])v=([^&]+)/', $permalink, $yt_matches );
554
+ $permalink = 'https://www.youtube.com/embed/' . $yt_matches[1];
555
  break;
556
  case 'vimeo':
557
  preg_match( '/(\d*)$/i', $permalink, $vim_matches );
584
  // Count of items inserted
585
  $items_inserted = 0;
586
 
587
+ // The date format expected by WordPress when inserting posts
588
+ $date_format = 'Y-m-d H:i:s';
589
+ // Check if we can schedule future items
590
+ $schedule_items_filter = apply_filters('wpra/importer/allow_scheduled_items', false);
591
+ $schedule_items_option = wprss_get_general_setting('schedule_future_items');
592
+ $schedule_future_items = $schedule_items_filter || $schedule_items_option;
593
+
594
+ // Get whether the imported items count should still be updated, even if the item is imported by a filter or add-on
595
+ $still_update_count = apply_filters( 'wprss_still_update_import_count', FALSE );
596
+
597
  foreach ( $items as $i => $item ) {
598
  $permalink = $item->get_permalink();
599
  $permalink = wprss_normalize_permalink($permalink, $item, $feed_ID);
634
  $item = apply_filters( 'wprss_insert_post_item_conditionals', $item, $feed_ID, $permalink );
635
  /* @var $item SimplePie_Item */
636
 
 
 
 
637
  // If the item is not NULL, continue to inserting the feed item post into the DB
638
  if ( $item !== NULL && !is_bool($item) ) {
639
  $logger->debug('Resuming insertion into DB');
640
 
641
  $post_status = 'publish';
642
 
643
+ // Get the date and normalize if not valid or not given by the feed
 
644
  $timestamp = $item->get_date( 'U' );
645
+ $has_date = !empty($timestamp);
646
 
647
  if ($has_date) {
648
+ $logger->debug('Feed item "{0}" date: {1}', [$item->get_title(), $item->get_date($date_format)]);
649
 
650
  if ($timestamp > time()) {
651
  // Item has a future timestamp ...
652
  $logger->debug('Item "{0}" has a future date', [$item->get_title()]);
653
 
654
+ // If we can schedule future items, set the post status to "future" (aka scheduled).
655
+ // Otherwise, clamp the timestamp to the current time minus 1 second for each item iteration.
656
+ // This results in the items having a 1-second time difference between them, and preserves their
657
+ // order when sorting by their timestamp.
658
+ if ($schedule_future_items) {
 
 
659
  $logger->debug('Setting future status');
660
+ $post_status = 'future';
661
  } else {
 
 
 
 
662
  $logger->debug('Date was clamped to present time');
663
+ $timestamp = min(time() - $i, $timestamp);
664
  }
665
  }
666
  } else {
667
+ // Item has no date, use the current time
668
  $logger->debug('Item "{0}" has no date. Using current time', [$item->get_title()]);
669
  $timestamp = time();
670
  }
671
 
672
+ $date = date( $date_format, $timestamp );
673
+ $date_gmt = gmdate( $date_format, $timestamp );
674
 
675
  $logger->debug('Date for "{0}" will be {1}', [$item->get_title(), $date]);
676
 
881
  *
882
  * This function is used by the cron job or the debugging functions to get all feeds from all feed sources
883
  *
884
+ * @param boolean $all If set to TRUE, the function will pull from all feed sources, regardless of their individual
885
  * update interval. If set to FALSE, only feed sources using the global update system will be updated.
886
  * (Optional) Default: TRUE.
887
  * @since 3.0
968
  *
969
  * @since 4.11.2
970
  *
971
+ * @param SimplePie_Item|mixed $item The item to validate.
972
  *
973
+ * @return SimplePie_Item|null The item, if it passes; otherwise, null.
974
  */
975
  function wprss_item_filter_valid($item)
976
  {
977
+ return $item instanceof SimplePie_Item
978
  ? $item
979
  : null;
980
  }
987
  *
988
  * @since 4.11.2
989
  *
990
+ * @param SimplePie_Item[] $items The items list.
991
+ * @param WP_Post $feedSource The feed source, for which to sort, if any.
992
  */
993
  function wprss_sort_items(&$items, $feedSource = null)
994
  {
1019
  *
1020
  * @since 4.11.2
1021
  *
1022
+ * @param SimplePie_Item|mixed $itemA The item being compared;
1023
+ * @param SimplePie_Item|mixed $itemB The item being compared to;
1024
  * @param callable[] $comparators A list of functions for item comparison.
1025
  *
1026
  * @return int A result usable as a return value for {@see usort()}.
1052
  * @since 4.11.2
1053
  *
1054
  * @param string $key The key of the field or setting.
1055
+ * @param WP_Post|null $feedSource The feed source, if any.
1056
+ * @return mixed
1057
  */
1058
  function wprss_get_source_meta_or_setting($key, $feedSource = null)
1059
  {
1060
  $value = null;
1061
+ if ($feedSource instanceof WP_Post) {
1062
  $value = $feedSource->{$key};
1063
  }
1064
 
1074
  *
1075
  * @since 4.11.2
1076
  *
1077
+ * @param SimplePie_Item|mixed $itemA The first item.
1078
+ * @param SimplePie_Item|mixed $itemB The second item.
1079
+ * @param WP_Post|null $feedSource The feed source for which the items are being compared, if any.
1080
  * @return int A comparison result for {@see usort()}.
1081
  */
1082
  function wprss_item_comparator_date($itemA, $itemB, $feedSource = null)
1099
  return null;
1100
  }
1101
  return $aDate > $bDate ? -1 : 1;
 
1102
 
1103
  case 'oldest':
1104
  return $aDate < $bDate ? -1 : 1;
 
1105
 
1106
  case '':
1107
  default:
1108
  return 0;
 
1109
  }
1110
  }
1111
 
1114
  *
1115
  * @since 4.11.2
1116
  *
1117
+ * @param WP_Post|null $feedSource The feed source, for which to get comparators, if any.
1118
  *
1119
  * @return callable[] The list of comparators.
1120
  */
includes/feed-processing.php CHANGED
@@ -122,18 +122,15 @@ function wprss_get_feed_items_for_source($source_id)
122
 
123
  /**
124
  * Queries the DB to get the GUIDs for existing feed items.
125
- *
126
- * @param int|string $feedId The ID of the feed source.
127
  */
128
- function wprss_get_existing_guids($feedId) {
129
  global $wpdb;
130
 
131
  $cols = $wpdb->get_col(
132
  "SELECT q.`meta_value`
133
  FROM {$wpdb->postmeta} AS p
134
  JOIN {$wpdb->postmeta} AS q
135
- ON (q.`meta_key` = 'wprss_item_guid' AND p.`post_id` = q.`post_id`)
136
- WHERE p.`meta_key` = 'wprss_feed_id' AND p.`meta_value` = '{$feedId}'"
137
  );
138
 
139
  return @array_flip($cols);
@@ -144,7 +141,7 @@ function wprss_get_existing_guids($feedId) {
144
  *
145
  * @since 3.0
146
  */
147
- function wprss_get_existing_permalinks($feed_ID)
148
  {
149
  global $wpdb;
150
 
@@ -152,8 +149,7 @@ function wprss_get_existing_permalinks($feed_ID)
152
  "SELECT q.`meta_value`
153
  FROM {$wpdb->postmeta} AS p
154
  JOIN {$wpdb->postmeta} AS q
155
- ON (q.`meta_key` = 'wprss_item_permalink' AND p.`post_id` = q.`post_id`)
156
- WHERE p.`meta_key` = 'wprss_feed_id' AND p.`meta_value` = '{$feed_ID}'"
157
  );
158
 
159
  return @array_flip($cols);
@@ -191,49 +187,20 @@ function wprss_item_title_exists($title)
191
  *
192
  * @since 4.7
193
  */
194
- function wprss_get_existing_titles($feed_ID = null)
195
  {
196
  global $wpdb;
197
 
198
- $condition = ($feed_ID !== null)
199
- ? "AND q.`meta_value` = '{$feed_ID}'"
200
- : '';
201
-
202
  $cols = $wpdb->get_col(
203
  "SELECT p.`post_title`
204
  FROM `{$wpdb->posts}` AS p
205
  JOIN `{$wpdb->postmeta}` AS q
206
- ON p.`ID` = q.`post_id`
207
- WHERE q.`meta_key` = 'wprss_feed_id' $condition"
208
  );
209
 
210
  return @array_flip($cols);
211
  }
212
 
213
- /**
214
- * Checks if a permalink exists.
215
- *
216
- * Untested!
217
- *
218
- * @param string $permalink The permalink, expected to be normalized.
219
- *
220
- * @return bool
221
- */
222
- function wprss_permalink_exists($permalink)
223
- {
224
- global $wpdb;
225
-
226
- $wpdb->query(
227
- $wpdb->prepare(
228
- "SELECT *
229
- FROM {$wpdb->postmeta}
230
- WHERE `meta_value` = '{$permalink}'"
231
- )
232
- );
233
-
234
- return $wpdb->num_rows > 0;
235
- }
236
-
237
  add_action('publish_wprss_feed', 'wprss_fetch_insert_feed_items', 10);
238
  /**
239
  * Fetches feed items from source provided and inserts into db
122
 
123
  /**
124
  * Queries the DB to get the GUIDs for existing feed items.
 
 
125
  */
126
+ function wprss_get_existing_guids() {
127
  global $wpdb;
128
 
129
  $cols = $wpdb->get_col(
130
  "SELECT q.`meta_value`
131
  FROM {$wpdb->postmeta} AS p
132
  JOIN {$wpdb->postmeta} AS q
133
+ ON (q.`meta_key` = 'wprss_item_guid' AND p.`post_id` = q.`post_id`)"
 
134
  );
135
 
136
  return @array_flip($cols);
141
  *
142
  * @since 3.0
143
  */
144
+ function wprss_get_existing_permalinks()
145
  {
146
  global $wpdb;
147
 
149
  "SELECT q.`meta_value`
150
  FROM {$wpdb->postmeta} AS p
151
  JOIN {$wpdb->postmeta} AS q
152
+ ON (q.`meta_key` = 'wprss_item_permalink' AND p.`post_id` = q.`post_id`)"
 
153
  );
154
 
155
  return @array_flip($cols);
187
  *
188
  * @since 4.7
189
  */
190
+ function wprss_get_existing_titles()
191
  {
192
  global $wpdb;
193
 
 
 
 
 
194
  $cols = $wpdb->get_col(
195
  "SELECT p.`post_title`
196
  FROM `{$wpdb->posts}` AS p
197
  JOIN `{$wpdb->postmeta}` AS q
198
+ ON p.`ID` = q.`post_id`"
 
199
  );
200
 
201
  return @array_flip($cols);
202
  }
203
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  add_action('publish_wprss_feed', 'wprss_fetch_insert_feed_items', 10);
205
  /**
206
  * Fetches feed items from source provided and inserts into db
js/editor.js CHANGED
@@ -39,7 +39,7 @@ var wprss_dialog_submit = null;
39
  }
40
  } else {
41
  if ( sources.length > 0 ) {
42
- shortcode += ' source="' + sources + '"';
43
  }
44
  }
45
 
39
  }
40
  } else {
41
  if ( sources.length > 0 ) {
42
+ shortcode += ' feeds="' + sources + '"';
43
  }
44
  }
45
 
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: RebelCode, jeangalea, markzahra, Mekku
3
  Plugin URI: https://www.wprssaggregator.com
4
  Tags: RSS import, RSS aggregator, autoblog, feed to post, news aggregator, rss to post, content curation, feed import, content syndication, rss feeds, podcast feed, youtube
5
  Requires at least: 4.0 or higher
6
- Tested up to: 5.8
7
  Requires PHP: 5.4
8
- Stable tag: 4.20
9
  License: GPLv3
10
 
11
  The most powerful and reliable RSS aggregator for WordPress. Build a news aggregator, autoblog and more in minutes with unlimited RSS feeds.
@@ -103,6 +103,7 @@ Our terms & conditions can be found [here](https://www.wprssaggregator.com/terms
103
  == High praise from trusted WordPress leaders ==
104
 
105
  * [WP Mayor](http://www.wpmayor.com/rss-feeds-review-wp-rss-aggregator/)
 
106
  * [WPBeginner](https://www.wpbeginner.com/showcase/best-news-aggregator-websites-how-to-build-your-own/)
107
  * [OSTraining](https://www.ostraining.com/blog/wordpress/wp-rss-aggregator/)
108
  * [Toolset](https://toolset.com/2019/03/import-content-post-typewp-rss-aggregator/)
@@ -254,6 +255,16 @@ Our complete Knowledge Base with FAQs can be found [here](https://kb.wprssaggreg
254
 
255
  == Changelog ==
256
 
 
 
 
 
 
 
 
 
 
 
257
  = 4.20 (2022-01-18) =
258
  **Added**
259
  - New option to use feed item GUIDs instead of permalinks to detect duplicate items.
3
  Plugin URI: https://www.wprssaggregator.com
4
  Tags: RSS import, RSS aggregator, autoblog, feed to post, news aggregator, rss to post, content curation, feed import, content syndication, rss feeds, podcast feed, youtube
5
  Requires at least: 4.0 or higher
6
+ Tested up to: 6.0
7
  Requires PHP: 5.4
8
+ Stable tag: 4.21
9
  License: GPLv3
10
 
11
  The most powerful and reliable RSS aggregator for WordPress. Build a news aggregator, autoblog and more in minutes with unlimited RSS feeds.
103
  == High praise from trusted WordPress leaders ==
104
 
105
  * [WP Mayor](http://www.wpmayor.com/rss-feeds-review-wp-rss-aggregator/)
106
+ * [Kinsta](https://kinsta.com/blog/wordpress-rss-feed/)
107
  * [WPBeginner](https://www.wpbeginner.com/showcase/best-news-aggregator-websites-how-to-build-your-own/)
108
  * [OSTraining](https://www.ostraining.com/blog/wordpress/wp-rss-aggregator/)
109
  * [Toolset](https://toolset.com/2019/03/import-content-post-typewp-rss-aggregator/)
255
 
256
  == Changelog ==
257
 
258
+ = 4.21 (2022-07-13) =
259
+ **Changed**
260
+ - Updated Twig to v1.42.2, to support PHP 8 or later.
261
+ - Optimized feed item date processing when an item is being imported.
262
+ - Permalink and GUID checks are now done across all feed sources when an item is being imported.
263
+
264
+ **Fixed**
265
+ - Various PHP 8 errors and deprecations compatibility.
266
+ - The classic editor button was generating incorrect shortcodes.
267
+
268
  = 4.20 (2022-01-18) =
269
  **Added**
270
  - New option to use feed item GUIDs instead of permalinks to detect duplicate items.
src/Data/ArrayDataSet.php CHANGED
@@ -4,11 +4,8 @@ namespace RebelCode\Wpra\Core\Data;
4
 
5
  use ArrayAccess;
6
  use ArrayIterator;
7
- use Dhii\Exception\CreateInvalidArgumentExceptionCapableTrait;
8
- use Dhii\I18n\StringTranslatingTrait;
9
- use Dhii\Util\Normalization\NormalizeArrayCapableTrait;
10
  use stdClass;
11
- use Traversable;
12
 
13
  /**
14
  * A data set implementation that uses a static array or object data store.
@@ -17,15 +14,6 @@ use Traversable;
17
  */
18
  class ArrayDataSet extends AbstractDataSet
19
  {
20
- /* @since 4.13 */
21
- use NormalizeArrayCapableTrait;
22
-
23
- /* @since 4.13 */
24
- use CreateInvalidArgumentExceptionCapableTrait;
25
-
26
- /* @since 4.13 */
27
- use StringTranslatingTrait;
28
-
29
  /**
30
  * The options data as an associative array.
31
  *
@@ -47,12 +35,12 @@ class ArrayDataSet extends AbstractDataSet
47
  *
48
  * @since 4.13
49
  *
50
- * @param array|stdClass|Traversable $data The data store, as an associative array, object or iterator.
51
- * @param bool $recursive Whether or not to recursively set data to children data sets.
52
  */
53
  public function __construct($data, $recursive = false)
54
  {
55
- $this->data = $this->_normalizeArray($data);
56
  $this->recursive = $recursive;
57
  }
58
 
@@ -73,7 +61,7 @@ class ArrayDataSet extends AbstractDataSet
73
  */
74
  protected function has($key)
75
  {
76
- return array_key_exists($key, $this->data);
77
  }
78
 
79
  /**
4
 
5
  use ArrayAccess;
6
  use ArrayIterator;
7
+ use RebelCode\Wpra\Core\Util\Normalize;
 
 
8
  use stdClass;
 
9
 
10
  /**
11
  * A data set implementation that uses a static array or object data store.
14
  */
15
  class ArrayDataSet extends AbstractDataSet
16
  {
 
 
 
 
 
 
 
 
 
17
  /**
18
  * The options data as an associative array.
19
  *
35
  *
36
  * @since 4.13
37
  *
38
+ * @param iterable|stdClass $data The data store, as an associative array, object or iterator.
39
+ * @param bool $recursive Whether to recursively set data to children data sets.
40
  */
41
  public function __construct($data, $recursive = false)
42
  {
43
+ $this->data = Normalize::toArray($data);
44
  $this->recursive = $recursive;
45
  }
46
 
61
  */
62
  protected function has($key)
63
  {
64
+ return array_key_exists($key, (array) $this->data);
65
  }
66
 
67
  /**
src/Entities/Collections/FeedItemCollection.php CHANGED
@@ -3,6 +3,7 @@
3
  namespace RebelCode\Wpra\Core\Entities\Collections;
4
 
5
  use RebelCode\Entities\Api\SchemaInterface;
 
6
 
7
  /**
8
  * A collection implementation that is specific to WP RSS Aggregator feed items.
@@ -63,7 +64,7 @@ class FeedItemCollection extends WpEntityCollection
63
  $r = parent::handleFilter($queryArgs, $key, $value);
64
 
65
  if ($key === 'feeds') {
66
- $slugs = $this->_normalizeArray($value);
67
  $posts = get_posts([
68
  'post_name__in' => $slugs,
69
  'post_type' => 'wprss_feed',
@@ -80,7 +81,7 @@ class FeedItemCollection extends WpEntityCollection
80
  $queryArgs['meta_query']['relation'] = 'AND';
81
  $queryArgs['meta_query'][] = [
82
  'key' => 'wprss_feed_id',
83
- 'value' => $this->_normalizeArray($value),
84
  'compare' => 'IN',
85
  ];
86
 
@@ -91,7 +92,7 @@ class FeedItemCollection extends WpEntityCollection
91
  $queryArgs['meta_query']['relation'] = 'AND';
92
  $queryArgs['meta_query'][] = [
93
  'key' => 'wprss_feed_id',
94
- 'value' => $this->_normalizeArray($value),
95
  'compare' => 'NOT IN',
96
  ];
97
 
3
  namespace RebelCode\Wpra\Core\Entities\Collections;
4
 
5
  use RebelCode\Entities\Api\SchemaInterface;
6
+ use RebelCode\Wpra\Core\Util\Normalize;
7
 
8
  /**
9
  * A collection implementation that is specific to WP RSS Aggregator feed items.
64
  $r = parent::handleFilter($queryArgs, $key, $value);
65
 
66
  if ($key === 'feeds') {
67
+ $slugs = Normalize::toArray($value);
68
  $posts = get_posts([
69
  'post_name__in' => $slugs,
70
  'post_type' => 'wprss_feed',
81
  $queryArgs['meta_query']['relation'] = 'AND';
82
  $queryArgs['meta_query'][] = [
83
  'key' => 'wprss_feed_id',
84
+ 'value' => Normalize::toArray($value),
85
  'compare' => 'IN',
86
  ];
87
 
92
  $queryArgs['meta_query']['relation'] = 'AND';
93
  $queryArgs['meta_query'][] = [
94
  'key' => 'wprss_feed_id',
95
+ 'value' => Normalize::toArray($value),
96
  'compare' => 'NOT IN',
97
  ];
98
 
src/Entities/Collections/WpEntityCollection.php CHANGED
@@ -4,9 +4,6 @@ namespace RebelCode\Wpra\Core\Entities\Collections;
4
 
5
  use ArrayAccess;
6
  use ArrayIterator;
7
- use Dhii\Exception\CreateInvalidArgumentExceptionCapableTrait;
8
- use Dhii\I18n\StringTranslatingTrait;
9
- use Dhii\Util\Normalization\NormalizeArrayCapableTrait;
10
  use InvalidArgumentException;
11
  use OutOfRangeException;
12
  use RebelCode\Entities\Api\EntityInterface;
@@ -30,15 +27,6 @@ use WP_Post;
30
  */
31
  class WpEntityCollection extends AbstractDataSet implements CollectionInterface
32
  {
33
- /* @since 4.13 */
34
- use NormalizeArrayCapableTrait;
35
-
36
- /* @since 4.13 */
37
- use CreateInvalidArgumentExceptionCapableTrait;
38
-
39
- /* @since 4.13 */
40
- use StringTranslatingTrait;
41
-
42
  /**
43
  * The post type.
44
  *
@@ -302,24 +290,6 @@ class WpEntityCollection extends AbstractDataSet implements CollectionInterface
302
  return $data;
303
  }
304
 
305
- /**
306
- * Normalizes a variable into a post array,
307
- *
308
- * @since 4.13
309
- *
310
- * @param array|stdClass|Traversable|WP_Post $post Post data array, object or iterable, or a WP_Post instance.
311
- *
312
- * @return array The post data array.
313
- */
314
- protected function toPostArray($post)
315
- {
316
- if ($post instanceof WP_Post) {
317
- return $post->to_array();
318
- }
319
-
320
- return $this->_normalizeArray($post);
321
- }
322
-
323
  /**
324
  * Recursively patches a subject with every entry in a given patch data array.
325
  *
4
 
5
  use ArrayAccess;
6
  use ArrayIterator;
 
 
 
7
  use InvalidArgumentException;
8
  use OutOfRangeException;
9
  use RebelCode\Entities\Api\EntityInterface;
27
  */
28
  class WpEntityCollection extends AbstractDataSet implements CollectionInterface
29
  {
 
 
 
 
 
 
 
 
 
30
  /**
31
  * The post type.
32
  *
290
  return $data;
291
  }
292
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293
  /**
294
  * Recursively patches a subject with every entry in a given patch data array.
295
  *
src/ErrorHandler.php CHANGED
@@ -2,7 +2,6 @@
2
 
3
  namespace RebelCode\Wpra\Core;
4
 
5
- use Dhii\I18n\StringTranslatingTrait;
6
  use Exception;
7
  use Psr\Log\LogLevel;
8
  use Throwable;
@@ -14,13 +13,6 @@ use Throwable;
14
  */
15
  class ErrorHandler
16
  {
17
- /*
18
- * Provides string translating functionality.
19
- *
20
- * @since 4.14
21
- */
22
- use StringTranslatingTrait;
23
-
24
  /**
25
  * The callback to invoke.
26
  *
2
 
3
  namespace RebelCode\Wpra\Core;
4
 
 
5
  use Exception;
6
  use Psr\Log\LogLevel;
7
  use Throwable;
13
  */
14
  class ErrorHandler
15
  {
 
 
 
 
 
 
 
16
  /**
17
  * The callback to invoke.
18
  *
src/Templates/Feeds/LegacyDisplayTemplate.php CHANGED
@@ -2,11 +2,9 @@
2
 
3
  namespace RebelCode\Wpra\Core\Templates\Feeds;
4
 
5
- use Dhii\Exception\CreateInvalidArgumentExceptionCapableTrait;
6
- use Dhii\I18n\StringTranslatingTrait;
7
  use Dhii\Output\TemplateInterface;
8
- use Dhii\Util\Normalization\NormalizeArrayCapableTrait;
9
  use InvalidArgumentException;
 
10
 
11
  /**
12
  * A standard template wrapper for the legacy WP RSS Aggregator display template.
@@ -15,15 +13,6 @@ use InvalidArgumentException;
15
  */
16
  class LegacyDisplayTemplate implements TemplateInterface
17
  {
18
- /* @since 4.13 */
19
- use NormalizeArrayCapableTrait;
20
-
21
- /* @since 4.13 */
22
- use CreateInvalidArgumentExceptionCapableTrait;
23
-
24
- /* @since 4.13 */
25
- use StringTranslatingTrait;
26
-
27
  /**
28
  * {@inheritdoc}
29
  *
@@ -32,7 +21,7 @@ class LegacyDisplayTemplate implements TemplateInterface
32
  public function render($context = null)
33
  {
34
  try {
35
- $arrCtx = $this->_normalizeArray($context);
36
  } catch (InvalidArgumentException $exception) {
37
  $arrCtx = [];
38
  }
2
 
3
  namespace RebelCode\Wpra\Core\Templates\Feeds;
4
 
 
 
5
  use Dhii\Output\TemplateInterface;
 
6
  use InvalidArgumentException;
7
+ use RebelCode\Wpra\Core\Util\Normalize;
8
 
9
  /**
10
  * A standard template wrapper for the legacy WP RSS Aggregator display template.
13
  */
14
  class LegacyDisplayTemplate implements TemplateInterface
15
  {
 
 
 
 
 
 
 
 
 
16
  /**
17
  * {@inheritdoc}
18
  *
21
  public function render($context = null)
22
  {
23
  try {
24
+ $arrCtx = Normalize::toArray($context);
25
  } catch (InvalidArgumentException $exception) {
26
  $arrCtx = [];
27
  }
src/Templates/Feeds/MasterFeedsTemplate.php CHANGED
@@ -2,20 +2,15 @@
2
 
3
  namespace RebelCode\Wpra\Core\Templates\Feeds;
4
 
5
- use Dhii\Exception\CreateInvalidArgumentExceptionCapableTrait;
6
- use Dhii\I18n\StringTranslatingTrait;
7
- use Dhii\Output\CreateTemplateRenderExceptionCapableTrait;
8
  use Dhii\Output\TemplateInterface;
9
- use Dhii\Util\Normalization\NormalizeArrayCapableTrait;
10
  use Exception;
11
  use InvalidArgumentException;
12
  use Psr\Log\LoggerInterface;
13
- use RebelCode\Entities\Entity;
14
  use RebelCode\Wpra\Core\Data\ArrayDataSet;
15
  use RebelCode\Wpra\Core\Data\Collections\CollectionInterface;
16
  use RebelCode\Wpra\Core\Data\DataSetInterface;
17
- use RebelCode\Wpra\Core\Data\EntityDataSet;
18
  use RebelCode\Wpra\Core\Templates\Feeds\Types\FeedTemplateTypeInterface;
 
19
  use RebelCode\Wpra\Core\Util\ParseArgsWithSchemaCapableTrait;
20
  use RebelCode\Wpra\Core\Util\SanitizeCommaListCapableTrait;
21
  use stdClass;
@@ -42,18 +37,6 @@ class MasterFeedsTemplate implements TemplateInterface
42
  /* @since 4.13 */
43
  use SanitizeCommaListCapableTrait;
44
 
45
- /* @since 4.13 */
46
- use NormalizeArrayCapableTrait;
47
-
48
- /* @since 4.13 */
49
- use CreateInvalidArgumentExceptionCapableTrait;
50
-
51
- /* @since 4.13 */
52
- use CreateTemplateRenderExceptionCapableTrait;
53
-
54
- /* @since 4.13 */
55
- use StringTranslatingTrait;
56
-
57
  /**
58
  * The key from where to read template options.
59
  *
@@ -173,8 +156,8 @@ class MasterFeedsTemplate implements TemplateInterface
173
 
174
  // Merge the model options with the non-schema ctx args
175
  $options = array_merge(
176
- $this->_normalizeArray($model[static::TEMPLATE_OPTIONS_KEY]),
177
- $this->_normalizeArray($ctx[static::CTX_OPTIONS_KEY])
178
  );
179
  // Include the template slug in the context
180
  $options['template'] = $model['slug'];
@@ -208,7 +191,7 @@ class MasterFeedsTemplate implements TemplateInterface
208
  protected function parseContext($ctx)
209
  {
210
  try {
211
- $normCtx = $this->_normalizeArray($ctx);
212
  } catch (InvalidArgumentException $exception) {
213
  $normCtx = [];
214
  }
2
 
3
  namespace RebelCode\Wpra\Core\Templates\Feeds;
4
 
 
 
 
5
  use Dhii\Output\TemplateInterface;
 
6
  use Exception;
7
  use InvalidArgumentException;
8
  use Psr\Log\LoggerInterface;
 
9
  use RebelCode\Wpra\Core\Data\ArrayDataSet;
10
  use RebelCode\Wpra\Core\Data\Collections\CollectionInterface;
11
  use RebelCode\Wpra\Core\Data\DataSetInterface;
 
12
  use RebelCode\Wpra\Core\Templates\Feeds\Types\FeedTemplateTypeInterface;
13
+ use RebelCode\Wpra\Core\Util\Normalize;
14
  use RebelCode\Wpra\Core\Util\ParseArgsWithSchemaCapableTrait;
15
  use RebelCode\Wpra\Core\Util\SanitizeCommaListCapableTrait;
16
  use stdClass;
37
  /* @since 4.13 */
38
  use SanitizeCommaListCapableTrait;
39
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  /**
41
  * The key from where to read template options.
42
  *
156
 
157
  // Merge the model options with the non-schema ctx args
158
  $options = array_merge(
159
+ Normalize::toArray($model[static::TEMPLATE_OPTIONS_KEY]),
160
+ Normalize::toArray($ctx[static::CTX_OPTIONS_KEY])
161
  );
162
  // Include the template slug in the context
163
  $options['template'] = $model['slug'];
191
  protected function parseContext($ctx)
192
  {
193
  try {
194
+ $normCtx = Normalize::toArray($ctx);
195
  } catch (InvalidArgumentException $exception) {
196
  $normCtx = [];
197
  }
src/Templates/Feeds/TemplateTypeTemplate.php CHANGED
@@ -2,13 +2,11 @@
2
 
3
  namespace RebelCode\Wpra\Core\Templates\Feeds;
4
 
5
- use Dhii\Exception\CreateInvalidArgumentExceptionCapableTrait;
6
- use Dhii\I18n\StringTranslatingTrait;
7
  use Dhii\Output\TemplateInterface;
8
- use Dhii\Util\Normalization\NormalizeArrayCapableTrait;
9
  use InvalidArgumentException;
10
  use RebelCode\Wpra\Core\Data\Collections\CollectionInterface;
11
  use RebelCode\Wpra\Core\Templates\Feeds\Types\FeedTemplateTypeInterface;
 
12
  use RebelCode\Wpra\Core\Util\ParseArgsWithSchemaCapableTrait;
13
  use stdClass;
14
  use Traversable;
@@ -23,15 +21,6 @@ class TemplateTypeTemplate implements TemplateInterface
23
  /* @since 4.14 */
24
  use ParseArgsWithSchemaCapableTrait;
25
 
26
- /* @since 4.14 */
27
- use NormalizeArrayCapableTrait;
28
-
29
- /* @since 4.14 */
30
- use CreateInvalidArgumentExceptionCapableTrait;
31
-
32
- /* @since 4.14 */
33
- use StringTranslatingTrait;
34
-
35
  /**
36
  * An associative array of template type instances.
37
  *
@@ -131,7 +120,7 @@ class TemplateTypeTemplate implements TemplateInterface
131
  protected function parseContext($ctx)
132
  {
133
  try {
134
- $normCtx = $this->_normalizeArray($ctx);
135
  } catch (InvalidArgumentException $exception) {
136
  $normCtx = [];
137
  }
2
 
3
  namespace RebelCode\Wpra\Core\Templates\Feeds;
4
 
 
 
5
  use Dhii\Output\TemplateInterface;
 
6
  use InvalidArgumentException;
7
  use RebelCode\Wpra\Core\Data\Collections\CollectionInterface;
8
  use RebelCode\Wpra\Core\Templates\Feeds\Types\FeedTemplateTypeInterface;
9
+ use RebelCode\Wpra\Core\Util\Normalize;
10
  use RebelCode\Wpra\Core\Util\ParseArgsWithSchemaCapableTrait;
11
  use stdClass;
12
  use Traversable;
21
  /* @since 4.14 */
22
  use ParseArgsWithSchemaCapableTrait;
23
 
 
 
 
 
 
 
 
 
 
24
  /**
25
  * An associative array of template type instances.
26
  *
120
  protected function parseContext($ctx)
121
  {
122
  try {
123
+ $normCtx = Normalize::toArray($ctx);
124
  } catch (InvalidArgumentException $exception) {
125
  $normCtx = [];
126
  }
src/Templates/Feeds/Types/AbstractFeedTemplateType.php CHANGED
@@ -3,14 +3,12 @@
3
  namespace RebelCode\Wpra\Core\Templates\Feeds\Types;
4
 
5
  use ArrayAccess;
6
- use Dhii\Exception\CreateInvalidArgumentExceptionCapableTrait;
7
- use Dhii\I18n\StringTranslatingTrait;
8
- use Dhii\Output\CreateTemplateRenderExceptionCapableTrait;
9
  use Dhii\Output\TemplateInterface;
10
- use Dhii\Util\Normalization\NormalizeArrayCapableTrait;
11
  use Exception;
12
  use InvalidArgumentException;
13
  use RebelCode\Wpra\Core\Data\Collections\CollectionInterface;
 
14
  use RebelCode\Wpra\Core\Util\ParseArgsWithSchemaCapableTrait;
15
 
16
  /**
@@ -27,18 +25,6 @@ abstract class AbstractFeedTemplateType implements FeedTemplateTypeInterface
27
  /* @since 4.13 */
28
  use ParseArgsWithSchemaCapableTrait;
29
 
30
- /* @since 4.13 */
31
- use NormalizeArrayCapableTrait;
32
-
33
- /* @since 4.13 */
34
- use CreateInvalidArgumentExceptionCapableTrait;
35
-
36
- /* @since 4.13 */
37
- use CreateTemplateRenderExceptionCapableTrait;
38
-
39
- /* @since 4.13 */
40
- use StringTranslatingTrait;
41
-
42
  /**
43
  * {@inheritdoc}
44
  *
@@ -46,7 +32,7 @@ abstract class AbstractFeedTemplateType implements FeedTemplateTypeInterface
46
  */
47
  public function render($ctx = null)
48
  {
49
- $argCtx = ($ctx === null) ? [] : $this->_normalizeArray($ctx);
50
  $prepCtx = $this->prepareContext($argCtx);
51
 
52
  $this->enqueueAssets();
@@ -54,9 +40,7 @@ abstract class AbstractFeedTemplateType implements FeedTemplateTypeInterface
54
  try {
55
  return $this->getTemplate()->render($prepCtx);
56
  } catch (Exception $ex) {
57
- throw $this->_createTemplateRenderException(
58
- $ex->getMessage(), null, $ex, $this, $prepCtx
59
- );
60
  }
61
  }
62
 
3
  namespace RebelCode\Wpra\Core\Templates\Feeds\Types;
4
 
5
  use ArrayAccess;
6
+ use Dhii\Output\Exception\TemplateRenderException;
 
 
7
  use Dhii\Output\TemplateInterface;
 
8
  use Exception;
9
  use InvalidArgumentException;
10
  use RebelCode\Wpra\Core\Data\Collections\CollectionInterface;
11
+ use RebelCode\Wpra\Core\Util\Normalize;
12
  use RebelCode\Wpra\Core\Util\ParseArgsWithSchemaCapableTrait;
13
 
14
  /**
25
  /* @since 4.13 */
26
  use ParseArgsWithSchemaCapableTrait;
27
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  /**
29
  * {@inheritdoc}
30
  *
32
  */
33
  public function render($ctx = null)
34
  {
35
+ $argCtx = ($ctx === null) ? [] : Normalize::toArray($ctx);
36
  $prepCtx = $this->prepareContext($argCtx);
37
 
38
  $this->enqueueAssets();
40
  try {
41
  return $this->getTemplate()->render($prepCtx);
42
  } catch (Exception $ex) {
43
+ throw new TemplateRenderException($ex->getMessage(), null, $ex, $this, $prepCtx);
 
 
44
  }
45
  }
46
 
src/Templates/TwigTemplate.php CHANGED
@@ -2,8 +2,6 @@
2
 
3
  namespace RebelCode\Wpra\Core\Templates;
4
 
5
- use Dhii\Exception\CreateInvalidArgumentExceptionCapableTrait;
6
- use Dhii\I18n\StringTranslatingTrait;
7
  use Dhii\Output\Exception\TemplateRenderException;
8
  use Dhii\Output\TemplateInterface;
9
  use Exception;
@@ -18,12 +16,6 @@ use Twig\Error\SyntaxError;
18
  */
19
  class TwigTemplate implements TemplateInterface
20
  {
21
- /* @since 4.13 */
22
- use CreateInvalidArgumentExceptionCapableTrait;
23
-
24
- /* @since 4.13 */
25
- use StringTranslatingTrait;
26
-
27
  /**
28
  * The Twig environment.
29
  *
2
 
3
  namespace RebelCode\Wpra\Core\Templates;
4
 
 
 
5
  use Dhii\Output\Exception\TemplateRenderException;
6
  use Dhii\Output\TemplateInterface;
7
  use Exception;
16
  */
17
  class TwigTemplate implements TemplateInterface
18
  {
 
 
 
 
 
 
19
  /**
20
  * The Twig environment.
21
  *
src/Util/Normalize.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace RebelCode\Wpra\Core\Util;
4
+
5
+ use InvalidArgumentException;
6
+ use stdClass;
7
+ use Traversable;
8
+
9
+ class Normalize
10
+ {
11
+ /**
12
+ * Normalizes a value into an array.
13
+ *
14
+ * @since [*next-version*]
15
+ *
16
+ * @param array|stdClass|Traversable $value The value to normalize.
17
+ *
18
+ * @return array The normalized value.
19
+ * @throws InvalidArgumentException If value cannot be normalized.
20
+ *
21
+ */
22
+ public static function toArray($value)
23
+ {
24
+ if (is_array($value) || $value instanceof stdClass) {
25
+ return (array) $value;
26
+ }
27
+
28
+ if (!($value instanceof Traversable)) {
29
+ throw new InvalidArgumentException(__('Not an iterable'), null, null);
30
+ } else {
31
+ return iterator_to_array($value, true);
32
+ }
33
+ }
34
+ }
src/Util/ParseArgsWithSchemaCapableTrait.php CHANGED
@@ -146,6 +146,6 @@ trait ParseArgsWithSchemaCapableTrait
146
  $array[$head] = [];
147
  }
148
 
149
- static::_arrayDeepSet($array[$head], $path, $value);
150
  }
151
  }
146
  $array[$head] = [];
147
  }
148
 
149
+ $this->_arrayDeepSet($array[$head], $path, $value);
150
  }
151
  }
vendor/composer/autoload_classmap.php CHANGED
@@ -375,6 +375,7 @@ return array(
375
  'RebelCode\\Wpra\\Core\\Util\\CallbackIterator' => $baseDir . '/src/Util/CallbackIterator.php',
376
  'RebelCode\\Wpra\\Core\\Util\\IteratorDelegateTrait' => $baseDir . '/src/Util/IteratorDelegateTrait.php',
377
  'RebelCode\\Wpra\\Core\\Util\\MergedIterator' => $baseDir . '/src/Util/MergedIterator.php',
 
378
  'RebelCode\\Wpra\\Core\\Util\\NormalizeWpPostCapableTrait' => $baseDir . '/src/Util/NormalizeWpPostCapableTrait.php',
379
  'RebelCode\\Wpra\\Core\\Util\\NullFunction' => $baseDir . '/src/Util/NullFunction.php',
380
  'RebelCode\\Wpra\\Core\\Util\\PaginatedIterator' => $baseDir . '/src/Util/PaginatedIterator.php',
@@ -386,6 +387,24 @@ return array(
386
  'RebelCode\\Wpra\\Core\\Util\\Sanitizers\\EquivalenceSanitizer' => $baseDir . '/src/Util/Sanitizers/EquivalenceSanitizer.php',
387
  'RebelCode\\Wpra\\Core\\Util\\Sanitizers\\IntSanitizer' => $baseDir . '/src/Util/Sanitizers/IntSanitizer.php',
388
  'RebelCode\\Wpra\\Core\\Util\\Sanitizers\\PhpFilterSanitizer' => $baseDir . '/src/Util/Sanitizers/PhpFilterSanitizer.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
  'RebelCode\\Wpra\\Core\\Wp\\Asset\\AbstractAsset' => $baseDir . '/src/Wp/Asset/AbstractAsset.php',
390
  'RebelCode\\Wpra\\Core\\Wp\\Asset\\AssetInterface' => $baseDir . '/src/Wp/Asset/AssetInterface.php',
391
  'RebelCode\\Wpra\\Core\\Wp\\Asset\\ScriptAsset' => $baseDir . '/src/Wp/Asset/ScriptAsset.php',
375
  'RebelCode\\Wpra\\Core\\Util\\CallbackIterator' => $baseDir . '/src/Util/CallbackIterator.php',
376
  'RebelCode\\Wpra\\Core\\Util\\IteratorDelegateTrait' => $baseDir . '/src/Util/IteratorDelegateTrait.php',
377
  'RebelCode\\Wpra\\Core\\Util\\MergedIterator' => $baseDir . '/src/Util/MergedIterator.php',
378
+ 'RebelCode\\Wpra\\Core\\Util\\Normalize' => $baseDir . '/src/Util/Normalize.php',
379
  'RebelCode\\Wpra\\Core\\Util\\NormalizeWpPostCapableTrait' => $baseDir . '/src/Util/NormalizeWpPostCapableTrait.php',
380
  'RebelCode\\Wpra\\Core\\Util\\NullFunction' => $baseDir . '/src/Util/NullFunction.php',
381
  'RebelCode\\Wpra\\Core\\Util\\PaginatedIterator' => $baseDir . '/src/Util/PaginatedIterator.php',
387
  'RebelCode\\Wpra\\Core\\Util\\Sanitizers\\EquivalenceSanitizer' => $baseDir . '/src/Util/Sanitizers/EquivalenceSanitizer.php',
388
  'RebelCode\\Wpra\\Core\\Util\\Sanitizers\\IntSanitizer' => $baseDir . '/src/Util/Sanitizers/IntSanitizer.php',
389
  'RebelCode\\Wpra\\Core\\Util\\Sanitizers\\PhpFilterSanitizer' => $baseDir . '/src/Util/Sanitizers/PhpFilterSanitizer.php',
390
+ 'RebelCode\\Wpra\\Core\\V5\\Feed' => $baseDir . '/src/V5/Feed.php',
391
+ 'RebelCode\\Wpra\\Core\\V5\\FeedInterface' => $baseDir . '/src/V5/FeedInterface.php',
392
+ 'RebelCode\\Wpra\\Core\\V5\\FeedItem' => $baseDir . '/src/V5/FeedItem.php',
393
+ 'RebelCode\\Wpra\\Core\\V5\\FeedItem\\Author' => $baseDir . '/src/V5/FeedItem/Author.php',
394
+ 'RebelCode\\Wpra\\Core\\V5\\FeedItem\\Category' => $baseDir . '/src/V5/FeedItem/Category.php',
395
+ 'RebelCode\\Wpra\\Core\\V5\\Feed\\DbFeed' => $baseDir . '/src/V5/Feed/DbFeed.php',
396
+ 'RebelCode\\Wpra\\Core\\V5\\Feed\\FeedMeta' => $baseDir . '/src/V5/Feed/FeedMeta.php',
397
+ 'RebelCode\\Wpra\\Core\\V5\\ImportContext' => $baseDir . '/src/V5/ImportContext.php',
398
+ 'RebelCode\\Wpra\\Core\\V5\\Importer' => $baseDir . '/src/V5/Importer.php',
399
+ 'RebelCode\\Wpra\\Core\\V5\\Importer\\FetchData' => $baseDir . '/src/V5/Importer/FetchData.php',
400
+ 'RebelCode\\Wpra\\Core\\V5\\Importer\\FetcherInterface' => $baseDir . '/src/V5/Importer/FetcherInterface.php',
401
+ 'RebelCode\\Wpra\\Core\\V5\\Importer\\SimplePieFetcher' => $baseDir . '/src/V5/Importer/SimplePieFetcher.php',
402
+ 'RebelCode\\Wpra\\Core\\V5\\IrItem' => $baseDir . '/src/V5/IrItem.php',
403
+ 'RebelCode\\Wpra\\Core\\V5\\Settings' => $baseDir . '/src/V5/Settings.php',
404
+ 'RebelCode\\Wpra\\Core\\V5\\Utils\\Context' => $baseDir . '/src/V5/Utils/Context.php',
405
+ 'RebelCode\\Wpra\\Core\\V5\\Utils\\CriticalTask' => $baseDir . '/src/V5/Utils/CriticalTask.php',
406
+ 'RebelCode\\Wpra\\Core\\V5\\Utils\\HtmlUtils' => $baseDir . '/src/V5/Utils/HtmlUtils.php',
407
+ 'RebelCode\\Wpra\\Core\\V5\\Utils\\Result' => $baseDir . '/src/V5/Utils/Result.php',
408
  'RebelCode\\Wpra\\Core\\Wp\\Asset\\AbstractAsset' => $baseDir . '/src/Wp/Asset/AbstractAsset.php',
409
  'RebelCode\\Wpra\\Core\\Wp\\Asset\\AssetInterface' => $baseDir . '/src/Wp/Asset/AssetInterface.php',
410
  'RebelCode\\Wpra\\Core\\Wp\\Asset\\ScriptAsset' => $baseDir . '/src/Wp/Asset/ScriptAsset.php',
vendor/composer/autoload_static.php CHANGED
@@ -558,6 +558,7 @@ class ComposerStaticInit46c8b76c439f86ad826af1a4d36b4e60
558
  'RebelCode\\Wpra\\Core\\Util\\CallbackIterator' => __DIR__ . '/../..' . '/src/Util/CallbackIterator.php',
559
  'RebelCode\\Wpra\\Core\\Util\\IteratorDelegateTrait' => __DIR__ . '/../..' . '/src/Util/IteratorDelegateTrait.php',
560
  'RebelCode\\Wpra\\Core\\Util\\MergedIterator' => __DIR__ . '/../..' . '/src/Util/MergedIterator.php',
 
561
  'RebelCode\\Wpra\\Core\\Util\\NormalizeWpPostCapableTrait' => __DIR__ . '/../..' . '/src/Util/NormalizeWpPostCapableTrait.php',
562
  'RebelCode\\Wpra\\Core\\Util\\NullFunction' => __DIR__ . '/../..' . '/src/Util/NullFunction.php',
563
  'RebelCode\\Wpra\\Core\\Util\\PaginatedIterator' => __DIR__ . '/../..' . '/src/Util/PaginatedIterator.php',
@@ -569,6 +570,24 @@ class ComposerStaticInit46c8b76c439f86ad826af1a4d36b4e60
569
  'RebelCode\\Wpra\\Core\\Util\\Sanitizers\\EquivalenceSanitizer' => __DIR__ . '/../..' . '/src/Util/Sanitizers/EquivalenceSanitizer.php',
570
  'RebelCode\\Wpra\\Core\\Util\\Sanitizers\\IntSanitizer' => __DIR__ . '/../..' . '/src/Util/Sanitizers/IntSanitizer.php',
571
  'RebelCode\\Wpra\\Core\\Util\\Sanitizers\\PhpFilterSanitizer' => __DIR__ . '/../..' . '/src/Util/Sanitizers/PhpFilterSanitizer.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
572
  'RebelCode\\Wpra\\Core\\Wp\\Asset\\AbstractAsset' => __DIR__ . '/../..' . '/src/Wp/Asset/AbstractAsset.php',
573
  'RebelCode\\Wpra\\Core\\Wp\\Asset\\AssetInterface' => __DIR__ . '/../..' . '/src/Wp/Asset/AssetInterface.php',
574
  'RebelCode\\Wpra\\Core\\Wp\\Asset\\ScriptAsset' => __DIR__ . '/../..' . '/src/Wp/Asset/ScriptAsset.php',
558
  'RebelCode\\Wpra\\Core\\Util\\CallbackIterator' => __DIR__ . '/../..' . '/src/Util/CallbackIterator.php',
559
  'RebelCode\\Wpra\\Core\\Util\\IteratorDelegateTrait' => __DIR__ . '/../..' . '/src/Util/IteratorDelegateTrait.php',
560
  'RebelCode\\Wpra\\Core\\Util\\MergedIterator' => __DIR__ . '/../..' . '/src/Util/MergedIterator.php',
561
+ 'RebelCode\\Wpra\\Core\\Util\\Normalize' => __DIR__ . '/../..' . '/src/Util/Normalize.php',
562
  'RebelCode\\Wpra\\Core\\Util\\NormalizeWpPostCapableTrait' => __DIR__ . '/../..' . '/src/Util/NormalizeWpPostCapableTrait.php',
563
  'RebelCode\\Wpra\\Core\\Util\\NullFunction' => __DIR__ . '/../..' . '/src/Util/NullFunction.php',
564
  'RebelCode\\Wpra\\Core\\Util\\PaginatedIterator' => __DIR__ . '/../..' . '/src/Util/PaginatedIterator.php',
570
  'RebelCode\\Wpra\\Core\\Util\\Sanitizers\\EquivalenceSanitizer' => __DIR__ . '/../..' . '/src/Util/Sanitizers/EquivalenceSanitizer.php',
571
  'RebelCode\\Wpra\\Core\\Util\\Sanitizers\\IntSanitizer' => __DIR__ . '/../..' . '/src/Util/Sanitizers/IntSanitizer.php',
572
  'RebelCode\\Wpra\\Core\\Util\\Sanitizers\\PhpFilterSanitizer' => __DIR__ . '/../..' . '/src/Util/Sanitizers/PhpFilterSanitizer.php',
573
+ 'RebelCode\\Wpra\\Core\\V5\\Feed' => __DIR__ . '/../..' . '/src/V5/Feed.php',
574
+ 'RebelCode\\Wpra\\Core\\V5\\FeedInterface' => __DIR__ . '/../..' . '/src/V5/FeedInterface.php',
575
+ 'RebelCode\\Wpra\\Core\\V5\\FeedItem' => __DIR__ . '/../..' . '/src/V5/FeedItem.php',
576
+ 'RebelCode\\Wpra\\Core\\V5\\FeedItem\\Author' => __DIR__ . '/../..' . '/src/V5/FeedItem/Author.php',
577
+ 'RebelCode\\Wpra\\Core\\V5\\FeedItem\\Category' => __DIR__ . '/../..' . '/src/V5/FeedItem/Category.php',
578
+ 'RebelCode\\Wpra\\Core\\V5\\Feed\\DbFeed' => __DIR__ . '/../..' . '/src/V5/Feed/DbFeed.php',
579
+ 'RebelCode\\Wpra\\Core\\V5\\Feed\\FeedMeta' => __DIR__ . '/../..' . '/src/V5/Feed/FeedMeta.php',
580
+ 'RebelCode\\Wpra\\Core\\V5\\ImportContext' => __DIR__ . '/../..' . '/src/V5/ImportContext.php',
581
+ 'RebelCode\\Wpra\\Core\\V5\\Importer' => __DIR__ . '/../..' . '/src/V5/Importer.php',
582
+ 'RebelCode\\Wpra\\Core\\V5\\Importer\\FetchData' => __DIR__ . '/../..' . '/src/V5/Importer/FetchData.php',
583
+ 'RebelCode\\Wpra\\Core\\V5\\Importer\\FetcherInterface' => __DIR__ . '/../..' . '/src/V5/Importer/FetcherInterface.php',
584
+ 'RebelCode\\Wpra\\Core\\V5\\Importer\\SimplePieFetcher' => __DIR__ . '/../..' . '/src/V5/Importer/SimplePieFetcher.php',
585
+ 'RebelCode\\Wpra\\Core\\V5\\IrItem' => __DIR__ . '/../..' . '/src/V5/IrItem.php',
586
+ 'RebelCode\\Wpra\\Core\\V5\\Settings' => __DIR__ . '/../..' . '/src/V5/Settings.php',
587
+ 'RebelCode\\Wpra\\Core\\V5\\Utils\\Context' => __DIR__ . '/../..' . '/src/V5/Utils/Context.php',
588
+ 'RebelCode\\Wpra\\Core\\V5\\Utils\\CriticalTask' => __DIR__ . '/../..' . '/src/V5/Utils/CriticalTask.php',
589
+ 'RebelCode\\Wpra\\Core\\V5\\Utils\\HtmlUtils' => __DIR__ . '/../..' . '/src/V5/Utils/HtmlUtils.php',
590
+ 'RebelCode\\Wpra\\Core\\V5\\Utils\\Result' => __DIR__ . '/../..' . '/src/V5/Utils/Result.php',
591
  'RebelCode\\Wpra\\Core\\Wp\\Asset\\AbstractAsset' => __DIR__ . '/../..' . '/src/Wp/Asset/AbstractAsset.php',
592
  'RebelCode\\Wpra\\Core\\Wp\\Asset\\AssetInterface' => __DIR__ . '/../..' . '/src/Wp/Asset/AssetInterface.php',
593
  'RebelCode\\Wpra\\Core\\Wp\\Asset\\ScriptAsset' => __DIR__ . '/../..' . '/src/Wp/Asset/ScriptAsset.php',
vendor/composer/installed.json CHANGED
@@ -1802,17 +1802,17 @@
1802
  },
1803
  {
1804
  "name": "twig/twig",
1805
- "version": "v1.41.0",
1806
- "version_normalized": "1.41.0.0",
1807
  "source": {
1808
  "type": "git",
1809
  "url": "https://github.com/twigphp/Twig.git",
1810
- "reference": "575cd5028362da591facde1ef5d7b94553c375c9"
1811
  },
1812
  "dist": {
1813
  "type": "zip",
1814
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/575cd5028362da591facde1ef5d7b94553c375c9",
1815
- "reference": "575cd5028362da591facde1ef5d7b94553c375c9",
1816
  "shasum": ""
1817
  },
1818
  "require": {
@@ -1822,13 +1822,13 @@
1822
  "require-dev": {
1823
  "psr/container": "^1.0",
1824
  "symfony/debug": "^2.7",
1825
- "symfony/phpunit-bridge": "^3.4.19|^4.1.8"
1826
  },
1827
- "time": "2019-05-14T11:59:08+00:00",
1828
  "type": "library",
1829
  "extra": {
1830
  "branch-alias": {
1831
- "dev-master": "1.41-dev"
1832
  }
1833
  },
1834
  "installation-source": "dist",
@@ -1867,6 +1867,10 @@
1867
  "keywords": [
1868
  "templating"
1869
  ],
 
 
 
 
1870
  "install-path": "../twig/twig"
1871
  }
1872
  ],
1802
  },
1803
  {
1804
  "name": "twig/twig",
1805
+ "version": "v1.42.2",
1806
+ "version_normalized": "1.42.2.0",
1807
  "source": {
1808
  "type": "git",
1809
  "url": "https://github.com/twigphp/Twig.git",
1810
+ "reference": "21707d6ebd05476854805e4f91b836531941bcd4"
1811
  },
1812
  "dist": {
1813
  "type": "zip",
1814
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/21707d6ebd05476854805e4f91b836531941bcd4",
1815
+ "reference": "21707d6ebd05476854805e4f91b836531941bcd4",
1816
  "shasum": ""
1817
  },
1818
  "require": {
1822
  "require-dev": {
1823
  "psr/container": "^1.0",
1824
  "symfony/debug": "^2.7",
1825
+ "symfony/phpunit-bridge": "^3.4.19|^4.1.8|^5.0"
1826
  },
1827
+ "time": "2019-06-18T15:35:16+00:00",
1828
  "type": "library",
1829
  "extra": {
1830
  "branch-alias": {
1831
+ "dev-master": "1.42-dev"
1832
  }
1833
  },
1834
  "installation-source": "dist",
1867
  "keywords": [
1868
  "templating"
1869
  ],
1870
+ "support": {
1871
+ "issues": "https://github.com/twigphp/Twig/issues",
1872
+ "source": "https://github.com/twigphp/Twig/tree/1.x"
1873
+ },
1874
  "install-path": "../twig/twig"
1875
  }
1876
  ],
vendor/composer/installed.php CHANGED
@@ -5,7 +5,7 @@
5
  'type' => 'wordpress-plugin',
6
  'install_path' => __DIR__ . '/../../',
7
  'aliases' => array(),
8
- 'reference' => '935532e5af1a44ac838ebb1f7054b1963781c4dc',
9
  'name' => 'wprss/core',
10
  'dev' => false,
11
  ),
@@ -329,12 +329,12 @@
329
  'dev_requirement' => false,
330
  ),
331
  'twig/twig' => array(
332
- 'pretty_version' => 'v1.41.0',
333
- 'version' => '1.41.0.0',
334
  'type' => 'library',
335
  'install_path' => __DIR__ . '/../twig/twig',
336
  'aliases' => array(),
337
- 'reference' => '575cd5028362da591facde1ef5d7b94553c375c9',
338
  'dev_requirement' => false,
339
  ),
340
  'wprss/core' => array(
@@ -343,7 +343,7 @@
343
  'type' => 'wordpress-plugin',
344
  'install_path' => __DIR__ . '/../../',
345
  'aliases' => array(),
346
- 'reference' => '935532e5af1a44ac838ebb1f7054b1963781c4dc',
347
  'dev_requirement' => false,
348
  ),
349
  ),
5
  'type' => 'wordpress-plugin',
6
  'install_path' => __DIR__ . '/../../',
7
  'aliases' => array(),
8
+ 'reference' => 'a00bf969d77068eabd825565643094274770d0f5',
9
  'name' => 'wprss/core',
10
  'dev' => false,
11
  ),
329
  'dev_requirement' => false,
330
  ),
331
  'twig/twig' => array(
332
+ 'pretty_version' => 'v1.42.2',
333
+ 'version' => '1.42.2.0',
334
  'type' => 'library',
335
  'install_path' => __DIR__ . '/../twig/twig',
336
  'aliases' => array(),
337
+ 'reference' => '21707d6ebd05476854805e4f91b836531941bcd4',
338
  'dev_requirement' => false,
339
  ),
340
  'wprss/core' => array(
343
  'type' => 'wordpress-plugin',
344
  'install_path' => __DIR__ . '/../../',
345
  'aliases' => array(),
346
+ 'reference' => 'a00bf969d77068eabd825565643094274770d0f5',
347
  'dev_requirement' => false,
348
  ),
349
  ),
vendor/twig/twig/composer.json CHANGED
@@ -28,7 +28,7 @@
28
  "symfony/polyfill-ctype": "^1.8"
29
  },
30
  "require-dev": {
31
- "symfony/phpunit-bridge": "^3.4.19|^4.1.8",
32
  "symfony/debug": "^2.7",
33
  "psr/container": "^1.0"
34
  },
@@ -42,7 +42,7 @@
42
  },
43
  "extra": {
44
  "branch-alias": {
45
- "dev-master": "1.41-dev"
46
  }
47
  }
48
  }
28
  "symfony/polyfill-ctype": "^1.8"
29
  },
30
  "require-dev": {
31
+ "symfony/phpunit-bridge": "^3.4.19|^4.1.8|^5.0",
32
  "symfony/debug": "^2.7",
33
  "psr/container": "^1.0"
34
  },
42
  },
43
  "extra": {
44
  "branch-alias": {
45
+ "dev-master": "1.42-dev"
46
  }
47
  }
48
  }
vendor/twig/twig/src/Environment.php CHANGED
@@ -41,11 +41,11 @@ use Twig\TokenParser\TokenParserInterface;
41
  */
42
  class Environment
43
  {
44
- const VERSION = '1.41.0';
45
- const VERSION_ID = 14100;
46
  const MAJOR_VERSION = 1;
47
- const MINOR_VERSION = 41;
48
- const RELEASE_VERSION = 0;
49
  const EXTRA_VERSION = '';
50
 
51
  protected $charset;
41
  */
42
  class Environment
43
  {
44
+ const VERSION = '1.42.2';
45
+ const VERSION_ID = 14202;
46
  const MAJOR_VERSION = 1;
47
+ const MINOR_VERSION = 42;
48
+ const RELEASE_VERSION = 2;
49
  const EXTRA_VERSION = '';
50
 
51
  protected $charset;
vendor/twig/twig/src/ExpressionParser.php CHANGED
@@ -649,7 +649,13 @@ class ExpressionParser
649
  $stream = $this->parser->getStream();
650
  $targets = [];
651
  while (true) {
652
- $token = $stream->expect(Token::NAME_TYPE, null, 'Only variables can be assigned to');
 
 
 
 
 
 
653
  $value = $token->getValue();
654
  if (\in_array(strtolower($value), ['true', 'false', 'none', 'null'])) {
655
  throw new SyntaxError(sprintf('You cannot assign a value to "%s".', $value), $token->getLine(), $stream->getSourceContext());
649
  $stream = $this->parser->getStream();
650
  $targets = [];
651
  while (true) {
652
+ $token = $this->parser->getCurrentToken();
653
+ if ($stream->test(Token::OPERATOR_TYPE) && preg_match(Lexer::REGEX_NAME, $token->getValue())) {
654
+ // in this context, string operators are variable names
655
+ $this->parser->getStream()->next();
656
+ } else {
657
+ $stream->expect(Token::NAME_TYPE, null, 'Only variables can be assigned to');
658
+ }
659
  $value = $token->getValue();
660
  if (\in_array(strtolower($value), ['true', 'false', 'none', 'null'])) {
661
  throw new SyntaxError(sprintf('You cannot assign a value to "%s".', $value), $token->getLine(), $stream->getSourceContext());
vendor/twig/twig/src/Extension/CoreExtension.php CHANGED
@@ -943,6 +943,9 @@ function twig_in_filter($value, $compare)
943
  if ($value instanceof Markup) {
944
  $value = (string) $value;
945
  }
 
 
 
946
 
947
  if (\is_array($compare)) {
948
  return \in_array($value, $compare, \is_object($value) || \is_resource($value));
@@ -1696,11 +1699,8 @@ function twig_array_filter($array, $arrow)
1696
  return array_filter($array, $arrow);
1697
  }
1698
 
1699
- while ($array instanceof \IteratorAggregate) {
1700
- $array = $array->getIterator();
1701
- }
1702
-
1703
- return new \CallbackFilterIterator($array, $arrow);
1704
  }
1705
 
1706
  function twig_array_map($array, $arrow)
943
  if ($value instanceof Markup) {
944
  $value = (string) $value;
945
  }
946
+ if ($compare instanceof Markup) {
947
+ $compare = (string) $compare;
948
+ }
949
 
950
  if (\is_array($compare)) {
951
  return \in_array($value, $compare, \is_object($value) || \is_resource($value));
1699
  return array_filter($array, $arrow);
1700
  }
1701
 
1702
+ // the IteratorIterator wrapping is needed as some internal PHP classes are \Traversable but do not implement \Iterator
1703
+ return new \CallbackFilterIterator(new \IteratorIterator($array), $arrow);
 
 
 
1704
  }
1705
 
1706
  function twig_array_map($array, $arrow)
vendor/twig/twig/src/Extension/DebugExtension.php CHANGED
@@ -54,7 +54,7 @@ function twig_var_dump(Environment $env, $context, array $vars = [])
54
  return;
55
  }
56
 
57
- ob_start(function () { return ''; });
58
 
59
  if (!$vars) {
60
  $vars = [];
54
  return;
55
  }
56
 
57
+ ob_start();
58
 
59
  if (!$vars) {
60
  $vars = [];
vendor/twig/twig/src/Loader/FilesystemLoader.php CHANGED
@@ -201,7 +201,6 @@ class FilesystemLoader implements LoaderInterface, ExistsLoaderInterface, Source
201
  *
202
  * @param string $name The template name
203
  *
204
- * @return string|false The template name or false
205
  * @return string|false|null The template name or false/null
206
  */
207
  protected function findTemplate($name)
201
  *
202
  * @param string $name The template name
203
  *
 
204
  * @return string|false|null The template name or false/null
205
  */
206
  protected function findTemplate($name)
vendor/twig/twig/src/Node/MacroNode.php CHANGED
@@ -104,7 +104,13 @@ class MacroNode extends Node
104
  ->outdent()
105
  ->write("]);\n\n")
106
  ->write("\$blocks = [];\n\n")
107
- ->write("ob_start(function () { return ''; });\n")
 
 
 
 
 
 
108
  ->write("try {\n")
109
  ->indent()
110
  ->subcompile($this->getNode('body'))
104
  ->outdent()
105
  ->write("]);\n\n")
106
  ->write("\$blocks = [];\n\n")
107
+ ;
108
+ if ($compiler->getEnvironment()->isDebug()) {
109
+ $compiler->write("ob_start();\n");
110
+ } else {
111
+ $compiler->write("ob_start(function () { return ''; });\n");
112
+ }
113
+ $compiler
114
  ->write("try {\n")
115
  ->indent()
116
  ->subcompile($this->getNode('body'))
vendor/twig/twig/src/Node/SetNode.php CHANGED
@@ -57,8 +57,12 @@ class SetNode extends Node implements NodeCaptureInterface
57
  $compiler->raw(')');
58
  } else {
59
  if ($this->getAttribute('capture')) {
 
 
 
 
 
60
  $compiler
61
- ->write("ob_start(function () { return ''; });\n")
62
  ->subcompile($this->getNode('values'))
63
  ;
64
  }
57
  $compiler->raw(')');
58
  } else {
59
  if ($this->getAttribute('capture')) {
60
+ if ($compiler->getEnvironment()->isDebug()) {
61
+ $compiler->write("ob_start();\n");
62
+ } else {
63
+ $compiler->write("ob_start(function () { return ''; });\n");
64
+ }
65
  $compiler
 
66
  ->subcompile($this->getNode('values'))
67
  ;
68
  }
vendor/twig/twig/src/Node/SpacelessNode.php CHANGED
@@ -31,7 +31,13 @@ class SpacelessNode extends Node
31
  {
32
  $compiler
33
  ->addDebugInfo($this)
34
- ->write("ob_start(function () { return ''; });\n")
 
 
 
 
 
 
35
  ->subcompile($this->getNode('body'))
36
  ->write("echo trim(preg_replace('/>\s+</', '><', ob_get_clean()));\n")
37
  ;
31
  {
32
  $compiler
33
  ->addDebugInfo($this)
34
+ ;
35
+ if ($compiler->getEnvironment()->isDebug()) {
36
+ $compiler->write("ob_start();\n");
37
+ } else {
38
+ $compiler->write("ob_start(function () { return ''; });\n");
39
+ }
40
+ $compiler
41
  ->subcompile($this->getNode('body'))
42
  ->write("echo trim(preg_replace('/>\s+</', '><', ob_get_clean()));\n")
43
  ;
vendor/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php CHANGED
@@ -102,7 +102,7 @@ class SandboxNodeVisitor extends AbstractNodeVisitor
102
  if ($node instanceof ModuleNode) {
103
  $this->inAModule = false;
104
 
105
- $node->setNode('constructor_end', new Node([new CheckSecurityNode($this->filters, $this->tags, $this->functions), $node->getNode('display_start')]));
106
  } elseif ($this->inAModule) {
107
  if ($node instanceof PrintNode || $node instanceof SetNode) {
108
  $this->needsToStringWrap = false;
102
  if ($node instanceof ModuleNode) {
103
  $this->inAModule = false;
104
 
105
+ $node->getNode('constructor_end')->setNode('_security_check', new Node([new CheckSecurityNode($this->filters, $this->tags, $this->functions), $node->getNode('display_start')]));
106
  } elseif ($this->inAModule) {
107
  if ($node instanceof PrintNode || $node instanceof SetNode) {
108
  $this->needsToStringWrap = false;
vendor/twig/twig/src/Parser.php CHANGED
@@ -251,7 +251,7 @@ class Parser implements \Twig_ParserInterface
251
 
252
  public function peekBlockStack()
253
  {
254
- return $this->blockStack[\count($this->blockStack) - 1];
255
  }
256
 
257
  public function popBlockStack()
@@ -334,10 +334,18 @@ class Parser implements \Twig_ParserInterface
334
 
335
  public function getImportedSymbol($type, $alias)
336
  {
337
- foreach ($this->importedSymbols as $functions) {
338
- if (isset($functions[$type][$alias])) {
339
- return $functions[$type][$alias];
 
 
 
 
 
 
340
  }
 
 
341
  }
342
  }
343
 
251
 
252
  public function peekBlockStack()
253
  {
254
+ return isset($this->blockStack[\count($this->blockStack) - 1]) ? $this->blockStack[\count($this->blockStack) - 1] : null;
255
  }
256
 
257
  public function popBlockStack()
334
 
335
  public function getImportedSymbol($type, $alias)
336
  {
337
+ if (null !== $this->peekBlockStack()) {
338
+ foreach ($this->importedSymbols as $functions) {
339
+ if (isset($functions[$type][$alias])) {
340
+ if (\count($this->blockStack) > 1) {
341
+ return null;
342
+ }
343
+
344
+ return $functions[$type][$alias];
345
+ }
346
  }
347
+ } else {
348
+ return isset($this->importedSymbols[0][$type][$alias]) ? $this->importedSymbols[0][$type][$alias] : null;
349
  }
350
  }
351
 
vendor/twig/twig/src/Template.php CHANGED
@@ -253,7 +253,11 @@ abstract class Template implements \Twig_TemplateInterface
253
  */
254
  public function renderParentBlock($name, array $context, array $blocks = [])
255
  {
256
- ob_start(function () { return ''; });
 
 
 
 
257
  $this->displayParentBlock($name, $context, $blocks);
258
 
259
  return ob_get_clean();
@@ -274,7 +278,11 @@ abstract class Template implements \Twig_TemplateInterface
274
  */
275
  public function renderBlock($name, array $context, array $blocks = [], $useBlocks = true)
276
  {
277
- ob_start(function () { return ''; });
 
 
 
 
278
  $this->displayBlock($name, $context, $blocks, $useBlocks);
279
 
280
  return ob_get_clean();
@@ -417,7 +425,11 @@ abstract class Template implements \Twig_TemplateInterface
417
  public function render(array $context)
418
  {
419
  $level = ob_get_level();
420
- ob_start(function () { return ''; });
 
 
 
 
421
  try {
422
  $this->display($context);
423
  } catch (\Exception $e) {
253
  */
254
  public function renderParentBlock($name, array $context, array $blocks = [])
255
  {
256
+ if ($this->env->isDebug()) {
257
+ ob_start();
258
+ } else {
259
+ ob_start(function () { return ''; });
260
+ }
261
  $this->displayParentBlock($name, $context, $blocks);
262
 
263
  return ob_get_clean();
278
  */
279
  public function renderBlock($name, array $context, array $blocks = [], $useBlocks = true)
280
  {
281
+ if ($this->env->isDebug()) {
282
+ ob_start();
283
+ } else {
284
+ ob_start(function () { return ''; });
285
+ }
286
  $this->displayBlock($name, $context, $blocks, $useBlocks);
287
 
288
  return ob_get_clean();
425
  public function render(array $context)
426
  {
427
  $level = ob_get_level();
428
+ if ($this->env->isDebug()) {
429
+ ob_start();
430
+ } else {
431
+ ob_start(function () { return ''; });
432
+ }
433
  try {
434
  $this->display($context);
435
  } catch (\Exception $e) {
vendor/twig/twig/src/TemplateWrapper.php CHANGED
@@ -96,7 +96,11 @@ final class TemplateWrapper
96
  {
97
  $context = $this->env->mergeGlobals($context);
98
  $level = ob_get_level();
99
- ob_start(function () { return ''; });
 
 
 
 
100
  try {
101
  $this->template->displayBlock($name, $context);
102
  } catch (\Exception $e) {
96
  {
97
  $context = $this->env->mergeGlobals($context);
98
  $level = ob_get_level();
99
+ if ($this->env->isDebug()) {
100
+ ob_start();
101
+ } else {
102
+ ob_start(function () { return ''; });
103
+ }
104
  try {
105
  $this->template->displayBlock($name, $context);
106
  } catch (\Exception $e) {
vendor/twig/twig/src/TokenParser/ExtendsTokenParser.php CHANGED
@@ -29,8 +29,10 @@ class ExtendsTokenParser extends AbstractTokenParser
29
  {
30
  $stream = $this->parser->getStream();
31
 
32
- if (!$this->parser->isMainScope()) {
33
- throw new SyntaxError('Cannot extend from a block.', $token->getLine(), $stream->getSourceContext());
 
 
34
  }
35
 
36
  if (null !== $this->parser->getParent()) {
29
  {
30
  $stream = $this->parser->getStream();
31
 
32
+ if ($this->parser->peekBlockStack()) {
33
+ throw new SyntaxError('Cannot use "extend" in a block.', $token->getLine(), $stream->getSourceContext());
34
+ } elseif (!$this->parser->isMainScope()) {
35
+ throw new SyntaxError('Cannot use "extend" in a macro.', $token->getLine(), $stream->getSourceContext());
36
  }
37
 
38
  if (null !== $this->parser->getParent()) {
vendor/twig/twig/src/TokenParser/FromTokenParser.php CHANGED
@@ -29,7 +29,7 @@ class FromTokenParser extends AbstractTokenParser
29
  {
30
  $macro = $this->parser->getExpressionParser()->parseExpression();
31
  $stream = $this->parser->getStream();
32
- $stream->expect('import');
33
 
34
  $targets = [];
35
  do {
@@ -49,14 +49,15 @@ class FromTokenParser extends AbstractTokenParser
49
 
50
  $stream->expect(Token::BLOCK_END_TYPE);
51
 
52
- $node = new ImportNode($macro, new AssignNameExpression($this->parser->getVarName(), $token->getLine()), $token->getLine(), $this->getTag());
 
53
 
54
  foreach ($targets as $name => $alias) {
55
  if ($this->parser->isReservedMacroName($name)) {
56
  throw new SyntaxError(sprintf('"%s" cannot be an imported macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
57
  }
58
 
59
- $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var'));
60
  }
61
 
62
  return $node;
29
  {
30
  $macro = $this->parser->getExpressionParser()->parseExpression();
31
  $stream = $this->parser->getStream();
32
+ $stream->expect(Token::NAME_TYPE, 'import');
33
 
34
  $targets = [];
35
  do {
49
 
50
  $stream->expect(Token::BLOCK_END_TYPE);
51
 
52
+ $var = new AssignNameExpression($this->parser->getVarName(), $token->getLine());
53
+ $node = new ImportNode($macro, $var, $token->getLine(), $this->getTag());
54
 
55
  foreach ($targets as $name => $alias) {
56
  if ($this->parser->isReservedMacroName($name)) {
57
  throw new SyntaxError(sprintf('"%s" cannot be an imported macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
58
  }
59
 
60
+ $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $var);
61
  }
62
 
63
  return $node;
vendor/twig/twig/src/TokenParser/ImportTokenParser.php CHANGED
@@ -27,7 +27,7 @@ class ImportTokenParser extends AbstractTokenParser
27
  public function parse(Token $token)
28
  {
29
  $macro = $this->parser->getExpressionParser()->parseExpression();
30
- $this->parser->getStream()->expect('as');
31
  $var = new AssignNameExpression($this->parser->getStream()->expect(Token::NAME_TYPE)->getValue(), $token->getLine());
32
  $this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
33
 
27
  public function parse(Token $token)
28
  {
29
  $macro = $this->parser->getExpressionParser()->parseExpression();
30
+ $this->parser->getStream()->expect(Token::NAME_TYPE, 'as');
31
  $var = new AssignNameExpression($this->parser->getStream()->expect(Token::NAME_TYPE)->getValue(), $token->getLine());
32
  $this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
33
 
vendor/twig/twig/src/TokenStream.php CHANGED
@@ -97,9 +97,10 @@ class TokenStream
97
  $token = $this->tokens[$this->current];
98
  if (!$token->test($type, $value)) {
99
  $line = $token->getLine();
100
- throw new SyntaxError(sprintf('%sUnexpected token "%s" of value "%s" ("%s" expected%s).',
101
  $message ? $message.'. ' : '',
102
- Token::typeToEnglish($token->getType()), $token->getValue(),
 
103
  Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''),
104
  $line,
105
  $this->source
97
  $token = $this->tokens[$this->current];
98
  if (!$token->test($type, $value)) {
99
  $line = $token->getLine();
100
+ throw new SyntaxError(sprintf('%sUnexpected token "%s"%s ("%s" expected%s).',
101
  $message ? $message.'. ' : '',
102
+ Token::typeToEnglish($token->getType()),
103
+ $token->getValue() ? sprintf(' of value "%s"', $token->getValue()) : '',
104
  Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''),
105
  $line,
106
  $this->source
wp-rss-aggregator.php CHANGED
@@ -4,7 +4,7 @@
4
  * Plugin Name: WP RSS Aggregator
5
  * Plugin URI: https://www.wprssaggregator.com/#utm_source=wpadmin&utm_medium=plugin&utm_campaign=wpraplugin
6
  * Description: Imports and aggregates multiple RSS Feeds.
7
- * Version: 4.20
8
  * Author: RebelCode
9
  * Author URI: https://www.wprssaggregator.com
10
  * Text Domain: wprss
@@ -76,7 +76,7 @@ use RebelCode\Wpra\Core\Plugin;
76
 
77
  // Set the version number of the plugin.
78
  if( !defined( 'WPRSS_VERSION' ) )
79
- define( 'WPRSS_VERSION', '4.20' );
80
 
81
  if( !defined( 'WPRSS_WP_MIN_VERSION' ) )
82
  define( 'WPRSS_WP_MIN_VERSION', '4.8' );
4
  * Plugin Name: WP RSS Aggregator
5
  * Plugin URI: https://www.wprssaggregator.com/#utm_source=wpadmin&utm_medium=plugin&utm_campaign=wpraplugin
6
  * Description: Imports and aggregates multiple RSS Feeds.
7
+ * Version: 4.21
8
  * Author: RebelCode
9
  * Author URI: https://www.wprssaggregator.com
10
  * Text Domain: wprss
76
 
77
  // Set the version number of the plugin.
78
  if( !defined( 'WPRSS_VERSION' ) )
79
+ define( 'WPRSS_VERSION', '4.21' );
80
 
81
  if( !defined( 'WPRSS_WP_MIN_VERSION' ) )
82
  define( 'WPRSS_WP_MIN_VERSION', '4.8' );