Plugin Directory

source: visualizer/trunk/classes/Visualizer/Module/Admin.php

Last change on this file was 3301363, checked in by themeisle, 6 months ago

Update to version 3.11.11 from GitHub

File size: 44.2 KB
Line 
1<?php
2// +----------------------------------------------------------------------+
3// | Copyright 2013  Madpixels  (email : visualizer@madpixels.net)        |
4// +----------------------------------------------------------------------+
5// | This program is free software; you can redistribute it and/or modify |
6// | it under the terms of the GNU General Public License, version 2, as  |
7// | published by the Free Software Foundation.                           |
8// |                                                                      |
9// | This program is distributed in the hope that it will be useful,      |
10// | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
11// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
12// | GNU General Public License for more details.                         |
13// |                                                                      |
14// | You should have received a copy of the GNU General Public License    |
15// | along with this program; if not, write to the Free Software          |
16// | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,               |
17// | MA 02110-1301 USA                                                    |
18// +----------------------------------------------------------------------+
19// | Author: Eugene Manuilov <eugene@manuilov.org>                        |
20// +----------------------------------------------------------------------+
21/**
22 * The module for all admin stuff.
23 *
24 * @category Visualizer
25 * @package Module
26 *
27 * @since 1.0.0
28 */
29class Visualizer_Module_Admin extends Visualizer_Module {
30
31        const NAME = __CLASS__;
32
33        /**
34         * Library page suffix.
35         *
36         * @since 1.0.0
37         *
38         * @access private
39         * @var string
40         */
41        private $_libraryPage;
42
43        /**
44         * Support page suffix.
45         *
46         * @access private
47         * @var string
48         */
49        private $_supportPage;
50
51        /**
52         * Constructor.
53         *
54         * @since 1.0.0
55         *
56         * @access public
57         *
58         * @param Visualizer_Plugin $plugin The instance of the plugin.
59         */
60        public function __construct( Visualizer_Plugin $plugin ) {
61                parent::__construct( $plugin );
62                $this->_addAction( 'load-post.php', 'enqueueMediaScripts' );
63                $this->_addAction( 'load-post-new.php', 'enqueueMediaScripts' );
64                $this->_addAction( 'enqueue_block_editor_assets', 'enqueueMediaScripts' );
65                $this->_addAction( 'admin_footer', 'renderTemplates' );
66                $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 0 );
67                $this->_addAction( 'admin_enqueue_scripts', 'enqueue_support_page' );
68                $this->_addAction( 'admin_menu', 'registerAdminMenu' );
69                $this->_addFilter( 'media_view_strings', 'setupMediaViewStrings' );
70                $this->_addFilter( 'plugin_action_links', 'getPluginActionLinks', 10, 2 );
71                $this->_addFilter( 'plugin_row_meta', 'getPluginMetaLinks', 10, 2 );
72                $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
73                $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
74                $this->_addFilter( 'themeisle_sdk_blackfriday_data', 'add_black_friday_data' );
75
76                // screen pagination
77                $this->_addFilter( 'set-screen-option', 'setScreenOptions', 10, 3 );
78
79                // revision support.
80                $this->_addFilter( 'wp_revisions_to_keep', 'limitRevisions', null, 10, 2 );
81                $this->_addAction( '_wp_put_post_revision', 'addRevision', null, 10, 1 );
82                $this->_addAction( 'wp_restore_post_revision', 'restoreRevision', null, 10, 2 );
83
84                $this->_addAction( 'visualizer_chart_schedules_spl', 'addSplChartSchedules', null, 10, 3 );
85
86                $this->_addAction( 'admin_init', 'init' );
87
88                $this->_addAction( 'visualizer_chart_languages', 'addMultilingualSupport' );
89
90                $this->_addFilter( 'admin_footer_text', 'render_review_notice' );
91
92                if ( ! defined( 'TI_CYPRESS_TESTING' ) ) {
93                        $this->_addFilter( 'themeisle-sdk/survey/' . VISUALIZER_DIRNAME, 'get_survey_metadata', 10, 2 );
94                }
95
96                if ( defined( 'TI_CYPRESS_TESTING' ) ) {
97                        $this->load_cypress_hooks();
98                }
99
100        }
101        /**
102         * Display review notice.
103         */
104        public function render_review_notice( $footer_text ) {
105                $current_screen = get_current_screen();
106
107                $visualizer_page_ids = ['toplevel_page_visualizer', 'visualizer_page_viz-support', 'visualizer_page_ti-about-visualizer' ];
108
109                if ( ! empty( $current_screen ) && isset( $current_screen->id ) ) {
110                        foreach ( $visualizer_page_ids as $page_to_check ) {
111                                if ( strpos( $current_screen->id, $page_to_check ) !== false ) {
112                                        $footer_text = sprintf(
113                                                // translators: %1$s - the name of the plugin (Visualizer), %2$s - message (You can help us by leaving a), %3$s - HTML entity code.
114                                                __( 'Enjoying %1$s? %2$s %3$s rating. Thank you for being so supportive!', 'visualizer' ),
115                                                '<b>Visualizer</b>',
116                                                esc_html__( 'You can help us by leaving a', 'visualizer' ),
117                                                '<a href="https://wordpress.org/support/plugin/visualizer/reviews/" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
118                                        );
119                                        break;
120                                }
121                        }
122                }
123
124                return $footer_text;
125        }
126
127
128        /**
129         * Define the hooks that are needed for cypress.
130         *
131         * @since   3.4.0
132         * @access  private
133         */
134        private function load_cypress_hooks() {
135                // all charts should load on the same page without pagination.
136                add_filter(
137                        'visualizer_query_args', function( $args ) {
138                                $args['posts_per_page'] = 20;
139                                return $args;
140                        }, 10, 1
141                );
142        }
143
144        /**
145         * Add disabled `optgroup` schedules to the drop downs.
146         *
147         * @since ?
148         *
149         * @access public
150         *
151         * @param string $feature The feature for which to add schedules.
152         * @param int    $chart_id The chart ID.
153         * @param int    $plan The plan number.
154         */
155        public function addSplChartSchedules( $feature, $chart_id, $plan ) {
156                if ( apply_filters( 'visualizer_is_business', false ) ) {
157                        return;
158                }
159
160                $is_new_personal = apply_filters( 'visualizer_is_new_personal', false );
161
162                $hours = array(
163                        '0.16' => __( '10 minutes', 'visualizer' ),
164                        '1'    => __( 'Each hour', 'visualizer' ),
165                        '12'   => __( 'Each 12 hours', 'visualizer' ),
166                        '24'   => __( 'Each day', 'visualizer' ),
167                        '72'   => __( 'Each 3 days', 'visualizer' ),
168                );
169
170                switch ( $feature ) {
171                        case 'json':
172                        case 'csv':
173                                // no more schedules if pro is already active.
174                                if ( Visualizer_Module::is_pro() && ! $is_new_personal ) {
175                                        return;
176                                }
177                                break;
178                        case 'wp':
179                                // fall-through.
180                        case 'db':
181                                break;
182                        default:
183                                return;
184                }
185
186                echo '<optgroup disabled label="' . __( 'Upgrade required', 'visualizer' ) . '">';
187                foreach ( $hours as $hour => $desc ) {
188                        echo '<option disabled>' . $desc . '</option>';
189                }
190                echo '</optgroup>';
191        }
192
193        /**
194         * No limits on revisions.
195         */
196        public function limitRevisions( $num, $post ) {
197                if ( Visualizer_Plugin::CPT_VISUALIZER === $post->post_type ) {
198                        return -1;
199                }
200                return $num;
201        }
202
203        /**
204         * Add a revision.
205         */
206        public function addRevision( $revision_id ) {
207                $parent_id = wp_is_post_revision( $revision_id );
208                if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $parent_id ) ) {
209                        // add the meta data to this revision.
210                        $meta = get_post_meta( $parent_id, '', true );
211
212                        if ( $meta ) {
213                                foreach ( $meta as $key => $value ) {
214                                        if ( 0 === strpos( $key, 'visualizer' ) ) {
215                                                add_metadata( 'post', $revision_id, $key, maybe_unserialize( $value[0] ) );
216                                        }
217                                }
218                        }
219                }
220        }
221
222        /**
223         * Restore a revision.
224         */
225        public function restoreRevision( $post_id, $revision_id ) {
226                if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $post_id ) ) {
227                        // get the meta information from the revision.
228                        $meta = get_metadata( 'post', $revision_id, '', true );
229
230                        // delete all meta information from the post before adding.
231                        $post_meta = get_post_meta( $post_id, '', true );
232                        if ( $post_meta ) {
233                                foreach ( $meta as $key => $value ) {
234                                        if ( 0 === strpos( $key, 'visualizer' ) ) {
235                                                delete_post_meta( $post_id, $key );
236                                        }
237                                }
238                        }
239
240                        if ( $meta ) {
241                                foreach ( $meta as $key => $value ) {
242                                        if ( 0 === strpos( $key, 'visualizer' ) ) {
243                                                add_post_meta( $post_id, $key, maybe_unserialize( $value[0] ) );
244                                        }
245                                }
246                        }
247                }
248        }
249
250        /**
251         * Admin init.
252         *
253         * @access  public
254         */
255        public function init() {
256                // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
257                if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
258                        $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
259                        $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
260                        $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
261                        $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
262                }
263        }
264
265        /**
266         * Add the strings required for the TinyMCE buttons for the classic block (not the classic editor).
267         *
268         * @since   ?
269         * @access  friendly
270         */
271        function get_strings_for_block( $settings ) {
272                $class = new Visualizer_Module_Language();
273                $strings         = $class->get_strings();
274                $array = array( 'visualizer_tinymce_plugin' => json_encode( $strings ) );
275                return array_merge( $settings, $array );
276        }
277
278        /**
279         * Load plugin translation for - TinyMCE API
280         *
281         * @access  public
282         * @param   array $arr  The tinymce_lang array.
283         * @return  array
284         */
285        public function add_tinymce_lang( $arr ) {
286                $ui_lang = VISUALIZER_ABSPATH . '/classes/Visualizer/Module/Language.php';
287                $ui_lang = apply_filters( 'visualizer_ui_lang_filter', $ui_lang );
288                $arr[] = $ui_lang;
289                return $arr;
290        }
291
292        /**
293         * Load custom js options - TinyMCE API
294         *
295         * @access  public
296         * @param   array $plugin_array  The tinymce plugin array.
297         * @return  array
298         */
299        public function tinymce_plugin( $plugin_array ) {
300                $plugin_array['visualizer_mce_button'] = VISUALIZER_ABSURL . 'js/mce.js';
301                return $plugin_array;
302        }
303
304        /**
305         * Register new button in the editor
306         *
307         * @access  public
308         * @param   array $buttons  The tinymce buttons array.
309         * @return  array
310         */
311        public function register_mce_button( $buttons ) {
312                array_push( $buttons, 'visualizer_mce_button' );
313                return $buttons;
314        }
315
316        /**
317         * Whether to show the feedback review or not.
318         *
319         * @access public
320         */
321        public function feedbackReviewTrigger( $dumb ) {
322                $query  = new WP_Query(
323                        array(
324                                'posts_per_page'        => 50,
325                                'post_type'             => Visualizer_Plugin::CPT_VISUALIZER,
326                                'fields'                => 'ids',
327                                'update_post_meta_cache' => false,
328                                'update_post_term_cache' => false,
329                        )
330                );
331
332                if ( $query->have_posts() && $query->post_count > 0 ) {
333                        return true;
334                }
335                return false;
336        }
337
338        /**
339         * Enqueues media scripts and styles.
340         *
341         * @since 1.0.0
342         * @uses wp_enqueue_style To enqueue style file.
343         * @uses wp_enqueue_script To enqueue script file.
344         *
345         * @access public
346         */
347        public function enqueueMediaScripts() {
348                global $typenow;
349                global $current_screen;
350
351                if ( post_type_supports( $typenow, 'editor' ) || $current_screen->id === 'widgets' || $current_screen->id === 'customize' ) {
352                        wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
353
354                        // Load all the assets for the different libraries we support.
355                        $deps   = array(
356                                Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
357                                Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
358                        );
359
360                        wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
361                        wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
362                        wp_enqueue_script( 'visualizer-media-controller', VISUALIZER_ABSURL . 'js/media/controller.js', array( 'visualizer-media-collection' ), Visualizer_Plugin::VERSION, true );
363                        wp_enqueue_script( 'visualizer-media-view', VISUALIZER_ABSURL . 'js/media/view.js', array( 'visualizer-media-controller' ), Visualizer_Plugin::VERSION, true );
364                        wp_localize_script(
365                                'visualizer-media-view',
366                                'visualizer',
367                                array(
368                                        'i10n' => array(
369                                                'insert'    => __( 'Insert', 'visualizer' ),
370                                        ),
371                                )
372                        );
373                        wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
374                        wp_enqueue_script( 'visualizer-media', VISUALIZER_ABSURL . 'js/media.js', array( 'visualizer-media-toolbar' ), Visualizer_Plugin::VERSION, true );
375                }
376        }
377
378        /**
379         * Extends media view strings with visualizer strings.
380         *
381         * @since 1.0.0
382         *
383         * @access public
384         *
385         * @param array $strings The array of media view strings.
386         *
387         * @return array The extended array of media view strings.
388         */
389        public function setupMediaViewStrings( $strings ) {
390                $chart_types = self::_getChartTypesLocalized( true, true, true );
391                $strings['visualizer'] = array(
392                        'actions'    => array(
393                                'get_charts'   => Visualizer_Plugin::ACTION_GET_CHARTS,
394                                'delete_chart' => Visualizer_Plugin::ACTION_DELETE_CHART,
395                        ),
396                        'controller' => array(
397                                'title' => esc_html__( 'Visualizations', 'visualizer' ),
398                        ),
399                        'routers'    => array(
400                                'library' => esc_html__( 'From Library', 'visualizer' ),
401                                'create'  => esc_html__( 'Create New', 'visualizer' ),
402                        ),
403                        'library'    => array(
404                                'filters' => $chart_types,
405                                'types'   => array_keys( $chart_types ),
406                        ),
407                        'nonce'      => wp_create_nonce(),
408                        'buildurl'   => esc_url( add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ) ),
409                );
410
411                return $strings;
412        }
413
414        /**
415         * Returns associated array of chart types and localized names.
416         *
417         * @since 1.0.0
418         *
419         * @static
420         * @access private
421         * @return array The associated array of chart types with localized names.
422         */
423        public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false, $where = null ) {
424                $additional = array();
425                if ( $add_select ) {
426                        $additional['select'] = array(
427                                'name'    => esc_html__( 'All', 'visualizer' ),
428                                'enabled' => true,
429                        );
430                }
431
432                $enabled = self::proFeaturesLocked();
433
434                $types = array_merge(
435                        $additional,
436                        array(
437                                'tabular' => array(
438                                        'name'    => esc_html__( 'Table', 'visualizer' ),
439                                        'enabled' => true,
440                                        'supports'  => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
441                                ),
442                                'pie'         => array(
443                                        'name'    => esc_html__( 'Pie/Donut', 'visualizer' ),
444                                        'enabled' => true,
445                                        'supports'  => array( 'Google Charts', 'ChartJS' ),
446                                ),
447                                'line'        => array(
448                                        'name'    => esc_html__( 'Line', 'visualizer' ),
449                                        'enabled' => true,
450                                        'supports'  => array( 'Google Charts', 'ChartJS' ),
451                                ),
452                                'bar'         => array(
453                                        'name'    => esc_html__( 'Bar', 'visualizer' ),
454                                        'enabled' => true,
455                                        'supports'  => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
456                                ),
457                                'area'        => array(
458                                        'name'    => esc_html__( 'Area', 'visualizer' ),
459                                        'enabled' => $enabled,
460                                        // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
461                                        'supports'  => array( 'Google Charts' ),
462                                        'demo_url'  => 'https://demo.themeisle.com/visualizer/area-chart/',
463                                ),
464                                'geo'         => array(
465                                        'name'    => esc_html__( 'Geo', 'visualizer' ),
466                                        'enabled' => $enabled,
467                                        'supports'  => array( 'Google Charts' ),
468                                        'demo_url'  => 'https://demo.themeisle.com/visualizer/geo-chart/',
469                                ),
470                                'column'      => array(
471                                        'name'    => esc_html__( 'Column', 'visualizer' ),
472                                        'enabled' => $enabled,
473                                        'supports'  => array( 'Google Charts', 'ChartJS' ),
474                                        'demo_url'  => 'https://demo.themeisle.com/visualizer/column-chart/',
475                                ),
476                                'bubble'         => array(
477                                        'name'    => esc_html__( 'Bubble', 'visualizer' ),
478                                        'enabled' => $enabled,
479                                        // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
480                                        'supports'  => array( 'Google Charts' ),
481                                        'demo_url'  => 'https://demo.themeisle.com/visualizer/bubble-chart/',
482                                ),
483                                'scatter'     => array(
484                                        'name'    => esc_html__( 'Scatter', 'visualizer' ),
485                                        'enabled' => $enabled,
486                                        'supports'  => array( 'Google Charts' ),
487                                        'demo_url'  => 'https://demo.themeisle.com/visualizer/scatter-chart/',
488                                ),
489                                'gauge'       => array(
490                                        'name'    => esc_html__( 'Gauge', 'visualizer' ),
491                                        'enabled' => $enabled,
492                                        'supports'  => array( 'Google Charts' ),
493                                        'demo_url'  => 'https://demo.themeisle.com/visualizer/gauge-chart/',
494                                ),
495                                'candlestick' => array(
496                                        'name'    => esc_html__( 'Candlestick', 'visualizer' ),
497                                        'enabled' => $enabled,
498                                        'supports'  => array( 'Google Charts' ),
499                                        'demo_url'  => 'https://demo.themeisle.com/visualizer/candlestick-chart/',
500                                ),
501                                // pro types
502                                'timeline'    => array(
503                                        'name'    => esc_html__( 'Timeline', 'visualizer' ),
504                                        'enabled' => false,
505                                        'supports'  => array( 'Google Charts', 'ChartJS' ),
506                                        'demo_url'  => 'https://demo.themeisle.com/visualizer/timeline-chart/',
507                                ),
508                                'combo'       => array(
509                                        'name'    => esc_html__( 'Combo', 'visualizer' ),
510                                        'enabled' => false,
511                                        'supports'  => array( 'Google Charts' ),
512                                        'demo_url'  => 'https://demo.themeisle.com/visualizer/combo-chart/',
513                                ),
514                                'polarArea'       => array(
515                                        'name'    => esc_html__( 'Polar Area', 'visualizer' ),
516                                        'enabled' => false,
517                                        'supports' => array( 'ChartJS' ),
518                                        'demo_url'  => 'https://demo.themeisle.com/visualizer/polar-area-chart/',
519                                ),
520                                'radar'       => array(
521                                        'name'    => esc_html__( 'Radar/Spider', 'visualizer' ),
522                                        'enabled' => false,
523                                        'supports' => array( 'ChartJS' ),
524                                        'demo_url'  => 'https://demo.themeisle.com/visualizer/radar-spider-chart/',
525                                ),
526                        )
527                );
528                $types = apply_filters( 'visualizer_pro_chart_types', $types );
529                if ( $enabledOnly ) {
530                        $filtered = array();
531                        foreach ( $types as $type => $array ) {
532                                if ( ! is_array( $array ) ) {
533                                        // support for old pro
534                                        $array  = array( 'enabled' => true, 'name' => $array );
535                                }
536                                // backward compatibility for PRO before v1.9.0
537                                if ( ! array_key_exists( 'supports', $array ) ) {
538                                        $array['supports'] = array( 'Google Charts' );
539                                }
540                                if ( ! $array['enabled'] ) {
541                                        continue;
542                                }
543                                $filtered[ $type ] = $array;
544                        }
545                        $types = $filtered;
546                }
547                if ( $get2Darray ) {
548                        $doubleD = array();
549                        foreach ( $types as $type => $array ) {
550                                if ( ! is_array( $array ) ) {
551                                        // support for old pro
552                                        $array  = array( 'enabled' => true, 'name' => $array );
553                                }
554                                // backward compatibility for PRO before v1.9.0
555                                if ( ! array_key_exists( 'supports', $array ) ) {
556                                        $array['supports'] = array( 'Google Charts' );
557                                }
558                                $doubleD[ $type ] = $array['name'];
559                        }
560                        $types = $doubleD;
561                }
562
563                return self::handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where );
564        }
565
566        /**
567         * Handle (soon-to-be) deprecated charts.
568         */
569        private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
570                $deprecated = array();
571
572                switch ( $where ) {
573                        case 'types':
574                                // fall-through
575                        case 'library':
576                                // if a user has a Gauge/Candlestick chart, then let them keep using it.
577                                if ( ! Visualizer_Module::is_pro() ) {
578                                        if ( ! self::hasChartType( 'gauge' ) ) {
579                                                if ( $get2Darray ) {
580                                                        $deprecated[]   = 'gauge';
581                                                } else {
582                                                        $types['gauge']['enabled'] = false;
583                                                }
584                                        }
585                                        if ( ! self::hasChartType( 'candlestick' ) ) {
586                                                if ( $get2Darray ) {
587                                                        $deprecated[]   = 'candlestick';
588                                                } else {
589                                                        $types['candlestick']['enabled'] = false;
590                                                }
591                                        }
592                                }
593                                break;
594                        default:
595                                // if a user has a Gauge/Candlestick chart, then let them keep using it.
596                                if ( ! Visualizer_Module::is_pro() ) {
597                                        if ( ! self::hasChartType( 'gauge' ) ) {
598                                                if ( $get2Darray ) {
599                                                        $deprecated[]   = 'gauge';
600                                                } else {
601                                                        $types['gauge']['enabled'] = false;
602                                                }
603                                        }
604                                        if ( ! self::hasChartType( 'candlestick' ) ) {
605                                                if ( $get2Darray ) {
606                                                        $deprecated[]   = 'candlestick';
607                                                } else {
608                                                        $types['candlestick']['enabled'] = false;
609                                                }
610                                        }
611                                }
612                }
613
614                if ( $deprecated ) {
615                        foreach ( $deprecated as $type ) {
616                                unset( $types[ $type ] );
617                        }
618                }
619
620                return $types;
621        }
622
623        /**
624         * Renders templates to use in media popup.
625         *
626         * @since 1.0.0
627         * @global string $pagenow The name of the current page.
628         *
629         * @access public
630         */
631        public function renderTemplates() {
632                global $pagenow;
633                if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
634                        return;
635                }
636                $render = new Visualizer_Render_Templates();
637                $render->render();
638        }
639
640        /**
641         * Enqueues library scripts and styles.
642         *
643         * @since 1.0.0
644         * @uses wp_enqueue_style() To enqueue library stylesheet.
645         * @uses wp_enqueue_script() To enqueue javascript file.
646         * @uses wp_enqueue_media() To enqueue media stuff.
647         *
648         * @access public
649         *
650         * @param string $suffix The current page suffix.
651         */
652        public function enqueueLibraryScripts( $suffix ) {
653                if ( $suffix !== $this->_libraryPage ) {
654                        return;
655                }
656
657                wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
658                $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
659                wp_enqueue_media();
660                wp_enqueue_script(
661                        'visualizer-library',
662                        VISUALIZER_ABSURL . 'js/library.js',
663                        array(
664                                'jquery',
665                                'media-views',
666                                'clipboard',
667                        ),
668                        Visualizer_Plugin::VERSION,
669                        true
670                );
671
672                wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
673
674                $query = $this->getQuery();
675                while ( $query->have_posts() ) {
676                        $chart = $query->next_post();
677                        $library = $this->load_chart_type( $chart->ID );
678                        if ( is_null( $library ) ) {
679                                continue;
680                        }
681                        wp_enqueue_script(
682                                "visualizer-render-$library",
683                                VISUALIZER_ABSURL . 'js/render-facade.js',
684                                apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
685                                Visualizer_Plugin::VERSION,
686                                true
687                        );
688                }
689
690                do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'library' );
691        }
692
693        /**
694         * Enqueue script for support page.
695         *
696         * @param string $hook_suffix Current hook.
697         */
698        public function enqueue_support_page( $hook_suffix ) {
699                if ( $this->_supportPage !== $hook_suffix ) {
700                        return;
701                }
702                do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'support' );
703        }
704
705        /**
706         * Adds visualizer tab for media upload tabs array.
707         *
708         * @since 1.0.0
709         *
710         * @access public
711         *
712         * @param array $tabs The array of media upload tabs.
713         *
714         * @return array Extended array of media upload tabs.
715         */
716        public function setupVisualizerTab( $tabs ) {
717                $tabs['visualizer'] = 'Visualizer';
718
719                return $tabs;
720        }
721
722        /**
723         * Registers admin menu for visualizer library.
724         *
725         * @since 1.0.0
726         *
727         * @access public
728         */
729        public function registerAdminMenu() {
730                $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
731
732                $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
733
734                add_submenu_page(
735                        Visualizer_Plugin::NAME,
736                        __( 'Chart Library', 'visualizer' ),
737                        __( 'Chart Library', 'visualizer' ),
738                        'edit_posts',
739                        'admin.php?page=' . Visualizer_Plugin::NAME
740                );
741                add_submenu_page(
742                        Visualizer_Plugin::NAME,
743                        __( 'Add New Chart', 'visualizer' ),
744                        __( 'Add New Chart', 'visualizer' ),
745                        'edit_posts',
746                        'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
747                );
748
749                $this->_supportPage = add_submenu_page(
750                        Visualizer_Plugin::NAME,
751                        __( 'Support', 'visualizer' ),
752                        __( 'Support', 'visualizer' ) . '<span class="dashicons dashicons-editor-help more-features-icon" style="width: 17px; height: 17px; margin-left: 4px; color: #ffca54; font-size: 17px; vertical-align: -3px;"></span>',
753                        'edit_posts',
754                        'viz-support',
755                        array( $this, 'renderSupportPage' )
756                );
757
758                remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
759
760                add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
761                add_action( 'admin_footer', array( $this, 'handleGetProSubMenu' ) );
762        }
763
764        /**
765         * Handle get pro plugin submenu.
766         */
767        public function handleGetProSubMenu() {
768                if ( ! Visualizer_Module::is_pro() ) {
769                        ?>
770                <style type="text/css">
771                        #toplevel_page_visualizer ul.wp-submenu li:last-child {
772                                background: #FF7E65;
773                                font-size: 14px;
774                                font-weight: 600;
775                                color: #fff;
776                        }
777                        #toplevel_page_visualizer ul.wp-submenu li:last-child > a > span {
778                                color: #fff !important;
779                        }
780                        #toplevel_page_visualizer ul.wp-submenu li:last-child > a:hover {
781                                box-shadow: inherit;
782                        }
783                </style>
784                        <?php
785                        if ( get_option( 'visualizer_fresh_install', false ) ) {
786                                ?>
787                        <style type="text/css">
788                                #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li {
789                                        display: none;
790                                }
791                        </style>
792                                <?php
793                        }
794                }
795        }
796
797        /**
798         * Adds the screen options for pagination.
799         */
800        function addScreenOptions() {
801                $screen = get_current_screen();
802
803                // bail if it's some other page.
804                if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
805                        return;
806                }
807
808                $args = array(
809                        'label' => __( 'Number of charts per page:', 'visualizer' ),
810                        'default' => 6,
811                        'option' => 'visualizer_library_per_page',
812                );
813                add_screen_option( 'per_page', $args );
814        }
815
816        /**
817         * Returns the screen option for pagination.
818         */
819        function setScreenOptions( $status, $option, $value ) {
820                if ( 'visualizer_library_per_page' === $option ) {
821                        return $value;
822                }
823        }
824
825        /**
826         * Adds the display filters to be used in the meta_query while displaying the charts.
827         */
828        private function getDisplayFilters( &$query_args ) {
829                $query  = array();
830                global $sitepress;
831                if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
832                        $current_lang = icl_get_current_language();
833                        if ( in_array( $current_lang, array( 'all', icl_get_default_language() ), true ) ) {
834                                $query[] = array(
835                                        'key'     => 'chart_lang',
836                                        'compare' => 'NOT EXISTS',
837                                );
838                        } else {
839                                $query[] = array(
840                                        'key'     => 'chart_lang',
841                                        'value'   => $current_lang,
842                                        'compare' => '=',
843                                );
844                        }
845                }
846
847                // add chart type filter to the query arguments
848                $type = filter_input( INPUT_GET, 'type' );
849                if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
850                        $query[] = array(
851                                'key'     => Visualizer_Plugin::CF_CHART_TYPE,
852                                'value'   => $type,
853                                'compare' => '=',
854                        );
855                }
856
857                // add chart library filter to the query arguments
858                $library = filter_input( INPUT_GET, 'library' );
859                if ( $library ) {
860                        $query[] = array(
861                                'key'     => Visualizer_Plugin::CF_CHART_LIBRARY,
862                                'value'   => $library,
863                                'compare' => '=',
864                        );
865                }
866
867                // add date filter to the query arguments
868                $date = filter_input( INPUT_GET, 'date' );
869                $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
870                if ( $date && in_array( $date, $possible, true ) ) {
871                        $query_args['date_query'] = array(
872                                'after' => "$date -1 day",
873                                'inclusive' => true,
874                        );
875                }
876
877                // add source filter to the query arguments
878                $source = filter_input( INPUT_GET, 'source' );
879                if ( $source ) {
880                        $source = ucwords( $source );
881                        $source = "Visualizer_Source_{$source}";
882                        $query[] = array(
883                                'key'     => Visualizer_Plugin::CF_SOURCE,
884                                'value'   => $source,
885                                'compare' => '=',
886                        );
887                }
888
889                $query_args['meta_query'] = $query;
890
891                $orderby = filter_input( INPUT_GET, 'orderby' );
892                $order = filter_input( INPUT_GET, 'order' );
893                if ( $orderby ) {
894                        $query_args['order_by'] = $orderby;
895                }
896                $query_args['order'] = empty( $order ) ? 'desc' : $order;
897        }
898
899        /**
900         * Get the instance of WP_Query that fetches the charts as per the given criteria.
901         */
902        private function getQuery() {
903                static $q;
904                if ( ! is_null( $q ) ) {
905                        return $q;
906                }
907
908                // get current page
909                $page = filter_input(
910                        INPUT_GET,
911                        'vpage',
912                        FILTER_VALIDATE_INT,
913                        array(
914                                'options' => array(
915                                        'min_range' => 1,
916                                        'default'   => 1,
917                                ),
918                        )
919                );
920
921                $per_page = 6;
922                $screen = get_current_screen();
923                if ( $screen ) {
924                        // retrieve the per_page option
925                        $screen_option = $screen->get_option( 'per_page', 'option' );
926                        // retrieve the value stored for the current user
927                        $user = get_current_user_id();
928                        $per_page = get_user_meta( $user, $screen_option, true );
929                        if ( empty( $per_page ) || $per_page < 1 ) {
930                                // nothing set, get the default value
931                                $per_page = $screen->get_option( 'per_page', 'default' );
932                        }
933                }
934
935                // the initial query arguments to fetch charts
936                $query_args = array(
937                        'post_type'      => Visualizer_Plugin::CPT_VISUALIZER,
938                        'posts_per_page' => $per_page,
939                        'paged'          => $page,
940                );
941
942                $this->getDisplayFilters( $query_args );
943
944                // Added by Ash/Upwork
945                $filterByMeta = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
946                if ( $filterByMeta ) {
947                        $query                    = array(
948                                'key'     => Visualizer_Plugin::CF_SETTINGS,
949                                'value'   => $filterByMeta,
950                                'compare' => 'LIKE',
951                        );
952                        $meta                     = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
953                        $meta[]                   = $query;
954                        $query_args['meta_query'] = $meta;
955                }
956                $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
957                return $q;
958        }
959
960        /**
961         * Renders support page.
962         *
963         * @since 3.3.0
964         *
965         * @access public
966         */
967        public function renderSupportPage() {
968                wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
969                include_once VISUALIZER_ABSPATH . '/templates/support.php';
970        }
971
972        /**
973         * Renders visualizer library page.
974         *
975         * @since 1.0.0
976         *
977         * @access public
978         */
979        public function renderLibraryPage() {
980                $charts = array();
981                $query = $this->getQuery();
982
983                // get current page
984                $page = filter_input(
985                        INPUT_GET,
986                        'vpage',
987                        FILTER_VALIDATE_INT,
988                        array(
989                                'options' => array(
990                                        'min_range' => 1,
991                                        'default'   => 1,
992                                ),
993                        )
994                );
995                // add chart type filter to the query arguments
996                $filter = filter_input( INPUT_GET, 'type' );
997                if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
998                        $filter = 'all';
999                }
1000
1001                $css        = '';
1002                while ( $query->have_posts() ) {
1003                        $chart = $query->next_post();
1004
1005                        // if the user has updated a chart and instead of saving it, has closed the modal. If the user refreshes, they should get the original chart.
1006                        $chart = $this->handleExistingRevisions( $chart->ID, $chart );
1007                        // refresh a "live" db query chart.
1008                        $chart = apply_filters( 'visualizer_schedule_refresh_chart', $chart, $chart->ID, false );
1009
1010                        $type   = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
1011
1012                        // fetch and update settings
1013                        $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
1014
1015                        $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
1016                        if ( ! empty( $atts['settings'] ) ) {
1017                                $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
1018                        }
1019
1020                        if ( $settings ) {
1021                                unset( $settings['height'], $settings['width'], $settings['chartArea'] );
1022                        }
1023
1024                        $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
1025                        $data   = self::get_chart_data( $chart, $type );
1026
1027                        // Set default setting series when add manual chart data - Only during first creation.
1028                        if ( isset( $settings['series'] ) && ! empty( $series ) ) {
1029                                $count_series = count( $series ) - count( $settings['series'] );
1030                                if ( $count_series > 1 ) {
1031                                        $clone_last_series = end( $settings['series'] );
1032                                        $clone_last_series = array_fill_keys( array_keys( $clone_last_series ), '' );
1033                                        foreach ( range( 1, $count_series ) as $item ) {
1034                                                $settings['series'][] = $clone_last_series;
1035                                        }
1036                                }
1037                        }
1038
1039                        $library = $this->load_chart_type( $chart->ID );
1040
1041                        $id         = 'visualizer-' . $chart->ID;
1042                        $arguments  = $this->get_inline_custom_css( $id, $settings );
1043                        if ( ! empty( $arguments ) ) {
1044                                $css        .= $arguments[0];
1045                                $settings   = $arguments[1];
1046                        }
1047
1048                        if ( isset( $settings['controls']['ui']['labelStacking'] ) ) {
1049                                unset( $settings['controls']['ui']['labelStacking'] );
1050                        }
1051                        if ( isset( $settings['controls']['ui']['orientation'] ) ) {
1052                                unset( $settings['controls']['ui']['orientation'] );
1053                        }
1054
1055                        // add chart to the array
1056                        $charts[ $id ] = array(
1057                                'id'       => $chart->ID,
1058                                'type'     => $type,
1059                                'series'   => $series,
1060                                'settings' => $settings,
1061                                'data'     => $data,
1062                                'library'  => $library,
1063                        );
1064                }
1065                // enqueue charts array
1066                $ajaxurl = admin_url( 'admin-ajax.php' );
1067
1068                wp_localize_script(
1069                        'visualizer-library',
1070                        'visualizer',
1071                        array(
1072                                'language'  => $this->get_language(),
1073                                'map_api_key' => get_option( 'visualizer-map-api-key' ),
1074                                'charts' => $charts,
1075                                'urls'   => array(
1076                                        'base'   => esc_url( add_query_arg( array( 'vpage' => false, 'vaction' => false ) ) ),
1077                                        'create' => esc_url(
1078                                                add_query_arg(
1079                                                        array(
1080                                                                'action'  => Visualizer_Plugin::ACTION_CREATE_CHART,
1081                                                                'library' => 'yes',
1082                                                                'type'      => isset( $_GET['type'] ) ? $_GET['type'] : '',
1083                                                                'chart-library'      => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
1084                                                                'vaction' => false,
1085                                                        ),
1086                                                        $ajaxurl
1087                                                )
1088                                        ),
1089                                        'edit'   => esc_url(
1090                                                add_query_arg(
1091                                                        array(
1092                                                                'action'  => Visualizer_Plugin::ACTION_EDIT_CHART,
1093                                                                'library' => 'yes',
1094                                                                'vaction' => false,
1095                                                        ),
1096                                                        $ajaxurl
1097                                                )
1098                                        ),
1099                                ),
1100                                'page_type' => 'library',
1101                                'is_front'  => false,
1102                                'i10n'          => array(
1103                                        'copied'        => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1104                                        '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' ),
1105                                ),
1106                                'is_pro_user' => Visualizer_Module::is_pro(),
1107                        )
1108                );
1109                // render library page
1110                $render             = new Visualizer_Render_Library();
1111                $render->charts     = $charts;
1112                $render->type       = $filter;
1113                $render->types      = self::_getChartTypesLocalized( false, false, false, true );
1114                $render->custom_css     = $css;
1115                $render->pagination = paginate_links(
1116                        array(
1117                                'base'    => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
1118                                'format'  => '',
1119                                'current' => $page,
1120                                'total'   => $query->max_num_pages,
1121                                'type'    => 'array',
1122                        )
1123                );
1124
1125                $render->render();
1126        }
1127
1128        /**
1129         * Updates the plugin's action links, which will be rendered at the plugins table.
1130         *
1131         * @since 1.0.0
1132         *
1133         * @access public
1134         *
1135         * @param array  $links The array of original action links.
1136         * @param string $file The plugin basename.
1137         *
1138         * @return array Updated array of action links.
1139         */
1140        public function getPluginActionLinks( $links, $file ) {
1141                if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
1142                        array_unshift(
1143                                $links,
1144                                sprintf(
1145                                        '<a href="%s">%s</a>',
1146                                        admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
1147                                        esc_html__( 'Library', 'visualizer' )
1148                                )
1149                        );
1150                }
1151
1152                return $links;
1153        }
1154
1155        /**
1156         * Updates the plugin's meta links, which will be rendered at the plugins table.
1157         *
1158         * @since 1.0.0
1159         *
1160         * @access public
1161         *
1162         * @param array  $plugin_meta The array of a plugin meta links.
1163         * @param string $plugin_file The plugin's basename.
1164         *
1165         * @return array Updated array of plugin meta links.
1166         */
1167        public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
1168                if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
1169                        // knowledge base link
1170                        $plugin_meta[] = sprintf(
1171                                '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1172                                esc_html__( 'Docs', 'visualizer' )
1173                        );
1174                        // flattr link
1175                        $plugin_meta[] = sprintf(
1176                                '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
1177                                esc_html__( 'Get Visualizer Pro', 'visualizer' )
1178                        );
1179                }
1180
1181                return $plugin_meta;
1182        }
1183
1184        /**
1185         * If check is existing user.
1186         *
1187         * @return bool Default false
1188         */
1189        public static function proFeaturesLocked() {
1190                if ( Visualizer_Module::is_pro() ) {
1191                        return true;
1192                }
1193                return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1194        }
1195
1196        /**
1197         * Multilingual Support.
1198         *
1199         * @param int $chart_id Chart ID.
1200         * @return bool Default false
1201         */
1202        public function addMultilingualSupport( $chart_id ) {
1203                global $sitepress;
1204                if ( Visualizer_Module::is_pro() ) {
1205                        return;
1206                }
1207                if ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) {
1208                        $language     = icl_get_languages();
1209                        $current_lang = icl_get_current_language();
1210                        $default_lang = icl_get_default_language();
1211                        $post_info    = wpml_get_language_information( null, $chart_id );
1212                        $translations = array();
1213                        if ( ! empty( $post_info ) && ( $default_lang === $post_info['language_code'] ) ) {
1214                                $trid         = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
1215                                $translations = $sitepress->get_element_translations( $trid );
1216                        }
1217                        if ( empty( $translations ) ) {
1218                                return;
1219                        }
1220                        ?>
1221                        <hr><div class="visualizer-languages-list only-pro">
1222                                <?php
1223                                foreach ( $language as $lang ) {
1224                                        $lang_code = $lang['code'];
1225                                        if ( $current_lang !== $lang_code ) {
1226                                                ?>
1227                                                <a href="javascript:;">
1228                                                        <img src="<?php echo esc_url( $lang['country_flag_url'] ); ?>" alt="<?php echo esc_attr( $lang['translated_name'] ); ?>">
1229                                                </a>
1230                                                <?php
1231                                        }
1232                                }
1233                                ?>
1234                                <a href="<?php echo tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'wpml-support', 'visualizer_render_char' ); ?>"target="_blank"><?php esc_html_e( 'Upgrade to PRO to active this translation for charts', 'visualizer' ); ?></a>
1235                        </div>
1236                        <?php
1237                }
1238        }
1239
1240        /**
1241         * Check chart is enabled or not.
1242         *
1243         * @param string $type Chart ID.
1244         *
1245         * @return bool Default false
1246         */
1247        public static function checkChartStatus( $type ) {
1248                $types = self::_getChartTypesLocalized( false, false, false, true );
1249                if ( isset( $types[ $type ] ) ) {
1250                        return ! empty( $types[ $type ]['enabled'] );
1251                }
1252                return false;
1253        }
1254
1255        /**
1256         * Get the survey metadata.
1257         *
1258         * @param array  $data The data for survey in Formbricks format.
1259         * @param string $page_slug The slug of the loaded page.
1260         *
1261         * @return array The survey metadata.
1262         */
1263        public function get_survey_metadata( $data, $page_slug ) {
1264                $install_date        = get_option( 'visualizer_install', time() );
1265                $install_days_number = intval( ( time() - $install_date ) / DAY_IN_SECONDS );
1266
1267                $license_status = apply_filters( 'product_visualizer_license_status', 'invalid' );
1268                $license_plan   = apply_filters( 'product_visualizer_license_plan', false );
1269                $license_key    = apply_filters( 'product_visualizer_license_key', false );
1270
1271                $plugin_data    = get_plugin_data( VISUALIZER_BASEFILE, false, false );
1272                $plugin_version = '';
1273
1274                if ( ! empty( $plugin_data['Version'] ) ) {
1275                        $plugin_version = $plugin_data['Version'];
1276                }
1277
1278                $count_charts_cache_key = 'visualizer_count_charts';
1279                $charts_number          = get_transient( $count_charts_cache_key );
1280
1281                if ( false === $charts_number ) {
1282                        $charts_number = $this->count_charts( 100 );
1283                        set_transient( $count_charts_cache_key, $charts_number, 100 === $charts_number ? WEEK_IN_SECONDS : 6 * HOUR_IN_SECONDS );
1284                } else {
1285                        $charts_number = strval( $charts_number );
1286                }
1287
1288                $data = array(
1289                        'environmentId' => 'cltef8cut1s7wyyfxy3rlxzs5',
1290                        'attributes' => array(
1291                                'free_version'        => $plugin_version,
1292                                'pro_version'         => defined( 'VISUALIZER_PRO_VERSION' ) ? VISUALIZER_PRO_VERSION : '',
1293                                'license_status'      => $license_status,
1294                                'install_days_number' => $install_days_number,
1295                                'charts_number'       => $charts_number,
1296                        ),
1297                );
1298
1299                if ( ! empty( $license_plan ) ) {
1300                        $data['attributes']['plan'] = $license_plan;
1301                }
1302
1303                if ( ! empty( $license_key ) ) {
1304                        $data['attributes']['license_key'] = apply_filters( 'themeisle_sdk_secret_masking', $license_key );
1305                }
1306
1307                return $data;
1308        }
1309
1310        /**
1311         * Count the charts.
1312         *
1313         * @param int $limit The count limit (optional).
1314         *
1315         * @return int The number of charts.
1316         */
1317        public function count_charts( $limit = -1 ) {
1318                $args = array(
1319                        'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
1320                        'post_status' => 'publish',
1321                        'posts_per_page' => $limit,
1322                        'fields' => 'ids',
1323                );
1324
1325                $query = new WP_Query( $args);
1326                return $query->post_count;
1327        }
1328
1329        /**
1330         * Set the black friday data.
1331         *
1332         * @param array $configs The configuration array for the loaded products.
1333         * @return array
1334         */
1335        public function add_black_friday_data( $configs ) {
1336                $config = $configs['default'];
1337
1338                // translators: %1$s - HTML tag, %2$s - discount, %3$s - HTML tag, %4$s - product name.
1339                $message_template = __( 'Our biggest sale of the year: %1$sup to %2$s OFF%3$s on %4$s. Don\'t miss this limited-time offer.', 'visualizer' );
1340                $product_label    = 'Visualizer';
1341                $discount         = '70%';
1342
1343                $plan    = apply_filters( 'product_visualizer_license_plan', 0 );
1344                $license = apply_filters( 'product_visualizer_license_key', false );
1345                $is_pro  = 0 < $plan;
1346
1347                if ( $is_pro ) {
1348                        // translators: %1$s - HTML tag, %2$s - discount, %3$s - HTML tag, %4$s - product name.
1349                        $message_template = __( 'Get %1$sup to %2$s off%3$s when you upgrade your %4$s plan or renew early.', 'visualizer' );
1350                        $product_label    = 'Visualizer Pro';
1351                        $discount         = '30%';
1352                }
1353
1354                $product_label = sprintf( '<strong>%s</strong>', $product_label );
1355                $url_params    = array(
1356                        'utm_term' => $is_pro ? 'plan-' . $plan : 'free',
1357                        'lkey'     => ! empty( $license ) ? $license : false,
1358                );
1359
1360                $config['message']  = sprintf( $message_template, '<strong>', $discount, '</strong>', $product_label );
1361                $config['sale_url'] = add_query_arg(
1362                        $url_params,
1363                        tsdk_translate_link( tsdk_utmify( 'https://themeisle.link/vizualizer-bf', 'bfcm', 'visualizer' ) )
1364                );
1365
1366                $configs[ VISUALIZER_DIRNAME ] = $config;
1367
1368                return $configs;
1369        }
1370}
Note: See TracBrowser for help on using the repository browser.