diff --git a/src/php/Integration/Promotions/Elementor_Pro.php b/src/php/Integration/Promotions/Elementor_Pro.php deleted file mode 100644 index cf46e68b..00000000 --- a/src/php/Integration/Promotions/Elementor_Pro.php +++ /dev/null @@ -1,117 +0,0 @@ -is_custom_code_screen() ) { - return; - } - ?> -
-

- -

-

- -

-

- - - - - - -

-
- id, [ 'edit-elementor_snippet', 'elementor_snippet' ], true ); - } - - /** - * Promotion on the Custom CSS section, inside the Elementor Editor. - * - * @return void - */ - public function promotion_in_custom_css_section() { - add_action( 'elementor/element/common/section_custom_css/before_section_end', [ $this, 'add_promotion_to_custom_css_section' ], 10, 2 ); - } - - /** - * Register promotion section after the Custom CSS section. - * - * @param Widget_Base|Element_Base $element The Elementor element. - */ - public function add_promotion_to_custom_css_section( $element ) { - $element->add_control( - 'code_snippets_promotion_notice', - [ - 'type' => Controls_Manager::NOTICE, - 'notice_type' => 'info', - 'dismissible' => true, - 'heading' => esc_html__( 'Manage your custom styles', 'code-snippets' ), - 'content' => $this->get_promotion_content(), - ] - ); - } - - /** - * Get the promotion content with appropriate link. - * - * @return string - */ - private function get_promotion_content(): string { - $message = esc_html__( 'Code Snippets Pro provides a powerful and user-friendly alternative to Elementor Custom Code, with cloud sync, conditional logic, and advanced features.', 'code-snippets' ); - - if ( code_snippets()->licensing->is_licensed() ) { - $link_text = esc_html__( 'Manage CSS snippets', 'code-snippets' ); - $url = add_query_arg( 'type', 'css', code_snippets()->get_menu_url( 'manage' ) ); - } else { - $link_text = esc_html__( 'Learn More', 'code-snippets' ); - $url = 'https://codesnippets.pro/pricing/?utm_source=elementor&utm_medium=banner&utm_campaign=elementor-addon-custom-code'; - } - - return sprintf( '%s

%s', $message, $url, $link_text ); - } -} diff --git a/src/php/Integration/Promotions/Notices/Elementor.php b/src/php/Integration/Promotions/Notices/Elementor.php new file mode 100644 index 00000000..77086fb5 --- /dev/null +++ b/src/php/Integration/Promotions/Notices/Elementor.php @@ -0,0 +1,65 @@ +get_data(); + return ! empty( $data ); + } +} diff --git a/src/php/Integration/Promotions/Notices/Insert_HTML_Snippet.php b/src/php/Integration/Promotions/Notices/Insert_HTML_Snippet.php new file mode 100644 index 00000000..29572e23 --- /dev/null +++ b/src/php/Integration/Promotions/Notices/Insert_HTML_Snippet.php @@ -0,0 +1,52 @@ +get_data(); + return ! empty( $data ); + } +} diff --git a/src/php/Integration/Promotions/Notices/Promotion_Base.php b/src/php/Integration/Promotions/Notices/Promotion_Base.php new file mode 100644 index 00000000..de70812e --- /dev/null +++ b/src/php/Integration/Promotions/Notices/Promotion_Base.php @@ -0,0 +1,249 @@ +get_plugin_name() ); + } + + /** + * Constructor to initialize the promotion notice. + */ + public function __construct() { + add_action( 'admin_notices', [ $this, 'display_promotion' ] ); + add_action( 'wp_ajax_' . self::AJAX_ACTION, [ $this, 'dismiss_promotion_ajax_handler' ] ); + } + + /** + * Determine if the current admin screen is one of the plugin's admin screens. + * + * @return bool True if it's a plugin admin screen, false otherwise. + */ + public function is_plugin_admin_screen(): bool { + if ( ! is_admin() ) { + return false; + } + + $current_screen = get_current_screen(); + + if ( ! $current_screen ) { + return false; + } + + return in_array( + $current_screen->id, + $this->get_plugin_admin_screens() ?? [], + true + ); + } + + /** + * Check if the promotion has been dismissed by the current user. + * + * @return bool True if the promotion is dismissed, false otherwise. + */ + public function is_promotion_dismissed(): bool { + $user_id = get_current_user_id(); + if ( ! $user_id ) { + return false; + } + + $dismissed_promotions = get_user_meta( $user_id, self::USER_META_KEY, true ); + if ( ! is_array( $dismissed_promotions ) ) { + $dismissed_promotions = []; + } + + return in_array( $this->get_plugin_slug(), $dismissed_promotions, true ); + } + + /** + * Display the promotion notice in the admin area. + */ + public function display_promotion() { + if ( ! $this->is_plugin_admin_screen() ) { + return; + } + + if ( $this->is_promotion_dismissed() ) { + return; + } + ?> + +
+
+ <?php esc_attr_e( 'Code Snippets Logo', 'code-snippets' ); ?> +
+
+

get_promotion_heading() ); ?>

+

get_promotion_message() ); ?>

+

print_promotion_buttons(); ?>

+
+
+ + has_snippets() ) { + printf( + '%s', + esc_url( add_query_arg( 'tab', 'plugins', code_snippets()->get_menu_url( 'import' ) ) ), + esc_html__( 'Migrate to Code Snippets', 'code-snippets' ) + ); + } else { + printf( + '%s', + esc_url( code_snippets()->get_menu_url() ), + esc_html__( 'Manage your snippets', 'code-snippets' ) + ); + } + + printf( + ' %s ', + esc_url( 'https://codesnippets.pro/pricing/?utm_source=' . $this->get_plugin_slug() . '&utm_medium=promotion&utm_campaign=custom-code' ), + esc_html__( 'Learn more', 'code-snippets' ) + ); + } +} diff --git a/src/php/Integration/Promotions/Notices/WP_Headers_And_Footers.php b/src/php/Integration/Promotions/Notices/WP_Headers_And_Footers.php new file mode 100644 index 00000000..4911ac8c --- /dev/null +++ b/src/php/Integration/Promotions/Notices/WP_Headers_And_Footers.php @@ -0,0 +1,49 @@ +add_promotion_control( $element, 'core' ); + } + ); + + // Elementor Pro. + add_action( + 'elementor/element/common/section_custom_css_pro/after_section_start', + function ( $element ) { + $this->add_promotion_control( $element, 'pro' ); + } + ); + } + + /** + * Register promotion section in the Custom CSS section. + * + * @param Widget_Base|Element_Base $element The Elementor element. + * @param string $suffix Identifier to append. + */ + public function add_promotion_control( $element, string $suffix ) { + $element->add_control( + "code_snippets_promotion_notice_elementor_$suffix", + [ + 'type' => Controls_Manager::NOTICE, + 'notice_type' => 'info', + 'dismissible' => true, + 'heading' => esc_html__( 'Manage your custom styles', 'code-snippets' ), + 'content' => $this->get_promotion_content(), + ] + ); + } + + /** + * Get the promotion content with appropriate link. + * + * @return string + */ + private function get_promotion_content(): string { + // translators: %s: plugin name. + $message = __( 'Code Snippets provides a powerful and user-friendly alternative to "%s", with cloud sync, advanced features, and an intuitive interface.', 'code-snippets' ); + $message = sprintf( $message, __( 'Elementor Custom Code', 'code-snippets' ) ); + + if ( code_snippets()->licensing->is_licensed() ) { + $link_text = __( 'Manage CSS snippets', 'code-snippets' ); + $link_url = add_query_arg( 'type', 'css', code_snippets()->get_menu_url() ); + } else { + $link_text = __( 'Learn more', 'code-snippets' ); + $link_url = 'https://codesnippets.pro/pricing/?utm_source=elementor&utm_medium=banner&utm_campaign=elementor-addon-custom-code'; + } + + return sprintf( + '%s

%s', + esc_html( $message ), + esc_url( $link_url ), + esc_html( $link_text ) + ); + } +} diff --git a/src/php/Integration/Promotions/Promotion_Manager.php b/src/php/Integration/Promotions/Promotion_Manager.php new file mode 100644 index 00000000..e7f1251d --- /dev/null +++ b/src/php/Integration/Promotions/Promotion_Manager.php @@ -0,0 +1,23 @@ +get_default_buttons(); + } +} diff --git a/src/php/Integration/Promotions/admin-notices/head-footer-code.php b/src/php/Integration/Promotions/admin-notices/head-footer-code.php new file mode 100644 index 00000000..46f16bc2 --- /dev/null +++ b/src/php/Integration/Promotions/admin-notices/head-footer-code.php @@ -0,0 +1,31 @@ +get_default_buttons(); + } +} diff --git a/src/php/Integration/Promotions/admin-notices/header-footer-code-manager.php b/src/php/Integration/Promotions/admin-notices/header-footer-code-manager.php new file mode 100644 index 00000000..f2b5ba13 --- /dev/null +++ b/src/php/Integration/Promotions/admin-notices/header-footer-code-manager.php @@ -0,0 +1,42 @@ +get_default_buttons( $this->has_snippets() ); + } + + protected function has_snippets(): bool { + $importer = new Header_Footer_Code_Manager_Importer(); + $data = $importer->get_data(); + return ! empty( $data ); + } +} diff --git a/src/php/Integration/Promotions/admin-notices/insert-html-snippet.php b/src/php/Integration/Promotions/admin-notices/insert-html-snippet.php new file mode 100644 index 00000000..032bc39a --- /dev/null +++ b/src/php/Integration/Promotions/admin-notices/insert-html-snippet.php @@ -0,0 +1,34 @@ +get_default_buttons(); + } +} diff --git a/src/php/Integration/Promotions/admin-notices/insert-php-code-snippet.php b/src/php/Integration/Promotions/admin-notices/insert-php-code-snippet.php new file mode 100644 index 00000000..bbb495e0 --- /dev/null +++ b/src/php/Integration/Promotions/admin-notices/insert-php-code-snippet.php @@ -0,0 +1,45 @@ +get_plugin_name() + ); + } + + public function get_promotion_buttons(): array { + return $this->get_default_buttons( $this->has_snippets() ); + } + + protected function has_snippets(): bool { + $importer = new Insert_PHP_Code_Snippet_Importer(); + $data = $importer->get_data(); + return ! empty( $data ); + } +} diff --git a/src/php/Integration/Promotions/admin-notices/insert-php.php b/src/php/Integration/Promotions/admin-notices/insert-php.php new file mode 100644 index 00000000..3ac6c5dd --- /dev/null +++ b/src/php/Integration/Promotions/admin-notices/insert-php.php @@ -0,0 +1,37 @@ +get_default_buttons(); + } +} diff --git a/src/php/Integration/Promotions/admin-notices/wp-headers-and-footers.php b/src/php/Integration/Promotions/admin-notices/wp-headers-and-footers.php new file mode 100644 index 00000000..28bd927b --- /dev/null +++ b/src/php/Integration/Promotions/admin-notices/wp-headers-and-footers.php @@ -0,0 +1,34 @@ +get_plugin_name() + ); + } + + public function get_promotion_buttons(): array { + return $this->get_default_buttons(); + } +} diff --git a/src/php/Integration/Promotions/other-promotions/elementor-editor.php b/src/php/Integration/Promotions/other-promotions/elementor-editor.php new file mode 100644 index 00000000..4a86d91f --- /dev/null +++ b/src/php/Integration/Promotions/other-promotions/elementor-editor.php @@ -0,0 +1,92 @@ +add_control( + 'code_snippets_promotion_notice_elementor_core', + [ + 'type' => \Elementor\Controls_Manager::NOTICE, + 'notice_type' => 'info', + 'dismissible' => true, + 'heading' => esc_html__( 'Manage your custom styles', 'code-snippets' ), + 'content' => $this->get_promotion_content(), + ] + ); + } + + /** + * Register promotion section in the Custom CSS section. + * + * @param \Elementor\Widget_Base|\Elementor\Element_Base $element The Elementor element. + */ + public function add_promotion_to_custom_css_section_in_elementor_pro( $element ) { + $element->add_control( + 'code_snippets_promotion_notice_elementor_pro', + [ + 'type' => \Elementor\Controls_Manager::NOTICE, + 'notice_type' => 'info', + 'dismissible' => true, + 'heading' => esc_html__( 'Manage your custom styles', 'code-snippets' ), + 'content' => $this->get_promotion_content(), + ] + ); + } + + /** + * Get the promotion content with appropriate link. + * + * @return string + */ + private function get_promotion_content(): string { + $message = sprintf( + esc_html__( 'Code Snippets provides a powerful and user-friendly alternative to "%s", with cloud sync, advanced features, and an intuitive interface.', 'code-snippets' ), + esc_html__( 'Elementor Custom Code', 'code-snippets' ) + ); + $link_text = esc_html__( 'Learn more', 'code-snippets' ); + $link_url = 'https://codesnippets.pro/pricing/?utm_source=elementor&utm_medium=banner&utm_campaign=elementor-addon-custom-code'; + + if ( $this->is_code_snippets_pro() ) { + $link_text = esc_html__( 'Manage CSS snippets', 'code-snippets' ); + $link_url = add_query_arg( 'type', 'css', code_snippets()->get_menu_url() ); + } + + return sprintf( + '%s

%s', + esc_html( $message ), + esc_url( $link_url ), + esc_html( $link_text ) + ); + } + + /** + * Check if pro version is installed and active. + * + * @return bool + */ + private function is_code_snippets_pro(): bool { + return code_snippets()->licensing->is_licensed(); + } +} diff --git a/src/php/Integration/Promotions/promotion-base.php b/src/php/Integration/Promotions/promotion-base.php new file mode 100644 index 00000000..f9a02167 --- /dev/null +++ b/src/php/Integration/Promotions/promotion-base.php @@ -0,0 +1,199 @@ +id, + $this->get_plugin_admin_screens() ?? [], + true + ); + + return $is_custom_code_page; + } + + public function is_promotion_dismissed(): bool { + $user_id = get_current_user_id(); + if ( ! $user_id ) { + return false; + } + + $dismissed_promotions = get_user_meta( $user_id, self::USER_META_KEY, true ); + if ( ! is_array( $dismissed_promotions ) ) { + $dismissed_promotions = []; + } + + return in_array( $this->get_plugin_slug(), $dismissed_promotions, true ); + } + + public function display_promotion() { + if ( ! $this->is_plugin_admin_screen() ) { + return; + } + + if ( $this->is_promotion_dismissed() ) { + return; + } + ?> + +
+
+ <?php esc_attr_e( 'Code Snippets Logo', 'code-snippets' ); ?> +
+
+

+ get_promotion_heading() ); ?> +

+

+ get_promotion_message() ); ?> +

+

+ get_promotion_buttons(); + + foreach ( $buttons as $button ) { + $url = isset( $button['url'] ) ? esc_url( $button['url'] ) : ''; + $text = isset( $button['text'] ) ? esc_html( $button['text'] ) : ''; + $class = isset( $button['class'] ) ? esc_attr( $button['class'] ) : 'button'; + $target = isset( $button['target'] ) ? esc_attr( $button['target'] ) : ''; + + printf( + '%s ', + $url, + $class, + $target ? ' target="' . $target . '"' : '', + $text + ); + } + ?> +

+
+
+ + code_snippets()->get_menu_url(), + 'text' => esc_html__( 'Manage your snippets', 'code-snippets' ), + 'class' => 'button button-primary', + ]; + + if ( $show_migrate ) { + $primary_button['url'] = add_query_arg( 'tab', 'plugins', code_snippets()->get_menu_url( 'import' ) ); + $primary_button['text'] = esc_html__( 'Migrate to Code Snippets', 'code-snippets' ); + } + + $secondary_button = [ + 'url' => 'https://codesnippets.pro/pricing/?utm_source=' . $this->get_plugin_slug() . '&utm_medium=promotion&utm_campaign=custom-code', + 'text' => esc_html__( 'Learn more', 'code-snippets' ), + 'class' => 'button button-secondary', + 'target' => '_blank', + 'rel' => 'noopener noreferrer', + ]; + + return [ $primary_button, $secondary_button ]; + } +} diff --git a/src/php/Integration/Promotions/promotion-manager.php b/src/php/Integration/Promotions/promotion-manager.php new file mode 100644 index 00000000..1e1d1f1e --- /dev/null +++ b/src/php/Integration/Promotions/promotion-manager.php @@ -0,0 +1,33 @@ +plugin_promotions = [ + // Notices in admin screens. + 'elementor' => Promotions\Elementor::class, + 'head-footer-code' => Promotions\Header_Footer_Code::class, + 'header-footer-code-manager' => Promotions\Header_Footer_Code_Manager::class, + 'insert-html-snippet' => Promotions\Insert_HTML_Snippet::class, + 'insert-php-code-snippet' => Promotions\Insert_PHP_Code_Snippet::class, + 'insert-php' => Promotions\Insert_PHP::class, + 'wp-headers-and-footers' => Promotions\WP_Headers_And_Footers::class, + + // Other Promotions. + 'elementor-editor' => Promotions\Elementor_Editor::class, + ]; + } + + public function __construct() { + if ( empty( $this->plugin_promotions ) ) { + $this->init_plugin_promotions(); + } + + foreach ( $this->plugin_promotions as $plugin_slug => $promotion_class ) { + new $promotion_class(); + } + } +} diff --git a/src/php/Plugin.php b/src/php/Plugin.php index 10eedd0e..8a575391 100644 --- a/src/php/Plugin.php +++ b/src/php/Plugin.php @@ -10,6 +10,7 @@ use Code_Snippets\Integration\Classic_Editor\MCE_Plugin; use Code_Snippets\Integration\Evaluate_Content; use Code_Snippets\Integration\Evaluate_Functions; +use Code_Snippets\Integration\Promotions\Promotion_Manager; use Code_Snippets\Integration\Shortcodes; use Code_Snippets\REST_API\Cloud\Cloud_Snippets_REST_Controller; use Code_Snippets\REST_API\Import\File_Import_REST_Controller; @@ -134,10 +135,9 @@ public function load_plugin() { new Shortcodes(); new MCE_Plugin(); new Upgrader( PLUGIN_VERSION, $this->db ); + new Promotion_Manager(); $this->init_snippet_files(); - - new Integration\Promotions\Elementor_Pro(); } /** diff --git a/src/php/class-plugin.php b/src/php/class-plugin.php index 27c5962c..688a10c2 100644 --- a/src/php/class-plugin.php +++ b/src/php/class-plugin.php @@ -161,8 +161,8 @@ public function load_plugin() { new Plugins_Import_Manager(); new Files_Import_Manager(); - // Initialize promotions. - new Promotions\Elementor_Pro(); + // Promotions. + new Promotion_Manager(); } /**