Skip to content

Added custom API call #1119

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 26 commits into
base: release-candidate
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2da3767
Added custom API call
sushmak02 Feb 25, 2025
268d677
Updated transient name
sushmak02 Feb 25, 2025
26e8f78
Fixes
sushmak02 Feb 25, 2025
fa16da3
Added a loader for button
sushmak02 Feb 25, 2025
c6a9193
Added permission check
sushmak02 Feb 25, 2025
7320c7a
Added rest api call for webhook
sushmak02 Feb 26, 2025
d53c67b
Added validation for email
sushmak02 Feb 26, 2025
8947355
Added expiration time for cookie
sushmak02 Feb 26, 2025
b98b148
Send rest endpoint with webhook
sushmak02 Feb 26, 2025
df25e81
Call validation api on webhook success
sushmak02 Feb 26, 2025
029f506
Fixed email response
sushmak02 Feb 26, 2025
5c4b993
Added error message position
sushmak02 Feb 26, 2025
869c423
Reverted unnexessery code
sushmak02 Feb 26, 2025
3a0b95a
Limited max attempt count
sushmak02 Feb 26, 2025
b108cbe
PHPCS fixes
sushmak02 Feb 26, 2025
6277bc4
Limit API calls
sushmak02 Feb 26, 2025
e5b0b53
Update with main branch
sushmak02 Feb 28, 2025
890483b
Save onboarding success option in database
sushmak02 Feb 28, 2025
efc56bf
Added websitedemos site as middleware
sushmak02 Feb 28, 2025
e38394e
Added website demos url
sushmak02 Feb 28, 2025
b59ed7a
Updated response
sushmak02 Feb 28, 2025
12bf1af
Updated changelog and version
sushmak02 Mar 3, 2025
01251b0
Send webhook url through websitedemos site
sushmak02 Mar 3, 2025
725400f
Updated commented code
sushmak02 Mar 3, 2025
a8d87eb
Updated commented code
sushmak02 Mar 3, 2025
53a2993
Merge pull request #1129 from brainstormforce/demosnet
sushmak02 Mar 3, 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
2 changes: 1 addition & 1 deletion build/main.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'react-dom', 'wp-api-fetch', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-polyfill'), 'version' => '78ef91a4006c2bfcc3fd');
<?php return array('dependencies' => array('react', 'react-dom', 'wp-api-fetch', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-polyfill'), 'version' => '90fa05f2b19bb4954b56');
2 changes: 1 addition & 1 deletion build/main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/main.js.map

Large diffs are not rendered by default.

62 changes: 37 additions & 25 deletions gettext.pot
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ msgid ""
msgstr ""

#: src/Components/Dashboard/WelcomeContainer.js:58
#: src/Components/Onboarding/Build.jsx:160
#: src/Components/Onboarding/Build.jsx:217
msgid "Create Header/Footer"
msgstr ""

Expand Down Expand Up @@ -630,98 +630,110 @@ msgstr ""
msgid "What's New?"
msgstr ""

#: src/Components/Onboarding/Build.jsx:104
#: src/Components/Onboarding/Build.jsx:110
#: src/Components/Settings/ThemeSupport.jsx:63
msgid "Settings saved successfully!"
msgstr ""

#: src/Components/Onboarding/Build.jsx:115
#: src/Components/Settings/ThemeSupport.jsx:68
msgid "Failed to save settings!"
msgstr ""

#: src/Components/Onboarding/Build.jsx:161
msgid "You're all set!🚀"
msgstr ""

#: src/Components/Onboarding/Build.jsx:107
#: src/Components/Onboarding/Build.jsx:164
msgid ""
"Start creating headers, footers, or pages with UAE and take your website to "
"the next level"
msgstr ""

#: src/Components/Onboarding/Build.jsx:113
#: src/Components/Onboarding/Build.jsx:170
msgid "Here’s how to get started:"
msgstr ""

#: src/Components/Onboarding/Build.jsx:117
#: src/Components/Onboarding/Build.jsx:174
msgid "Click on “Create” button"
msgstr ""

#: src/Components/Onboarding/Build.jsx:118
#: src/Components/Onboarding/Build.jsx:175
msgid ""
"Choose the type of template you want to create and customize the selected "
"option"
msgstr ""

#: src/Components/Onboarding/Build.jsx:119
#: src/Components/Onboarding/Build.jsx:176
msgid ""
"Use the Elementor editor to customize your template according to your "
"preferences using UAE widgets"
msgstr ""

#: src/Components/Onboarding/Build.jsx:120
#: src/Components/Onboarding/Build.jsx:177
msgid "Click “Publish” to make it live"
msgstr ""

#: src/Components/Onboarding/Build.jsx:185
#: src/Components/Onboarding/Build.jsx:242
msgid "Go To Dashboard"
msgstr ""

#: src/Components/Onboarding/Build.jsx:202
#: src/Components/Onboarding/Build.jsx:259
msgid "We have a special reward just for you!"
msgstr ""

#: src/Components/Onboarding/Build.jsx:205
#: src/Components/Onboarding/Build.jsx:262
msgid "Unlock your surprise now"
msgstr ""

#: src/Components/Onboarding/Build.jsx:219
#: src/Components/Onboarding/Build.jsx:276
msgid "Unlock My Surprise"
msgstr ""

#: src/Components/Onboarding/Build.jsx:234
#: src/Components/Onboarding/Build.jsx:291
msgid "Help make UAE Better"
msgstr ""

#: src/Components/Onboarding/Build.jsx:263
#: src/Components/Onboarding/Build.jsx:320
msgid ""
"Help us improve by sharing anonymous data about your website setup. This "
"includes non-sensitive info about plugins, themes, and settings, so we can "
"create a better product for you. Your privacy is always our top priority. "
"Learn more in our privacy policy."
msgstr ""

#: src/Components/Onboarding/Build.jsx:278
#: src/Components/Onboarding/Build.jsx:335
msgid "We have a special Reward just for you! 🎁"
msgstr ""

#: src/Components/Onboarding/Build.jsx:292
#: src/Components/Onboarding/Build.jsx:353
msgid ""
"Enter your email address to get special offer that we have for you and stay "
"updated on UAE’s latest news and updates."
msgstr ""

#: src/Components/Onboarding/Build.jsx:296
#: src/Components/Onboarding/Build.jsx:357
msgid "Email Address"
msgstr ""

#: src/Components/Onboarding/Build.jsx:336
#: src/Components/Onboarding/Build.jsx:397
msgid "Submit Email"
msgstr ""

#: src/Components/Onboarding/Build.jsx:42
#: src/Components/Onboarding/Build.jsx:43
msgid "Please enter a valid email address"
msgstr ""

#: src/Components/Onboarding/Build.jsx:66
#: src/Components/Settings/ThemeSupport.jsx:63
msgid "Settings saved successfully!"
#: src/Components/Onboarding/Build.jsx:72
msgid "Entered email ID is invalid!"
msgstr ""

#: src/Components/Onboarding/Build.jsx:71
#: src/Components/Settings/ThemeSupport.jsx:68
msgid "Failed to save settings!"
#: src/Components/Onboarding/Build.jsx:75
msgid "Entered email ID already exists, try a different one."
msgstr ""

#: src/Components/Onboarding/Build.jsx:81
msgid "Something went wrong. Try again"
msgstr ""

#: src/Components/Onboarding/Success.jsx:144
Expand Down
4 changes: 2 additions & 2 deletions inc/class-hfe-settings-page.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ public function hfe_global_css() {
*/
public function fetch_user_email() {
$current_user = wp_get_current_user();
if ( $current_user->ID !== 0 ) {
if ( 0 !== $current_user->ID ) {
return $current_user->user_email;
} else {
return null;
Expand All @@ -235,7 +235,7 @@ public function enqueue_admin_scripts() {

$uae_logo = HFE_URL . 'assets/images/settings/dashboard-logo.svg';
$white_logo = HFE_URL . 'assets/images/settings/white-logo.svg';
$show_view_all = ( $post_type === 'elementor-hf' && $pagenow === 'post.php' ) ? 'yes' : 'no';
$show_view_all = ( 'elementor-hf' === $post_type && 'post.php' === $pagenow ) ? 'yes' : 'no';
$hfe_edit_url = admin_url( 'edit.php?post_type=elementor-hf' );
$is_hfe_post = ( 'elementor-hf' === $post_type && ( 'post.php' === $pagenow || 'post-new.php' === $pagenow ) ) ? 'yes' : 'no';

Expand Down
223 changes: 223 additions & 0 deletions inc/settings/hfe-settings-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,229 @@ public function register_routes() {
'permission_callback' => [ $this, 'get_items_permissions_check' ],
]
);

register_rest_route(
'hfe/v1',
'/email-response',
[
'methods' => 'POST',
'callback' => [ $this, 'get_response_from_suretriggers' ],
'permission_callback' => '__return_true',
]
);

register_rest_route(
'hfe/v1',
'/email-webhook',
[
'methods' => 'POST',
'callback' => [ $this, 'send_email_to_webhook_api' ],
'permission_callback' => [ $this, 'get_items_permissions_check' ],
]
);

register_rest_route(
'hfe/v1',
'/email-validation',
[
'methods' => 'POST',
'callback' => [ $this, 'get_email_status' ],
'permission_callback' => [ $this, 'get_items_permissions_check' ],
]
);
}

/**
* Get the API URL.
*
* @since x.x.x
* @return string
*/
public function get_api_domain() {
return apply_filters( 'hfe_api_domain', 'https://websitedemos.net/' );
}

/**
* Send Email to Webhook.
* @param WP_REST_Request $request Request object.
*
*/
public function send_email_to_webhook_api( WP_REST_Request $request ) {
$nonce = $request->get_header( 'X-WP-Nonce' );
if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
return new WP_Error( 'invalid_nonce', __( 'Invalid nonce', 'header-footer-elementor' ), [ 'status' => 403 ] );
}

$session_id = isset( $_COOKIE['hfe_custom_user_session_id'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['hfe_custom_user_session_id'] ) ) : '';

if ( ! $session_id ) {
$session_id = md5( wp_generate_uuid4() . microtime( true ) );
if ( ! headers_sent() ) {
setcookie( 'hfe_custom_user_session_id', $session_id, time() + ( 20 * MINUTE_IN_SECONDS ), '/' );
}
}

$email = sanitize_email( $request->get_param( 'email' ) );
$date = sanitize_text_field( $request->get_param( 'date' ) );

if ( empty( $email ) || empty( $date ) ) {
return new WP_Error( 'missing_parameters', __( 'Missing email or date parameter', 'header-footer-elementor' ), [ 'status' => 400 ] );
}

// Store the email validation request temporarily.
set_transient(
"hfe_email_validation_{$session_id}",
[
'email' => $email,
'date' => $date,
],
10 * MINUTE_IN_SECONDS
);

$api_domain = trailingslashit( $this->get_api_domain() );
$api_domain_url = $api_domain . 'wp-json/uaelite/v1/subscribe/';
$validation_url = esc_url_raw( get_site_url() . '/wp-json/hfe/v1/email-response/' );

// Append session_id to track requests.
$body = array(
'email' => $email,
'date' => $date,
'session_id' => $session_id,
'validation_url' => $validation_url,
);

$args = array(
'body' => $body,


'timeout' => 30,
);

$response = wp_remote_post( $api_domain_url, $args );

if ( is_wp_error( $response ) ) {
return new WP_Error( 'webhook_error', __( 'Error calling endpoint', 'header-footer-elementor' ), [ 'status' => 500 ] );
}

$response_code = wp_remote_retrieve_response_code( $response );
$response_body = json_decode( wp_remote_retrieve_body( $response ), true );

if ( ! in_array( $response_code, [ 200, 201, 204 ], true ) ) {
return new WP_Error( 'webhook_error', __( 'Error in API response: ' . ( $response_body['message'] ?? 'Unknown error' ), 'header-footer-elementor' ), [ 'status' => $response_code ] );
}

return new WP_REST_Response(
[
'message' => 'success',

'session_id' => $session_id,
],
200
);
}

/**
* Email Validation Response.
* @param WP_REST_Request $request Request object.
*
*/
public function get_response_from_suretriggers( WP_REST_Request $request ) {

$body = $request->get_params();

$email = isset( $body['email'] ) ? sanitize_email( $body['email'] ) : '';
$status = isset( $body['status'] ) ? sanitize_text_field( $body['status'] ) : '';
$session_id = isset( $body['session_id'] ) ? sanitize_text_field( $body['session_id'] ) : '';

if ( ! $email || ! $status || ! $session_id ) {
return new WP_REST_Response( [ 'message' => 'Invalid request' ], 400 );
}

$existing_session = get_transient( "hfe_email_validation_{$session_id}" );

if ( false === $existing_session ) {
return new WP_REST_Response( [ 'message' => 'Session expired or invalid.' ], 403 );
}

if ( $email !== $existing_session['email'] ) {
return new WP_REST_Response( [ 'message' => 'Email mismatch' ], 400 );
}

// Store validation result.
set_transient(
"uae_validation_data_{$session_id}",
[
'email' => $email,
'status' => $status,
],
5 * MINUTE_IN_SECONDS
);

// Invalidate the original transient to prevent reuse.
delete_transient( "hfe_email_validation_{$session_id}" );

return new WP_REST_Response(
[
'message' => 'Validation received successfully.',
'status' => $status,
],
200
);
}

/**
* Handle Email Validation Response.
* @param WP_REST_Request $request Request object.
*
*/
public function get_email_status( WP_REST_Request $request ) {

$nonce = $request->get_header( 'X-WP-Nonce' );

if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
return new WP_Error( 'invalid_nonce', __( 'Invalid nonce', 'header-footer-elementor' ), [ 'status' => 403 ] );
}

// Retrieve session ID from cookie.
$session_id = isset( $_COOKIE['hfe_custom_user_session_id'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['hfe_custom_user_session_id'] ) ) : '';

if ( empty( $session_id ) ) {
return new WP_REST_Response(
[
'status' => 'error',
'message' => 'Session expired or invalid.',
],
403
);
}

// Check if session is still valid.
$existing_session = get_transient( "uae_validation_data_{$session_id}" );

$params = $request->get_json_params();
$email = isset( $params['email'] ) ? sanitize_email( $params['email'] ) : '';

if ( empty( $email ) ) {
return new WP_REST_Response(
[
'status' => 'error',
'message' => 'Invalid email address',
],
400
);
}

$status = isset( $existing_session['status'] ) ? $existing_session['status'] : 'pending';

if ( 'pending' !== $status ) {
delete_transient( "uae_validation_data_{$session_id}" );
}

if ( 'valid' === $status ) {
update_option( "uae_onboarding_success", true );
}

return new WP_REST_Response( [ 'status' => $status ], 200 );
}

/**
Expand Down
Loading