From e8df48f391851ca730a2c223e4c6db027ed45469 Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Thu, 13 Feb 2025 12:52:44 +0200 Subject: [PATCH 1/3] feat: load Formbricks survey via internal pages hooks --- inc/plugins/class-dashboard.php | 69 ++++++++++++++++--- otter-blocks.php | 1 + .../inc/server/class-dashboard-server.php | 1 + src/dashboard/components/LicenseField.js | 2 +- src/dashboard/index.js | 19 +---- 5 files changed, 62 insertions(+), 30 deletions(-) diff --git a/inc/plugins/class-dashboard.php b/inc/plugins/class-dashboard.php index bf6b901ee..4763b90e7 100644 --- a/inc/plugins/class-dashboard.php +++ b/inc/plugins/class-dashboard.php @@ -28,13 +28,15 @@ class Dashboard { public function init() { add_action( 'admin_menu', array( $this, 'register_menu_page' ) ); add_action( 'admin_init', array( $this, 'maybe_redirect' ) ); - add_action( 'admin_notices', array( $this, 'maybe_add_otter_banner' ), 30 ); + add_action( 'admin_notices', array( $this, 'form_submission_elements' ), 30 ); add_action( 'admin_head', array( $this, 'add_inline_css' ) ); $form_options = get_option( 'themeisle_blocks_form_emails' ); if ( ! empty( $form_options ) ) { add_action( 'wp_dashboard_setup', array( $this, 'form_submissions_widget' ) ); } + + add_filter( 'themeisle-sdk/survey/' . OTTER_PRODUCT_SLUG, array( $this, 'get_survey_metadata' ), 10, 2 ); } /** @@ -217,7 +219,7 @@ public function enqueue_options_assets() { $this->get_dashboard_data() ); - $this->load_survey(); + do_action( 'themeisle_internal_page', OTTER_PRODUCT_SLUG, 'dashboard' ); } /** @@ -243,7 +245,7 @@ public function get_dashboard_data() { 'showFeedbackNotice' => $this->should_show_feedback_notice(), 'deal' => ! Pro::is_pro_installed() ? $offer->get_localized_data() : array(), 'hasOnboarding' => false !== get_theme_support( FSE_Onboarding::SUPPORT_KEY ), - 'days_since_install' => (int) round( ( time() - get_option( 'otter_blocks_install', time() ) ) / DAY_IN_SECONDS ), + 'days_since_install' => intval( ( time() - get_option( 'otter_blocks_install', time() ) ) / DAY_IN_SECONDS ), 'rootUrl' => get_site_url(), 'neveThemePreviewUrl' => esc_url( add_query_arg( @@ -273,6 +275,14 @@ public function get_dashboard_data() { ), 'neveInstalled' => defined( 'NEVE_VERSION' ), ); + + if ( + isset( $global_data['license'], $global_data['license']['key'] ) + && 'free' !== $global_data['license']['key'] + && 6 >= strlen( $global_data['license']['key'] ) + ) { + $global_data['license']['key'] = str_repeat( '*', 26 ) . substr( $global_data['license']['key'], -6 ); + } return apply_filters( 'otter_dashboard_data', $global_data ); } @@ -302,15 +312,19 @@ public function maybe_redirect() { } /** - * Add the Otter banner on the 'edit-otter_form_record' page. + * Add elements for Form Block submission page. * * @return void */ - public function maybe_add_otter_banner() { + public function form_submission_elements() { $screen = get_current_screen(); if ( 'edit-otter_form_record' === $screen->id || 'otter-blocks_page_form-submissions-free' === $screen->id ) { $this->the_otter_banner(); } + + if ( 'edit-otter_form_record' === $screen->id ) { + do_action( 'themeisle_internal_page', OTTER_PRODUCT_SLUG, 'form-submissions' ); + } } /** @@ -734,15 +748,48 @@ public function form_submissions_widget_content() { } /** - * Load the Formbricks deps from SDK to initiate the survey. + * Register survey. + * + * @param array $data The data in Formbricks format. + * @param string $page_slug The page slug. + * + * @return array The data in Frombricks format. */ - private function load_survey() { - $survey_handler = apply_filters( 'themeisle_sdk_dependency_script_handler', 'survey' ); - if ( empty( $survey_handler ) ) { - return; + public function get_survey_metadata( $data, $page_slug ) { + $dash_data = $this->get_dashboard_data(); + + $install_category = 0; + $install_days_number = $dash_data['days_since_install']; + + if ( 1 < $install_days_number && 8 > $install_days_number ) { + $install_category = 7; + } elseif ( 8 <= $install_days_number && 31 > $install_days_number ) { + $install_category = 30; + } elseif ( 30 < $install_days_number && 90 > $install_days_number ) { + $install_category = 90; + } elseif ( 90 <= $install_days_number ) { + $install_category = 91; + } + + $data = array( + 'environmentId' => 'clp9hqm8c1osfdl2ixwd0k0iz', + 'attributes' => array( + 'days_since_install' => $install_category, + 'install_days_number' => $install_days_number, + 'plan' => isset( $dash_data['license'], $dash_data['license']['type'] ) ? $dash_data['license']['type'] : 'free', + 'freeVersion' => $dash_data['version'], + ), + ); + + if ( isset( $dash_data['license'], $dash_data['license']['key'] ) ) { + $data['attributes']['license_key'] = apply_filters( 'themeisle_sdk_secret_masking', apply_filters( 'product_otter_license_key', '' ) ); + } + + if ( isset( $dash_data['proVersion'] ) ) { + $data['attributes']['proVersion'] = $dash_data['proVersion']; } - do_action( 'themeisle_sdk_dependency_enqueue_script', 'survey' ); + return $data; } /** diff --git a/otter-blocks.php b/otter-blocks.php index e582824bf..9dd98aca2 100644 --- a/otter-blocks.php +++ b/otter-blocks.php @@ -29,6 +29,7 @@ define( 'OTTER_BLOCKS_VERSION', '3.0.10' ); define( 'OTTER_BLOCKS_PRO_SUPPORT', true ); define( 'OTTER_BLOCKS_SHOW_NOTICES', false ); +define( 'OTTER_PRODUCT_SLUG', basename( OTTER_BLOCKS_PATH ) ); $vendor_file = OTTER_BLOCKS_PATH . '/vendor/autoload.php'; diff --git a/plugins/otter-pro/inc/server/class-dashboard-server.php b/plugins/otter-pro/inc/server/class-dashboard-server.php index 2bc3fe35a..901d1e699 100644 --- a/plugins/otter-pro/inc/server/class-dashboard-server.php +++ b/plugins/otter-pro/inc/server/class-dashboard-server.php @@ -65,6 +65,7 @@ public function apply_dashboard_data( $data ) { 'hasNevePro' => defined( 'NEVE_PRO_VERSION' ), 'storeURL' => 'https://store.themeisle.com/', 'purchaseHistoryURL' => 'https://store.themeisle.com/purchase-history', + 'proVersion' => OTTER_PRO_VERSION, ) ); } diff --git a/src/dashboard/components/LicenseField.js b/src/dashboard/components/LicenseField.js index d798d695a..bcc11297a 100644 --- a/src/dashboard/components/LicenseField.js +++ b/src/dashboard/components/LicenseField.js @@ -87,7 +87,7 @@ const LicenseField = () => { setLicenseKey( e.target.value ) } diff --git a/src/dashboard/index.js b/src/dashboard/index.js index 0590a2ffc..e996a749d 100644 --- a/src/dashboard/index.js +++ b/src/dashboard/index.js @@ -74,21 +74,4 @@ const App = () => { const root = createRoot( document.getElementById( 'otter' ) ); -root.render( ); - -/** - * Initialize the formbricks survey. - * - * @see https://github.com/formbricks/setup-examples/tree/main/html - */ -window.addEventListener('themeisle:survey:loaded', function () { - window?.tsdk_formbricks?.init?.({ - environmentId: 'clp9hqm8c1osfdl2ixwd0k0iz', - apiHost: 'https://app.formbricks.com', - userId: 'otter_' + ( undefined !== window.otterObj?.license?.key ? window.otterObj.license.key : window.otterObj.rootUrl.replace( /[^\w\d]*/g, '' ) ), - attributes: { - plan: undefined !== window.otterObj?.license?.type ? window.otterObj.license.type : 'free', - days_since_install: convertToCategory( window.otterObj.days_since_install ) - } - }); -}); +root.render( ); \ No newline at end of file From f46b22658b739143147141345fe44ac62969e789 Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Tue, 18 Feb 2025 11:39:44 +0200 Subject: [PATCH 2/3] refactor: remove install category for survey --- inc/plugins/class-dashboard.php | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/inc/plugins/class-dashboard.php b/inc/plugins/class-dashboard.php index 4763b90e7..12ecae055 100644 --- a/inc/plugins/class-dashboard.php +++ b/inc/plugins/class-dashboard.php @@ -757,24 +757,12 @@ public function form_submissions_widget_content() { */ public function get_survey_metadata( $data, $page_slug ) { $dash_data = $this->get_dashboard_data(); - - $install_category = 0; - $install_days_number = $dash_data['days_since_install']; - if ( 1 < $install_days_number && 8 > $install_days_number ) { - $install_category = 7; - } elseif ( 8 <= $install_days_number && 31 > $install_days_number ) { - $install_category = 30; - } elseif ( 30 < $install_days_number && 90 > $install_days_number ) { - $install_category = 90; - } elseif ( 90 <= $install_days_number ) { - $install_category = 91; - } + $install_days_number = $dash_data['days_since_install']; $data = array( 'environmentId' => 'clp9hqm8c1osfdl2ixwd0k0iz', 'attributes' => array( - 'days_since_install' => $install_category, 'install_days_number' => $install_days_number, 'plan' => isset( $dash_data['license'], $dash_data['license']['type'] ) ? $dash_data['license']['type'] : 'free', 'freeVersion' => $dash_data['version'], From 42493f03eb47c1f37686f4a626a89b982aa4a077 Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Tue, 18 Feb 2025 11:56:01 +0200 Subject: [PATCH 3/3] feat: deactivate license using the saved license --- inc/plugins/class-dashboard.php | 6 ++++-- .../otter-pro/inc/server/class-dashboard-server.php | 10 +++++++++- src/dashboard/components/LicenseField.js | 10 ++++++---- tests/php/static-analysis-stubs/otter.php | 1 + 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/inc/plugins/class-dashboard.php b/inc/plugins/class-dashboard.php index 12ecae055..a07fa9428 100644 --- a/inc/plugins/class-dashboard.php +++ b/inc/plugins/class-dashboard.php @@ -275,16 +275,18 @@ public function get_dashboard_data() { ), 'neveInstalled' => defined( 'NEVE_VERSION' ), ); + + $global_data = apply_filters( 'otter_dashboard_data', $global_data ); if ( isset( $global_data['license'], $global_data['license']['key'] ) && 'free' !== $global_data['license']['key'] - && 6 >= strlen( $global_data['license']['key'] ) + && 6 <= strlen( $global_data['license']['key'] ) ) { $global_data['license']['key'] = str_repeat( '*', 26 ) . substr( $global_data['license']['key'], -6 ); } - return apply_filters( 'otter_dashboard_data', $global_data ); + return $global_data; } /** diff --git a/plugins/otter-pro/inc/server/class-dashboard-server.php b/plugins/otter-pro/inc/server/class-dashboard-server.php index 901d1e699..df505f61e 100644 --- a/plugins/otter-pro/inc/server/class-dashboard-server.php +++ b/plugins/otter-pro/inc/server/class-dashboard-server.php @@ -86,6 +86,7 @@ public function register_routes() { 'args' => array( 'key' => array( 'type' => 'string', + 'required' => false, 'sanitize_callback' => function ( $key ) { return (string) esc_attr( $key ); }, @@ -123,7 +124,10 @@ public function register_routes() { public function toggle_license( $request ) { $fields = $request->get_json_params(); - if ( ! isset( $fields['key'] ) || ! isset( $fields['action'] ) ) { + if ( + ! isset( $fields['action'] ) + || ( 'activate' === $fields['action'] && ! isset( $fields['key'] ) ) + ) { return new \WP_REST_Response( array( 'message' => __( 'Invalid Action. Please refresh the page and try again.', 'otter-pro' ), @@ -131,6 +135,10 @@ public function toggle_license( $request ) { ) ); } + + if ( 'deactivate' === $fields['action'] ) { + $fields['key'] = apply_filters( 'product_otter_license_key', 'free' ); + } $response = apply_filters( 'themeisle_sdk_license_process_otter', $fields['key'], $fields['action'] ); diff --git a/src/dashboard/components/LicenseField.js b/src/dashboard/components/LicenseField.js index bcc11297a..c985b3cb3 100644 --- a/src/dashboard/components/LicenseField.js +++ b/src/dashboard/components/LicenseField.js @@ -100,10 +100,12 @@ const LicenseField = () => { isSecondary={ isValid } isBusy={ isLoading } disabled={ isLoading } - onClick={ () => onSaveLicense({ - action: isValid ? 'deactivate' : 'activate', - key: licenseKey - }) } + onClick={ () => { + onSaveLicense({ + action: isValid ? 'deactivate' : 'activate', + key: isValid ? undefined : licenseKey + }); + } } > { isValid ? __( 'Deactivate', 'otter-blocks' ) : __( 'Activate', 'otter-blocks' ) } diff --git a/tests/php/static-analysis-stubs/otter.php b/tests/php/static-analysis-stubs/otter.php index b9d655030..f2673a28d 100644 --- a/tests/php/static-analysis-stubs/otter.php +++ b/tests/php/static-analysis-stubs/otter.php @@ -9,6 +9,7 @@ define( 'OTTER_BLOCKS_URL', plugins_url( '/', __FILE__ ) ); define( 'OTTER_BLOCKS_PATH', dirname( __FILE__ ) ); define( 'OTTER_BLOCKS_VERSION', '2.2.7' ); +define( 'OTTER_PRODUCT_SLUG', basename( OTTER_BLOCKS_PATH ) ); define( 'OTTER_PRO_VERSION', OTTER_BLOCKS_VERSION ); define( 'OTTER_PRO_URL', OTTER_BLOCKS_URL . 'plugins/otter-pro/' );