PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.11.12
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.11.12
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 / Render / Layout.php

Layout.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.11.12, at classes/Visualizer/Render/Layout.php

1,271 lines 53.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // +----------------------------------------------------------------------+
4 // | Copyright 2013 Madpixels (email : visualizer@madpixels.net) |
5 // +----------------------------------------------------------------------+
6 // | This program is free software; you can redistribute it and/or modify |
7 // | it under the terms of the GNU General Public License, version 2, as |
8 // | published by the Free Software Foundation. |
9 // | |
10 // | This program is distributed in the hope that it will be useful, |
11 // | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 // | GNU General Public License for more details. |
14 // | |
15 // | You should have received a copy of the GNU General Public License |
16 // | along with this program; if not, write to the Free Software |
17 // | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, |
18 // | MA 02110-1301 USA |
19 // +----------------------------------------------------------------------+
20 // | Author: Eugene Manuilov <eugene@manuilov.org> |
21 // +----------------------------------------------------------------------+
22 /**
23 * Layout rendering class.
24 *
25 * @category Visualizer
26 * @package Render
27 */
28 class Visualizer_Render_Layout extends Visualizer_Render {
29
30 /**
31 * Fallback time for live update option.
32 *
33 * @var float
34 */
35 public static $live_option_fallback_hour = 0.16; // 10 minutes
36
37 /**
38 * Renders template.
39 *
40 * @since 1.0.0
41 *
42 * @abstract
43 * @access protected
44 */
45 protected function _toHTML() {
46 // empty.
47 }
48
49 /**
50 * Show the layout by delegating the call to the layout-specific method with the params.
51 *
52 * @access public
53 */
54 public static function show( $layout ) {
55 return call_user_func( array( __CLASS__, '_render' . str_replace( ' ', '', ucwords( str_replace( '-', ' ', $layout ) ) ) ), func_get_args() );
56 }
57
58 /**
59 * Show the DB query box.
60 *
61 * @access public
62 */
63 public static function _renderDbQuery( $args ) {
64 global $wpdb;
65 $query = $args[1];
66 if ( ! $query ) {
67 $query = '
68 /* List Posts published per. month */
69 SELECT CONCAT( YEAR(post_date), "/", MONTH(post_date) ) as date, COUNT(*) AS post_count
70 FROM ' . $wpdb->prefix . 'posts
71 WHERE post_type = "post" AND post_status = "publish"
72 GROUP BY YEAR(post_date), MONTH(post_date)
73 ORDER BY YEAR(post_date) DESC, MONTH(post_date) DESC;';
74 }
75 ?>
76 <div id='visualizer-db-query' style="display: none">
77 <div class="visualizer-db-query-form">
78 <div>
79 <form id='db-query-form'>
80 <input type="hidden" name="chart_id" value="<?php echo $args[2]; ?>">
81 <?php do_action( 'visualizer_db_query_add_layout', $args ); ?>
82 <textarea name='query' class='visualizer-db-query' placeholder="<?php _e( 'Your query goes here', 'visualizer' ); ?>"><?php echo $query; ?></textarea>
83 </form>
84 <div class='db-wizard-error'></div>
85 </div>
86 <div>
87 <input type="button" class="button button-primary" id='visualizer-query-fetch' value='<?php _e( 'Show Results', 'visualizer' ); ?>'>
88 </div>
89 </div>
90 <div class='db-wizard-hints'>
91 <ul>
92 <li><?php echo __( 'Your database prefix is:', 'visualizer' ); ?> <span class="visualizer-emboss"><?php echo $wpdb->prefix; ?></span></li>
93 <li>
94 <?php
95 echo sprintf(
96 // translators: %1$s - HTML link tag, %2$s - HTML closing link tag.
97 __( 'For examples of queries and links to resources that you can use with this feature, please click %1$shere%2$s', 'visualizer' ),
98 '<a href="' . VISUALIZER_DB_QUERY_DOC_URL . '" target="_blank">',
99 '</a>'
100 );
101 ?>
102 </li>
103 <li>
104 <?php
105 echo sprintf(
106 // translators: %1$s - HTML link tag, %2$s - HTML closing link tag.
107 __( 'Use %1$sShift+Space%2$s for autocompleting keywords or table names.', 'visualizer' ),
108 '<span class="visualizer-emboss">',
109 '</span>'
110 );
111 ?>
112 </li>
113 <?php do_action( 'visualizer_db_query_add_hints', $args ); ?>
114 </ul>
115 </div>
116 <div class='db-wizard-results'></div>
117
118 </div>
119 <?php
120 }
121
122 /**
123 * Show the DB wizard's results table.
124 *
125 * @access public
126 */
127 public static function _renderDbWizardResults( $args ) {
128 $headers = $args[1];
129 $results = $args[2];
130 ob_start();
131 ?>
132 <table cellspacing="0" width="100%" id="results">
133 <thead>
134 <tr>
135 <?php
136 foreach ( $headers as $header ) {
137 echo '<th>' . $header['label'] . '</th>';
138 }
139 ?>
140 </tr>
141 </thead>
142 <tfoot>
143 </tfoot>
144 <tbody>
145 <?php
146 foreach ( $results as $result ) {
147 echo '<tr>';
148 foreach ( $result as $r ) {
149 echo '<td>' . $r . '</td>';
150 }
151 echo '</tr>';
152 }
153 ?>
154 </tbody>
155 </table>
156 <?php
157 return ob_get_clean();
158 }
159
160 /**
161 * Show the JSON/REST parameters boxes.
162 *
163 * @access public
164 */
165 public static function _renderJsonScreen( $args ) {
166 $id = $args[1];
167 $action = esc_url(
168 add_query_arg(
169 array(
170 'action' => Visualizer_Plugin::ACTION_JSON_SET_DATA,
171 'security' => wp_create_nonce( Visualizer_Plugin::ACTION_JSON_SET_DATA . Visualizer_Plugin::VERSION ),
172 'chart' => $id,
173 ),
174 admin_url( 'admin-ajax.php' )
175 )
176 );
177
178 $is_wc_source = get_post_meta( $id, Visualizer_Plugin::CF_IS_WOOCOMMERCE_SOURCE, true );
179 $url = get_post_meta( $id, Visualizer_Plugin::CF_JSON_URL, true );
180 $root = get_post_meta( $id, Visualizer_Plugin::CF_JSON_ROOT, true );
181 $paging = get_post_meta( $id, Visualizer_Plugin::CF_JSON_PAGING, true );
182 $headers = get_post_meta( $id, Visualizer_Plugin::CF_JSON_HEADERS, true );
183 if ( empty( $headers ) ) {
184 $headers = array();
185 }
186 if ( $headers && empty( $headers['method'] ) ) {
187 $headers['method'] = 'get';
188 }
189 $methods = apply_filters( 'visualizer_json_request_methods', array( 'GET', 'POST' ) );
190
191 // open the headers by default?
192 $headers_open = $headers && array_key_exists( 'auth', $headers ) && ( array_key_exists( 'username', $headers['auth'] ) && ! empty( $headers['auth']['username'] ) ) || ( ! empty( $headers['auth'] ) && is_string( $headers['auth'] ) );
193 ?>
194 <div id="visualizer-json-screen" style="display: none">
195 <div class="visualizer-json-form">
196 <h3 class="viz-step step1"><?php _e( 'STEP 1: Specify the JSON endpoint/URL', 'visualizer' ); ?></h3>
197 <div>
198 <form id="json-endpoint-form">
199 <div class="json-wizard-hints">
200 <ul class="info">
201 <li>
202 <?php
203 echo sprintf(
204 // translators: %1$s - HTML link tag, %2$s - HTML closing link tag.
205 __( 'If you want to add authentication or headers to the endpoint or change the request in any way, please refer to our document %1$shere%2$s.', 'visualizer' ),
206 '<a href="https://docs.themeisle.com/article/1043-visualizer-how-to-extend-rest-endpoints-with-json-response" target="_blank">',
207 '</a>'
208 );
209 ?>
210 </li>
211 </ul>
212 </div>
213
214 <input
215 type="url"
216 id="vz-import-json-url"
217 name="url"
218 value="<?php echo esc_url( $url ); ?>"
219 placeholder="<?php esc_html_e( 'Please enter the URL', 'visualizer' ); ?>"
220 class="visualizer-input json-form-element"
221 <?php echo $is_wc_source ? 'readonly' : ''; ?>
222 >
223 <button class="button button-secondary button-small" id="visualizer-json-fetch"><?php esc_html_e( 'Fetch Endpoint', 'visualizer' ); ?></button>
224
225 <div class="visualizer-json-subform">
226 <h3 class="viz-substep <?php echo $headers_open ? 'open' : ''; ?>"><?php _e( 'Headers', 'visualizer' ); ?></h3>
227 <div class="json-wizard-headers">
228 <div class="json-wizard-header">
229 <div><?php _e( 'Request Type', 'visualizer' ); ?></div>
230 <div>
231 <select name="method" class="json-form-element">
232 <?php foreach ( $methods as $method ) { ?>
233 <option value="<?php echo $method; ?>" <?php $headers && selected( $headers['method'], $method ); ?>><?php echo $method; ?></option>
234 <?php } ?>
235 </select>
236 </div>
237 </div>
238 <div class="json-wizard-header">
239 <div><?php _e( 'Credentials', 'visualizer' ); ?></div>
240 <div>
241 <input
242 type="text"
243 id="vz-import-json-username"
244 name="username"
245 value="<?php echo ( array_key_exists( 'auth', $headers ) && array_key_exists( 'username', $headers['auth'] ) ? $headers['auth']['username'] : '' ); ?>"
246 placeholder="<?php esc_html_e( 'Username/Access Key', 'visualizer' ); ?>"
247 class="json-form-element">
248 &
249 <input
250 type="password"
251 id="vz-import-json-password"
252 name="password"
253 value="<?php echo ( array_key_exists( 'auth', $headers ) && array_key_exists( 'password', $headers['auth'] ) ? $headers['auth']['password'] : '' ); ?>"
254 placeholder="<?php esc_html_e( 'Password/Secret Key', 'visualizer' ); ?>"
255 class="json-form-element">
256 </div>
257 </div>
258 <div class="json-wizard-header">
259 <div></div>
260 <div><?php esc_html_e( 'OR', 'visualizer' ); ?></div>
261 </div>
262 <div class="json-wizard-header">
263 <div><?php esc_html_e( 'Authorization', 'visualizer' ); ?></div>
264 <div>
265 <input
266 type="text"
267 id="vz-import-json-auth"
268 name="auth"
269 value="<?php echo ( array_key_exists( 'auth', $headers ) && is_string( $headers['auth'] ) ? $headers['auth'] : '' ); ?>"
270 placeholder="<?php esc_html_e( 'e.g. SharedKey <AccountName>:<Signature>', 'visualizer' ); ?>"
271 class="visualizer-input json-form-element">
272 </div>
273 </div>
274 <div class="json-wizard-header">
275 <div class="field-title"><?php esc_html_e( 'Additional headers', 'visualizer' ); ?></div>
276 <div>
277 <textarea name="additional_headers" class="visualizer-input" placeholder="<?php esc_html_e( 'Key:Value, Key2:Value2,...', 'visualizer' ); ?>"><?php echo isset( $headers['additional_headers'] ) ? $headers['additional_headers'] : ''; ?></textarea>
278 </div>
279 </div>
280 </div>
281 </div>
282 </form>
283 </div>
284 <h3 class="viz-step step2 <?php echo empty( $url ) ? 'ui-state-disabled' : ''; ?> json-root-form"><?php _e( 'STEP 2: Choose the JSON root', 'visualizer' ); ?></h3>
285 <div>
286 <form id="json-root-form">
287 <input type="hidden" name="chart" value="<?php echo $id; ?>">
288 <select name="root" id="vz-import-json-root" class="json-form-element">
289 <?php
290 if ( ! empty( $root ) ) {
291 ?>
292 <option value="<?php echo esc_attr( $root ); ?>"><?php echo str_replace( Visualizer_Source_Json::TAG_SEPARATOR, Visualizer_Source_Json::TAG_SEPARATOR_VIEW, $root ); ?></option>
293 <?php
294 }
295 ?>
296 </select>
297 <button class="button button-secondary button-small" id="visualizer-json-parse"><?php esc_html_e( 'Parse Endpoint', 'visualizer' ); ?></button>
298 </form>
299 </div>
300 <h3 class="viz-step step3 <?php echo empty( $root ) ? 'ui-state-disabled' : ''; ?>"><?php _e( 'STEP 3: Specify miscellaneous parameters', 'visualizer' ); ?></h3>
301 <div>
302 <form id="json-conclude-form-helper">
303 <div class="<?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature' ); ?>">
304 <div class="json-pagination">
305 <select name="paging" id="vz-import-json-paging" class="json-form-element" data-template='<?php echo sprintf( 'Get results from the first %d pages using %s', apply_filters( 'visualizer_json_fetch_pages', 5, $url ), '?' ); ?>'>
306 <option value="0" class="static"><?php _e( 'Get results from the first page only', 'visualizer' ); ?></option>
307 <?php
308 if ( ! empty( $paging ) ) {
309 ?>
310 <option value="<?php echo esc_attr( $paging ); ?>"><?php echo sprintf( 'Get results from the first %d pages using %s', apply_filters( 'visualizer_json_fetch_pages', 5, $url ), str_replace( Visualizer_Source_Json::TAG_SEPARATOR, Visualizer_Source_Json::TAG_SEPARATOR_VIEW, $paging ) ); ?></option>
311 <?php
312 }
313 ?>
314 </select>
315 <?php
316 if ( ! Visualizer_Module::is_pro() ) {
317 ?>
318 <br/>
319 <br/>
320 <br/>
321 <br/>
322 <?php
323 }
324 ?>
325 <?php echo apply_filters( 'visualizer_pro_upsell', '' ); ?>
326 </div>
327 </div>
328 </form>
329 </div>
330 <h3 class="viz-step step4 ui-state-disabled"><?php _e( 'STEP 4: Select the data to display in the chart', 'visualizer' ); ?></h3>
331 <div>
332 <form id="json-conclude-form" action="<?php echo $action; ?>" method="post" target="thehole">
333 <div class="json-wizard-hints html-table-editor-hints">
334 <ul class="info">
335 <li><?php _e( 'If you see Invalid Data in the table, you may have selected the wrong root to fetch data from. Please select an alternative from the JSON root dropdown.', 'visualizer' ); ?></li>
336 <li><?php _e( 'Select whether to include the data in the chart. Each column selected will form one series.', 'visualizer' ); ?></li>
337 <li><?php _e( 'If a column is selected to be included, specify its data type.', 'visualizer' ); ?></li>
338 <li><?php _e( 'You can use drag/drop to reorder the columns but this column position is not saved. So when you reload the table, you may have to reorder again.', 'visualizer' ); ?></li>
339 <li><?php _e( 'You can select any number of columns but the chart type selected will determine how many will display in the chart.', 'visualizer' ); ?></li>
340 <li><?php _e( 'Once you have made your selection, click \'Show Chart\' on the right to view the chart.', 'visualizer' ); ?></li>
341 </ul>
342 </div>
343 <div class="json-table"></div>
344 <button class="button button-primary" style="display: none" id="visualizer-json-conclude"></button>
345 </form>
346 </div>
347 </div>
348 </div>
349 <?php
350 }
351
352 /**
353 * Show the simple editor(s).
354 *
355 * @access public
356 */
357 public static function _renderSimpleEditorScreen( $args ) {
358 $chart_id = $args[1];
359 $action = esc_url(
360 add_query_arg(
361 array(
362 'action' => Visualizer_Plugin::ACTION_UPLOAD_DATA,
363 'nonce' => wp_create_nonce(),
364 'chart' => $chart_id,
365 ),
366 admin_url( 'admin-ajax.php' )
367 )
368 );
369 ?>
370 <div class="viz-simple-editor">
371 <div class="viz-simple-editor-type viz-table-editor">
372 <form id="table-editor-form" action="<?php echo $action; ?>" method="post" target="thehole">
373 <div class="html-table-editor-hints">
374 <ul class="info">
375 <li><?php _e( 'Select whether to include the data in the chart. Each column selected will form one series.', 'visualizer' ); ?></li>
376 <li><?php _e( 'If a column is selected to be included, specify its data type.', 'visualizer' ); ?></li>
377 <li><?php _e( 'You can use drag/drop to reorder the columns but this column position is not saved. So when you reload the table, you may have to reorder again.', 'visualizer' ); ?></li>
378 <li><?php _e( 'You can select any number of columns but the chart type selected will determine how many will display in the chart.', 'visualizer' ); ?></li>
379 </ul>
380 </div>
381 <div class="viz-html-table">
382 <?php Visualizer_Render_Layout::show( 'editor-table', null, $chart_id, 'viz-html-table', true, true ); ?>
383 </div>
384 <input type="hidden" name="table_data" value="yes">
385 <input type="hidden" name="editor-type" value="table">
386 </form>
387 </div>
388
389 <?php Visualizer_Render_Layout::show( 'text-editor', $chart_id ); ?>
390
391 </div>
392 <?php
393
394 }
395
396 /**
397 * Show the text area editor.
398 *
399 * @access public
400 */
401 public static function _renderTextEditor( $args ) {
402 $chart_id = $args[1];
403 $csv = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA_AS, array(), $chart_id, 'csv-display' );
404 $data = '';
405 if ( ! empty( $csv ) && isset( $csv['string'] ) ) {
406 $data = str_replace( PHP_EOL, "\n", stripslashes( $csv['string'] ) );
407 }
408 ?>
409 <div class="viz-simple-editor-type viz-text-editor">
410 <textarea id="edited_text"><?php echo $data; ?></textarea>
411 </div>
412 <?php
413 }
414
415 /**
416 * Show the JSON endpoint's parsed table.
417 *
418 * @access public
419 */
420 public static function _renderEditorTable( $args ) {
421 $data = $args[1];
422 $chart_id = $args[2];
423 $class = $args[3];
424 $echo = $args[4];
425 $editable_data = $args[5];
426 $series = get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true );
427 $headers = array();
428
429 if ( is_null( $data ) ) {
430 foreach ( $series as $column ) {
431 $headers[] = $column['label'];
432 }
433 $chart = get_post( $chart_id );
434 $type = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true );
435 $data = Visualizer_Module::get_chart_data( $chart, $type );
436 } else {
437 $headers = array_keys( $data[0] );
438 }
439
440 $classes = implode( ' ', array( 'viz-editor-table', $class ) );
441
442 if ( $series ) {
443 $temp = $series;
444 $series = array();
445 foreach ( $temp as $array ) {
446 $series[ $array['label'] ] = $array['type'];
447 }
448 }
449 if ( ! $echo ) {
450 ob_start();
451 }
452 ?>
453 <table cellspacing="0" width="100%" class="results cell-border stripe <?php echo $classes; ?>">
454 <thead>
455 <tr>
456 <th><?php _e( 'Label', 'visualizer' ); ?></th>
457 <?php
458 foreach ( $headers as $header ) {
459 if ( $editable_data ) {
460 echo '<th><input type="text" name="header[]" value="' . esc_attr( $header ) . '"></th>';
461 } else {
462 echo '<th>' . $header . '</th>';
463 }
464 }
465 ?>
466 </tr>
467 </thead>
468 <tbody>
469 <tr>
470 <th><?php _e( 'Data Type', 'visualizer' ); ?></th>
471 <?php
472 $index = 0;
473 foreach ( $headers as $header ) {
474 echo '<td>';
475 if ( $editable_data ) {
476 echo '<select name="type[]">';
477 } else {
478 echo '<input name="header[]" type="hidden" value="' . $header . '">';
479 echo '<select name="type[' . $header . ']" class="viz-select-data-type">';
480 }
481 echo '<option value="" title="' . __( 'Exclude from chart', 'visualizer' ) . '">' . __( 'Exclude', 'visualizer' ) . '</option>';
482 echo '<option value="0" disabled title="' . __( 'Include in chart and select data type', 'visualizer' ) . '">--' . __( 'OR', 'visualizer' ) . '--</option>';
483
484 foreach ( Visualizer_Source::getAllowedTypes() as $type ) {
485 $selected = array_key_exists( $header, $series ) && $type === $series[ $header ] ? 'selected' : '';
486 echo '<option value="' . $type . '" ' . $selected . '>' . $type . '</option>';
487 }
488
489 echo '</select></td>';
490 }
491 ?>
492 </tr>
493 <?php
494 // for remote sources, the data exists inside 'data'.
495 if ( array_key_exists( 'data', $data ) ) {
496 $data = $data['data'];
497 }
498
499 foreach ( $data as $row ) {
500 echo '<tr>';
501 echo '<th>' . __( 'Value', 'visualizer' ) . '</th>';
502 $index = 0;
503 if ( empty( $row ) ) {
504 echo '<td></td>';
505 continue;
506 }
507 foreach ( array_values( $row ) as $value ) {
508 if ( $editable_data ) {
509 echo '<td><input type="text" name="data' . $index++ . '[]" value="' . esc_attr( stripslashes( $value ) ) . '"></td>';
510 } else {
511 echo '<td>' . ( is_array( $value ) ? __( 'Invalid Data', 'visualizer' ) : $value ) . '</td>';
512 }
513 }
514
515 echo '</tr>';
516 }
517 ?>
518 </tbody>
519 </table>
520 <?php
521 if ( ! $echo ) {
522 return ob_get_clean();
523 }
524 }
525
526 /**
527 * Generates the permissions tab.
528 *
529 * @access private
530 */
531 private static function _renderPermissions( $args ) {
532 $chart_id = $args[1];
533
534 // ignore for unit tests because Travis throws the error "Indirect modification of overloaded property Visualizer_Render_Page_Data::$permissions has no effect".
535 if ( defined( 'WP_TESTS_DOMAIN' ) ) {
536 return;
537 }
538
539 $permissions = apply_filters( 'visualizer_pro_get_permissions', null, $chart_id );
540 if ( is_array( $permissions ) ) {
541 $permissions = $permissions['permissions'];
542 } else {
543 $permissions = array();
544 }
545 if ( ! isset( $permissions['read'] ) ) {
546 $permissions['read'] = 'all';
547 }
548 if ( ! isset( $permissions['edit'] ) ) {
549 $permissions['edit'] = 'roles';
550 $permissions['edit-specific'] = 'administrator';
551 }
552
553 Visualizer_Render_Sidebar::_renderGroupStart( esc_html__( 'Permissions', 'visualizer' ) . '<span class="dashicons dashicons-lock"></span>', '', apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'chart-permissions' ), 'vz-permissions' );
554 echo '<div style="position: relative">';
555 Visualizer_Render_Sidebar::_renderSectionStart();
556 Visualizer_Render_Sidebar::_renderSectionDescription( esc_html__( 'Configure permissions for the chart.', 'visualizer' ) );
557 Visualizer_Render_Sidebar::_renderSectionEnd();
558
559 Visualizer_Render_Sidebar::_renderSectionStart( esc_html__( 'Who can see this chart?', 'visualizer' ), false );
560 Visualizer_Render_Sidebar::_renderSelectItem(
561 '',
562 'permissions[read]',
563 $permissions['read'],
564 array(
565 'all' => esc_html__( 'All Users', 'visualizer' ),
566 'users' => esc_html__( 'Select Users', 'visualizer' ),
567 'roles' => esc_html__( 'Select Roles', 'visualizer' ),
568 ),
569 '',
570 false,
571 array( 'visualizer-permission', 'visualizer-permission-type', 'visualizer-permission-read' ),
572 array(
573 'permission-type' => 'read',
574 )
575 );
576
577 $options = apply_filters( 'visualizer_pro_get_permissions_data', array(), isset( $permissions['read'] ) ? $permissions['read'] : 'roles' );
578
579 Visualizer_Render_Sidebar::_renderSelectItem(
580 '',
581 'permissions[read-specific][]',
582 isset( $permissions['read-specific'] ) ? $permissions['read-specific'] : array(),
583 $options,
584 '',
585 true,
586 array( 'visualizer-permission', 'visualizer-permission-specific', 'visualizer-permission-read-specific' )
587 );
588 Visualizer_Render_Sidebar::_renderSectionEnd();
589
590 Visualizer_Render_Sidebar::_renderSectionStart( esc_html__( 'Who can edit this chart?', 'visualizer' ), false );
591 Visualizer_Render_Sidebar::_renderSelectItem(
592 '',
593 'permissions[edit]',
594 $permissions['edit'],
595 array(
596 'all' => esc_html__( 'All Users', 'visualizer' ),
597 'users' => esc_html__( 'Select Users', 'visualizer' ),
598 'roles' => esc_html__( 'Select Roles', 'visualizer' ),
599 ),
600 '',
601 false,
602 array( 'visualizer-permission', 'visualizer-permission-type', 'visualizer-permission-edit' ),
603 array(
604 'permission-type' => 'edit',
605 )
606 );
607
608 $options = apply_filters( 'visualizer_pro_get_permissions_data', array(), isset( $permissions['edit'] ) ? $permissions['edit'] : 'roles' );
609
610 Visualizer_Render_Sidebar::_renderSelectItem(
611 '',
612 'permissions[edit-specific][]',
613 isset( $permissions['edit-specific'] ) ? $permissions['edit-specific'] : array(),
614 $options,
615 '',
616 true,
617 array( 'visualizer-permission', 'visualizer-permission-specific', 'visualizer-permission-edit-specific' )
618 );
619 Visualizer_Render_Sidebar::_renderSectionEnd();
620 echo apply_filters( 'visualizer_pro_upsell', '', 'chart-permissions' );
621 echo '</div>';
622 Visualizer_Render_Sidebar::_renderGroupEnd();
623 }
624
625 /**
626 * Show the Settings tab for this chart.
627 *
628 * @access public
629 */
630 public static function _renderTabAdvanced( $args ) {
631 $chart_id = $args[1];
632 $sidebar = $args[2];
633
634 $chart_options = get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true );
635 $backend_title = isset( $chart_options['backend-title'] ) && ! empty( $chart_options['backend-title'] ) ? $chart_options['backend-title'] : '';
636
637 ?>
638 <ul class="viz-group-wrapper full-height">
639 <li class="viz-group open" id="vz-chart-settings">
640 <ul class="viz-group-content">
641 <ul class="viz-group-wrapper">
642 <form id="settings-form" action="<?php echo esc_url( add_query_arg( 'nonce', wp_create_nonce() ) ); ?>" method="post">
643 <input type="hidden" id="chart-img" name="chart-img">
644 <input type="hidden" id="backend-title" name="backend-title" value="<?php echo esc_html( $backend_title ); ?>">
645 <?php echo $sidebar; ?>
646 <?php self::_renderPermissions( $args ); ?>
647 <input type="hidden" name="save" value="1">
648 </form>
649 <form id="cancel-form" action="<?php echo esc_url( add_query_arg( 'nonce', wp_create_nonce() ) ); ?>" method="post">
650 <input type="hidden" name="cancel" value="1">
651 </form>
652 </ul>
653 </ul>
654 </li>
655 <?php
656 }
657
658 /**
659 * Show the Docs tab for this chart.
660 *
661 * @access public
662 */
663 public static function _renderTabHelp( $args ) {
664 $chart_id = $args[1];
665 $type = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true );
666 switch ( $type ) {
667 case 'tabular':
668 $type = 'table';
669 break;
670 case 'polarArea':
671 $type = 'polar-area';
672 break;
673 case 'radar':
674 $type = 'radar-spider';
675 break;
676 }
677
678 $displayType = str_replace( '-', '/', $type );
679 ?>
680 <ul class="viz-group-wrapper full-height">
681 <li class="viz-group open" id="vz-chart-help">
682 <ul class="viz-group-wrapper">
683 <?php
684 // open this tab by default.
685 Visualizer_Render_Sidebar::_renderGroupStart( esc_html__( 'Documentation', 'visualizer' ), '', 'open' );
686 Visualizer_Render_Sidebar::_renderSectionStart( esc_html__( 'General', 'visualizer' ), true );
687 ?>
688 <h4><span class="dashicons dashicons-editor-help"></span><a href="<?php echo VISUALIZER_MAIN_DOC; ?>" target="_blank"><?php _e( 'Main documentation page', 'visualizer' ); ?></a></h4>
689 <h4><span class="dashicons dashicons-media-code"></span><a href="<?php echo VISUALIZER_CODE_SNIPPETS_URL; ?>" target="_blank"><?php _e( 'Custom code snippets', 'visualizer' ); ?></a></h4>
690 <?php
691 Visualizer_Render_Sidebar::_renderSectionEnd();
692 // translators: %s - the chart type.
693 Visualizer_Render_Sidebar::_renderSectionStart( sprintf( __( '%s chart', 'visualizer' ), ucwords( $displayType ) ), true );
694 ?>
695 <h4><span class="dashicons dashicons-video-alt2"></span>&nbsp;<a href="<?php echo str_replace( '#', "$type-chart", VISUALIZER_DEMO_URL ); ?>" target="_blank"><?php _e( 'View demo', 'visualizer' ); ?></a></h4>
696 <h4><span class="dashicons dashicons-search"></span><a href="<?php echo str_replace( '#', $type, VISUALIZER_DOC_COLLECTION ); ?>" target="_blank">
697 <?php
698 echo sprintf(
699 // translators: %s - the chart type.
700 __( 'Articles containing "%s"', 'visualizer' ),
701 $displayType
702 );
703 ?>
704 </a>
705 </h4>
706 <?php
707 Visualizer_Render_Sidebar::_renderSectionEnd();
708 Visualizer_Render_Sidebar::_renderGroupEnd();
709 ?>
710 </ul>
711 </li>
712 </ul>
713
714 <?php
715 }
716
717 /**
718 * Show the Data Source tab for this chart.
719 *
720 * @access public
721 */
722 public static function _renderTabBasic( $args ) {
723 $chart_id = $args[1];
724
725 $upload_link = esc_url(
726 add_query_arg(
727 array(
728 'action' => Visualizer_Plugin::ACTION_UPLOAD_DATA,
729 'nonce' => wp_create_nonce(),
730 'chart' => $chart_id,
731 ),
732 admin_url( 'admin-ajax.php' )
733 )
734 );
735
736 // this will allow us to open the correct source tab by default.
737 $source_of_chart = strtolower( get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true ) );
738 // Import from woocommerce report.
739 $is_woocommerce_source = strtolower( get_post_meta( $chart_id, Visualizer_Plugin::CF_IS_WOOCOMMERCE_SOURCE, true ) );
740 if ( ! empty( $is_woocommerce_source ) ) {
741 $source_of_chart .= '_wc';
742 }
743 // both import from wp and import from db have the same source so we need to differentiate.
744 $filter_config = get_post_meta( $chart_id, Visualizer_Plugin::CF_FILTER_CONFIG, true );
745 // if filter config is present, then its import from wp.
746 if ( ! empty( $filter_config ) ) {
747 $source_of_chart .= '_wp';
748 }
749 $editor_type = get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, true );
750 if (
751 $editor_type ||
752 ! Visualizer_Module::is_pro() // Use Manual Source for non-pro users since it is the only unlocked source.
753 ) {
754 $source_of_chart = 'visualizer_source_manual';
755 }
756
757 $type = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true );
758 $lib = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_LIBRARY, true );
759 ?>
760 <ul class="viz-group-wrapper full-height">
761 <li class="viz-group open" id="vz-chart-source">
762 <ul class="viz-group-content">
763 <ul class="viz-group-wrapper">
764 <!-- manual -->
765 <li class="viz-group visualizer_source_manual">
766 <h2 class="viz-group-title viz-sub-group visualizer-editor-tab" data-current="chart"><?php _e( 'Manual Data', 'visualizer' ); ?></h2>
767 <div class="viz-group-content edit-data-content">
768 <form id="editor-form" action="<?php echo $upload_link; ?>" method="post" target="thehole">
769 <input type="hidden" id="chart-data" name="chart_data">
770 <input type="hidden" id="chart-data-src" name="chart_data_src">
771
772 <?php if ( Visualizer_Module::can_show_feature( 'simple-editor' ) ) { ?>
773 <div>
774 <p class="viz-group-description viz-editor-selection">
775 <?php _e( 'Use the', 'visualizer' ); ?>
776 <select name="editor-type" id="viz-editor-type">
777 <?php
778 if ( empty( $editor_type ) ) {
779 $editor_type = Visualizer_Module::is_pro() ? 'excel' : 'text';
780 }
781 foreach ( apply_filters( 'visualizer_editors', array( 'text' => __( 'Text', 'visualizer' ), 'table' => __( 'Simple', 'visualizer' ) ) ) as $e_type => $e_label ) {
782 ?>
783 <option value="<?php echo $e_type; ?>" <?php selected( $editor_type, $e_type ); ?> ><?php echo $e_label; ?></option>
784 <?php } ?>
785 </select>
786 <?php _e( 'editor to manually edit the chart data.', 'visualizer' ); ?>
787 </p>
788 <input type="button" id="editor-undo" class="button button-secondary" style="display: none" value="<?php _e( 'Undo Changes', 'visualizer' ); ?>">
789 <input type="button" id="editor-button" class="button button-primary "
790 value="<?php _e( 'Edit Data', 'visualizer' ); ?>" data-current="chart"
791 data-t-editor="<?php _e( 'Show Chart', 'visualizer' ); ?>"
792 data-t-chart="<?php _e( 'Edit Data', 'visualizer' ); ?>"
793 >
794 <p class="viz-group-description viz-info-msg"><?php echo sprintf( __( 'Please make sure you click \'Show Chart\' before you save the chart.', 'visualizer' ) ); ?></p>
795 </div>
796 <?php } else { ?>
797 <input type="button" id="editor-undo" class="button button-secondary" style="display: none" value="<?php _e( 'Undo Changes', 'visualizer' ); ?>">
798 <input type="button" id="editor-chart-button" class="button button-primary "
799 value="<?php _e( 'View Editor', 'visualizer' ); ?>" data-current="chart"
800 data-t-editor="<?php _e( 'Show Chart', 'visualizer' ); ?>"
801 data-t-chart="<?php _e( 'View Editor', 'visualizer' ); ?>"
802 >
803 <p class="viz-group-description viz-info-msg"><?php echo sprintf( __( 'Please make sure you click \'Show Chart\' before you save the chart.', 'visualizer' ) ); ?></p>
804 <?php } ?>
805 </form>
806 </div>
807 </li>
808
809 <!-- import from file -->
810 <li class="viz-group visualizer_source_csv <?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'import-file' ); ?> ">
811 <h2 class="viz-group-title viz-sub-group visualizer-src-tab"><?php _e( 'Import data from file', 'visualizer' ); ?><span class="dashicons dashicons-lock"></span></h2>
812 <div class="viz-group-content">
813 <div>
814 <p class="viz-group-description"><?php esc_html_e( 'Select and upload your data CSV file here. The first row of the CSV file should contain the column headings. The second one should contain series type (string, number, boolean, date, datetime, timeofday).', 'visualizer' ); ?></p>
815 <p class="viz-group-description viz-info-msg">
816 <b>
817 <?php
818 echo sprintf(
819 // translators: $s - the chart type with the link attached.
820 __( 'If you are unsure about how to format your data CSV then please take a look at this sample: %s. If you are using non-English characters, please make sure you save the file in UTF-8 encoding.', 'visualizer' ),
821 '<a href="' . VISUALIZER_ABSURL . 'samples/' . $type . '.csv" target="_blank">' . $type . '.csv</a>'
822 );
823 ?>
824 </b>
825 </p>
826 <form id="vz-csv-file-form" action="<?php echo $upload_link; ?>" method="post"
827 target="thehole" enctype="multipart/form-data">
828 <input type="hidden" id="remote-data" name="remote_data">
829 <div class="">
830 <input type="file" id="csv-file" name="local_data">
831 </div>
832 <input type="button" class="button button-primary" id="vz-import-file"
833 value="<?php _e( 'Import', 'visualizer' ); ?>">
834 </form>
835 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'import-file' ); ?>
836 </div>
837 </div>
838 </li>
839 <!-- import from url -->
840 <li class="viz-group visualizer-import-url visualizer_source_csv_remote visualizer_source_json <?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'import-url' ); ?> ">
841 <h2 class="viz-group-title viz-sub-group visualizer-src-tab"><?php _e( 'Import data from URL', 'visualizer' ); ?><span class="dashicons dashicons-lock"></span></h2>
842 <ul class="viz-group-content">
843 <!-- import from csv url -->
844 <li class="viz-subsection">
845 <span class="viz-section-title"><?php _e( 'Import from CSV', 'visualizer' ); ?></span>
846 <div class="only-pro-anchor">
847 <div class="viz-section-items section-items">
848 <p class="viz-group-description">
849 <?php
850 echo sprintf(
851 // translators: %1$s - HTML link tag, %2$s - HTML closing link tag.
852 __( 'You can use this to import data from a remote CSV file or %1$sGoogle Spreadsheet%2$s.', 'visualizer' ),
853 '<a href="https://docs.themeisle.com/article/607-how-can-i-populate-data-from-google-spreadsheet" target="_blank" >',
854 '</a>'
855 );
856 ?>
857 </p>
858 <p class="viz-group-description viz-info-msg">
859 <b>
860 <?php
861 echo sprintf(
862 // translators: %s - the chart type with the link attached.
863 __( 'If you are unsure about how to format your data CSV then please take a look at this sample: %s. If you are using non-English characters, please make sure you save the file in UTF-8 encoding.', 'visualizer' ),
864 '<a href="' . VISUALIZER_ABSURL . 'samples/' . $type . '.csv" target="_blank">' . $type . '.csv</a>'
865 );
866 ?>
867 </b>
868 </p>
869 <form id="vz-one-time-import" action="<?php echo $upload_link; ?>" method="post"
870 target="thehole" enctype="multipart/form-data">
871 <div class="remote-file-section">
872 <input type="url" id="vz-schedule-url" name="remote_data" value="<?php echo esc_attr( get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_URL, true ) ); ?>" placeholder="<?php esc_html_e( 'Please enter the URL of CSV file', 'visualizer' ); ?>" class="visualizer-input visualizer-remote-url">
873 </div>
874 <select name="vz-import-time" id="vz-import-time" class="visualizer-select">
875 <?php
876 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_SCHEDULE, true );
877 $schedules = apply_filters(
878 'visualizer_chart_schedules', array(
879 '-1' => __( 'One-time', 'visualizer' ),
880 ),
881 'csv',
882 $chart_id
883 );
884 foreach ( $schedules as $num => $name ) {
885 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
886 $extra = self::is_hour_selected( $hours, $num ) ? 'selected' : '';
887 ?>
888 <option value="<?php echo $num; ?>" <?php echo $extra; ?>><?php echo $name; ?></option>
889 <?php
890 }
891 do_action( 'visualizer_chart_schedules_spl', 'csv', $chart_id, 1 );
892 ?>
893 </select>
894
895 <?php
896 if ( ! Visualizer_Module::is_pro() ) {
897 ?>
898 <input type="button" id="view-remote-file" class="button button-primary" value="<?php _e( 'Import', 'visualizer' ); ?>">
899 <?php
900 } else {
901 ?>
902 <input type="button" id="vz-save-schedule" class="button button-primary" value="<?php _e( 'Import & Save schedule', 'visualizer' ); ?>">
903 <?php
904 }
905 ?>
906 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'import-url' ); ?>
907 </form>
908 </div>
909 </div>
910 </li>
911 <!-- import from json url -->
912 <li class="viz-subsection">
913 <span class="viz-section-title visualizer_source_json"><?php _e( 'Import from JSON', 'visualizer' ); ?></span>
914 <div class="only-pro-anchor">
915 <div class="viz-section-items section-items">
916 <p class="viz-group-description"><?php _e( 'You can choose here to import/synchronize your chart data with a remote JSON source. For more info check <a href="https://docs.themeisle.com/article/1052-how-to-generate-charts-from-json-data-rest-endpoints" target="_blank" >this</a> tutorial', 'visualizer' ); ?></p>
917 <form id="vz-import-json" action="<?php echo $upload_link; ?>" method="post" target="thehole" enctype="multipart/form-data">
918 <div class="remote-file-section">
919 <?php
920 $bttn_label = 'visualizer_source_json' === $source_of_chart ? __( 'Modify Parameters', 'visualizer' ) : __( 'Create Parameters', 'visualizer' );
921 if ( Visualizer_Module::is_pro() ) {
922 ?>
923 <p class="viz-group-description"><?php _e( 'How often do you want to check the URL', 'visualizer' ); ?></p>
924 <select name="time" id="vz-json-time" class="visualizer-select json-form-element" data-chart="<?php echo $chart_id; ?>">
925 <?php
926 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, true );
927 $schedules = apply_filters(
928 'visualizer_chart_schedules', array(
929 '-1' => __( 'One-time', 'visualizer' ),
930 ),
931 'json',
932 $chart_id
933 );
934 foreach ( $schedules as $num => $name ) {
935 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
936 $extra = self::is_hour_selected( $hours, $num ) ? 'selected' : '';
937 ?>
938 <option value="<?php echo $num; ?>" <?php echo $extra; ?>><?php echo $name; ?></option>
939 <?php
940 }
941 do_action( 'visualizer_chart_schedules_spl', 'json', $chart_id, 1 );
942 ?>
943 </select>
944 <?php
945 }
946 ?>
947 </div>
948
949 <input type="button" id="json-chart-button" class="button button-secondary show-chart-toggle"
950 value="<?php echo $bttn_label; ?>" data-current="chart"
951 data-t-filter="<?php _e( 'Show Chart', 'visualizer' ); ?>"
952 data-t-chart="<?php echo $bttn_label; ?>">
953 <?php
954 if ( Visualizer_Module::is_pro() ) {
955 ?>
956 <input type="button" id="json-chart-save-button" class="button button-primary "
957 value="<?php _e( 'Save Schedule', 'visualizer' ); ?>">
958 <?php
959 }
960 ?>
961 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'import-url' ); ?>
962 </form>
963 </div>
964 </div>
965 </li>
966 </ul>
967 </li>
968 <!-- import from chart -->
969 <li class="viz-group viz-import-from-other <?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature' ); ?>">
970 <h2 class="viz-group-title viz-sub-group"
971 data-current="chart"><?php _e( 'Import from other chart', 'visualizer' ); ?><span
972 class="dashicons dashicons-lock"></span></h2>
973 <div class="viz-group-content edit-data-content">
974 <div>
975 <p class="viz-group-description"><?php _e( 'You can import here data from your previously created charts', 'visualizer' ); ?></p>
976 <form>
977 <select name="vz-import-from-chart" id="chart-id" class="visualizer-select">
978 <?php
979 $fetch_link = esc_url(
980 add_query_arg(
981 array(
982 'action' => Visualizer_Module::is_pro() ? Visualizer_Pro::ACTION_FETCH_DATA : '',
983 'nonce' => wp_create_nonce(),
984 ),
985 admin_url( 'admin-ajax.php' )
986 )
987 );
988 $query_args_charts = array(
989 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
990 'posts_per_page' => 300,
991 'no_found_rows' => true,
992 );
993 $charts = array();
994 $query = new WP_Query( $query_args_charts );
995 while ( $query->have_posts() ) {
996 $chart = $query->next_post();
997 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
998
999 $title = '#' . $chart->ID;
1000 if ( ! empty( $settings['title'] ) ) {
1001 $title = $settings['title'];
1002 }
1003 // for ChartJS, title is an array.
1004 if ( is_array( $title ) && isset( $title['text'] ) ) {
1005 $title = $title['text'];
1006 }
1007 if ( empty( $title ) ) {
1008 $title = '#' . $chart->ID;
1009 }
1010
1011 ?>
1012 <option value="<?php echo $chart->ID; ?>"><?php echo $title; ?></option>
1013 <?php
1014 }
1015 ?>
1016
1017 </select>
1018 </form>
1019 <input type="button" id="existing-chart" class="button button-primary"
1020 value="<?php _e( 'Import Chart', 'visualizer' ); ?>"
1021 data-viz-link="<?php echo $fetch_link; ?>">
1022 <?php
1023 if ( ! Visualizer_Module_Admin::proFeaturesLocked() ) {
1024 echo apply_filters( 'visualizer_pro_upsell', '', 'import-chart' );
1025 }
1026 ?>
1027 </div>
1028 </div>
1029 </li>
1030
1031 <?php
1032 $save_filter = esc_url(
1033 add_query_arg(
1034 array(
1035 'action' => Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY,
1036 'security' => wp_create_nonce( Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY . Visualizer_Plugin::VERSION ),
1037 'chart' => $chart_id,
1038 ), admin_url( 'admin-ajax.php' )
1039 )
1040 );
1041 ?>
1042 <!-- import from WordPress -->
1043 <li class="viz-group visualizer_source_query_wp <?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'import-wp' ); ?> ">
1044 <h2 class="viz-group-title viz-sub-group"><?php _e( 'Import from WordPress', 'visualizer' ); ?><span
1045 class="dashicons dashicons-lock"></span></h2>
1046 <div class="viz-group-content edit-data-content">
1047 <div>
1048 <p class="viz-group-description"><?php _e( 'You can import data from WordPress here.', 'visualizer' ); ?></p>
1049 <form id="vz-filter-wizard" action="<?php echo $save_filter; ?>" method="post" target="thehole">
1050 <p class="viz-group-description"><?php _e( 'How often do you want to refresh the data from WordPress.', 'visualizer' ); ?></p>
1051 <select name="refresh" id="vz-filter-import-time" class="visualizer-select">
1052 <?php
1053 $bttn_label = 'visualizer_source_query_wp' === $source_of_chart ? __( 'Modify Filter', 'visualizer' ) : __( 'Create Filter', 'visualizer' );
1054 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, true );
1055 $schedules = apply_filters(
1056 'visualizer_chart_schedules', array(
1057 '-1' => __( 'One-time', 'visualizer' ),
1058 ),
1059 'wp',
1060 $chart_id
1061 );
1062 foreach ( $schedules as $num => $name ) {
1063 $extra = self::is_hour_selected( $hours, $num ) ? 'selected' : '';
1064 ?>
1065 <option value="<?php echo $num; ?>" <?php echo $extra; ?>><?php echo $name; ?></option>
1066 <?php
1067 }
1068 do_action( 'visualizer_chart_schedules_spl', 'wp', $chart_id, 1 );
1069 ?>
1070 </select>
1071
1072 <input type="button" id="filter-chart-button" class="button button-secondary show-chart-toggle" value="<?php echo $bttn_label; ?>" data-current="chart" data-t-filter="<?php _e( 'Show Chart', 'visualizer' ); ?>" data-t-chart="<?php echo $bttn_label; ?>">
1073 <input type="button" id="db-filter-save-button" class="button button-primary" value="<?php _e( 'Save Schedule', 'visualizer' ); ?>">
1074 </form>
1075 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'import-wp' ); ?>
1076 </div>
1077 </div>
1078 </li>
1079
1080 <!-- import from WooCommerce -->
1081 <?php
1082 if ( class_exists( 'WooCommerce', false ) ) :
1083 $wc_source = strtolower( get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_WOOCOMMERCE_SOURCE, true ) );
1084 $wc_source_list = apply_filters(
1085 'visualizer_woocommerce_report_endpoints',
1086 array(
1087 array(
1088 'name' => esc_html__( 'Sales', 'visualizer' ),
1089 'endpoint' => esc_attr( 'sales' ),
1090 ),
1091 array(
1092 'name' => esc_html__( 'Top Sellers', 'visualizer' ),
1093 'endpoint' => esc_attr( 'top_sellers' ),
1094 ),
1095 array(
1096 'name' => esc_html__( 'Coupons Totals', 'visualizer' ),
1097 'endpoint' => esc_attr( 'coupons/totals' ),
1098 ),
1099 array(
1100 'name' => esc_html__( 'Customers Totals', 'visualizer' ),
1101 'endpoint' => esc_attr( 'customers/totals' ),
1102 ),
1103 array(
1104 'name' => esc_html__( 'Orders Totals', 'visualizer' ),
1105 'endpoint' => esc_attr( 'orders/totals' ),
1106 ),
1107 array(
1108 'name' => esc_html__( 'Products Totals', 'visualizer' ),
1109 'endpoint' => esc_attr( 'products/totals' ),
1110 ),
1111 array(
1112 'name' => esc_html__( 'Reviews Totals', 'visualizer' ),
1113 'endpoint' => esc_attr( 'reviews/totals' ),
1114 ),
1115 )
1116 );
1117 ?>
1118 <li class="viz-group visualizer_woocommerce_source<?php echo 'visualizer_source_json_wc' === $source_of_chart ? ' open' : ''; ?> <?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'import-wc-report' ); ?> ">
1119 <h2 class="viz-group-title viz-sub-group"><?php _e( 'Import from WooCommerce Reports', 'visualizer' ); ?><span class="dashicons dashicons-lock"></span></h2>
1120 <div class="viz-group-content edit-data-content">
1121 <div>
1122 <p class="viz-group-description"><?php _e( 'You can choose here to import/synchronize your chart data with a WooCommerce report API. For more info check <a href="https://woocommerce.github.io/woocommerce-rest-api-docs/?shell#reports" target="_blank" >this</a> tutorial', 'visualizer' ); ?></p>
1123 <form id="vz-import-woo-report" action="<?php echo $upload_link; ?>" method="post" target="thehole" enctype="multipart/form-data">
1124 <div class="remote-file-section">
1125 <?php
1126 $bttn_label = 'visualizer_source_json_wc' === $source_of_chart ? __( 'Modify Parameters', 'visualizer' ) : __( 'Create Parameters', 'visualizer' );
1127 ?>
1128 <p class="viz-group-description"><?php _e( 'How often do you want to check the URL', 'visualizer' ); ?></p>
1129 <select name="time" id="vz-woo-time" class="visualizer-select json-form-element" data-chart="<?php echo $chart_id; ?>">
1130 <?php
1131 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, true );
1132 $schedules = apply_filters(
1133 'visualizer_chart_schedules', array(
1134 '-1' => __( 'One-time', 'visualizer' ),
1135 ),
1136 'json',
1137 $chart_id
1138 );
1139 foreach ( $schedules as $num => $name ) {
1140 $extra = self::is_hour_selected( $hours, $num ) ? 'selected' : '';
1141 ?>
1142 <option value="<?php echo $num; ?>" <?php echo $extra; ?>><?php echo $name; ?></option>
1143 <?php
1144 }
1145 do_action( 'visualizer_chart_schedules_spl', 'json', $chart_id, 1 );
1146 ?>
1147 </select>
1148 <p class="viz-group-description"><?php _e( 'Select report endpoint', 'visualizer' ); ?></p>
1149 <select name="vz_woo_source" id="vz-woo-source" class="visualizer-select json-form-element" data-chart="<?php echo $chart_id; ?>">
1150 <option value=""></option>
1151 <?php
1152 if ( ! empty( $wc_source_list ) ) {
1153 foreach ( $wc_source_list as $api ) {
1154 if ( isset( $api['name'] ) && $api['endpoint'] ) {
1155 echo sprintf( '<option value="%2$s" %3$s>%1$s</option>', $api['name'], $api['endpoint'], selected( $wc_source, $api['endpoint'], false ) ); // phpcs:ignore
1156 }
1157 }
1158 }
1159 ?>
1160 </select>
1161 </div>
1162
1163 <input type="button" id="woo-chart-button" class="button button-secondary show-chart-toggle"
1164 value="<?php echo $bttn_label; ?>" data-current="chart"
1165 data-t-filter="<?php _e( 'Show Chart', 'visualizer' ); ?>"
1166 data-t-chart="<?php echo $bttn_label; ?>"
1167 <?php empty( $wc_source ) ? 'disabled' : ''; ?>
1168 >
1169 <input type="button" id="woo-chart-save-button" class="button button-primary "
1170 value="<?php _e( 'Save Schedule', 'visualizer' ); ?>" <?php empty( $wc_source ) ? 'disabled' : ''; ?>>
1171 </form>
1172 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'import-wc-report' ); ?>
1173 </div>
1174 </div>
1175 </li>
1176 <?php endif; ?>
1177 <?php
1178 $save_query = esc_url(
1179 add_query_arg(
1180 array(
1181 'action' => Visualizer_Plugin::ACTION_SAVE_DB_QUERY,
1182 'security' => wp_create_nonce( Visualizer_Plugin::ACTION_SAVE_DB_QUERY . Visualizer_Plugin::VERSION ),
1183 'chart' => $chart_id,
1184 ), admin_url( 'admin-ajax.php' )
1185 )
1186 );
1187 ?>
1188 <!-- import from db -->
1189 <li class="viz-group visualizer_source_query <?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'db-query' ); ?>">
1190 <h2 class="viz-group-title viz-sub-group"><?php _e( 'Import from database', 'visualizer' ); ?><span
1191 class="dashicons dashicons-lock"></span></h2>
1192 <div class="viz-group-content edit-data-content">
1193 <div>
1194 <p class="viz-group-description"><?php _e( 'You can import data from the database here.', 'visualizer' ); ?></p>
1195 <form id="vz-db-wizard" action="<?php echo $save_query; ?>" method="post" target="thehole">
1196 <p class="viz-group-description"><?php _e( 'How often do you want to refresh the data from the database.', 'visualizer' ); ?></p>
1197 <select name="refresh" id="vz-db-import-time" class="visualizer-select">
1198 <?php
1199 $bttn_label = 'visualizer_source_query' === $source_of_chart ? __( 'Modify Query', 'visualizer' ) : __( 'Create Query', 'visualizer' );
1200 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, true );
1201 $schedules = apply_filters(
1202 'visualizer_chart_schedules', array(
1203 '-1' => __( 'One-time', 'visualizer' ),
1204 ),
1205 'db',
1206 $chart_id
1207 );
1208 foreach ( $schedules as $num => $name ) {
1209 $extra = self::is_hour_selected( $hours, $num ) ? 'selected' : '';
1210 ?>
1211 <option value="<?php echo $num; ?>" <?php echo $extra; ?>><?php echo $name; ?></option>
1212 <?php
1213 }
1214 do_action( 'visualizer_chart_schedules_spl', 'db', $chart_id, 1 );
1215 ?>
1216 </select>
1217 <input type="hidden" name="params" id="viz-db-wizard-params">
1218
1219 <input type="button" id="db-chart-button" class="button button-secondary show-chart-toggle" value="<?php echo $bttn_label; ?>" data-current="chart" data-t-filter="<?php _e( 'Show Chart', 'visualizer' ); ?>" data-t-chart="<?php echo $bttn_label; ?>">
1220 <input type="button" id="db-chart-save-button" class="button button-primary" value="<?php _e( 'Save Schedule', 'visualizer' ); ?>">
1221 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'db-query' ); ?>
1222 </form>
1223 </div>
1224 </div>
1225 </li>
1226 </ul>
1227 </li>
1228 </ul>
1229 </ul>
1230
1231 <span id="visualizer-chart-id" data-id="<?php echo $chart_id; ?>" data-chart-source="<?php echo esc_attr( $source_of_chart ); ?>" data-chart-type="<?php echo esc_attr( $type ); ?>" data-chart-lib="<?php echo esc_attr( $lib ); ?>"></span>
1232 <iframe id="thehole" name="thehole"></iframe>
1233 <?php
1234 }
1235
1236 /**
1237 * Check if the given hour is selected.
1238 *
1239 * @param int|float|string $hour The hour.
1240 * @param int|float|string $reference The number.
1241 *
1242 * @return bool
1243 */
1244 public static function is_hour_selected( $hour, $reference ) {
1245
1246 if ( ! is_numeric( $hour ) || ! is_numeric( $reference ) ) {
1247 return false;
1248 }
1249
1250 $hour = floatval( $hour );
1251 $reference = floatval( $reference );
1252
1253 if ( self::is_live_update_option( $reference ) ) {
1254 $reference = self::$live_option_fallback_hour;
1255 }
1256
1257 return abs( $hour - $reference ) < 0.000001;
1258 }
1259
1260 /**
1261 * Check if the reference option is deprecated live update option.
1262 *
1263 * @param float $reference_hour The reference hour.
1264 *
1265 * @return bool
1266 */
1267 public static function is_live_update_option( $reference_hour ) {
1268 return abs( $reference_hour ) < 0.000001;
1269 }
1270 }
1271