PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.3.4
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.3.4
4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 3.10.4 All 148 releases
visualizer / classes / Visualizer / Module / Admin.php

Admin.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.3.4, at classes/Visualizer/Module/Admin.php

861 lines 28.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 */
29 class 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 * Constructor.
45 *
46 * @since 1.0.0
47 *
48 * @access public
49 *
50 * @param Visualizer_Plugin $plugin The instance of the plugin.
51 */
52 public function __construct( Visualizer_Plugin $plugin ) {
53 parent::__construct( $plugin );
54 $this->_addAction( 'load-post.php', 'enqueueMediaScripts' );
55 $this->_addAction( 'load-post-new.php', 'enqueueMediaScripts' );
56 $this->_addAction( 'admin_footer', 'renderTemplates' );
57 $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 8 );
58 $this->_addAction( 'admin_menu', 'registerAdminMenu' );
59 $this->_addFilter( 'media_view_strings', 'setupMediaViewStrings' );
60 $this->_addFilter( 'plugin_action_links', 'getPluginActionLinks', 10, 2 );
61 $this->_addFilter( 'plugin_row_meta', 'getPluginMetaLinks', 10, 2 );
62 $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
63 $this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
64 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
65
66 // revision support.
67 $this->_addFilter( 'wp_revisions_to_keep', 'limitRevisions', null, 10, 2 );
68 $this->_addAction( '_wp_put_post_revision', 'addRevision', null, 10, 1 );
69 $this->_addAction( 'wp_restore_post_revision', 'restoreRevision', null, 10, 2 );
70
71 $this->_addAction( 'admin_init', 'init' );
72 }
73
74 /**
75 * No limits on revisions.
76 */
77 public function limitRevisions( $num, $post ) {
78 if ( Visualizer_Plugin::CPT_VISUALIZER === $post->post_type ) {
79 return -1;
80 }
81 return $num;
82 }
83
84 /**
85 * Add a revision.
86 */
87 public function addRevision( $revision_id ) {
88 $parent_id = wp_is_post_revision( $revision_id );
89 if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $parent_id ) ) {
90 // add the meta data to this revision.
91 $meta = get_post_meta( $parent_id, '', true );
92
93 if ( $meta ) {
94 foreach ( $meta as $key => $value ) {
95 if ( 0 === strpos( $key, 'visualizer' ) ) {
96 add_metadata( 'post', $revision_id, $key, maybe_unserialize( $value[0] ) );
97 }
98 }
99 }
100 }
101 }
102
103 /**
104 * Restore a revision.
105 */
106 public function restoreRevision( $post_id, $revision_id ) {
107 if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $post_id ) ) {
108 // get the meta information from the revision.
109 $meta = get_metadata( 'post', $revision_id, '', true );
110
111 // delete all meta information from the post before adding.
112 $post_meta = get_post_meta( $post_id, '', true );
113 if ( $post_meta ) {
114 foreach ( $meta as $key => $value ) {
115 if ( 0 === strpos( $key, 'visualizer' ) ) {
116 delete_post_meta( $post_id, $key );
117 }
118 }
119 }
120
121 if ( $meta ) {
122 foreach ( $meta as $key => $value ) {
123 if ( 0 === strpos( $key, 'visualizer' ) ) {
124 add_post_meta( $post_id, $key, maybe_unserialize( $value[0] ) );
125 }
126 }
127 }
128 }
129 }
130
131 /**
132 * Admin init.
133 *
134 * @access public
135 */
136 public function init() {
137 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
138 if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
139 $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
140 $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
141 $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
142 }
143 }
144
145 /**
146 * Load plugin translation for - TinyMCE API
147 *
148 * @access public
149 * @param array $arr The tinymce_lang array.
150 * @return array
151 */
152 public function add_tinymce_lang( $arr ) {
153 $ui_lang = VISUALIZER_ABSPATH . '/classes/Visualizer/Module/Language.php';
154 $ui_lang = apply_filters( 'visualizer_ui_lang_filter', $ui_lang );
155 $arr[] = $ui_lang;
156 return $arr;
157 }
158
159 /**
160 * Load custom js options - TinyMCE API
161 *
162 * @access public
163 * @param array $plugin_array The tinymce plugin array.
164 * @return array
165 */
166 public function tinymce_plugin( $plugin_array ) {
167 $plugin_array['visualizer_mce_button'] = VISUALIZER_ABSURL . 'js/mce.js';
168 return $plugin_array;
169 }
170
171 /**
172 * Register new button in the editor
173 *
174 * @access public
175 * @param array $buttons The tinymce buttons array.
176 * @return array
177 */
178 public function register_mce_button( $buttons ) {
179 array_push( $buttons, 'visualizer_mce_button' );
180 return $buttons;
181 }
182
183 /**
184 * Whether to show the feedback review or not.
185 *
186 * @access public
187 */
188 public function feedbackReviewTrigger( $dumb ) {
189 $query = new WP_Query(
190 array(
191 'posts_per_page' => 50,
192 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
193 'fields' => 'ids',
194 'update_post_meta_cache' => false,
195 'update_post_term_cache' => false,
196 )
197 );
198
199 if ( $query->have_posts() && $query->post_count > 0 ) {
200 return true;
201 }
202 return false;
203 }
204
205 /**
206 * Enqueues media scripts and styles.
207 *
208 * @since 1.0.0
209 * @uses wp_enqueue_style To enqueue style file.
210 * @uses wp_enqueue_script To enqueue script file.
211 *
212 * @access public
213 */
214 public function enqueueMediaScripts() {
215 global $typenow;
216 if ( post_type_supports( $typenow, 'editor' ) ) {
217 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
218
219 // Load all the assets for the different libraries we support.
220 $deps = array(
221 Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
222 Visualizer_Render_Sidebar_Type_DataTable_DataTable::enqueue_assets( array( 'media-editor' ) ),
223 );
224
225 wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
226 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
227 wp_enqueue_script( 'visualizer-media-controller', VISUALIZER_ABSURL . 'js/media/controller.js', array( 'visualizer-media-collection' ), Visualizer_Plugin::VERSION, true );
228 wp_enqueue_script( 'visualizer-media-view', VISUALIZER_ABSURL . 'js/media/view.js', array( 'visualizer-media-controller' ), Visualizer_Plugin::VERSION, true );
229 wp_localize_script(
230 'visualizer-media-view',
231 'visualizer',
232 array(
233 'i10n' => array(
234 'insert' => __( 'Insert', 'visualizer' ),
235 ),
236 )
237 );
238 wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
239 wp_enqueue_script( 'visualizer-media', VISUALIZER_ABSURL . 'js/media.js', array( 'visualizer-media-toolbar' ), Visualizer_Plugin::VERSION, true );
240 }
241 }
242
243 /**
244 * Extends media view strings with visualizer strings.
245 *
246 * @since 1.0.0
247 *
248 * @access public
249 *
250 * @param array $strings The array of media view strings.
251 *
252 * @return array The extended array of media view strings.
253 */
254 public function setupMediaViewStrings( $strings ) {
255 $chart_types = self::_getChartTypesLocalized( true, true, true );
256 $strings['visualizer'] = array(
257 'actions' => array(
258 'get_charts' => Visualizer_Plugin::ACTION_GET_CHARTS,
259 'delete_chart' => Visualizer_Plugin::ACTION_DELETE_CHART,
260 ),
261 'controller' => array(
262 'title' => esc_html__( 'Visualizations', 'visualizer' ),
263 ),
264 'routers' => array(
265 'library' => esc_html__( 'From Library', 'visualizer' ),
266 'create' => esc_html__( 'Create New', 'visualizer' ),
267 ),
268 'library' => array(
269 'filters' => $chart_types,
270 'types' => array_keys( $chart_types ),
271 ),
272 'nonce' => wp_create_nonce(),
273 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
274 );
275
276 return $strings;
277 }
278
279 /**
280 * Returns associated array of chart types and localized names.
281 *
282 * @since 1.0.0
283 *
284 * @static
285 * @access private
286 * @return array The associated array of chart types with localized names.
287 */
288 public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false, $where = null ) {
289 $additional = array();
290 if ( $add_select ) {
291 $additional['select'] = array(
292 'name' => esc_html__( 'All', 'visualizer' ),
293 'enabled' => true,
294 );
295 }
296
297 $types = array_merge(
298 $additional,
299 array(
300 'dataTable' => array(
301 'name' => esc_html__( 'Table', 'visualizer' ),
302 'enabled' => true,
303 'supports' => array( 'DataTable' ),
304 ),
305 'pie' => array(
306 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
307 'enabled' => true,
308 'supports' => array( 'Google Charts', 'ChartJS' ),
309 ),
310 'line' => array(
311 'name' => esc_html__( 'Line', 'visualizer' ),
312 'enabled' => true,
313 'supports' => array( 'Google Charts', 'ChartJS' ),
314 ),
315 'area' => array(
316 'name' => esc_html__( 'Area', 'visualizer' ),
317 'enabled' => true,
318 // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
319 'supports' => array( 'Google Charts' ),
320 ),
321 'geo' => array(
322 'name' => esc_html__( 'Geo', 'visualizer' ),
323 'enabled' => true,
324 'supports' => array( 'Google Charts' ),
325 ),
326 'bar' => array(
327 'name' => esc_html__( 'Bar', 'visualizer' ),
328 'enabled' => true,
329 'supports' => array( 'Google Charts', 'ChartJS' ),
330 ),
331 'column' => array(
332 'name' => esc_html__( 'Column', 'visualizer' ),
333 'enabled' => true,
334 'supports' => array( 'Google Charts', 'ChartJS' ),
335 ),
336 'scatter' => array(
337 'name' => esc_html__( 'Scatter', 'visualizer' ),
338 'enabled' => true,
339 'supports' => array( 'Google Charts' ),
340 ),
341 'gauge' => array(
342 'name' => esc_html__( 'Gauge', 'visualizer' ),
343 'enabled' => true,
344 'supports' => array( 'Google Charts' ),
345 ),
346 'candlestick' => array(
347 'name' => esc_html__( 'Candlestick', 'visualizer' ),
348 'enabled' => true,
349 'supports' => array( 'Google Charts' ),
350 ),
351 // pro types
352 'table' => array(
353 'name' => esc_html__( 'Table (Deprecated)', 'visualizer' ),
354 'enabled' => false,
355 'supports' => array( 'Google Charts' ),
356 ),
357 'timeline' => array(
358 'name' => esc_html__( 'Timeline', 'visualizer' ),
359 'enabled' => false,
360 'supports' => array( 'Google Charts', 'ChartJS' ),
361 ),
362 'combo' => array(
363 'name' => esc_html__( 'Combo', 'visualizer' ),
364 'enabled' => false,
365 'supports' => array( 'Google Charts' ),
366 ),
367 'polarArea' => array(
368 'name' => esc_html__( 'Polar Area', 'visualizer' ),
369 'enabled' => false,
370 'supports' => array( 'ChartJS' ),
371 ),
372 'radar' => array(
373 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
374 'enabled' => false,
375 'supports' => array( 'ChartJS' ),
376 ),
377 )
378 );
379 $types = apply_filters( 'visualizer_pro_chart_types', $types );
380 if ( $enabledOnly ) {
381 $filtered = array();
382 foreach ( $types as $type => $array ) {
383 if ( ! is_array( $array ) ) {
384 // support for old pro
385 $array = array( 'enabled' => true, 'name' => $array );
386 }
387 // backward compatibility for PRO before v1.9.0
388 if ( ! array_key_exists( 'supports', $array ) ) {
389 $array['supports'] = array( 'Google Charts' );
390 }
391 if ( ! $array['enabled'] ) {
392 continue;
393 }
394 $filtered[ $type ] = $array;
395 }
396 $types = $filtered;
397 }
398 if ( $get2Darray ) {
399 $doubleD = array();
400 foreach ( $types as $type => $array ) {
401 if ( ! is_array( $array ) ) {
402 // support for old pro
403 $array = array( 'enabled' => true, 'name' => $array );
404 }
405 // backward compatibility for PRO before v1.9.0
406 if ( ! array_key_exists( 'supports', $array ) ) {
407 $array['supports'] = array( 'Google Charts' );
408 }
409 $doubleD[ $type ] = $array['name'];
410 }
411 $types = $doubleD;
412 }
413
414 return self::handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where );
415 }
416
417 /**
418 * Handle (soon-to-be) deprecated charts.
419 */
420 private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
421 $deprecated = array();
422
423 switch ( $where ) {
424 case 'types':
425 // fall-through
426 case 'library':
427 // if the user has a Google Table chart, show it as deprecated otherwise remove the option from the library.
428 if ( ! self::hasChartType( 'table' ) ) {
429 $deprecated[] = 'table';
430 if ( $get2Darray ) {
431 $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
432 } else {
433 $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
434 }
435 }
436
437 // if a user has a Gauge/Candlestick chart, then let them keep using it.
438 if ( ! Visualizer_Module::is_pro() ) {
439 if ( ! self::hasChartType( 'gauge' ) ) {
440 if ( $get2Darray ) {
441 $deprecated[] = 'gauge';
442 } else {
443 $types['gauge']['enabled'] = false;
444 }
445 }
446 if ( ! self::hasChartType( 'candlestick' ) ) {
447 if ( $get2Darray ) {
448 $deprecated[] = 'candlestick';
449 } else {
450 $types['candlestick']['enabled'] = false;
451 }
452 }
453 }
454 break;
455 default:
456 // remove the option to create a Google Table chart.
457 $deprecated[] = 'table';
458
459 // rename the new table chart type.
460 if ( $get2Darray ) {
461 $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
462 } else {
463 $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
464 }
465
466 // if a user has a Gauge/Candlestick chart, then let them keep using it.
467 if ( ! Visualizer_Module::is_pro() ) {
468 if ( ! self::hasChartType( 'gauge' ) ) {
469 if ( $get2Darray ) {
470 $deprecated[] = 'gauge';
471 } else {
472 $types['gauge']['enabled'] = false;
473 }
474 }
475 if ( ! self::hasChartType( 'candlestick' ) ) {
476 if ( $get2Darray ) {
477 $deprecated[] = 'candlestick';
478 } else {
479 $types['candlestick']['enabled'] = false;
480 }
481 }
482 }
483 }
484
485 if ( $deprecated ) {
486 foreach ( $deprecated as $type ) {
487 unset( $types[ $type ] );
488 }
489 }
490
491 return $types;
492 }
493
494 /**
495 * Renders templates to use in media popup.
496 *
497 * @since 1.0.0
498 * @global string $pagenow The name of the current page.
499 *
500 * @access public
501 */
502 public function renderTemplates() {
503 global $pagenow;
504 if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
505 return;
506 }
507 $render = new Visualizer_Render_Templates();
508 $render->render();
509 }
510
511 /**
512 * Enqueues library scripts and styles.
513 *
514 * @since 1.0.0
515 * @uses wp_enqueue_style() To enqueue library stylesheet.
516 * @uses wp_enqueue_script() To enqueue javascript file.
517 * @uses wp_enqueue_media() To enqueue media stuff.
518 *
519 * @access public
520 *
521 * @param string $suffix The current page suffix.
522 */
523 public function enqueueLibraryScripts( $suffix ) {
524 if ( $suffix === $this->_libraryPage ) {
525 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
526 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
527 wp_enqueue_media();
528 wp_enqueue_script(
529 'visualizer-library',
530 VISUALIZER_ABSURL . 'js/library.js',
531 array(
532 'jquery',
533 'media-views',
534 ),
535 Visualizer_Plugin::VERSION,
536 true
537 );
538
539 wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
540
541 $query = $this->getQuery();
542 while ( $query->have_posts() ) {
543 $chart = $query->next_post();
544 $library = $this->load_chart_type( $chart->ID );
545 if ( is_null( $library ) ) {
546 continue;
547 }
548 wp_enqueue_script(
549 "visualizer-render-$library",
550 VISUALIZER_ABSURL . 'js/render-facade.js',
551 apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
552 Visualizer_Plugin::VERSION,
553 true
554 );
555 }
556 }
557 }
558
559 /**
560 * Adds visualizer tab for media upload tabs array.
561 *
562 * @since 1.0.0
563 *
564 * @access public
565 *
566 * @param array $tabs The array of media upload tabs.
567 *
568 * @return array Extended array of media upload tabs.
569 */
570 public function setupVisualizerTab( $tabs ) {
571 $tabs['visualizer'] = 'Visualizer';
572
573 return $tabs;
574 }
575
576 /**
577 * Registers admin menu for visualizer library.
578 *
579 * @since 1.0.0
580 *
581 * @access public
582 */
583 public function registerAdminMenu() {
584 $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
585
586 $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
587
588 add_submenu_page(
589 Visualizer_Plugin::NAME,
590 __( 'Chart Library', 'visualizer' ),
591 __( 'Chart Library', 'visualizer' ),
592 'edit_posts',
593 admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME )
594 );
595 add_submenu_page(
596 Visualizer_Plugin::NAME,
597 __( 'Add New Chart', 'visualizer' ),
598 __( 'Add New Chart', 'visualizer' ),
599 'edit_posts',
600 admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew' )
601 );
602 add_submenu_page(
603 Visualizer_Plugin::NAME,
604 __( 'Support', 'visualizer' ),
605 __( '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>',
606 'edit_posts',
607 'viz-support',
608 array( $this, 'renderSupportPage' )
609 );
610 remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
611 }
612
613 /**
614 * Get the instance of WP_Query that fetches the charts as per the given criteria.
615 */
616 private function getQuery() {
617 static $q;
618 if ( ! is_null( $q ) ) {
619 return $q;
620 }
621
622 // get current page
623 $page = filter_input(
624 INPUT_GET,
625 'vpage',
626 FILTER_VALIDATE_INT,
627 array(
628 'options' => array(
629 'min_range' => 1,
630 'default' => 1,
631 ),
632 )
633 );
634 // the initial query arguments to fetch charts
635 $query_args = array(
636 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
637 'posts_per_page' => 6,
638 'paged' => $page,
639 );
640 // add chart type filter to the query arguments
641 $filter = filter_input( INPUT_GET, 'type' );
642 if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) {
643 $query_args['meta_query'] = array(
644 array(
645 'key' => Visualizer_Plugin::CF_CHART_TYPE,
646 'value' => $filter,
647 'compare' => '=',
648 ),
649 );
650 } else {
651 $filter = 'all';
652 }
653 // Added by Ash/Upwork
654 $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
655 if ( $filterByMeta ) {
656 $query = array(
657 'key' => Visualizer_Plugin::CF_SETTINGS,
658 'value' => $filterByMeta,
659 'compare' => 'LIKE',
660 );
661 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
662 $meta[] = $query;
663 $query_args['meta_query'] = $meta;
664 }
665 $q = new WP_Query( $query_args );
666 return $q;
667 }
668
669 /**
670 * Renders support page.
671 *
672 * @since 3.3.0
673 *
674 * @access public
675 */
676 public function renderSupportPage() {
677 wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
678 include_once VISUALIZER_ABSPATH . '/templates/support.php';
679 }
680
681 /**
682 * Renders visualizer library page.
683 *
684 * @since 1.0.0
685 *
686 * @access public
687 */
688 public function renderLibraryPage() {
689 $charts = array();
690 $query = $this->getQuery();
691
692 // get current page
693 $page = filter_input(
694 INPUT_GET,
695 'vpage',
696 FILTER_VALIDATE_INT,
697 array(
698 'options' => array(
699 'min_range' => 1,
700 'default' => 1,
701 ),
702 )
703 );
704 // add chart type filter to the query arguments
705 $filter = filter_input( INPUT_GET, 'type' );
706 if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
707 $filter = 'all';
708 }
709
710 $css = '';
711 while ( $query->have_posts() ) {
712 $chart = $query->next_post();
713
714 // 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.
715 $chart = $this->handleExistingRevisions( $chart->ID, $chart );
716 // refresh a "live" db query chart.
717 $chart = apply_filters( 'visualizer_schedule_refresh_chart', $chart, $chart->ID, false );
718
719 $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
720
721 // fetch and update settings
722 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
723
724 $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
725 if ( ! empty( $atts['settings'] ) ) {
726 $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
727 }
728
729 unset( $settings['height'], $settings['width'], $settings['chartArea'] );
730 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
731 $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
732
733 $library = $this->load_chart_type( $chart->ID );
734
735 $id = 'visualizer-' . $chart->ID;
736 $arguments = $this->get_inline_custom_css( $id, $settings );
737 if ( ! empty( $arguments ) ) {
738 $css .= $arguments[0];
739 $settings = $arguments[1];
740 }
741
742 // add chart to the array
743 $charts[ $id ] = array(
744 'id' => $chart->ID,
745 'type' => $type,
746 'series' => $series,
747 'settings' => $settings,
748 'data' => $data,
749 'library' => $library,
750 );
751 }
752 // enqueue charts array
753 $ajaxurl = admin_url( 'admin-ajax.php' );
754 wp_localize_script(
755 'visualizer-library',
756 'visualizer',
757 array(
758 'language' => $this->get_language(),
759 'map_api_key' => get_option( 'visualizer-map-api-key' ),
760 'charts' => $charts,
761 'urls' => array(
762 'base' => add_query_arg( array( 'vpage' => false, 'vaction' => false ) ),
763 'create' => add_query_arg(
764 array(
765 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
766 'library' => 'yes',
767 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
768 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
769 'vaction' => false,
770 ),
771 $ajaxurl
772 ),
773 'edit' => add_query_arg(
774 array(
775 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
776 'library' => 'yes',
777 'vaction' => false,
778 ),
779 $ajaxurl
780 ),
781 ),
782 'page_type' => 'library',
783 'is_front' => false,
784 )
785 );
786 // render library page
787 $render = new Visualizer_Render_Library();
788 $render->charts = $charts;
789 $render->type = $filter;
790 $render->types = self::_getChartTypesLocalized( false, false, false, true );
791 $render->custom_css = $css;
792 $render->pagination = paginate_links(
793 array(
794 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
795 'format' => '',
796 'current' => $page,
797 'total' => $query->max_num_pages,
798 'type' => 'array',
799 )
800 );
801 $render->render();
802 }
803
804 /**
805 * Updates the plugin's action links, which will be rendered at the plugins table.
806 *
807 * @since 1.0.0
808 *
809 * @access public
810 *
811 * @param array $links The array of original action links.
812 * @param string $file The plugin basename.
813 *
814 * @return array Updated array of action links.
815 */
816 public function getPluginActionLinks( $links, $file ) {
817 if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
818 array_unshift(
819 $links,
820 sprintf(
821 '<a href="%s">%s</a>',
822 admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
823 esc_html__( 'Library', 'visualizer' )
824 )
825 );
826 }
827
828 return $links;
829 }
830
831 /**
832 * Updates the plugin's meta links, which will be rendered at the plugins table.
833 *
834 * @since 1.0.0
835 *
836 * @access public
837 *
838 * @param array $plugin_meta The array of a plugin meta links.
839 * @param string $plugin_file The plugin's basename.
840 *
841 * @return array Updated array of plugin meta links.
842 */
843 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
844 if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
845 // knowledge base link
846 $plugin_meta[] = sprintf(
847 '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
848 esc_html__( 'Docs', 'visualizer' )
849 );
850 // flattr link
851 $plugin_meta[] = sprintf(
852 '<a style="color:red" href="' . Visualizer_Plugin::PRO_TEASER_URL . '" target="_blank">%s</a>',
853 esc_html__( 'Pro Addon', 'visualizer' )
854 );
855 }
856
857 return $plugin_meta;
858 }
859
860 }
861