Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
693dcac
Remove refresh() calls
n7studios Nov 27, 2025
bd03fdf
Make clearer what the kit/v1/blocks REST API endpoint is used for
n7studios Nov 27, 2025
a419320
Call convertkit_maybe_delete_credentials() when a refresh() request r…
n7studios Nov 27, 2025
50489c6
Use `return-refresh-result` WordPress Libraries
n7studios Nov 27, 2025
c057ce5
Resources: Don’t call init(), which might automatically call refresh()
n7studios Nov 27, 2025
5bef858
Setup Wizard: Handle errors on fetching resources
n7studios Nov 27, 2025
3c25fe1
PHPStan compat.
n7studios Nov 27, 2025
f574154
Tests: Add Sequences to Test Resources
n7studios Nov 27, 2025
d8e1bcf
Remove sequences from test resource data
n7studios Nov 27, 2025
3d72285
Merge remote-tracking branch 'origin/tests-resources-include-sequence…
n7studios Nov 27, 2025
595b9f5
Merge remote-tracking branch 'origin/tests-non-inline-forms-setup-res…
n7studios Nov 27, 2025
495c92c
Tests: Integration: Resources: Call `init` before each test
n7studios Nov 27, 2025
9ac4e58
Merge remote-tracking branch 'origin/tests-non-inline-forms-setup-res…
n7studios Nov 27, 2025
e7614e4
Merge remote-tracking branch 'origin/tests-non-inline-forms-setup-res…
n7studios Nov 27, 2025
458e49d
Resources: Forms: Return 404 if the Form ID doesn’t exist in the cach…
n7studios Nov 27, 2025
739e6fa
Form Block/Shortcode Render: Update logic to handle forms missing in …
n7studios Nov 27, 2025
b4e1707
Coding standards
n7studios Nov 27, 2025
2ff82d5
Merge branch 'main' into remove-refresh-resources-calls
n7studios Dec 2, 2025
f8bfda8
Move convertkit_maybe_delete_credentials() to resource class’ refresh…
n7studios Dec 2, 2025
9b77e11
Update WordPress Libraries to 2.1.2
n7studios Dec 2, 2025
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
47 changes: 39 additions & 8 deletions admin/section/class-convertkit-admin-section-general.php
Original file line number Diff line number Diff line change
Expand Up @@ -603,25 +603,56 @@ public function maybe_initialize_and_refresh_resources() {
}

// Refresh Forms.
$this->forms->refresh();
$result = $this->forms->refresh();

// Bail if an error occured.
if ( is_wp_error( $result ) ) {
return;
}

// Also refresh Landing Pages, Tags and Posts. Whilst not displayed in the Plugin Settings, this ensures up to date
// lists are stored for when editing e.g. Pages.
$landing_pages = new ConvertKit_Resource_Landing_Pages( 'settings' );
$landing_pages->refresh();
$result = $landing_pages->refresh();

// Bail if an error occured.
if ( is_wp_error( $result ) ) {
return;
}

remove_all_actions( 'convertkit_resource_refreshed_posts' );
$posts = new ConvertKit_Resource_Posts( 'settings' );
$posts->refresh();
$posts = new ConvertKit_Resource_Posts( 'settings' );
$result = $posts->refresh();

// Bail if an error occured.
if ( is_wp_error( $result ) ) {
return;
}

$products = new ConvertKit_Resource_Products( 'settings' );
$products->refresh();
$result = $products->refresh();

// Bail if an error occured.
if ( is_wp_error( $result ) ) {
return;
}

$sequences = new ConvertKit_Resource_Sequences( 'settings' );
$sequences->refresh();
$result = $sequences->refresh();

// Bail if an error occured.
if ( is_wp_error( $result ) ) {
return;
}

$tags = new ConvertKit_Resource_Tags( 'settings' );
$result = $tags->refresh();

// Bail if an error occured.
if ( is_wp_error( $result ) ) {
return;
}

$tags = new ConvertKit_Resource_Tags( 'settings' );
$tags->refresh();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,23 @@ public function load_screen_data( $step ) {
// Fetch Landing Pages.
$this->landing_pages = new ConvertKit_Resource_Landing_Pages( 'landing_page_wizard' );

// Refresh Landing Page resources, in case the user just created their first Product or Tag
// in ConvertKit.
$this->landing_pages->refresh();
// Refresh Landing Page resources, in case the user just created their first Landing Page in Kit.
$result = $this->landing_pages->refresh();

// Bail if an error occured.
if ( is_wp_error( $result ) ) {
// Change the next button label and make it a link to reload the screen.
unset( $this->steps[1]['next_button'] );
$this->current_url = add_query_arg(
array(
'page' => $this->page_name,
'ck_post_type' => $this->post_type,
'step' => 1,
),
admin_url( 'options.php' )
);
return;
}

// If no Landing Pages exist in ConvertKit, change the next button label and make it a link to reload
// the screen.
Expand Down
18 changes: 16 additions & 2 deletions admin/setup-wizard/class-convertkit-admin-setup-wizard-plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -316,12 +316,26 @@ function ( $hosts ) {

switch ( $step ) {
case 2:
// Re-load settings class now that the API Key and Secret has been defined.
// Re-load settings class now that the Access and Refresh Tokens have been defined.
$this->settings = new ConvertKit_Settings();

// Fetch Forms.
$this->forms = new ConvertKit_Resource_Forms( 'setup_wizard' );
$this->forms->refresh();
$result = $this->forms->refresh();

// Bail if an error occured.
if ( is_wp_error( $result ) ) {
// Change the next button label and make it a link to reload the screen.
$this->steps[2]['next_button']['label'] = __( 'I\'ve created a form in Kit', 'convertkit' );
$this->steps[2]['next_button']['link'] = add_query_arg(
array(
'page' => $this->page_name,
'step' => 2,
),
admin_url( 'options.php' )
);
return;
}

// If no Forms exist in ConvertKit, change the next button label and make it a link to reload
// the screen.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,58 @@ public function load_screen_data( $step ) {

// Refresh Forms, Products and Tags resources, in case the user just created their first Form, Product or Tag
// in ConvertKit.
$this->forms->refresh();
$this->products->refresh();
$this->tags->refresh();
$result = $this->forms->refresh();

// Bail if an error occured.
if ( is_wp_error( $result ) ) {
// Change the next label and make it a link to reload the screen.
unset( $this->steps[1]['next_button'] );
$this->current_url = add_query_arg(
array(
'page' => $this->page_name,
'ck_post_type' => $this->post_type,
'step' => 1,
),
admin_url( 'options.php' )
);
return;
}

// Refresh Products.
$result = $this->products->refresh();

// Bail if an error occured.
if ( is_wp_error( $result ) ) {
// Change the next label and make it a link to reload the screen.
unset( $this->steps[1]['next_button'] );
$this->current_url = add_query_arg(
array(
'page' => $this->page_name,
'ck_post_type' => $this->post_type,
'step' => 1,
),
admin_url( 'options.php' )
);
return;
}

// Refresh Tags.
$result = $this->tags->refresh();

// Bail if an error occured.
if ( is_wp_error( $result ) ) {
// Change the next label and make it a link to reload the screen.
unset( $this->steps[1]['next_button'] );
$this->current_url = add_query_arg(
array(
'page' => $this->page_name,
'ck_post_type' => $this->post_type,
'step' => 1,
),
admin_url( 'options.php' )
);
return;
}

// If no Forms, Products and Tags exist in ConvertKit, change the next button label and make it a link to reload
// the screen.
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"type": "project",
"license": "GPLv3",
"require": {
"convertkit/convertkit-wordpress-libraries": "2.1.1"
"convertkit/convertkit-wordpress-libraries": "2.1.2"
},
"require-dev": {
"php-webdriver/webdriver": "^1.0",
Expand Down
7 changes: 0 additions & 7 deletions includes/blocks/class-convertkit-block-broadcasts.php
Original file line number Diff line number Diff line change
Expand Up @@ -487,13 +487,6 @@ public function render( $atts ) {
// Fetch Posts.
$posts = new ConvertKit_Resource_Posts( 'output_broadcasts' );

// If this is an admin request, refresh the Posts resource now from the API,
// as it's an inexpensive query of ~ 0.5 seconds when we're editing a Page
// containing this block.
if ( function_exists( 'is_admin' ) && is_admin() ) {
$posts->refresh();
}

// If no Posts exist, bail.
if ( ! $posts->exist() ) {
if ( $settings->debug_enabled() ) {
Expand Down
14 changes: 12 additions & 2 deletions includes/blocks/class-convertkit-block-form.php
Original file line number Diff line number Diff line change
Expand Up @@ -385,10 +385,20 @@ public function render( $atts ) {
// If an error occured, it might be that we're requesting a Form ID that exists in ConvertKit
// but does not yet exist in the Plugin's Form Resources.
// If so, refresh the Form Resources and try again.
if ( is_wp_error( $form ) ) {
if ( is_wp_error( $form ) && $form->get_error_data() === 404 ) {
// Refresh Forms from the API.
$forms->refresh();
$result = $forms->refresh();

// Bail if an error occured.
if ( is_wp_error( $result ) ) {
if ( $settings->debug_enabled() ) {
return '<!-- ' . $result->get_error_message() . ' --> <!-- ' . $form->get_error_message() . ' -->';
}

return '';
}

// Refresh succeeded.
// Get Form HTML again.
$form = $forms->get_html( $form_id, $post_id );
}
Expand Down
29 changes: 22 additions & 7 deletions includes/class-convertkit-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,41 @@ public function __construct() {
*/
public function register_routes() {

// Register route to return all blocks registered by the Plugin.
// Register route to refresh resources andreturn all blocks registered by the Plugin,
// when the user clicks the refresh button in the Gutenberg editor.
register_rest_route(
'kit/v1',
'/blocks',
array(
'methods' => WP_REST_Server::READABLE,

// Refresh resources and return blocks.
// Return blocks.
'callback' => function () {
// Refresh resources from the API, to reflect any changes.
// Refresh Forms.
$forms = new ConvertKit_Resource_Forms( 'block_edit' );
$forms->refresh();
$result = $forms->refresh();
if ( is_wp_error( $result ) ) {
// Return blocks without refreshing other resources.
return rest_ensure_response( convertkit_get_blocks() );
}

// Refresh Posts.
$posts = new ConvertKit_Resource_Posts( 'block_edit' );
$posts->refresh();
$result = $posts->refresh();
if ( is_wp_error( $result ) ) {
// Return blocks without refreshing other resources.
return rest_ensure_response( convertkit_get_blocks() );
}

// Refresh Products.
$products = new ConvertKit_Resource_Products( 'block_edit' );
$products->refresh();
$result = $products->refresh();
if ( is_wp_error( $result ) ) {
// Return blocks without refreshing other resources.
return rest_ensure_response( convertkit_get_blocks() );
}

// Return blocks.
// Return blocks, which will now include the refreshed resources.
return rest_ensure_response( convertkit_get_blocks() );
},

Expand Down
33 changes: 30 additions & 3 deletions includes/class-convertkit-resource-forms.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,34 @@ public function __construct( $context = false ) {
);
}

// Call parent initialization function.
parent::init();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Drops the init() call, so refresh() can only occur if called directly by the Plugin.

// Get last query time and existing resources.
$this->last_queried = get_option( $this->settings_name . '_last_queried' );
$this->resources = get_option( $this->settings_name );
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes certain any existing cached resources are available, if the API isn't available.


}

/**
* Fetches resources (forms, landing pages or tags) from the API, storing them in the options table
* with a last queried timestamp.
*
* If the refresh results in a 401, removes the access and refresh tokens from the settings.
*
* @since 3.1.2
*
* @return WP_Error|array
*/
public function refresh() {

// Call parent refresh method.
$result = parent::refresh();

// If an error occured, maybe delete credentials from the Plugin's settings
// if the error is a 401 unauthorized.
if ( is_wp_error( $result ) ) {
convertkit_maybe_delete_credentials( $result, CONVERTKIT_OAUTH_CLIENT_ID );
}

return $result;

}

Expand Down Expand Up @@ -496,7 +522,8 @@ public function get_html( $id, $post_id = 0 ) {
/* translators: ConvertKit Form ID */
__( 'Kit Form ID %s does not exist on Kit.', 'convertkit' ),
$id
)
),
404
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Provides context to the error i.e. a Kit Form ID was specified that either does not exist in the cached resources, is an ID for a legacy form, or truly doesn't exist (the user entered the wrong ID in the shortcode).

);
}

Expand Down
5 changes: 3 additions & 2 deletions includes/class-convertkit-resource-landing-pages.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ public function __construct( $context = 'landing_pages' ) {
);
}

// Call parent initialization function.
parent::init();
// Get last query time and existing resources.
$this->last_queried = get_option( $this->settings_name . '_last_queried' );
$this->resources = get_option( $this->settings_name );

}

Expand Down
5 changes: 3 additions & 2 deletions includes/class-convertkit-resource-posts.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ public function __construct( $context = false ) {
);
}

// Call parent initialization function.
parent::init();
// Get last query time and existing resources.
$this->last_queried = get_option( $this->settings_name . '_last_queried' );
$this->resources = get_option( $this->settings_name );

}

Expand Down
5 changes: 3 additions & 2 deletions includes/class-convertkit-resource-products.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ public function __construct( $context = false ) {
);
}

// Call parent initialization function.
parent::init();
// Get last query time and existing resources.
$this->last_queried = get_option( $this->settings_name . '_last_queried' );
$this->resources = get_option( $this->settings_name );

}

Expand Down
5 changes: 3 additions & 2 deletions includes/class-convertkit-resource-sequences.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ public function __construct( $context = false ) {
);
}

// Call parent initialization function.
parent::init();
// Get last query time and existing resources.
$this->last_queried = get_option( $this->settings_name . '_last_queried' );
$this->resources = get_option( $this->settings_name );

}

Expand Down
5 changes: 3 additions & 2 deletions includes/class-convertkit-resource-tags.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ public function __construct( $context = false ) {
);
}

// Call parent initialization function.
parent::init();
// Get last query time and existing resources.
$this->last_queried = get_option( $this->settings_name . '_last_queried' );
$this->resources = get_option( $this->settings_name );

}

Expand Down
Loading