Skip to content

Commit 393bbe8

Browse files
feat: improved feeds validation UX
1 parent e3949c4 commit 393bbe8

File tree

6 files changed

+360
-61
lines changed

6 files changed

+360
-61
lines changed

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

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2513,4 +2513,128 @@ public function add_black_friday_data( $configs ) {
25132513

25142514
return $configs;
25152515
}
2516+
2517+
/**
2518+
* Validate the feed URL and check if it's a valid RSS/Atom feed.
2519+
*
2520+
* @return void
2521+
*/
2522+
public function validate_feed() {
2523+
try {
2524+
if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), FEEDZY_BASEFILE ) ) {
2525+
wp_send_json_error( array( 'message' => __( 'Security check failed.', 'feedzy-rss-feeds' ) ) );
2526+
return;
2527+
}
2528+
2529+
$feed_urls = isset($_POST['feed_url']) ? sanitize_text_field( wp_unslash( $_POST['feed_url'] ) ) : '';
2530+
2531+
if (empty($feed_urls)) {
2532+
wp_send_json_error(array('message' => __('Feed URL cannot be empty.', 'feedzy-rss-feeds')));
2533+
return;
2534+
}
2535+
2536+
$urls = array_map('trim', explode(',', $feed_urls));
2537+
$urls = array_filter($urls);
2538+
2539+
if (empty($urls)) {
2540+
wp_send_json_error(array('message' => __('No valid URLs provided.', 'feedzy-rss-feeds')));
2541+
return;
2542+
}
2543+
2544+
$results = array();
2545+
2546+
$cache = isset($_POST['cache']) ? sanitize_text_field( wp_unslash( $_POST['cache'] ) ) : '1_mins';
2547+
2548+
foreach ($urls as $feed_url) {
2549+
$feed_url = esc_url_raw($feed_url);
2550+
2551+
if (!filter_var($feed_url, FILTER_VALIDATE_URL)) {
2552+
$results[] = array(
2553+
'url' => $feed_url,
2554+
'status' => 'error',
2555+
'message' => __('Invalid URL format', 'feedzy-rss-feeds')
2556+
);
2557+
continue;
2558+
}
2559+
2560+
$feed = $this->fetch_feed(array($feed_url), $cache, array());
2561+
2562+
if ( is_wp_error($feed) ) {
2563+
$results[] = array(
2564+
'url' => $feed_url,
2565+
'status' => 'error',
2566+
'message' => __( 'Error fetching feed: ', 'feedzy-rss-feeds') . $feed->get_error_message()
2567+
);
2568+
continue;
2569+
}
2570+
2571+
if (
2572+
! is_object($feed) ||
2573+
! method_exists($feed, 'get_item_quantity')
2574+
) {
2575+
$results[] = array(
2576+
'url' => $feed_url,
2577+
'status' => 'error',
2578+
'message' => __('Invalid feed object returned', 'feedzy-rss-feeds')
2579+
);
2580+
continue;
2581+
}
2582+
2583+
try {
2584+
$items = $feed->get_item_quantity();
2585+
$title = $feed->get_title();
2586+
$error = $feed->error();
2587+
2588+
if ( is_array( $error ) && ! empty( $error ) ) {
2589+
$results[] = array(
2590+
'url' => $feed_url,
2591+
'status' => 'error',
2592+
'message' => __( 'Error fetching feed: ', 'feedzy-rss-feeds') . implode(', ', $error ),
2593+
);
2594+
continue;
2595+
}
2596+
2597+
if ( $items === 0 ) {
2598+
$results[] = array(
2599+
'url' => $feed_url,
2600+
'status' => 'warning',
2601+
'message' => __('Feed is empty', 'feedzy-rss-feeds')
2602+
);
2603+
continue;
2604+
}
2605+
2606+
$results[] = array(
2607+
'url' => $feed_url,
2608+
'status' => 'success',
2609+
/* translators: %d is the number of items found in the feed */
2610+
'message' => $title . sprintf( _n(
2611+
'%d item found',
2612+
'%d items found',
2613+
$items,
2614+
'feedzy-rss-feeds'
2615+
), $items ),
2616+
'items' => $items,
2617+
'title' => $title
2618+
);
2619+
2620+
} catch ( Throwable $e ) {
2621+
$results[] = array(
2622+
'url' => $feed_url,
2623+
'status' => 'error',
2624+
/* translators: %s is the error message */
2625+
'message' => sprintf(__('Error reading feed: %s', 'feedzy-rss-feeds'), $e->getMessage())
2626+
);
2627+
}
2628+
}
2629+
2630+
wp_send_json_success(array(
2631+
'results' => $results
2632+
));
2633+
} catch (Exception $e) {
2634+
wp_send_json_error(array(
2635+
/* translators: %s is the error message */
2636+
'message' => sprintf(__('An error occurred: %s', 'feedzy-rss-feeds'), $e->getMessage())
2637+
));
2638+
}
2639+
}
25162640
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ public function enqueue_styles() {
163163
array(
164164
'ajax' => array(
165165
'security' => wp_create_nonce( FEEDZY_BASEFILE ),
166+
'url' => admin_url('admin-ajax.php'),
166167
),
167168
'i10n' => array(
168169
'importing' => __( 'Importing', 'feedzy-rss-feeds' ) . '...',

includes/feedzy-rss-feeds.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ private function define_admin_hooks() {
202202
self::$instance->loader->add_filter( 'admin_footer', self::$instance->admin, 'handle_upgrade_submenu' );
203203
self::$instance->loader->add_action( 'current_screen', self::$instance->admin, 'handle_legacy' );
204204
self::$instance->loader->add_action( 'init', self::$instance->admin, 'register_settings' );
205+
self::$instance->loader->add_action('wp_ajax_feedzy_validate_feed', self::$instance->admin, 'validate_feed');
205206

206207
// do not load this with the loader as this will need a corresponding remove_filter also.
207208
add_filter( 'update_post_metadata', array( self::$instance->admin, 'validate_category_feeds' ), 10, 5 );

includes/views/css/import-metabox-edit.css

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,34 @@ span.feedzy-spinner {
202202
.fz-import-field.hidden {
203203
display: none;
204204
}
205+
206+
.feedzy-wrap .fz-validation-message {
207+
margin: 10px 0;
208+
padding: 12px 15px;
209+
border-radius: 4px;
210+
font-size: 14px;
211+
animation: slideIn 0.3s ease-out;
212+
position: relative;
213+
z-index: 10;
214+
display: flex;
215+
flex-direction: column;
216+
align-items: flex-start;
217+
gap: 8px;
218+
border: 1px solid black;
219+
}
220+
221+
.feedzy-wrap .fz-validation-message button {
222+
margin-left: auto;
223+
}
224+
225+
.fz-validation-message .fz-success {
226+
color: #155724;
227+
}
228+
229+
.fz-validation-message .fz-error {
230+
color: #721c24;
231+
}
232+
233+
.fz-validation-message .fz-warning {
234+
color: #856404;
235+
}

includes/views/import-metabox-edit.php

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,25 +42,29 @@
4242
<div class="fz-input-group-left">
4343
<div class="fz-group">
4444
<div class="fz-input-icon">
45-
<input type="text" id="feedzy-import-source" title="<?php esc_attr_e( 'Make sure you validate the feed by using the validate button on the right', 'feedzy-rss-feeds' ); ?>"
46-
placeholder="<?php esc_attr_e( 'Paste your feed URL and click the plus icon to add it in the list', 'feedzy-rss-feeds' ); ?>"
47-
class="form-control" />
48-
<div class="fz-input-group-append">
49-
<button class="fz-plus-btn add-outside-tags" disabled>
50-
<span class="dashicons dashicons-plus-alt2"></span>
51-
</button>
45+
<div class="fz-feed-validator-wrapper">
46+
<input type="text"
47+
id="feedzy-import-source"
48+
title="<?php esc_attr_e( 'Make sure you validate the feed by using the validate button on the right', 'feedzy-rss-feeds' ); ?>"
49+
placeholder="<?php esc_attr_e( 'Paste your feed URL and click the plus icon to add it in the list', 'feedzy-rss-feeds' ); ?>"
50+
class="form-control" />
51+
<div class="fz-input-group-append">
52+
<button class="btn btn-flate btn-icon add-outside-tags"
53+
type="button"
54+
id="feedzy-validate-feed"
55+
role="button"
56+
title="<?php esc_attr_e('Validate Feed', 'feedzy-rss-feeds'); ?>">
57+
<i class="dashicons dashicons-plus-alt2" aria-hidden="true"></i>
58+
</a>
59+
</div>
5260
</div>
5361
</div>
54-
<div class="cta">
55-
<a class="btn btn-flate btn-icon" id="feedzy-validate-feed" target="_blank" data-href-base="https://validator.w3.org/feed/check.cgi?url="
56-
href="#" title="<?php esc_attr_e( 'Validate Feed', 'feedzy-rss-feeds' ); ?>"><i
57-
title="<?php esc_attr_e( 'Validate Feed', 'feedzy-rss-feeds' ); ?>"
58-
class="dashicons dashicons-external"></i></a>
59-
</div>
6062
</div>
6163
<div class="help-text">
6264
<?php esc_html_e( 'You can add multiple sources at once, by separating them with commas. Make sure to use the validate button. Invalid feeds may not import anything.', 'feedzy-rss-feeds' ); ?>
6365
</div>
66+
<div class="fz-validation-summary">
67+
</div>
6468
</div>
6569
<div class="fz-input-group-right">
6670
<div class="dropdown">

0 commit comments

Comments
 (0)