plugin updates

This commit is contained in:
Tony Volpe
2024-09-25 09:45:47 -04:00
parent cc870f301f
commit f6021c7c22
245 changed files with 4835 additions and 4671 deletions

View File

@@ -12,6 +12,7 @@ use Leadin\data\Portal_Options;
use Leadin\admin\Connection;
use Leadin\admin\Impact;
use Leadin\data\User_Metadata;
use Leadin\auth\OAuthCryptoError;
/**
* Class containing all the constants used for admin script localization.
@@ -93,7 +94,7 @@ class AdminConstants {
'theme' => get_option( 'stylesheet' ),
'adminUrl' => admin_url(),
'websiteName' => get_bloginfo( 'name' ),
'domain' => parse_url( get_site_url(), PHP_URL_HOST ),
'domain' => wp_parse_url( get_site_url(), PHP_URL_HOST ),
'wp_user' => $wp_user->first_name ? $wp_user->first_name : $wp_user->user_nicename,
'nonce' => self::get_connection_nonce(),
'accountName' => Portal_Options::get_account_name(),
@@ -143,7 +144,10 @@ class AdminConstants {
* Returns a minimal version of leadinConfig, containing the data needed by the background iframe.
*/
public static function get_background_leadin_config() {
$wp_user_id = get_current_user_id();
$wp_user_id = get_current_user_id();
$portal_id = Portal_Options::get_portal_id();
$refresh_token = OAuth::get_refresh_token();
$is_connected = ! empty( $portal_id ) && ! empty( $refresh_token );
$background_config = array(
'adminUrl' => admin_url(),
@@ -153,7 +157,7 @@ class AdminConstants {
'formsScriptPayload' => Filters::apply_forms_payload_filters(),
'meetingsScript' => Filters::apply_meetings_script_url_filters(),
'hublet' => Filters::apply_hublet_filters(),
'hubspotBaseUrl' => Filters::apply_base_url_filters( Connection::is_connected() ),
'hubspotBaseUrl' => Filters::apply_base_url_filters( $is_connected ),
'leadinPluginVersion' => constant( 'LEADIN_PLUGIN_VERSION' ),
'locale' => get_locale(),
'restUrl' => get_rest_url(),
@@ -162,7 +166,7 @@ class AdminConstants {
'phpVersion' => Versions::get_php_version(),
'pluginPath' => constant( 'LEADIN_PATH' ),
'plugins' => get_plugins(),
'portalId' => Portal_Options::get_portal_id(),
'portalId' => $portal_id,
'accountName' => Portal_Options::get_account_name(),
'portalDomain' => Portal_Options::get_portal_domain(),
'portalEmail' => get_user_meta( $wp_user_id, 'leadin_email', true ),
@@ -170,17 +174,18 @@ class AdminConstants {
'theme' => get_option( 'stylesheet' ),
'wpVersion' => Versions::get_wp_version(),
'leadinQueryParams' => self::get_hubspot_query_params_array(),
'connectionStatus' => Connection::is_connected() ? 'Connected' : 'NotConnected',
'connectionStatus' => $is_connected ? 'Connected' : 'NotConnected',
'contentEmbed' => self::get_content_embed_config(),
'requiresContentEmbedScope' => is_plugin_active( 'hubspot-content-embed/content-embed.php' ) ? '1' : '0',
'lastAuthorizeTime' => Portal_Options::get_last_authorize_time(),
'lastDeauthorizeTime' => Portal_Options::get_last_deauthorize_time(),
'lastDisconnectTime' => Portal_Options::get_last_disconnect_time(),
'refreshTokenError' => Portal_Options::get_refresh_token_error(),
);
if ( Connection::is_connected() ) {
$background_config['refreshToken'] = OAuth::get_refresh_token();
if ( false === $refresh_token ) {
$background_config['decryptError'] = OAuthCryptoError::DECRYPT_FAILED;
} else {
$background_config['refreshToken'] = $refresh_token;
}
return $background_config;
@@ -192,7 +197,7 @@ class AdminConstants {
public static function get_leadin_config() {
$leadin_config = self::get_background_leadin_config();
if ( ! Connection::is_connected() ) {
if ( 'NotConnected' === $leadin_config['connectionStatus'] ) {
if ( ! Impact::has_params() ) {
$impact_link = Impact::get_affiliate_link();
if ( ! empty( $impact_link ) ) {

View File

@@ -31,8 +31,6 @@ class Connection {
return ! empty( Portal_Options::get_portal_id() ) && ! empty( OAuth::get_refresh_token() );
}
/**
* Returns true if the current request is for the plugin to connect to a portal
*/

View File

@@ -255,13 +255,15 @@ class LeadinAdmin {
if ( Versions::is_php_version_not_supported() ) {
$error_message = sprintf(
/* translators: %1$s: Plugin current version %2$s: PHP required version */
__( 'HubSpot All-In-One Marketing %1$s requires PHP %2$s or higher Please upgrade WordPress first', 'leadin' ),
LEADIN_PLUGIN_VERSION,
LEADIN_REQUIRED_PHP_VERSION
);
} elseif ( Versions::is_wp_version_not_supported() ) {
$error_message = sprintf(
__( 'HubSpot All-In-One Marketing %1$s requires PHP %2$s or higher Please upgrade WordPress first', 'leadin' ),
/* translators: %1$s: Plugin current version %2$s: WordPress required version */
__( 'HubSpot All-In-One Marketing %1$s requires WordPress %2$s or higher Please upgrade WordPress first', 'leadin' ),
LEADIN_PLUGIN_VERSION,
LEADIN_REQUIRED_WP_VERSION
);

View File

@@ -32,6 +32,7 @@ class NoticeManager {
 
<?php
echo sprintf(
/* translators: %1$s: HTML anchor opening tag %2$s: HTML anchor closing tag */
esc_html( __( 'The HubSpot plugin is not connected right now To use HubSpot tools on your WordPress site, %1$sconnect the plugin now%2$s', 'leadin' ) ),
'<a class="leadin-banner__link" href="admin.php?page=leadin&bannerClick=true">',
'</a>'

View File

@@ -25,14 +25,18 @@ class ReviewBanner {
public function leadin_render_review_banner() {
$nonce = wp_create_nonce( 'leadin-review' );
$dismiss_notice_text = __( 'Dismiss this notice', 'leadin' );
$hello_text = sprintf(
$hello_text = sprintf(
/* translators: %1$s: Current user name or nickname */
__( 'Hey %1$s,', 'leadin' ),
User_Metadata::get_first_name() ? User_Metadata::get_first_name() : User_Metadata::get_nickname()
);
$notice_text = __( 'Have you got 2 minutes to complete %1$sthis survey%2$s about the HubSpot for WordPress plugin?', 'leadin' );
$feedback_text = __( 'We read every response Your feedback helps our team make the improvements that you need the most', 'leadin' );
$from_hubspot_text = __( 'HubSpot for WordPress Team', 'leadin' );
$thanks_message = __( 'Thanks,', 'leadin' );
/* translators: %1$s: HTML anchor opening tag %2$s: HTML anchor closing tag */
$notice_text = __( 'Have you got 2 minutes to complete %1$sthis survey%2$s about the HubSpot for WordPress plugin?', 'leadin' );
$feedback_text = __( 'We read every response Your feedback helps our team make the improvements that you need the most', 'leadin' );
$from_hubspot_text = __( 'HubSpot for WordPress Team', 'leadin' );
$thanks_message = __( 'Thanks,', 'leadin' );
?>
<div id="leadin-review-banner" class="leadin-banner leadin-review-banner leadin-review-banner--hide notice notice-warning">

View File

@@ -40,13 +40,13 @@ class User_Meta_Api_Controller extends Base_Api_Controller {
* @param array $request Request body.
*/
public function track_consent( $request ) {
$data = json_decode( $request->get_body(), true );
$data = wp_json_decode( $request->get_body(), true );
if ( array_key_exists( 'canTrack', $data ) ) {
$consent = $data['canTrack'];
User_Metadata::set_track_consent( $consent ? 'true' : 'false' );
}
return new \WP_REST_Response(
json_encode( User_Metadata::get_track_consent(), true ),
wp_json_encode( User_Metadata::get_track_consent(), true ),
200
);
}

View File

@@ -107,7 +107,7 @@ class ElementorForm extends Widget_Base {
if ( Plugin::$instance->editor->is_edit_mode() ) {
?>
<div class="hubspot-form-edit-mode" data-attributes="<?php echo esc_attr( json_encode( $content ) ); ?>">
<div class="hubspot-form-edit-mode" data-attributes="<?php echo esc_attr( wp_json_encode( $content ) ); ?>">
&nbsp;
</div>
<?php

View File

@@ -100,17 +100,21 @@ class ElementorMeeting extends Widget_Base {
* Render the widget
*/
protected function render() {
$settings = $this->get_settings_for_display();
$content = $settings['content'];
$settings = $this->get_settings_for_display();
$content = $settings['content'];
$parsed_parameters = array(
'url' => isset( $content['url'] ) && filter_var( $content['url'], FILTER_VALIDATE_URL ) ? esc_url_raw( $content['url'] ) : '',
);
if ( Plugin::$instance->editor->is_edit_mode() ) {
?>
<div class="hubspot-meeting-edit-mode" data-attributes=<?php echo json_encode( $content ); ?>>
<div class="hubspot-meeting-edit-mode" data-attributes=<?php echo esc_attr( json_encode( $parsed_parameters ) ); ?>>
&nbsp;
</div>
<?php
if ( empty( $content ) ) {
if ( empty( $parsed_parameters['url'] ) ) {
?>
<div class="hubspot-widget-empty">
@@ -119,9 +123,8 @@ class ElementorMeeting extends Widget_Base {
}
}
if ( ! empty( $content ) ) {
$url = $content['url'];
echo do_shortcode( '[hubspot url="' . $url . '" type="meeting"]' );
if ( ! empty( $parsed_parameters['url'] ) ) {
echo do_shortcode( '[hubspot url="' . $parsed_parameters['url'] . '" type="meeting"]' );
}
}
}

View File

@@ -13,9 +13,6 @@ use Leadin\admin\MenuConstants;
*/
class OAuth {
const MAX_RETRIES = 3;
const RETRY_DELAY_MICROSECONDS = 100000; // 100ms converted to microseconds
/**
* Authorizes the plugin with given oauth credentials by storing them in the options DB.
*
@@ -38,33 +35,28 @@ class OAuth {
}
/**
* Attempts to get and decrypt the refresh token with retries.
* Attempts to get and decrypt the refresh token.
* Records an error if decryption fails or if the token is invalid.
*
* @return string The decrypted refresh token, or an empty string on failure.
* Note: WordPress sites that are missing keys and salts will have the refresh token stored in plaintext.
* The decrypt function will return the plaintext token in this case.
*
* @return string The result of decrypt function, or an empty string on failure.
*/
public static function get_refresh_token() {
for ( $attempt = 0; $attempt < self::MAX_RETRIES; $attempt++ ) {
$encrypted_refresh_token = Portal_Options::get_refresh_token();
$encrypted_refresh_token = Portal_Options::get_refresh_token();
if ( ! self::is_valid_value( $encrypted_refresh_token ) ) {
Portal_Options::set_refresh_token_error( 'Token is invalid or missing' );
self::retry_delay();
continue;
}
$refresh_token = OAuthCrypto::decrypt( $encrypted_refresh_token );
if ( ! self::is_valid_value( $refresh_token ) ) {
Portal_Options::set_refresh_token_error( 'Decryption failed' );
self::retry_delay();
continue;
}
return $refresh_token;
if ( ! self::is_valid_value( $encrypted_refresh_token ) ) {
return '';
}
return '';
$refresh_token = OAuthCrypto::decrypt( $encrypted_refresh_token );
if ( ! self::is_valid_value( $refresh_token ) ) {
return false;
}
return $refresh_token;
}
/**
@@ -76,11 +68,4 @@ class OAuth {
private static function is_valid_value( $value ) {
return false !== $value && null !== $value && '' !== $value;
}
/**
* Delays the execution to handle transient issues before retrying.
*/
private static function retry_delay() {
usleep( self::RETRY_DELAY_MICROSECONDS );
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Leadin\auth;
/**
* Error codes for OAuthCrypto
*/
class OAuthCryptoError {
const DECRYPT_FAILED = 'DECRYPT_FAILED';
}

View File

@@ -134,9 +134,11 @@ class AssetsManager {
public static function localize_gutenberg() {
$embed_domain = Filters::apply_js_base_url_filters();
wp_enqueue_script( self::APP_EMBEDDER, "$embed_domain/integrated-app-embedder/v1.js", array(), LEADIN_PLUGIN_VERSION, true );
self::enqueue_forms_script();
self::enqueue_meetings_script();
wp_register_style( self::GUTENBERG, LEADIN_JS_BASE_PATH . '/gutenberg.css', array(), LEADIN_PLUGIN_VERSION );
wp_enqueue_style( self::GUTENBERG );
wp_register_script( self::GUTENBERG, LEADIN_JS_BASE_PATH . '/gutenberg.js', array( 'wp-blocks', 'wp-element', 'wp-i18n', self::APP_EMBEDDER ), LEADIN_PLUGIN_VERSION, true );
wp_register_script( self::GUTENBERG, LEADIN_JS_BASE_PATH . '/gutenberg.js', array( 'wp-blocks', 'wp-element', 'wp-i18n', self::APP_EMBEDDER, self::MEETINGS_SCRIPT, self::FORMS_SCRIPT ), LEADIN_PLUGIN_VERSION, true );
wp_localize_script( self::GUTENBERG, self::LEADIN_CONFIG, AdminConstants::get_background_leadin_config() );
wp_set_script_translations( self::GUTENBERG, 'leadin', __DIR__ . '/../languages' );
}

View File

@@ -17,8 +17,6 @@ class Portal_Options {
const LAST_AUTHORIZE_TIME = LEADIN_PREFIX . '_last_authorize_time';
const LAST_DEAUTHORIZE_TIME = LEADIN_PREFIX . '_last_deauthorize_time';
const LAST_DISCONNECT_TIME = LEADIN_PREFIX . '_last_disconnect_time';
const REFRESH_TOKEN_ERROR = LEADIN_PREFIX . '_refresh_token_error';
/**
* Return portal id.
*/
@@ -230,15 +228,6 @@ class Portal_Options {
return update_option( self::LAST_DISCONNECT_TIME, time() );
}
/**
* Set if the refresh token failed to be retrieved.
*
* @param string $error the error message.
*/
public static function set_refresh_token_error( $error = 'unknown' ) {
return update_option( self::REFRESH_TOKEN_ERROR, $error );
}
/**
* Get the last time authorization was performed.
*
@@ -265,14 +254,4 @@ class Portal_Options {
public static function get_last_disconnect_time() {
return get_option( self::LAST_DISCONNECT_TIME, false );
}
/**
* Get the last error message for when retrieving the refresh token failed.
*
* @return string The error message, or 'unknown' if not set.
*/
public static function get_refresh_token_error() {
return get_option( self::REFRESH_TOKEN_ERROR, 'unknown' );
}
}