Skip to content

Commit

Permalink
feat: add Hyve Promo
Browse files Browse the repository at this point in the history
This PR adds a promotion notice to WP's Plugin Install screen based on the following conditions:

- The user has a page containing "Support" in the title.
  • Loading branch information
HardeepAsrani authored Sep 9, 2024
1 parent ec03171 commit 47348ce
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 13 deletions.
2 changes: 1 addition & 1 deletion assets/js/build/about/about.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'wp-components', 'wp-element'), 'version' => '2f7b01c785d210cc0a66');
<?php return array('dependencies' => array('react', 'wp-components', 'wp-element'), 'version' => 'fc64a210bede1308e242');
2 changes: 1 addition & 1 deletion assets/js/build/about/about.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/js/build/float_widget/float.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('wp-components', 'wp-element'), 'version' => 'ce3090dc0e13b5e1c2e4');
<?php return array('dependencies' => array('react', 'wp-components', 'wp-element'), 'version' => '80cf3f304af2c0a33ac3');
2 changes: 1 addition & 1 deletion assets/js/build/float_widget/float.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion assets/js/build/promos/index.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-components', 'wp-compose', 'wp-data', 'wp-edit-post', 'wp-element', 'wp-hooks', 'wp-plugins'), 'version' => '2cd9ed3afc77de83f989');
<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-components', 'wp-compose', 'wp-data', 'wp-edit-post', 'wp-element', 'wp-hooks', 'wp-plugins'), 'version' => 'dfd4ce8c8029dca3f091');
2 changes: 1 addition & 1 deletion assets/js/build/promos/index.js

Large diffs are not rendered by default.

139 changes: 139 additions & 0 deletions assets/js/src/hyve.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import { createRoot, useState } from '@wordpress/element';
import { Button } from '@wordpress/components';
import useSettings from "./common/useSettings";
import { activatePlugin, installPluginOrTheme } from './common/utils';

const HyveNotice = ({
onDismiss = () => {}
}) => {
const {
title,
option,
optionKey,
labels,
hyveActivationUrl,
hyveDash,
} = window.themeisleSDKPromotions;

const [ dismissed, setDismissed ] = useState( false );
const [ progress, setProgress ] = useState( null );
const [ getOption, updateOption ] = useSettings();

const dismissNotice = async () => {
setDismissed( true );
const newValue = { ...option };
newValue['hyve-plugins-install'] = new Date().getTime() / 1000 | 0;
window.themeisleSDKPromotions.option = newValue;
await updateOption( optionKey, JSON.stringify( newValue ) );

if ( onDismiss ) {
onDismiss();
}
};

const installPluginRequest = async e => {
e.preventDefault();
setProgress( 'installing' );
await installPluginOrTheme( 'hyve-lite' );

setProgress( 'activating' );
await activatePlugin( hyveActivationUrl );

updateOption( 'themeisle_sdk_promotions_hyve_installed', ! Boolean( getOption( 'themeisle_sdk_promotions_hyve_installed' ) ) );
setProgress('done');
};

if ( dismissed ) {
return null;
}

const installPluginRequestStatus = () => {
return progress === 'done' ? (
<div className="done">
<p>{ labels.all_set }</p>

<Button
icon="external"
variant="primary"
href={ hyveDash }
target="_blank"
>
{ labels.hyve.gotodash }
</Button>
</div>
) : (
<p className="om-progress">
<span className="dashicons dashicons-update spin"/>
<span>
{ progress === 'installing' && labels.installing }
{ progress === 'activating' && labels.activating }
&hellip;
</span>
</p>
);
};

const actionButtons = (
<div className="actions">
<Button
variant="primary"
onClick={ installPluginRequest }
>
{ labels.hyve.install }
</Button>

<Button
variant="link"
target="_blank"
href="https://wordpress.org/plugins/hyve-lite/"
>
<span className="dashicons dashicons-external"/>
<span>{ labels.learnmore }</span>
</Button>
</div>
);

return (
<>
<Button
disabled={ progress && progress !== 'done' }
onClick={ dismissNotice }
variant="link"
className="om-notice-dismiss"
>
<span className="dashicons-no-alt dashicons"/>
<span className="screen-reader-text">{ labels.hyve.dismisscta }</span>
</Button>

<div className="content">
<div>
<p>{ title }</p>
<p className="description">{labels.hyve.message}</p>
{ progress ? installPluginRequestStatus() : actionButtons }
</div>
</div>
</>
);
};

const renderHyveNotice = () => {
if ( window.themeisleSDKPromotions.option['hyve-plugins-install']) {
return;
}

const root = document.querySelector( '#ti-hyve-notice' );

if ( ! root ) {
return;
}

createRoot( root ).render(
<HyveNotice
onDismiss={() => {
root.style.display = 'none';
}}
/>
);
};

renderHyveNotice();
1 change: 1 addition & 0 deletions assets/js/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ import './optimole.js';
import './rop.js';
import './neve.js';
import './redirection-for-cf7.js';
import './hyve.js';
6 changes: 6 additions & 0 deletions src/Loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,12 @@ final class Loader {
'gst' => 'Get Started Free',
'message' => 'Add URL redirects, spam protection, execute JavaScript after submissions, and more with the Redirection for CF7 free plugin.',
],
'hyve' => [
'gotodash' => 'Go to Hyve Dashboard',
'install' => 'Install Hyve',
'dismisscta' => 'Dismiss this notice.',
'message' => 'Hyve is an AI-powered chatbot that turns your WordPress content into interactive conversations, helping you efficiently handle user inquiries.',
],
],
'welcome' => [
'ctan' => 'No, thanks.',
Expand Down
97 changes: 90 additions & 7 deletions src/Modules/Promotions.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ class Promotions extends Abstract_Module {
*/
private $option_redirection_cf7 = 'themeisle_sdk_promotions_redirection_cf7_installed';

/**
* Option key for Hyve.
*
* @var string
*/
private $option_hyve = 'themeisle_sdk_promotions_hyve_installed';

/**
* Loaded promotion.
*
Expand Down Expand Up @@ -128,6 +135,7 @@ public function can_load( $product ) {
$promotions_to_load[] = 'woo_plugins';
$promotions_to_load[] = 'neve';
$promotions_to_load[] = 'redirection-cf7';
$promotions_to_load[] = 'hyve';

$promotions_to_load = array_unique( $promotions_to_load );

Expand Down Expand Up @@ -223,6 +231,10 @@ public function register_reference() {
if ( isset( $_GET['neve_reference_key'] ) ) {
update_option( 'neve_reference_key', sanitize_key( $_GET['neve_reference_key'] ) );
}

if ( isset( $_GET['hyve_reference_key'] ) ) {
update_option( 'hyve_reference_key', sanitize_key( $_GET['hyve_reference_key'] ) );
}
}

/**
Expand Down Expand Up @@ -292,6 +304,16 @@ public function register_settings() {
'default' => false,
)
);
register_setting(
'themeisle_sdk_settings',
$this->option_hyve,
array(
'type' => 'boolean',
'sanitize_callback' => 'rest_sanitize_boolean',
'show_in_rest' => true,
'default' => false,
)
);
}

/**
Expand Down Expand Up @@ -345,6 +367,9 @@ private function get_promotions() {
$has_ppom = defined( 'PPOM_VERSION' ) || $this->is_plugin_installed( 'woocommerce-product-addon' );
$has_redirection_cf7 = defined( 'WPCF7_PRO_REDIRECT_PLUGIN_VERSION' ) || $this->is_plugin_installed( 'wpcf7-redirect' );
$had_redirection_cf7_promo = get_option( $this->option_redirection_cf7, false );
$has_hyve = defined( 'HYVE_LITE_VERSION' ) || $this->is_plugin_installed( 'hyve' ) || $this->is_plugin_installed( 'hyve-lite' );
$had_hyve_from_promo = get_option( $this->option_hyve, false );
$has_hyve_conditions = version_compare( get_bloginfo( 'version' ), '6.2', '>=' ) && $this->has_support_page();
$is_min_req_v = version_compare( get_bloginfo( 'version' ), '5.8', '>=' );
$current_theme = wp_get_theme();
$has_neve = $current_theme->template === 'neve' || $current_theme->parent() === 'neve';
Expand Down Expand Up @@ -433,6 +458,12 @@ private function get_promotions() {
'delayed' => true,
],
],
'hyve' => [
'hyve-plugins-install' => [
'env' => ! $has_hyve && ! $had_hyve_from_promo && $has_hyve_conditions,
'screen' => 'plugin-install',
],
],
];

foreach ( $all as $slug => $data ) {
Expand Down Expand Up @@ -495,13 +526,14 @@ private function get_last_dismiss_time() {
private function filter_by_screen_and_merge() {
$current_screen = get_current_screen();

$is_elementor = isset( $_GET['action'] ) && $_GET['action'] === 'elementor';
$is_media = isset( $current_screen->id ) && $current_screen->id === 'upload';
$is_posts = isset( $current_screen->id ) && $current_screen->id === 'edit-post';
$is_editor = method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor();
$is_theme_install = isset( $current_screen->id ) && ( $current_screen->id === 'theme-install' );
$is_product = isset( $current_screen->id ) && $current_screen->id === 'product';
$is_cf7_install = isset( $current_screen->id ) && function_exists( 'str_contains' ) ? str_contains( $current_screen->id, 'page_wpcf7' ) : false;
$is_elementor = isset( $_GET['action'] ) && $_GET['action'] === 'elementor';
$is_media = isset( $current_screen->id ) && $current_screen->id === 'upload';
$is_posts = isset( $current_screen->id ) && $current_screen->id === 'edit-post';
$is_editor = method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor();
$is_theme_install = isset( $current_screen->id ) && ( $current_screen->id === 'theme-install' );
$is_plugin_install = isset( $current_screen->id ) && ( $current_screen->id === 'plugin-install' );
$is_product = isset( $current_screen->id ) && $current_screen->id === 'product';
$is_cf7_install = isset( $current_screen->id ) && function_exists( 'str_contains' ) ? str_contains( $current_screen->id, 'page_wpcf7' ) : false;

$return = [];

Expand Down Expand Up @@ -567,6 +599,11 @@ private function filter_by_screen_and_merge() {
unset( $this->promotions[ $slug ][ $key ] );
}
break;
case 'plugin-install':
if ( ! $is_plugin_install ) {
unset( $this->promotions[ $slug ][ $key ] );
}
break;
}
}

Expand Down Expand Up @@ -607,6 +644,9 @@ private function load_promotion( $slug ) {
if ( $this->get_upsells_dismiss_time( 'redirection-cf7' ) === false ) {
add_action( 'admin_notices', [ $this, 'render_redirection_cf7_notice' ] );
}
if ( $this->get_upsells_dismiss_time( 'hyve-plugins-install' ) === false ) {
add_action( 'admin_notices', [ $this, 'render_hyve_notice' ] );
}

$this->load_woo_promos();

Expand Down Expand Up @@ -658,6 +698,10 @@ private function load_promotion( $slug ) {
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue' ] );
add_action( 'admin_notices', [ $this, 'render_redirection_cf7_notice' ] );
break;
case 'hyve-plugins-install':
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue' ] );
add_action( 'admin_notices', [ $this, 'render_hyve_notice' ] );
break;
}
}

Expand Down Expand Up @@ -714,6 +758,8 @@ public function enqueue() {
'redirectionCF7MoreUrl' => tsdk_utmify( 'https://docs.themeisle.com/collection/2014-redirection-for-contact-form-7', 'redirection-for-contact-form-7', 'plugin-install' ),
'rfCF7ActivationUrl' => $this->get_plugin_activation_link( 'wpcf7-redirect' ),
'cf7Dash' => esc_url( add_query_arg( [ 'page' => 'wpcf7-new' ], admin_url( 'admin.php' ) ) ),
'hyveActivationUrl' => $this->get_plugin_activation_link( 'hyve-lite' ),
'hyveDash' => esc_url( add_query_arg( [ 'page' => 'hyve' ], admin_url( 'admin.php' ) ) ),
'nevePreviewURL' => esc_url( add_query_arg( [ 'theme' => 'neve' ], admin_url( 'theme-install.php' ) ) ),
'neveAction' => $neve_action,
'activateNeveURL' => esc_url(
Expand Down Expand Up @@ -752,6 +798,13 @@ public function render_neve_themes_notice() {
echo '<div id="ti-neve-notice" class="notice notice-info ti-sdk-om-notice"></div>';
}

/**
* Render Hyve notice.
*/
public function render_hyve_notice() {
echo '<div id="ti-hyve-notice" class="notice notice-info ti-sdk-om-notice"></div>';
}

/**
* Render Redirection for CF7 notice.
*/
Expand Down Expand Up @@ -1168,4 +1221,34 @@ public function dismiss_promotion() {
wp_send_json( $response );
wp_die();
}

/**
* Check if the user has a support page.
*/
public function has_support_page() {
$transient_name = 'tisdk_has_support_page';
$has_support = get_transient( $transient_name );

if ( false === $has_support ) {
global $wpdb;

// We use %i escape identifier that was added in WP 6.2.0, hence need to ignore PHPCS warning.
// We only show this notice to users on higher version as that is the minimum for Hyve as well.
$query = $wpdb->get_var( //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$wpdb->prepare( // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
'SELECT ID FROM %i WHERE post_type = %s AND post_status = %s AND post_title LIKE %s LIMIT 1', // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnsupportedPlaceholder
$wpdb->posts,
'page',
'publish',
'%support%'
)
);

$has_support = $query ? 'yes' : 'no';

set_transient( $transient_name, $has_support, 7 * DAY_IN_SECONDS );
}

return 'yes' === $has_support;
}
}

0 comments on commit 47348ce

Please sign in to comment.