Skip to content

Commit 770b335

Browse files
Merge branch 'development' of girish.github.com:Codeinwp/feedzy-rss-feeds into bugfix/pro/815
2 parents 22d3c83 + d6f868e commit 770b335

28 files changed

+2113
-37
lines changed

.DS_Store

-6 KB
Binary file not shown.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ cypress.env.json
1414
js/build
1515
/build
1616
artifacts
17+
.DS_Store

CHANGELOG.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,42 @@
1+
#### [Version 5.0.0](https://github.com/Codeinwp/feedzy-rss-feeds/compare/v4.4.16...v5.0.0) (2025-01-06)
2+
3+
### New Features
4+
- [Free] Created a new Feedzy Loop block that provides greater flexibility. This new block allows you to easily modify the design of feed items using the Gutenberg editor, giving you enhanced control over layout and styling.
5+
- [PRO] Auto-delete featured image after a number of days set up together with the post.
6+
- [PRO] Added the possibility to choose more, randomly selected fallback images for posts.
7+
- [PRO] Assign individual imports to specific authors (existing usernames) using the Feedzy UI.
8+
- [PRO] Allow actions to be used on custom fields in Feedzy import jobs. You can now translate, trim, search & replace, or even rephrase with AI custom fields that you import to your posts from different tags.
9+
- [PRO] Added the ability to export and upload import jobs. This feature helps with re-creating existing imports, transferring them to a different server where Feedzy is also used, and saves significant time.
10+
- [PRO] Global management for assigning imported posts to categories based on keywords used in titles with [#auto_categories].
11+
- [PRO] Added OpenRouter integration for enhanced connectivity, allowing users to utilize more large language models (LLMs) beyond OpenAI.
12+
- [PRO] Allowed cron settings to be configured per import job instead of globally.
13+
14+
### Improvements
15+
- [Free] Made the default tags created with new import actionable.
16+
- [Free] Improved the run_cron method to enhance compatibility and stability across various server setups.
17+
- [Free] Made the image URL an available option for use as a featured image. This enhancement allows you to use a direct URL of an online image in your import job instead of the [#item_image] tag, setting it as the featured image for imported posts.
18+
- [Free] Renamed Feed Categories to Feed Groups for better clarity.
19+
- [Free] Improved error logging next to each import job to provide more detailed insights.
20+
- [Free] Added regex and wildcard support in the Search and Replace action.
21+
- [Free] Use the Action Scheduler when available for better reliability.
22+
- [Free] Added a new integrations tab for managing service connections.
23+
- [PRO] Improved filtering systems for the import process and the Feedzy Loop block. With robust filtering options, you can include items matching any condition, filter by fields like title, description, or custom fields, and use operators like contains, equals, or regex for precise control.
24+
- [PRO] Improved the way duplicates are removed during imports [Option to filter duplicates by magic tags].
25+
- [PRO] Simplified the translation user experience by incorporating translations into the action tags.
26+
- [PRO] Added more OpenAI models for enhanced selection options.
27+
- [PRO] Created a prompt for passing parameters to OpenAI to generate featured images more accurately.
28+
- [PRO] Moved the license key field from General Settings to Feedzy Settings for better accessibility.
29+
30+
### Bug Fixes
31+
- [Free] Added the option to exclude the default category (ID not equal to 1) from being assigned to imported posts.
32+
- [Free] Fixed reappearing notices for a smoother user experience.
33+
- [Free] Updated the demo URL in the onboarding process.
34+
- [Free] Ensured that an author is always assigned to imported posts.
35+
- [PRO] Fixed the helper link to direct users to the correct OpenAI API key page.
36+
- [PRO] Fixed compatibility issues with certain third-party products when Feedzy External Image is used.
37+
- [PRO] Fixed a bug where content paraphrased with OpenAI returned quotes unexpectedly.
38+
- [PRO] Clarified that the PRO version requires the free plugin for seamless functionality.
39+
140
##### [Version 4.4.16](https://github.com/Codeinwp/feedzy-rss-feeds/compare/v4.4.15...v4.4.16) (2024-11-18)
241

342
- Fixed compatibility issue with WordPress 6.7, preventing the New Import button from showing up

css/feedzy-rss-feeds.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* feedzy-rss-feeds.css
33
* Feedzy RSS Feed
44
* Copyright: (c) 2016 Themeisle, themeisle.com
5-
* Version: 4.4.16
5+
* Version: 5.0.0
66
* Plugin Name: FEEDZY RSS Feeds
77
* Plugin URI: https://themeisle.com/plugins/feedzy-rss-feeds/
88
* Author: Themeisle

css/settings.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2558,4 +2558,4 @@ li.draggable-item .components-panel__body-toggle.components-button{
25582558
-webkit-transform: rotate(360deg);
25592559
transform:rotate(360deg);
25602560
}
2561-
}
2561+
}

feedzy-rss-feed.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Plugin Name: Feedzy RSS Feeds Lite
1616
* Plugin URI: https://themeisle.com/plugins/feedzy-rss-feeds/
1717
* Description: A small and lightweight RSS aggregator plugin. Fast and very easy to use, it allows you to aggregate multiple RSS feeds into your WordPress site through fully customizable shortcodes & widgets.
18-
* Version: 4.4.16
18+
* Version: 5.0.0
1919
* Author: Themeisle
2020
* Author URI: http://themeisle.com
2121
* License: GPL-2.0+

includes/admin/feedzy-rss-feeds-admin.php

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,24 +1850,8 @@ public function feedzy_block_editor_content( $wizard_data = array() ) {
18501850
return $post_content;
18511851
}
18521852

1853-
$feed_url = $wizard_data['feed'];
1854-
$feedzy_rest_url = get_rest_url( null, 'feedzy/v' . FEEDZY_REST_VERSION . '/feed/' );
1855-
$response = wp_remote_post(
1856-
$feedzy_rest_url,
1857-
array(
1858-
'timeout' => 100,
1859-
'body' => array(
1860-
'url' => array( $feed_url ),
1861-
),
1862-
)
1863-
);
1864-
if ( ! is_wp_error( $response ) ) {
1865-
$data = wp_remote_retrieve_body( $response );
1866-
$data = json_decode( $data );
1867-
$data->feeds = $feed_url;
1868-
$data = wp_json_encode( $data );
1869-
$post_content = '<!-- wp:feedzy-rss-feeds/feedzy-block ' . $data . ' /-->';
1870-
}
1853+
$feed_url = $wizard_data['feed'];
1854+
$post_content = '<!-- wp:feedzy-rss-feeds/loop {"feed":{"type":"url","source":["' . esc_url( $feed_url ) . '"]}} --><!-- wp:group {"style":{"spacing":{"padding":{"top":"var:preset|spacing|30","bottom":"var:preset|spacing|30","left":"var:preset|spacing|30","right":"var:preset|spacing|30"},"margin":{"top":"var:preset|spacing|30","bottom":"var:preset|spacing|30"}}},"layout":{"type":"constrained"}} --><div class="wp-block-group" style="margin-top:var(--wp--preset--spacing--30);margin-bottom:var(--wp--preset--spacing--30);padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)"><!-- wp:image --><figure class="wp-block-image"><a href="{{feedzy_url}}"><img src="' . esc_url( FEEDZY_ABSURL . 'img/feedzy.svg' ) . '" alt="{{feedzy_title}}"/></a></figure><!-- /wp:image --><!-- wp:paragraph --><p><a href="{{feedzy_url}}">{{feedzy_title}}</a></p><!-- /wp:paragraph --><!-- wp:paragraph {"fontSize":"medium"} --><p class="has-medium-font-size">{{feedzy_meta}}</p><!-- /wp:paragraph --><!-- wp:paragraph {"fontSize":"small"} --><p class="has-small-font-size">{{feedzy_description}}</p><!-- /wp:paragraph --></div><!-- /wp:group --><!-- /wp:feedzy-rss-feeds/loop -->';
18711855
return $post_content;
18721856
}
18731857

includes/feedzy-rss-feeds.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public static function instance() {
104104
*/
105105
public function init() {
106106
self::$plugin_name = 'feedzy-rss-feeds';
107-
self::$version = '4.4.16';
107+
self::$version = '5.0.0';
108108
self::$instance->load_dependencies();
109109
self::$instance->define_admin_hooks();
110110
}
@@ -285,6 +285,7 @@ function () {
285285
function () {
286286
if ( function_exists( 'register_block_type' ) ) {
287287
Feedzy_Rss_Feeds_Gutenberg_Block::get_instance();
288+
Feedzy_Rss_Feeds_Loop_Block::get_instance();
288289
}
289290
}
290291
);
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
<?php
2+
/**
3+
* Class for functionalities related to Loop block.
4+
*
5+
* Defines the functions that need to be used for Loop block,
6+
* and REST router.
7+
*
8+
* @package feedzy-rss-feeds
9+
* @subpackage feedzy-rss-feeds/includes/guteneberg
10+
* @author Themeisle <[email protected]>
11+
*/
12+
class Feedzy_Rss_Feeds_Loop_Block {
13+
14+
/**
15+
* A reference to an instance of this class.
16+
*
17+
* @var Feedzy_Rss_Feeds_Loop_Block The one Feedzy_Rss_Feeds_Loop_Block instance.
18+
*/
19+
private static $instance;
20+
21+
/**
22+
* Instance of Feedzy_Rss_Feeds_Admin class.
23+
*
24+
* @var Feedzy_Rss_Feeds_Admin $admin The Feedzy_Rss_Feeds_Admin instance.
25+
*/
26+
private $admin;
27+
28+
/**
29+
* Feedzy RSS Feeds plugin version.
30+
*
31+
* @var string $version The current version of the plugin.
32+
*/
33+
protected $version;
34+
35+
/**
36+
* Returns an instance of this class.
37+
*/
38+
public static function get_instance() {
39+
if ( null === self::$instance ) {
40+
self::$instance = new Feedzy_Rss_Feeds_Loop_Block();
41+
}
42+
return self::$instance;
43+
}
44+
45+
/**
46+
* Initializes the plugin by setting filters and administration functions.
47+
*/
48+
private function __construct() {
49+
$this->version = Feedzy_Rss_Feeds::get_version();
50+
$this->admin = Feedzy_Rss_Feeds::instance()->get_admin();
51+
add_action( 'init', array( $this, 'register_block' ) );
52+
add_filter( 'feedzy_loop_item', array( $this, 'apply_magic_tags' ), 10, 2 );
53+
}
54+
55+
/**
56+
* Register Block
57+
*/
58+
public function register_block() {
59+
$metadata_file = trailingslashit( FEEDZY_ABSPATH ) . '/build/loop/block.json';
60+
register_block_type_from_metadata(
61+
$metadata_file,
62+
array(
63+
'render_callback' => array( $this, 'render_callback' ),
64+
)
65+
);
66+
67+
wp_set_script_translations( 'feedzy-rss-feeds-loop-editor-script', 'feedzy-rss-feeds' );
68+
69+
// Pass in REST URL
70+
wp_localize_script(
71+
'feedzy-rss-feeds-loop-editor-script',
72+
'feedzyData',
73+
array(
74+
'imagepath' => esc_url( FEEDZY_ABSURL . 'img/' ),
75+
'defaultImage' => esc_url( FEEDZY_ABSURL . 'img/feedzy.svg' ),
76+
'isPro' => feedzy_is_pro(),
77+
)
78+
);
79+
80+
wp_localize_script(
81+
'feedzy-rss-feeds-loop-editor-script',
82+
'feedzyConditionsData',
83+
apply_filters(
84+
'feedzy_conditions_data',
85+
array(
86+
'isPro' => feedzy_is_pro(),
87+
'operators' => Feedzy_Rss_Feeds_Conditions::get_operators(),
88+
)
89+
)
90+
);
91+
}
92+
93+
/**
94+
* Render Callback
95+
*
96+
* @param array $attributes The block attributes.
97+
* @param string $content The block content.
98+
* @return string The block content.
99+
*/
100+
public function render_callback( $attributes, $content ) {
101+
$content = empty( $content ) ? ( $attributes['innerBlocksContent'] ?? '' ) : $content;
102+
$is_preview = isset( $attributes['innerBlocksContent'] ) && ! empty( $attributes['innerBlocksContent'] );
103+
$feed_urls = array();
104+
105+
if ( isset( $attributes['feed']['type'] ) && 'group' === $attributes['feed']['type'] && isset( $attributes['feed']['source'] ) && is_numeric( $attributes['feed']['source'] ) ) {
106+
$group = $attributes['feed']['source'];
107+
$value = get_post_meta( $group, 'feedzy_category_feed', true );
108+
$value = trim( $value );
109+
$feed_urls = !empty( $value ) ? explode( ',', $value ) : array();
110+
}
111+
112+
if ( isset( $attributes['feed']['type'] ) && 'url' === $attributes['feed']['type'] && isset( $attributes['feed']['source'] ) && is_array( $attributes['feed']['source'] ) ) {
113+
$feed_urls = $attributes['feed']['source'];
114+
}
115+
116+
if ( empty( $feed_urls ) ) {
117+
return '<div>' . esc_html__( 'No feeds to display', 'feedzy-rss-feeds' ) . '</div>';
118+
}
119+
120+
$column_count = isset($attributes['layout']) && isset($attributes['layout']['columnCount']) && !empty($attributes['layout']['columnCount']) ? $attributes['layout']['columnCount'] : 1;
121+
122+
$default_query = array(
123+
'max' => 5,
124+
'sort' => 'default',
125+
'refresh' => '12_hours',
126+
);
127+
128+
$query = isset( $attributes['query'] ) ? wp_parse_args( $attributes['query'], $default_query ) : $default_query;
129+
$filters = isset( $attributes['conditions'] ) ? $attributes['conditions'] : array();
130+
131+
$options = array(
132+
'feeds' => implode( ',', $feed_urls ),
133+
'max' => $query['max'],
134+
'sort' => $query['sort'],
135+
'offset' => 0,
136+
'target' => '_blank',
137+
'keywords_ban' => '',
138+
'columns' => '1',
139+
'thumb' => 'auto',
140+
'default' => '',
141+
'title' => '',
142+
'meta' => 'yes',
143+
'multiple_meta' => 'no',
144+
'summary' => 'yes',
145+
'summarylength' => '',
146+
'filters' => wp_json_encode( $filters ),
147+
);
148+
149+
$sizes = array(
150+
'width' => 300,
151+
'height' => 300,
152+
);
153+
154+
$feed = $this->admin->fetch_feed( $feed_urls, $query['refresh'], $options );
155+
156+
if ( isset( $feed->error ) && ! empty( $feed->error ) ) {
157+
return '<div>' . esc_html__( 'An error occurred while fetching the feed.', 'feedzy-rss-feeds' ) . '</div>';
158+
}
159+
160+
$feed_items = apply_filters( 'feedzy_get_feed_array', array(), $options, $feed, implode( ',', $feed_urls ), $sizes );
161+
162+
if ( empty( $feed_items ) ) {
163+
return '<div>' . esc_html__( 'No items to display.', 'feedzy-rss-feeds' ) . '</div>';
164+
}
165+
166+
$loop = '';
167+
168+
foreach ($feed_items as $key => $item) {
169+
$loop .= apply_filters( 'feedzy_loop_item', $content, $item );
170+
}
171+
172+
return sprintf(
173+
'<div %1$s>%2$s</div>',
174+
$wrapper_attributes = get_block_wrapper_attributes( array(
175+
'class' => 'feedzy-loop-columns-' . $column_count,
176+
) ),
177+
$loop
178+
);
179+
}
180+
181+
/**
182+
* Magic Tags Replacement.
183+
*
184+
* @param string $content The content.
185+
*
186+
* @return string The content.
187+
*/
188+
public function apply_magic_tags( $content, $item ) {
189+
$pattern = '/\{\{feedzy_([^}]+)\}\}/';
190+
$content = str_replace(
191+
array(
192+
FEEDZY_ABSURL . 'img/feedzy.svg',
193+
'http://{{feedzy_url}}'
194+
),
195+
array(
196+
'{{feedzy_image}}',
197+
'{{feedzy_url}}'
198+
),
199+
$content
200+
);
201+
202+
return preg_replace_callback( $pattern, function( $matches ) use ( $item ) {
203+
return isset( $matches[1] ) ? $this->get_value( $matches[1], $item ) : '';
204+
}, $content );
205+
}
206+
207+
/**
208+
* Get Dynamic Value.
209+
*
210+
* @param string $key The key.
211+
* @param array $item Feed item.
212+
*
213+
* @return string The value.
214+
*/
215+
public function get_value( $key, $item ) {
216+
switch ( $key ) {
217+
case 'title':
218+
return isset( $item['item_title'] ) ? $item['item_title'] : '';
219+
case 'url':
220+
return isset( $item['item_url'] ) ? $item['item_url'] : '';
221+
case 'date':
222+
$item_date = isset( $item['item_date'] ) ? wp_date( get_option( 'date_format' ), $item['item_date'] ) : '';
223+
return $item_date;
224+
case 'time':
225+
$item_date = isset( $item['item_date'] ) ? wp_date( get_option( 'time_format' ), $item['item_date'] ) : '';
226+
return $item_date;
227+
case 'datetime':
228+
$item_date = isset( $item['item_date'] ) ? wp_date( get_option( 'date_format' ), $item['item_date'] ) : '';
229+
$item_time = isset( $item['item_date'] ) ? wp_date( get_option( 'time_format' ), $item['item_date'] ) : '';
230+
/* translators: 1: date, 2: time */
231+
$datetime = sprintf( __( '%1$s at %2$s', 'feedzy-rss-feeds' ), $item_date, $item_time );
232+
return $datetime;
233+
case 'author':
234+
if ( isset( $item['item_author'] ) && is_string( $item['item_author'] ) ) {
235+
return $item['item_author'];
236+
} elseif ( isset( $item['item_author'] ) && is_object( $item['item_author'] ) ) {
237+
return $item['item_author']->get_name();
238+
}
239+
return '';
240+
case 'description':
241+
return isset( $item['item_description'] ) ? $item['item_description'] : '';
242+
case 'content':
243+
return isset( $item['item_content'] ) ? $item['item_content'] : '';
244+
case 'meta':
245+
return isset( $item['item_meta'] ) ? $item['item_meta'] : '';
246+
case 'categories':
247+
return isset( $item['item_categories'] ) ? $item['item_categories'] : '';
248+
case 'image':
249+
$settings = apply_filters( 'feedzy_get_settings', array() );
250+
if ( $settings && ! empty( $settings['general']['default-thumbnail-id'] ) ) {
251+
$default_img = wp_get_attachment_image_src( $settings['general']['default-thumbnail-id'], 'full' );
252+
$default_img = ! empty( $default_img ) ? reset( $default_img ) : '';
253+
} else {
254+
$default_img = FEEDZY_ABSURL . 'img/feedzy.svg';
255+
}
256+
257+
return isset( $item['item_img_path'] ) ? $item['item_img_path'] : $default_img;
258+
case 'media':
259+
return isset( $item['item_media']['src'] ) ? $item['item_media']['src'] : '';
260+
case 'price':
261+
return isset( $item['item_price'] ) ? $item['item_price'] : '';
262+
case 'source':
263+
return isset( $item['item_source'] ) ? $item['item_source'] : '';
264+
default:
265+
return '';
266+
}
267+
}
268+
}

0 commit comments

Comments
 (0)