From c50062e5cafe130cdf4fe728037effff56d7f393 Mon Sep 17 00:00:00 2001 From: vytisbulkevicius <36594177+vytisbulkevicius@users.noreply.github.com> Date: Thu, 16 May 2024 09:58:43 +0300 Subject: [PATCH 01/16] Update index.php --- index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.php b/index.php index c98ccde74..56d86e6cb 100644 --- a/index.php +++ b/index.php @@ -2,7 +2,7 @@ /* Plugin Name: Visualizer: Tables and Charts for WordPress Plugin URI: https://themeisle.com/plugins/visualizer-charts-and-graphs/ - Description: A simple, easy to use and quite powerful tool to create, manage and embed interactive charts into your WordPress posts and pages. The plugin uses Google Visualization API to render charts, which supports cross-browser compatibility (adopting VML for older IE versions) and cross-platform portability to iOS and new Android releases. + Description: Effortlessly create and embed responsive charts and tables with Visualizer, a powerful WordPress plugin that enhances data presentation from multiple sources. Version: 3.11.1 Author: Themeisle Author URI: http://themeisle.com From 2e20fdb3f000cd2d9d2fe2a63f4fb181c2092eed Mon Sep 17 00:00:00 2001 From: GrigoreMihai Date: Fri, 17 May 2024 14:55:59 +0300 Subject: [PATCH 02/16] chore: replaced favicons with dashicons --- js/library.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/js/library.js b/js/library.js index 4718d915c..df7233eb2 100644 --- a/js/library.js +++ b/js/library.js @@ -35,11 +35,6 @@ function createPopupProBlocker() { - var link = document.createElement('link'); - link.rel = 'stylesheet'; - link.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css'; - document.head.appendChild(link); - var overlay = document.createElement('div'); overlay.classList.add('vizualizer-renew-notice-overlay'); overlay.id = 'overlay-visualizer'; @@ -49,7 +44,7 @@ function createPopupProBlocker() { popup.classList.add('vizualizer-renew-notice-popup'); var closeIcon = document.createElement('i'); - closeIcon.classList.add('fas', 'fa-times', 'vizualizer-renew-notice-close-icon'); + closeIcon.classList.add('dashicons', 'dashicons-no', 'vizualizer-renew-notice-close-icon'); closeIcon.addEventListener('click', function() { document.body.removeChild(overlay); popup.style.display = 'none'; @@ -73,7 +68,7 @@ function createPopupProBlocker() { link1.href = 'https://store.themeisle.com/'; link1.target = '_blank'; var button1 = document.createElement('button'); - button1.innerHTML = ' Renew License'; + button1.innerHTML = ' Renew License'; button1.classList.add('vizualizer-renew-notice-button', 'vizualizer-renew-notice-renew-button'); link1.appendChild(button1); buttonsContainer.appendChild(link1); @@ -81,7 +76,7 @@ function createPopupProBlocker() { var link2 = document.createElement('a'); link2.href = '/wp-admin/options-general.php#visualizer_pro_license'; var button2 = document.createElement('button'); - button2.innerHTML = ' Activate License'; + button2.innerHTML = ' Activate License'; button2.classList.add('vizualizer-renew-notice-button', 'vizualizer-renew-notice-activate-button'); link2.appendChild(button2); buttonsContainer.appendChild(link2); From 1ea938f7b03f27a9baab6b9cc20978d14f35b6bd Mon Sep 17 00:00:00 2001 From: GrigoreMihai Date: Fri, 17 May 2024 15:15:41 +0300 Subject: [PATCH 03/16] chore: added renew notice dom cleanup on close --- js/library.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/js/library.js b/js/library.js index df7233eb2..263d18b24 100644 --- a/js/library.js +++ b/js/library.js @@ -43,14 +43,6 @@ function createPopupProBlocker() { var popup = document.createElement('div'); popup.classList.add('vizualizer-renew-notice-popup'); - var closeIcon = document.createElement('i'); - closeIcon.classList.add('dashicons', 'dashicons-no', 'vizualizer-renew-notice-close-icon'); - closeIcon.addEventListener('click', function() { - document.body.removeChild(overlay); - popup.style.display = 'none'; - }); - popup.appendChild(closeIcon); - var heading = document.createElement('h1'); heading.textContent = 'Alert!'; heading.classList.add('vizualizer-renew-notice-heading'); @@ -83,6 +75,17 @@ function createPopupProBlocker() { popup.appendChild(buttonsContainer); + var closeIcon = document.createElement('i'); + + closeIcon.classList.add('dashicons', 'dashicons-no', 'vizualizer-renew-notice-close-icon'); + + closeIcon.addEventListener('click', function() { + document.body.removeChild(overlay); + document.body.removeChild(popup); + }); + + popup.appendChild(closeIcon); + document.body.appendChild(popup); } From 874cf97b0d739d7485efd402d8aeb9769048c68b Mon Sep 17 00:00:00 2001 From: GrigoreMihai Date: Fri, 17 May 2024 19:13:34 +0300 Subject: [PATCH 04/16] chore: added proper links for license renew on lock notice --- classes/Visualizer/Module/Admin.php | 9 +++++++++ classes/Visualizer/Plugin.php | 2 ++ js/library.js | 4 ++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/classes/Visualizer/Module/Admin.php b/classes/Visualizer/Module/Admin.php index 281bcca35..d6e9a55dd 100644 --- a/classes/Visualizer/Module/Admin.php +++ b/classes/Visualizer/Module/Admin.php @@ -1019,6 +1019,13 @@ public function renderLibraryPage() { } // enqueue charts array $ajaxurl = admin_url( 'admin-ajax.php' ); + $license = get_option( 'visualizer_pro_license_data', 'free' ); + $license_key = ''; + $download_id = ''; + if ( ! empty( $license ) && is_object( $license ) ) { + $license_key = $license->key; + $download_id = $license->download_id; + } wp_localize_script( 'visualizer-library', 'visualizer', @@ -1058,6 +1065,8 @@ public function renderLibraryPage() { 'conflict' => __( 'We have detected a potential conflict with another component that prevents Visualizer from functioning properly. Please disable any of the following components if they are activated on your instance: Modern Events Calendar plugin, Acronix plugin. In case the aforementioned components are not activated or you continue to see this error message, please disable all other plugins and enable them one by one to find out the component that is causing the conflict.', 'visualizer' ), ), 'is_pro_user' => Visualizer_Module::is_pro(), + 'admin_license_url' => admin_url('options-general.php#visualizer_pro_license'), + 'renew_license_url' => tsdk_utmify( Visualizer_Plugin::STORE_URL . '?edd_license_key=' . $license_key . '&download_id=' .$download_id, 'visualizer_license_block' ), ) ); // render library page diff --git a/classes/Visualizer/Plugin.php b/classes/Visualizer/Plugin.php index 49517b512..3f20628a0 100644 --- a/classes/Visualizer/Plugin.php +++ b/classes/Visualizer/Plugin.php @@ -57,6 +57,8 @@ class Visualizer_Plugin { const ACTION_UPLOAD_DATA = 'visualizer-upload-data'; const ACTION_EXPORT_DATA = 'visualizer-export-data'; + const STORE_URL = 'https://store.themeisle.com/'; + /** *Action used for fetching specific users/roles for permissions. */ diff --git a/js/library.js b/js/library.js index 263d18b24..7184c45c2 100644 --- a/js/library.js +++ b/js/library.js @@ -57,7 +57,7 @@ function createPopupProBlocker() { buttonsContainer.classList.add('vizualizer-renew-notice-buttons-container'); var link1 = document.createElement('a'); - link1.href = 'https://store.themeisle.com/'; + link1.href = visualizer.renew_license_url; link1.target = '_blank'; var button1 = document.createElement('button'); button1.innerHTML = ' Renew License'; @@ -66,7 +66,7 @@ function createPopupProBlocker() { buttonsContainer.appendChild(link1); var link2 = document.createElement('a'); - link2.href = '/wp-admin/options-general.php#visualizer_pro_license'; + link2.href = visualizer.admin_license_url; var button2 = document.createElement('button'); button2.innerHTML = ' Activate License'; button2.classList.add('vizualizer-renew-notice-button', 'vizualizer-renew-notice-activate-button'); From 7c53f0021aa3d88e097fd34320c1f81bbc4c3410 Mon Sep 17 00:00:00 2001 From: GrigoreMihai Date: Mon, 20 May 2024 13:23:31 +0300 Subject: [PATCH 05/16] chore: optimized feature lock notice rendering --- classes/Visualizer/Module/Admin.php | 10 +--- classes/Visualizer/Render/Library.php | 58 ++++++++++++++++++++ css/library.css | 3 +- js/library.js | 77 +++++---------------------- 4 files changed, 73 insertions(+), 75 deletions(-) diff --git a/classes/Visualizer/Module/Admin.php b/classes/Visualizer/Module/Admin.php index d6e9a55dd..c50675853 100644 --- a/classes/Visualizer/Module/Admin.php +++ b/classes/Visualizer/Module/Admin.php @@ -1019,13 +1019,7 @@ public function renderLibraryPage() { } // enqueue charts array $ajaxurl = admin_url( 'admin-ajax.php' ); - $license = get_option( 'visualizer_pro_license_data', 'free' ); - $license_key = ''; - $download_id = ''; - if ( ! empty( $license ) && is_object( $license ) ) { - $license_key = $license->key; - $download_id = $license->download_id; - } + wp_localize_script( 'visualizer-library', 'visualizer', @@ -1065,8 +1059,6 @@ public function renderLibraryPage() { 'conflict' => __( 'We have detected a potential conflict with another component that prevents Visualizer from functioning properly. Please disable any of the following components if they are activated on your instance: Modern Events Calendar plugin, Acronix plugin. In case the aforementioned components are not activated or you continue to see this error message, please disable all other plugins and enable them one by one to find out the component that is causing the conflict.', 'visualizer' ), ), 'is_pro_user' => Visualizer_Module::is_pro(), - 'admin_license_url' => admin_url('options-general.php#visualizer_pro_license'), - 'renew_license_url' => tsdk_utmify( Visualizer_Plugin::STORE_URL . '?edd_license_key=' . $license_key . '&download_id=' .$download_id, 'visualizer_license_block' ), ) ); // render library page diff --git a/classes/Visualizer/Render/Library.php b/classes/Visualizer/Render/Library.php index 6263ef646..09210caa1 100644 --- a/classes/Visualizer/Render/Library.php +++ b/classes/Visualizer/Render/Library.php @@ -215,10 +215,48 @@ private function getDisplayForm() { * @access private */ private function _renderLibrary() { + $license = get_option( 'visualizer_pro_license_data', 'free' ); + $license_key = ''; + $download_id = ''; + if ( ! empty( $license ) && is_object( $license ) ) { + $license_key = $license->key; + $download_id = $license->download_id; + } + $admin_license_url = admin_url('options-general.php#visualizer_pro_license'); + $renew_license_url = tsdk_utmify( Visualizer_Plugin::STORE_URL . '?edd_license_key=' . $license_key . '&download_id=' .$download_id, 'visualizer_license_block' ); // Added by Ash/Upwork $filterBy = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended // Added by Ash/Upwork echo $this->custom_css; + if ( ! Visualizer_Module::is_pro() ) { + echo ' +
+
+

Alert!

+

' . esc_html__( 'In order to edit premium charts, benefit from updates and support for Visualizer Premium plugin, please renew your license code or activate it.', 'visualizer' ) . '

+ + +
+ '; + } echo '
'; echo ''; $this->getDisplayForm(); @@ -251,6 +289,26 @@ private function _renderLibrary() { $this->_renderSidebar(); } echo '
'; + +// echo ' +// +//

Alert!

+//

+// In order to edit premium charts, benefit from updates and support for Visualizer Premium plugin, please renew your license code or activate it. +//

+// +// '; } else { echo '
'; echo '
'; diff --git a/css/library.css b/css/library.css index 5fdd3c079..621cef62b 100644 --- a/css/library.css +++ b/css/library.css @@ -522,6 +522,7 @@ div#visualizer-types ul, div#visualizer-types form p { .vizualizer-renew-notice-overlay { + display: none; position: fixed; top: 0; left: 0; @@ -532,7 +533,7 @@ div#visualizer-types ul, div#visualizer-types form p { } .vizualizer-renew-notice-popup { - display: block; + display: none; position: fixed; top: 50%; left: 50%; diff --git a/js/library.js b/js/library.js index 7184c45c2..55869c474 100644 --- a/js/library.js +++ b/js/library.js @@ -33,61 +33,13 @@ }); })(wp.media.view); -function createPopupProBlocker() { - - var overlay = document.createElement('div'); - overlay.classList.add('vizualizer-renew-notice-overlay'); - overlay.id = 'overlay-visualizer'; - document.body.appendChild(overlay); - - var popup = document.createElement('div'); - popup.classList.add('vizualizer-renew-notice-popup'); - - var heading = document.createElement('h1'); - heading.textContent = 'Alert!'; - heading.classList.add('vizualizer-renew-notice-heading'); - popup.appendChild(heading); - - var message = document.createElement('p'); - message.textContent = 'In order to edit premium charts, benefit from updates and support for Visualizer Premium plugin, please renew your license code or activate it.'; - message.classList.add('vizualizer-renew-notice-message'); - popup.appendChild(message); - - var buttonsContainer = document.createElement('div'); - buttonsContainer.classList.add('vizualizer-renew-notice-buttons-container'); - - var link1 = document.createElement('a'); - link1.href = visualizer.renew_license_url; - link1.target = '_blank'; - var button1 = document.createElement('button'); - button1.innerHTML = ' Renew License'; - button1.classList.add('vizualizer-renew-notice-button', 'vizualizer-renew-notice-renew-button'); - link1.appendChild(button1); - buttonsContainer.appendChild(link1); - - var link2 = document.createElement('a'); - link2.href = visualizer.admin_license_url; - var button2 = document.createElement('button'); - button2.innerHTML = ' Activate License'; - button2.classList.add('vizualizer-renew-notice-button', 'vizualizer-renew-notice-activate-button'); - link2.appendChild(button2); - buttonsContainer.appendChild(link2); - - popup.appendChild(buttonsContainer); - - var closeIcon = document.createElement('i'); - - closeIcon.classList.add('dashicons', 'dashicons-no', 'vizualizer-renew-notice-close-icon'); - - closeIcon.addEventListener('click', function() { - document.body.removeChild(overlay); - document.body.removeChild(popup); - }); - - popup.appendChild(closeIcon); - - document.body.appendChild(popup); - +function createPopupProBlocker( $ , e ) { + if ( ! visualizer.is_pro_user && e.target.classList.contains('viz-is-pro-chart') ) { + $("#overlay-visualizer").css("display", "block"); + $(".vizualizer-renew-notice-popup").css("display", "block"); + return true; + } + return false; } (function ($, vmv, vu) { @@ -135,8 +87,7 @@ function createPopupProBlocker() { $('.visualizer-chart-shortcode').click(function (e) { - if ( ! visualizer.is_pro_user && e.target.classList.contains('viz-is-pro-chart') ) { - createPopupProBlocker(); + if ( createPopupProBlocker( $, e ) ) { e.preventDefault(); e.stopPropagation(); return; @@ -193,8 +144,7 @@ function createPopupProBlocker() { $('.visualizer-chart-edit').click(function (event) { - if ( ! visualizer.is_pro_user && event.target.classList.contains('viz-is-pro-chart') ) { - createPopupProBlocker(); + if ( createPopupProBlocker( $, event ) ) { return; } @@ -213,16 +163,14 @@ function createPopupProBlocker() { return false; }); $(".visualizer-chart-clone").on("click", function ( event ) { - if ( ! visualizer.is_pro_user && event.target.classList.contains('viz-is-pro-chart') ) { - createPopupProBlocker(); + if ( createPopupProBlocker( $, event ) ) { event.preventDefault(); } }); $(".visualizer-chart-export").on("click", function (event) { - if ( ! visualizer.is_pro_user && event.target.classList.contains('viz-is-pro-chart') ) { - createPopupProBlocker(); + if ( createPopupProBlocker( $, event ) ) { return; } @@ -247,8 +195,7 @@ function createPopupProBlocker() { }); $(".visualizer-chart-image").on("click", function (event) { - if ( ! visualizer.is_pro_user && event.target.classList.contains('viz-is-pro-chart') ) { - createPopupProBlocker(); + if ( createPopupProBlocker( $, event ) ) { return; } $('body').trigger('visualizer:action:specificchart', {action: 'image', id: $(this).attr("data-chart"), data: null, dataObj: {name: $(this).attr("data-chart-title")}}); From 94c9181cc1ef8cf4ef718ea3d13e3d937044c624 Mon Sep 17 00:00:00 2001 From: GrigoreMihai Date: Mon, 20 May 2024 13:32:31 +0300 Subject: [PATCH 06/16] removed leftover testing code --- classes/Visualizer/Render/Library.php | 28 ++++----------------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/classes/Visualizer/Render/Library.php b/classes/Visualizer/Render/Library.php index 09210caa1..0ffeeacb1 100644 --- a/classes/Visualizer/Render/Library.php +++ b/classes/Visualizer/Render/Library.php @@ -222,8 +222,8 @@ private function _renderLibrary() { $license_key = $license->key; $download_id = $license->download_id; } - $admin_license_url = admin_url('options-general.php#visualizer_pro_license'); - $renew_license_url = tsdk_utmify( Visualizer_Plugin::STORE_URL . '?edd_license_key=' . $license_key . '&download_id=' .$download_id, 'visualizer_license_block' ); + $admin_license_url = admin_url( 'options-general.php#visualizer_pro_license' ); + $renew_license_url = tsdk_utmify( Visualizer_Plugin::STORE_URL . '?edd_license_key=' . $license_key . '&download_id=' . $download_id, 'visualizer_license_block' ); // Added by Ash/Upwork $filterBy = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended // Added by Ash/Upwork @@ -235,12 +235,12 @@ private function _renderLibrary() {

Alert!

' . esc_html__( 'In order to edit premium charts, benefit from updates and support for Visualizer Premium plugin, please renew your license code or activate it.', 'visualizer' ) . '

'; - -// echo ' -// -//

Alert!

-//

-// In order to edit premium charts, benefit from updates and support for Visualizer Premium plugin, please renew your license code or activate it. -//

-//
-// '; } else { echo '
'; echo '
'; From 565348d79d7e823fe0215054a30014221ed10951 Mon Sep 17 00:00:00 2001 From: GrigoreMihai Date: Mon, 20 May 2024 13:34:44 +0300 Subject: [PATCH 07/16] lint code --- classes/Visualizer/Render/Library.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/Visualizer/Render/Library.php b/classes/Visualizer/Render/Library.php index 0ffeeacb1..e5602dd5c 100644 --- a/classes/Visualizer/Render/Library.php +++ b/classes/Visualizer/Render/Library.php @@ -235,7 +235,7 @@ private function _renderLibrary() {

Alert!

' . esc_html__( 'In order to edit premium charts, benefit from updates and support for Visualizer Premium plugin, please renew your license code or activate it.', 'visualizer' ) . '

'; } - /** - * Renders library content. - * - * @since 1.0.0 + * Renders pro charts blocker. * * @access private */ - private function _renderLibrary() { + private function _renderProPopupBlocker () { $license = get_option( 'visualizer_pro_license_data', 'free' ); $license_key = ''; $download_id = ''; @@ -224,10 +221,7 @@ private function _renderLibrary() { } $admin_license_url = admin_url( 'options-general.php#visualizer_pro_license' ); $renew_license_url = tsdk_utmify( Visualizer_Plugin::STORE_URL . '?edd_license_key=' . $license_key . '&download_id=' . $download_id, 'visualizer_license_block' ); - // Added by Ash/Upwork - $filterBy = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended - // Added by Ash/Upwork - echo $this->custom_css; + if ( ! Visualizer_Module::is_pro() ) { echo '
@@ -257,6 +251,23 @@ private function _renderLibrary() { }); '; } + } + /** + * Renders library content. + * + * @since 1.0.0 + * + * @access private + */ + private function _renderLibrary() { + + // Added by Ash/Upwork + $filterBy = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended + // Added by Ash/Upwork + echo $this->custom_css; + + $this->_renderProPopupBlocker(); + echo '
'; echo ''; $this->getDisplayForm(); From 064c73b909c170a0fa652967c2901dda115b99d5 Mon Sep 17 00:00:00 2001 From: GrigoreMihai Date: Mon, 20 May 2024 13:49:34 +0300 Subject: [PATCH 09/16] lint code --- classes/Visualizer/Render/Library.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/Visualizer/Render/Library.php b/classes/Visualizer/Render/Library.php index e1e05936a..73bc66091 100644 --- a/classes/Visualizer/Render/Library.php +++ b/classes/Visualizer/Render/Library.php @@ -211,7 +211,7 @@ private function getDisplayForm() { * * @access private */ - private function _renderProPopupBlocker () { + private function _renderProPopupBlocker() { $license = get_option( 'visualizer_pro_license_data', 'free' ); $license_key = ''; $download_id = ''; From 7b5d823cdc9319ed66bed2646f66c73c452ab2c2 Mon Sep 17 00:00:00 2001 From: Bogdan Preda Date: Mon, 20 May 2024 19:10:40 +0300 Subject: [PATCH 10/16] fix: sql for subscriber added check for pro filter References: Codeinwp/visualizer-pro#472 --- classes/Visualizer/Module/Chart.php | 15 ++++++ tests/test-ajax.php | 72 +++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/classes/Visualizer/Module/Chart.php b/classes/Visualizer/Module/Chart.php index d13c1f00d..00de88a4e 100644 --- a/classes/Visualizer/Module/Chart.php +++ b/classes/Visualizer/Module/Chart.php @@ -1431,6 +1431,10 @@ public function getQueryData() { wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) ); } + if ( ! Visualizer_Module::is_pro() ) { + wp_send_json_error( array( 'msg' => __( 'Feature is not available.', 'visualizer' ) ) ); + } + $params = wp_parse_args( $_POST['params'] ); $chart_id = filter_var( $params['chart_id'], FILTER_VALIDATE_INT ); $query = trim( $params['query'], ';' ); @@ -1452,6 +1456,17 @@ public function getQueryData() { public function saveQuery() { check_ajax_referer( Visualizer_Plugin::ACTION_SAVE_DB_QUERY . Visualizer_Plugin::VERSION, 'security' ); + if ( ! current_user_can( 'administrator' ) ) { + wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) ); + } + if ( ! is_super_admin() ) { + wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) ); + } + + if ( ! Visualizer_Module::is_pro() ) { + wp_send_json_error( array( 'msg' => __( 'Feature is not available.', 'visualizer' ) ) ); + } + $chart_id = filter_input( INPUT_GET, 'chart', diff --git a/tests/test-ajax.php b/tests/test-ajax.php index 416ffd768..0140cd78a 100644 --- a/tests/test-ajax.php +++ b/tests/test-ajax.php @@ -66,6 +66,8 @@ public function setUp() { public function test_ajax_response_get_query_data_valid_query() { $this->_setRole( 'administrator' ); + $this->enable_pro(); + $_GET['security'] = wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION ); global $wpdb; @@ -93,6 +95,8 @@ public function test_ajax_response_get_query_data_valid_query() { public function test_ajax_response_get_query_data_invalid_query() { $this->_setRole( 'administrator' ); + $this->enable_pro(); + $_GET['security'] = wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION ); $_POST['params'] = array( @@ -120,6 +124,8 @@ public function test_ajax_response_get_query_data_invalid_query() { public function test_ajax_response_get_query_data_valid_query_with_filtered_columns() { $this->_setRole( 'administrator' ); + $this->enable_pro(); + $_GET['security'] = wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION ); $_POST['params'] = array( @@ -203,6 +209,8 @@ public function test_ajax_response_get_query_data_subcriber_dissallow() { public function test_ajax_response_get_query_data_invalid_query_subquery() { $this->_setRole( 'administrator' ); + $this->enable_pro(); + $_GET['security'] = wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION ); $_POST['params'] = array( @@ -230,6 +238,8 @@ public function test_ajax_response_get_query_data_invalid_query_subquery() { public function test_ajax_response_get_query_data_invalid_query_comment() { $this->_setRole( 'administrator' ); + $this->enable_pro(); + $_GET['security'] = wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION ); $_POST['params'] = array( @@ -264,4 +274,66 @@ public function test_sql_comment_strip() { $source = new Visualizer_Source_Query( "/* SELECT */ DELETE * FROM test_table /* WHERE post_type = 'post' */"); $this->assertEquals( 'DELETE * FROM test_table', $source->get_query() ); } + + /** + * Test Save Query not allowed for subscriber. + */ + public function test_sql_save_chart_subscriber() { + $this->_setRole( 'subscriber' ); + + $_GET['security'] = wp_create_nonce( Visualizer_Plugin::ACTION_SAVE_DB_QUERY . Visualizer_Plugin::VERSION ); + $_GET['chart'] = '1'; + + $_POST['params'] = array( + 'query' => "SELECT * FROM wp_posts LIMIT 1", + ); + try { + // Trigger the AJAX action + $this->_handleAjax( Visualizer_Plugin::ACTION_SAVE_DB_QUERY ); + } catch ( WPAjaxDieContinueException $e ) { + // We expected this, do nothing. + } + + $response = json_decode( $this->_last_response ); + $this->assertIsObject( $response ); + $this->assertObjectHasAttribute( 'success', $response ); + $this->assertObjectHasAttribute( 'data', $response ); + $this->assertEquals( 'Action not allowed for this user.', $response->data->msg ); + $this->assertFalse( $response->success ); + } + + /** + * Test Save Query not allowed if not pro. + */ + public function test_sql_save_chart_admin() { + wp_set_current_user( $this->admin_user_id ); + $this->_setRole( 'administrator' ); + + $_GET['security'] = wp_create_nonce( Visualizer_Plugin::ACTION_SAVE_DB_QUERY . Visualizer_Plugin::VERSION ); + $_GET['chart'] = '1'; + + $_POST['params'] = array( + 'query' => "SELECT * FROM wp_posts LIMIT 1", + ); + try { + // Trigger the AJAX action + $this->_handleAjax( Visualizer_Plugin::ACTION_SAVE_DB_QUERY ); + } catch ( WPAjaxDieContinueException $e ) { + // We expected this, do nothing. + } + + $response = json_decode( $this->_last_response ); + $this->assertIsObject( $response ); + $this->assertObjectHasAttribute( 'success', $response ); + $this->assertObjectHasAttribute( 'data', $response ); + $this->assertEquals( 'Feature is not available.', $response->data->msg ); + $this->assertFalse( $response->success ); + } + + /** + * Utility method to mock pro version. + */ + private function enable_pro() { + add_filter( 'visualizer_is_pro', '__return_true' ); + } } From cedcd06d0dcdaf0121c5884a7fd8080283363fa6 Mon Sep 17 00:00:00 2001 From: Bogdan Preda Date: Mon, 20 May 2024 19:13:57 +0300 Subject: [PATCH 11/16] chore: code style --- tests/test-ajax.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-ajax.php b/tests/test-ajax.php index 0140cd78a..a7bd7a6b5 100644 --- a/tests/test-ajax.php +++ b/tests/test-ajax.php @@ -285,7 +285,7 @@ public function test_sql_save_chart_subscriber() { $_GET['chart'] = '1'; $_POST['params'] = array( - 'query' => "SELECT * FROM wp_posts LIMIT 1", + 'query' => 'SELECT * FROM wp_posts LIMIT 1', ); try { // Trigger the AJAX action @@ -313,7 +313,7 @@ public function test_sql_save_chart_admin() { $_GET['chart'] = '1'; $_POST['params'] = array( - 'query' => "SELECT * FROM wp_posts LIMIT 1", + 'query' => 'SELECT * FROM wp_posts LIMIT 1', ); try { // Trigger the AJAX action From e6e85fbb0cc9debe0994884f8beeda210a5f61e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 16:27:43 +0000 Subject: [PATCH 12/16] chore(deps): bump codeinwp/themeisle-sdk from 3.3.21 to 3.3.22 Bumps [codeinwp/themeisle-sdk](https://github.com/Codeinwp/themeisle-sdk) from 3.3.21 to 3.3.22. - [Release notes](https://github.com/Codeinwp/themeisle-sdk/releases) - [Changelog](https://github.com/Codeinwp/themeisle-sdk/blob/master/CHANGELOG.md) - [Commits](https://github.com/Codeinwp/themeisle-sdk/compare/v3.3.21...v3.3.22) --- updated-dependencies: - dependency-name: codeinwp/themeisle-sdk dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 1692ba8f4..e496acc34 100644 --- a/composer.lock +++ b/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "codeinwp/themeisle-sdk", - "version": "3.3.21", + "version": "3.3.22", "source": { "type": "git", "url": "https://github.com/Codeinwp/themeisle-sdk.git", - "reference": "c73f9f8e32ccfa933ef244eb284dd58e0dace8eb" + "reference": "1754febc3c25c4c884424e72801c4d3f2ec7097e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeinwp/themeisle-sdk/zipball/c73f9f8e32ccfa933ef244eb284dd58e0dace8eb", - "reference": "c73f9f8e32ccfa933ef244eb284dd58e0dace8eb", + "url": "https://api.github.com/repos/Codeinwp/themeisle-sdk/zipball/1754febc3c25c4c884424e72801c4d3f2ec7097e", + "reference": "1754febc3c25c4c884424e72801c4d3f2ec7097e", "shasum": "" }, "require-dev": { @@ -42,9 +42,9 @@ ], "support": { "issues": "https://github.com/Codeinwp/themeisle-sdk/issues", - "source": "https://github.com/Codeinwp/themeisle-sdk/tree/v3.3.21" + "source": "https://github.com/Codeinwp/themeisle-sdk/tree/v3.3.22" }, - "time": "2024-04-29T13:20:44+00:00" + "time": "2024-05-17T15:04:51+00:00" }, { "name": "markbaker/complex", From 7a582503d141f755d28f71ada1880bfc31bc1c6d Mon Sep 17 00:00:00 2001 From: GrigoreMihai Date: Wed, 22 May 2024 22:18:00 +0300 Subject: [PATCH 13/16] chore: addresed pr review changes --- classes/Visualizer/Render/Library.php | 27 +++++++++++++++------------ css/library.css | 13 +++++++++++-- js/library.js | 12 ++++++------ 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/classes/Visualizer/Render/Library.php b/classes/Visualizer/Render/Library.php index 73bc66091..73d610803 100644 --- a/classes/Visualizer/Render/Library.php +++ b/classes/Visualizer/Render/Library.php @@ -212,6 +212,9 @@ private function getDisplayForm() { * @access private */ private function _renderProPopupBlocker() { + if ( Visualizer_Module::is_pro() ) { + return; + } $license = get_option( 'visualizer_pro_license_data', 'free' ); $license_key = ''; $download_id = ''; @@ -221,13 +224,11 @@ private function _renderProPopupBlocker() { } $admin_license_url = admin_url( 'options-general.php#visualizer_pro_license' ); $renew_license_url = tsdk_utmify( Visualizer_Plugin::STORE_URL . '?edd_license_key=' . $license_key . '&download_id=' . $download_id, 'visualizer_license_block' ); - - if ( ! Visualizer_Module::is_pro() ) { - echo ' + echo '
'; - } + } /** * Renders library content. diff --git a/css/library.css b/css/library.css index 621cef62b..81017ca3d 100644 --- a/css/library.css +++ b/css/library.css @@ -595,8 +595,17 @@ div#visualizer-types ul, div#visualizer-types form p { .vizualizer-renew-notice-close-icon { position: absolute; - top: 10px; - right: 10px; + top: -10px; + right: -70px; cursor: pointer; color: #333; + background: none; + border: none; + padding: 0; + outline: none; + /* Reset button styles */ + display: inline-block; + font: inherit; + text-align: inherit; + text-decoration: none; } diff --git a/js/library.js b/js/library.js index 55869c474..d0efddd14 100644 --- a/js/library.js +++ b/js/library.js @@ -85,11 +85,11 @@ function createPopupProBlocker( $ , e ) { $(this).parent('form').submit(); }); - $('.visualizer-chart-shortcode').click(function (e) { + $('.visualizer-chart-shortcode').click(function (event) { - if ( createPopupProBlocker( $, e ) ) { - e.preventDefault(); - e.stopPropagation(); + if ( createPopupProBlocker( $, event ) ) { + event.preventDefault(); + event.stopPropagation(); return; } @@ -98,12 +98,12 @@ function createPopupProBlocker( $ , e ) { if (window.getSelection && document.createRange) { selection = window.getSelection(); range = document.createRange(); - range.selectNodeContents(e.target); + range.selectNodeContents(event.target); selection.removeAllRanges(); selection.addRange(range); } else if (document.selection && document.body.createTextRange) { range = document.body.createTextRange(); - range.moveToElementText(e.target); + range.moveToElementText(event.target); range.select(); } }); From ebe416e4f31428e96e41c6c26b1460098af683f7 Mon Sep 17 00:00:00 2001 From: Bogdan Preda Date: Thu, 23 May 2024 11:14:10 +0300 Subject: [PATCH 14/16] fix: widget not loading References: #1156 --- classes/Visualizer/Module/Admin.php | 5 ++++- tests/e2e/specs/gutenberg-editor.spec.js | 23 ++++++++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/classes/Visualizer/Module/Admin.php b/classes/Visualizer/Module/Admin.php index 281bcca35..7e3a508ad 100644 --- a/classes/Visualizer/Module/Admin.php +++ b/classes/Visualizer/Module/Admin.php @@ -53,6 +53,7 @@ public function __construct( Visualizer_Plugin $plugin ) { parent::__construct( $plugin ); $this->_addAction( 'load-post.php', 'enqueueMediaScripts' ); $this->_addAction( 'load-post-new.php', 'enqueueMediaScripts' ); + $this->_addAction( 'enqueue_block_editor_assets', 'enqueueMediaScripts' ); $this->_addAction( 'admin_footer', 'renderTemplates' ); $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 0 ); $this->_addAction( 'admin_menu', 'registerAdminMenu' ); @@ -330,7 +331,9 @@ public function feedbackReviewTrigger( $dumb ) { */ public function enqueueMediaScripts() { global $typenow; - if ( post_type_supports( $typenow, 'editor' ) ) { + global $current_screen; + + if ( post_type_supports( $typenow, 'editor' ) || $current_screen->id === 'widgets' ) { wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION ); // Load all the assets for the different libraries we support. diff --git a/tests/e2e/specs/gutenberg-editor.spec.js b/tests/e2e/specs/gutenberg-editor.spec.js index e5859b8cc..5da67cae7 100644 --- a/tests/e2e/specs/gutenberg-editor.spec.js +++ b/tests/e2e/specs/gutenberg-editor.spec.js @@ -31,7 +31,7 @@ test.describe( 'Charts with Gutenberg Editor', () => { test('new chart creation', async ( { admin, editor, page } ) => { await admin.createNewPost(); await editor.insertBlock( { name: 'visualizer/chart'} ); - + await expect( page.getByText('Make a new chart or display') ).toBeVisible(); await expect( page.getByLabel('Editor content').locator('a') ).toBeVisible(); @@ -40,7 +40,7 @@ test.describe( 'Charts with Gutenberg Editor', () => { // Create chart via popup. await page.frameLocator('iframe').getByRole('button', { name: 'Next' }).click(); await page.frameLocator('iframe').getByRole('button', { name: 'Create Chart' }).click(); - + await expect( page.getByRole('button', { name: 'Save', exact: true }) ).toBeVisible(); await page.getByRole('button', { name: 'Save', exact: true }).click(); await expect( page.getByRole('button', { name: 'Done' }) ).toBeVisible(); @@ -98,7 +98,7 @@ test.describe( 'Charts with Gutenberg Editor', () => { await page.getByRole('button', { name: 'Import from other chart' }).click(); await page.getByRole('button', { name: 'Import data from database' }).click(); - + const upgradeLinks = await page.locator('a').filter({ hasText: 'Upgrade Now' }).count(); expect( upgradeLinks ).toBe( 6 ); @@ -131,4 +131,21 @@ test.describe( 'Charts with Gutenberg Editor', () => { await expect(page.getByLabel('Visualizer', { exact: true }).locator('h1')).toContainText('Visualizer'); await page.getByRole('button', { name: ' Close dialog' }).click(); } ); + + test( 'check widgets', async ( { admin, editor, page } ) => { + await createChartWithAdmin( admin, page ); + + await admin.visitAdminPage( 'widgets.php' ); + + await page.getByLabel('Close', { exact: true }).click(); + await page.getByLabel('Toggle block inserter').click(); + await page.getByPlaceholder('Search').fill('visuali'); + await page.getByRole('option', { name: ' Visualizer Chart' }).click(); + await page.locator('div').filter({ hasText: /^Display an existing chart$/ }).click(); + await page.getByTitle('Insert Chart').first().click(); + + await expect(page.getByLabel('Block: Visualizer Chart')).toContainText('Visualizer'); + await expect(page.locator('rect').first()).toBeVisible(); + + } ); } ); From 187c7f6fc60eb79d14a9adc6064030cca1752f05 Mon Sep 17 00:00:00 2001 From: GrigoreMihai Date: Thu, 23 May 2024 15:33:41 +0300 Subject: [PATCH 15/16] chore: added e2e test for pro chart lock --- classes/Visualizer/Render/Library.php | 2 +- tests/e2e/specs/upsell.spec.js | 216 +++++++++++++++----------- 2 files changed, 122 insertions(+), 96 deletions(-) diff --git a/classes/Visualizer/Render/Library.php b/classes/Visualizer/Render/Library.php index 73d610803..1c61c5cc5 100644 --- a/classes/Visualizer/Render/Library.php +++ b/classes/Visualizer/Render/Library.php @@ -212,7 +212,7 @@ private function getDisplayForm() { * @access private */ private function _renderProPopupBlocker() { - if ( Visualizer_Module::is_pro() ) { + if ( Visualizer_Module::is_pro() ) { return; } $license = get_option( 'visualizer_pro_license_data', 'free' ); diff --git a/tests/e2e/specs/upsell.spec.js b/tests/e2e/specs/upsell.spec.js index 9e63ffb3e..170b7ef71 100644 --- a/tests/e2e/specs/upsell.spec.js +++ b/tests/e2e/specs/upsell.spec.js @@ -9,99 +9,125 @@ const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); const { deleteAllCharts, getAssetFilePath, CHART_JS_LABELS, selectChartAdmin } = require('../utils/common'); test.describe( 'Upsell', () => { - test.beforeEach( async ( { admin, requestUtils, page } ) => { - await deleteAllCharts( requestUtils ); - await admin.visitAdminPage( 'admin.php?page=visualizer' ); - page.setDefaultTimeout( 5000 ); - } ); - - test( 'chart selection on admin', async ( { admin, page } ) => { - await admin.visitAdminPage( 'admin.php?page=visualizer&vaction=addnew' ); - await page.waitForURL( '**/admin.php?page=visualizer&vaction=addnew' ); - await page.waitForSelector('h1:text("Visualizer")'); - - expect( await page.frameLocator('iframe').locator('.pro-upsell').count() ).toBe( 11 ); - - const proUpsellElements = await page.frameLocator('iframe').locator('a.pro-upsell').all(); - - for (const element of proUpsellElements) { - const href = await element.getAttribute('href'); - const searchParams = new URLSearchParams(href); - expect( searchParams.get('utm_campaign') ).toBe('charttypes'); - } - } ); - - test( 'chart settings on admin', async ( { admin, page } ) => { - await admin.visitAdminPage( 'admin.php?page=visualizer&vaction=addnew' ); - await page.waitForURL( '**/admin.php?page=visualizer&vaction=addnew' ); - await page.waitForSelector('h1:text("Visualizer")'); - await selectChartAdmin( page.frameLocator('iframe'), CHART_JS_LABELS.pie ); - - await expect( page.frameLocator('iframe').locator( '#viz-tabs' ) ).toBeVisible(); - - expect( await page.frameLocator('iframe').locator('#vz-chart-source .viz-group-title .dashicons-lock').count() ).toBe( 5 ); - - - const uploadFileUpsell = page.frameLocator('iframe').locator('#vz-chart-source .visualizer_source_csv .only-pro-inner a'); - let href = await uploadFileUpsell.getAttribute('href'); - let searchParams = new URLSearchParams(href); - expect( searchParams.get('utm_campaign') ).toBe('import-file'); - - const remoteImportUpsell = page.frameLocator('iframe').locator('#vz-chart-source .visualizer_source_json .only-pro-inner a').first(); - href = await remoteImportUpsell.getAttribute('href'); - searchParams = new URLSearchParams(href); - expect( searchParams.get('utm_campaign') ).toBe('import-url'); - - const otherChartUpsell = page.frameLocator('iframe').locator('#vz-chart-source .viz-import-from-other .only-pro-inner a'); - href = await otherChartUpsell.getAttribute('href'); - searchParams = new URLSearchParams(href); - expect( searchParams.get('utm_campaign') ).toBe('import-chart'); - - const wpImportUpsell = page.frameLocator('iframe').locator('#vz-chart-source .visualizer_source_query_wp .only-pro-inner a'); - href = await wpImportUpsell.getAttribute('href'); - searchParams = new URLSearchParams(href); - expect( searchParams.get('utm_campaign') ).toBe('import-wp'); - await page.frameLocator('iframe').getByRole('heading', { name: /Import from WordPress/ }).click(); - await expect(page.frameLocator('iframe').locator('#vz-chart-source')).toContainText('Upgrade to PRO to activate this feature!'); - - const dbImportUpsell = page.frameLocator('iframe').locator('#vz-chart-source .visualizer_source_query .only-pro-inner a'); - href = await dbImportUpsell.getAttribute('href'); - searchParams = new URLSearchParams(href); - expect( searchParams.get('utm_campaign') ).toBe('db-query'); - - await page.frameLocator('iframe').getByRole('heading', { name: /Import from database/ }).click(); - await expect(page.frameLocator('iframe').locator('#vz-db-wizard')).toContainText('Upgrade to Plus plan to activate this feature!'); - await expect(page.frameLocator('iframe').locator('#vz-db-wizard')).toContainText('Upgrade Now'); - - await page.frameLocator('iframe').getByRole('link', { name: 'Settings' }).click(); - - const dataFilterConfigurationUpsell = page.frameLocator('iframe').locator('#vz-data-controls .only-pro-inner a'); - href = await dataFilterConfigurationUpsell.getAttribute('href'); - searchParams = new URLSearchParams(href); - expect( searchParams.get('utm_campaign') ).toBe('data-filter-configuration'); - - const frontendActionsUpsell = page.frameLocator('iframe').locator('#vz-frontend-actions .only-pro-inner a'); - href = await frontendActionsUpsell.getAttribute('href'); - searchParams = new URLSearchParams(href); - expect( searchParams.get('utm_campaign') ).toBe('frontend-actions'); - - const chartPermissionsUpsell = page.frameLocator('iframe').locator('#vz-permissions .only-pro-inner a'); - href = await chartPermissionsUpsell.getAttribute('href'); - searchParams = new URLSearchParams(href); - expect( searchParams.get('utm_campaign') ).toBe('chart-permissions'); - await page.frameLocator('iframe').getByRole('heading', { name: /Permissions/ }).click(); - await expect(page.frameLocator('iframe').locator('#vz-db-wizard')).toContainText('Upgrade to Plus plan to activate this feature!'); - await expect(page.frameLocator('iframe').locator('#vz-db-wizard')).toContainText('Upgrade Now'); - }); - - test( 'featured tab in Install Plugin (SDK)', async ( { admin, page } ) => { - await admin.visitAdminPage( 'plugin-install.php' ); - - // Those should be visible only when a PRO product is installed. - await expect( page.getByText('Image Optimization by Optimole') ).toBeHidden(); - await expect( page.locator('#the-list div').filter({ hasText: 'Otter Blocks' }).nth(1) ).toBeHidden(); - - await expect( page.getByLabel('Install Image Optimization by') ).toBeHidden(); - await expect( page.getByLabel('Install Otter Blocks') ).toBeHidden(); - }); + test.beforeEach( async ( { admin, requestUtils, page } ) => { + await deleteAllCharts( requestUtils ); + await admin.visitAdminPage( 'admin.php?page=visualizer' ); + page.setDefaultTimeout( 5000 ); + } ); + + test( 'chart selection on admin', async ( { admin, page } ) => { + await admin.visitAdminPage( 'admin.php?page=visualizer&vaction=addnew' ); + await page.waitForURL( '**/admin.php?page=visualizer&vaction=addnew' ); + await page.waitForSelector('h1:text("Visualizer")'); + + expect( await page.frameLocator('iframe').locator('.pro-upsell').count() ).toBe( 11 ); + + const proUpsellElements = await page.frameLocator('iframe').locator('a.pro-upsell').all(); + + for (const element of proUpsellElements) { + const href = await element.getAttribute('href'); + const searchParams = new URLSearchParams(href); + expect( searchParams.get('utm_campaign') ).toBe('charttypes'); + } + } ); + + test( 'chart settings on admin', async ( { admin, page } ) => { + await admin.visitAdminPage( 'admin.php?page=visualizer&vaction=addnew' ); + await page.waitForURL( '**/admin.php?page=visualizer&vaction=addnew' ); + await page.waitForSelector('h1:text("Visualizer")'); + await selectChartAdmin( page.frameLocator('iframe'), CHART_JS_LABELS.pie ); + + await expect( page.frameLocator('iframe').locator( '#viz-tabs' ) ).toBeVisible(); + + expect( await page.frameLocator('iframe').locator('#vz-chart-source .viz-group-title .dashicons-lock').count() ).toBe( 5 ); + + + const uploadFileUpsell = page.frameLocator('iframe').locator('#vz-chart-source .visualizer_source_csv .only-pro-inner a'); + let href = await uploadFileUpsell.getAttribute('href'); + let searchParams = new URLSearchParams(href); + expect( searchParams.get('utm_campaign') ).toBe('import-file'); + + const remoteImportUpsell = page.frameLocator('iframe').locator('#vz-chart-source .visualizer_source_json .only-pro-inner a').first(); + href = await remoteImportUpsell.getAttribute('href'); + searchParams = new URLSearchParams(href); + expect( searchParams.get('utm_campaign') ).toBe('import-url'); + + const otherChartUpsell = page.frameLocator('iframe').locator('#vz-chart-source .viz-import-from-other .only-pro-inner a'); + href = await otherChartUpsell.getAttribute('href'); + searchParams = new URLSearchParams(href); + expect( searchParams.get('utm_campaign') ).toBe('import-chart'); + + const wpImportUpsell = page.frameLocator('iframe').locator('#vz-chart-source .visualizer_source_query_wp .only-pro-inner a'); + href = await wpImportUpsell.getAttribute('href'); + searchParams = new URLSearchParams(href); + expect( searchParams.get('utm_campaign') ).toBe('import-wp'); + await page.frameLocator('iframe').getByRole('heading', { name: /Import from WordPress/ }).click(); + await expect(page.frameLocator('iframe').locator('#vz-chart-source')).toContainText('Upgrade to PRO to activate this feature!'); + + const dbImportUpsell = page.frameLocator('iframe').locator('#vz-chart-source .visualizer_source_query .only-pro-inner a'); + href = await dbImportUpsell.getAttribute('href'); + searchParams = new URLSearchParams(href); + expect( searchParams.get('utm_campaign') ).toBe('db-query'); + + await page.frameLocator('iframe').getByRole('heading', { name: /Import from database/ }).click(); + await expect(page.frameLocator('iframe').locator('#vz-db-wizard')).toContainText('Upgrade to Plus plan to activate this feature!'); + await expect(page.frameLocator('iframe').locator('#vz-db-wizard')).toContainText('Upgrade Now'); + + await page.frameLocator('iframe').getByRole('link', { name: 'Settings' }).click(); + + const dataFilterConfigurationUpsell = page.frameLocator('iframe').locator('#vz-data-controls .only-pro-inner a'); + href = await dataFilterConfigurationUpsell.getAttribute('href'); + searchParams = new URLSearchParams(href); + expect( searchParams.get('utm_campaign') ).toBe('data-filter-configuration'); + + const frontendActionsUpsell = page.frameLocator('iframe').locator('#vz-frontend-actions .only-pro-inner a'); + href = await frontendActionsUpsell.getAttribute('href'); + searchParams = new URLSearchParams(href); + expect( searchParams.get('utm_campaign') ).toBe('frontend-actions'); + + const chartPermissionsUpsell = page.frameLocator('iframe').locator('#vz-permissions .only-pro-inner a'); + href = await chartPermissionsUpsell.getAttribute('href'); + searchParams = new URLSearchParams(href); + expect( searchParams.get('utm_campaign') ).toBe('chart-permissions'); + await page.frameLocator('iframe').getByRole('heading', { name: /Permissions/ }).click(); + await expect(page.frameLocator('iframe').locator('#vz-db-wizard')).toContainText('Upgrade to Plus plan to activate this feature!'); + await expect(page.frameLocator('iframe').locator('#vz-db-wizard')).toContainText('Upgrade Now'); + }); + + test( 'featured tab in Install Plugin (SDK)', async ( { admin, page } ) => { + await admin.visitAdminPage( 'plugin-install.php' ); + + // Those should be visible only when a PRO product is installed. + await expect( page.getByText('Image Optimization by Optimole') ).toBeHidden(); + await expect( page.locator('#the-list div').filter({ hasText: 'Otter Blocks' }).nth(1) ).toBeHidden(); + + await expect( page.getByLabel('Install Image Optimization by') ).toBeHidden(); + await expect( page.getByLabel('Install Otter Blocks') ).toBeHidden(); + }); + + test( 'pro chart license lock', async ( { admin, page } ) => { + await admin.visitAdminPage('admin.php?page=visualizer'); + await page.waitForURL('**/admin.php?page=visualizer'); + + // Check if the popup HTML is present + const popupSelector = '.vizualizer-renew-notice-popup'; + const popup = await page.$(popupSelector); + expect(popup).not.toBeNull(); + + const heading = await page.$('h1.vizualizer-renew-notice-heading'); + expect(heading).not.toBeNull(); + + const message = await page.$('p.vizualizer-renew-notice-message'); + expect(message).not.toBeNull(); + + const renewButton = await page.$('button.vizualizer-renew-notice-renew-button'); + expect(renewButton).not.toBeNull(); + + const activateButton = await page.$('button.vizualizer-renew-notice-activate-button'); + expect(activateButton).not.toBeNull(); + + const closeButton = await page.$('button.vizualizer-renew-notice-close-icon'); + expect(closeButton).not.toBeNull(); + }); + } ); From f32f8723f29b116cd30d836ce0e14effc37a2d61 Mon Sep 17 00:00:00 2001 From: "themeisle[bot]" <> Date: Thu, 23 May 2024 13:49:24 +0000 Subject: [PATCH 16/16] chore(release): 3.11.2 ##### [Version 3.11.2](https://github.com/Codeinwp/visualizer/compare/v3.11.1...v3.11.2) (2024-05-23) - Fixed Visualizer block widget not loading - Improved the popup rendering - Enhanced security --- CHANGELOG.md | 6 ++++++ classes/Visualizer/Plugin.php | 2 +- css/media.css | 2 +- index.php | 2 +- package.json | 2 +- readme.txt | 9 +++++++++ 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f2112511..51d1a7242 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +##### [Version 3.11.2](https://github.com/Codeinwp/visualizer/compare/v3.11.1...v3.11.2) (2024-05-23) + +- Fixed Visualizer block widget not loading +- Improved the popup rendering +- Enhanced security + ##### [Version 3.11.1](https://github.com/Codeinwp/visualizer/compare/v3.11.0...v3.11.1) (2024-05-14) - Fixed the permissions of the plans diff --git a/classes/Visualizer/Plugin.php b/classes/Visualizer/Plugin.php index 3f20628a0..af9ab7a30 100644 --- a/classes/Visualizer/Plugin.php +++ b/classes/Visualizer/Plugin.php @@ -28,7 +28,7 @@ class Visualizer_Plugin { const NAME = 'visualizer'; - const VERSION = '3.11.1'; + const VERSION = '3.11.2'; // custom post types const CPT_VISUALIZER = 'visualizer'; diff --git a/css/media.css b/css/media.css index 9ce24b9b1..806f2dedb 100644 --- a/css/media.css +++ b/css/media.css @@ -1,5 +1,5 @@ /* - Version: 3.11.1 + Version: 3.11.2 */ #visualizer-library-view { padding: 30px 10px 10px 30px; diff --git a/index.php b/index.php index 56d86e6cb..cf5750c1b 100644 --- a/index.php +++ b/index.php @@ -3,7 +3,7 @@ Plugin Name: Visualizer: Tables and Charts for WordPress Plugin URI: https://themeisle.com/plugins/visualizer-charts-and-graphs/ Description: Effortlessly create and embed responsive charts and tables with Visualizer, a powerful WordPress plugin that enhances data presentation from multiple sources. - Version: 3.11.1 + Version: 3.11.2 Author: Themeisle Author URI: http://themeisle.com Requires at least: 5.2 diff --git a/package.json b/package.json index 476d19d1c..71ae10712 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "visualizer", - "version": "3.11.1", + "version": "3.11.2", "description": "Visualizer Lite", "repository": { "type": "git", diff --git a/readme.txt b/readme.txt index b29e3a214..e782ee453 100755 --- a/readme.txt +++ b/readme.txt @@ -226,6 +226,15 @@ Pay attention that to turn your shortcodes into graphs, your theme has to have ` == Changelog == +##### [Version 3.11.2](https://github.com/Codeinwp/visualizer/compare/v3.11.1...v3.11.2) (2024-05-23) + +- Fixed Visualizer block widget not loading +- Improved the popup rendering +- Enhanced security + + + + ##### [Version 3.11.1](https://github.com/Codeinwp/visualizer/compare/v3.11.0...v3.11.1) (2024-05-14) - Fixed the permissions of the plans