Skip to content

Commit 804dd56

Browse files
Merge pull request #1046 from Codeinwp/feat/pro/775
Adds import/export configuration
2 parents 7d45ada + af61a81 commit 804dd56

File tree

7 files changed

+228
-4
lines changed

7 files changed

+228
-4
lines changed

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

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,12 @@ public function enqueue_styles() {
165165
'clearLogButton' => __( 'Clear Log', 'feedzy-rss-feeds' ),
166166
'okButton' => __( 'Ok', 'feedzy-rss-feeds' ),
167167
'removeErrorLogsMsg' => __( 'Removed all error logs.', 'feedzy-rss-feeds' ),
168+
'importButton' => sprintf(
169+
'<a href="#" class="page-title-action fz-export-import-btn%1$s"><span class="dashicons %2$s"></span>%3$s</a>',
170+
! feedzy_is_pro() ? ' only-pro' : '',
171+
feedzy_is_pro() ? 'dashicons-upload' : 'dashicons-lock',
172+
esc_html__( 'Import Job', 'feedzy-rss-feeds' )
173+
),
168174
),
169175
)
170176
);
@@ -2471,6 +2477,11 @@ public function admin_notices() {
24712477
if ( false === Feedzy_Rss_Feeds_Util_Scheduler::is_scheduled( 'feedzy_cron' ) ) {
24722478
echo wp_kses_post( '<div class="notice notice-error"><p>' . __( 'Unable to register cron job. Your feeds might not get updated', 'feedzy-rss-feeds' ) . '</p></div>' );
24732479
}
2480+
2481+
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
2482+
if ( ! empty( $_GET['imported'] ) ) {
2483+
echo wp_kses_post( '<div class="notice notice-success is-dismissible"><p>' . __( 'Successfully imported.', 'feedzy-rss-feeds' ) . '</p></div>' );
2484+
}
24742485
}
24752486

24762487
/**
@@ -2838,12 +2849,12 @@ public function add_import_actions( $actions, $post ) {
28382849
unset( $actions['inline hide-if-no-js'] );
28392850

28402851
$actions['feedzy_purge'] = sprintf(
2841-
'<a href="#" class="feedzy-purge" data-id="%d">%2$s</a><span class="feedzy-spinner spinner"></span>',
2852+
'<a href="#" class="feedzy-purge" data-id="%d">%2$s</a>',
28422853
$post->ID,
28432854
esc_html( __( 'Purge &amp; Reset', 'feedzy-rss-feeds' ) )
28442855
);
2845-
if ( feedzy_is_pro() ) {
28462856

2857+
if ( feedzy_is_pro() ) {
28472858
$actions['feedzy_clone'] =
28482859
sprintf(
28492860
'<a href="%1$s" class="feedzy-clone" >%2$s</a>',
@@ -2877,6 +2888,25 @@ public function add_import_actions( $actions, $post ) {
28772888
$is_not_first = true;
28782889
}
28792890
}
2891+
// Export action.
2892+
$export_action = sprintf(
2893+
'<a href="%s" class="%s"style="%s">%s</a>',
2894+
feedzy_is_pro() ? esc_url(
2895+
add_query_arg(
2896+
array(
2897+
'action' => 'fz_export_job',
2898+
'_wpnonce' => wp_create_nonce( 'fz_export_job' ),
2899+
'id' => $post->ID,
2900+
),
2901+
admin_url( 'admin.php' )
2902+
)
2903+
) : '#',
2904+
feedzy_is_pro() ? 'fz-export-btn' : 'fz-export-btn-pro',
2905+
! feedzy_is_pro() ? 'opacity:0.5;' : '',
2906+
( ! feedzy_is_pro() ? '<span style="font-size: 13px;line-height: 1.5em;width: 13px;height: 13px;" class="dashicons dashicons-lock"></span>' : '' ) . esc_html__( 'Export', 'feedzy-rss-feeds' )
2907+
);
2908+
2909+
$actions['export'] = $export_action;
28802910
} elseif ( 1 === intval( get_post_meta( $post->ID, 'feedzy', true ) ) ) {
28812911
// show an unclickable action that mentions that it is imported by us
28822912
// so that users are aware
@@ -3342,4 +3372,51 @@ private function clear_error_logs() {
33423372
)
33433373
);
33443374
}
3375+
3376+
/**
3377+
* Load edit screen.
3378+
*/
3379+
public function load_edit_screen() {
3380+
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
3381+
if ( empty( $_GET['post_type'] ) || 'feedzy_imports' !== $_GET['post_type'] ) {
3382+
return;
3383+
}
3384+
add_action( 'admin_footer', array( $this, 'add_import_export_section' ) );
3385+
}
3386+
3387+
/**
3388+
* Add import export section.
3389+
*/
3390+
public function add_import_export_section() {
3391+
if ( ! feedzy_is_pro() ) :
3392+
?>
3393+
<div id="fz_import_export_upsell" class="hidden" style="max-width:450px">
3394+
<div class="modal-content">
3395+
<span class="notice-dismiss close-modal">
3396+
<span class="screen-reader-text"><?php esc_html_e( 'Dismiss this dialog', 'feedzy-rss-feeds' ); ?></span>
3397+
</span>
3398+
<div class="modal-header">
3399+
<h2><span class="dashicons dashicons-lock"></span> <?php esc_html_e( 'Import/Export is a PRO feature', 'feedzy-rss-feeds' ); ?></h2>
3400+
</div>
3401+
<div class="modal-body">
3402+
<p><?php esc_html_e( 'We\'re sorry, import/export is not available on your plan. Please upgrade to the Pro plan to unlock all these features.', 'feedzy-rss-feeds' ); ?></p>
3403+
</div>
3404+
<div class="modal-footer">
3405+
<div class="button-container"><a href="<?php echo esc_url( tsdk_translate_link( tsdk_utmify( FEEDZY_UPSELL_LINK, 'importExport' ) ) ); ?>" target="_blank" rel="noopener " class="button button-primary button-large"><?php esc_html_e( 'Upgrade to PRO', 'feedzy-rss-feeds' ); ?><span aria-hidden="true" class="dashicons dashicons-external"></span></a></div>
3406+
</div>
3407+
</div>
3408+
</div>
3409+
<?php endif; ?>
3410+
<script type="template/text" id="fz_import_field_section">
3411+
<div class="fz-import-field hidden">
3412+
<form method="post" enctype="multipart/form-data" action="<?php echo esc_url( add_query_arg( array( 'action' => 'fz_import_job' ), admin_url( 'admin.php' ) ) ); ?>">
3413+
<h4> <?php esc_html_e( 'Choose the inport job .json file to import.', 'feedzy-rss-feeds' ); ?></h4>
3414+
<?php wp_nonce_field( 'fz_import_job' ); ?>
3415+
<input type="file" accept=".json" name="fz_import" required>
3416+
<button type="submit" class="button button-primary"><?php esc_html_e( 'Import', 'feedzy-rss-feeds' ); ?></button>
3417+
</form>
3418+
</div>
3419+
</script>
3420+
<?php
3421+
}
33453422
}

includes/feedzy-rss-feeds-feed-tweaks.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,13 +231,13 @@ function feedzy_is_legacyv5( ) {
231231

232232
return $legacy === 1;
233233
}
234+
234235
/**
235236
* Check if the user is pro or not.
236237
*
237238
* @return bool If the users is pro or not
238239
*/
239240
function feedzy_is_pro( $check_license = true ) {
240-
241241
$status = apply_filters( 'product_feedzy_license_status', false ) === 'valid';
242242
if ( ! $check_license ) {
243243
$status = true;

includes/feedzy-rss-feeds.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ function () {
260260
self::$instance->loader->add_filter( 'feedzy_magic_tags_post_excerpt', $plugin_import, 'magic_tags_post_excerpt', 11 );
261261
self::$instance->loader->add_action( 'admin_action_feedzy_clone_import_job', $plugin_import, 'feedzy_clone_import_job' );
262262
self::$instance->loader->add_action( 'admin_notices', $plugin_import, 'feedzy_import_clone_success_notice' );
263+
self::$instance->loader->add_action( 'load-edit.php', $plugin_import, 'load_edit_screen' );
263264
// Remove elementor feature.
264265
self::$instance->loader->add_action( 'elementor/experiments/feature-registered', self::$instance->admin, 'feedzy_remove_elementor_feature', 10, 2 );
265266
// Remove widget.

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

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,66 @@ span.feedzy-spinner {
138138
.feedzy-errors-dialog + .ui-widget-content button.feedzy-clear-logs {
139139
margin-left: 0;
140140
}
141+
142+
.wp-core-ui .fz-export-import-btn {
143+
display: inline-flex !important;
144+
align-items: center;
145+
}
146+
147+
.wp-core-ui .fz-header-action {
148+
display: inline-flex !important;
149+
gap: 8px;
150+
}
151+
152+
#fz_import_export_upsell .modal-content {
153+
background: #fff;
154+
border-radius: 3px;]
155+
width: auto;
156+
margin: 1.75rem auto ;
157+
}
158+
#fz_import_export_upsell .modal-body {
159+
text-align: center;
160+
}
161+
#fz_import_export_upsell .modal-header {
162+
padding-bottom: 10px;
163+
margin-bottom: 10px;
164+
position: relative;
165+
}
166+
#fz_import_export_upsell .modal-header .dashicons {
167+
font-size: 1.3em;
168+
line-height: inherit;
169+
}
170+
#fz_import_export_upsell .modal-header h2 {
171+
text-align: center;
172+
}
173+
#fz_import_export_upsell .close-modal {
174+
position: absolute;
175+
top: 0;
176+
right: 0;
177+
}
178+
#fz_import_export_upsell .modal-footer .dashicons{
179+
180+
vertical-align: middle;
181+
font-size: initial;
182+
}
183+
#fz_import_export_upsell .modal-footer {
184+
padding-top: 10px;
185+
margin-top: 10px;
186+
text-align: center;
187+
}
188+
.fz-import-field {
189+
background-color: #fff;
190+
max-width: 400px;
191+
width: 100%;
192+
margin: 0 auto;
193+
position: relative;
194+
padding: 15px;
195+
height: 120px;
196+
display: flex;
197+
align-items: center;
198+
justify-content: center;
199+
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
200+
}
201+
.fz-import-field.hidden {
202+
display: none;
203+
}

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

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,59 @@
659659
tagList.find( 'input:text' ).val( '' );
660660
}
661661
} );
662+
// Append import button.
663+
$( feedzy.i10n.importButton ).insertAfter( $( '.page-title-action', document ) );
664+
$( $( '.page-title-action', document ) ).wrapAll( '<div class="fz-header-action"></div>' );
665+
666+
// Create dialog box
667+
$( '#fz_import_export_upsell' ).dialog( {
668+
title: '',
669+
dialogClass: 'wp-dialog',
670+
autoOpen: false,
671+
draggable: false,
672+
width: 'auto',
673+
modal: true,
674+
resizable: false,
675+
closeOnEscape: true,
676+
position: {
677+
my: "center",
678+
at: "center",
679+
of: window
680+
},
681+
open: function( event, ui ) {
682+
$(".ui-dialog-titlebar-close", ui.dialog | ui).hide();
683+
$(".ui-dialog-titlebar", ui.dialog | ui).hide();
684+
},
685+
create: function() {
686+
// style fix for WordPress admin
687+
$( '.ui-dialog-titlebar-close' ).addClass( 'ui-button' );
688+
},
689+
} );
690+
691+
$( '.fz-export-import-btn.only-pro, .fz-export-btn-pro' ).on( 'click', function( e ) {
692+
e.preventDefault();
693+
$( '#fz_import_export_upsell' ).dialog( 'open' );
694+
});
695+
696+
$( '#fz_import_export_upsell' ).on( 'click', '.close-modal', function ( e ) {
697+
e.preventDefault();
698+
$( '#fz_import_export_upsell' ).dialog( 'close' );
699+
} );
700+
701+
$(document).on( 'click', '.fz-export-import-btn:not(.only-pro)', function( e ) {
702+
e.preventDefault();
703+
if ( $('.fz-import-field').length === 0 ) {
704+
var importField = $( '#fz_import_field_section' ).html();
705+
$( importField ).insertAfter( $( this ).parents( 'div.wrap' ).find( '.wp-header-end' ) );
706+
}
707+
$('.fz-import-field').toggleClass('hidden');
708+
});
709+
710+
let url = new URL(window.location.href);
711+
if (url.searchParams.has('imported')) {
712+
url.searchParams.delete('imported');
713+
history.replaceState(history.state, '', url.href);
714+
}
662715
}
663716

664717
function initSummary() {

tests/e2e/specs/upsell.spec.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,33 @@ test.describe( 'Upsell', () => {
4343
await expect( upgradeAlert ).toBeVisible();
4444
} );
4545
});
46+
47+
test.describe( 'List Page Upsell', () => {
48+
test.beforeEach( async ( { requestUtils, page } ) => {
49+
await page.goto('/wp-admin/edit.php?post_type=feedzy_imports');
50+
} );
51+
52+
test('Import/Export', async ({ editor, page }) => {
53+
// Locate and click the "Import Job" link
54+
const importButton = page.locator('.fz-export-import-btn');
55+
await expect(importButton).toBeVisible();
56+
await importButton.click();
57+
58+
// Wait for the popup to become visible
59+
const upsellPopup = page.locator('#fz_import_export_upsell');
60+
await expect(upsellPopup).toBeVisible();
61+
62+
// Locate and check the "Upgrade to PRO" link inside the popup
63+
const upgradeToProLink = upsellPopup.locator('a', { hasText: 'Upgrade to PRO' });
64+
await expect(upgradeToProLink).toBeVisible();
65+
66+
// Get the URL from the "Upgrade to PRO" link
67+
const upsellLink = new URL(await upgradeToProLink.getAttribute('href'));
68+
69+
// Validate the URL parameters
70+
expect(upsellLink.host).toBe('themeisle.com');
71+
expect(upsellLink.searchParams.get('utm_source')).toBe('wpadmin');
72+
expect(upsellLink.searchParams.get('utm_medium')).toBe('edit');
73+
expect(upsellLink.searchParams.get('utm_content')).toBe('feedzy-rss-feeds');
74+
});
75+
});

tests/e2e/utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ export async function runFeedImport( page ) {
129129

130130
// Open the dialog with the imported feeds.
131131
await page.locator('.feedzy-items a').click();
132-
await expect( page.locator('#ui-id-1').locator('li a').count() ).resolves.toBeGreaterThan(0);
132+
await expect( page.locator('#ui-id-2').locator('li a').count() ).resolves.toBeGreaterThan(0);
133133
await page.getByRole('button', { name: 'Ok' }).click();
134134
}
135135

0 commit comments

Comments
 (0)