PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.0.8
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.0.8
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.0.8, at classes/Visualizer/Module/Admin.php

624 lines 19.1 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', 'renderTempaltes' );
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( 'visualizer_logger_data', 'getLoggerData' );
62 $this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
63 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
64
65 // revision support.
66 $this->_addFilter( 'wp_revisions_to_keep', 'limitRevisions', null, 10, 2 );
67 $this->_addAction( '_wp_put_post_revision', 'addRevision', null, 10, 1 );
68 $this->_addAction( 'wp_restore_post_revision', 'restoreRevision', null, 10, 2 );
69
70 $this->_addAction( 'admin_init', 'init' );
71 }
72
73 /**
74 * No limits on revisions.
75 */
76 public function limitRevisions( $num, $post ) {
77 if ( Visualizer_Plugin::CPT_VISUALIZER === $post->post_type ) {
78 return -1;
79 }
80 return $num;
81 }
82
83 /**
84 * Add a revision.
85 */
86 public function addRevision( $revision_id ) {
87 $parent_id = wp_is_post_revision( $revision_id );
88 if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $parent_id ) ) {
89 // add the meta data to this revision.
90 $meta = get_post_meta( $parent_id, '', true );
91
92 if ( $meta ) {
93 foreach ( $meta as $key => $value ) {
94 if ( 0 === strpos( $key, 'visualizer' ) ) {
95 add_metadata( 'post', $revision_id, $key, maybe_unserialize( $value[0] ) );
96 }
97 }
98 }
99 }
100 }
101
102 /**
103 * Restore a revision.
104 */
105 public function restoreRevision( $post_id, $revision_id ) {
106 if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $post_id ) ) {
107 // get the meta information from the revision.
108 $meta = get_metadata( 'post', $revision_id, '', true );
109
110 // delete all meta information from the post before adding.
111 $post_meta = get_post_meta( $post_id, '', true );
112 if ( $post_meta ) {
113 foreach ( $meta as $key => $value ) {
114 if ( 0 === strpos( $key, 'visualizer' ) ) {
115 delete_post_meta( $post_id, $key );
116 }
117 }
118 }
119
120 if ( $meta ) {
121 foreach ( $meta as $key => $value ) {
122 if ( 0 === strpos( $key, 'visualizer' ) ) {
123 add_post_meta( $post_id, $key, maybe_unserialize( $value[0] ) );
124 }
125 }
126 }
127 }
128 }
129
130 /**
131 * Admin init.
132 *
133 * @access public
134 */
135 public function init() {
136 if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
137 $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
138 $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
139 $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
140 }
141 }
142
143 /**
144 * Load plugin translation for - TinyMCE API
145 *
146 * @access public
147 * @param array $arr The tinymce_lang array.
148 * @return array
149 */
150 public function add_tinymce_lang( $arr ) {
151 $ui_lang = VISUALIZER_ABSPATH . '/classes/Visualizer/Module/Language.php';
152 $ui_lang = apply_filters( 'visualizer_ui_lang_filter', $ui_lang );
153 $arr[] = $ui_lang;
154 return $arr;
155 }
156
157 /**
158 * Load custom js options - TinyMCE API
159 *
160 * @access public
161 * @param array $plugin_array The tinymce plugin array.
162 * @return array
163 */
164 public function tinymce_plugin( $plugin_array ) {
165 $plugin_array['visualizer_mce_button'] = VISUALIZER_ABSURL . 'js/mce.js';
166 return $plugin_array;
167 }
168
169 /**
170 * Register new button in the editor
171 *
172 * @access public
173 * @param array $buttons The tinymce buttons array.
174 * @return array
175 */
176 public function register_mce_button( $buttons ) {
177 array_push( $buttons, 'visualizer_mce_button' );
178 return $buttons;
179 }
180
181 /**
182 * Whether to show the feedback review or not.
183 *
184 * @access public
185 */
186 public function feedbackReviewTrigger( $dumb ) {
187 $query = new WP_Query(
188 array(
189 'posts_per_page' => 50,
190 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
191 'fields' => 'ids',
192 'update_post_meta_cache' => false,
193 'update_post_term_cache' => false,
194 )
195 );
196
197 if ( $query->have_posts() && $query->post_count > 0 ) {
198 return true;
199 }
200 return false;
201 }
202
203 /**
204 * Enqueues media scripts and styles.
205 *
206 * @since 1.0.0
207 * @uses wp_enqueue_style To enqueue style file.
208 * @uses wp_enqueue_script To enqueue script file.
209 *
210 * @access public
211 */
212 public function enqueueMediaScripts() {
213 global $typenow;
214 if ( post_type_supports( $typenow, 'editor' ) ) {
215 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
216 wp_enqueue_script( 'visualizer-google-jsapi-new', '//www.gstatic.com/charts/loader.js', array( 'media-editor' ), null, true );
217 wp_enqueue_script( 'visualizer-google-jsapi-old', '//www.google.com/jsapi', array( 'visualizer-google-jsapi-new' ), null, true );
218 wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', array( 'visualizer-google-jsapi-old' ), Visualizer_Plugin::VERSION, true );
219 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
220 wp_enqueue_script( 'visualizer-media-controller', VISUALIZER_ABSURL . 'js/media/controller.js', array( 'visualizer-media-collection' ), Visualizer_Plugin::VERSION, true );
221 wp_enqueue_script( 'visualizer-media-view', VISUALIZER_ABSURL . 'js/media/view.js', array( 'visualizer-media-controller' ), Visualizer_Plugin::VERSION, true );
222 wp_localize_script(
223 'visualizer-media-view', 'visualizer', array(
224 'i10n' => array(
225 'insert' => __( 'Insert', 'visualizer' ),
226 ),
227 )
228 );
229 wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
230 wp_enqueue_script( 'visualizer-media', VISUALIZER_ABSURL . 'js/media.js', array( 'visualizer-media-toolbar' ), Visualizer_Plugin::VERSION, true );
231 }
232 }
233
234 /**
235 * Extends media view strings with visualizer strings.
236 *
237 * @since 1.0.0
238 *
239 * @access public
240 *
241 * @param array $strings The array of media view strings.
242 *
243 * @return array The extended array of media view strings.
244 */
245 public function setupMediaViewStrings( $strings ) {
246 $chart_types = self::_getChartTypesLocalized( true, true, true );
247 $strings['visualizer'] = array(
248 'actions' => array(
249 'get_charts' => Visualizer_Plugin::ACTION_GET_CHARTS,
250 'delete_chart' => Visualizer_Plugin::ACTION_DELETE_CHART,
251 ),
252 'controller' => array(
253 'title' => esc_html__( 'Visualizations', 'visualizer' ),
254 ),
255 'routers' => array(
256 'library' => esc_html__( 'From Library', 'visualizer' ),
257 'create' => esc_html__( 'Create New', 'visualizer' ),
258 ),
259 'library' => array(
260 'filters' => $chart_types,
261 'types' => array_keys( $chart_types ),
262 ),
263 'nonce' => wp_create_nonce(),
264 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
265 );
266
267 return $strings;
268 }
269
270 /**
271 * Returns associated array of chart types and localized names.
272 *
273 * @since 1.0.0
274 *
275 * @static
276 * @access private
277 * @return array The associated array of chart types with localized names.
278 */
279 public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false ) {
280 $additional = array();
281 if ( $add_select ) {
282 $additional['select'] = array(
283 'name' => esc_html__( 'All', 'visualizer' ),
284 'enabled' => true,
285 );
286 }
287
288 $types = array_merge(
289 $additional, array(
290 'pie' => array(
291 'name' => esc_html__( 'Pie', 'visualizer' ),
292 'enabled' => true,
293 ),
294 'line' => array(
295 'name' => esc_html__( 'Line', 'visualizer' ),
296 'enabled' => true,
297 ),
298 'area' => array(
299 'name' => esc_html__( 'Area', 'visualizer' ),
300 'enabled' => true,
301 ),
302 'geo' => array(
303 'name' => esc_html__( 'Geo', 'visualizer' ),
304 'enabled' => true,
305 ),
306 'bar' => array(
307 'name' => esc_html__( 'Bar', 'visualizer' ),
308 'enabled' => true,
309 ),
310 'column' => array(
311 'name' => esc_html__( 'Column', 'visualizer' ),
312 'enabled' => true,
313 ),
314 'gauge' => array(
315 'name' => esc_html__( 'Gauge', 'visualizer' ),
316 'enabled' => true,
317 ),
318 'scatter' => array(
319 'name' => esc_html__( 'Scatter', 'visualizer' ),
320 'enabled' => true,
321 ),
322 'candlestick' => array(
323 'name' => esc_html__( 'Candlestick', 'visualizer' ),
324 'enabled' => true,
325 ),
326 // pro types
327 'table' => array(
328 'name' => esc_html__( 'Table', 'visualizer' ),
329 'enabled' => false,
330 ),
331 'timeline' => array(
332 'name' => esc_html__( 'Timeline', 'visualizer' ),
333 'enabled' => false,
334 ),
335 'combo' => array(
336 'name' => esc_html__( 'Combo', 'visualizer' ),
337 'enabled' => false,
338 ),
339 )
340 );
341 $types = apply_filters( 'visualizer_pro_chart_types', $types );
342 if ( $enabledOnly ) {
343 $filtered = array();
344 foreach ( $types as $type => $array ) {
345 if ( ! is_array( $array ) ) {
346 // support for old pro
347 $array = array( 'enabled' => true, 'name' => $array );
348 }
349 if ( ! $array['enabled'] ) {
350 continue;
351 }
352 $filtered[ $type ] = $array;
353 }
354 $types = $filtered;
355 }
356 if ( $get2Darray ) {
357 $doubleD = array();
358 foreach ( $types as $type => $array ) {
359 if ( ! is_array( $array ) ) {
360 // support for old pro
361 $array = array( 'enabled' => true, 'name' => $array );
362 }
363 $doubleD[ $type ] = $array['name'];
364 }
365 $types = $doubleD;
366 }
367
368 return $types;
369 }
370
371 /**
372 * Renders templates to use in media popup.
373 *
374 * @since 1.0.0
375 * @global string $pagenow The name of the current page.
376 *
377 * @access public
378 */
379 public function renderTempaltes() {
380 global $pagenow;
381 if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
382 return;
383 }
384 $render = new Visualizer_Render_Templates();
385 $render->render();
386 }
387
388 /**
389 * Enqueues library scripts and styles.
390 *
391 * @since 1.0.0
392 * @uses wp_enqueue_style() To enqueue library stylesheet.
393 * @uses wp_enqueue_script() To enqueue javascript file.
394 * @uses wp_enqueue_media() To enqueue media stuff.
395 *
396 * @access public
397 *
398 * @param string $suffix The current page suffix.
399 */
400 public function enqueueLibraryScripts( $suffix ) {
401 if ( $suffix == $this->_libraryPage ) {
402 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
403 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
404 wp_enqueue_media();
405 wp_enqueue_script(
406 'visualizer-library', VISUALIZER_ABSURL . 'js/library.js', array(
407 'jquery',
408 'media-views',
409 ), Visualizer_Plugin::VERSION, true
410 );
411 wp_enqueue_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
412 wp_enqueue_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true );
413 wp_enqueue_script(
414 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array(
415 'google-jsapi-old',
416 'visualizer-library',
417 ), Visualizer_Plugin::VERSION, true
418 );
419 }
420 }
421
422 /**
423 * Adds visualizer tab for media upload tabs array.
424 *
425 * @since 1.0.0
426 *
427 * @access public
428 *
429 * @param array $tabs The array of media upload tabs.
430 *
431 * @return array Extended array of media upload tabs.
432 */
433 public function setupVisualizerTab( $tabs ) {
434 $tabs['visualizer'] = 'Visualizer';
435
436 return $tabs;
437 }
438
439 /**
440 * Registers admin menu for visualizer library.
441 *
442 * @since 1.0.0
443 *
444 * @access public
445 */
446 public function registerAdminMenu() {
447 $title = esc_html__( 'Visualizer Library', 'visualizer' );
448 $callback = array( $this, 'renderLibraryPage' );
449 $this->_libraryPage = add_submenu_page( 'upload.php', $title, $title, 'edit_posts', Visualizer_Plugin::NAME, $callback );
450 }
451
452 /**
453 * Renders visualizer library page.
454 *
455 * @since 1.0.0
456 *
457 * @access public
458 */
459 public function renderLibraryPage() {
460 // get current page
461 $page = filter_input(
462 INPUT_GET, 'vpage', FILTER_VALIDATE_INT, array(
463 'options' => array(
464 'min_range' => 1,
465 'default' => 1,
466 ),
467 )
468 );
469 // the initial query arguments to fetch charts
470 $query_args = array(
471 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
472 'posts_per_page' => 6,
473 'paged' => $page,
474 );
475 // add chart type filter to the query arguments
476 $filter = filter_input( INPUT_GET, 'type' );
477 if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
478 $query_args['meta_query'] = array(
479 array(
480 'key' => Visualizer_Plugin::CF_CHART_TYPE,
481 'value' => $filter,
482 'compare' => '=',
483 ),
484 );
485 } else {
486 $filter = 'all';
487 }
488 // Added by Ash/Upwork
489 $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
490 if ( $filterByMeta ) {
491 $query = array(
492 'key' => Visualizer_Plugin::CF_SETTINGS,
493 'value' => $filterByMeta,
494 'compare' => 'LIKE',
495 );
496 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
497 $meta[] = $query;
498 $query_args['meta_query'] = $meta;
499 }
500 // Added by Ash/Upwork
501 // fetch charts
502 $charts = array();
503 $query = new WP_Query( $query_args );
504 while ( $query->have_posts() ) {
505 $chart = $query->next_post();
506
507 // 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.
508 $chart = $this->handleExistingRevisions( $chart->ID, $chart );
509
510 // fetch and update settings
511 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
512 unset( $settings['height'], $settings['width'] );
513 $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
514 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
515 $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
516 // add chart to the array
517 $charts[ 'visualizer-' . $chart->ID ] = array(
518 'id' => $chart->ID,
519 'type' => $type,
520 'series' => $series,
521 'settings' => $settings,
522 'data' => $data,
523 );
524 }
525 // enqueue charts array
526 $ajaxurl = admin_url( 'admin-ajax.php' );
527 wp_localize_script(
528 'visualizer-library', 'visualizer', array(
529 'language' => $this->get_language(),
530 'map_api_key' => get_option( 'visualizer-map-api-key' ),
531 'charts' => $charts,
532 'urls' => array(
533 'base' => add_query_arg( 'vpage', false ),
534 'create' => add_query_arg(
535 array(
536 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
537 'library' => 'yes',
538 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
539 ), $ajaxurl
540 ),
541 'edit' => add_query_arg(
542 array(
543 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
544 'library' => 'yes',
545 ), $ajaxurl
546 ),
547 ),
548 )
549 );
550 // render library page
551 $render = new Visualizer_Render_Library();
552 $render->charts = $charts;
553 $render->type = $filter;
554 $render->types = self::_getChartTypesLocalized();
555 $render->pagination = paginate_links(
556 array(
557 'base' => add_query_arg( 'vpage', '%#%' ),
558 'format' => '',
559 'current' => $page,
560 'total' => $query->max_num_pages,
561 'type' => 'array',
562 )
563 );
564 $render->render();
565 }
566
567 /**
568 * Updates the plugin's action links, which will be rendered at the plugins table.
569 *
570 * @since 1.0.0
571 *
572 * @access public
573 *
574 * @param array $links The array of original action links.
575 * @param string $file The plugin basename.
576 *
577 * @return array Updated array of action links.
578 */
579 public function getPluginActionLinks( $links, $file ) {
580 if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
581 array_unshift(
582 $links,
583 sprintf(
584 '<a href="%s">%s</a>',
585 admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
586 esc_html__( 'Library', 'visualizer' )
587 )
588 );
589 }
590
591 return $links;
592 }
593
594 /**
595 * Updates the plugin's meta links, which will be rendered at the plugins table.
596 *
597 * @since 1.0.0
598 *
599 * @access public
600 *
601 * @param array $plugin_meta The array of a plugin meta links.
602 * @param string $plugin_file The plugin's basename.
603 *
604 * @return array Updated array of plugin meta links.
605 */
606 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
607 if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
608 // knowledge base link
609 $plugin_meta[] = sprintf(
610 '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
611 esc_html__( 'Knowledge Base', 'visualizer' )
612 );
613 // flattr link
614 $plugin_meta[] = sprintf(
615 '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
616 esc_html__( 'Pro Addon', 'visualizer' )
617 );
618 }
619
620 return $plugin_meta;
621 }
622
623 }
624