Skip to content

Improved feed group UX #1108

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions css/settings.css
Original file line number Diff line number Diff line change
Expand Up @@ -2559,6 +2559,29 @@ li.draggable-item .components-panel__body-toggle.components-button{
border-bottom: 0;
padding: 24px 0 0;
}
.validate-feeds-actions {
display: flex;;
}
.validate-feeds-actions .spinner:not(.is-active) {
display: none;
}
.validate-feeds-actions .spinner.is-active {
display: inline-block;
}
.feedzy-preview-list {
padding-left: 15px;
}
.feedzy-preview-list li {
list-style: disc;
}
.feedzy-preview-list li a {
text-decoration: none;
}
.feedzy-preview-list li time {
font-size: 11px;
font-weight: 500;
color: #757575;
}
@-webkit-keyframes spin {
100% { -webkit-transform: rotate(360deg); }
}
Expand Down
8 changes: 4 additions & 4 deletions includes/abstract/feedzy-rss-feeds-admin-abstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -1598,7 +1598,7 @@ private function get_feed_item_filter( $sc, $sizes, $item, $feed_url, $index, $i
'item_url_follow' => isset( $sc['follow'] ) && 'yes' === $sc['follow'] ? 'nofollow' : '',
'item_url_title' => $item->get_title(),
'item_img' => $content_thumb,
'item_img_path' => $this->feedzy_retrieve_image( $item, $sc ),
'item_img_path' => isset( $sc['thumb'] ) && ( 'yes' === $sc['thumb'] || 'auto' === $sc['thumb'] ) ? $this->feedzy_retrieve_image( $item, $sc ) : '',
'item_title' => $content_title,
'item_content_class' => 'rss_content',
'item_content_style' => '',
Expand Down Expand Up @@ -1866,9 +1866,9 @@ public function feedzy_image_encode( $img_url ) {
// Check if img url is set as an URL parameter.
$url_tab = wp_parse_url( $img_url );
if ( isset( $url_tab['query'] ) ) {
preg_match_all( '/(http|https):\/\/[^ ]+(\.gif|\.GIF|\.jpg|\.JPG|\.jpeg|\.JPEG|\.png|\.PNG)/', $url_tab['query'], $img_url );
if ( isset( $img_url[0][0] ) ) {
$img_url = $img_url[0][0];
preg_match_all( '/(http|https):\/\/[^ ]+(\.gif|\.GIF|\.jpg|\.JPG|\.jpeg|\.JPEG|\.png|\.PNG)/', $url_tab['query'], $matches );
if ( isset( $matches[0][0] ) ) {
$img_url = $matches[0][0];
}
}

Expand Down
162 changes: 160 additions & 2 deletions includes/admin/feedzy-rss-feeds-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,19 @@ public function add_feedzy_post_type_metaboxes() {
'low'
);
}

if ( 'publish' === get_post_status() ) {
add_meta_box(
'feedzy_category_feeds_preview',
__( 'Feed Preview', 'feedzy-rss-feeds' ),
array(
$this,
'render_feed_preview',
),
'feedzy_categories',
'side'
);
}
}

/**
Expand Down Expand Up @@ -750,12 +763,106 @@ public function feedzy_category_feed() {
)
. '</strong><br/><br/>'
. $invalid
. '<textarea name="feedzy_category_feed" rows="15" class="widefat" placeholder="' . __( 'Place your URL\'s here followed by a comma.', 'feedzy-rss-feeds' ) . '" >' . $feed . '</textarea>
<p><a href="' . esc_url( 'https://docs.themeisle.com/article/1119-feedzy-rss-feeds-documentation#categories' ) . '" target="_blank">' . __( 'Learn how to organize feeds in Groups', 'feedzy-rss-feeds' ) . '</a></p>
. '<textarea name="feedzy_category_feed" rows="10" class="widefat" placeholder="themeisle.com/blog/feed/, https://wptavern.com/feed/, https://www.wpbeginner.com/feed/, https://wpshout.com/feed/, https://planet.wordpress.org/feed/" >' . $feed . '</textarea>
<div class="validate-feeds-actions">
<span class="spinner"></span>
<button class="button validate-feeds" ' . esc_attr( empty( $feed ) ? 'disabled' : '' ) . '>' . __( 'Validate & Remove Invalid Feeds', 'feedzy-rss-feeds' ) . '</button>
</div>
';
echo wp_kses( $output, apply_filters( 'feedzy_wp_kses_allowed_html', array() ) );
}

/**
* Render the feed preview metabox.
*
* @return void
*/
public function render_feed_preview() {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is used to render the feed preview in the sidebar. Since it's not an AJAX or form submission context, check_ajax_referer() doesn't apply.

if ( isset( $_GET['action'] ) && 'edit' !== $_GET['action'] ) {
return;
}
$feeds = get_post_meta( get_the_ID(), 'feedzy_category_feed', true );
$feed_urls = $this->normalize_urls( $feeds );
if ( empty( $feed_urls ) ) {
echo '<p>' . esc_html__( 'No feeds available for preview.', 'feedzy-rss-feeds' ) . '</p>';
return;
}
$shortcode = array(
'sort' => 'date_desc',
'thumb' => 'no',
'max' => 0,
);
$atts = $this->get_short_code_attributes( $shortcode );
$atts = $this->sanitize_attr( $atts, $feed_urls );
$sizes = array(
'width' => 0,
'height' => 0,
);
$feed = $this->fetch_feed( $feed_urls, $atts['refresh'], $atts );
$feed_items = apply_filters( 'feedzy_get_feed_array', array(), $atts, $feed, $feed_urls, $sizes );
$total_items = count( $feed_items );

$max_items_preview_count = 5;
$preview_feed_items = array_slice( $feed_items, 0, $max_items_preview_count );
?>
<strong>
<?php
echo esc_html(
sprintf(
// translators: %1$s the number of maximum displayed items, %2$s is the total number of items available in the feed.
__( 'Latest %1$s feed items out of %2$s available from', 'feedzy-rss-feeds' ),
$max_items_preview_count,
$total_items
)
);
?>
</strong>
<div>
<ul class="feedzy-preview-list">
<?php
foreach ( $preview_feed_items as $item ) {
$datetime = date_i18n( 'c', $item['item_date'] );
$time_content = date_i18n( 'Y-m-d', $item['item_date'] );
?>
<li <?php echo esc_attr( $item['itemAttr'] ); ?>>
<a href="<?php echo esc_url( $item['item_url'] ); ?>" target="_blank">
<?php echo esc_html( $item['item_title'] ); ?>
</a>
<br/>
<time
datetime="<?php echo esc_attr( $datetime ); ?>"
content="<?php echo esc_attr( $time_content ); ?>"
>
<?php echo esc_html( $this->get_humman_readable_time_diff( $item['item_date'] ) ); ?>
</time>
</li>
<?php
}
?>
</ul>
</div>
<?php
}

/**
* Get human readable time difference.
*
* @param int $item_publish_time The item publish time.
*
* @return string
*/
private function get_humman_readable_time_diff( $item_publish_time ) {
$array = current_datetime();
$localtime = $array->getTimestamp() + $array->getOffset();

return sprintf(
// translators: %s is the time difference.
__( '%s ago', 'feedzy-rss-feeds' ),
human_time_diff( $item_publish_time, $localtime )
);
}

/**
* Utility method to save metabox data to
* custom post type.
Expand Down Expand Up @@ -841,6 +948,13 @@ public function feedzy_category_columns( $columns ) {
$columns['actions'] = __( 'Actions', 'feedzy-rss-feeds' );
}

$new_columns = $this->array_insert_before( 'slug', $columns, 'source', __( 'Source', 'feedzy-rss-feeds' ) );
if ( $new_columns ) {
$columns = $new_columns;
} else {
$columns['Source'] = __( 'source', 'feedzy-rss-feeds' );
}

return $columns;
}

Expand Down Expand Up @@ -885,6 +999,33 @@ public function manage_feedzy_category_columns( $column, $post_id ) {
case 'actions':
echo wp_kses_post( sprintf( '<button class="button button-primary validate-category" title="%s" data-category-id="%d">%s</button>', __( 'Click to remove invalid URLs from this category', 'feedzy-rss-feeds' ), $post_id, __( 'Validate & Clean', 'feedzy-rss-feeds' ) ) );
break;
case 'source':
$src = get_post_meta( $post_id, 'feedzy_category_feed', true );
if ( empty( $src ) ) {
$src = __( 'No Source Configured', 'feedzy-rss-feeds' );
} else {
$urls = $this->normalize_urls( $src );
$src = '';
if ( is_array( $urls ) ) {

foreach ( $urls as $key => $url ) {
$too_long = 130;
if ( strlen( $src ) > $too_long ) {
$src .= '...';
break;
} else {
$src .= '<a href="' . $url . '" target="_blank" title="' . __( 'Click to view', 'feedzy-rss-feeds' ) . '">' . $url . '</a>';
if ( count( $urls ) > $key + 1 ) {
$src .= ', ';
}
}
}
} else {
$src .= '<a href="' . esc_url( $urls ) . '" target="_blank" title="' . __( 'Click to view', 'feedzy-rss-feeds' ) . '">' . esc_html( $urls ) . '</a>';
}
}
echo wp_kses_post( $src );
break;
default:
break;
}
Expand Down Expand Up @@ -1477,6 +1618,23 @@ public function ajax() {
}
wp_send_json_success( array( 'invalid' => count( $invalid ) ) );
break;
case 'validate_feeds_group':
$feeds = isset( $_POST['feeds'] ) ? sanitize_text_field( wp_unslash( $_POST['feeds'] ) ) : '';
if ( empty( $feeds ) ) {
wp_send_json_error( __( 'No feeds provided for validation.', 'feedzy-rss-feeds' ) );
}
$feeds = $this->normalize_urls( $feeds );
if ( ! is_array( $feeds ) ) {
$feeds = array( $feeds );
}
$valid = $this->get_valid_source_urls( $feeds, '1_mins', false );
$invalid = array_diff( $feeds, $valid );
wp_send_json_success(
array(
'valid' => $valid,
'invalid' => $invalid,
)
);
}
}

Expand Down
30 changes: 30 additions & 0 deletions includes/feedzy-rss-feeds-activator.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,35 @@ public static function activate() {
)
);
}
self::add_feeds_group();
}

/**
* Adds a default feeds group with some popular WordPress-related feeds.
*
* This method checks if a feeds group already exists, and if not, creates one
* with a set of predefined feeds.
*
* @return void
*/
public static function add_feeds_group() {
if ( get_option( '_feedzy_news_group_id', false ) ) {
return;
}

$group_args = array(
'post_title' => __( 'News sites', 'feedzy-rss-feeds' ),
'post_type' => 'feedzy_categories',
'post_status' => 'publish',
'post_content' => '',
);

$news_group = wp_insert_post( $group_args );

$feed_groups = 'https://themeisle.com/blog/feed/, https://wptavern.com/feed/, https://www.wpbeginner.com/feed/, https://wpshout.com/feed/, https://planet.wordpress.org/feed/';

add_post_meta( $news_group, 'feedzy_category_feed', $feed_groups );

update_option( '_feedzy_news_group_id', $news_group );
}
}
7 changes: 5 additions & 2 deletions includes/feedzy-rss-feeds-feed-tweaks.php
Original file line number Diff line number Diff line change
Expand Up @@ -466,10 +466,13 @@ function ( $allowed_html = array() ) {
'value' => array(),
'class' => array(),
'data-feedzy' => array(),
'placeholder' => array(),
'rows' => array(),
),
'button' => array(
'class' => array(),
'id' => array(),
'class' => array(),
'id' => array(),
'disabled' => array(),
),
'p' => array(
'class' => array(),
Expand Down
35 changes: 35 additions & 0 deletions js/categories.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

$(document).ready(function(){
init();
validateFeeds();
});

function init(){
Expand Down Expand Up @@ -33,4 +34,38 @@
});
}

// validate feeds group.
function validateFeeds() {
$('#feedzy_category_feeds textarea[name="feedzy_category_feed"]').on('input', function() {
if ($(this).val().length < 1) {
$('.validate-feeds').attr('disabled', true);
} else {
$('.validate-feeds').attr('disabled', false);
}
});

$('#feedzy_category_feeds .button.validate-feeds').on('click', function(e) {
e.preventDefault();
var button = $(this);
button.attr('disabled', true);
$('#feedzy_category_feeds .spinner').addClass('is-active');
$.ajax({
url: ajaxurl,
method: 'POST',
data: {
action: 'feedzy_categories',
_action: 'validate_feeds_group',
security: feedzy.ajax.security,
feeds: $('textarea[name="feedzy_category_feed"]').val()
},
success: function(data) {
if (data.success) {
$('textarea[name="feedzy_category_feed"]').val(data.data.valid.join(', '));
$('#feedzy_category_feeds .spinner').removeClass('is-active');
}
}
})
});
}

})(jQuery, feedzy);
Loading