plugin installs
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin;
|
||||
|
||||
use Leadin\data\Filters;
|
||||
use Leadin\admin\Links;
|
||||
use Leadin\admin\Routing;
|
||||
use Leadin\auth\OAuth;
|
||||
use Leadin\utils\Versions;
|
||||
use Leadin\data\User;
|
||||
use Leadin\data\Portal_Options;
|
||||
use Leadin\admin\Connection;
|
||||
use Leadin\admin\Impact;
|
||||
use Leadin\data\User_Metadata;
|
||||
|
||||
/**
|
||||
* Class containing all the constants used for admin script localization.
|
||||
*/
|
||||
class AdminConstants {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return utm_campaign to add to the signup link.
|
||||
*/
|
||||
private static function get_utm_campaign() {
|
||||
$wpe_template = get_option( 'wpe_template' );
|
||||
if ( 'hubspot' === $wpe_template ) {
|
||||
return 'wp-engine-site-template';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array with the utm parameters for signup
|
||||
*/
|
||||
private static function get_utm_query_params_array() {
|
||||
$utm_params = array(
|
||||
'utm_source' => 'wordpress-plugin',
|
||||
'utm_medium' => 'marketplaces',
|
||||
);
|
||||
|
||||
$utm_campaign = self::get_utm_campaign();
|
||||
if ( ! empty( $utm_campaign ) ) {
|
||||
$utm_params['utm_campaign'] = $utm_campaign;
|
||||
}
|
||||
return $utm_params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a nonce used on the connection class
|
||||
*/
|
||||
private static function get_connection_nonce() {
|
||||
return wp_create_nonce( 'hubspot-nonce' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array with the user's pre-fill info for signup
|
||||
*/
|
||||
private static function get_signup_prefill_params_array() {
|
||||
$wp_user = wp_get_current_user();
|
||||
$user_info = array(
|
||||
'firstName' => $wp_user->user_firstname,
|
||||
'lastName' => $wp_user->user_lastname,
|
||||
'email' => $wp_user->user_email,
|
||||
'company' => get_bloginfo( 'name' ),
|
||||
);
|
||||
|
||||
return $user_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of properties to be included in the signup search string
|
||||
*/
|
||||
public static function get_signup_query_params_array() {
|
||||
$signup_params = array();
|
||||
$signup_params['leadinPluginVersion'] = constant( 'LEADIN_PLUGIN_VERSION' );
|
||||
$signup_params['trackConsent'] = User_Metadata::get_track_consent();
|
||||
$user_prefill_params = self::get_signup_prefill_params_array();
|
||||
$signup_params = array_merge( $signup_params, $user_prefill_params );
|
||||
return $signup_params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return query params array for the iframe.
|
||||
*/
|
||||
public static function get_hubspot_query_params_array() {
|
||||
$wp_user = wp_get_current_user();
|
||||
$hubspot_config = array(
|
||||
'l' => get_locale(),
|
||||
'php' => Versions::get_php_version(),
|
||||
'v' => LEADIN_PLUGIN_VERSION,
|
||||
'wp' => Versions::get_wp_version(),
|
||||
'theme' => get_option( 'stylesheet' ),
|
||||
'adminUrl' => admin_url(),
|
||||
'websiteName' => get_bloginfo( 'name' ),
|
||||
'domain' => 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(),
|
||||
'hsdio' => Portal_Options::get_device_id(),
|
||||
'portalDomain' => Portal_Options::get_portal_domain(),
|
||||
);
|
||||
|
||||
$utm_params = self::get_utm_query_params_array();
|
||||
$hubspot_config = array_merge( $hubspot_config, $utm_params );
|
||||
|
||||
if ( User::is_admin() ) {
|
||||
$hubspot_config['admin'] = '1';
|
||||
}
|
||||
|
||||
if ( Routing::has_just_connected_with_oauth() ) {
|
||||
$hubspot_config['justConnected'] = true;
|
||||
}
|
||||
if ( Routing::is_new_portal_with_oauth() ) {
|
||||
$hubspot_config['isNewPortal'] = true;
|
||||
}
|
||||
|
||||
if ( ! Connection::is_connected() ) {
|
||||
$signup_params = self::get_signup_query_params_array();
|
||||
$hubspot_config = array_merge( $hubspot_config, $signup_params, Impact::get_params() );
|
||||
}
|
||||
|
||||
return $hubspot_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about Content embed plugin necessary for user guide to determine if/how to install & activate
|
||||
*/
|
||||
public static function get_content_embed_config() {
|
||||
$content_embed_config = array_merge(
|
||||
array(
|
||||
'userCanInstall' => current_user_can( 'install_plugins' ),
|
||||
'userCanActivate' => current_user_can( 'activate_plugins' ),
|
||||
'nonce' => wp_create_nonce( ContentEmbedInstaller::INSTALL_ARG ),
|
||||
),
|
||||
ContentEmbedInstaller::is_content_embed_active_installed()
|
||||
);
|
||||
|
||||
return $content_embed_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
$background_config = array(
|
||||
'adminUrl' => admin_url(),
|
||||
'activationTime' => Portal_Options::get_activation_time(),
|
||||
'deviceId' => Portal_Options::get_device_id(),
|
||||
'formsScript' => Filters::apply_forms_script_url_filters(),
|
||||
'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() ),
|
||||
'leadinPluginVersion' => constant( 'LEADIN_PLUGIN_VERSION' ),
|
||||
'locale' => get_locale(),
|
||||
'restUrl' => get_rest_url(),
|
||||
'restNonce' => wp_create_nonce( 'wp_rest' ),
|
||||
'redirectNonce' => wp_create_nonce( Routing::REDIRECT_NONCE ),
|
||||
'phpVersion' => Versions::get_php_version(),
|
||||
'pluginPath' => constant( 'LEADIN_PATH' ),
|
||||
'plugins' => get_plugins(),
|
||||
'portalId' => Portal_Options::get_portal_id(),
|
||||
'accountName' => Portal_Options::get_account_name(),
|
||||
'portalDomain' => Portal_Options::get_portal_domain(),
|
||||
'portalEmail' => get_user_meta( $wp_user_id, 'leadin_email', true ),
|
||||
'reviewSkippedDate' => User_Metadata::get_skip_review(),
|
||||
'theme' => get_option( 'stylesheet' ),
|
||||
'wpVersion' => Versions::get_wp_version(),
|
||||
'leadinQueryParams' => self::get_hubspot_query_params_array(),
|
||||
'connectionStatus' => Connection::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();
|
||||
}
|
||||
|
||||
return $background_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns leadinConfig, containing all the data needed by the leadin javascript.
|
||||
*/
|
||||
public static function get_leadin_config() {
|
||||
$leadin_config = self::get_background_leadin_config();
|
||||
|
||||
if ( ! Connection::is_connected() ) {
|
||||
if ( ! Impact::has_params() ) {
|
||||
$impact_link = Impact::get_affiliate_link();
|
||||
if ( ! empty( $impact_link ) ) {
|
||||
$leadin_config['impactLink'] = Impact::get_affiliate_link();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $leadin_config;
|
||||
}
|
||||
}
|
||||
168
wp/wp-content/plugins/leadin/public/admin/class-connection.php
Normal file
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin;
|
||||
|
||||
use Leadin\data\Portal_Options;
|
||||
use Leadin\data\User;
|
||||
use Leadin\utils\QueryParameters;
|
||||
use Leadin\auth\OAuth;
|
||||
|
||||
/**
|
||||
* Handles portal connection to the plugin.
|
||||
*/
|
||||
class Connection {
|
||||
|
||||
const CONNECT_KEYS = array(
|
||||
'refresh_token',
|
||||
'expires_in',
|
||||
'portal_id',
|
||||
'portal_domain',
|
||||
'portal_name',
|
||||
'hublet',
|
||||
);
|
||||
|
||||
const CONNECT_NONCE_ARG = 'leadin_connect';
|
||||
const DISCONNECT_NONCE_ARG = 'leadin_disconnect';
|
||||
|
||||
/**
|
||||
* Returns true if a portal has been connected to the plugin
|
||||
*/
|
||||
public static function is_connected() {
|
||||
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
|
||||
*/
|
||||
public static function is_connection_requested() {
|
||||
$maybe_leadin_connect = QueryParameters::get_param( self::CONNECT_NONCE_ARG, 'hubspot-nonce', self::CONNECT_NONCE_ARG );
|
||||
$maybe_refresh_token = QueryParameters::get_param( 'refresh_token', 'hubspot-nonce', self::CONNECT_NONCE_ARG );
|
||||
|
||||
return isset( $maybe_leadin_connect ) && isset( $maybe_refresh_token );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current request is for the plugin to connect to a portal
|
||||
*/
|
||||
public static function is_new_portal() {
|
||||
$maybe_is_new_portal = QueryParameters::get_param( 'is_new_portal', 'hubspot-nonce', self::CONNECT_NONCE_ARG );
|
||||
|
||||
return isset( $maybe_is_new_portal );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current request is to disconnect the plugin from the portal
|
||||
*/
|
||||
public static function is_disconnection_requested() {
|
||||
$maybe_leadin_disconnect = QueryParameters::get_param( self::DISCONNECT_NONCE_ARG, 'hubspot-nonce', self::DISCONNECT_NONCE_ARG );
|
||||
return isset( $maybe_leadin_disconnect );
|
||||
}
|
||||
/**
|
||||
* Retrieves user ID and create new metadata
|
||||
*
|
||||
* @param Array $user_meta array of pairs metadata - value.
|
||||
*/
|
||||
private static function add_metadata( $user_meta ) {
|
||||
$wp_user = wp_get_current_user();
|
||||
$wp_user_id = $wp_user->ID;
|
||||
foreach ( $user_meta as $key => $value ) {
|
||||
add_user_meta( $wp_user_id, $key, $value );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves user ID and deletes a piece of the users meta data.
|
||||
*
|
||||
* @param String $meta_key is the key of the data you want to delete.
|
||||
*/
|
||||
private static function delete_metadata( $meta_key ) {
|
||||
$wp_user = wp_get_current_user();
|
||||
$wp_user_id = $wp_user->ID;
|
||||
delete_user_meta( $wp_user_id, $meta_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect portal id, domain, name to WordPress options and HubSpot email to user meta data.
|
||||
*
|
||||
* @param Number $portal_id HubSpot account id.
|
||||
* @param String $portal_name HubSpot account name.
|
||||
* @param String $portal_domain HubSpot account domain.
|
||||
* @param String $hs_user_email HubSpot user email.
|
||||
* @param String $hublet HubSpot account's hublet.
|
||||
*/
|
||||
public static function connect( $portal_id, $portal_name, $portal_domain, $hs_user_email, $hublet ) {
|
||||
self::disconnect();
|
||||
self::store_portal_info( $portal_id, $portal_name, $portal_domain, $hublet );
|
||||
self::add_metadata( array( 'leadin_email' => $hs_user_email ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect the plugin with OAuthorization. Storing OAuth tokens and metadata for the connected portal.
|
||||
*/
|
||||
public static function oauth_connect() {
|
||||
$connect_params = QueryParameters::get_parameters( self::CONNECT_KEYS, 'hubspot-nonce', self::CONNECT_NONCE_ARG );
|
||||
|
||||
self::disconnect();
|
||||
self::store_portal_info(
|
||||
$connect_params['portal_id'],
|
||||
$connect_params['portal_name'],
|
||||
$connect_params['portal_domain'],
|
||||
$connect_params['hublet']
|
||||
);
|
||||
|
||||
OAuth::authorize( $connect_params['refresh_token'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes portal id and domain from the WordPress options.
|
||||
*/
|
||||
public static function disconnect() {
|
||||
Portal_Options::set_last_disconnect_time();
|
||||
|
||||
self::delete_portal_info();
|
||||
|
||||
$users = get_users(
|
||||
array( 'role__in' => array( 'administrator', 'editor' ) ),
|
||||
array( 'fields' => array( 'ID' ) )
|
||||
);
|
||||
foreach ( $users as $user ) {
|
||||
delete_user_meta( $user->ID, 'leadin_email' );
|
||||
delete_user_meta( $user->ID, 'leadin_skip_review' );
|
||||
delete_user_meta( $user->ID, 'leadin_review_banner_last_call' );
|
||||
delete_user_meta( $user->ID, 'leadin_has_min_contacts' );
|
||||
delete_user_meta( $user->ID, 'leadin_track_consent' );
|
||||
}
|
||||
|
||||
OAuth::deauthorize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the portal metadata for connecting the plugin in the options table
|
||||
*
|
||||
* @param String $portal_id ID for connecting portal.
|
||||
* @param String $portal_name Name of the connecting portal.
|
||||
* @param String $portal_domain Domain for the connecting portal.
|
||||
* @param String $hublet Hublet for the connecting portal.
|
||||
*/
|
||||
public static function store_portal_info( $portal_id, $portal_name, $portal_domain, $hublet ) {
|
||||
Portal_Options::set_portal_id( $portal_id );
|
||||
Portal_Options::set_account_name( $portal_name );
|
||||
Portal_Options::set_portal_domain( $portal_domain );
|
||||
Portal_Options::set_hublet( $hublet );
|
||||
Portal_Options::set_disable_internal_tracking();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete stored portal metadata for disconnecting the plugin from the options table
|
||||
*/
|
||||
private static function delete_portal_info() {
|
||||
Portal_Options::delete_portal_id();
|
||||
Portal_Options::delete_account_name();
|
||||
Portal_Options::delete_portal_domain();
|
||||
Portal_Options::delete_hublet();
|
||||
Portal_Options::delete_disable_internal_tracking();
|
||||
Portal_Options::delete_business_unit_id();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin;
|
||||
|
||||
use Leadin\utils\QueryParameters;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class used to install the Content embed plugin
|
||||
*/
|
||||
class ContentEmbedInstaller {
|
||||
|
||||
const CONTENT_EMBED_LINK = 'https://api.hubapi.com/content-embed/v1/plugin/download/content-hub-embed.zip';
|
||||
const INSTALL_ARG = 'contentembed_install';
|
||||
const INSTALL_OPTION = LEADIN_PREFIX . '_content_embed_ui_install';
|
||||
|
||||
/**
|
||||
* Class constructor, adds the necessary hooks.
|
||||
*/
|
||||
public function __construct() {
|
||||
if ( is_admin() ) {
|
||||
add_action( 'wp_ajax_content_embed_install', array( $this, 'wp_ajax_install_content_embed' ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* AJAX to install Content embed plugin by downloading from URL in Content embed API.
|
||||
* Modified from: https://github.com/WordPress/wordpress-develop/blob/trunk/src/wp-admin/includes/ajax-actions.php#L4444
|
||||
*/
|
||||
public function wp_ajax_install_content_embed() {
|
||||
$nonce = isset( $_REQUEST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( ( $_REQUEST['_wpnonce'] ) ) ) : '';
|
||||
|
||||
if ( ! current_user_can( 'install_plugins' ) || ! wp_verify_nonce( $nonce, self::INSTALL_ARG ) ) {
|
||||
$status['errorCode'] = 'PERMISSIONS_ERROR';
|
||||
$status['errorMessage'] = 'User does not have permission to install or activate plugins.';
|
||||
return wp_send_json_error( $status, 403 );
|
||||
}
|
||||
|
||||
$active_or_installed = self::is_content_embed_active_installed();
|
||||
$activated = $active_or_installed['active'];
|
||||
$installed = $active_or_installed['installed'];
|
||||
|
||||
if ( $activated || $installed ) {
|
||||
$status['errorCode'] = $activated ? 'ALREADY_ACTIVATED' : 'ALREADY_INSTALLED';
|
||||
$status['errorMessage'] = 'Content embed already installed or activated';
|
||||
wp_send_json_error( $status );
|
||||
}
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
|
||||
$skin = new \WP_Ajax_Upgrader_Skin();
|
||||
$upgrader = new \Plugin_Upgrader( $skin );
|
||||
$result = $upgrader->install( self::CONTENT_EMBED_LINK );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
$status['errorCode'] = 'GENERIC_ERROR';
|
||||
$status['errorMessage'] = $result->get_error_message();
|
||||
wp_send_json_error( $status );
|
||||
}
|
||||
|
||||
if ( is_wp_error( $skin->result ) ) {
|
||||
$status['errorCode'] = 'GENERIC_ERROR';
|
||||
$status['errorMessage'] = $skin->result->get_error_message();
|
||||
wp_send_json_error( $status );
|
||||
}
|
||||
|
||||
if ( $skin->get_errors()->has_errors() ) {
|
||||
$status['errorCode'] = 'GENERIC_ERROR';
|
||||
$status['errorMessage'] = $skin->get_error_messages();
|
||||
wp_send_json_error( $status );
|
||||
}
|
||||
|
||||
if ( is_null( $result ) ) {
|
||||
global $wp_filesystem;
|
||||
$status['errorCode'] = 'FILESYSTEM_ERROR';
|
||||
$status['errorMessage'] = 'Unable to connect to the filesystem. Please confirm your credentials.';
|
||||
|
||||
// Pass through the error from WP_Filesystem if one was raised.
|
||||
if ( $wp_filesystem instanceof \WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->has_errors() ) {
|
||||
$status['errorMessage'] = esc_html( $wp_filesystem->errors->get_error_message() );
|
||||
}
|
||||
wp_send_json_error( $status );
|
||||
}
|
||||
|
||||
$plugin_info = $upgrader->plugin_info();
|
||||
if ( ! $plugin_info ) {
|
||||
return wp_send_json_error(
|
||||
array(
|
||||
'errorCode' => 'INFO_FETCH_ERROR',
|
||||
'errorMessage' => 'Plugin installation failed, could not retrieve plugin info',
|
||||
),
|
||||
500
|
||||
);
|
||||
}
|
||||
|
||||
$status = array(
|
||||
'message' => 'Plugin installed and activated successfully',
|
||||
'plugin_info' => $plugin_info,
|
||||
'activated' => false,
|
||||
);
|
||||
|
||||
if ( current_user_can( 'activate_plugins' ) ) {
|
||||
$activation_response = activate_plugin( $plugin_info );
|
||||
if ( is_wp_error( $activation_response ) ) {
|
||||
$status['errorCode'] = 'ACTIVATION_ERROR';
|
||||
$status['errorMessage'] = $activation_response->get_error_message();
|
||||
} else {
|
||||
$status['activated'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
update_option( self::INSTALL_OPTION, true );
|
||||
return wp_send_json_success( $status );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if there is a copy of Content embed installed, and if so, if it is active.
|
||||
* Checks for path names with junk at the end to handle multiple installs
|
||||
*/
|
||||
public static function is_content_embed_active_installed() {
|
||||
$content_embed_regex = '/hubspot-content-embed((-.*)?)\/content-embed.php/';
|
||||
if ( ! function_exists( 'get_plugins' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
// Filter based on regex in case there are multiple copies installed for some reason.
|
||||
$all_plugins = array_keys( get_plugins() );
|
||||
$content_embed_paths = array_filter(
|
||||
$all_plugins,
|
||||
function ( $plugin_path ) use ( $content_embed_regex ) {
|
||||
return preg_match( $content_embed_regex, $plugin_path );
|
||||
}
|
||||
);
|
||||
|
||||
$installed = ! empty( $content_embed_paths );
|
||||
$active = ! empty(
|
||||
array_filter(
|
||||
$content_embed_paths,
|
||||
function ( $plugin_path ) {
|
||||
return is_plugin_active( $plugin_path );
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
return array(
|
||||
'installed' => $installed,
|
||||
'active' => $active,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin;
|
||||
|
||||
use Leadin\data\Portal_Options;
|
||||
use \Leadin\includes\utils as utils;
|
||||
|
||||
/**
|
||||
* Class responsible for rendering the deactivation feedback form.
|
||||
*/
|
||||
class DeactivationForm {
|
||||
|
||||
/**
|
||||
* Class constructor, adds necessary hooks.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'admin_footer', array( $this, 'add_feedback_form' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render deactivation feedback form on plugin page.
|
||||
*/
|
||||
public function add_feedback_form() {
|
||||
if ( get_current_screen()->id === 'plugins' ) {
|
||||
// handlers and logic are added via jQuery in the frontend.
|
||||
?>
|
||||
<div id="leadin-feedback-container" style="display: none;">
|
||||
<div class="leadin-feedback-header">
|
||||
<h2><?php echo esc_html( __( "We're sorry to see you go", 'leadin' ) ); ?></h2>
|
||||
<div class="leadin-modal-close">
|
||||
<svg class="leadin-close-svg" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
|
||||
<path class="leadin-close-path" d="M14.5,1.5l-13,13m0-13,13,13" transform="translate(-1 -1)"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="leadin-feedback-body">
|
||||
<div>
|
||||
<strong>
|
||||
<?php echo esc_html( __( "If you have a moment, please let us know why you're deactivating the plugin", 'leadin' ) ); ?>
|
||||
</strong>
|
||||
</div>
|
||||
<form id='leadin-deactivate-form' class="leadin-deactivate-form">
|
||||
<?php
|
||||
$radio_buttons = array(
|
||||
"I can't sign up or log in",
|
||||
'The plugin is impacting website performance',
|
||||
"The plugin isn't working",
|
||||
"The plugin isn't useful",
|
||||
'Temporarily disabling or troubleshooting',
|
||||
'Other',
|
||||
);
|
||||
|
||||
$radio_button_translations = array(
|
||||
__( "I can't sign up or log in", 'leadin' ),
|
||||
__( 'The plugin is impacting website performance', 'leadin' ),
|
||||
__( "The plugin isn't working", 'leadin' ),
|
||||
__( "The plugin isn't useful", 'leadin' ),
|
||||
__( 'Temporarily disabling or troubleshooting', 'leadin' ),
|
||||
__( 'Other', 'leadin' ),
|
||||
);
|
||||
|
||||
$buttons_count = count( $radio_buttons );
|
||||
for ( $i = 0; $i < $buttons_count; $i++ ) {
|
||||
?>
|
||||
<div class="leadin-radio-input-container">
|
||||
<input
|
||||
type="radio"
|
||||
id="leadinFeedback<?php echo esc_attr( $i ); ?>"
|
||||
name="feedback"
|
||||
value="<?php echo esc_attr( $radio_buttons[ $i ] ); ?>"
|
||||
class="leadin-feedback-radio"
|
||||
required
|
||||
>
|
||||
<label for="leadinFeedback<?php echo esc_attr( $i ); ?>">
|
||||
<?php echo esc_html( $radio_button_translations[ $i ] ); ?>
|
||||
</label>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<textarea name="details" class="leadin-feedback-text-area leadin-feedback-text-control" placeholder="<?php echo esc_html( __( 'Feedback', 'leadin' ) ); ?>"></textarea>
|
||||
<input type="hidden" name="portal_id" value="<?php echo esc_html( Portal_Options::get_portal_id() ); ?>">
|
||||
<div class="leadin-button-container">
|
||||
<button type="submit" id="leadin-feedback-submit" class="leadin-button leadin-primary-button leadin-loader-button">
|
||||
<div class="leadin-loader-button-content">
|
||||
<?php echo esc_html( __( 'Submit & deactivate', 'leadin' ) ); ?>
|
||||
</div>
|
||||
<div class="leadin-loader"></div>
|
||||
</button>
|
||||
<button type="button" id="leadin-feedback-skip" class="leadin-button leadin-secondary-button">
|
||||
<?php echo esc_html( __( 'Skip & deactivate', 'leadin' ) ); ?>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin;
|
||||
|
||||
use Leadin\AssetsManager;
|
||||
use Leadin\utils\Versions;
|
||||
|
||||
/**
|
||||
* Contains all the methods used to initialize Gutenberg blocks.
|
||||
*/
|
||||
class Gutenberg {
|
||||
/**
|
||||
* Class constructor, register Gutenberg blocks.
|
||||
*/
|
||||
public function __construct() {
|
||||
if ( ! function_exists( 'register_block_type' ) ) {
|
||||
// Gutenberg is not active.
|
||||
return;
|
||||
}
|
||||
|
||||
add_action( 'init', array( $this, 'register_gutenberg_block' ) );
|
||||
add_filter( 'block_categories_all', array( $this, 'add_hubspot_category' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add HubSpot category to Gutenberg blocks.
|
||||
*
|
||||
* @param Array $categories Array of block categories.
|
||||
*/
|
||||
public function add_hubspot_category( $categories ) {
|
||||
return array_merge(
|
||||
$categories,
|
||||
array(
|
||||
array(
|
||||
'slug' => 'leadin-blocks',
|
||||
'title' => __( 'HubSpot', 'leadin' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Register HubSpot Form Gutenberg block.
|
||||
*/
|
||||
public function register_gutenberg_block() {
|
||||
AssetsManager::localize_gutenberg();
|
||||
register_block_type(
|
||||
'leadin/hubspot-blocks',
|
||||
array(
|
||||
'editor_script' => AssetsManager::GUTENBERG,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
46
wp/wp-content/plugins/leadin/public/admin/class-impact.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin;
|
||||
|
||||
use Leadin\data\Filters;
|
||||
|
||||
const IR_CLICK_ID = 'irclickid';
|
||||
const MPID = 'mpid';
|
||||
|
||||
/**
|
||||
* Class containing the logic to get Impact affiliate information when necessary
|
||||
*/
|
||||
class Impact {
|
||||
/**
|
||||
* Apply leadin_impact_code filter.
|
||||
*/
|
||||
public static function get_affiliate_link() {
|
||||
return Filters::apply_impact_code_filters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get impact properties from query parameters.
|
||||
*/
|
||||
public static function get_params() {
|
||||
$params = array();
|
||||
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||
if ( isset( $_GET['leadin_irclickid'] ) ) {
|
||||
$params[ IR_CLICK_ID ] = sanitize_text_field( \wp_unslash( $_GET['leadin_irclickid'] ) );
|
||||
}
|
||||
|
||||
if ( isset( $_GET['leadin_mpid'] ) ) {
|
||||
$params[ MPID ] = sanitize_text_field( \wp_unslash( $_GET['leadin_mpid'] ) );
|
||||
}
|
||||
// phpcs:enable
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the function `get_params` returns both irclickid and mpid.
|
||||
*/
|
||||
public static function has_params() {
|
||||
return 2 === \count( self::get_params() );
|
||||
}
|
||||
}
|
||||
286
wp/wp-content/plugins/leadin/public/admin/class-leadinadmin.php
Normal file
@@ -0,0 +1,286 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin;
|
||||
|
||||
use Leadin\AssetsManager;
|
||||
use Leadin\data\User;
|
||||
use Leadin\admin\Connection;
|
||||
use Leadin\data\User_Metadata;
|
||||
use Leadin\admin\MenuConstants;
|
||||
use Leadin\admin\Gutenberg;
|
||||
use Leadin\admin\NoticeManager;
|
||||
use Leadin\admin\PluginActionsManager;
|
||||
use Leadin\admin\DeactivationForm;
|
||||
use Leadin\admin\Links;
|
||||
use Leadin\admin\ContentEmbedInstaller;
|
||||
use Leadin\auth\OAuth;
|
||||
use Leadin\admin\utils\Background;
|
||||
use Leadin\utils\QueryParameters;
|
||||
use Leadin\utils\Versions;
|
||||
use Leadin\includes\utils as utils;
|
||||
|
||||
use Leadin\data\Portal_Options;
|
||||
use Leadin\data\Filters;
|
||||
|
||||
/**
|
||||
* Class responsible for initializing the admin side of the plugin.
|
||||
*/
|
||||
class LeadinAdmin {
|
||||
|
||||
const REDIRECT_TRANSIENT = 'leadin_redirect_after_activation';
|
||||
|
||||
/**
|
||||
* Class constructor, adds all the hooks and instantiate the APIs.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'plugins_loaded', array( $this, 'load_languages' ), 14 );
|
||||
add_action( 'admin_init', array( $this, 'redirect_after_activation' ) );
|
||||
add_action( 'admin_init', array( $this, 'store_activation_time' ) );
|
||||
add_action( 'admin_init', array( $this, 'authorize' ) );
|
||||
add_action( 'admin_init', array( $this, 'check_review_requested' ) );
|
||||
add_action( 'admin_menu', array( $this, 'build_menu' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
register_activation_hook( LEADIN_BASE_PATH, array( $this, 'do_activate_action' ) );
|
||||
|
||||
/**
|
||||
* The following hooks are public APIs.
|
||||
*/
|
||||
add_action( 'leadin_redirect', array( $this, 'set_redirect_transient' ) );
|
||||
add_action( 'leadin_activate', array( $this, 'do_redirect_action' ), 100 );
|
||||
|
||||
new PluginActionsManager();
|
||||
new DeactivationForm();
|
||||
new NoticeManager();
|
||||
new Gutenberg();
|
||||
new ContentEmbedInstaller();
|
||||
add_action( 'elementor/documents/register_controls', array( $this, 'register_document_controls' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register additional document controls.
|
||||
*
|
||||
* @param \Elementor\Core\DocumentTypes\PageBase $document The PageBase document instance.
|
||||
*/
|
||||
public function register_document_controls( $document ) {
|
||||
if ( ! $document instanceof \Elementor\Core\DocumentTypes\PageBase || ! $document::get_property( 'has_elements' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$document->start_controls_section(
|
||||
'hubspot',
|
||||
array(
|
||||
'label' => esc_html__( 'Hubspot', 'leadin' ),
|
||||
'tab' => \Elementor\Controls_Manager::TAB_SETTINGS,
|
||||
)
|
||||
);
|
||||
|
||||
$document->add_control(
|
||||
'content_type',
|
||||
array(
|
||||
'label' => esc_html__( 'Select the content type HubSpot Analytics uses to track this page', 'leadin' ),
|
||||
'label_block' => true,
|
||||
'type' => \Elementor\Controls_Manager::SELECT,
|
||||
'options' => array(
|
||||
'' => esc_html__( 'Detect Automatically', 'leadin' ),
|
||||
'blog-post' => esc_html__( 'Blog Post', 'leadin' ),
|
||||
'knowledge-article' => esc_html__( 'Knowledge Article', 'leadin' ),
|
||||
'landing-page' => esc_html__( 'Landing Page', 'leadin' ),
|
||||
'listing-page' => esc_html__( 'Listing Page', 'leadin' ),
|
||||
'standard-page' => esc_html__( 'Standard Page', 'leadin' ),
|
||||
),
|
||||
'default' => '',
|
||||
)
|
||||
);
|
||||
|
||||
$document->end_controls_section();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Load the .mo language files.
|
||||
*/
|
||||
public function load_languages() {
|
||||
load_plugin_textdomain( 'leadin', false, '/leadin/languages' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler called on plugin activation.
|
||||
*/
|
||||
public function do_activate_action() {
|
||||
\do_action( 'leadin_activate' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the leadin_activate action.
|
||||
*/
|
||||
public function do_redirect_action() {
|
||||
\do_action( 'leadin_redirect' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set transient after activating the plugin.
|
||||
*/
|
||||
public function set_redirect_transient() {
|
||||
set_transient( self::REDIRECT_TRANSIENT, true, 60 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to the dashboard after activation.
|
||||
*/
|
||||
public function redirect_after_activation() {
|
||||
if ( get_transient( self::REDIRECT_TRANSIENT ) ) {
|
||||
delete_transient( self::REDIRECT_TRANSIENT );
|
||||
wp_safe_redirect( admin_url( 'admin.php?page=leadin' ) );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect/disconnect the plugin
|
||||
*/
|
||||
public function authorize() {
|
||||
if ( User::is_admin() ) {
|
||||
if ( Connection::is_connection_requested() ) {
|
||||
$redirect_params = array();
|
||||
Connection::oauth_connect();
|
||||
$redirect_params['leadin_just_connected'] = 1;
|
||||
|
||||
if ( Connection::is_new_portal() ) {
|
||||
$redirect_params['is_new_portal'] = 1;
|
||||
}
|
||||
Routing::redirect( MenuConstants::USER_GUIDE, $redirect_params );
|
||||
} elseif ( Connection::is_disconnection_requested() ) {
|
||||
Connection::disconnect();
|
||||
Routing::redirect( MenuConstants::ROOT );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if query parameter for review is present on the request
|
||||
* then add user metadata to persist review time
|
||||
* Redirects if value is equal to true
|
||||
*/
|
||||
public function check_review_requested() {
|
||||
if ( Connection::is_connected() && Routing::has_review_request() ) {
|
||||
User_Metadata::set_skip_review( time() );
|
||||
if ( Routing::is_review_request() ) {
|
||||
header( 'Location: https://survey.hsforms.com/1ILAEu_k_Ttiy344dpHM--w1h' );
|
||||
exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store activation time in a WP option.
|
||||
*/
|
||||
public function store_activation_time() {
|
||||
if ( empty( Portal_Options::get_activation_time() ) ) {
|
||||
Portal_Options::set_activation_time();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds scripts for the admin section.
|
||||
*/
|
||||
public function enqueue_scripts() {
|
||||
AssetsManager::register_assets();
|
||||
AssetsManager::enqueue_admin_assets();
|
||||
if ( get_current_screen()->id === 'plugins' ) {
|
||||
AssetsManager::enqueue_feedback_assets();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Leadin menu to admin sidebar
|
||||
*/
|
||||
public function build_menu() {
|
||||
if ( Connection::is_connected() ) {
|
||||
add_menu_page( __( 'HubSpot', 'leadin' ), __( 'HubSpot', 'leadin' ), Filters::apply_view_plugin_menu_capability_filters(), MenuConstants::ROOT, array( $this, 'build_integrated_app' ), 'dashicons-sprocket', '25.100713' );
|
||||
|
||||
add_submenu_page( MenuConstants::ROOT, __( 'User Guide', 'leadin' ), __( 'User Guide', 'leadin' ), Filters::apply_view_plugin_menu_capability_filters(), MenuConstants::USER_GUIDE, array( $this, 'build_integrated_app' ) );
|
||||
add_submenu_page( MenuConstants::ROOT, __( 'Forms', 'leadin' ), __( 'Forms', 'leadin' ), Filters::apply_view_plugin_menu_capability_filters(), MenuConstants::FORMS, array( $this, 'build_integrated_app' ) );
|
||||
add_submenu_page( MenuConstants::ROOT, __( 'Live Chat', 'leadin' ), __( 'Live Chat', 'leadin' ), Filters::apply_view_plugin_menu_capability_filters(), MenuConstants::CHATFLOWS, array( $this, 'build_integrated_app' ) );
|
||||
|
||||
add_submenu_page( MenuConstants::ROOT, __( 'Contacts', 'leadin' ), self::make_external_link( Links::get_iframe_src( MenuConstants::CONTACTS ), __( 'Contacts', 'leadin' ), 'leadin_contacts_link' ), Filters::apply_view_plugin_menu_capability_filters(), MenuConstants::CONTACTS, array( $this, 'build_app' ) );
|
||||
add_submenu_page( MenuConstants::ROOT, __( 'Email', 'leadin' ), self::make_external_link( Links::get_iframe_src( MenuConstants::EMAIL ), __( 'Email', 'leadin' ), 'leadin_email_link' ), Filters::apply_view_plugin_menu_capability_filters(), MenuConstants::EMAIL, array( $this, 'build_app' ) );
|
||||
add_submenu_page( MenuConstants::ROOT, __( 'Lists', 'leadin' ), self::make_external_link( Links::get_iframe_src( MenuConstants::LISTS ), __( 'Lists', 'leadin' ), 'leadin_lists_link' ), Filters::apply_view_plugin_menu_capability_filters(), MenuConstants::LISTS, array( $this, 'build_app' ) );
|
||||
add_submenu_page( MenuConstants::ROOT, __( 'Reporting', 'leadin' ), self::make_external_link( Links::get_iframe_src( MenuConstants::REPORTING ), __( 'Reporting', 'leadin' ), 'leadin_reporting_link' ), Filters::apply_view_plugin_menu_capability_filters(), MenuConstants::REPORTING, array( $this, 'build_app' ) );
|
||||
|
||||
add_submenu_page( MenuConstants::ROOT, __( 'Settings', 'leadin' ), __( 'Settings', 'leadin' ), Filters::apply_view_plugin_menu_capability_filters(), MenuConstants::SETTINGS, array( $this, 'build_integrated_app' ) );
|
||||
|
||||
add_submenu_page( MenuConstants::ROOT, __( 'Upgrade', 'leadin' ), self::make_external_link( Links::get_iframe_src( MenuConstants::PRICING ), __( 'Upgrade', 'leadin' ), 'leadin_pricing_link' ), Filters::apply_view_plugin_menu_capability_filters(), MenuConstants::PRICING, array( $this, 'build_app' ) );
|
||||
|
||||
remove_submenu_page( MenuConstants::ROOT, MenuConstants::ROOT );
|
||||
} else {
|
||||
$notification_icon = ' <span class="update-plugins count-1"><span class="plugin-count">!</span></span>';
|
||||
add_menu_page( __( 'HubSpot', 'leadin' ), __( 'HubSpot', 'leadin' ) . $notification_icon, Filters::apply_connect_plugin_capability_filters(), MenuConstants::ROOT, array( $this, 'build_integrated_app' ), 'dashicons-sprocket', '25.100713' );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wraps external link.
|
||||
*
|
||||
* @param String $href link destination.
|
||||
* @param String $content link content.
|
||||
* @param String $class class for ATs.
|
||||
*/
|
||||
public function make_external_link( $href, $content, $class ) {
|
||||
return "<a href=\"$href\" class=\"external_link $class\" target=\"_blank\" onclick=\"blur()\">$content</a>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the leadin admin page.
|
||||
*/
|
||||
public function build_app() {
|
||||
AssetsManager::enqueue_bridge_assets();
|
||||
self::render_app();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the integrated forms app.
|
||||
*/
|
||||
public function build_integrated_app() {
|
||||
AssetsManager::enqueue_integrated_app_assets();
|
||||
self::render_app();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render app container
|
||||
*/
|
||||
public function render_app() {
|
||||
$error_message = '';
|
||||
|
||||
if ( Versions::is_php_version_not_supported() ) {
|
||||
$error_message = sprintf(
|
||||
__( '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' ),
|
||||
LEADIN_PLUGIN_VERSION,
|
||||
LEADIN_REQUIRED_WP_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
if ( $error_message ) {
|
||||
?>
|
||||
<div class='notice notice-warning'>
|
||||
<p>
|
||||
<?php echo esc_html( $error_message ); ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<div id="leadin-iframe-fallback-container"></div>
|
||||
<div id="leadin-iframe-container"></div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
192
wp/wp-content/plugins/leadin/public/admin/class-links.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin;
|
||||
|
||||
use Leadin\data\Filters;
|
||||
use Leadin\data\Portal_Options;
|
||||
use Leadin\admin\MenuConstants;
|
||||
use Leadin\admin\utils\Background;
|
||||
use Leadin\data\User;
|
||||
use Leadin\utils\QueryParameters;
|
||||
use Leadin\utils\Versions;
|
||||
use Leadin\auth\OAuth;
|
||||
use Leadin\admin\Connection;
|
||||
use Leadin\admin\Impact;
|
||||
use Leadin\admin\AdminConstants;
|
||||
use Leadin\includes\utils as utils;
|
||||
use Leadin\auth\OAuthCrypto;
|
||||
|
||||
/**
|
||||
* Class containing all the functions to generate links to HubSpot.
|
||||
*/
|
||||
class Links {
|
||||
/**
|
||||
* Deprecated for OAuth2 routes
|
||||
*
|
||||
* Get a map of <admin_page, url>
|
||||
* Where
|
||||
* - admin_page is a string
|
||||
* - url is either a string or another map <route, string_url>, both strings
|
||||
*/
|
||||
public static function get_routes_mapping() {
|
||||
$portal_id = Portal_Options::get_portal_id();
|
||||
$reporting_page = "/reports-dashboard/$portal_id";
|
||||
$user_guide = "/wordpress-plugin-ui/$portal_id/onboarding/start";
|
||||
|
||||
return array(
|
||||
MenuConstants::ROOT => $user_guide,
|
||||
MenuConstants::USER_GUIDE => $user_guide,
|
||||
MenuConstants::REPORTING => $reporting_page,
|
||||
MenuConstants::CONTACTS => "/contacts/$portal_id",
|
||||
MenuConstants::LISTS => array(
|
||||
'' => "/contacts/$portal_id/objectLists/all",
|
||||
'default' => "/contacts/$portal_id/objectLists",
|
||||
'lists' => "/contacts/$portal_id/lists",
|
||||
),
|
||||
MenuConstants::EMAIL => array(
|
||||
'' => "/email/$portal_id",
|
||||
'cms' => "/content/$portal_id/create/email",
|
||||
),
|
||||
MenuConstants::SETTINGS => array(
|
||||
'' => "/wordpress-plugin-ui/$portal_id/settings",
|
||||
'forms' => "/settings/$portal_id/marketing/form",
|
||||
),
|
||||
MenuConstants::PRICING => "/pricing/$portal_id/marketing",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get page name from the current page id.
|
||||
* E.g. "hubspot_page_leadin_forms" => "forms"
|
||||
*/
|
||||
private static function get_page_id() {
|
||||
$screen_id = get_current_screen()->id;
|
||||
return preg_replace( '/^(hubspot_page_|toplevel_page_)/', '', $screen_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parsed `leadin_route` from the query string.
|
||||
*/
|
||||
private static function get_iframe_route() {
|
||||
$iframe_route = QueryParameters::get_param_array( 'leadin_route', 'hubspot-route' );
|
||||
return is_array( $iframe_route ) ? $iframe_route : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parsed `leadin_search` from the query string.
|
||||
*/
|
||||
private static function get_iframe_search_string() {
|
||||
return QueryParameters::get_param( 'leadin_search', 'hubspot-route' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return query string from object
|
||||
*
|
||||
* @param array $arr query parameters to stringify.
|
||||
*/
|
||||
private static function http_build_query( $arr ) {
|
||||
if ( ! is_array( $arr ) ) {
|
||||
return '';
|
||||
}
|
||||
return http_build_query( $arr, '', ini_get( 'arg_separator.output' ), PHP_QUERY_RFC3986 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate static version.
|
||||
*
|
||||
* @param String $version version of the static bundle.
|
||||
*/
|
||||
private static function is_static_version_valid( $version ) {
|
||||
preg_match( '/static-\d+\.\d+/', $version, $match );
|
||||
return ! empty( $match );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string query parameters to add to the iframe src.
|
||||
*/
|
||||
public static function get_query_params() {
|
||||
$config_array = AdminConstants::get_hubspot_query_params_array();
|
||||
\array_merge( $config_array, Impact::get_params() );
|
||||
|
||||
return self::http_build_query( $config_array );
|
||||
}
|
||||
|
||||
/**
|
||||
* This function computes the right iframe src based on query params and current page.
|
||||
*
|
||||
* The `page` query param is used as a key to get the url from the get_routes_mapping
|
||||
* This query param will get ignored if $page_id function param is present
|
||||
* The `leadin_route[]` query params are added to the url
|
||||
*
|
||||
* e.g.:
|
||||
* ?page=leadin_forms&leadin_route[]=foo&leadin_route[]=bar will redirect to /forms/$portal_id/foo/bar
|
||||
*
|
||||
* If the value of get_routes_mapping is an array, the first value of `leadin_route` will be used as key.
|
||||
* If the key isn't found, it will fall back to ''
|
||||
*
|
||||
* e.g.:
|
||||
* ?page=leadin_settings&leadin=route[]=forms&leadin_route[]=bar will redirect to /settings/$portal_id/forms/bar
|
||||
* ?page=leadin_settings&leadin=route[]=foo&leadin_route[]=bar will redirect to /wordpress_plugin_ui/$portal_id/settings/foo/bar
|
||||
*
|
||||
* @param String $page_id is used as a key to get the url from the get_routes_mapping by overriding the query param.
|
||||
*
|
||||
* Returns the right iframe src.
|
||||
*/
|
||||
public static function get_iframe_src( $page_id = '' ) {
|
||||
$leadin_onboarding = 'leadin_onboarding';
|
||||
$leadin_new_portal = 'leadin_new_portal';
|
||||
$browser_search_string = '';
|
||||
|
||||
if ( get_transient( $leadin_onboarding ) ) {
|
||||
delete_transient( $leadin_onboarding );
|
||||
$browser_search_string = '&justConnected=true';
|
||||
if ( get_transient( $leadin_new_portal ) ) {
|
||||
delete_transient( $leadin_new_portal );
|
||||
$browser_search_string = $browser_search_string . '&isNewPortal=true';
|
||||
}
|
||||
}
|
||||
|
||||
$sub_routes_array = self::get_iframe_route();
|
||||
$inframe_search_string = self::get_iframe_search_string();
|
||||
$browser_search_string = $browser_search_string . $inframe_search_string;
|
||||
|
||||
if ( empty( Portal_Options::get_portal_id() ) ) {
|
||||
$wp_user = wp_get_current_user();
|
||||
$wp_user_id = $wp_user->ID;
|
||||
set_transient( $leadin_onboarding, 'true' );
|
||||
} else {
|
||||
if ( '' === $page_id ) {
|
||||
$page_id = self::get_page_id();
|
||||
}
|
||||
|
||||
$routes = self::get_routes_mapping();
|
||||
|
||||
$is_external = MenuConstants::PRICING === $page_id || MenuConstants::REPORTING === $page_id || MenuConstants::LISTS === $page_id || MenuConstants::CONTACTS === $page_id || MenuConstants::EMAIL === $page_id;
|
||||
|
||||
if ( empty( $route ) && isset( $routes[ $page_id ] ) ) {
|
||||
$route = $routes[ $page_id ];
|
||||
|
||||
if ( \is_array( $route ) && isset( $sub_routes_array[0] ) ) {
|
||||
$first_sub_route = $sub_routes_array[0];
|
||||
|
||||
if ( isset( $route[ $first_sub_route ] ) ) {
|
||||
$route = $route[ $first_sub_route ];
|
||||
array_shift( $sub_routes_array );
|
||||
}
|
||||
}
|
||||
|
||||
if ( \is_array( $route ) ) {
|
||||
$route = $route[''];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sub_routes = join( '/', $sub_routes_array );
|
||||
$sub_routes = empty( $sub_routes ) ? $sub_routes : "/$sub_routes";
|
||||
// Query string separator "?" may have been added to the URL already.
|
||||
$add_separator = strpos( $sub_routes, '?' ) ? '&' : '?';
|
||||
$additional_query_params = Filters::apply_query_params_filters();
|
||||
|
||||
return Filters::apply_base_url_filters() . "$route$sub_routes" . $add_separator . self::get_query_params() . $browser_search_string . $additional_query_params;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin;
|
||||
|
||||
/**
|
||||
* Static class containing the id of each menu item.
|
||||
*/
|
||||
class MenuConstants {
|
||||
const ROOT = 'leadin';
|
||||
const USER_GUIDE = 'leadin_user_guide';
|
||||
const REPORTING = 'leadin_reporting';
|
||||
const EMAIL = 'leadin_email';
|
||||
const FORMS = 'leadin_forms';
|
||||
const CONTACTS = 'leadin_contacts';
|
||||
const LISTS = 'leadin_lists';
|
||||
const SETTINGS = 'leadin_settings';
|
||||
const PRICING = 'leadin_pricing';
|
||||
const CHATFLOWS = 'leadin_chatflows';
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin;
|
||||
|
||||
use Leadin\data\User;
|
||||
use Leadin\admin\Connection;
|
||||
use Leadin\data\User_Metadata;
|
||||
use Leadin\admin\AdminConstants;
|
||||
use Leadin\admin\ReviewBanner;
|
||||
|
||||
/**
|
||||
* Class responsible for rendering the admin notices.
|
||||
*/
|
||||
class NoticeManager {
|
||||
|
||||
|
||||
/**
|
||||
* Class constructor, adds the necessary hooks.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'admin_notices', array( $this, 'leadin_action_required_notice' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the disconnected banner.
|
||||
*/
|
||||
private function leadin_render_disconnected_banner() {
|
||||
?>
|
||||
<div id="leadin-disconnected-banner" class="leadin-banner notice notice-warning is-dismissible">
|
||||
<p>
|
||||
<img src="<?php echo esc_attr( LEADIN_ASSETS_PATH . '/images/sprocket.svg' ); ?>" height="16" style="margin-bottom: -3px" />
|
||||
|
||||
<?php
|
||||
echo sprintf(
|
||||
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>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Find what notice (if any) needs to be rendered
|
||||
*/
|
||||
public function leadin_action_required_notice() {
|
||||
$current_screen = get_current_screen();
|
||||
if ( User::is_admin() ) {
|
||||
if ( self::should_show_disconnected_notice() ) {
|
||||
$this->leadin_render_disconnected_banner();
|
||||
} elseif ( self::should_show_review_notice() ) {
|
||||
$review_banner = new ReviewBanner();
|
||||
$review_banner->leadin_render_review_banner();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find if disconnected notice should be shown
|
||||
*/
|
||||
public function should_show_disconnected_notice() {
|
||||
$current_screen = get_current_screen();
|
||||
return ! Connection::is_connected() && 'leadin' !== $current_screen->parent_base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find if review notice should be shown
|
||||
*/
|
||||
public function should_show_review_notice() {
|
||||
$current_screen = get_current_screen();
|
||||
$is_dashboard = 'index' === $current_screen->parent_base;
|
||||
$is_not_skipped = empty( User_Metadata::get_skip_review() );
|
||||
return $is_dashboard && Connection::is_connected() && $is_not_skipped;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin;
|
||||
|
||||
use Leadin\data\Filters;
|
||||
use Leadin\admin\Links;
|
||||
use Leadin\admin\Connection;
|
||||
use Leadin\data\Portal_Options;
|
||||
|
||||
/**
|
||||
* Class responsible for the custom functionalities inside the plugins.php page.
|
||||
*/
|
||||
class PluginActionsManager {
|
||||
/**
|
||||
* Class constructor, adds the necessary hooks.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_filter( 'plugin_action_links_leadin/leadin.php', array( $this, 'add_plugin_settings_link' ) );
|
||||
add_filter( 'plugin_action_links_leadin/leadin.php', array( $this, 'leadin_plugin_advanced_features_link' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds setting link for Leadin to plugins management page.
|
||||
*
|
||||
* @param array $links Return the links for the settings page.
|
||||
* @return array
|
||||
*/
|
||||
public function add_plugin_settings_link( $links ) {
|
||||
if ( Connection::is_connected() ) {
|
||||
$page = 'leadin_settings';
|
||||
} else {
|
||||
$page = 'leadin';
|
||||
}
|
||||
$url = get_admin_url( get_current_blog_id(), "admin.php?page=$page" );
|
||||
$settings_link = '<a href="' . $url . '">' . __( 'Settings', 'leadin' ) . '</a>';
|
||||
array_unshift( $links, $settings_link );
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds upgrade link for Leadin to plugins management page
|
||||
*
|
||||
* @param array $links Return the links for the upgrade page.
|
||||
* @return array
|
||||
*/
|
||||
public function leadin_plugin_advanced_features_link( $links ) {
|
||||
if ( Connection::is_connected() ) {
|
||||
$portal_id = Portal_Options::get_portal_id();
|
||||
$url = Filters::apply_base_url_filters() . '/pricing/' . $portal_id . '/marketing?' . Links::get_query_params();
|
||||
$advanced_features_link = '<a class="hubspot-menu-pricing" target="_blank" rel="noopener" href="' . esc_attr( $url ) . '">' . esc_html( __( 'Upgrade', 'leadin' ) ) . '</a>';
|
||||
array_push( $links, $advanced_features_link );
|
||||
}
|
||||
return $links;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin;
|
||||
|
||||
use Leadin\data\User_Metadata;
|
||||
use Leadin\admin\AdminConstants;
|
||||
use Leadin\AssetsManager;
|
||||
|
||||
/**
|
||||
* Class responsible for rendering the review banner
|
||||
*/
|
||||
class ReviewBanner {
|
||||
|
||||
|
||||
/**
|
||||
* Constructor enqueues scripts for tracking events and creates background leadin iframe
|
||||
*/
|
||||
public function __construct() {
|
||||
AssetsManager::enqueue_review_banner_tracking_script();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the review banner.
|
||||
*/
|
||||
public function leadin_render_review_banner() {
|
||||
$nonce = wp_create_nonce( 'leadin-review' );
|
||||
$dismiss_notice_text = __( 'Dismiss this notice', 'leadin' );
|
||||
$hello_text = sprintf(
|
||||
__( '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' );
|
||||
?>
|
||||
<div id="leadin-review-banner" class="leadin-banner leadin-review-banner leadin-review-banner--hide notice notice-warning">
|
||||
|
||||
<a href="?leadin_review=false&_wpnonce=<?php echo esc_html( $nonce ); ?>"
|
||||
id="dismiss-review-banner-button">
|
||||
<button class="leadin-review-banner__dismiss notice-dismiss">
|
||||
<span class="screen-reader-text">
|
||||
<?php echo esc_html( $dismiss_notice_text ); ?>
|
||||
</span>
|
||||
</button>
|
||||
</a>
|
||||
|
||||
<div class="leadin-review-banner__content">
|
||||
<p class="leadin-review-banner__text">
|
||||
<?php echo esc_html( $hello_text ); ?>
|
||||
</p>
|
||||
|
||||
<div class="leadin-review-banner__content-body">
|
||||
|
||||
<p class="leadin-review-banner__text">
|
||||
<?php
|
||||
echo sprintf(
|
||||
esc_html( $notice_text ),
|
||||
'<a class="leadin-banner__link" id="leave-review-button" target="_blank" href="?leadin_review=true&_wpnonce=' . esc_html( $nonce ) . '" aria-label="' . esc_html( __( 'Leave us a review | link opens in a new tab', 'leadin' ) ) . '" >',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<p class="leadin-review-banner__text">
|
||||
<?php echo esc_html( $feedback_text ); ?>
|
||||
</p>
|
||||
</div>
|
||||
<div class="leadin-review-banner__content-body">
|
||||
<p class="leadin-review-banner__text">
|
||||
<?php echo esc_html( $thanks_message ); ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="leadin-review-banner__author">
|
||||
<img src="<?php echo esc_attr( LEADIN_ASSETS_PATH . '/images/hubspot-team-profile.png' ); ?>" height="48" />
|
||||
|
||||
<p class="leadin-review-banner__text">
|
||||
Kelly
|
||||
<br/>
|
||||
<?php echo esc_html( $from_hubspot_text ); ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin;
|
||||
|
||||
use Leadin\data\Portal_Options;
|
||||
use Leadin\data\User_Metadata;
|
||||
use Leadin\admin\client\Contacts_Api_Client;
|
||||
|
||||
|
||||
/**
|
||||
* Class responsible for controlling if review banner should show.
|
||||
*/
|
||||
class ReviewController {
|
||||
|
||||
const CONTACTS_CREATED_SINCE_ACTIVATION = 5;
|
||||
const REVIEW_BANNER_INTRO_PERIOD = 15;
|
||||
const DAYS_SINCE_LAST_FETCH = 1;
|
||||
|
||||
/**
|
||||
* Checks if user has enough contacts created since plugin activation.
|
||||
*/
|
||||
public static function has_contacts_created_since_activation() {
|
||||
if ( self::has_min_contacts() ) {
|
||||
return true;
|
||||
} elseif ( ! self::should_fetch_contacts() ) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
User_Metadata::set_review_banner_last_call( time() );
|
||||
$client = new Contacts_Api_Client();
|
||||
$contacts = $client->get_contacts_from_timestamp( Portal_Options::get_activation_time() );
|
||||
$has_min_contacts = count( $contacts->results ) >= self::CONTACTS_CREATED_SINCE_ACTIVATION;
|
||||
User_Metadata::set_has_min_contacts( $has_min_contacts );
|
||||
return $has_min_contacts;
|
||||
} catch ( \Exception $e ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if current time is after introductary period.
|
||||
*/
|
||||
public static function is_after_introductary_period() {
|
||||
$activation_time = new \DateTime();
|
||||
$activation_time->setTimestamp( Portal_Options::get_activation_time() );
|
||||
$diff = $activation_time->diff( new \DateTime() );
|
||||
return $diff->days >= self::REVIEW_BANNER_INTRO_PERIOD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check SKIP_REVIEW meta data for a user.
|
||||
*/
|
||||
public static function is_reviewed_or_skipped() {
|
||||
return ! empty( User_Metadata::get_skip_review() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if contacts have been fetched at the current day.
|
||||
*/
|
||||
public static function should_fetch_contacts() {
|
||||
$last_call_ts = User_Metadata::get_review_banner_last_call();
|
||||
if ( empty( $last_call_ts ) ) {
|
||||
return true;
|
||||
}
|
||||
$last_call_date = new \DateTime();
|
||||
$last_call_date->setTimestamp( $last_call_ts );
|
||||
$diff = $last_call_date->diff( new \DateTime() );
|
||||
return $diff->days >= self::DAYS_SINCE_LAST_FETCH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if contacts minimun have already been fulfilled .
|
||||
*/
|
||||
public static function has_min_contacts() {
|
||||
return User_Metadata::get_has_min_contacts();
|
||||
}
|
||||
|
||||
}
|
||||
101
wp/wp-content/plugins/leadin/public/admin/class-routing.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin;
|
||||
|
||||
use Leadin\utils\QueryParameters;
|
||||
|
||||
/**
|
||||
* Class for helping route around the plugin in OAuth mode.
|
||||
*/
|
||||
class Routing {
|
||||
|
||||
const EXPIRED = 'leadin_expired';
|
||||
const JUST_CONNECTED = 'leadin_just_connected';
|
||||
const IS_NEW_PORTAL = 'is_new_portal';
|
||||
const REDIRECT_NONCE = 'leadin_redirect';
|
||||
const REVIEW = 'leadin_review';
|
||||
|
||||
/**
|
||||
* Redirect to the root of the leadin plugin with optional query parameters.
|
||||
* Verified with a redirect nonce.
|
||||
*
|
||||
* @param string $page the WordPress page parameter to redirect to.
|
||||
* @param array $extra_params Associative array of parameters to add to the redirected URL.
|
||||
*/
|
||||
public static function redirect( $page, $extra_params = array() ) {
|
||||
$redirect_params = array_merge(
|
||||
array( 'page' => $page ),
|
||||
array( self::REDIRECT_NONCE => wp_create_nonce( self::REDIRECT_NONCE ) ),
|
||||
$extra_params
|
||||
);
|
||||
|
||||
$redirect_url = add_query_arg(
|
||||
urlencode_deep( $redirect_params ),
|
||||
admin_url( 'admin.php' )
|
||||
);
|
||||
|
||||
nocache_headers();
|
||||
wp_safe_redirect( $redirect_url );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a boolean if the plugin has just been connected.
|
||||
* Signified by query parameter flag `leadin_just_connected`.
|
||||
*
|
||||
* @return bool True if the plugin has just connected.
|
||||
*/
|
||||
public static function has_just_connected_with_oauth() {
|
||||
$just_connected_param = QueryParameters::get_param(
|
||||
self::JUST_CONNECTED,
|
||||
self::REDIRECT_NONCE,
|
||||
self::REDIRECT_NONCE
|
||||
);
|
||||
|
||||
return null !== $just_connected_param;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a boolean if the plugin is being used with a new portal.
|
||||
* Signified by query parameter flag `is_new_portal`.
|
||||
*
|
||||
* @return bool True if the plugin has just connected using a new portal.
|
||||
*/
|
||||
public static function is_new_portal_with_oauth() {
|
||||
$just_connected_param = QueryParameters::get_param(
|
||||
self::IS_NEW_PORTAL,
|
||||
self::REDIRECT_NONCE,
|
||||
self::REDIRECT_NONCE
|
||||
);
|
||||
|
||||
return null !== $just_connected_param;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads query param to see if request has review request query params
|
||||
*
|
||||
* @return bool True if the `leadin_review` query parameter is not empty
|
||||
*/
|
||||
public static function has_review_request() {
|
||||
$is_review_request = QueryParameters::get_param(
|
||||
self::REVIEW,
|
||||
'leadin-review'
|
||||
);
|
||||
return ! empty( $is_review_request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads query param to see if request has review request query params set to true
|
||||
*
|
||||
* @return bool True if the `leadin_review` query parameter is true
|
||||
*/
|
||||
public static function is_review_request() {
|
||||
$is_review_request = QueryParameters::get_param(
|
||||
self::REVIEW,
|
||||
'leadin-review'
|
||||
);
|
||||
return 'true' === $is_review_request;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin\api;
|
||||
|
||||
use Leadin\api\Base_Api_Controller;
|
||||
use Leadin\data\Portal_Options;
|
||||
|
||||
/**
|
||||
* Hublet Api. Used to fetch portal's hublet and update in case of region migration
|
||||
*/
|
||||
class Hublet_Api_Controller extends Base_Api_Controller {
|
||||
|
||||
/**
|
||||
* Class constructor, register route.
|
||||
*/
|
||||
public function __construct() {
|
||||
self::register_leadin_admin_route(
|
||||
'/hublet',
|
||||
\WP_REST_Server::EDITABLE,
|
||||
array( $this, 'update_hublet' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get's correct hublet and updates it in Options
|
||||
*
|
||||
* @param array $request Request body.
|
||||
*/
|
||||
public function update_hublet( $request ) {
|
||||
$data = json_decode( $request->get_body(), true );
|
||||
$hublet = $data['hublet'];
|
||||
|
||||
if ( ! $hublet ) {
|
||||
return new \WP_REST_Response( 'Hublet is required', 400 );
|
||||
}
|
||||
Portal_Options::set_hublet( $hublet );
|
||||
return new \WP_REST_Response( $hublet, 200 );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin\api;
|
||||
|
||||
use Leadin\api\Base_Api_Controller;
|
||||
use Leadin\data\Portal_Options;
|
||||
|
||||
/**
|
||||
* Disable Internal Tracking Api. Used to exclude internal users to appear in HS analytics
|
||||
*/
|
||||
class Internal_Tracking_Api_Controller extends Base_Api_Controller {
|
||||
|
||||
/**
|
||||
* Class constructor, register route.
|
||||
*/
|
||||
public function __construct() {
|
||||
self::register_leadin_admin_route(
|
||||
'/internal-tracking',
|
||||
\WP_REST_Server::READABLE,
|
||||
array( $this, 'get_internal_tracking_option' )
|
||||
);
|
||||
self::register_leadin_admin_route(
|
||||
'/internal-tracking',
|
||||
\WP_REST_Server::EDITABLE,
|
||||
array( $this, 'set_internal_tracking_option' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the disable internal tracking option.
|
||||
*
|
||||
* @return bool Internal tracking option value.
|
||||
*/
|
||||
public function get_internal_tracking_option() {
|
||||
return new \WP_REST_Response( Portal_Options::get_disable_internal_tracking(), 200 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the disable internal tracking option.
|
||||
*
|
||||
* @param array $request Request body.
|
||||
*
|
||||
* @return string OK response message.
|
||||
*/
|
||||
public function set_internal_tracking_option( $request ) {
|
||||
Portal_Options::set_disable_internal_tracking( json_decode( $request->get_body(), true ) );
|
||||
return new \WP_REST_Response( 'OK', 200 );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin\api;
|
||||
|
||||
use Leadin\api\Base_Api_Controller;
|
||||
use Leadin\admin\Connection;
|
||||
use Leadin\data\Portal_Options;
|
||||
|
||||
/**
|
||||
* Portal Api, used to clean portal id and domain from the WordPress options.
|
||||
*/
|
||||
class Portal_Api_Controller extends Base_Api_Controller {
|
||||
|
||||
/**
|
||||
* Class constructor, register route.
|
||||
*/
|
||||
public function __construct() {
|
||||
self::register_leadin_admin_route(
|
||||
'/business-unit',
|
||||
\WP_REST_Server::READABLE,
|
||||
array( $this, 'get_business_unit_option' )
|
||||
);
|
||||
self::register_leadin_admin_route(
|
||||
'/business-unit',
|
||||
\WP_REST_Server::EDITABLE,
|
||||
array( $this, 'set_business_unit_option' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get business unit id option.
|
||||
*
|
||||
* @return string Business Unit Id
|
||||
*/
|
||||
public function get_business_unit_option() {
|
||||
return new \WP_REST_Response( Portal_Options::get_business_unit_id(), 200 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set business unit id option.
|
||||
*
|
||||
* @param number $request Request body.
|
||||
*
|
||||
* @return string OK response message.
|
||||
*/
|
||||
public function set_business_unit_option( $request ) {
|
||||
$data = json_decode( $request->get_body(), true );
|
||||
$business_unit_id = $data['businessUnitId'];
|
||||
Portal_Options::set_business_unit_id( $business_unit_id );
|
||||
return new \WP_REST_Response( 'OK', 200 );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\admin\api;
|
||||
|
||||
use Leadin\api\Base_Api_Controller;
|
||||
use Leadin\data\User_Metadata;
|
||||
|
||||
/**
|
||||
* User meta review Api, used to set the user metadata.
|
||||
*/
|
||||
class User_Meta_Api_Controller extends Base_Api_Controller {
|
||||
|
||||
/**
|
||||
* Class constructor, register route.
|
||||
*/
|
||||
public function __construct() {
|
||||
self::register_leadin_route(
|
||||
'/skip-review',
|
||||
\WP_REST_Server::CREATABLE,
|
||||
array( $this, 'skip_review' )
|
||||
);
|
||||
self::register_leadin_route(
|
||||
'/track-consent',
|
||||
\WP_REST_Server::CREATABLE,
|
||||
array( $this, 'track_consent' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip Review. Sets SKIP_REVIEW meta data for a user with current datetime.
|
||||
*/
|
||||
public function skip_review() {
|
||||
User_Metadata::set_skip_review( time() );
|
||||
return new \WP_REST_Response( 'OK', 200 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to set user consent on HubSpot anonymous tracking.
|
||||
*
|
||||
* @param array $request Request body.
|
||||
*/
|
||||
public function track_consent( $request ) {
|
||||
$data = 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 ),
|
||||
200
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
namespace Leadin\admin\widgets;
|
||||
|
||||
use Leadin\data\Filters;
|
||||
use Elementor\Plugin;
|
||||
use Elementor\Widget_Base;
|
||||
|
||||
/**
|
||||
* ElementorForm Widget
|
||||
*/
|
||||
class ElementorForm extends Widget_Base {
|
||||
|
||||
/**
|
||||
* Widget internal name.
|
||||
*/
|
||||
public function get_name() {
|
||||
return 'hubspot-form';
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget title.
|
||||
*/
|
||||
public function get_title() {
|
||||
return esc_html( 'HubSpot Form' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget display icon.
|
||||
*/
|
||||
public function get_icon() {
|
||||
return 'eicon-form-horizontal';
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget help url.
|
||||
*/
|
||||
public function get_custom_help_url() {
|
||||
return 'https://wordpress.org/support/plugin/leadin/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget category.
|
||||
*/
|
||||
public function get_categories() {
|
||||
return array( 'general', 'hubspot' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget keywords.
|
||||
*/
|
||||
public function get_keywords() {
|
||||
return array( 'hubspot', 'form', 'leadin' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget style.
|
||||
*/
|
||||
public function get_style_depends() {
|
||||
wp_register_style( 'leadin-elementor', LEADIN_JS_BASE_PATH . '/elementor.css', array(), LEADIN_PLUGIN_VERSION );
|
||||
wp_register_style( 'leadin-css', LEADIN_ASSETS_PATH . '/style/leadin.css', array(), LEADIN_PLUGIN_VERSION );
|
||||
return array( 'leadin-elementor', 'leadin-css' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget script.
|
||||
*/
|
||||
public function get_script_depends() {
|
||||
wp_register_script(
|
||||
'leadin-forms-v2',
|
||||
Filters::apply_forms_script_url_filters(),
|
||||
array(),
|
||||
LEADIN_PLUGIN_VERSION,
|
||||
true
|
||||
);
|
||||
return array( 'leadin-forms-v2' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget controls.
|
||||
*/
|
||||
protected function register_controls() {
|
||||
$this->start_controls_section(
|
||||
'content_section',
|
||||
array(
|
||||
'label' => esc_html( __( 'Form', 'leadin' ) ),
|
||||
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
|
||||
)
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'content',
|
||||
array(
|
||||
'type' => 'leadinformselect',
|
||||
)
|
||||
);
|
||||
|
||||
$this->end_controls_section();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the widget
|
||||
*/
|
||||
protected function render() {
|
||||
$settings = $this->get_settings_for_display();
|
||||
$content = $settings['content'];
|
||||
|
||||
if ( Plugin::$instance->editor->is_edit_mode() ) {
|
||||
|
||||
?>
|
||||
<div class="hubspot-form-edit-mode" data-attributes="<?php echo esc_attr( json_encode( $content ) ); ?>">
|
||||
|
||||
</div>
|
||||
<?php
|
||||
if ( empty( $content ) ) {
|
||||
?>
|
||||
<div class="hubspot-widget-empty">
|
||||
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $content ) ) {
|
||||
$portal_id = $content['portalId'];
|
||||
$form_id = $content['formId'];
|
||||
echo do_shortcode( '[hubspot portal="' . $portal_id . '" id="' . $form_id . '" type="form"]' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
namespace Leadin\admin\widgets;
|
||||
|
||||
use Leadin\AssetsManager;
|
||||
|
||||
/**
|
||||
* Class for Elementor form selector control
|
||||
*/
|
||||
class ElementorFormSelect extends \Elementor\Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Returns control internal name
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'leadinformselect';
|
||||
}
|
||||
|
||||
/**
|
||||
* Load assets needed for control
|
||||
*/
|
||||
public function enqueue() {
|
||||
AssetsManager::enqueue_elementor_script();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default settings for control
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return array(
|
||||
'label_block' => true,
|
||||
'rows' => 3,
|
||||
'hsptform_options' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render Function
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-hbspt-form-selector" data-id="<?php echo esc_html( $control_uid ); ?>"></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
namespace Leadin\admin\widgets;
|
||||
|
||||
use Elementor\Plugin;
|
||||
use Elementor\Widget_Base;
|
||||
|
||||
/**
|
||||
* ElementorMeeting Widget
|
||||
*/
|
||||
class ElementorMeeting extends Widget_Base {
|
||||
|
||||
/**
|
||||
* Widget internal name.
|
||||
*/
|
||||
public function get_name() {
|
||||
return 'hubspot-meeting';
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget title.
|
||||
*/
|
||||
public function get_title() {
|
||||
return esc_html( 'HubSpot Meeting' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget display icon.
|
||||
*/
|
||||
public function get_icon() {
|
||||
return 'eicon-calendar';
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget help url.
|
||||
*/
|
||||
public function get_custom_help_url() {
|
||||
return 'https://wordpress.org/support/plugin/leadin/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget category.
|
||||
*/
|
||||
public function get_categories() {
|
||||
return array( 'general', 'hubspot' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget keywords.
|
||||
*/
|
||||
public function get_keywords() {
|
||||
return array( 'hubspot', 'meeting', 'leadin' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget style.
|
||||
*/
|
||||
public function get_style_depends() {
|
||||
wp_register_style( 'leadin-elementor', LEADIN_JS_BASE_PATH . '/elementor.css', array(), LEADIN_PLUGIN_VERSION );
|
||||
wp_register_style( 'leadin-css', LEADIN_ASSETS_PATH . '/style/leadin.css', array(), LEADIN_PLUGIN_VERSION );
|
||||
return array( 'leadin-elementor', 'leadin-css' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget script.
|
||||
*/
|
||||
public function get_script_depends() {
|
||||
wp_register_script(
|
||||
'leadin-meeting',
|
||||
'https://static.hsappstatic.net/MeetingsEmbed/ex/MeetingsEmbedCode.js',
|
||||
array(),
|
||||
LEADIN_PLUGIN_VERSION,
|
||||
true
|
||||
);
|
||||
return array( 'leadin-meeting' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget controls.
|
||||
*/
|
||||
protected function register_controls() {
|
||||
$this->start_controls_section(
|
||||
'content_section',
|
||||
array(
|
||||
'label' => esc_html( __( 'Meetings Scheduler', 'leadin' ) ),
|
||||
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
|
||||
)
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'content',
|
||||
array(
|
||||
'type' => 'leadinmeetingselect',
|
||||
)
|
||||
);
|
||||
|
||||
$this->end_controls_section();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the widget
|
||||
*/
|
||||
protected function render() {
|
||||
$settings = $this->get_settings_for_display();
|
||||
$content = $settings['content'];
|
||||
|
||||
if ( Plugin::$instance->editor->is_edit_mode() ) {
|
||||
?>
|
||||
<div class="hubspot-meeting-edit-mode" data-attributes=<?php echo json_encode( $content ); ?>>
|
||||
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if ( empty( $content ) ) {
|
||||
?>
|
||||
<div class="hubspot-widget-empty">
|
||||
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $content ) ) {
|
||||
$url = $content['url'];
|
||||
echo do_shortcode( '[hubspot url="' . $url . '" type="meeting"]' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
namespace Leadin\admin\widgets;
|
||||
|
||||
use Leadin\AssetsManager;
|
||||
|
||||
/**
|
||||
* Class for Elementor form selector control
|
||||
*/
|
||||
class ElementorMeetingSelect extends \Elementor\Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Returns control internal name
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'leadinmeetingselect';
|
||||
}
|
||||
|
||||
/**
|
||||
* Load assets needed for control
|
||||
*/
|
||||
public function enqueue() {
|
||||
AssetsManager::enqueue_elementor_script();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default settings for control
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return array(
|
||||
'label_block' => true,
|
||||
'rows' => 3,
|
||||
'hsptmeeting_options' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render Function
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-hbspt-meeting-selector" data-id="<?php echo esc_html( $control_uid ); ?>"></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
<svg width="40px" height="42px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
||||
<path d="M288 32c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9L306.7 128 169.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L352 173.3l41.4 41.4c9.2 9.2 22.9 11.9 34.9 6.9s19.8-16.6 19.8-29.6V64c0-17.7-14.3-32-32-32H288zM80 64C35.8 64 0 99.8 0 144V400c0 44.2 35.8 80 80 80H336c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32v80c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16h80c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z"/></svg>
|
||||
|
After Width: | Height: | Size: 552 B |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 39 KiB |
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="200px" height="57px" viewBox="0 0 200 57" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 49.3 (51167) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>HubSpot Wordmark - Full Color</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="HubSpot-Wordmark---Full-Color" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Page-1">
|
||||
<polygon id="Fill-1" fill="#33475B" points="21.6380887 9.3174744 21.6380887 25.2935836 6.96607509 25.2935836 6.96607509 9.3174744 -0.000136518771 9.3174744 -0.000136518771 47.4539932 6.96607509 47.4539932 6.96607509 31.9966553 21.6380887 31.9966553 21.6380887 47.4539932 28.603959 47.4539932 28.603959 9.3174744"></polygon>
|
||||
<g id="Group-14" transform="translate(32.764505, 0.283276)">
|
||||
<path d="M18.1330717,34.8429693 C18.1330717,38.0255631 15.5528669,40.6057679 12.370273,40.6057679 C9.18767918,40.6057679 6.6074744,38.0255631 6.6074744,34.8429693 L6.6074744,18.5084983 L-3.41296928e-05,18.5084983 L-3.41296928e-05,34.8429693 C0.000989761092,41.6682253 5.53477816,47.2006485 12.3600341,47.1996246 C19.1842662,47.1986007 24.7156655,41.6668601 24.7166894,34.8429693 L24.7166894,18.5084983 L18.1330717,18.5084983 L18.1330717,34.8429693 Z" id="Fill-2" fill="#33475B"></path>
|
||||
<path d="M67.0886689,20.1911945 C67.0886689,16.8430717 69.303686,15.7816382 71.7303072,15.7816382 C73.6862799,15.7816382 76.2695563,17.2696928 77.9589761,19.0751536 L82.2866212,13.9761775 C80.1262116,11.0546758 75.743959,9.03419795 72.1569283,9.03419795 C64.9896928,9.03419795 59.8053925,13.2321502 59.8053925,20.1911945 C59.8053925,33.1024573 75.5869625,29.0068942 75.5869625,36.2321502 C75.5869625,38.4604778 73.4231399,40.4301024 70.9453242,40.4301024 C67.0374744,40.4301024 65.7712628,38.5188396 63.976041,36.4980205 L59.1739932,41.4915358 C62.2456655,45.2628669 66.0340614,47.1772014 70.5733106,47.1772014 C77.3825256,47.1772014 82.86,42.9283959 82.86,36.2867577 C82.86,21.9522867 67.07843,26.4062116 67.07843,20.1911945" id="Fill-4" fill="#33475B"></path>
|
||||
<path d="M164.720102,41.0786348 C160.816007,41.0786348 159.706792,39.389215 159.706792,36.8021843 L159.706792,25.3513311 L165.77471,25.3513311 L165.77471,19.5492833 L159.706792,19.5492833 L159.706792,11.8943345 L153.006792,14.9011604 L153.006792,38.2253925 C153.006792,44.1909215 157.122833,47.1980887 162.767884,47.1980887 C163.653208,47.2141297 164.538191,47.1434812 165.409863,46.9864846 L167.044334,40.9694198 C166.307133,41.020273 165.460717,41.0714676 164.720102,41.0714676" id="Fill-6" fill="#33475B"></path>
|
||||
<path d="M43.2423891,40.546041 C39.0956314,40.546041 35.7338567,37.1842662 35.7338567,33.0375085 C35.7338567,28.8907509 39.0956314,25.5289761 43.2423891,25.5289761 C47.3891468,25.5289761 50.7509215,28.8907509 50.7509215,33.0375085 C50.7509215,37.1842662 47.3891468,40.546041 43.2423891,40.546041 M43.2833447,18.6996246 C40.0103072,18.6996246 37.7270307,19.64843 35.5188396,21.8156655 L35.5188396,9.26276451 L28.9010922,9.26276451 L28.9010922,32.5289761 C28.9010922,41.2388737 35.1980205,47.204744 42.2731058,47.204744 C50.1229352,47.204744 57.027372,41.1330717 57.027372,32.9555973 C57.027372,24.8805119 50.6724232,18.7030375 43.2833447,18.7030375" id="Fill-8" fill="#33475B"></path>
|
||||
<path d="M108.87372,32.5255631 C108.87372,36.6723208 105.511945,40.0340956 101.365188,40.0340956 C97.21843,40.0340956 93.8566553,36.6723208 93.8566553,32.5255631 C93.8566553,28.3788055 97.21843,25.0170307 101.365188,25.0170307 C105.511945,25.0170307 108.87372,28.3788055 108.87372,32.5255631 M115.139932,32.6074744 C115.139932,24.4163481 108.249147,18.3583276 100.385666,18.3583276 C93.3105802,18.3583276 87.0136519,24.324198 87.0136519,33.0340956 L87.0136519,56.313959 L93.6313993,56.313959 L93.6313993,43.7439932 C95.8361775,45.9078157 98.1228669,46.8600341 101.392491,46.8600341 C108.781229,46.8600341 115.136519,40.6859727 115.136519,32.6074744" id="Fill-10" fill="#33475B"></path>
|
||||
<path d="M134.23901,39.8977816 C130.152321,39.8977816 126.839352,36.5848123 126.839352,32.4981229 C126.839352,28.4117747 130.152321,25.0991468 134.23901,25.0991468 C138.3257,25.0991468 141.638328,28.4117747 141.638328,32.4981229 C141.638328,36.5848123 138.3257,39.8977816 134.23901,39.8977816 M136.453686,18.2527304 L136.453686,11.6721843 C138.228771,10.8435154 139.366655,9.06501706 139.375529,7.1056314 L139.375529,6.95238908 C139.367679,4.15989761 137.106246,1.89846416 134.314096,1.89095563 L134.160512,1.89095563 C131.368362,1.89846416 129.106587,4.15989761 129.098737,6.95238908 L129.098737,7.1056314 C129.107611,9.06501706 130.245495,10.8435154 132.02058,11.6721843 L132.02058,18.2527304 C129.520239,18.6349829 127.16529,19.6708191 125.194642,21.255802 L107.126382,7.19778157 C107.255051,6.73430034 107.323652,6.25580205 107.33116,5.77491468 C107.334915,2.62133106 104.781331,0.0619453925 101.627747,0.0581911263 C98.4745051,0.0540955631 95.9151195,2.60767918 95.9113652,5.7609215 C95.9072696,8.91450512 98.4608532,11.4738908 101.614437,11.4776451 C102.606246,11.4742321 103.579625,11.2093857 104.436962,10.709727 L122.201126,24.5394198 C118.926724,29.4796928 119.014778,35.9223549 122.423311,40.7715017 L117.017167,46.1773038 C116.583379,46.0394198 116.13116,45.9656997 115.675529,45.959215 C113.084061,45.959215 110.982696,48.0602389 110.982696,50.6520478 C110.982696,53.2438567 113.084061,55.3448805 115.675529,55.3448805 C118.267338,55.3448805 120.368362,53.2438567 120.368362,50.6520478 C120.36256,50.1964164 120.28884,49.7445392 120.150273,49.3104096 L125.498396,43.9622867 C131.827406,48.7964164 140.876212,47.5848123 145.710341,41.255802 C150.544471,34.9274744 149.333208,25.8779863 143.004198,21.0438567 C141.088157,19.5803754 138.83628,18.6209898 136.453686,18.2527304" id="Fill-12" fill="#FF7A59"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.9 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 585.44 164.79"><defs><style>.cls-1{fill:none;}.cls-2{clip-path:url(#clip-path);}.cls-3{fill:#33475b;}.cls-4{clip-path:url(#clip-path-3);}.cls-5{fill:#ff7a59;}</style><clipPath id="clip-path" transform="translate(0 -1.17)"><rect class="cls-1" width="585.44" height="165.96"/></clipPath><clipPath id="clip-path-3" transform="translate(0 -1.17)"><rect class="cls-1" x="375.89" y="0.13" width="156.42" height="163.35"/></clipPath></defs><title>Asset 3</title><g id="Layer_2" data-name="Layer 2"><g id="Outlines_-_Full_Color" data-name="Outlines - Full Color"><g class="cls-2"><polygon class="cls-3" points="63.4 26.3 63.4 73.11 20.41 73.11 20.41 26.3 0 26.3 0 138.04 20.41 138.04 20.41 92.75 63.4 92.75 63.4 138.04 83.81 138.04 83.81 26.3 63.4 26.3"/><g class="cls-2"><path class="cls-3" d="M149.13,103.09a16.88,16.88,0,0,1-33.77,0V55.23H96v47.86a36.21,36.21,0,0,0,72.42,0V55.23H149.13Z" transform="translate(0 -1.17)"/><path class="cls-3" d="M292.57,60.16c0-9.81,6.49-12.92,13.6-12.92,5.73,0,13.3,4.36,18.25,9.65L337.1,41.95c-6.33-8.56-19.17-14.48-29.68-14.48-21,0-36.19,12.3-36.19,32.69,0,37.83,46.24,25.83,46.24,47,0,6.53-6.34,12.3-13.6,12.3-11.45,0-15.16-5.6-20.42-11.52l-14.07,14.63c9,11.05,20.1,16.66,33.4,16.66,19.95,0,36-12.45,36-31.91,0-42-46.24-28.95-46.24-47.16" transform="translate(0 -1.17)"/><path class="cls-3" d="M578.63,121.36c-11.44,0-14.69-4.95-14.69-12.53V75.28h17.78v-17H563.94V35.85l-19.63,8.81V113c0,17.48,12.06,26.29,28.6,26.29a39.62,39.62,0,0,0,7.74-.62l4.79-17.63c-2.16.15-4.64.3-6.81.3" transform="translate(0 -1.17)"/><path class="cls-3" d="M222.82,55.79c-9.59,0-16.28,2.78-22.75,9.13V28.14H180.68V96.31c0,25.52,18.45,43,39.18,43,23,0,43.23-17.79,43.23-41.75,0-23.66-18.62-41.76-40.27-41.76m-.12,64a22,22,0,1,1,22-22,22,22,0,0,1-22,22" transform="translate(0 -1.17)"/><path class="cls-3" d="M433.36,96.54c0-24-20.19-41.75-43.23-41.75-20.73,0-39.18,17.48-39.18,43V166h19.39V129.17c6.46,6.34,13.16,9.13,22.74,9.13,21.65,0,40.27-18.09,40.27-41.76M415,96.3a22,22,0,1,1-22-22,22,22,0,0,1,22,22" transform="translate(0 -1.17)"/></g><g class="cls-4"><path class="cls-5" d="M495.81,54.48V35.2a14.84,14.84,0,0,0,8.56-13.38v-.45A14.87,14.87,0,0,0,489.54,6.54h-.45a14.87,14.87,0,0,0-14.83,14.83v.45a14.84,14.84,0,0,0,8.56,13.38V54.48a42.06,42.06,0,0,0-20,8.8L409.88,22.09a16.55,16.55,0,0,0,.6-4.17,16.73,16.73,0,1,0-16.75,16.71A16.55,16.55,0,0,0,402,32.38L454.05,72.9a42.18,42.18,0,0,0,.65,47.56L438.86,136.3a13.61,13.61,0,0,0-3.93-.64,13.75,13.75,0,1,0,13.75,13.75,13.53,13.53,0,0,0-.64-3.93l15.67-15.67a42.25,42.25,0,1,0,32.1-75.33m-6.49,63.42A21.68,21.68,0,1,1,511,96.22a21.68,21.68,0,0,1-21.68,21.68" transform="translate(0 -1.17)"/></g></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,45 @@
|
||||
<svg width="82.5" height="75" viewBox="0 0 55 50" xmlns="http://www.w3.org/2000/svg">
|
||||
<style>
|
||||
@keyframes loadingColorAnimation {
|
||||
25% {
|
||||
fill: #0091ae;
|
||||
}
|
||||
75% {
|
||||
fill: #0091ae;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loadingAnimation {
|
||||
0%, 100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
25% {
|
||||
transform: translateY(.25em);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
75% {
|
||||
transform: translateY(-.25em);
|
||||
}
|
||||
}
|
||||
|
||||
circle {
|
||||
fill: #f5f8fa;
|
||||
animation: loadingAnimation 1s linear infinite, loadingColorAnimation 1s linear infinite;
|
||||
}
|
||||
|
||||
g circle:nth-child(2) {
|
||||
animation-delay: -0.66s;
|
||||
}
|
||||
|
||||
g circle:nth-child(3) {
|
||||
animation-delay: -0.33s;
|
||||
}
|
||||
</style>
|
||||
<g>
|
||||
<circle cx="10" cy="25" r="5"></circle>
|
||||
<circle cx="25" cy="25" r="5"></circle>
|
||||
<circle cx="40" cy="25" r="5"></circle>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 931 B |
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="40px" height="42px" viewBox="0 0 40 42" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>HubSpot Sprocket - Full Color</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<polygon id="path-1" points="0.000123751494 0 39.7808917 0 39.7808917 41.6871084 0.000123751494 41.6871084"></polygon>
|
||||
</defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="HubSpot-Sprocket---Full-Color">
|
||||
<mask id="mask-2" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<g id="path-1"></g>
|
||||
<path d="M28.8989809,30.0402293 C25.817707,30.0402293 23.319363,27.5423949 23.319363,24.461121 C23.319363,21.3798471 25.817707,18.881758 28.8989809,18.881758 C31.98,18.881758 34.4780892,21.3798471 34.4780892,24.461121 C34.4780892,27.5423949 31.98,30.0402293 28.8989809,30.0402293 M30.5692994,13.7199745 L30.5692994,8.75717196 C31.864586,8.14519744 32.7723567,6.8346242 32.7723567,5.31360508 L32.7723567,5.1989554 C32.7723567,3.10010191 31.0546497,1.38264968 28.956051,1.38264968 L28.8414013,1.38264968 C26.7425478,1.38264968 25.0248408,3.10010191 25.0248408,5.1989554 L25.0248408,5.31360508 C25.0248408,6.8346242 25.9328662,8.14519744 27.2281529,8.75717196 L27.2281529,13.7202293 C25.2994904,14.0180637 23.5371974,14.8137325 22.0829299,15.9844331 L8.45643312,5.38417836 C8.54611464,5.0392102 8.6090446,4.6835414 8.60955416,4.310293 C8.61261148,1.93271338 6.68777072,0.00303184713 4.31019108,-2.5477707e-05 C1.93286624,-0.00308280255 0.0029299363,1.92175796 0.000127388535,4.29933756 C-0.0029299363,6.67666244 1.92191083,8.60634396 4.29949044,8.60940128 C5.07426752,8.6104204 5.7912102,8.390293 6.42,8.03284076 L19.8243312,18.4603567 C18.6842038,20.181121 18.0166879,22.2422675 18.0166879,24.461121 C18.0166879,26.7841784 18.7504458,28.9327134 19.9907006,30.7001019 L15.9142675,34.776535 C15.5919745,34.6799745 15.2574522,34.6122038 14.9033121,34.6122038 C12.9499363,34.6122038 11.3659873,36.1961529 11.3659873,38.1497834 C11.3659873,40.103414 12.9499363,41.6871084 14.9033121,41.6871084 C16.8571974,41.6871084 18.4408917,40.103414 18.4408917,38.1497834 C18.4408917,37.7958981 18.3733758,37.461121 18.2765605,37.1390828 L22.3089172,33.1067261 C24.1392357,34.5041784 26.4184713,35.3431592 28.8989809,35.3431592 C34.9089172,35.3431592 39.7810191,30.4710573 39.7810191,24.461121 C39.7810191,19.0203567 35.7840764,14.5255796 30.5692994,13.7199745" id="Fill-1" fill="#F3785B" fill-rule="nonzero" mask="url(#mask-2)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Generated by Fontastic.me</metadata>
|
||||
<defs>
|
||||
<font id="untitled-font-1" horiz-adv-x="512">
|
||||
<font-face font-family="untitled-font-1" units-per-em="512" ascent="480" descent="-32"/>
|
||||
<missing-glyph horiz-adv-x="512" />
|
||||
|
||||
<glyph glyph-name="sprocket-white" unicode="a" d="M354 156c-34 0-61 28-61 62 0 34 27 61 61 61 34 0 62-27 62-61 0-34-28-62-62-62m19 180l0 55c14 7 24 22 24 38l0 2c0 23-19 42-42 42l-1 0c-23 0-42-19-42-42l0-2c0-16 10-31 24-38l0-55c-21-3-41-12-57-25l-151 118c1 3 2 7 2 11 0 27-21 48-47 48-27 0-48-21-48-47 0-27 21-48 47-48 9 0 17 2 24 6l148-115c-13-19-20-42-20-66 0-26 8-50 22-69l-45-45c-4 1-7 2-11 2-22 0-39-18-39-40 0-21 17-39 39-39 21 0 39 18 39 39 0 4-1 8-2 12l45 44c20-15 45-25 72-25 67 0 121 54 121 121 0 60-45 110-102 118"/>
|
||||
</font></defs></svg>
|
||||
|
After Width: | Height: | Size: 956 B |
@@ -0,0 +1,33 @@
|
||||
#leadin,
|
||||
#wpbody,
|
||||
#wpbody-content,
|
||||
#wpcontent,
|
||||
#wpwrap,
|
||||
body,
|
||||
html {
|
||||
height: 100% !important;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
body.toplevel_page_leadin {
|
||||
background-color: #f5f8fa !important;
|
||||
}
|
||||
|
||||
#wpbody-content,
|
||||
#wpcontent {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
#wpfooter {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#leadin-iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
border: 0 none transparent !important;
|
||||
padding: 0 !important;
|
||||
width: 100% !important;
|
||||
left: 0;
|
||||
background: white;
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
.leadin-feedback-window {
|
||||
background-color: #fff;
|
||||
font-family: 'Lexend Deca', Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
color: #33475b;
|
||||
width: 524px !important; /* need to override the inline styling thickbox applies */
|
||||
height: 600px !important;
|
||||
margin-left: 0px !important;
|
||||
transform: translateX(-50%);
|
||||
top: 30px !important;
|
||||
margin-top: 0px !important;
|
||||
visibility: visible !important;
|
||||
}
|
||||
|
||||
.leadin-feedback-window strong {
|
||||
font-weight: 550;
|
||||
}
|
||||
|
||||
.leadin-feedback-content {
|
||||
width: auto !important; /* need to override the inline styling thickbox applies */
|
||||
height: auto !important;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.leadin-radio-input-container {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.leadin-deactivate-form {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.leadin-input,
|
||||
.leadin-input[type],
|
||||
.leadin-feedback-text-area {
|
||||
border-radius: 3px;
|
||||
border: 1px solid #cbd6e2;
|
||||
background-color: #f5f8fa;
|
||||
margin-top: 10px;
|
||||
padding: 9px 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.leadin-input:focus,
|
||||
.leadin-input[type]:focus,
|
||||
.leadin-feedback-text-area:focus {
|
||||
border-color: rgba(0, 208, 228, 0.5);
|
||||
box-shadow: 0 0 4px 1px rgba(0, 208, 228, 0.3), 0 0 0 1px #00d0e4;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.leadin-feedback-text-area {
|
||||
margin-bottom: 30px;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
|
||||
transition-property: all;
|
||||
transition-duration: 0.15s;
|
||||
transition-timing-function: ease-out;
|
||||
transition-delay: 0s;
|
||||
}
|
||||
|
||||
input[type='radio']:checked:before.leadin-feedback-radio {
|
||||
background-color: #00a4bd;
|
||||
}
|
||||
|
||||
input[type='radio']:focus.leadin-feedback-radio {
|
||||
border-color: #00a4bd;
|
||||
}
|
||||
|
||||
.leadin-button-container {
|
||||
margin-top: 30px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.leadin-button-container .leadin-button {
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.leadin-feedback-header {
|
||||
background-color: #00bda5;
|
||||
background-image: linear-gradient(-303deg, #00a4bd, #00afb2 56%, #00bda5);
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
|
||||
align-items: center;
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
.leadin-feedback-header h2 {
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
font-size: 20px;
|
||||
line-height: 40px;
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
.leadin-feedback-body {
|
||||
margin-top: 80px;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
.leadin-modal-close {
|
||||
color: #fff;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
justify-content: center;
|
||||
line-height: normal;
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
right: 22px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
z-index: 1;
|
||||
transition: color 150ms ease-out 0s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.leadin-close-svg {
|
||||
display: block;
|
||||
-webkit-box-flex: 1;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.leadin-close-path {
|
||||
fill: currentcolor;
|
||||
stroke: currentcolor;
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
.leadin-modal-close::after {
|
||||
padding: 20px;
|
||||
content: ' ';
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 100%;
|
||||
padding: 20px;
|
||||
transition-property: background-color;
|
||||
transition-duration: 150ms;
|
||||
transition-timing-function: ease-out;
|
||||
transition-delay: 0s;
|
||||
}
|
||||
|
||||
.leadin-modal-close:hover::after {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.leadin-loader {
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: 18%;
|
||||
left: 43%;
|
||||
border-top: 0.2em solid #ffbcac;
|
||||
border-right: 0.2em solid #ffbcac;
|
||||
border-bottom: 0.2em solid #ffbcac;
|
||||
border-left: 0.2em solid #ff7a59;
|
||||
border-radius: 50%;
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
-webkit-transform: translateZ(0);
|
||||
-ms-transform: translateZ(0);
|
||||
transform: translateZ(0);
|
||||
-webkit-animation: load8 1.1s infinite linear;
|
||||
animation: load8 1.1s infinite linear;
|
||||
}
|
||||
@-webkit-keyframes load8 {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes load8 {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.leadin-loader-button.loading .leadin-loader {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.leadin-loader-button.loading .leadin-loader-button-content {
|
||||
opacity: 0;
|
||||
}
|
||||
312
wp/wp-content/plugins/leadin/public/assets/style/leadin.css
Normal file
@@ -0,0 +1,312 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/* For sprocket icon on WordPress admin menu */
|
||||
@font-face {
|
||||
font-family: 'hs-font';
|
||||
src: url('fonts/hs-font.woff') format('woff'),
|
||||
url('fonts/hs-font.svg#hs-font') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Lexend Deca';
|
||||
src: url('fonts/LexendDeca-Light.woff2') format('woff2'),
|
||||
url('fonts/LexendDeca-Medium.woff2') format('woff2'),
|
||||
url('fonts/LexendDeca-SemiBold.woff2') format('woff2'),
|
||||
url('fonts/LexendDeca-Bold.woff2') format('woff2');
|
||||
}
|
||||
|
||||
#wp-admin-bar-leadin-admin-menu .ab-icon:before,
|
||||
.dashicons-sprocket:before {
|
||||
font-family: 'hs-font' !important;
|
||||
content: attr(data-icon);
|
||||
font-style: normal !important;
|
||||
font-weight: normal !important;
|
||||
font-variant: normal !important;
|
||||
text-transform: none !important;
|
||||
speak: none;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
#wp-admin-bar-leadin-admin-menu .ab-icon:before,
|
||||
.dashicons-sprocket:before {
|
||||
content: '\61';
|
||||
}
|
||||
|
||||
/* Button */
|
||||
.leadin-button {
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
padding: 12px 24px;
|
||||
font-weight: 500;
|
||||
border: 1px solid #ff7a59;
|
||||
border-radius: 3px;
|
||||
transition: all 0.15s;
|
||||
transition-timing-function: ease-out;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.leadin-loader-button {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.leadin-button.loading {
|
||||
background-color: #fff;
|
||||
color: #ff7a59;
|
||||
transition-timing-function: ease-out;
|
||||
}
|
||||
|
||||
.leadin-button.loading:hover {
|
||||
background-color: #fff8f6;
|
||||
}
|
||||
|
||||
.leadin-button.loading:active {
|
||||
background-color: #ffebe6;
|
||||
}
|
||||
|
||||
.leadin-primary-button {
|
||||
background-color: #ff7a59;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.leadin-primary-button:hover {
|
||||
background-color: #ff8f73;
|
||||
border-color: #ff8f73;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.leadin-primary-button:active {
|
||||
background-color: #e66e50;
|
||||
border-color: #e66e50;
|
||||
}
|
||||
|
||||
.leadin-secondary-button {
|
||||
background-color: #fff;
|
||||
color: #ff7a53;
|
||||
}
|
||||
|
||||
.leadin-secondary-button:hover {
|
||||
background-color: #fff8f6;
|
||||
}
|
||||
|
||||
.leadin-secondary-button:active {
|
||||
background-color: #ffebe6;
|
||||
}
|
||||
|
||||
/* Notice */
|
||||
.leadin-notice {
|
||||
height: fit-content;
|
||||
padding-top: 27px;
|
||||
padding-bottom: 27px;
|
||||
}
|
||||
|
||||
.leadin-notice__logo {
|
||||
float: left;
|
||||
padding-left: 20px;
|
||||
margin-top: -10px;
|
||||
}
|
||||
|
||||
.leadin-notice__logo > img {
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.leadin-notice__title,
|
||||
.leadin-notice__content {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
.leadin-notice__title {
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.leadin-notice__content {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.leadin-notice__options {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.leadin-notice__footer {
|
||||
display: flex;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.leadin-notice__footer-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.leadin-notice__footer-image {
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
}
|
||||
|
||||
.leadin-notice__cta {
|
||||
padding: 6px 14px;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.leadin-banner.notice-warning {
|
||||
border-left-color: #ff7a59;
|
||||
}
|
||||
|
||||
.leadin-banner__link {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.leadin-review-banner {
|
||||
position: relative;
|
||||
padding: 20px 28px 26px 28px;
|
||||
color: #5f5f5f;
|
||||
}
|
||||
|
||||
.leadin-review-banner--hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.leadin-review-banner__dismiss {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 22px;
|
||||
}
|
||||
|
||||
.leadin-review-banner__content {
|
||||
min-height: 74px;
|
||||
}
|
||||
|
||||
.leadin-review-banner__content-body {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.leadin-review-banner__text {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 19px;
|
||||
}
|
||||
|
||||
.leadin-review-banner__author {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
gap: 8px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.leadin-review-banner__profile {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
#toplevel_page_leadin a[href*='leadin_settings'],
|
||||
#toplevel_page_leadin a[href*='leadin_user_guide'],
|
||||
#toplevel_page_leadin a[href*='leadin_forms'],
|
||||
#toplevel_page_leadin a[href*='leadin_chatflows'],
|
||||
#toplevel_page_leadin a.leadin_lists_link,
|
||||
#toplevel_page_leadin a.leadin_reporting_link,
|
||||
#toplevel_page_leadin a.leadin_contacts_link,
|
||||
#toplevel_page_leadin a.leadin_email_link,
|
||||
#toplevel_page_leadin a.leadin_pricing_link {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
#toplevel_page_leadin a[href*='leadin_lists'],
|
||||
#toplevel_page_leadin a[href*='leadin_reporting'],
|
||||
#toplevel_page_leadin a[href*='leadin_pricing'],
|
||||
#toplevel_page_leadin a[href*='leadin_contacts'],
|
||||
#toplevel_page_leadin a[href*='leadin_email'] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#toplevel_page_leadin a[href*='leadin_pricing'] + .external_link {
|
||||
color: #ff7a59 !important;
|
||||
}
|
||||
|
||||
#toplevel_page_leadin a[href*='leadin_pricing'] + .external_link:hover {
|
||||
color: #ffbcac !important;
|
||||
}
|
||||
|
||||
#toplevel_page_leadin a[href*='leadin_pricing'] + .external_link::after {
|
||||
background-color: #ff7a59;
|
||||
}
|
||||
|
||||
#toplevel_page_leadin a[href*='leadin_pricing'] + .external_link:hover::after {
|
||||
background-color: #ffbcac;
|
||||
}
|
||||
|
||||
#toplevel_page_leadin .external_link:hover::after {
|
||||
background-color: #72aee6;
|
||||
}
|
||||
|
||||
#toplevel_page_leadin .external_link::after {
|
||||
content: '';
|
||||
-webkit-mask: url('../images/external_link.svg') no-repeat 50% 50%;
|
||||
mask: url('../images/external_link.svg') no-repeat 50% 50%;
|
||||
-webkit-mask-size: cover;
|
||||
mask-size: cover;
|
||||
position: absolute;
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
background-size: contain;
|
||||
margin: 4px 2px;
|
||||
background-color: rgba(240, 246, 252, 0.7);
|
||||
}
|
||||
|
||||
/* Needed to prevent the notice banners being shown briefly under the iframe */
|
||||
#leadin-iframe-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#leadin-iframe-fallback-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
left: 0;
|
||||
background: white;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.elementor-element-editable .hubspot-form-edit-mode + .hubspot-widget-empty,
|
||||
.elementor-element-editable .hubspot-meeting-edit-mode + .hubspot-widget-empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hubspot-form-edit-mode ~ .hbspt-form,
|
||||
.hubspot-meeting-edit-mode ~ .meetings-iframe-container {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.hubspot-widget-empty {
|
||||
background-image: url('../images/hubspot.svg');
|
||||
background-color: #f5f8fa;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center 25px;
|
||||
background-size: 120px;
|
||||
color: #33475b;
|
||||
font-family: 'Lexend Deca', Helvetica, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
padding: 90px 20% 25px;
|
||||
}
|
||||
|
||||
.hubspot-widget-empty p {
|
||||
font-size: inherit !important;
|
||||
line-height: 24px;
|
||||
margin: 4px 0;
|
||||
}
|
||||
86
wp/wp-content/plugins/leadin/public/auth/class-oauth.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\auth;
|
||||
|
||||
use Leadin\data\User;
|
||||
use Leadin\data\Portal_Options;
|
||||
use Leadin\auth\OAuthCrypto;
|
||||
use Leadin\admin\Routing;
|
||||
use Leadin\admin\MenuConstants;
|
||||
|
||||
/**
|
||||
* Class managing OAuth2 authorization
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param string $refresh_token OAuth refresh token to store.
|
||||
*/
|
||||
public static function authorize( $refresh_token ) {
|
||||
$encrypted_refresh_token = OAuthCrypto::encrypt( $refresh_token );
|
||||
Portal_Options::set_refresh_token( $encrypted_refresh_token );
|
||||
|
||||
Portal_Options::set_last_authorize_time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deauthorizes the plugin by deleting OAuth credentials from the options DB.
|
||||
*/
|
||||
public static function deauthorize() {
|
||||
Portal_Options::delete_refresh_token();
|
||||
|
||||
Portal_Options::set_last_deauthorize_time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to get and decrypt the refresh token with retries.
|
||||
* Records an error if decryption fails or if the token is invalid.
|
||||
*
|
||||
* @return string The decrypted refresh token, 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();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the provided value is valid (not false, null, or empty).
|
||||
*
|
||||
* @param mixed $value The value to check.
|
||||
* @return bool Whether the value is valid.
|
||||
*/
|
||||
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 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\auth;
|
||||
|
||||
/**
|
||||
* Encrypting/decrypting OAuth credentials
|
||||
* Adapted from https://felix-arntz.me/blog/storing-confidential-data-in-wordpress/
|
||||
*/
|
||||
class OAuthCrypto {
|
||||
|
||||
/**
|
||||
* Return the key to use in encrypting/decrypting OAuth credentials
|
||||
*/
|
||||
private static function get_key() {
|
||||
if ( defined( 'LOGGED_IN_KEY' ) ) {
|
||||
return LOGGED_IN_KEY;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the salt to use in encrypting/decrypting OAuth credentials
|
||||
*/
|
||||
private static function get_salt() {
|
||||
if ( defined( 'LOGGED_IN_SALT' ) ) {
|
||||
return LOGGED_IN_SALT;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a value, encrypt it if the openssl extension is loaded and we have a valid key/salt
|
||||
*
|
||||
* @param string $value Value to encrypt.
|
||||
*
|
||||
* @return string Encrypted value
|
||||
*/
|
||||
public static function encrypt( $value ) {
|
||||
if ( ! extension_loaded( 'openssl' ) ||
|
||||
empty( self::get_key() ) ||
|
||||
empty( self::get_salt() ) ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$method = 'aes-256-ctr';
|
||||
$init_vector_length = openssl_cipher_iv_length( $method );
|
||||
$init_vector = openssl_random_pseudo_bytes( $init_vector_length );
|
||||
|
||||
$raw_value = openssl_encrypt( $value . self::get_salt(), $method, self::get_key(), 0, $init_vector );
|
||||
if ( ! $raw_value ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
|
||||
return base64_encode( $init_vector . $raw_value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrpyt a given value
|
||||
*
|
||||
* @param string $value the encrypted value to decrypt.
|
||||
*
|
||||
* @return string The decrypted value
|
||||
*/
|
||||
public static function decrypt( $value ) {
|
||||
if ( ! extension_loaded( 'openssl' ) ||
|
||||
empty( self::get_key() ) ||
|
||||
empty( self::get_salt() ) ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
|
||||
$raw_value = base64_decode( $value, true );
|
||||
|
||||
$method = 'aes-256-ctr';
|
||||
$init_vector_length = openssl_cipher_iv_length( $method );
|
||||
$init_vector = substr( $raw_value, 0, $init_vector_length );
|
||||
|
||||
$raw_value = substr( $raw_value, $init_vector_length );
|
||||
|
||||
$value = openssl_decrypt( $raw_value, $method, self::get_key(), 0, $init_vector );
|
||||
if ( ! $value || substr( $value, - strlen( self::get_salt() ) ) !== self::get_salt() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return substr( $value, 0, - strlen( self::get_salt() ) );
|
||||
}
|
||||
}
|
||||
167
wp/wp-content/plugins/leadin/public/class-assetsmanager.php
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin;
|
||||
|
||||
use Leadin\data\Filters;
|
||||
use Leadin\admin\AdminConstants;
|
||||
use Leadin\data\Portal_Options;
|
||||
|
||||
/**
|
||||
* Class responsible of managing all the plugin assets.
|
||||
*/
|
||||
class AssetsManager {
|
||||
const ADMIN_CSS = 'leadin-css';
|
||||
const BRIDGE_CSS = 'leadin-bridge-css';
|
||||
const ADMIN_JS = 'leadin-js';
|
||||
|
||||
const FEEDBACK_CSS = 'leadin-feedback-css';
|
||||
const FEEDBACK_JS = 'leadin-feedback';
|
||||
const TRACKING_CODE = 'leadin-script-loader-js';
|
||||
const GUTENBERG = 'leadin-gutenberg';
|
||||
const MEETINGS_GUTENBERG = 'leadin-meetings-gutenberg';
|
||||
const FORMS_SCRIPT = 'leadin-forms-v2';
|
||||
const MEETINGS_SCRIPT = 'leadin-meeting';
|
||||
const LEADIN_CONFIG = 'leadinConfig';
|
||||
const LEADIN_I18N = 'leadinI18n';
|
||||
const REVIEW_BANNER = 'leadin-review-banner';
|
||||
const ELEMENTOR = 'leadin-elementor';
|
||||
const APP_ENTRY_CSS = 'leadin-app-css';
|
||||
const APP_EMBEDDER = 'leadin-app-embedder';
|
||||
|
||||
/**
|
||||
* Register and localize all assets.
|
||||
*/
|
||||
public static function register_assets() {
|
||||
wp_register_style( self::ADMIN_CSS, LEADIN_ASSETS_PATH . '/style/leadin.css', array(), LEADIN_PLUGIN_VERSION );
|
||||
wp_register_script( self::ADMIN_JS, LEADIN_JS_BASE_PATH . '/leadin.js', array( 'jquery', 'wp-element' ), LEADIN_PLUGIN_VERSION, true );
|
||||
|
||||
wp_localize_script( self::ADMIN_JS, self::LEADIN_CONFIG, AdminConstants::get_leadin_config() );
|
||||
wp_register_script( self::FEEDBACK_JS, LEADIN_JS_BASE_PATH . '/feedback.js', array( 'jquery', 'thickbox' ), LEADIN_PLUGIN_VERSION, true );
|
||||
wp_localize_script( self::FEEDBACK_JS, self::LEADIN_CONFIG, AdminConstants::get_background_leadin_config() );
|
||||
wp_register_style( self::FEEDBACK_CSS, LEADIN_ASSETS_PATH . '/style/leadin-feedback.css', array(), LEADIN_PLUGIN_VERSION );
|
||||
wp_register_style( self::BRIDGE_CSS, LEADIN_ASSETS_PATH . '/style/leadin-bridge.css?', array(), LEADIN_PLUGIN_VERSION );
|
||||
wp_register_style( self::APP_ENTRY_CSS, LEADIN_JS_BASE_PATH . '/leadin.css', array(), LEADIN_PLUGIN_VERSION );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue the assets needed in the admin section.
|
||||
*/
|
||||
public static function enqueue_admin_assets() {
|
||||
wp_enqueue_style( self::ADMIN_CSS );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue the assets needed to render the deactivation feedback form.
|
||||
*/
|
||||
public static function enqueue_feedback_assets() {
|
||||
$embed_domain = Filters::apply_script_loader_domain_filters();
|
||||
wp_enqueue_script( self::APP_EMBEDDER, "$embed_domain/integrated-app-embedder/v1.js", array(), LEADIN_PLUGIN_VERSION, true );
|
||||
wp_enqueue_style( self::FEEDBACK_CSS );
|
||||
wp_enqueue_script( self::FEEDBACK_JS );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue the assets needed to correctly render the plugin's iframe.
|
||||
*/
|
||||
public static function enqueue_bridge_assets() {
|
||||
wp_enqueue_style( self::BRIDGE_CSS );
|
||||
wp_enqueue_script( self::ADMIN_JS );
|
||||
wp_enqueue_style( self::APP_ENTRY_CSS );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enqueue the assets needed to correctly render the integrated forms app.
|
||||
*/
|
||||
public static function enqueue_integrated_app_assets() {
|
||||
$embed_domain = Filters::apply_js_base_url_filters();
|
||||
wp_enqueue_style( self::BRIDGE_CSS );
|
||||
wp_enqueue_script( self::ADMIN_JS );
|
||||
wp_enqueue_style( self::APP_ENTRY_CSS );
|
||||
wp_enqueue_script( self::APP_EMBEDDER, "$embed_domain/integrated-app-embedder/v1.js", array(), LEADIN_PLUGIN_VERSION, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register and enqueue the HubSpot's script loader (aka tracking code), used to collect data from your visitors.
|
||||
* https://knowledge.hubspot.com/account/how-does-hubspot-track-visitors
|
||||
*
|
||||
* @param Object $leadin_wordpress_info Object used to pass to the script loader.
|
||||
*/
|
||||
public static function enqueue_script_loader( $leadin_wordpress_info ) {
|
||||
$embed_domain = Filters::apply_script_loader_domain_filters();
|
||||
$portal_id = Portal_Options::get_portal_id();
|
||||
$business_unit_id = Portal_Options::get_business_unit_id();
|
||||
$embed_url = "https://$embed_domain/$portal_id.js?integration=WordPress";
|
||||
|
||||
if ( $business_unit_id && '' !== $business_unit_id ) {
|
||||
$embed_url = $embed_url . "&businessUnitId=$business_unit_id";
|
||||
}
|
||||
|
||||
wp_register_script( self::TRACKING_CODE, $embed_url, array(), LEADIN_PLUGIN_VERSION, true );
|
||||
wp_localize_script( self::TRACKING_CODE, 'leadin_wordpress', $leadin_wordpress_info );
|
||||
wp_enqueue_script( self::TRACKING_CODE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register and enqueue forms script
|
||||
*/
|
||||
public static function enqueue_forms_script() {
|
||||
wp_enqueue_script(
|
||||
self::FORMS_SCRIPT,
|
||||
Filters::apply_forms_script_url_filters(),
|
||||
array(),
|
||||
LEADIN_PLUGIN_VERSION,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register and enqueue meetings script
|
||||
*/
|
||||
public static function enqueue_meetings_script() {
|
||||
wp_enqueue_script(
|
||||
self::MEETINGS_SCRIPT,
|
||||
'https://static.hsappstatic.net/MeetingsEmbed/ex/MeetingsEmbedCode.js',
|
||||
array(),
|
||||
LEADIN_PLUGIN_VERSION,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register and localize the Gutenberg scripts.
|
||||
*/
|
||||
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 );
|
||||
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_localize_script( self::GUTENBERG, self::LEADIN_CONFIG, AdminConstants::get_background_leadin_config() );
|
||||
wp_set_script_translations( self::GUTENBERG, 'leadin', __DIR__ . '/../languages' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register and enqueue a new script for tracking review banner events.
|
||||
*/
|
||||
public static function enqueue_review_banner_tracking_script() {
|
||||
wp_register_script( self::REVIEW_BANNER, LEADIN_JS_BASE_PATH . '/reviewBanner.js', array( 'jquery' ), LEADIN_PLUGIN_VERSION, true );
|
||||
wp_localize_script( self::REVIEW_BANNER, self::LEADIN_CONFIG, AdminConstants::get_background_leadin_config() );
|
||||
wp_enqueue_script( self::REVIEW_BANNER );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register and enqueue a new script/style for elementor.
|
||||
*/
|
||||
public static function enqueue_elementor_script() {
|
||||
$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 );
|
||||
wp_register_style( self::ELEMENTOR, LEADIN_JS_BASE_PATH . '/elementor.css', array(), LEADIN_PLUGIN_VERSION );
|
||||
wp_enqueue_style( self::ELEMENTOR );
|
||||
wp_register_script( self::ELEMENTOR, LEADIN_JS_BASE_PATH . '/elementor.js', array( 'wp-element', 'wp-i18n', self::APP_EMBEDDER ), LEADIN_PLUGIN_VERSION, true );
|
||||
wp_localize_script( self::ELEMENTOR, self::LEADIN_CONFIG, AdminConstants::get_background_leadin_config() );
|
||||
wp_enqueue_script( self::ELEMENTOR );
|
||||
wp_set_script_translations( self::ELEMENTOR, 'leadin', __DIR__ . '/../languages' );
|
||||
}
|
||||
|
||||
}
|
||||
68
wp/wp-content/plugins/leadin/public/class-leadin.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin;
|
||||
|
||||
require_once LEADIN_PLUGIN_DIR . '/public/includes/api-loader.php';
|
||||
|
||||
use \Leadin\AssetsManager;
|
||||
use \Leadin\PageHooks;
|
||||
use \Leadin\admin\LeadinAdmin;
|
||||
use Leadin\admin\widgets\ElementorForm;
|
||||
use Leadin\admin\widgets\ElementorMeeting;
|
||||
use Leadin\admin\widgets\ElementorFormSelect;
|
||||
use Leadin\admin\widgets\ElementorMeetingSelect;
|
||||
|
||||
/**
|
||||
* Main class of the plugin.
|
||||
*/
|
||||
class Leadin {
|
||||
/**
|
||||
* Plugin's constructor. Everything starts here.
|
||||
*/
|
||||
public function __construct() {
|
||||
new PageHooks();
|
||||
add_action( 'elementor/elements/categories_registered', array( $this, 'add_elementor_widget_categories' ) );
|
||||
add_action( 'elementor/controls/register', array( $this, 'register_hsselectors_control' ) );
|
||||
add_action( 'elementor/widgets/register', array( $this, 'register_elementor_widgets' ) );
|
||||
if ( is_admin() ) {
|
||||
new LeadinAdmin();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register widgets for Elementor.
|
||||
*
|
||||
* @param object $elements_manager elementor widget manager.
|
||||
*/
|
||||
public function add_elementor_widget_categories( $elements_manager ) {
|
||||
$elements_manager->add_category(
|
||||
'hubspot',
|
||||
array(
|
||||
'title' => esc_html__( 'Hubspot', 'leadin' ),
|
||||
'icon' => 'fa fa-plug',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register widgets for Elementor.
|
||||
*
|
||||
* @param object $widgets_manager elementor widget manager.
|
||||
*/
|
||||
public function register_elementor_widgets( $widgets_manager ) {
|
||||
$widgets_manager->register( new ElementorForm() );
|
||||
$widgets_manager->register( new ElementorMeeting() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register controls for elementor widget
|
||||
*
|
||||
* @param object $controls_manager elementor controls manager.
|
||||
*/
|
||||
public function register_hsselectors_control( $controls_manager ) {
|
||||
$controls_manager->register( new ElementorFormSelect() );
|
||||
$controls_manager->register( new ElementorMeetingSelect() );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
149
wp/wp-content/plugins/leadin/public/class-pagehooks.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin;
|
||||
|
||||
use Leadin\data\Filters;
|
||||
use Leadin\AssetsManager;
|
||||
use Leadin\data\User;
|
||||
use Leadin\auth\OAuth;
|
||||
use Leadin\admin\Connection;
|
||||
use Leadin\data\Portal_Options;
|
||||
use Leadin\utils\ShortcodeRenderUtils;
|
||||
|
||||
/**
|
||||
* Class responsible of adding the script loader to the website, as well as rendering forms, live chat, etc.
|
||||
*/
|
||||
class PageHooks {
|
||||
/**
|
||||
* Class constructor, adds the necessary hooks.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'init', array( $this, 'register_content_type_meta' ) );
|
||||
|
||||
add_action( 'wp_head', array( $this, 'add_page_analytics' ) );
|
||||
if ( Connection::is_connected() ) {
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'add_frontend_scripts' ) );
|
||||
}
|
||||
add_filter( 'script_loader_tag', array( $this, 'add_id_to_tracking_code' ), 10, 2 );
|
||||
add_filter( 'script_loader_tag', array( $this, 'add_defer_to_forms_script' ), 10, 2 );
|
||||
add_shortcode( 'hubspot', array( $this, 'leadin_add_hubspot_shortcode' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register meta key for content type
|
||||
*/
|
||||
public function register_content_type_meta() {
|
||||
register_post_meta(
|
||||
'',
|
||||
'content-type', // meta key.
|
||||
array(
|
||||
'object_subtype' => 'post', // specify a post type here.
|
||||
'type' => 'string',
|
||||
'single' => true,
|
||||
'show_in_rest' => true,
|
||||
'auth_callback' => function () {
|
||||
return current_user_can( 'edit_posts' );
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the script loader to the page.
|
||||
*/
|
||||
public function add_frontend_scripts() {
|
||||
if ( Portal_Options::get_disable_internal_tracking() && ( is_user_logged_in() || current_user_can( 'install_plugins' ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( is_single() ) {
|
||||
$page_type = 'post';
|
||||
} elseif ( is_front_page() ) {
|
||||
$page_type = 'home';
|
||||
} elseif ( is_archive() ) {
|
||||
$page_type = 'archive';
|
||||
} elseif ( is_page() ) {
|
||||
$page_type = 'page';
|
||||
} else {
|
||||
$page_type = 'other';
|
||||
}
|
||||
|
||||
$leadin_wordpress_info = array(
|
||||
'userRole' => User::get_role(),
|
||||
'pageType' => $page_type,
|
||||
'leadinPluginVersion' => LEADIN_PLUGIN_VERSION,
|
||||
);
|
||||
|
||||
AssetsManager::enqueue_script_loader( $leadin_wordpress_info );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the script containing the information needed by the script loader.
|
||||
*/
|
||||
public function add_page_analytics() {
|
||||
$portal_id = Portal_Options::get_portal_id();
|
||||
|
||||
if ( empty( $portal_id ) ) {
|
||||
echo '<!-- HubSpot WordPress Plugin v' . esc_html( LEADIN_PLUGIN_VERSION ) . ': embed JS disabled as a portalId has not yet been configured -->';
|
||||
} else {
|
||||
$content_type = Filters::apply_page_content_type_filters();
|
||||
$page_id = get_the_ID();
|
||||
$post_meta = get_post_meta( $page_id );
|
||||
if ( isset( $post_meta['content-type'][0] ) && '' !== $post_meta['content-type'][0] ) {
|
||||
$content_type = $post_meta['content-type'][0];
|
||||
} elseif ( is_plugin_active( 'elementor/elementor.php' ) ) {
|
||||
$page_settings_manager = \Elementor\Core\Settings\Manager::get_settings_managers( 'page' );
|
||||
$page_settings_model = $page_settings_manager->get_model( $page_id );
|
||||
$elementor_content_type = $page_settings_model->get_settings( 'content_type' );
|
||||
if ( ! empty( $elementor_content_type ) ) {
|
||||
$content_type = $elementor_content_type;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<!-- DO NOT COPY THIS SNIPPET! Start of Page Analytics Tracking for HubSpot WordPress plugin v<?php echo esc_html( LEADIN_PLUGIN_VERSION ); ?>-->
|
||||
<script class="hsq-set-content-id" data-content-id="<?php echo esc_html( $content_type ); ?>">
|
||||
var _hsq = _hsq || [];
|
||||
_hsq.push(["setContentType", "<?php echo esc_html( $content_type ); ?>"]);
|
||||
</script>
|
||||
<!-- DO NOT COPY THIS SNIPPET! End of Page Analytics Tracking for HubSpot WordPress plugin -->
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the required id to the script loader <script>
|
||||
*
|
||||
* @param String $tag tag name.
|
||||
* @param String $handle handle.
|
||||
*/
|
||||
public function add_id_to_tracking_code( $tag, $handle ) {
|
||||
if ( AssetsManager::TRACKING_CODE === $handle ) {
|
||||
$tag = str_replace( "id='" . $handle . "-js'", "async defer id='hs-script-loader'", $tag );
|
||||
}
|
||||
return $tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add defer to leadin forms plugin
|
||||
*
|
||||
* @param String $tag tag name.
|
||||
* @param String $handle handle.
|
||||
*/
|
||||
public function add_defer_to_forms_script( $tag, $handle ) {
|
||||
if ( AssetsManager::FORMS_SCRIPT === $handle ) {
|
||||
$tag = str_replace( 'src', 'defer src', $tag );
|
||||
}
|
||||
return $tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse leadin shortcodes
|
||||
*
|
||||
* @param array $attributes Shortcode attributes.
|
||||
*/
|
||||
public function leadin_add_hubspot_shortcode( $attributes ) {
|
||||
return ShortcodeRenderUtils::render_shortcode( $attributes );
|
||||
}
|
||||
|
||||
}
|
||||
173
wp/wp-content/plugins/leadin/public/data/class-filters.php
Normal file
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
namespace Leadin\data;
|
||||
|
||||
use Leadin\data\Portal_Options;
|
||||
|
||||
|
||||
/**
|
||||
* Class containing all the custom filters defined to be used instead of constants.
|
||||
*/
|
||||
class Filters {
|
||||
|
||||
/**
|
||||
* Return the current hublet.
|
||||
*/
|
||||
public static function apply_hublet_filters() {
|
||||
return apply_filters( LEADIN_PREFIX . '_hublet', Portal_Options::get_hublet() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the prefix for UI urls.
|
||||
*/
|
||||
public static function apply_app_prefix_filters() {
|
||||
return self::resolve_hublet( apply_filters( LEADIN_PREFIX . '_app_prefix', 'app' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the prefix for UI urls.
|
||||
*/
|
||||
public static function apply_js_prefix_filters() {
|
||||
return self::resolve_hublet( apply_filters( LEADIN_PREFIX . '_js_prefix', 'js' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the prefix for API urls.
|
||||
*/
|
||||
public static function apply_api_prefix_filters() {
|
||||
return self::resolve_hublet( apply_filters( LEADIN_PREFIX . '_api_prefix', 'api' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Hubspot domain.
|
||||
*/
|
||||
public static function apply_hubspot_domain_filters() {
|
||||
return apply_filters( LEADIN_PREFIX . '_hubspot_domain', 'hubspot.com' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply leadin_base_url filter.
|
||||
*
|
||||
* @param boolean $cross_hublet if false it's use non-hublet specific prefix. For example, "app" instead of "app-eu1".
|
||||
*/
|
||||
public static function apply_base_url_filters( $cross_hublet = true ) {
|
||||
$prefix = $cross_hublet ? self::apply_app_prefix_filters() : apply_filters( LEADIN_PREFIX . '_app_prefix', 'app' );
|
||||
$domain = self::apply_hubspot_domain_filters();
|
||||
return apply_filters( LEADIN_PREFIX . '_base_url', "https://$prefix.$domain" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply leadin_js_base_url filter.
|
||||
*/
|
||||
public static function apply_js_base_url_filters() {
|
||||
$prefix = self::apply_js_prefix_filters();
|
||||
$domain = self::apply_hubspot_domain_filters();
|
||||
return apply_filters( LEADIN_PREFIX . '_js_base_url', "https://$prefix.$domain" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply filter to get the base url for the HubSpot api.
|
||||
*
|
||||
* @param boolean $cross_hublet if true it's use non-hublet specific prefix. For example, "api" instead of "api-eu1".
|
||||
*/
|
||||
public static function apply_base_api_url_filters( $cross_hublet = false ) {
|
||||
$prefix = $cross_hublet ? 'api' : self::apply_api_prefix_filters();
|
||||
$domain = self::apply_hubspot_domain_filters();
|
||||
return apply_filters( LEADIN_PREFIX . '_base_api_url', "https://$prefix.$domain" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply leadin_signup_base_url filter.
|
||||
*/
|
||||
public static function apply_signup_base_url_filters() {
|
||||
$domain = self::apply_hubspot_domain_filters();
|
||||
return apply_filters( LEADIN_PREFIX . '_signup_base_url', "https://app.$domain" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply leadin_forms_script_url filter.
|
||||
*/
|
||||
public static function apply_forms_script_url_filters() {
|
||||
$hublet_domain = self::resolve_hublet( 'js' );
|
||||
return apply_filters( LEADIN_PREFIX . '_forms_script_url', "https://$hublet_domain.hsforms.net/forms/embed/v2.js" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply leadin_meetings_script_url filter.
|
||||
*/
|
||||
public static function apply_meetings_script_url_filters() {
|
||||
return apply_filters( LEADIN_PREFIX . '_meetings_script_url', 'https://static.hsappstatic.net/MeetingsEmbed/ex/MeetingsEmbedCode.js' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply leadin_script_loader_domain filter.
|
||||
*/
|
||||
public static function apply_script_loader_domain_filters() {
|
||||
$hublet_domain = self::resolve_hublet( 'js' );
|
||||
return apply_filters( LEADIN_PREFIX . '_script_loader_domain', "$hublet_domain.hs-scripts.com" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply leadin_forms_payload filter.
|
||||
*/
|
||||
public static function apply_forms_payload_filters() {
|
||||
return apply_filters( LEADIN_PREFIX . '_forms_payload', '' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply leadin_forms_payload_url filter.
|
||||
*/
|
||||
public static function apply_page_content_type_filters() {
|
||||
if ( is_single() ) {
|
||||
$content_type = 'blog-post';
|
||||
} elseif ( is_archive() || is_search() ) {
|
||||
$content_type = 'listing-page';
|
||||
} else {
|
||||
$content_type = 'standard-page';
|
||||
}
|
||||
|
||||
return apply_filters( LEADIN_PREFIX . '_page_content_type', $content_type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply leadin_view_plugin_menu_capability filter.
|
||||
*/
|
||||
public static function apply_view_plugin_menu_capability_filters() {
|
||||
return apply_filters( LEADIN_PREFIX . '_view_plugin_menu_capability', 'edit_posts' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply leadin_connect_plugin_capability filter.
|
||||
*/
|
||||
public static function apply_connect_plugin_capability_filters() {
|
||||
return apply_filters( LEADIN_PREFIX . '_connect_plugin_capability', 'manage_options' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply leadin_impact_code filter.
|
||||
*/
|
||||
public static function apply_impact_code_filters() {
|
||||
return apply_filters( LEADIN_PREFIX . '_impact_code', null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply leadin_query_params filter.
|
||||
*/
|
||||
public static function apply_query_params_filters() {
|
||||
return apply_filters( LEADIN_PREFIX . '_query_params', '' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add hublet to the prefix.
|
||||
*
|
||||
* @param String $prefix Prefix to add the hublet to.
|
||||
*/
|
||||
private static function resolve_hublet( $prefix ) {
|
||||
$hublet = self::apply_hublet_filters();
|
||||
$result = $prefix;
|
||||
if ( ! empty( $hublet ) && 'na1' !== $hublet ) {
|
||||
$result = "$prefix-$hublet";
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\data;
|
||||
|
||||
/**
|
||||
* Class that wraps the functions to access options related to the HubSpot account.
|
||||
*/
|
||||
class Portal_Options {
|
||||
const PORTAL_ID = LEADIN_PREFIX . '_portalId';
|
||||
const PORTAL_DOMAIN = LEADIN_PREFIX . '_portal_domain';
|
||||
const ACCOUNT_NAME = LEADIN_PREFIX . '_account_name';
|
||||
const HUBLET = LEADIN_PREFIX . '_hublet';
|
||||
const DISABLE_INTERNAL_TRACKING = LEADIN_PREFIX . '_disable_internal_tracking';
|
||||
const ACTIVATION_TIME = LEADIN_PREFIX . '_activation_time';
|
||||
const REFRESH_TOKEN = LEADIN_PREFIX . '_refresh_token';
|
||||
const BUSINESS_UNIT_ID = LEADIN_PREFIX . '_business_unit_id';
|
||||
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.
|
||||
*/
|
||||
public static function get_portal_id() {
|
||||
return get_option( self::PORTAL_ID );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set portal id.
|
||||
*
|
||||
* @param Number $portal_id HubSpot portal id.
|
||||
*/
|
||||
public static function set_portal_id( $portal_id ) {
|
||||
return update_option( self::PORTAL_ID, $portal_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete portal id.
|
||||
*/
|
||||
public static function delete_portal_id() {
|
||||
return delete_option( self::PORTAL_ID );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return portal's domain.
|
||||
*/
|
||||
public static function get_portal_domain() {
|
||||
return get_option( self::PORTAL_DOMAIN );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set portal domain.
|
||||
*
|
||||
* @param string $domain domain.
|
||||
*/
|
||||
public static function set_portal_domain( $domain ) {
|
||||
return update_option( self::PORTAL_DOMAIN, $domain );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete portal domain.
|
||||
*/
|
||||
public static function delete_portal_domain() {
|
||||
return delete_option( self::PORTAL_DOMAIN );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return account name.
|
||||
*/
|
||||
public static function get_account_name() {
|
||||
return get_option( self::ACCOUNT_NAME );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set account name.
|
||||
*
|
||||
* @param string $name name.
|
||||
*/
|
||||
public static function set_account_name( $name ) {
|
||||
return update_option( self::ACCOUNT_NAME, $name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete account name.
|
||||
*/
|
||||
public static function delete_account_name() {
|
||||
return delete_option( self::ACCOUNT_NAME );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return option containing hublet info.
|
||||
*/
|
||||
public static function get_hublet() {
|
||||
return get_option( self::HUBLET );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return option containing hublet info.
|
||||
*
|
||||
* @param string $hublet hublet.
|
||||
*/
|
||||
public static function set_hublet( $hublet ) {
|
||||
return update_option( self::HUBLET, $hublet );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete hublet
|
||||
*/
|
||||
public static function delete_hublet() {
|
||||
return delete_option( self::HUBLET );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return option flag for disabling internal users to appear at HS analytics.
|
||||
*/
|
||||
public static function get_disable_internal_tracking() {
|
||||
return get_option( self::DISABLE_INTERNAL_TRACKING );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set option containing flag for disabling internal users to appear at HS analytics.
|
||||
*
|
||||
* @param string $internal_tracking hublet.
|
||||
*/
|
||||
public static function set_disable_internal_tracking( $internal_tracking = '0' ) {
|
||||
return update_option( self::DISABLE_INTERNAL_TRACKING, $internal_tracking );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete option flag for disabling internal tracking
|
||||
*/
|
||||
public static function delete_disable_internal_tracking() {
|
||||
return delete_option( self::DISABLE_INTERNAL_TRACKING );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return activation time.
|
||||
*/
|
||||
public static function get_activation_time() {
|
||||
return get_option( self::ACTIVATION_TIME );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set activation time.
|
||||
*/
|
||||
public static function set_activation_time() {
|
||||
return update_option( self::ACTIVATION_TIME, time() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete portal id.
|
||||
*/
|
||||
public static function delete_activation_time() {
|
||||
return delete_option( self::ACTIVATION_TIME );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return refresh access token.
|
||||
*/
|
||||
public static function get_refresh_token() {
|
||||
return get_option( self::REFRESH_TOKEN );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set refresh access token.
|
||||
*
|
||||
* @param string $refresh_token token.
|
||||
*/
|
||||
public static function set_refresh_token( $refresh_token ) {
|
||||
return update_option( self::REFRESH_TOKEN, $refresh_token );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete refresh access token.
|
||||
*/
|
||||
public static function delete_refresh_token() {
|
||||
return delete_option( self::REFRESH_TOKEN );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return device id hash.
|
||||
*/
|
||||
public static function get_device_id() {
|
||||
$site_url = get_home_url();
|
||||
$user_id = get_current_user_id();
|
||||
return hash( 'sha256', "$site_url:$user_id" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return business_unit_id for connected portal.
|
||||
*/
|
||||
public static function get_business_unit_id() {
|
||||
return get_option( self::BUSINESS_UNIT_ID );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set business_unit_id for the connected portal.
|
||||
*
|
||||
* @param number $business_unit_id businessUnitId.
|
||||
*/
|
||||
public static function set_business_unit_id( $business_unit_id ) {
|
||||
return update_option( self::BUSINESS_UNIT_ID, $business_unit_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete business_unit_id.
|
||||
*/
|
||||
public static function delete_business_unit_id() {
|
||||
return delete_option( self::BUSINESS_UNIT_ID );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set when last authorized.
|
||||
*/
|
||||
public static function set_last_authorize_time() {
|
||||
return update_option( self::LAST_AUTHORIZE_TIME, time() );
|
||||
}
|
||||
/**
|
||||
* Set when last deauthorized.
|
||||
*/
|
||||
public static function set_last_deauthorize_time() {
|
||||
return update_option( self::LAST_DEAUTHORIZE_TIME, time() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set when last disconnect.
|
||||
*/
|
||||
public static function set_last_disconnect_time() {
|
||||
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.
|
||||
*
|
||||
* @return mixed The last authorization time, or false if not set.
|
||||
*/
|
||||
public static function get_last_authorize_time() {
|
||||
return get_option( self::LAST_AUTHORIZE_TIME, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last time deauthorization was performed.
|
||||
*
|
||||
* @return mixed The last deauthorization time, or false if not set.
|
||||
*/
|
||||
public static function get_last_deauthorize_time() {
|
||||
return get_option( self::LAST_DEAUTHORIZE_TIME, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last time a disconnect was performed.
|
||||
*
|
||||
* @return mixed The last disconnect time, or false if not set.
|
||||
*/
|
||||
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' );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\data;
|
||||
|
||||
use Leadin\data\User;
|
||||
|
||||
/**
|
||||
* Handles metadata for users in the admin area.
|
||||
*/
|
||||
class User_Metadata {
|
||||
|
||||
const SKIP_REVIEW = 'leadin_skip_review';
|
||||
const REVIEW_BANNER_LAST_CALL = 'leadin_review_banner_last_call';
|
||||
const HAS_MIN_CONTACTS = 'leadin_has_min_contacts';
|
||||
const TRACK_CONSENT = 'leadin_track_consent';
|
||||
const FIRST_NAME = 'first_name';
|
||||
const NICKNAME = 'nickname';
|
||||
|
||||
|
||||
/**
|
||||
* Get FIRST_NAME meta data for a user.
|
||||
*/
|
||||
public static function get_first_name() {
|
||||
return User::get_metadata( self::FIRST_NAME );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get NICKNAME meta data for a user.
|
||||
*/
|
||||
public static function get_nickname() {
|
||||
return User::get_metadata( self::NICKNAME );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SKIP_REVIEW meta data for a user.
|
||||
*
|
||||
* @param int $skip_epoch Epoch time of when the review was skipped.
|
||||
*/
|
||||
public static function set_skip_review( $skip_epoch ) {
|
||||
return User::set_metadata( self::SKIP_REVIEW, $skip_epoch );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SKIP_REVIEW meta data for a user.
|
||||
*/
|
||||
public static function get_skip_review() {
|
||||
return User::get_metadata( self::SKIP_REVIEW );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set REVIEW_BANNER_LAST_CALL meta data for a user.
|
||||
*
|
||||
* @param int $skip_epoch Epoch time of when the review was skipped.
|
||||
*/
|
||||
public static function set_review_banner_last_call( $skip_epoch ) {
|
||||
return User::set_metadata( self::REVIEW_BANNER_LAST_CALL, $skip_epoch );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get REVIEW_BANNER_LAST_CALL meta data for a user.
|
||||
*/
|
||||
public static function get_review_banner_last_call() {
|
||||
return User::get_metadata( self::REVIEW_BANNER_LAST_CALL );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set HAS_MIN_CONTACTS meta data for a user.
|
||||
*
|
||||
* @param bool $value Boolean to see if contacts already been fetched and fulfill threshold.
|
||||
*/
|
||||
public static function set_has_min_contacts( $value ) {
|
||||
return User::set_metadata( self::HAS_MIN_CONTACTS, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HAS_MIN_CONTACTS meta data for a user.
|
||||
*/
|
||||
public static function get_has_min_contacts() {
|
||||
return User::get_metadata( self::HAS_MIN_CONTACTS );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set TRACK_CONSENT meta data for a user.
|
||||
*
|
||||
* @param bool $consent User consent to anonymous tracking.
|
||||
*/
|
||||
public static function set_track_consent( $consent ) {
|
||||
return User::set_metadata( self::TRACK_CONSENT, $consent );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TRACK_CONSENT meta data for a user.
|
||||
*/
|
||||
public static function get_track_consent() {
|
||||
return User::get_metadata( self::TRACK_CONSENT );
|
||||
}
|
||||
|
||||
}
|
||||
59
wp/wp-content/plugins/leadin/public/data/class-user.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\data;
|
||||
|
||||
/**
|
||||
* Static function that wraps the WordPress current user functions.
|
||||
*/
|
||||
class User {
|
||||
/**
|
||||
* Return the first role of the current user. If unauthenticated, return 'visitor'.
|
||||
*/
|
||||
public static function get_role() {
|
||||
global $current_user;
|
||||
|
||||
if ( is_user_logged_in() ) {
|
||||
$user_roles = $current_user->roles;
|
||||
$user_role = array_shift( $user_roles );
|
||||
} else {
|
||||
$user_role = 'visitor';
|
||||
}
|
||||
|
||||
return $user_role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the current user has the `manage_options` capability.
|
||||
*/
|
||||
public static function is_admin() {
|
||||
return current_user_can( 'manage_options' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set metadata for current user
|
||||
*
|
||||
* @param String $key metadata key to store data in.
|
||||
* @param String $data metadata value to store.
|
||||
*/
|
||||
public static function set_metadata( $key, $data ) {
|
||||
update_user_meta( get_current_user_id(), $key, $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch metadata stored for this user by key
|
||||
*
|
||||
* @param String $key metadata to retrieve by the key.
|
||||
*/
|
||||
public static function get_metadata( $key ) {
|
||||
return get_user_meta( get_current_user_id(), $key, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete metadata associated with this user
|
||||
*
|
||||
* @param String $key key to delete metadata for.
|
||||
*/
|
||||
public static function delete_metadata( $key ) {
|
||||
delete_user_meta( get_current_user_id(), $key );
|
||||
}
|
||||
}
|
||||
27
wp/wp-content/plugins/leadin/public/includes/api-loader.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin;
|
||||
|
||||
use Leadin\api\Healthcheck_Api_Controller;
|
||||
|
||||
use Leadin\admin\api\Internal_Tracking_Api_Controller;
|
||||
use Leadin\admin\api\Hublet_Api_Controller;
|
||||
use Leadin\admin\api\User_Meta_Api_Controller;
|
||||
use Leadin\admin\api\Portal_Api_Controller;
|
||||
|
||||
add_action(
|
||||
'rest_api_init',
|
||||
'Leadin\\leadin_register_routes'
|
||||
);
|
||||
|
||||
/**
|
||||
* Register api endpoints.
|
||||
*/
|
||||
function leadin_register_routes() {
|
||||
new Healthcheck_Api_Controller();
|
||||
// Admin routes.
|
||||
new Internal_Tracking_Api_Controller();
|
||||
new Hublet_Api_Controller();
|
||||
new User_Meta_Api_Controller();
|
||||
new Portal_Api_Controller();
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\api;
|
||||
|
||||
use Leadin\data\Filters;
|
||||
|
||||
/**
|
||||
* Base class to set a rest endpoint
|
||||
*/
|
||||
class Base_Api_Controller {
|
||||
|
||||
/**
|
||||
* Register a route with given parameters
|
||||
*
|
||||
* @param string $path The path for the route to register the service on. Route gets namespaced with leadin/v1.
|
||||
* @param string $methods Comma seperated list of methods allowed for this route.
|
||||
* @param array $callback Method to execute when this endpoint is requested.
|
||||
*/
|
||||
public function register_leadin_route( $path, $methods, $callback ) {
|
||||
register_rest_route(
|
||||
'leadin/v1',
|
||||
$path,
|
||||
array(
|
||||
'methods' => $methods,
|
||||
'callback' => $callback,
|
||||
'permission_callback' => array( $this, 'verify_permissions' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an admin route with given parameters
|
||||
*
|
||||
* @param string $path The path for the route to register the service on. Route gets namespaced with leadin/v1.
|
||||
* @param string $methods Comma seperated list of methods allowed for this route.
|
||||
* @param array $callback Method to execute when this endpoint is requested.
|
||||
*/
|
||||
public function register_leadin_admin_route( $path, $methods, $callback ) {
|
||||
register_rest_route(
|
||||
'leadin/v1',
|
||||
$path,
|
||||
array(
|
||||
'methods' => $methods,
|
||||
'callback' => $callback,
|
||||
'permission_callback' => array( $this, 'verify_admin_permissions' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Permissions required by user to execute the request. User permissions are already
|
||||
* verified by nonce 'wp_rest' automatically.
|
||||
*
|
||||
* @return bool true if the user has adequate permissions for this endpoint.
|
||||
*/
|
||||
public function verify_permissions() {
|
||||
return current_user_can( Filters::apply_view_plugin_menu_capability_filters() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Permissions required by user to execute the request. User permissions are already
|
||||
* verified by nonce 'wp_rest' automatically.
|
||||
*
|
||||
* @return bool true if the user has adequate admin permissions for this endpoint.
|
||||
*/
|
||||
public function verify_admin_permissions() {
|
||||
return current_user_can( Filters::apply_connect_plugin_capability_filters() );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\api;
|
||||
|
||||
use Leadin\api\Base_Api_Controller;
|
||||
|
||||
/**
|
||||
* Healthcheck deployment endpoint
|
||||
*/
|
||||
class Healthcheck_Api_Controller extends Base_Api_Controller {
|
||||
|
||||
/**
|
||||
* Class constructor, register route.
|
||||
*/
|
||||
public function __construct() {
|
||||
self::register_leadin_route(
|
||||
'/healthcheck',
|
||||
\WP_REST_Server::READABLE,
|
||||
array( $this, 'get_healthcheck_request' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for healtcheck endpoint.
|
||||
* leadin/v1/healthcheck Method:GET.
|
||||
*
|
||||
* @return string OK response message.
|
||||
*/
|
||||
public function get_healthcheck_request() {
|
||||
return new \WP_REST_Response( 'OK', 200 );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\utils;
|
||||
|
||||
/**
|
||||
* Class containing utility functions for the sanitizing and getting query parameters.
|
||||
*/
|
||||
class QueryParameters {
|
||||
|
||||
/**
|
||||
* Return a text sanitized, unslashed query parameter by its key, validated with a nonce.
|
||||
*
|
||||
* @param String $key Key for the query parameter to return.
|
||||
* @param String $nonce_action Name of the nonce action to verify the given nonce against.
|
||||
* @param String $nonce_arg Query parmeter the nonce is in.
|
||||
*/
|
||||
public static function get_param( $key, $nonce_action, $nonce_arg = '_wpnonce' ) {
|
||||
if (
|
||||
isset( $_GET[ $key ] ) &&
|
||||
isset( $_GET[ $nonce_arg ] ) &&
|
||||
wp_verify_nonce( sanitize_text_field( wp_unslash( ( $_GET[ $nonce_arg ] ) ) ), $nonce_action )
|
||||
) {
|
||||
return sanitize_text_field( wp_unslash( ( $_GET[ $key ] ) ) );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array sanitized, unslashed query parameter by its key, validated with a nonce.
|
||||
*
|
||||
* @param String $key Key for the query parameter to return.
|
||||
* @param String $nonce_action Name of the nonce action to verify the given nonce against.
|
||||
* @param String $nonce_arg Query parmeter the nonce is in.
|
||||
*/
|
||||
public static function get_param_array( $key, $nonce_action, $nonce_arg = '_wpnonce' ) {
|
||||
if (
|
||||
isset( $_GET[ $key ] ) &&
|
||||
isset( $_GET[ $nonce_arg ] ) &&
|
||||
wp_verify_nonce( sanitize_text_field( wp_unslash( ( $_GET[ $nonce_arg ] ) ) ), $nonce_action )
|
||||
) {
|
||||
return array_map( 'sanitize_text_field', wp_unslash( $_GET[ $key ] ) );
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an associative array of query param keys and values given an array of keys
|
||||
* that are sanitized and validated against a nonce
|
||||
*
|
||||
* @param String $keys Array of keys to fetch query parameter values for.
|
||||
* @param String $nonce_action Name of the nonce action to verify the given nonce against.
|
||||
* @param String $nonce_arg Query parmeter the nonce is in.
|
||||
*/
|
||||
public static function get_parameters( $keys, $nonce_action, $nonce_arg = '_wpnonce' ) {
|
||||
$query_params = array_reduce(
|
||||
$keys,
|
||||
function( $result, $key ) use ( $nonce_arg, $nonce_action ) {
|
||||
$query_param = QueryParameters::get_param( $key, $nonce_action, $nonce_arg );
|
||||
|
||||
$result[ $key ] = $query_param;
|
||||
return $result;
|
||||
},
|
||||
array()
|
||||
);
|
||||
|
||||
return $query_params;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\utils;
|
||||
|
||||
/**
|
||||
* Static class containing methods used on ajax requests handling.
|
||||
*/
|
||||
class RequestUtils {
|
||||
/**
|
||||
* Send JSON response.
|
||||
*
|
||||
* @param Mixed $body response to send as JSON.
|
||||
* @param Number $code http code to return.
|
||||
*/
|
||||
private static function send( $body, $code ) {
|
||||
wp_send_json( $body, intval( $code ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Send JSON response with 200 code.
|
||||
*
|
||||
* @param Mixed $body response to send as JSON.
|
||||
*/
|
||||
public static function send_json( $body = array() ) {
|
||||
self::send( $body, 200 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Send error response with message
|
||||
*
|
||||
* @param String $error Message to be sent on te JSON.
|
||||
* @param Number $code Error code to be sent in the error. Default 400.
|
||||
*/
|
||||
public static function send_error_message( $error, $code = 400 ) {
|
||||
self::send(
|
||||
array(
|
||||
'error' => $error,
|
||||
),
|
||||
intval( $code )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send JSON response with a message key.
|
||||
*
|
||||
* @param String $message Message to be sent on te JSON.
|
||||
*/
|
||||
public static function send_message( $message ) {
|
||||
self::send(
|
||||
array(
|
||||
'message' => $message,
|
||||
),
|
||||
200
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\utils;
|
||||
|
||||
use Leadin\data\Filters;
|
||||
use Leadin\AssetsManager;
|
||||
|
||||
/**
|
||||
* Util Class responsible for rendering shortcodes.
|
||||
*/
|
||||
class ShortcodeRenderUtils {
|
||||
|
||||
/**
|
||||
* Render leadin shortcodes output
|
||||
*
|
||||
* @param array $shortcode_attrs Shortcode attributes.
|
||||
*/
|
||||
public static function render_shortcode( $shortcode_attrs ) {
|
||||
$parsed_attributes = shortcode_atts( array( 'type' => null ), $shortcode_attrs );
|
||||
|
||||
$type = $parsed_attributes['type'];
|
||||
if ( ! isset( $type ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( $type ) {
|
||||
case 'form':
|
||||
return self::render_form( $shortcode_attrs );
|
||||
case 'cta':
|
||||
return self::render_cta( $shortcode_attrs );
|
||||
case 'meeting':
|
||||
return self::render_meeting( $shortcode_attrs );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render form leadin shortcodes
|
||||
*
|
||||
* @param array $attrs Shortcode attributes.
|
||||
*/
|
||||
private static function render_form( $attrs ) {
|
||||
$parsed_attributes = shortcode_atts(
|
||||
array(
|
||||
'portal' => null,
|
||||
'id' => null,
|
||||
),
|
||||
$attrs
|
||||
);
|
||||
|
||||
$portal_id = $parsed_attributes['portal'];
|
||||
$id = $parsed_attributes['id'];
|
||||
|
||||
if ( ! isset( $portal_id ) || ! isset( $id ) || ! is_numeric( $portal_id ) ||
|
||||
! ( self::is_valid_uuid( $id ) || is_numeric( $id ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$form_div_uuid = self::generate_div_uuid();
|
||||
$hublet = Filters::apply_hublet_filters();
|
||||
AssetsManager::enqueue_forms_script();
|
||||
return '
|
||||
<script>
|
||||
window.hsFormsOnReady = window.hsFormsOnReady || [];
|
||||
window.hsFormsOnReady.push(()=>{
|
||||
hbspt.forms.create({
|
||||
portalId: ' . $portal_id . ',
|
||||
formId: "' . $id . '",
|
||||
target: "#hbspt-form-' . $form_div_uuid . '",
|
||||
region: "' . $hublet . '",
|
||||
' . Filters::apply_forms_payload_filters() . '
|
||||
})});
|
||||
</script>
|
||||
<div class="hbspt-form" id="hbspt-form-' . $form_div_uuid . '"></div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render cta leadin shortcodes
|
||||
*
|
||||
* @param array $attrs Shortcode attributes.
|
||||
*/
|
||||
private static function render_cta( $attrs ) {
|
||||
$parsed_attributes = shortcode_atts(
|
||||
array(
|
||||
'portal' => null,
|
||||
'id' => null,
|
||||
),
|
||||
$attrs
|
||||
);
|
||||
|
||||
$portal_id = $parsed_attributes['portal'];
|
||||
$id = $parsed_attributes['id'];
|
||||
|
||||
if ( ! isset( $portal_id ) || ! isset( $id ) || ! is_numeric( $portal_id ) ||
|
||||
! ( self::is_valid_uuid( $id ) || is_numeric( $id ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
return '
|
||||
<!--HubSpot Call-to-Action Code -->
|
||||
<span class="hs-cta-wrapper" id="hs-cta-wrapper-' . $id . '">
|
||||
<span class="hs-cta-node hs-cta-' . $id . '" id="' . $id . '">
|
||||
<!--[if lte IE 8]>
|
||||
<div id="hs-cta-ie-element"></div>
|
||||
<![endif]-->
|
||||
<a href="https://cta-redirect.hubspot.com/cta/redirect/' . $portal_id . '/' . $id . '" >
|
||||
<img class="hs-cta-img" id="hs-cta-img-' . $id . '" style="border-width:0px;" src="https://no-cache.hubspot.com/cta/default/' . $portal_id . '/' . $id . '.png" alt="New call-to-action"/>
|
||||
</a>
|
||||
</span>
|
||||
<' . 'script charset="utf-8" src="//js.hubspot.com/cta/current.js"></script>
|
||||
<script>
|
||||
hbspt.cta.load(' . $portal_id . ', \'' . $id . '\', {});
|
||||
</script>
|
||||
</span>
|
||||
<!-- end HubSpot Call-to-Action Code -->
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render meeting leadin shortcodes
|
||||
*
|
||||
* @param array $attrs Shortcode attributes.
|
||||
*/
|
||||
private static function render_meeting( $attrs ) {
|
||||
$parsed_attributes = shortcode_atts(
|
||||
array(
|
||||
'url' => null,
|
||||
),
|
||||
$attrs
|
||||
);
|
||||
|
||||
$url = esc_url_raw( $parsed_attributes['url'] );
|
||||
|
||||
if ( filter_var( $url, FILTER_VALIDATE_URL ) === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
AssetsManager::enqueue_meetings_script();
|
||||
|
||||
return '
|
||||
<div class="meetings-iframe-container" data-src="' . $url . '?embed=true"></div>
|
||||
<script>
|
||||
if(window.hbspt && window.hbspt.meetings){
|
||||
window.hbspt.meetings.create(".meetings-iframe-container");
|
||||
}
|
||||
</script>
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates 10 characters long string with random values
|
||||
*/
|
||||
private static function get_random_number_string() {
|
||||
$result = '';
|
||||
for ( $i = 0; $i < 10; $i++ ) {
|
||||
$result .= wp_rand( 0, 9 );
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a unique uuid
|
||||
*/
|
||||
private static function generate_div_uuid() {
|
||||
return time() * 1000 . '-' . self::get_random_number_string();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if input is a valid uuid.
|
||||
*
|
||||
* @param String $uuid input to validate.
|
||||
*/
|
||||
private static function is_valid_uuid( $uuid ) {
|
||||
if ( ! is_string( $uuid ) || ( preg_match( '/^[a-f\d]{8}(-[a-f\d]{4}){4}[a-f\d]{8}$/i', $uuid ) !== 1 ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
62
wp/wp-content/plugins/leadin/public/utils/class-versions.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\utils;
|
||||
|
||||
/**
|
||||
* Static class containing all the utility functions related to versioning.
|
||||
*/
|
||||
class Versions {
|
||||
/**
|
||||
* Return the given version until the patch version
|
||||
* eg: 6.4.2.1-beta => 6.4.2
|
||||
*
|
||||
* @param String $version version.
|
||||
*/
|
||||
private static function parse_version( $version ) {
|
||||
preg_match( '/^\d+(\.\d+){0,2}/', $version, $match );
|
||||
if ( empty( $match ) ) {
|
||||
return '';
|
||||
}
|
||||
return $match[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current WordPress version.
|
||||
*/
|
||||
public static function get_wp_version() {
|
||||
global $wp_version;
|
||||
return self::parse_version( $wp_version );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current PHP version.
|
||||
*/
|
||||
public static function get_php_version() {
|
||||
return self::parse_version( phpversion() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the current PHP version is not supported.
|
||||
*/
|
||||
public static function is_php_version_not_supported() {
|
||||
return version_compare( phpversion(), LEADIN_REQUIRED_PHP_VERSION, '<' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the current WordPress version is not supported.
|
||||
*/
|
||||
public static function is_wp_version_not_supported() {
|
||||
global $wp_version;
|
||||
return version_compare( $wp_version, LEADIN_REQUIRED_WP_VERSION, '<' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if a given version is less than the supported version
|
||||
*
|
||||
* @param String $version Given version to check.
|
||||
* @param String $version_to_compare The version number to test the given version against.
|
||||
*/
|
||||
public static function is_version_less_than( $version, $version_to_compare ) {
|
||||
return version_compare( $version, $version_to_compare, '<' );
|
||||
}
|
||||
}
|
||||
33
wp/wp-content/plugins/leadin/public/wp/class-page.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Leadin\wp;
|
||||
|
||||
/**
|
||||
* Static function that wraps WordPress utility functions for WordPress pages.
|
||||
*/
|
||||
class Page {
|
||||
/**
|
||||
* Return true if the current page has Gutenberg active.
|
||||
*/
|
||||
public static function is_gutenberg_page() {
|
||||
if ( function_exists( 'is_gutenberg_page' ) && is_gutenberg_page() ) {
|
||||
// The Gutenberg plugin is on.
|
||||
return true;
|
||||
}
|
||||
|
||||
$current_screen = get_current_screen();
|
||||
if ( method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor() ) {
|
||||
// Gutenberg page on 5+.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the current page is the WP Admin dashboard.
|
||||
*/
|
||||
public static function is_dashboard() {
|
||||
$screen = get_current_screen();
|
||||
return 'dashboard' === $screen->id;
|
||||
}
|
||||
}
|
||||