Skip to content

Commit

Permalink
Merge branch 'development' of girish.github.com:Codeinwp/feedzy-rss-f…
Browse files Browse the repository at this point in the history
…eeds into bugfix/pro/815
  • Loading branch information
girishpanchal30 committed Jan 9, 2025
2 parents 22d3c83 + d6f868e commit 770b335
Show file tree
Hide file tree
Showing 28 changed files with 2,113 additions and 37 deletions.
Binary file removed .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ cypress.env.json
js/build
/build
artifacts
.DS_Store
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,42 @@
#### [Version 5.0.0](https://github.com/Codeinwp/feedzy-rss-feeds/compare/v4.4.16...v5.0.0) (2025-01-06)

### New Features
- [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.
- [PRO] Auto-delete featured image after a number of days set up together with the post.
- [PRO] Added the possibility to choose more, randomly selected fallback images for posts.
- [PRO] Assign individual imports to specific authors (existing usernames) using the Feedzy UI.
- [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.
- [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.
- [PRO] Global management for assigning imported posts to categories based on keywords used in titles with [#auto_categories].
- [PRO] Added OpenRouter integration for enhanced connectivity, allowing users to utilize more large language models (LLMs) beyond OpenAI.
- [PRO] Allowed cron settings to be configured per import job instead of globally.

### Improvements
- [Free] Made the default tags created with new import actionable.
- [Free] Improved the run_cron method to enhance compatibility and stability across various server setups.
- [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.
- [Free] Renamed Feed Categories to Feed Groups for better clarity.
- [Free] Improved error logging next to each import job to provide more detailed insights.
- [Free] Added regex and wildcard support in the Search and Replace action.
- [Free] Use the Action Scheduler when available for better reliability.
- [Free] Added a new integrations tab for managing service connections.
- [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.
- [PRO] Improved the way duplicates are removed during imports [Option to filter duplicates by magic tags].
- [PRO] Simplified the translation user experience by incorporating translations into the action tags.
- [PRO] Added more OpenAI models for enhanced selection options.
- [PRO] Created a prompt for passing parameters to OpenAI to generate featured images more accurately.
- [PRO] Moved the license key field from General Settings to Feedzy Settings for better accessibility.

### Bug Fixes
- [Free] Added the option to exclude the default category (ID not equal to 1) from being assigned to imported posts.
- [Free] Fixed reappearing notices for a smoother user experience.
- [Free] Updated the demo URL in the onboarding process.
- [Free] Ensured that an author is always assigned to imported posts.
- [PRO] Fixed the helper link to direct users to the correct OpenAI API key page.
- [PRO] Fixed compatibility issues with certain third-party products when Feedzy External Image is used.
- [PRO] Fixed a bug where content paraphrased with OpenAI returned quotes unexpectedly.
- [PRO] Clarified that the PRO version requires the free plugin for seamless functionality.

##### [Version 4.4.16](https://github.com/Codeinwp/feedzy-rss-feeds/compare/v4.4.15...v4.4.16) (2024-11-18)

- Fixed compatibility issue with WordPress 6.7, preventing the New Import button from showing up
Expand Down
2 changes: 1 addition & 1 deletion css/feedzy-rss-feeds.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* feedzy-rss-feeds.css
* Feedzy RSS Feed
* Copyright: (c) 2016 Themeisle, themeisle.com
* Version: 4.4.16
* Version: 5.0.0
* Plugin Name: FEEDZY RSS Feeds
* Plugin URI: https://themeisle.com/plugins/feedzy-rss-feeds/
* Author: Themeisle
Expand Down
2 changes: 1 addition & 1 deletion css/settings.css
Original file line number Diff line number Diff line change
Expand Up @@ -2558,4 +2558,4 @@ li.draggable-item .components-panel__body-toggle.components-button{
-webkit-transform: rotate(360deg);
transform:rotate(360deg);
}
}
}
2 changes: 1 addition & 1 deletion feedzy-rss-feed.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* Plugin Name: Feedzy RSS Feeds Lite
* Plugin URI: https://themeisle.com/plugins/feedzy-rss-feeds/
* 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.
* Version: 4.4.16
* Version: 5.0.0
* Author: Themeisle
* Author URI: http://themeisle.com
* License: GPL-2.0+
Expand Down
20 changes: 2 additions & 18 deletions includes/admin/feedzy-rss-feeds-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -1850,24 +1850,8 @@ public function feedzy_block_editor_content( $wizard_data = array() ) {
return $post_content;
}

$feed_url = $wizard_data['feed'];
$feedzy_rest_url = get_rest_url( null, 'feedzy/v' . FEEDZY_REST_VERSION . '/feed/' );
$response = wp_remote_post(
$feedzy_rest_url,
array(
'timeout' => 100,
'body' => array(
'url' => array( $feed_url ),
),
)
);
if ( ! is_wp_error( $response ) ) {
$data = wp_remote_retrieve_body( $response );
$data = json_decode( $data );
$data->feeds = $feed_url;
$data = wp_json_encode( $data );
$post_content = '<!-- wp:feedzy-rss-feeds/feedzy-block ' . $data . ' /-->';
}
$feed_url = $wizard_data['feed'];
$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 -->';
return $post_content;
}

Expand Down
3 changes: 2 additions & 1 deletion includes/feedzy-rss-feeds.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public static function instance() {
*/
public function init() {
self::$plugin_name = 'feedzy-rss-feeds';
self::$version = '4.4.16';
self::$version = '5.0.0';
self::$instance->load_dependencies();
self::$instance->define_admin_hooks();
}
Expand Down Expand Up @@ -285,6 +285,7 @@ function () {
function () {
if ( function_exists( 'register_block_type' ) ) {
Feedzy_Rss_Feeds_Gutenberg_Block::get_instance();
Feedzy_Rss_Feeds_Loop_Block::get_instance();
}
}
);
Expand Down
268 changes: 268 additions & 0 deletions includes/gutenberg/feedzy-rss-feeds-loop-block.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
<?php
/**
* Class for functionalities related to Loop block.
*
* Defines the functions that need to be used for Loop block,
* and REST router.
*
* @package feedzy-rss-feeds
* @subpackage feedzy-rss-feeds/includes/guteneberg
* @author Themeisle <[email protected]>
*/
class Feedzy_Rss_Feeds_Loop_Block {

/**
* A reference to an instance of this class.
*
* @var Feedzy_Rss_Feeds_Loop_Block The one Feedzy_Rss_Feeds_Loop_Block instance.
*/
private static $instance;

/**
* Instance of Feedzy_Rss_Feeds_Admin class.
*
* @var Feedzy_Rss_Feeds_Admin $admin The Feedzy_Rss_Feeds_Admin instance.
*/
private $admin;

/**
* Feedzy RSS Feeds plugin version.
*
* @var string $version The current version of the plugin.
*/
protected $version;

/**
* Returns an instance of this class.
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new Feedzy_Rss_Feeds_Loop_Block();
}
return self::$instance;
}

/**
* Initializes the plugin by setting filters and administration functions.
*/
private function __construct() {
$this->version = Feedzy_Rss_Feeds::get_version();
$this->admin = Feedzy_Rss_Feeds::instance()->get_admin();
add_action( 'init', array( $this, 'register_block' ) );
add_filter( 'feedzy_loop_item', array( $this, 'apply_magic_tags' ), 10, 2 );
}

/**
* Register Block
*/
public function register_block() {
$metadata_file = trailingslashit( FEEDZY_ABSPATH ) . '/build/loop/block.json';
register_block_type_from_metadata(
$metadata_file,
array(
'render_callback' => array( $this, 'render_callback' ),
)
);

wp_set_script_translations( 'feedzy-rss-feeds-loop-editor-script', 'feedzy-rss-feeds' );

// Pass in REST URL
wp_localize_script(
'feedzy-rss-feeds-loop-editor-script',
'feedzyData',
array(
'imagepath' => esc_url( FEEDZY_ABSURL . 'img/' ),
'defaultImage' => esc_url( FEEDZY_ABSURL . 'img/feedzy.svg' ),
'isPro' => feedzy_is_pro(),
)
);

wp_localize_script(
'feedzy-rss-feeds-loop-editor-script',
'feedzyConditionsData',
apply_filters(
'feedzy_conditions_data',
array(
'isPro' => feedzy_is_pro(),
'operators' => Feedzy_Rss_Feeds_Conditions::get_operators(),
)
)
);
}

/**
* Render Callback
*
* @param array $attributes The block attributes.
* @param string $content The block content.
* @return string The block content.
*/
public function render_callback( $attributes, $content ) {
$content = empty( $content ) ? ( $attributes['innerBlocksContent'] ?? '' ) : $content;
$is_preview = isset( $attributes['innerBlocksContent'] ) && ! empty( $attributes['innerBlocksContent'] );
$feed_urls = array();

if ( isset( $attributes['feed']['type'] ) && 'group' === $attributes['feed']['type'] && isset( $attributes['feed']['source'] ) && is_numeric( $attributes['feed']['source'] ) ) {
$group = $attributes['feed']['source'];
$value = get_post_meta( $group, 'feedzy_category_feed', true );
$value = trim( $value );
$feed_urls = !empty( $value ) ? explode( ',', $value ) : array();
}

if ( isset( $attributes['feed']['type'] ) && 'url' === $attributes['feed']['type'] && isset( $attributes['feed']['source'] ) && is_array( $attributes['feed']['source'] ) ) {
$feed_urls = $attributes['feed']['source'];
}

if ( empty( $feed_urls ) ) {
return '<div>' . esc_html__( 'No feeds to display', 'feedzy-rss-feeds' ) . '</div>';
}

$column_count = isset($attributes['layout']) && isset($attributes['layout']['columnCount']) && !empty($attributes['layout']['columnCount']) ? $attributes['layout']['columnCount'] : 1;

$default_query = array(
'max' => 5,
'sort' => 'default',
'refresh' => '12_hours',
);

$query = isset( $attributes['query'] ) ? wp_parse_args( $attributes['query'], $default_query ) : $default_query;
$filters = isset( $attributes['conditions'] ) ? $attributes['conditions'] : array();

$options = array(
'feeds' => implode( ',', $feed_urls ),
'max' => $query['max'],
'sort' => $query['sort'],
'offset' => 0,
'target' => '_blank',
'keywords_ban' => '',
'columns' => '1',
'thumb' => 'auto',
'default' => '',
'title' => '',
'meta' => 'yes',
'multiple_meta' => 'no',
'summary' => 'yes',
'summarylength' => '',
'filters' => wp_json_encode( $filters ),
);

$sizes = array(
'width' => 300,
'height' => 300,
);

$feed = $this->admin->fetch_feed( $feed_urls, $query['refresh'], $options );

if ( isset( $feed->error ) && ! empty( $feed->error ) ) {
return '<div>' . esc_html__( 'An error occurred while fetching the feed.', 'feedzy-rss-feeds' ) . '</div>';
}

$feed_items = apply_filters( 'feedzy_get_feed_array', array(), $options, $feed, implode( ',', $feed_urls ), $sizes );

if ( empty( $feed_items ) ) {
return '<div>' . esc_html__( 'No items to display.', 'feedzy-rss-feeds' ) . '</div>';
}

$loop = '';

foreach ($feed_items as $key => $item) {
$loop .= apply_filters( 'feedzy_loop_item', $content, $item );
}

return sprintf(
'<div %1$s>%2$s</div>',
$wrapper_attributes = get_block_wrapper_attributes( array(
'class' => 'feedzy-loop-columns-' . $column_count,
) ),
$loop
);
}

/**
* Magic Tags Replacement.
*
* @param string $content The content.
*
* @return string The content.
*/
public function apply_magic_tags( $content, $item ) {
$pattern = '/\{\{feedzy_([^}]+)\}\}/';
$content = str_replace(
array(
FEEDZY_ABSURL . 'img/feedzy.svg',
'http://{{feedzy_url}}'
),
array(
'{{feedzy_image}}',
'{{feedzy_url}}'
),
$content
);

return preg_replace_callback( $pattern, function( $matches ) use ( $item ) {
return isset( $matches[1] ) ? $this->get_value( $matches[1], $item ) : '';
}, $content );
}

/**
* Get Dynamic Value.
*
* @param string $key The key.
* @param array $item Feed item.
*
* @return string The value.
*/
public function get_value( $key, $item ) {
switch ( $key ) {
case 'title':
return isset( $item['item_title'] ) ? $item['item_title'] : '';
case 'url':
return isset( $item['item_url'] ) ? $item['item_url'] : '';
case 'date':
$item_date = isset( $item['item_date'] ) ? wp_date( get_option( 'date_format' ), $item['item_date'] ) : '';
return $item_date;
case 'time':
$item_date = isset( $item['item_date'] ) ? wp_date( get_option( 'time_format' ), $item['item_date'] ) : '';
return $item_date;
case 'datetime':
$item_date = isset( $item['item_date'] ) ? wp_date( get_option( 'date_format' ), $item['item_date'] ) : '';
$item_time = isset( $item['item_date'] ) ? wp_date( get_option( 'time_format' ), $item['item_date'] ) : '';
/* translators: 1: date, 2: time */
$datetime = sprintf( __( '%1$s at %2$s', 'feedzy-rss-feeds' ), $item_date, $item_time );
return $datetime;
case 'author':
if ( isset( $item['item_author'] ) && is_string( $item['item_author'] ) ) {
return $item['item_author'];
} elseif ( isset( $item['item_author'] ) && is_object( $item['item_author'] ) ) {
return $item['item_author']->get_name();
}
return '';
case 'description':
return isset( $item['item_description'] ) ? $item['item_description'] : '';
case 'content':
return isset( $item['item_content'] ) ? $item['item_content'] : '';
case 'meta':
return isset( $item['item_meta'] ) ? $item['item_meta'] : '';
case 'categories':
return isset( $item['item_categories'] ) ? $item['item_categories'] : '';
case 'image':
$settings = apply_filters( 'feedzy_get_settings', array() );
if ( $settings && ! empty( $settings['general']['default-thumbnail-id'] ) ) {
$default_img = wp_get_attachment_image_src( $settings['general']['default-thumbnail-id'], 'full' );
$default_img = ! empty( $default_img ) ? reset( $default_img ) : '';
} else {
$default_img = FEEDZY_ABSURL . 'img/feedzy.svg';
}

return isset( $item['item_img_path'] ) ? $item['item_img_path'] : $default_img;
case 'media':
return isset( $item['item_media']['src'] ) ? $item['item_media']['src'] : '';
case 'price':
return isset( $item['item_price'] ) ? $item['item_price'] : '';
case 'source':
return isset( $item['item_source'] ) ? $item['item_source'] : '';
default:
return '';
}
}
}
Loading

0 comments on commit 770b335

Please sign in to comment.