Files
2026-04-28 15:13:50 +02:00

395 lines
13 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Gutenberg Blocks registration class.
*
* @since 1.9.10
*
* @package OMAPI
* @author Thomas Griffin
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Gutenberg Blocks registration class.
*
* @since 1.9.10
*/
class OMAPI_Blocks {
/**
* Holds the class object.
*
* @since 1.9.10
*
* @var object
*/
public static $instance;
/**
* Path to the file.
*
* @since 1.9.10
*
* @var string
*/
public $file = __FILE__;
/**
* Holds the base class object.
*
* @since 1.9.10
*
* @var object
*/
public $base;
/**
* The data to be localized for JS.
*
* @since 2.2.0
*
* @var array
*/
protected $data_for_js = array();
/**
* The campaign options list array.
*
* @var null|array
*/
protected static $campaigns_list = null;
/**
* Primary class constructor.
*
* @since 1.9.10
*/
public function __construct() {
// Set our object.
$this->set();
if ( function_exists( 'register_block_type' ) ) {
// Register our blocks.
$this->register_blocks();
add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) );
// Register the global post campaign switch meta.
register_meta(
'post',
'om_disable_all_campaigns',
array(
'show_in_rest' => true,
'single' => true,
'type' => 'boolean',
)
);
}
}
/**
* Sets our object instance and base class instance.
*
* @since 1.9.10
*/
public function set() {
self::$instance = $this;
$this->base = OMAPI::get_instance();
}
/**
* Register OptinMonster Gutenberg blocks on the backend.
*
* @since 1.9.10
*/
public function register_blocks() {
$use_blocks_json = version_compare( $GLOBALS['wp_version'], '5.8', '>=' );
$block_type = plugin_dir_path( OMAPI_FILE ) . 'assets/js/';
$args = array(
'render_callback' => array( $this, 'get_output' ),
);
if ( ! $use_blocks_json ) {
$block_type = 'optinmonster/campaign-selector';
$args['attributes'] = array(
'slug' => array(
'type' => 'string',
),
'followrules' => array(
'type' => 'boolean',
),
);
}
register_block_type( $block_type, $args );
}
/**
* Load OptinMonster Gutenberg block scripts.
*
* @since 1.9.10
*/
public function enqueue_block_editor_assets() {
global $pagenow;
$version = $this->base->asset_version();
$css_handle = $this->base->plugin_slug . '-blocks-admin';
wp_enqueue_style( $css_handle, $this->base->url . 'assets/dist/css/blocks-admin.min.css', array(), $version );
if ( function_exists( 'wp_add_inline_style' ) ) {
$data = get_post_type()
? get_post_type_object( get_post_type() )
: array();
$css = $this->base->get_min_css_view_contents( 'disable-warning-css.php', (object) $data );
wp_add_inline_style( $css_handle, $css );
}
$campaign_selector_handle = $this->base->plugin_slug . '-gutenberg-campaign-selector';
wp_enqueue_script(
$campaign_selector_handle,
$this->base->url . 'assets/dist/js/campaign-selector.min.js',
array( 'wp-blocks', 'wp-i18n', 'wp-element' ),
$version,
true
);
OMAPI_Utils::add_inline_script( $campaign_selector_handle, 'OMAPI', $this->get_data_for_js() );
$is_widgets_page = 'widgets.php' === $pagenow;
// Prevent enqueueing sidebar settings on widgets screen...
if ( ! $is_widgets_page && ! is_customize_preview() ) {
wp_enqueue_script(
$this->base->plugin_slug . '-gutenberg-sidebar-settings',
$this->base->url . 'assets/dist/js/om-settings.min.js',
array( $campaign_selector_handle, 'wp-plugins', 'wp-edit-post', 'wp-element' ),
$version
);
}
if ( version_compare( $GLOBALS['wp_version'], '5.3', '>=' ) ) {
wp_enqueue_script(
$this->base->plugin_slug . '-gutenberg-format-button',
$this->base->url . 'assets/dist/js/om-format.min.js',
array(
$campaign_selector_handle,
'wp-rich-text',
'wp-element',
$is_widgets_page && version_compare( $GLOBALS['wp_version'], '5.8.0', '>=' )
? 'wp-edit-widgets'
: 'wp-editor',
),
$version
);
}
}
/**
* Get OptinMonster data for Gutenberg JS.
*
* @since 2.2.0
*
* @param string $key The js data to get, by key.
*
* @return array Array of data for JS.
*/
public function get_data_for_js( $key = null ) {
if ( empty( $this->data_for_js ) ) {
// For translation of strings.
$i18n = array(
'title' => esc_html__( 'OptinMonster', 'optin-monster-api' ),
'description' => esc_html__( 'Select and display one of your OptinMonster inline campaigns.', 'optin-monster-api' ),
'campaign_select' => esc_html__( 'Select Campaign...', 'optin-monster-api' ),
'campaign_select_display' => esc_html__( 'Select and display your email marketing call-to-action campaigns from OptinMonster', 'optin-monster-api' ),
'create_new_popup' => esc_html__( 'Create New Popup Campaign', 'optin-monster-api' ),
'create_new_inline' => esc_html__( 'Create New Inline Campaign', 'optin-monster-api' ),
'block_settings' => esc_html__( 'OptinMonster Block Settings', 'optin-monster-api' ),
'settings' => esc_html__( 'OptinMonster Settings', 'optin-monster-api' ),
'campaign_selected' => esc_html__( 'Campaign', 'optin-monster-api' ),
'followrules_label' => esc_html__( 'Use Output Settings', 'optin-monster-api' ),
/* translators: %s - Output Settings (linked).*/
'followrules_help' => esc_html__( 'Ensure this campaign follows any conditions you\'ve selected in its %s', 'optin-monster-api' ),
'output_settings' => esc_html__( 'Output Settings', 'optin-monster-api' ),
'no_sites' => esc_html__( 'Please create a free account or connect an existing account to use an OptinMonster block.', 'optin-monster-api' ),
'no_sites_button_create_account' => esc_html__( 'Create a Free Account', 'optin-monster-api' ),
'no_sites_button_connect_account' => esc_html__( 'Connect an Existing Account', 'optin-monster-api' ),
'no_inline_campaigns' => esc_html__( 'You dont have any inline campaigns yet!', 'optin-monster-api' ),
'no_campaigns_help' => esc_html__( 'Create an inline campaign to display in your posts and pages.', 'optin-monster-api' ),
'create_inline_campaign' => esc_html__( 'Create Your First Inline Campaign', 'optin-monster-api' ),
'create_popup_campaign' => esc_html__( 'Create Your First Popup', 'optin-monster-api' ),
'no_campaigns_button_help' => esc_html__( 'Learn how to create your first campaign', 'optin-monster-api' ),
'found_error' => esc_html__( 'An error was encountered', 'optin-monster-api' ),
'disable_all' => esc_html__( 'Disable all OptinMonster campaigns.', 'optin-monster-api' ),
'view_all' => esc_html__( 'View All Campaigns', 'optin-monster-api' ),
'not_connected' => esc_html__( 'You Have Not Connected with OptinMonster', 'optin-monster-api' ),
'no_campaigns_yet' => esc_html__( 'You dont have any campaigns created yet.', 'optin-monster-api' ),
'update_selected_popup' => esc_html__( 'Update Selected OptinMonster Campaign', 'optin-monster-api' ),
'open_popup' => esc_html__( 'Open an OptinMonster Popup', 'optin-monster-api' ),
'remove_popup' => esc_html__( 'Remove Campaign Link', 'optin-monster-api' ),
'upgrade_monsterlink' => esc_html__( 'Unlock access to the OptinMonster click-to-load feature called MonsterLinks by upgrading your subscription.', 'optin-monster-api' ),
'upgrade' => esc_html__( 'Upgrade Now', 'optin-monster-api' ),
);
$i18n['description'] = html_entity_decode( $i18n['description'], ENT_COMPAT, 'UTF-8' );
$campaigns = $this->get_campaign_options();
$site_ids = $this->base->get_site_ids();
$post = get_post();
$this->data_for_js = array(
'logoUrl' => $this->base->url . 'assets/css/images/icons/archie-icon.svg',
'i18n' => $i18n,
'campaigns' => array(
'inline' => ! empty( $campaigns['inline'] ) ? $campaigns['inline'] : array(),
'other' => ! empty( $campaigns['other'] ) ? $campaigns['other'] : array(),
),
'site_ids' => ! empty( $site_ids ) ? $site_ids : array(),
'post' => $post,
'omEnv' => defined( 'OPTINMONSTER_ENV' ) ? OPTINMONSTER_ENV : '',
'canMonsterlink' => $this->base->has_rule_type( 'monster-link' ),
'templatesUri' => OMAPI_Urls::templates(),
'playbooksUri' => OMAPI_Urls::playbooks(),
'campaignsUri' => OMAPI_Urls::campaigns(),
'settingsUri' => OMAPI_Urls::settings(),
'wizardUri' => OMAPI_Urls::wizard(),
'upgradeUri' => OMAPI_Urls::upgrade( 'gutenberg', '--FEATURE--' ),
'apiUrl' => esc_url_raw( OPTINMONSTER_APIJS_URL ),
'omUserId' => $this->base->get_option( 'accountUserId' ),
'outputSettingsUrl' => OMAPI_Urls::campaign_output_settings( '%s' ),
'editUrl' => OMAPI_Urls::om_app(
'campaigns/--CAMPAIGN_SLUG--/edit/',
rawurlencode( OMAPI_Urls::campaign_output_settings( '--CAMPAIGN_SLUG--' ) )
),
'monsterlink' => esc_url_raw( OPTINMONSTER_SHAREABLE_LINK ) . '/c/',
'wpVersion' => $GLOBALS['wp_version'],
'customFieldsSupported' => post_type_supports( get_post_type( $post ), 'custom-fields' ),
'pluginUrl' => esc_url_raw( plugin_dir_url( dirname( __FILE__ ) ) ),
);
}
if ( $key ) {
return isset( $this->data_for_js[ $key ] ) ? $this->data_for_js[ $key ] : null;
}
return $this->data_for_js;
}
/**
* Does the user have any associated OM sites registered?
*
* @since 2.2.0
*
* @return boolean
*/
public function has_sites() {
$site_ids = $this->base->get_site_ids();
return ! empty( $site_ids );
}
/**
* Get campaign options.
*
* @since 2.2.0
*
* @param boolean $titles_only Whether to include titles only, or separate data as array.
*
* @return array Array of campaign options.
*/
public function get_campaign_options( $titles_only = false ) {
if ( null === self::$campaigns_list ) {
$campaigns_list = array(
'inline' => array(),
'other' => array(),
);
if ( $this->has_sites() ) {
$campaigns = $this->base->get_campaigns();
if ( ! empty( $campaigns ) ) {
foreach ( $campaigns as $campaign ) {
$title = mb_strlen( $campaign->post_title, 'UTF-8' ) > 100
? mb_substr( $campaign->post_title, 0, 97, 'UTF-8' ) . '...'
: $campaign->post_title;
$title .= ' (' . $campaign->post_name . ')';
$type = 'inline' === $campaign->campaign_type ? 'inline' : 'other';
$campaigns_list[ $type ][ $campaign->post_name ] = array(
'title' => $title,
'pending' => empty( $campaign->enabled ),
);
}
}
}
self::$campaigns_list = $campaigns_list;
}
if ( $titles_only && ! empty( self::$campaigns_list ) ) {
$list = array();
foreach ( self::$campaigns_list as $type => $type_list ) {
foreach ( $type_list as $campaign_name => $args ) {
$list[ $type ][ $campaign_name ] = $args['title'] . ( $args['pending'] ? ' [Pending]' : '' );
}
}
return $list;
}
return self::$campaigns_list;
}
/**
* Get form HTML to display in a OptinMonster Gutenberg block.
*
* @param array $atts Attributes passed by OptinMonster Gutenberg block.
*
* @since 1.9.10
*
* @return string
*/
public function get_output( $atts ) {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$context = ! empty( $_REQUEST['context'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['context'] ) ) : '';
$is_rest = defined( 'REST_REQUEST' ) && REST_REQUEST;
$is_gutes = $is_rest && 'edit' === $context;
// Our Guten-block handles the embed output manually.
if ( $is_gutes ) {
return;
}
// Unslash and sanitize the shortcode attributes.
$atts = array_map( 'sanitize_text_field', wp_unslash( $atts ) );
// Gutenberg block shortcodes default to following the rules.
// See assets/js/campaign-selector.js, attributes.followrules.
if ( ! isset( $atts['followrules'] ) ) {
$atts['followrules'] = true;
}
$atts['followrules'] = wp_validate_boolean( $atts['followrules'] );
$output = $this->base->shortcode->shortcode( $atts );
if (
! empty( $output )
&& ! wp_script_is( $this->base->plugin_slug . '-api-script', 'enqueued' )
) {
// Need to enqueue the base api script.
$this->base->output->api_script();
}
// Just return the shortcode output to the frontend.
return $output;
}
}