first commit

This commit is contained in:
Roman Pyrih
2026-03-10 09:50:10 +01:00
commit 64c4a90405
7289 changed files with 2645777 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
<?php
namespace Elementor\Modules\Promotions\AdminMenuItems;
use Elementor\Core\Utils\Promotions\Filtered_Promotions_Manager;
use Elementor\Modules\Promotions\AdminMenuItems\Interfaces\Promotion_Menu_Item;
use Elementor\Settings;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
abstract class Base_Promotion_Item implements Promotion_Menu_Item {
public function get_name(): string {
return 'base_promotion';
}
public function is_visible(): bool {
return true;
}
public function get_parent_slug(): string {
return Settings::PAGE_ID;
}
public function get_capability(): string {
return 'manage_options';
}
public function get_cta_text() {
return esc_html__( 'Upgrade Now', 'elementor' );
}
public function get_image_url() {
return ELEMENTOR_ASSETS_URL . 'images/go-pro-wp-dashboard.svg';
}
public function get_promotion_description() {
return '';
}
public function render() {
$config = [
'title' => $this->get_promotion_title(),
'description' => $this->get_promotion_description(),
'image' => $this->get_image_url(),
'upgrade_text' => $this->get_cta_text(),
'upgrade_url' => $this->get_cta_url(),
];
$config = Filtered_Promotions_Manager::get_filtered_promotion_data( $config, 'elementor/' . $this->get_name() . '/custom_promotion', 'upgrade_url' );
$description = $config['description'] ?? $this->get_promotion_description() ?? '';
?>
<div class="wrap">
<div class="elementor-blank_state">
<img src="<?php echo esc_url( $config['image'] ?? $this->get_image_url() ); ?>" loading="lazy" />
<h3><?php echo esc_html( $config['title'] ?? $this->get_promotion_title() ); ?></h3>
<?php if ( $description ) : ?>
<p><?php echo esc_html( $description ); ?></p>
<?php endif; ?>
<a class="elementor-button go-pro" href="<?php echo esc_url( $config['upgrade_url'] ?? $this->get_cta_url() ); ?>">
<?php echo esc_html( $config['upgrade_text'] ?? $this->get_cta_text() ); ?>
</a>
</div>
</div>
<?php
}
}

View File

@@ -0,0 +1,110 @@
<?php
namespace Elementor\Modules\Promotions\AdminMenuItems;
use Elementor\Core\Admin\Menu\Interfaces\Admin_Menu_Item_With_Page;
use Elementor\Core\Utils\Promotions\Filtered_Promotions_Manager;
use Elementor\Settings;
use Elementor\Utils;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
abstract class Base_Promotion_Template implements Admin_Menu_Item_With_Page {
abstract protected function get_promotion_title(): string;
abstract protected function get_cta_url(): string;
abstract protected function get_content_lines(): array;
abstract protected function get_video_url(): string;
public function is_visible(): bool {
return true;
}
public function get_parent_slug(): string {
return Settings::PAGE_ID;
}
public function get_capability(): string {
return 'manage_options';
}
protected function get_cta_text() {
return esc_html__( 'Upgrade Now', 'elementor' );
}
/**
* Should the promotion have a side note.
*
* @return string
*/
protected function get_side_note(): string {
return '';
}
private function get_lines() {
ob_start();
if ( ! empty( $this->get_content_lines() ) ) {
?>
<ul>
<?php foreach ( $this->get_content_lines() as $item ) { ?>
<li><?php Utils::print_unescaped_internal_string( $item ); ?></li>
<?php } ?>
</ul>
<?php
}
return ob_get_clean();
}
public function render() {
$promotion_data = $this->get_promotion_data();
?>
<div class="e-feature-promotion">
<div class="e-feature-promotion_data">
<h3><?php Utils::print_unescaped_internal_string( $promotion_data['promotion_title'] ); ?></h3>
<?php Utils::print_unescaped_internal_string( $promotion_data['lines'] ); ?>
<a class="elementor-button go-pro" href="<?php echo esc_url( $promotion_data['cta_url'] ); ?>" target="_blank">
<?php Utils::print_unescaped_internal_string( $promotion_data['cta_text'] ); ?>
</a>
<?php if ( ! empty( $promotion_data['side_note'] ) ) { ?>
<div class="side-note">
<p><?php Utils::print_unescaped_internal_string( $promotion_data['side_note'] ); ?></p>
</div>
<?php } ?>
</div>
<iframe class="e-feature-promotion_iframe" src="<?php Utils::print_unescaped_internal_string( $promotion_data['video_url'] ); ?>&rel=0" title="Elementor" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div>
<?php
}
/**
* @return array|null
*/
private function get_promotion_data(): ?array {
return Filtered_Promotions_Manager::get_filtered_promotion_data( $this->build_promotion_data_array(), 'elementor/' . $this->get_name() . '/custom_promotion', 'cta_url' );
}
/**
* @return array
*/
private function build_promotion_data_array(): array {
return [
'promotion_title' => $this->get_promotion_title(),
'cta_url' => $this->get_cta_url(),
'cta_text' => $this->get_cta_text(),
'video_url' => $this->get_video_url(),
'lines' => $this->get_lines(),
'side_note' => $this->get_side_note(),
];
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Elementor\Modules\Promotions\AdminMenuItems;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Custom_Code_Promotion_Item extends Base_Promotion_Template {
public function get_name() {
return 'custom_code';
}
public function get_label() {
return esc_html__( 'Custom Code', 'elementor' );
}
public function get_page_title() {
return esc_html__( 'Custom Code', 'elementor' );
}
protected function get_promotion_title(): string {
return esc_html__( 'Enjoy Creative Freedom with Custom Code', 'elementor' );
}
protected function get_content_lines(): array {
return [
esc_html__( 'Add Custom Code snippets anywhere on your website, including the header or footer to measure your pages performance*', 'elementor' ),
esc_html__( 'Use Custom Code to create sophisticated custom interactions to engage visitors', 'elementor' ),
esc_html__( 'Leverage Elementor AI to instantly generate Custom Code for Elementor', 'elementor' ),
];
}
protected function get_side_note(): string {
return esc_html__( '* Requires an Advanced subscription or higher', 'elementor' );
}
protected function get_cta_url(): string {
return 'https://go.elementor.com/go-pro-custom-code/';
}
protected function get_video_url(): string {
return 'https://www.youtube-nocookie.com/embed/IOovQd1hJUg?si=xeBJ_mRZxRH1l5O6';
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace Elementor\Modules\Promotions\AdminMenuItems;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Custom_Fonts_Promotion_Item extends Base_Promotion_Template {
public function get_name() {
return 'custom_fonts';
}
public function get_label() {
return esc_html__( 'Custom Fonts', 'elementor' );
}
public function get_page_title() {
return esc_html__( 'Custom Fonts', 'elementor' );
}
protected function get_promotion_title(): string {
return esc_html__( 'Stay on brand with a Custom Font', 'elementor' );
}
protected function get_content_lines(): array {
return [
esc_html__( 'Upload any font to keep your website true to your brand', 'elementor' ),
sprintf(
/* translators: %s: br */
esc_html__( 'Remain GDPR compliant with Custom Fonts that let you disable %s Google Fonts from your website', 'elementor' ),
'<br />'
),
];
}
protected function get_cta_url(): string {
return 'https://go.elementor.com/go-pro-custom-fonts/';
}
protected function get_video_url(): string {
return 'https://www.youtube-nocookie.com/embed/j_guJkm28eY?si=cdd2TInwuGDTtCGD';
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace Elementor\Modules\Promotions\AdminMenuItems;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Custom_Icons_Promotion_Item extends Base_Promotion_Template {
public function get_name() {
return 'custom_icons';
}
public function get_label() {
return esc_html__( 'Custom Icons', 'elementor' );
}
public function get_page_title() {
return esc_html__( 'Custom Icons', 'elementor' );
}
protected function get_promotion_title(): string {
return sprintf(
/* translators: %s: `<br>` tag. */
esc_html__( 'Enjoy creative freedom %s with Custom Icons', 'elementor' ),
'<br />'
);
}
protected function get_content_lines(): array {
return [
sprintf(
/* translators: %s: `<br>` tag. */
esc_html__( 'Expand your icon library beyond FontAwesome and add icon %s libraries of your choice', 'elementor' ),
'<br />'
),
esc_html__( 'Add any icon, anywhere on your website', 'elementor' ),
];
}
protected function get_cta_url(): string {
return 'https://go.elementor.com/go-pro-custom-icons/';
}
protected function get_video_url(): string {
return 'https://www.youtube-nocookie.com/embed/PsowinxDWfM?si=SV9Z3TLz3_XEy5C6';
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Elementor\Modules\Promotions\AdminMenuItems;
use Elementor\Core\Admin\EditorOneMenu\Interfaces\Menu_Item_Interface;
use Elementor\Modules\EditorOne\Classes\Menu_Config;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class Editor_One_Custom_Code_Menu extends Custom_Code_Promotion_Item implements Menu_Item_Interface {
public function get_position(): int {
return 40;
}
public function get_slug(): string {
return 'elementor_custom_code';
}
public function get_parent_slug(): string {
return 'elementor_custom_code';
}
public function get_label(): string {
return esc_html__( 'Code', 'elementor' );
}
public function get_group_id(): string {
return Menu_Config::CUSTOM_ELEMENTS_GROUP_ID;
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Elementor\Modules\Promotions\AdminMenuItems;
use Elementor\Core\Admin\EditorOneMenu\Interfaces\Menu_Item_Third_Level_Interface;
use Elementor\Modules\EditorOne\Classes\Menu_Config;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class Editor_One_Custom_Elements_Menu implements Menu_Item_Third_Level_Interface {
public function get_capability(): string {
return 'manage_options';
}
public function get_parent_slug(): string {
return Menu_Config::ELEMENTOR_MENU_SLUG;
}
public function is_visible(): bool {
return true;
}
public function get_label(): string {
return esc_html__( 'Custom Elements', 'elementor' );
}
public function get_position(): int {
return 70;
}
public function get_slug(): string {
return 'elementor-custom-elements';
}
public function get_icon(): string {
return 'adjustments';
}
public function get_group_id(): string {
return Menu_Config::CUSTOM_ELEMENTS_GROUP_ID;
}
public function has_children(): bool {
return true;
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace Elementor\Modules\Promotions\AdminMenuItems;
use Elementor\Core\Admin\EditorOneMenu\Interfaces\Menu_Item_Interface;
use Elementor\Modules\EditorOne\Classes\Menu_Config;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class Editor_One_Fonts_Menu extends Custom_Fonts_Promotion_Item implements Menu_Item_Interface {
public function get_position(): int {
return 10;
}
public function get_slug(): string {
return 'elementor_custom_fonts';
}
public function get_parent_slug(): string {
return Menu_Config::ELEMENTOR_MENU_SLUG;
}
public function get_label(): string {
return esc_html__( 'Fonts', 'elementor' );
}
public function get_group_id(): string {
return Menu_Config::CUSTOM_ELEMENTS_GROUP_ID;
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace Elementor\Modules\Promotions\AdminMenuItems;
use Elementor\Core\Admin\EditorOneMenu\Interfaces\Menu_Item_Interface;
use Elementor\Modules\EditorOne\Classes\Menu_Config;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class Editor_One_Icons_Menu extends Custom_Icons_Promotion_Item implements Menu_Item_Interface {
public function get_position(): int {
return 20;
}
public function get_slug(): string {
return 'elementor_custom_icons';
}
public function get_parent_slug(): string {
return Menu_Config::ELEMENTOR_MENU_SLUG;
}
public function get_label(): string {
return esc_html__( 'Icons', 'elementor' );
}
public function get_group_id(): string {
return Menu_Config::CUSTOM_ELEMENTS_GROUP_ID;
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace Elementor\Modules\Promotions\AdminMenuItems;
use Elementor\Core\Admin\EditorOneMenu\Interfaces\Menu_Item_Interface;
use Elementor\Modules\EditorOne\Classes\Menu_Config;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class Editor_One_Popups_Menu extends Popups_Promotion_Item implements Menu_Item_Interface {
public function get_position(): int {
return 50;
}
public function get_slug(): string {
return 'popup_templates';
}
public function get_parent_slug(): string {
return Menu_Config::ELEMENTOR_MENU_SLUG;
}
public function get_label(): string {
return esc_html__( 'Popups', 'elementor' );
}
public function get_group_id(): string {
return Menu_Config::TEMPLATES_GROUP_ID;
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Elementor\Modules\Promotions\AdminMenuItems;
use Elementor\Core\Admin\EditorOneMenu\Interfaces\Menu_Item_Third_Level_Interface;
use Elementor\Modules\EditorOne\Classes\Menu_Config;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class Editor_One_Submissions_Menu extends Form_Submissions_Promotion_Item implements Menu_Item_Third_Level_Interface {
public function get_position(): int {
return 50;
}
public function get_slug(): string {
return 'e-form-submissions';
}
public function get_parent_slug(): string {
return Menu_Config::ELEMENTOR_MENU_SLUG;
}
public function get_label(): string {
return esc_html__( 'Submissions', 'elementor' );
}
public function get_group_id(): string {
return Menu_Config::EDITOR_GROUP_ID;
}
public function get_icon(): string {
return 'send';
}
public function has_children(): bool {
return false;
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace Elementor\Modules\Promotions\AdminMenuItems;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Form_Submissions_Promotion_Item extends Base_Promotion_Template {
public function get_name() {
return 'submissions';
}
public function get_label() {
return esc_html__( 'Submissions', 'elementor' );
}
public function get_page_title() {
return esc_html__( 'Submissions', 'elementor' );
}
public function get_promotion_title(): string {
return sprintf(
/* translators: %s: `<br>` tag. */
esc_html__( 'Create Forms and Collect Leads %s with Elementor Pro', 'elementor' ),
'<br>'
);
}
protected function get_content_lines(): array {
return [
esc_html__( 'Create single or multi-step forms to engage and convert visitors', 'elementor' ),
esc_html__( 'Use any field to collect the information you need', 'elementor' ),
esc_html__( 'Integrate your favorite marketing software*', 'elementor' ),
esc_html__( 'Collect lead submissions directly within your WordPress Admin to manage, analyze and perform bulk actions on the submitted lead*', 'elementor' ),
];
}
protected function get_cta_url(): string {
return 'https://go.elementor.com/go-pro-submissions/';
}
protected function get_video_url(): string {
return 'https://www.youtube-nocookie.com/embed/LNfnwba9C-8?si=JLHk3UAexnvTfU1a';
}
protected function get_side_note(): string {
return esc_html__( '* Requires an Advanced subscription or higher', 'elementor' );
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace Elementor\Modules\Promotions\AdminMenuItems;
use Elementor\Core\Admin\Menu\Interfaces\Admin_Menu_Item_With_Page;
use Elementor\Core\Utils\Promotions\Filtered_Promotions_Manager;
use Elementor\Settings;
use Elementor\Utils;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Go_Pro_Promotion_Item implements Admin_Menu_Item_With_Page {
const URL = 'https://go.elementor.com/pro-admin-menu/';
public function get_name() {
return 'admin_menu_promo';
}
public function is_visible() {
return true;
}
public function get_parent_slug() {
return Settings::PAGE_ID;
}
public function get_label() {
$upgrade_text = esc_html__( 'Upgrade', 'elementor' );
if ( Utils::is_sale_time() ) {
$upgrade_text = esc_html__( 'Upgrade Sale Now', 'elementor' );
}
return apply_filters( 'elementor/admin_menu/custom_promotion', [ 'upgrade_text' => $upgrade_text ] )['upgrade_text'] ?? $upgrade_text;
}
public function get_page_title() {
return '';
}
public function get_capability() {
return 'manage_options';
}
public static function get_url() {
$url = self::URL;
$filtered_url = apply_filters( 'elementor/admin_menu/custom_promotion', [ 'upgrade_url' => $url ] )['upgrade_url'] ?? '';
$promotion_data = Filtered_Promotions_Manager::get_filtered_promotion_data( [ 'upgrade_url' => $filtered_url ], 'elementor/admin_menu/custom_promotion', 'upgrade_url' );
return $promotion_data ['upgrade_url'];
}
public function render() {
// Redirects from the module on `admin_init`.
die;
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace Elementor\Modules\Promotions\AdminMenuItems\Interfaces;
use Elementor\Core\Admin\Menu\Interfaces\Admin_Menu_Item_With_Page;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
interface Promotion_Menu_Item extends Admin_Menu_Item_With_Page {
public function get_image_url();
public function get_promotion_title();
public function get_promotion_description();
public function get_cta_text();
public function get_cta_url();
}

View File

@@ -0,0 +1,63 @@
<?php
namespace Elementor\Modules\Promotions\AdminMenuItems;
use Elementor\Core\Utils\Promotions\Filtered_Promotions_Manager;
use Elementor\TemplateLibrary\Source_Local;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Popups_Promotion_Item extends Base_Promotion_Item {
private array $promotion_data;
public function __construct() {
$this->promotion_data = [
'title' => esc_html__( 'Get Popup Builder', 'elementor' ),
'content' => esc_html__(
'The Popup Builder lets you take advantage of all the amazing features in Elementor, so you can build beautiful & highly converting popups. Get Elementor Pro and start designing your popups today.',
'elementor'
),
'action_button' => [
'text' => esc_html__( 'Upgrade Now', 'elementor' ),
'url' => 'https://go.elementor.com/go-pro-popup-builder/',
],
];
$this->promotion_data = Filtered_Promotions_Manager::get_filtered_promotion_data( $this->promotion_data, 'elementor/templates/popup', 'action_button', 'url' );
}
public function get_parent_slug(): string {
return Source_Local::ADMIN_MENU_SLUG;
}
public function get_name(): string {
return 'popups';
}
public function get_label(): string {
return esc_html__( 'Popups', 'elementor' );
}
public function get_page_title() {
return esc_html__( 'Popups', 'elementor' );
}
public function get_promotion_title() {
return $this->promotion_data['title'];
}
public function get_promotion_description() {
return $this->promotion_data['content'];
}
public function get_cta_url() {
return $this->promotion_data['action_button']['url'];
}
public function get_cta_text() {
return $this->promotion_data['action_button']['text'];
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Elementor\Modules\Promotions\Controls;
use Elementor\Modules\AtomicWidgets\Controls\Base\Atomic_Control_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Atomic_Promotion_Control extends Atomic_Control_Base {
public static function make( string $type ): self {
return new self( $type );
}
public function get_type(): string {
return $this->get_bind();
}
public function get_props(): array {
return [];
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Elementor\Modules\Promotions\Controls;
use Elementor\Base_Data_Control;
class Promotion_Control extends Base_Data_Control {
const TYPE = 'promotion_control';
public function get_type() {
return static::TYPE;
}
public function content_template() {
?>
<div data-promotion="{{{ data.name }}}" class="elementor-control-type-switcher elementor-label-inline e-control-promotion__wrapper">
<div class="elementor-control-content">
<div class="elementor-control-field">
<# if ( data.label ) {#>
<label for="<?php $this->print_control_uid(); ?>" class="elementor-control-title">{{{ data.label }}}</label>
<# } #>
<span class="e-control-promotion__lock-wrapper">
<i class="eicon-lock"></i>
</span>
<div class="elementor-control-input-wrapper">
<label class="elementor-switch elementor-control-unit-2 e-control-promotion-switch">
<input type="checkbox" class="elementor-switch-input" disabled>
<span class="elementor-switch-label" data-off="Off"></span>
<span class="elementor-switch-handle"></span>
</label>
</div>
<div class="e-promotion-react-wrapper" data-promotion="{{{ data.name }}}"></div>
</div>
</div>
</div>
<?php
}
}

View File

@@ -0,0 +1,327 @@
<?php
namespace Elementor\Modules\Promotions;
use Elementor\Api;
use Elementor\Controls_Manager;
use Elementor\Core\Admin\Menu\Admin_Menu_Manager;
use Elementor\Core\Base\Module as Base_Module;
use Elementor\Modules\Promotions\AdminMenuItems\Custom_Code_Promotion_Item;
use Elementor\Modules\Promotions\AdminMenuItems\Custom_Fonts_Promotion_Item;
use Elementor\Modules\Promotions\AdminMenuItems\Custom_Icons_Promotion_Item;
use Elementor\Modules\Promotions\AdminMenuItems\Editor_One_Custom_Code_Menu;
use Elementor\Modules\Promotions\AdminMenuItems\Editor_One_Custom_Elements_Menu;
use Elementor\Modules\Promotions\AdminMenuItems\Editor_One_Fonts_Menu;
use Elementor\Modules\Promotions\AdminMenuItems\Editor_One_Icons_Menu;
use Elementor\Modules\Promotions\AdminMenuItems\Editor_One_Popups_Menu;
use Elementor\Modules\Promotions\AdminMenuItems\Editor_One_Submissions_Menu;
use Elementor\Modules\Promotions\AdminMenuItems\Form_Submissions_Promotion_Item;
use Elementor\Modules\Promotions\AdminMenuItems\Go_Pro_Promotion_Item;
use Elementor\Modules\Promotions\AdminMenuItems\Popups_Promotion_Item;
use Elementor\Modules\Promotions\Controls\Atomic_Promotion_Control;
use Elementor\Modules\Promotions\Pointers\Birthday;
use Elementor\Modules\Promotions\Pointers\Black_Friday;
use Elementor\Modules\Promotions\PropTypes\Promotion_Prop_Type;
use Elementor\Modules\Promotions\Widgets\Ally_Dashboard_Widget;
use Elementor\Widgets_Manager;
use Elementor\Utils;
use Elementor\Includes\EditorAssetsAPI;
use Elementor\Plugin;
use Elementor\Modules\EditorOne\Classes\Menu_Data_Provider;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Module extends Base_Module {
const ADMIN_MENU_PRIORITY = 100;
const ADMIN_MENU_PROMOTIONS_PRIORITY = 120;
public static function is_active() {
return ! Utils::has_pro();
}
public function get_name() {
return 'promotions';
}
public function __construct() {
parent::__construct();
add_action( 'admin_init', function () {
$this->handle_external_redirects();
} );
add_action( 'elementor/admin/menu/register', function ( Admin_Menu_Manager $admin_menu ) {
$this->register_menu_items( $admin_menu );
}, static::ADMIN_MENU_PRIORITY );
add_action( 'elementor/editor-one/menu/register', function ( Menu_Data_Provider $menu_data_provider ) {
$this->register_editor_one_menu_items( $menu_data_provider );
} );
add_action( 'elementor/admin/menu/register', function ( Admin_Menu_Manager $admin_menu ) {
$this->register_promotion_menu_item( $admin_menu );
}, static::ADMIN_MENU_PROMOTIONS_PRIORITY );
add_action( 'elementor/widgets/register', function( Widgets_Manager $manager ) {
foreach ( Api::get_promotion_widgets() as $widget_data ) {
$manager->register( new Widgets\Pro_Widget_Promotion( [], [
'widget_name' => $widget_data['name'],
'widget_title' => $widget_data['title'],
] ) );
}
} );
if ( Birthday::should_display_notice() ) {
new Birthday();
}
if ( Black_Friday::should_display_notice() ) {
new Black_Friday();
}
if ( Utils::has_pro() ) {
return;
}
add_action( 'elementor/controls/register', function ( Controls_Manager $controls_manager ) {
$controls_manager->register( new Controls\Promotion_Control() );
} );
add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'enqueue_react_data' ] );
add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'enqueue_editor_v4_alphachip' ] );
add_filter( 'elementor/editor/localize_settings', [ $this, 'add_v4_promotions_data' ] );
// Add Ally promo
Ally_Dashboard_Widget::init();
$this->register_atomic_promotions();
}
/**
* Get Ally Scanner URL
*
* @return string
*/
public static function get_ally_external_scanner_url(): string {
return apply_filters( 'elementor/ally_external_scanner_url', 'https://elementor.com/tools/ally-accessibility-checker/scanner' );
}
private function handle_external_redirects() {
$page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
if ( empty( $page ) ) {
return;
}
if ( 'go_elementor_pro' === $page ) {
wp_redirect( Go_Pro_Promotion_Item::get_url() ); // phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect
die;
}
}
private function register_menu_items( Admin_Menu_Manager $admin_menu ) {
if ( ! $this->is_editor_one_active() ) {
$admin_menu->register( 'e-form-submissions', new Form_Submissions_Promotion_Item() );
$admin_menu->register( 'elementor_custom_fonts', new Custom_Fonts_Promotion_Item() );
$admin_menu->register( 'elementor_custom_icons', new Custom_Icons_Promotion_Item() );
$admin_menu->register( 'elementor_custom_code', new Custom_Code_Promotion_Item() );
$admin_menu->register( 'popup_templates', new Popups_Promotion_Item() );
}
}
private function register_editor_one_menu_items( Menu_Data_Provider $menu_data_provider ) {
$menu_data_provider->register_menu( new Editor_One_Custom_Elements_Menu() );
$menu_data_provider->register_menu( new Editor_One_Submissions_Menu() );
$menu_data_provider->register_menu( new Editor_One_Fonts_Menu() );
$menu_data_provider->register_menu( new Editor_One_Icons_Menu() );
$menu_data_provider->register_menu( new Editor_One_Custom_Code_Menu() );
$menu_data_provider->register_menu( new Editor_One_Popups_Menu() );
}
private function register_promotion_menu_item( Admin_Menu_Manager $admin_menu ) {
if ( ! $this->is_editor_one_active() ) {
$admin_menu->register( 'go_elementor_pro', new Go_Pro_Promotion_Item() );
}
}
public function enqueue_react_data(): void {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$min_suffix = Utils::is_script_debug() ? '' : '.min';
wp_enqueue_script(
'e-react-promotions',
ELEMENTOR_ASSETS_URL . 'js/e-react-promotions' . $min_suffix . '.js',
[
'react',
'react-dom',
'backbone-marionette',
'elementor-editor-modules',
'elementor-v2-ui',
],
ELEMENTOR_VERSION,
true
);
wp_set_script_translations( 'e-react-promotions', 'elementor' );
wp_localize_script(
'e-react-promotions',
'elementorPromotionsData',
$this->get_app_js_config()
);
}
public function enqueue_editor_v4_alphachip(): void {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$min_suffix = Utils::is_script_debug() ? '' : '.min';
wp_enqueue_script(
'editor-v4-opt-in-alphachip',
ELEMENTOR_ASSETS_URL . 'js/editor-v4-opt-in-alphachip' . $min_suffix . '.js',
[
'react',
'react-dom',
'elementor-common',
'elementor-v2-ui',
],
ELEMENTOR_VERSION,
true
);
}
private function get_app_js_config(): array {
$editor_assets_api = new EditorAssetsAPI( $this->get_api_config() );
$promotion_data = new PromotionData( $editor_assets_api );
return $promotion_data->get_promotion_data();
}
private function get_api_config(): array {
return [
EditorAssetsAPI::ASSETS_DATA_URL => 'https://assets.elementor.com/free-to-pro-upsell/v1/free-to-pro-upsell.json',
EditorAssetsAPI::ASSETS_DATA_TRANSIENT_KEY => '_elementor_free_to_pro_upsell',
EditorAssetsAPI::ASSETS_DATA_KEY => 'free-to-pro-upsell',
];
}
public function add_v4_promotions_data( array $settings ): array {
if ( ! current_user_can( 'manage_options' ) ) {
return $settings;
}
$editor_assets_api = new EditorAssetsAPI( $this->get_v4_promotions_api_config() );
$promotion_data = new PromotionData( $editor_assets_api );
$settings['v4Promotions'] = $promotion_data->get_v4_promotions_data();
return $settings;
}
private function get_v4_promotions_api_config(): array {
return [
EditorAssetsAPI::ASSETS_DATA_URL => 'https://assets.elementor.com/packages/v1/promotions.json',
EditorAssetsAPI::ASSETS_DATA_TRANSIENT_KEY => '_elementor_v4_promotions',
EditorAssetsAPI::ASSETS_DATA_KEY => 'promotions',
];
}
private function is_editor_one_active(): bool {
return (bool) Plugin::instance()->modules_manager->get_modules( 'editor-one' );
}
private function is_atomic_widgets_active(): bool {
return Plugin::$instance->experiments->is_feature_active( 'e_atomic_elements' );
}
private function get_atomic_promotion_configs(): array {
return [
[
'key' => 'attributes',
'label' => __( 'Attributes', 'elementor' ),
'section' => 'settings',
'priority' => 40,
],
[
'key' => 'display-conditions',
'label' => __( 'Display Conditions', 'elementor' ),
'section' => 'settings',
'priority' => 50,
],
];
}
private function register_atomic_promotions(): void {
add_action( 'elementor/init', function() {
if ( ! $this->is_atomic_widgets_active() ) {
return;
}
add_filter(
'elementor/atomic-widgets/props-schema',
[ $this, 'inject_atomic_promotion_props' ]
);
foreach ( $this->get_atomic_promotion_configs() as $config ) {
add_filter(
'elementor/atomic-widgets/controls',
fn( array $controls, $element ) => $this->inject_atomic_promotion_control( $controls, $element, $config ),
$config['priority'],
2
);
}
} );
}
public function inject_atomic_promotion_props( array $schema ): array {
foreach ( $this->get_atomic_promotion_configs() as $config ) {
$key = $config['key'];
if ( isset( $schema[ $key ] ) ) {
continue;
}
$schema[ $key ] = Promotion_Prop_Type::make( $key );
}
return $schema;
}
protected function inject_atomic_promotion_control( array $element_controls, $atomic_element, array $config ): array {
$key = $config['key'];
$schema = $atomic_element::get_props_schema();
if ( ! array_key_exists( $key, $schema ) ) {
return $element_controls;
}
foreach ( $element_controls as $item ) {
if ( ! ( $item instanceof \Elementor\Modules\AtomicWidgets\Controls\Section ) ) {
continue;
}
if ( $item->get_id() !== $config['section'] ) {
continue;
}
$control = Atomic_Promotion_Control::make( $key )
->set_label( $config['label'] )
->set_meta( [
'topDivider' => true,
] );
$item->add_item( $control );
break;
}
return $element_controls;
}
}

View File

@@ -0,0 +1,114 @@
<?php
namespace Elementor\Modules\Promotions\Pointers;
use Elementor\User;
use Elementor\Utils;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Birthday {
const PROMOTION_URL = 'https://go.elementor.com/go-pro-wordpress-notice-birthday/';
const ELEMENTOR_POINTER_ID = 'toplevel_page_elementor';
const SEEN_TODAY_KEY = '_elementor-2025-birthday';
const DISMISS_ACTION_KEY = 'birthday_pointer_2025';
public function __construct() {
add_action( 'admin_print_footer_scripts-index.php', [ $this, 'enqueue_notice' ] );
}
public function enqueue_notice() {
if ( ! $this->should_display_notice() ) {
return;
}
$this->set_seen_today();
$this->enqueue_dependencies();
$pointer_content = '<h3>' . esc_html__( 'Elementors 9th Birthday sale!', 'elementor' ) . '</h3>';
$pointer_content .= '<p>' . esc_html__( 'Celebrate Elementors birthday with us—exclusive deals are available now.', 'elementor' );
$pointer_content .= sprintf(
'<p><a class="button button-primary" href="%s" target="_blank">%s</a></p>',
self::PROMOTION_URL,
esc_html__( 'View Deals', 'elementor' )
);
$allowed_tags = [
'h3' => [],
'p' => [],
'a' => [
'class' => [],
'target' => [ '_blank' ],
'href' => [],
],
];
?>
<script>
jQuery( document ).ready( function( $ ) {
$( "#<?php echo esc_attr( self::ELEMENTOR_POINTER_ID ); ?>" ).pointer( {
content: '<?php echo wp_kses( $pointer_content, $allowed_tags ); ?>',
position: {
edge: <?php echo is_rtl() ? "'right'" : "'left'"; ?>,
align: "center"
},
close: function() {
elementorCommon.ajax.addRequest( "introduction_viewed", {
data: {
introductionKey: '<?php echo esc_attr( static::DISMISS_ACTION_KEY ); ?>'
}
} );
}
} ).pointer( "open" );
} );
</script>
<?php
}
public static function should_display_notice(): bool {
return self::is_user_allowed() &&
! self::is_dismissed() &&
self::is_campaign_time() &&
! self::is_already_seen_today() &&
! Utils::has_pro();
}
private static function is_user_allowed(): bool {
return current_user_can( 'manage_options' ) || current_user_can( 'edit_pages' );
}
private static function is_campaign_time() {
$start = new \DateTime( '2025-06-10 12:00:00', new \DateTimeZone( 'UTC' ) );
$end = new \DateTime( '2025-06-17 03:59:00', new \DateTimeZone( 'UTC' ) );
$now = new \DateTime( 'now', new \DateTimeZone( 'UTC' ) );
return $now >= $start && $now <= $end;
}
private static function is_already_seen_today() {
return get_transient( self::get_user_transient_id() );
}
private function set_seen_today() {
$now = time();
$midnight = strtotime( 'tomorrow midnight' );
$seconds_until_midnight = $midnight - $now;
set_transient( self::get_user_transient_id(), $now, $seconds_until_midnight );
}
private static function get_user_transient_id(): string {
return self::SEEN_TODAY_KEY . '_' . get_current_user_id();
}
private function enqueue_dependencies() {
wp_enqueue_script( 'wp-pointer' );
wp_enqueue_style( 'wp-pointer' );
}
private static function is_dismissed(): bool {
return User::get_introduction_meta( static::DISMISS_ACTION_KEY );
}
}

View File

@@ -0,0 +1,114 @@
<?php
namespace Elementor\Modules\Promotions\Pointers;
use Elementor\User;
use Elementor\Utils;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class Black_Friday {
const PROMOTION_URL = 'https://go.elementor.com/go-pro-wordpress-notice-bf-25/';
const ELEMENTOR_POINTER_ID = 'toplevel_page_elementor';
const SEEN_TODAY_KEY = '_elementor_2025_black_friday';
const DISMISS_ACTION_KEY = 'black_friday_pointer_2025';
public function __construct() {
add_action( 'admin_print_footer_scripts-index.php', [ $this, 'enqueue_notice' ] );
}
public function enqueue_notice() {
if ( ! $this->should_display_notice() ) {
return;
}
$this->set_seen_today();
$this->enqueue_dependencies();
$pointer_content = '<h3>' . esc_html__( 'Black Friday Is On!', 'elementor' ) . '</h3>';
$pointer_content .= '<p>' . esc_html__( 'Save big on Elementor Pro and unlock the tools to design without limits.', 'elementor' ) . '</p>';
$pointer_content .= sprintf(
'<p><a class="button button-primary" href="%s" target="_blank">%s</a></p>',
self::PROMOTION_URL,
esc_html__( 'View Deals', 'elementor' )
);
$allowed_tags = [
'h3' => [],
'p' => [],
'a' => [
'class' => [],
'target' => [ '_blank' ],
'href' => [],
],
];
?>
<script>
jQuery( document ).ready( function( $ ) {
$( "#<?php echo esc_attr( self::ELEMENTOR_POINTER_ID ); ?>" ).pointer( {
content: '<?php echo wp_kses( $pointer_content, $allowed_tags ); ?>',
position: {
edge: <?php echo is_rtl() ? "'right'" : "'left'"; ?>,
align: "center"
},
close: function() {
elementorCommon.ajax.addRequest( "introduction_viewed", {
data: {
introductionKey: '<?php echo esc_attr( static::DISMISS_ACTION_KEY ); ?>'
}
} );
}
} ).pointer( "open" );
} );
</script>
<?php
}
public static function should_display_notice(): bool {
return self::is_user_allowed() &&
! self::is_dismissed() &&
self::is_campaign_time() &&
! self::is_already_seen_today() &&
! Utils::has_pro();
}
private static function is_user_allowed(): bool {
return current_user_can( 'manage_options' ) || current_user_can( 'edit_pages' );
}
private static function is_campaign_time() {
$start = new \DateTime( '2025-11-25 12:00:00', new \DateTimeZone( 'UTC' ) );
$end = new \DateTime( '2025-12-03 03:59:00', new \DateTimeZone( 'UTC' ) );
$now = new \DateTime( 'now', new \DateTimeZone( 'UTC' ) );
return $now >= $start && $now <= $end;
}
private static function is_already_seen_today() {
return get_transient( self::get_user_transient_id() );
}
private function set_seen_today() {
$now = time();
$midnight = strtotime( 'tomorrow midnight' );
$seconds_until_midnight = $midnight - $now;
set_transient( self::get_user_transient_id(), $now, $seconds_until_midnight );
}
private static function get_user_transient_id(): string {
return self::SEEN_TODAY_KEY . '_' . get_current_user_id();
}
private function enqueue_dependencies() {
wp_enqueue_script( 'wp-pointer' );
wp_enqueue_style( 'wp-pointer' );
}
private static function is_dismissed(): bool {
return User::get_introduction_meta( static::DISMISS_ACTION_KEY );
}
}

View File

@@ -0,0 +1,149 @@
<?php
namespace Elementor\Modules\Promotions;
use Elementor\Core\Utils\Promotions\Filtered_Promotions_Manager;
use Elementor\Includes\EditorAssetsAPI;
use Elementor\Utils;
class PromotionData {
protected EditorAssetsAPI $editor_assets_api;
public function __construct( EditorAssetsAPI $editor_assets_api ) {
$this->editor_assets_api = $editor_assets_api;
}
public function get_promotion_data( $force_request = false ): array {
$assets_data = $this->transform_assets_data( $force_request );
return [
Utils::ANIMATED_HEADLINE => $this->get_animated_headline_data( $assets_data ),
Utils::VIDEO_PLAYLIST => $this->get_video_playlist_data( $assets_data ),
Utils::CTA => $this->get_cta_button_data( $assets_data ),
Utils::IMAGE_CAROUSEL => $this->get_image_carousel_data( $assets_data ),
Utils::TESTIMONIAL_WIDGET => $this->get_testimonial_widget_data( $assets_data ),
];
}
public function get_v4_promotions_data( $force_request = false ): array {
$assets_data = $this->editor_assets_api->get_assets_data( $force_request );
if ( empty( $assets_data ) ) {
return [];
}
$promotions = [];
foreach ( $assets_data as $item ) {
foreach ( $item as $key => $promotion ) {
$promotions[ $key ] = [
'title' => esc_html( $promotion['title'] ?? '' ),
'content' => esc_html( $promotion['content'] ?? '' ),
'ctaUrl' => esc_url( $promotion['ctaUrl'] ?? '' ),
'image' => esc_url( $promotion['image'] ?? '' ),
];
}
}
return $promotions;
}
private function transform_assets_data( $force_request = false ) {
$assets_data = $this->editor_assets_api->get_assets_data( $force_request );
$transformed_data = [];
foreach ( $assets_data as $asset ) {
$transformed_data[ $asset['id'] ] = $asset['imageSrc'];
}
return $transformed_data;
}
private function get_animated_headline_data( $assets_data ) {
$data = [
'image' => esc_url( $assets_data[ Utils::ANIMATED_HEADLINE ] ?? '' ),
'image_alt' => esc_attr__( 'Upgrade', 'elementor' ),
'title' => esc_html__( 'Bring Headlines to Life', 'elementor' ),
'description' => [
esc_html__( 'Highlight key messages dynamically.', 'elementor' ),
esc_html__( 'Apply rotating effects to text.', 'elementor' ),
esc_html__( 'Fully customize your headlines.', 'elementor' ),
],
'upgrade_text' => esc_html__( 'Upgrade Now', 'elementor' ),
'upgrade_url' => 'https://go.elementor.com/go-pro-heading-widget-control/',
];
return $this->filter_data( Utils::ANIMATED_HEADLINE, $data );
}
private function get_video_playlist_data( $assets_data ) {
$data = [
'image' => esc_url( $assets_data[ Utils::VIDEO_PLAYLIST ] ?? '' ),
'image_alt' => esc_attr__( 'Upgrade', 'elementor' ),
'title' => esc_html__( 'Showcase Video Playlists', 'elementor' ),
'description' => [
esc_html__( 'Embed videos with full control.', 'elementor' ),
esc_html__( 'Adjust layout and playback settings.', 'elementor' ),
esc_html__( 'Seamlessly customize video appearance.', 'elementor' ),
],
'upgrade_text' => esc_html__( 'Upgrade Now', 'elementor' ),
'upgrade_url' => 'https://go.elementor.com/go-pro-video-widget-control/',
];
return $this->filter_data( Utils::VIDEO_PLAYLIST, $data );
}
private function get_cta_button_data( $assets_data ) {
$data = [
'image' => esc_url( $assets_data[ Utils::CTA ] ?? '' ),
'image_alt' => esc_attr__( 'Upgrade', 'elementor' ),
'title' => esc_html__( 'Boost Conversions with CTAs', 'elementor' ),
'description' => [
esc_html__( 'Combine text, buttons, and images.', 'elementor' ),
esc_html__( 'Add hover animations and CSS effects.', 'elementor' ),
esc_html__( 'Create unique, interactive designs.', 'elementor' ),
],
'upgrade_text' => esc_html__( 'Upgrade Now', 'elementor' ),
'upgrade_url' => 'https://go.elementor.com/go-pro-button-widget-control/',
];
return $this->filter_data( Utils::CTA, $data );
}
private function get_image_carousel_data( $assets_data ) {
$data = [
'image' => esc_url( $assets_data[ Utils::IMAGE_CAROUSEL ] ?? '' ),
'image_alt' => esc_attr__( 'Upgrade', 'elementor' ),
'title' => esc_html__( 'Design Custom Carousels', 'elementor' ),
'description' => [
esc_html__( 'Create flexible custom carousels.', 'elementor' ),
esc_html__( 'Adjust transitions and animations.', 'elementor' ),
esc_html__( 'Showcase multiple items with style.', 'elementor' ),
],
'upgrade_text' => esc_html__( 'Upgrade Now', 'elementor' ),
'upgrade_url' => 'https://go.elementor.com/go-pro-image-carousel-widget-control/',
];
return $this->filter_data( Utils::IMAGE_CAROUSEL, $data );
}
private function get_testimonial_widget_data( $assets_data ) {
$data = [
'image' => esc_url( $assets_data[ Utils::TESTIMONIAL_WIDGET ] ?? '' ),
'image_alt' => esc_attr__( 'Upgrade', 'elementor' ),
'title' => esc_html__( 'Upgrade Your Testimonials', 'elementor' ),
'description' => [
esc_html__( 'Display reviews in a rotating carousel.', 'elementor' ),
esc_html__( 'Boost credibility with dynamic testimonials.', 'elementor' ),
esc_html__( 'Customize layouts for visual appeal.', 'elementor' ),
],
'upgrade_text' => esc_html__( 'Upgrade Now', 'elementor' ),
'upgrade_url' => 'https://go.elementor.com/go-pro-testimonial-widget-control/',
];
return $this->filter_data( Utils::TESTIMONIAL_WIDGET, $data );
}
private function filter_data( $widget_name, $asset_data ): array {
return Filtered_Promotions_Manager::get_filtered_promotion_data( $asset_data, "elementor/widgets/{$widget_name}/custom_promotion", 'upgrade_url' );
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Elementor\Modules\Promotions\PropTypes;
use Elementor\Modules\AtomicWidgets\PropTypes\Base\Array_Prop_Type;
use Elementor\Modules\AtomicWidgets\PropTypes\Primitives\String_Prop_Type;
use Elementor\Modules\AtomicWidgets\PropTypes\Contracts\Prop_Type;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Promotion_Prop_Type extends Array_Prop_Type {
private string $key;
public function __construct( string $key = 'promotion' ) {
$this->key = $key;
parent::__construct();
}
public static function make( string $key = 'promotion' ): self {
return new static( $key );
}
public static function get_key(): string {
return 'promotion';
}
public function jsonSerialize(): array {
$data = parent::jsonSerialize();
$data['key'] = $this->key;
return $data;
}
protected function define_item_type(): Prop_Type {
return String_Prop_Type::make();
}
}

View File

@@ -0,0 +1,113 @@
<?php
namespace Elementor\Modules\Promotions\Widgets;
use Elementor\Core\Utils\Hints;
use Elementor\Modules\Promotions\Module as Promotions;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Ally_Dashboard_Widget {
public const ALLY_SCANNER_RUN = 'ea11y_dashboard_widget_scanner_run';
public const ALLY_NONCE_KEY = 'ea11y_dashboard_widget_nonce';
public const ALLY_PUBLIC_URL = 'https://wordpress.org/plugins/pojo-accessibility/';
/**
* Check is widget already submitted
*
* @access public
*/
public static function is_scanner_run() {
return get_option( self::ALLY_SCANNER_RUN );
}
/**
* Displays the Elementor Ally dashboard widget.
*
* @access public
*/
public static function ally_widget_render(): void {
$is_scanner_run = self::is_scanner_run();
$submit_id = $is_scanner_run ? 'e-dashboard-ally-submitted' : 'e-dashboard-ally-submit';
$link = $is_scanner_run ? self::ALLY_PUBLIC_URL : Promotions::get_ally_external_scanner_url() . '?url=' . home_url();
?>
<div class="e-dashboard-ally e-dashboard-widget">
<div class="e-dashboard-ally-img">
<svg width="151" height="151" viewBox="0 0 151 151" fill="none">
<path d="M76.1725 1.00457C117.143 1.55928 149.912 35.2226 149.363 76.1937C148.814 117.165 115.156 149.929 74.1846 149.374C33.2136 148.819 0.445007 115.156 0.993951 74.1849C1.54289 33.2138 35.2015 0.449866 76.1725 1.00457ZM74.3834 134.537C107.16 134.981 134.087 108.77 134.526 75.9928C134.965 43.2159 108.751 16.2853 75.9737 15.8415C43.1969 15.3977 16.27 41.6089 15.8309 74.3858C15.3917 107.163 41.6066 134.093 74.3834 134.537Z" fill="black" fill-opacity="0.12"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M75.0737 61.5437C75.6982 61.5855 76.3058 61.7729 76.8471 62.092C77.4593 62.4529 77.9646 62.9701 78.312 63.5898L88.6938 81.5006L88.7609 81.6391C89.0068 82.247 89.1008 82.9071 89.0337 83.5595C88.9664 84.2118 88.7401 84.8393 88.3754 85.3843C88.0107 85.9289 87.5175 86.3771 86.9405 86.6879C86.3633 86.9985 85.7182 87.1629 85.0628 87.1676L85.0543 87.1691H64.5848C64.5581 87.169 64.5311 87.1667 64.5049 87.1648C64.497 87.1654 64.4885 87.1672 64.4806 87.1676L64.3678 87.1662L64.1279 87.1477C63.5724 87.0855 63.0346 86.9075 62.5501 86.6251C61.9962 86.3021 61.5266 85.851 61.1823 85.31C60.8383 84.7694 60.6293 84.1534 60.5712 83.5152C60.5133 82.8768 60.6085 82.2316 60.8496 81.6376L60.9167 81.5006L71.2971 63.5898C71.6444 62.9704 72.1516 62.4529 72.7635 62.092C73.3819 61.7275 74.0874 61.5338 74.8053 61.5337L75.0737 61.5437ZM74.821 80.2226C74.0135 80.2226 73.3589 80.8773 73.3589 81.6848C73.3589 82.4923 74.0135 83.1469 74.821 83.1469H74.8353L74.9852 83.1397C75.7221 83.0645 76.2974 82.4415 76.2974 81.6848C76.2974 80.928 75.7221 80.305 74.9852 80.2298L74.8353 80.2226H74.821ZM74.8195 68.8928C74.2143 68.8932 73.723 69.384 73.723 69.9893V77.2999C73.7237 77.9045 74.2148 78.396 74.8195 78.3964C75.4246 78.3964 75.9154 77.9048 75.9161 77.2999V69.9893C75.9161 69.3838 75.4251 68.8928 74.8195 68.8928Z" fill="#DC2626"/>
</svg>
</div>
<div class="e-dashboard-ally-info">
<h4 class="e-dashboard-ally-title">
<?php $is_scanner_run
? esc_html_e( "Don't leave accessibility issues unresolved", 'elementor' )
: esc_html_e( 'Accessibility check recommended', 'elementor' ); ?>
</h4>
<p class="e-dashboard-ally-description">
<?php $is_scanner_run
? esc_html_e( 'Install Ally for free to fix accessibility issues directly in WordPress.', 'elementor' )
: esc_html_e( 'Most sites have accessibility gaps. Run a free scan to see how yours performs.', 'elementor' ) ?>
</p>
<a href="<?php echo esc_url( $link ); ?>" target="_blank" rel="noreferrer" id="<?php echo esc_attr( $submit_id ); ?>" class="button button-primary">
<?php $is_scanner_run
? esc_html_e( 'Get it free', 'elementor' )
: esc_html_e( 'Run free scan', 'elementor' ); ?>
</a>
</div>
<script>
jQuery(function($) {
$("#e-dashboard-ally-submit").on("click", function() {
$.post(ajaxurl, {
action: "e-ally-scanner-run",
nonce: "<?php echo esc_html( wp_create_nonce( self::ALLY_NONCE_KEY ) ); ?>"
});
});
});
</script>
</div>
<?php }
/**
* Ajax action handler
*
* @access public
*/
public static function handle_click() {
check_ajax_referer( self::ALLY_NONCE_KEY, 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( 'Insufficient permissions' );
}
update_option( self::ALLY_SCANNER_RUN, true );
wp_send_json_success();
}
/**
* Add widget to the list
*
* @access public
*/
public static function register_ally_dashboard_widgets() {
add_meta_box(
'e-dashboard-ally',
'<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.6853 15.5557C0.586489 13.9112 0 11.9778 0 10C0 7.34785 1.05357 4.8043 2.92893 2.92893C4.8043 1.05357 7.34785 0 10 0C11.9778 0 13.9112 0.586489 15.5557 1.6853C17.2002 2.78412 18.4819 4.3459 19.2388 6.17316C19.9957 8.00042 20.1937 10.0111 19.8078 11.9509C19.422 13.8907 18.4696 15.6725 17.0711 17.0711C15.6725 18.4696 13.8907 19.422 11.9509 19.8078C10.0111 20.1937 8.00042 19.9957 6.17316 19.2388C4.3459 18.4819 2.78412 17.2002 1.6853 15.5557ZM7.50039 5.83301H5.83398V14.1666H7.50039V5.83301ZM14.166 5.83301H9.16683V7.49941H14.166V5.83301ZM14.166 9.16585H9.16683V10.8323H14.166V9.16585ZM14.166 12.5002H9.16683V14.1666H14.166V12.5002Z" fill="#0C0D0E"/>
</svg>' . esc_html__( 'Accessibility', 'elementor' ),
[ self::class, 'ally_widget_render' ],
'dashboard',
'column3',
'high'
);
}
public static function init(): void {
if ( ! Hints::is_plugin_active( 'pojo-accessibility' ) ) {
// Register action
add_action( 'wp_ajax_e-ally-scanner-run', [ self::class, 'handle_click' ] );
// Register Dashboard Widgets.
add_action( 'wp_dashboard_setup', [ self::class, 'register_ally_dashboard_widgets' ], 99 );
}
}
}

View File

@@ -0,0 +1,106 @@
<?php
namespace Elementor\Modules\Promotions\Widgets;
use Elementor\Widget_Base;
use Elementor\Core\Utils\Promotions\Filtered_Promotions_Manager;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Pro_Widget_Promotion extends Widget_Base {
private $widget_data;
public function hide_on_search() {
return true;
}
public function show_in_panel() {
return false;
}
public function get_name() {
return $this->widget_data['widget_name'];
}
public function get_title() {
return $this->widget_data['widget_title'];
}
public function get_categories() {
return [ 'general', 'pro-elements' ];
}
public function on_import( $element ) {
$element['settings']['__should_import'] = true;
return $element;
}
protected function register_controls() {}
protected function render() {
if ( $this->is_editor_render() ) {
$this->render_promotion();
} else {
$this->render_empty_content();
}
}
private function is_editor_render(): bool {
return \Elementor\Plugin::$instance->editor->is_edit_mode();
}
private function render_promotion() {
$promotion = Filtered_Promotions_Manager::get_filtered_promotion_data(
[
'image_url' => esc_url( $this->get_promotion_image_url() ),
'text' => sprintf(
/* translators: %s: Widget title. */
esc_html__( 'This result includes the Elementor Pro %s widget. Upgrade now to unlock it and grow your web creation toolkit.', 'elementor' ),
esc_html( $this->widget_data['widget_title'] )
),
'upgrade_url' => esc_url( 'https://go.elementor.com/go-pro-element-pro/' ),
],
'elementor/pro-widget/promotion',
'upgrade_url'
);
?>
<div class="e-container">
<span class="e-badge"><i class="eicon-lock" aria-hidden="true"></i> <?php echo esc_html__( 'Pro', 'elementor' ); ?></span>
<p>
<img src="<?php echo esc_url( $promotion['image_url'] ); ?>" loading="lazy" alt="Go Pro">
<?php
echo esc_html( $promotion['text'] );
?>
</p>
<div class="e-actions">
<a href="#" class="e-btn e-btn-txt e-promotion-delete"><?php echo esc_html__( 'Remove', 'elementor' ); ?></a>
<a href="<?php echo esc_url( $promotion['upgrade_url'] ); ?>" rel="noreferrer" target="_blank" class="e-btn go-pro elementor-clickable e-promotion-go-pro"><?php echo esc_html__( 'Go Pro', 'elementor' ); ?></a>
</div>
</div>
<?php
}
private function get_promotion_image_url(): string {
return ELEMENTOR_ASSETS_URL . 'images/go-pro.svg';
}
private function render_empty_content() {
echo ' ';
}
protected function content_template() {}
public function __construct( $data = [], $args = null ) {
$this->widget_data = [
'widget_name' => $args['widget_name'],
'widget_title' => $args['widget_title'],
];
parent::__construct( $data, $args );
}
public function render_plain_content( $instance = [] ) {}
}