diff --git a/admin/importers/class-convertkit-admin-importer-aweber.php b/admin/importers/class-convertkit-admin-importer-aweber.php new file mode 100644 index 000000000..fd982f283 --- /dev/null +++ b/admin/importers/class-convertkit-admin-importer-aweber.php @@ -0,0 +1,101 @@ +get_forms_detected_in_posts(); + } + + // Fetch AWeber account, using OAuth1 or OAuth2. + // This is how the AWeber Plugin fetches the account data, as nothing is cached in their Plugin or the database. + $response = $aweber_webform_plugin->getAWeberAccount( + get_option( $aweber_webform_plugin->adminOptionsName ), // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase + get_option( $aweber_webform_plugin->oauth2TokensOptions ) // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase + ); + + // If no account is returned, fall back to showing the AWeber Form IDs found in the posts, if any. + if ( ! isset( $response['account'] ) ) { + return $this->get_forms_detected_in_posts(); + } + + // Get account, which contains forms and form split tests. + $account = $response['account']; + $web_forms = $account->getWebForms(); + $web_form_split_tests = $account->getWebFormSplitTests(); + + // Build array of forms. + $forms = array(); + foreach ( $web_forms as $form ) { + $forms[ $form->id ] = sprintf( '%s: %s', __( 'Sign Up Form', 'convertkit' ), $form->name ); + } + foreach ( $web_form_split_tests as $form ) { + $forms[ $form->id ] = sprintf( '%s: %s', __( 'Split Tests', 'convertkit' ), $form->name ); + } + + // Return forms. + return $forms; + + } + + /** + * Returns an array of AWeber form IDs and titles found in the posts. + * + * @since 3.1.5 + * + * @return array + */ + private function get_forms_detected_in_posts() { + + $forms = array(); + + foreach ( $this->get_form_ids_in_posts() as $form_id ) { + $forms[ $form_id ] = sprintf( 'AWeber Form ID #%s', $form_id ); + } + + return $forms; + + } + +} diff --git a/admin/importers/class-convertkit-admin-importer-mc4wp.php b/admin/importers/class-convertkit-admin-importer-mc4wp.php index ff18b17af..84ed6e071 100644 --- a/admin/importers/class-convertkit-admin-importer-mc4wp.php +++ b/admin/importers/class-convertkit-admin-importer-mc4wp.php @@ -32,35 +32,6 @@ class ConvertKit_Admin_Importer_MC4WP extends ConvertKit_Admin_Importer { */ public $shortcode_id_attribute = 'id'; - /** - * Returns an array of post IDs that contain the MC4WP form shortcode. - * - * @since 3.1.0 - * - * @return array - */ - public function get_forms_in_posts() { - - global $wpdb; - - // Search post_content for [mc4wp_form] shortcode and return array of post IDs. - $results = $wpdb->get_col( - $wpdb->prepare( - " - SELECT ID - FROM {$wpdb->posts} - WHERE post_status = %s - AND post_content LIKE %s - ", - 'publish', - '%[' . $this->shortcode_name . '%' - ) - ); - - return $results ? $results : array(); - - } - /** * Returns an array of MC4WP form IDs and titles. * diff --git a/admin/importers/class-convertkit-admin-importer.php b/admin/importers/class-convertkit-admin-importer.php index 74632cb57..be55e6819 100644 --- a/admin/importers/class-convertkit-admin-importer.php +++ b/admin/importers/class-convertkit-admin-importer.php @@ -42,13 +42,33 @@ abstract class ConvertKit_Admin_Importer { abstract public function get_forms(); /** - * Returns an array of post IDs that contain the third party form shortcode. + * Returns an array of post IDs that contain the AWeber form shortcode. * - * @since 3.1.0 + * @since 3.1.5 * * @return array */ - abstract public function get_forms_in_posts(); + public function get_forms_in_posts() { + + global $wpdb; + + // Search post_content for [aweber] shortcode and return array of post IDs. + $results = $wpdb->get_col( + $wpdb->prepare( + " + SELECT ID + FROM {$wpdb->posts} + WHERE post_status = %s + AND post_content LIKE %s + ", + 'publish', + '%[' . $this->shortcode_name . '%' + ) + ); + + return $results ? $results : array(); + + } /** * Returns whether any third party forms exist. @@ -145,4 +165,66 @@ public function replace_shortcodes_in_content( $content, $third_party_form_id, $ } + /** + * Returns an array of all unique form IDs from the posts that contain the third party form shortcode. + * + * @since 3.1.5 + * + * @return array + */ + public function get_form_ids_in_posts() { + + // Get Post IDs that contain the AWeber form shortcode. + $post_ids = $this->get_forms_in_posts(); + + // If no post IDs are found, return an empty array. + if ( ! count( $post_ids ) ) { + return array(); + } + + // Iterate through Posts, extracting the Form IDs from the AWeber form shortcodes. + $form_ids = array(); + foreach ( $post_ids as $post_id ) { + $content_form_ids = $this->get_form_ids_from_content( get_post_field( 'post_content', $post_id ) ); + $form_ids = array_merge( $form_ids, $content_form_ids ); + } + + $form_ids = array_values( array_unique( $form_ids ) ); + + return $form_ids; + + } + + /** + * Returns an array of form IDs within the shortcode for the third party Form plugin. + * + * @since 3.1.5 + * + * @param string $content Content containing third party Form Shortcodes. + * @return array + */ + public function get_form_ids_from_content( $content ) { + + $pattern = '/\[' // Start regex with an opening square bracket. + . preg_quote( $this->shortcode_name, '/' ) // Match the shortcode name, escaping any regex special chars. + . '(?:\s+[^\]]*)?' // Optionally match any attributes (key/value pairs), non-greedy. + . preg_quote( $this->shortcode_id_attribute, '/' )// Match the id attribute name. + . '\s*=\s*' // Optional whitespace, equals sign, optional whitespace. + . '(?:"([^"]+)"|([^\s\]]+))' // Capture quoted or unquoted value. + . '[^\]]*?\]/i'; // Match up to closing bracket, case-insensitive. + + preg_match_all( $pattern, $content, $matches ); + + // Extract form IDs: They could be in either $matches[1] (quoted) or $matches[2] (unquoted). + $form_ids = array_filter( + array_merge( + isset( $matches[1] ) ? $matches[1] : array(), + isset( $matches[2] ) ? $matches[2] : array() + ) + ); + + return $form_ids; + + } + } diff --git a/admin/section/class-convertkit-admin-section-tools.php b/admin/section/class-convertkit-admin-section-tools.php index 87129de98..fe62b0091 100644 --- a/admin/section/class-convertkit-admin-section-tools.php +++ b/admin/section/class-convertkit-admin-section-tools.php @@ -57,6 +57,7 @@ public function register_notices( $notices ) { 'import_configuration_invalid_file_type' => __( 'The uploaded configuration file isn\'t valid.', 'convertkit' ), 'import_configuration_empty' => __( 'The uploaded configuration file contains no settings.', 'convertkit' ), 'import_configuration_success' => __( 'Configuration imported successfully.', 'convertkit' ), + 'migrate_aweber_configuration_success' => __( 'AWeber forms migrated successfully.', 'convertkit' ), 'migrate_mc4wp_configuration_success' => __( 'MC4WP forms migrated successfully.', 'convertkit' ), ) ); @@ -76,6 +77,7 @@ private function maybe_perform_actions() { $this->maybe_download_system_info(); $this->maybe_export_configuration(); $this->maybe_import_configuration(); + $this->maybe_migrate_aweber_configuration(); $this->maybe_migrate_mc4wp_configuration(); } @@ -316,6 +318,41 @@ private function maybe_import_configuration() { } + /** + * Replaces AWeber Form Shortcodes with Kit Form Shortcodes, if the user submitted the + * AWeber Migrate Configuration section. + * + * @since 3.1.5 + */ + private function maybe_migrate_aweber_configuration() { + + // Bail if nonce verification fails. + if ( ! isset( $_REQUEST['_convertkit_settings_tools_nonce'] ) ) { + return; + } + + if ( ! wp_verify_nonce( sanitize_key( $_REQUEST['_convertkit_settings_tools_nonce'] ), 'convertkit-settings-tools' ) ) { + return; + } + + // Bail if no AWeber Form IDs were submitted. + if ( ! isset( $_REQUEST['_wp_convertkit_integration_aweber_settings'] ) ) { + return; + } + + // Initialise the importer. + $aweber = new ConvertKit_Admin_Importer_AWeber(); + + // Iterate through the AWeber Form IDs and replace the shortcodes with the Kit Form Shortcodes. + foreach ( array_map( 'sanitize_text_field', wp_unslash( $_REQUEST['_wp_convertkit_integration_aweber_settings'] ) ) as $aweber_form_id => $kit_form_id ) { + $aweber->replace_shortcodes_in_posts( (int) $aweber_form_id, (int) $kit_form_id ); + } + + // Redirect to Tools screen. + $this->redirect_with_success_notice( 'migrate_aweber_configuration_success' ); + + } + /** * Replaces MC4WP Form Shortcodes with Kit Form Shortcodes, if the user submitted the * MC4WP Migrate Configuration section. @@ -373,7 +410,8 @@ public function render() { $forms = new ConvertKit_Resource_Forms(); // Get Importers. - $mc4wp = new ConvertKit_Admin_Importer_MC4WP(); + $aweber = new ConvertKit_Admin_Importer_AWeber(); + $mc4wp = new ConvertKit_Admin_Importer_MC4WP(); // Output view. require_once CONVERTKIT_PLUGIN_PATH . '/views/backend/settings/tools.php'; diff --git a/views/backend/settings/tools.php b/views/backend/settings/tools.php index 907c97115..597fb4d72 100644 --- a/views/backend/settings/tools.php +++ b/views/backend/settings/tools.php @@ -102,6 +102,61 @@ has_forms_in_posts() && $aweber->has_forms() && $forms->exist() ) { + ?> +
+
+
| + | + |
|---|---|
| + | + + | +
+ +
+