Skip to content

Commit 3781401

Browse files
feat: improved remove duplicates (#1034)
* Improve remove duplicates * fix: update upsell link * Add multiple tags support * Encode the tag value if the value type is an object * Create unique meta key * e2e: check upsell link * Add phpunit tests * Improve PHPUnit testcases * fix: change meta key * fix: import count * fix: php warning * fix: e2e and phpunit testcase error * fix: phpunit testcase error --------- Co-authored-by: Hardeep Asrani <[email protected]>
1 parent dcc8bf5 commit 3781401

File tree

5 files changed

+106
-5
lines changed

5 files changed

+106
-5
lines changed

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

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ public function feedzy_import_feed_options() {
373373
$import_auto_translation = get_post_meta( $post->ID, 'import_auto_translation', true );
374374
$import_auto_translation = 'yes' === $import_auto_translation ? 'checked' : '';
375375
$import_translation_lang = get_post_meta( $post->ID, 'import_auto_translation_lang', true );
376+
$mark_duplicate_tag = get_post_meta( $post->ID, 'mark_duplicate_tag', true );
376377
$import_post_author = get_post_meta( $post->ID, 'import_post_author', true );
377378
$filter_conditions = get_post_meta( $post->ID, 'filter_conditions', true );
378379

@@ -1033,6 +1034,9 @@ private function get_complete_import_status( $post_id ) {
10331034
if ( $items ) {
10341035
$status['cumulative'] = count( $items );
10351036
}
1037+
if ( ! empty( $status['duplicates'] ) ) {
1038+
$status['total'] = absint( $status['total'] - count( $status['duplicates'] ) );
1039+
}
10361040

10371041
return $status;
10381042
}
@@ -1411,6 +1415,8 @@ private function run_job( $job, $max ) {
14111415
$import_translation_lang = get_post_meta( $job->ID, 'import_auto_translation_lang', true );
14121416
$filter_conditions = get_post_meta( $job->ID, 'filter_conditions', true );
14131417
$import_post_author = get_post_meta( $job->ID, 'import_post_author', true );
1418+
$mark_duplicate_tag = get_post_meta( $job->ID, 'mark_duplicate_tag', true );
1419+
$mark_duplicate_tag = feedzy_is_pro() && ! empty( $mark_duplicate_tag ) ? preg_replace( '/[\[\]#]/', '', $mark_duplicate_tag ) : '';
14141420
$max = $import_feed_limit;
14151421

14161422
if ( empty( $filter_conditions ) ) {
@@ -1567,11 +1573,36 @@ private function run_job( $job, $max ) {
15671573
$is_duplicate = $use_new_hash ? in_array( $item_hash, $imported_items_new, true ) : in_array( $item_hash, $imported_items_old, true );
15681574
$items_found[ $item['item_url'] ] = $item['item_title'];
15691575

1576+
$duplicate_tag_value = array();
1577+
$mark_duplicate_key = 'item_url';
15701578
if ( 'yes' === $import_remove_duplicates && ! $is_duplicate ) {
1571-
$is_duplicate_post = $this->is_duplicate_post( $import_post_type, 'feedzy_item_url', esc_url_raw( $item['item_url'] ) );
1579+
if ( ! empty( $mark_duplicate_tag ) ) {
1580+
$mark_duplicate_tag = is_string( $mark_duplicate_tag ) ? explode( ',', $mark_duplicate_tag ) : $mark_duplicate_tag;
1581+
$mark_duplicate_tag = array_map( 'trim', $mark_duplicate_tag );
1582+
$duplicate_tag_value = array_map(
1583+
function ( $tag ) use ( $item_obj, $item ) {
1584+
if ( str_contains( $tag, 'item_custom' ) && $this->feedzy_is_business() ) {
1585+
$tag = apply_filters( 'feedzy_parse_custom_tags', "[#$tag]", $item_obj );
1586+
} elseif ( isset( $item[ $tag ] ) ) {
1587+
$tag = isset( $item[ $tag ] ) ? is_object( $item[ $tag ] ) ? wp_json_encode( $item[ $tag ] ) : $item[ $tag ] : '';
1588+
}
1589+
return $tag;
1590+
},
1591+
$mark_duplicate_tag
1592+
);
1593+
}
1594+
if ( ! empty( $duplicate_tag_value ) ) {
1595+
$duplicate_tag_value = implode( ' ', $duplicate_tag_value );
1596+
$duplicate_tag_value = substr( sanitize_key( wp_strip_all_tags( $duplicate_tag_value ) ), 0, apply_filters( 'feedzy_mark_duplicate_content_limit', 256 ) );
1597+
$mark_duplicate_key = 'mark_duplicate';
1598+
} else {
1599+
$duplicate_tag_value = esc_url_raw( $item['item_url'] );
1600+
}
1601+
$is_duplicate_post = $this->is_duplicate_post( $import_post_type, 'feedzy_' . $mark_duplicate_key, $duplicate_tag_value );
15721602
if ( ! empty( $is_duplicate_post ) ) {
15731603
foreach ( $is_duplicate_post as $p ) {
1574-
$found_duplicates[] = get_post_meta( $p, 'feedzy_item_url', true );
1604+
$found_duplicates[ $item_hash ] = get_post_meta( $p, 'feedzy_' . $mark_duplicate_key, true );
1605+
$duplicates[ $item['item_url'] ] = $item['item_title'];
15751606
wp_delete_post( $p, true );
15761607
}
15771608
}
@@ -2120,6 +2151,11 @@ function( $term ) {
21202151
update_post_meta( $new_post_id, 'feedzy_job', $job->ID );
21212152
update_post_meta( $new_post_id, 'feedzy_item_author', sanitize_text_field( $author ) );
21222153

2154+
// Verify that the `$mark_duplicate_key` does not match `'item_url'` to ensure the condition applies only when a different tag is specified.
2155+
if ( $mark_duplicate_key && 'item_url' !== $mark_duplicate_key ) {
2156+
update_post_meta( $new_post_id, 'feedzy_' . $mark_duplicate_key, $duplicate_tag_value );
2157+
}
2158+
21232159
// we can use this to associate the items that were imported in a particular run.
21242160
update_post_meta( $new_post_id, 'feedzy_job_time', $last_run );
21252161

includes/views/import-metabox-edit.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,8 +657,23 @@ class="fz-switch-toggle" type="checkbox" value="yes"
657657
</div>
658658
</div>
659659

660-
<div class="form-block form-block-two-column <?php echo feedzy_is_legacyv5() ? '' : esc_attr( apply_filters( 'feedzy_upsell_class', '' ) ); ?>">
661-
<?php echo feedzy_is_legacyv5() ? '' : wp_kses_post( apply_filters( 'feedzy_upsell_content', '', 'count', 'import' ) ); ?>
660+
<div class="form-block form-block-two-column <?php echo esc_attr( apply_filters( 'feedzy_upsell_class', '' ) ); ?>">
661+
<?php echo wp_kses_post( apply_filters( 'feedzy_upsell_content', '', 'remove-duplicates', 'import' ) ); ?>
662+
<div class="fz-left">
663+
<h4 class="h4"><?php esc_html_e( 'Mark Duplicates By', 'feedzy-rss-feeds' ); ?> <?php echo ! feedzy_is_pro() ? ' <span class="pro-label">PRO</span>' : ''; ?></h4>
664+
</div>
665+
<div class="fz-right">
666+
<div class="fz-form-group">
667+
<label class="form-label"><?php esc_html_e( 'Mark the duplicate items using the magic tag value', 'feedzy-rss-feeds' ); ?></label>
668+
<input type="text" id="feedzy_mark_duplicate" name="feedzy_meta_data[mark_duplicate_tag]" class="form-control" value="<?php echo esc_attr( $mark_duplicate_tag ); ?>"<?php disabled( true, 'checked' !== $import_remove_duplicates ); ?> />
669+
<div class="help-text pt-8">
670+
<?php esc_html_e( 'Helpful if you want to identify and remove duplicate items. Enter a magic tag to mark duplicates based on its value, e.g: [#item_title], [#item_content], [#item_url] etc.', 'feedzy-rss-feeds' ); ?>
671+
</div>
672+
</div>
673+
</div>
674+
</div>
675+
676+
<div class="form-block form-block-two-column">
662677
<div class="fz-left">
663678
<h4 class="h4"><?php esc_html_e( 'Items Count', 'feedzy-rss-feeds' ); ?><?php echo ! feedzy_is_pro() && ! feedzy_is_legacyv5() ? ' <span class="pro-label">PRO</span>' : ''; ?></h4>
664679
</div>

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,14 @@
661661
}
662662
} );
663663

664+
$( document ).on( 'change', 'input#remove-duplicates', function() {
665+
if ( $(this).is(':checked') ) {
666+
$('input#feedzy_mark_duplicate').attr( 'disabled', false );
667+
} else {
668+
$('input#feedzy_mark_duplicate').attr( 'disabled', true );
669+
}
670+
} );
671+
664672
$(document).on( 'input', 'input[name="custom_vars_value[]"]', function () {
665673
$(this)
666674
.next('.fz-action-icon')

tests/e2e/specs/upsell.spec.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ test.describe( 'Upsell', () => {
4141
await page.locator('.fz-form-group:has( #fz-event-execution )').hover({ force: true });
4242
upgradeAlert = page.locator('#feedzy-import-form a[href*="utm_campaign=schedule-import-job"]');
4343
await expect( upgradeAlert ).toBeVisible();
44+
45+
await page.locator('.fz-form-group:has( #feedzy_mark_duplicate )').hover({ force: true });
46+
upgradeAlert = page.locator('#feedzy-import-form a[href*="utm_campaign=remove-duplicates"]');
47+
await expect( upgradeAlert ).toBeVisible();
4448
} );
4549
});
4650

tests/test-import.php

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public function setUp(): void {
3232
* @access public
3333
* @dataProvider importDataProvider
3434
*/
35-
public function test_feedzy_imports( $random_name1, $random_name2, $urls, $magic_tags = '[#item_content]', $use_filter = false, $type = 'post' ) {
35+
public function test_feedzy_imports( $random_name1, $random_name2, $urls, $magic_tags = '[#item_content]', $use_filter = false, $type = 'post', $check_duplicate = false ) {
3636
do_action( 'init' );
3737

3838
$num_items = $this->import_limit;
@@ -93,6 +93,11 @@ public function test_feedzy_imports( $random_name1, $random_name2, $urls, $magic
9393
$_POST['custom_vars_key'] = array();
9494
$_POST['custom_vars_value'] = array();
9595

96+
if ( $check_duplicate ) {
97+
$_POST['feedzy_meta_data']['import_remove_duplicates'] = 'yes';
98+
$_POST['feedzy_meta_data']['mark_duplicate_tag'] = '[#item_author]';
99+
}
100+
96101
do_action( 'save_post_feedzy_imports', $p->ID, $p );
97102
$this->assertEquals( $p->post_title, $random_name2 );
98103
$this->assertEquals( $p->post_type, 'feedzy_imports' );
@@ -110,6 +115,11 @@ public function test_feedzy_imports( $random_name1, $random_name2, $urls, $magic
110115
$import_custom_fields = get_post_meta( $p->ID, 'imports_custom_fields', true );
111116
$import_feed_limit = get_post_meta( $p->ID, 'import_feed_limit', true );
112117

118+
if ( $check_duplicate ) {
119+
$remove_duplicates = get_post_meta( $p->ID, 'import_remove_duplicates', true );
120+
$mark_duplicate_tag = get_post_meta( $p->ID, 'mark_duplicate_tag', true );
121+
}
122+
113123
$this->assertEquals( $type, $import_post_type );
114124
$this->assertEquals( 'category_' . $category_id, $import_post_term );
115125
$this->assertEquals( 'publish', $import_post_status );
@@ -123,6 +133,11 @@ public function test_feedzy_imports( $random_name1, $random_name2, $urls, $magic
123133
$this->assertEquals( '', $import_custom_fields );
124134
$this->assertEquals( $num_items, $import_feed_limit );
125135

136+
if ( $check_duplicate ) {
137+
$this->assertEquals( 'yes', $remove_duplicates );
138+
$this->assertEquals( '[#item_author]', $mark_duplicate_tag );
139+
}
140+
126141
$feed_src = str_replace( PHP_EOL, '', $urls );
127142

128143
// Do Cron
@@ -232,6 +247,11 @@ public function test_feedzy_imports( $random_name1, $random_name2, $urls, $magic
232247
$this->assertEquals( 1, get_post_meta( $created[0]->ID, 'feedzy', true ) );
233248
$this->assertNotEmpty( get_post_meta( $created[0]->ID, 'feedzy_item_url', true ) );
234249

250+
// Check found duplicates items.
251+
if ( $check_duplicate ) {
252+
$this->assertNotEmpty( get_post_meta( $created[0]->ID, 'feedzy_mark_duplicate', true ) );
253+
}
254+
235255
// Check Post Delete
236256
$this->assertNotEquals( false, wp_delete_post( $p->ID ) );
237257
return $created[0];
@@ -370,6 +390,24 @@ function( $date ) {
370390
update_option( 'gmt_offset', 0 ); // reset UTC
371391
}
372392

393+
/**
394+
* Test check duplicate.
395+
*/
396+
public function test_check_duplicate() {
397+
define( 'FEEDZY_PRO_ABSPATH', '' );
398+
add_filter(
399+
'product_feedzy_license_status',
400+
function () {
401+
return 'valid';
402+
},
403+
99
404+
);
405+
406+
$post = $this->test_feedzy_imports( $this->get_rand_name(), $this->get_rand_name(), $this->get_two_rand_feeds(), '[#item_content]', false, 'post', true );
407+
408+
$this->assertNotEmpty( $post );
409+
}
410+
373411
/**
374412
* Utility method to generate a random 5 char string.
375413
*

0 commit comments

Comments
 (0)