PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 4.0.8
Visualizer – Tables & Charts Manager with Built-in AI Generator v4.0.8
4.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 All 149 releases
visualizer / classes / Visualizer / Render / Layout.php

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

1,301 lines 55.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 $auth = isset( $headers['auth'] ) ? $headers['auth'] : '';
192 $auth_username = is_array( $auth ) && isset( $auth['username'] ) ? $auth['username'] : '';
193 $auth_password = is_array( $auth ) && isset( $auth['password'] ) ? $auth['password'] : '';
194 $auth_string = is_string( $auth ) ? $auth : '';
195
196 // open the headers by default?
197 $headers_open = ! empty( $auth_username ) || ! empty( $auth_string );
198 ?>
199 <div id="visualizer-json-screen" style="display: none">
200 <div class="visualizer-json-form">
201 <h3 class="viz-step step1"><?php _e( 'STEP 1: Specify the JSON endpoint/URL', 'visualizer' ); ?></h3>
202 <div>
203 <form id="json-endpoint-form">
204 <div class="json-wizard-hints">
205 <ul class="info">
206 <li>
207 <?php
208 echo sprintf(
209 // translators: %1$s - HTML link tag, %2$s - HTML closing link tag.
210 __( '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' ),
211 '<a href="https://docs.themeisle.com/article/1043-visualizer-how-to-extend-rest-endpoints-with-json-response" target="_blank">',
212 '</a>'
213 );
214 ?>
215 </li>
216 </ul>
217 </div>
218
219 <input
220 type="url"
221 id="vz-import-json-url"
222 name="url"
223 value="<?php echo esc_url( $url ); ?>"
224 placeholder="<?php esc_html_e( 'Please enter the URL', 'visualizer' ); ?>"
225 class="visualizer-input json-form-element"
226 <?php echo $is_wc_source ? 'readonly' : ''; ?>
227 >
228 <button class="button button-secondary button-small" id="visualizer-json-fetch"><?php esc_html_e( 'Fetch Endpoint', 'visualizer' ); ?></button>
229
230 <div class="visualizer-json-subform">
231 <h3 class="viz-substep <?php echo $headers_open ? 'open' : ''; ?>"><?php _e( 'Headers', 'visualizer' ); ?></h3>
232 <div class="json-wizard-headers">
233 <div class="json-wizard-header">
234 <div><?php _e( 'Request Type', 'visualizer' ); ?></div>
235 <div>
236 <select name="method" class="json-form-element">
237 <?php foreach ( $methods as $method ) { ?>
238 <option value="<?php echo $method; ?>" <?php $headers && selected( $headers['method'], $method ); ?>><?php echo $method; ?></option>
239 <?php } ?>
240 </select>
241 </div>
242 </div>
243 <div class="json-wizard-header">
244 <div><?php _e( 'Credentials', 'visualizer' ); ?></div>
245 <div>
246 <input
247 type="text"
248 id="vz-import-json-username"
249 name="username"
250 value="<?php echo esc_attr( $auth_username ); ?>"
251 placeholder="<?php esc_html_e( 'Username/Access Key', 'visualizer' ); ?>"
252 class="json-form-element">
253 &
254 <input
255 type="password"
256 id="vz-import-json-password"
257 name="password"
258 value="<?php echo esc_attr( $auth_password ); ?>"
259 placeholder="<?php esc_html_e( 'Password/Secret Key', 'visualizer' ); ?>"
260 class="json-form-element">
261 </div>
262 </div>
263 <div class="json-wizard-header">
264 <div></div>
265 <div><?php esc_html_e( 'OR', 'visualizer' ); ?></div>
266 </div>
267 <div class="json-wizard-header">
268 <div><?php esc_html_e( 'Authorization', 'visualizer' ); ?></div>
269 <div>
270 <input
271 type="text"
272 id="vz-import-json-auth"
273 name="auth"
274 value="<?php echo esc_attr( $auth_string ); ?>"
275 placeholder="<?php esc_html_e( 'e.g. SharedKey <AccountName>:<Signature>', 'visualizer' ); ?>"
276 class="visualizer-input json-form-element">
277 </div>
278 </div>
279 <div class="json-wizard-header">
280 <div class="field-title"><?php esc_html_e( 'Additional headers', 'visualizer' ); ?></div>
281 <div>
282 <textarea name="additional_headers" class="visualizer-input" placeholder="<?php esc_html_e( 'Key:Value, Key2:Value2,...', 'visualizer' ); ?>"><?php echo esc_textarea( isset( $headers['additional_headers'] ) ? $headers['additional_headers'] : '' ); ?></textarea>
283 </div>
284 </div>
285 </div>
286 </div>
287 </form>
288 </div>
289 <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>
290 <div>
291 <form id="json-root-form">
292 <input type="hidden" name="chart" value="<?php echo $id; ?>">
293 <select name="root" id="vz-import-json-root" class="json-form-element">
294 <?php
295 if ( ! empty( $root ) ) {
296 ?>
297 <option value="<?php echo esc_attr( $root ); ?>"><?php echo esc_html( str_replace( Visualizer_Source_Json::TAG_SEPARATOR, Visualizer_Source_Json::TAG_SEPARATOR_VIEW, $root ) ); ?></option>
298 <?php
299 }
300 ?>
301 </select>
302 <button class="button button-secondary button-small" id="visualizer-json-parse"><?php esc_html_e( 'Parse Endpoint', 'visualizer' ); ?></button>
303 </form>
304 </div>
305 <h3 class="viz-step step3 <?php echo empty( $root ) ? 'ui-state-disabled' : ''; ?>"><?php _e( 'STEP 3: Specify miscellaneous parameters', 'visualizer' ); ?></h3>
306 <div>
307 <form id="json-conclude-form-helper">
308 <div class="<?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature' ); ?>">
309 <div class="json-pagination">
310 <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 ), '?' ); ?>'>
311 <option value="0" class="static"><?php _e( 'Get results from the first page only', 'visualizer' ); ?></option>
312 <?php
313 if ( ! empty( $paging ) ) {
314 ?>
315 <option value="<?php echo esc_attr( $paging ); ?>"><?php echo esc_html( 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>
316 <?php
317 }
318 ?>
319 </select>
320 <?php
321 if ( ! Visualizer_Module::is_pro() ) {
322 ?>
323 <br/>
324 <br/>
325 <br/>
326 <br/>
327 <?php
328 }
329 ?>
330 <?php echo apply_filters( 'visualizer_pro_upsell', '' ); ?>
331 </div>
332 </div>
333 </form>
334 </div>
335 <h3 class="viz-step step4 ui-state-disabled"><?php _e( 'STEP 4: Select the data to display in the chart', 'visualizer' ); ?></h3>
336 <div>
337 <form id="json-conclude-form" action="<?php echo $action; ?>" method="post" target="thehole">
338 <div class="json-wizard-hints html-table-editor-hints">
339 <ul class="info">
340 <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>
341 <li><?php _e( 'Select whether to include the data in the chart. Each column selected will form one series.', 'visualizer' ); ?></li>
342 <li><?php _e( 'If a column is selected to be included, specify its data type.', 'visualizer' ); ?></li>
343 <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>
344 <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>
345 <li><?php _e( 'Once you have made your selection, click \'Show Chart\' on the right to view the chart.', 'visualizer' ); ?></li>
346 </ul>
347 </div>
348 <div class="json-table"></div>
349 <button class="button button-primary" style="display: none" id="visualizer-json-conclude"></button>
350 </form>
351 </div>
352 </div>
353 </div>
354 <?php
355 }
356
357 /**
358 * Show the simple editor(s).
359 *
360 * @access public
361 */
362 public static function _renderSimpleEditorScreen( $args ) {
363 $chart_id = $args[1];
364 $action = esc_url(
365 add_query_arg(
366 array(
367 'action' => Visualizer_Plugin::ACTION_UPLOAD_DATA,
368 'nonce' => wp_create_nonce( 'visualizer-upload-data' ),
369 'chart' => $chart_id,
370 ),
371 admin_url( 'admin-ajax.php' )
372 )
373 );
374 ?>
375 <div class="viz-simple-editor">
376 <div class="viz-simple-editor-type viz-table-editor">
377 <form id="table-editor-form" action="<?php echo $action; ?>" method="post" target="thehole">
378 <div class="html-table-editor-hints">
379 <ul class="info">
380 <li><?php _e( 'Select whether to include the data in the chart. Each column selected will form one series.', 'visualizer' ); ?></li>
381 <li><?php _e( 'If a column is selected to be included, specify its data type.', 'visualizer' ); ?></li>
382 <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>
383 <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>
384 </ul>
385 </div>
386 <div class="viz-html-table">
387 <?php Visualizer_Render_Layout::show( 'editor-table', null, $chart_id, 'viz-html-table', true, true ); ?>
388 </div>
389 <input type="hidden" name="table_data" value="yes">
390 <input type="hidden" name="editor-type" value="table">
391 </form>
392 </div>
393
394 <?php Visualizer_Render_Layout::show( 'text-editor', $chart_id ); ?>
395
396 </div>
397 <?php
398 }
399
400 /**
401 * Show the text area editor.
402 *
403 * @access public
404 */
405 public static function _renderTextEditor( $args ) {
406 $chart_id = $args[1];
407 $csv = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA_AS, array(), $chart_id, 'csv-display' );
408 $data = '';
409 if ( ! empty( $csv ) && isset( $csv['string'] ) ) {
410 $data = str_replace( PHP_EOL, "\n", stripslashes( $csv['string'] ) );
411 }
412 ?>
413 <div class="viz-simple-editor-type viz-text-editor">
414 <textarea id="edited_text"><?php echo $data; ?></textarea>
415 </div>
416 <?php
417 }
418
419 /**
420 * Show the JSON endpoint's parsed table.
421 *
422 * @access public
423 */
424 public static function _renderEditorTable( $args ) {
425 $data = $args[1];
426 $chart_id = $args[2];
427 $class = $args[3];
428 $echo = $args[4];
429 $editable_data = $args[5];
430 $series = get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true );
431 $headers = array();
432
433 if ( is_null( $data ) ) {
434 foreach ( $series as $column ) {
435 $headers[] = $column['label'];
436 }
437 $chart = get_post( $chart_id );
438 $type = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true );
439 $data = Visualizer_Module::get_chart_data( $chart, $type );
440 } else {
441 $headers = array_keys( $data[0] );
442 }
443
444 $classes = implode( ' ', array( 'viz-editor-table', $class ) );
445
446 if ( $series ) {
447 $temp = $series;
448 $series = array();
449 foreach ( $temp as $array ) {
450 $series[ $array['label'] ] = $array['type'];
451 }
452 }
453 if ( ! $echo ) {
454 ob_start();
455 }
456 ?>
457 <table cellspacing="0" width="100%" class="results cell-border stripe <?php echo $classes; ?>">
458 <thead>
459 <tr>
460 <th><?php _e( 'Label', 'visualizer' ); ?></th>
461 <?php
462 foreach ( $headers as $header ) {
463 if ( $editable_data ) {
464 echo '<th><input type="text" name="header[]" value="' . esc_attr( $header ) . '"></th>';
465 } else {
466 echo '<th>' . $header . '</th>';
467 }
468 }
469 ?>
470 </tr>
471 </thead>
472 <tbody>
473 <tr>
474 <th><?php _e( 'Data Type', 'visualizer' ); ?></th>
475 <?php
476 $index = 0;
477 foreach ( $headers as $header ) {
478 echo '<td>';
479 if ( $editable_data ) {
480 echo '<select name="type[]">';
481 } else {
482 echo '<input name="header[]" type="hidden" value="' . $header . '">';
483 echo '<select name="type[' . $header . ']" class="viz-select-data-type">';
484 }
485 echo '<option value="" title="' . __( 'Exclude from chart', 'visualizer' ) . '">' . __( 'Exclude', 'visualizer' ) . '</option>';
486 echo '<option value="0" disabled title="' . __( 'Include in chart and select data type', 'visualizer' ) . '">--' . __( 'OR', 'visualizer' ) . '--</option>';
487
488 foreach ( Visualizer_Source::getAllowedTypes() as $type ) {
489 $selected = array_key_exists( $header, $series ) && $type === $series[ $header ] ? 'selected' : '';
490 echo '<option value="' . $type . '" ' . $selected . '>' . $type . '</option>';
491 }
492
493 echo '</select></td>';
494 }
495 ?>
496 </tr>
497 <?php
498 // for remote sources, the data exists inside 'data'.
499 if ( array_key_exists( 'data', $data ) ) {
500 $data = $data['data'];
501 }
502
503 foreach ( $data as $row ) {
504 echo '<tr>';
505 echo '<th>' . __( 'Value', 'visualizer' ) . '</th>';
506 $index = 0;
507 if ( empty( $row ) ) {
508 echo '<td></td>';
509 continue;
510 }
511 foreach ( array_values( $row ) as $value ) {
512 if ( $editable_data ) {
513 echo '<td><input type="text" name="data' . $index++ . '[]" value="' . esc_attr( stripslashes( $value ) ) . '"></td>';
514 } else {
515 echo '<td>' . ( is_array( $value ) ? __( 'Invalid Data', 'visualizer' ) : $value ) . '</td>';
516 }
517 }
518
519 echo '</tr>';
520 }
521 ?>
522 </tbody>
523 </table>
524 <?php
525 if ( ! $echo ) {
526 return ob_get_clean();
527 }
528 }
529
530 /**
531 * Generates the permissions tab.
532 *
533 * @access private
534 */
535 private static function _renderPermissions( $args ) {
536 $chart_id = $args[1];
537
538 // ignore for unit tests because Travis throws the error "Indirect modification of overloaded property Visualizer_Render_Page_Data::$permissions has no effect".
539 if ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) {
540 return;
541 }
542
543 $permissions = apply_filters( 'visualizer_pro_get_permissions', null, $chart_id );
544 if ( is_array( $permissions ) ) {
545 $permissions = $permissions['permissions'];
546 } else {
547 $permissions = array();
548 }
549 if ( ! isset( $permissions['read'] ) ) {
550 $permissions['read'] = 'all';
551 }
552 if ( ! isset( $permissions['edit'] ) ) {
553 $permissions['edit'] = 'roles';
554 $permissions['edit-specific'] = 'administrator';
555 }
556
557 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' );
558 echo '<div style="position: relative">';
559 Visualizer_Render_Sidebar::_renderSectionStart();
560 Visualizer_Render_Sidebar::_renderSectionDescription( esc_html__( 'Configure permissions for the chart.', 'visualizer' ) );
561 Visualizer_Render_Sidebar::_renderSectionEnd();
562
563 Visualizer_Render_Sidebar::_renderSectionStart( esc_html__( 'Who can see this chart?', 'visualizer' ), false );
564 Visualizer_Render_Sidebar::_renderSelectItem(
565 '',
566 'permissions[read]',
567 $permissions['read'],
568 array(
569 'all' => esc_html__( 'All Users', 'visualizer' ),
570 'users' => esc_html__( 'Select Users', 'visualizer' ),
571 'roles' => esc_html__( 'Select Roles', 'visualizer' ),
572 ),
573 '',
574 false,
575 array( 'visualizer-permission', 'visualizer-permission-type', 'visualizer-permission-read' ),
576 array(
577 'permission-type' => 'read',
578 )
579 );
580
581 $options = apply_filters( 'visualizer_pro_get_permissions_data', array(), isset( $permissions['read'] ) ? $permissions['read'] : 'roles' );
582
583 Visualizer_Render_Sidebar::_renderSelectItem(
584 '',
585 'permissions[read-specific][]',
586 isset( $permissions['read-specific'] ) ? $permissions['read-specific'] : array(),
587 $options,
588 '',
589 true,
590 array( 'visualizer-permission', 'visualizer-permission-specific', 'visualizer-permission-read-specific' )
591 );
592 Visualizer_Render_Sidebar::_renderSectionEnd();
593
594 Visualizer_Render_Sidebar::_renderSectionStart( esc_html__( 'Who can edit this chart?', 'visualizer' ), false );
595 Visualizer_Render_Sidebar::_renderSelectItem(
596 '',
597 'permissions[edit]',
598 $permissions['edit'],
599 array(
600 'all' => esc_html__( 'All Users', 'visualizer' ),
601 'users' => esc_html__( 'Select Users', 'visualizer' ),
602 'roles' => esc_html__( 'Select Roles', 'visualizer' ),
603 ),
604 '',
605 false,
606 array( 'visualizer-permission', 'visualizer-permission-type', 'visualizer-permission-edit' ),
607 array(
608 'permission-type' => 'edit',
609 )
610 );
611
612 $options = apply_filters( 'visualizer_pro_get_permissions_data', array(), isset( $permissions['edit'] ) ? $permissions['edit'] : 'roles' );
613
614 Visualizer_Render_Sidebar::_renderSelectItem(
615 '',
616 'permissions[edit-specific][]',
617 isset( $permissions['edit-specific'] ) ? $permissions['edit-specific'] : array(),
618 $options,
619 '',
620 true,
621 array( 'visualizer-permission', 'visualizer-permission-specific', 'visualizer-permission-edit-specific' )
622 );
623 Visualizer_Render_Sidebar::_renderSectionEnd();
624 echo apply_filters( 'visualizer_pro_upsell', '', 'chart-permissions', 'https://docs.themeisle.com/article/1280-how-to-customize-permissions' );
625 echo '</div>';
626 Visualizer_Render_Sidebar::_renderGroupEnd();
627 }
628
629 /**
630 * Show the Settings tab for this chart.
631 *
632 * @access public
633 */
634 public static function _renderTabAdvanced( $args ) {
635 $chart_id = $args[1];
636 $sidebar = $args[2];
637
638 $chart_options = get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true );
639 $backend_title = isset( $chart_options['backend-title'] ) && ! empty( $chart_options['backend-title'] ) ? $chart_options['backend-title'] : '';
640
641 ?>
642 <ul class="viz-group-wrapper full-height">
643 <li class="viz-group open" id="vz-chart-settings">
644 <ul class="viz-group-content">
645 <ul class="viz-group-wrapper">
646 <form id="settings-form" action="<?php echo esc_url( add_query_arg( 'nonce', wp_create_nonce() ) ); ?>" method="post">
647 <input type="hidden" id="chart-img" name="chart-img">
648 <input type="hidden" id="backend-title" name="backend-title" value="<?php echo esc_html( $backend_title ); ?>">
649 <?php echo $sidebar; ?>
650 <?php self::_renderPermissions( $args ); ?>
651 <input type="hidden" name="save" value="1">
652 </form>
653 <form id="cancel-form" action="<?php echo esc_url( add_query_arg( 'nonce', wp_create_nonce() ) ); ?>" method="post">
654 <input type="hidden" name="cancel" value="1">
655 </form>
656 </ul>
657 </ul>
658 </li>
659 <?php
660 }
661
662 /**
663 * Show the Docs tab for this chart.
664 *
665 * @access public
666 */
667 public static function _renderTabHelp( $args ) {
668 $chart_id = $args[1];
669 $type = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true );
670 switch ( $type ) {
671 case 'tabular':
672 $type = 'table';
673 break;
674 case 'polarArea':
675 $type = 'polar-area';
676 break;
677 case 'radar':
678 $type = 'radar-spider';
679 break;
680 }
681
682 $displayType = str_replace( '-', '/', $type );
683 ?>
684 <ul class="viz-group-wrapper full-height">
685 <li class="viz-group open" id="vz-chart-help">
686 <ul class="viz-group-wrapper">
687 <?php
688 // open this tab by default.
689 Visualizer_Render_Sidebar::_renderGroupStart( esc_html__( 'Documentation', 'visualizer' ), '', 'open' );
690 Visualizer_Render_Sidebar::_renderSectionStart( esc_html__( 'General', 'visualizer' ), true );
691 ?>
692 <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>
693 <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>
694 <?php
695 Visualizer_Render_Sidebar::_renderSectionEnd();
696 // translators: %s - the chart type.
697 Visualizer_Render_Sidebar::_renderSectionStart( sprintf( __( '%s chart', 'visualizer' ), ucwords( $displayType ) ), true );
698 ?>
699 <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>
700 <h4><span class="dashicons dashicons-search"></span><a href="<?php echo str_replace( '#', $type, VISUALIZER_DOC_COLLECTION ); ?>" target="_blank">
701 <?php
702 echo sprintf(
703 // translators: %s - the chart type.
704 __( 'Articles containing "%s"', 'visualizer' ),
705 $displayType
706 );
707 ?>
708 </a>
709 </h4>
710 <?php
711 Visualizer_Render_Sidebar::_renderSectionEnd();
712 Visualizer_Render_Sidebar::_renderGroupEnd();
713 ?>
714 </ul>
715 </li>
716 </ul>
717
718 <?php
719 }
720
721 /**
722 * Show the Data Source tab for this chart.
723 *
724 * @access public
725 */
726 public static function _renderTabBasic( $args ) {
727 $chart_id = $args[1];
728
729 $upload_link = esc_url(
730 add_query_arg(
731 array(
732 'action' => Visualizer_Plugin::ACTION_UPLOAD_DATA,
733 'nonce' => wp_create_nonce( 'visualizer-upload-data' ),
734 'chart' => $chart_id,
735 ),
736 admin_url( 'admin-ajax.php' )
737 )
738 );
739
740 // this will allow us to open the correct source tab by default.
741 $source_of_chart = strtolower( get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true ) );
742 // Import from woocommerce report.
743 $is_woocommerce_source = strtolower( get_post_meta( $chart_id, Visualizer_Plugin::CF_IS_WOOCOMMERCE_SOURCE, true ) );
744 if ( ! empty( $is_woocommerce_source ) ) {
745 $source_of_chart .= '_wc';
746 }
747 // both import from wp and import from db have the same source so we need to differentiate.
748 $filter_config = get_post_meta( $chart_id, Visualizer_Plugin::CF_FILTER_CONFIG, true );
749 // if filter config is present, then its import from wp.
750 if ( ! empty( $filter_config ) ) {
751 $source_of_chart .= '_wp';
752 }
753 $editor_type = get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, true );
754 if (
755 $editor_type ||
756 ! Visualizer_Module::is_pro() // Use Manual Source for non-pro users since it is the only unlocked source.
757 ) {
758 $source_of_chart = 'visualizer_source_manual';
759 }
760
761 $type = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true );
762 $lib = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_LIBRARY, true );
763 ?>
764 <ul class="viz-group-wrapper full-height">
765 <li class="viz-group open" id="vz-chart-source">
766 <ul class="viz-group-content">
767 <ul class="viz-group-wrapper">
768 <!-- manual -->
769 <li class="viz-group visualizer_source_manual">
770 <h2 class="viz-group-title viz-sub-group visualizer-editor-tab" data-current="chart" role="button" tabindex="0"><?php _e( 'Manual Data', 'visualizer' ); ?></h2>
771 <div class="viz-group-content edit-data-content">
772 <form id="editor-form" action="<?php echo $upload_link; ?>" method="post" target="thehole">
773 <input type="hidden" id="chart-data" name="chart_data">
774 <input type="hidden" id="chart-data-src" name="chart_data_src">
775
776 <?php if ( Visualizer_Module::can_show_feature( 'simple-editor' ) ) { ?>
777 <div>
778 <p class="viz-group-description viz-editor-selection">
779 <?php _e( 'Use the', 'visualizer' ); ?>
780 <select name="editor-type" id="viz-editor-type">
781 <?php
782 if ( empty( $editor_type ) ) {
783 $editor_type = Visualizer_Module::is_pro() ? 'excel' : 'text';
784 }
785 foreach ( apply_filters( 'visualizer_editors', array( 'text' => __( 'Text', 'visualizer' ), 'table' => __( 'Simple', 'visualizer' ) ) ) as $e_type => $e_label ) {
786 ?>
787 <option value="<?php echo $e_type; ?>" <?php selected( $editor_type, $e_type ); ?> ><?php echo $e_label; ?></option>
788 <?php } ?>
789 </select>
790 <?php _e( 'editor to manually edit the chart data.', 'visualizer' ); ?>
791 </p>
792 <input type="button" id="editor-undo" class="button button-secondary" style="display: none" value="<?php _e( 'Undo Changes', 'visualizer' ); ?>">
793 <input type="button" id="editor-button" class="button button-primary "
794 value="<?php _e( 'Edit Data', 'visualizer' ); ?>" data-current="chart"
795 data-t-editor="<?php _e( 'Show Chart', 'visualizer' ); ?>"
796 data-t-chart="<?php _e( 'Edit Data', 'visualizer' ); ?>"
797 >
798 <p class="viz-group-description viz-info-msg" style="display:none"><?php echo sprintf( __( 'Please make sure you click \'Show Chart\' before you save the chart.', 'visualizer' ) ); ?></p>
799 </div>
800 <?php } else { ?>
801 <input type="button" id="editor-undo" class="button button-secondary" style="display: none" value="<?php _e( 'Undo Changes', 'visualizer' ); ?>">
802 <input type="button" id="editor-chart-button" class="button button-primary "
803 value="<?php _e( 'View Editor', 'visualizer' ); ?>" data-current="chart"
804 data-t-editor="<?php _e( 'Show Chart', 'visualizer' ); ?>"
805 data-t-chart="<?php _e( 'View Editor', 'visualizer' ); ?>"
806 >
807 <p class="viz-group-description viz-info-msg" style="display:none"><?php echo sprintf( __( 'Please make sure you click \'Show Chart\' before you save the chart.', 'visualizer' ) ); ?></p>
808 <?php } ?>
809 </form>
810 </div>
811 </li>
812
813 <!-- import from file -->
814 <li class="viz-group visualizer_source_csv <?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'import-file' ); ?> ">
815 <h2 class="viz-group-title viz-sub-group visualizer-src-tab" role="button" tabindex="0"><?php _e( 'Import data from file', 'visualizer' ); ?><span class="dashicons dashicons-lock"></span></h2>
816 <div class="viz-group-content">
817 <div>
818 <p class="viz-group-description"><?php esc_html_e( 'Select and upload your data file here. Supported formats: CSV, XLSX. The first row should contain the column headings. The second row should contain the series type (string, number, boolean, date, datetime, timeofday).', 'visualizer' ); ?></p>
819 <p class="viz-group-description viz-info-msg">
820 <b>
821 <?php
822 echo sprintf(
823 // translators: $s - the chart type with the link attached.
824 __( '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' ),
825 '<a href="' . VISUALIZER_ABSURL . 'samples/' . $type . '.csv" target="_blank">' . $type . '.csv</a>'
826 );
827 ?>
828 </b>
829 </p>
830 <form id="vz-csv-file-form" action="<?php echo $upload_link; ?>" method="post"
831 target="thehole" enctype="multipart/form-data">
832 <input type="hidden" id="remote-data" name="remote_data">
833 <div class="">
834 <input type="file" id="csv-file" name="local_data" accept=".csv,.xlsx">
835 </div>
836 <input type="button" class="button button-primary" id="vz-import-file"
837 value="<?php _e( 'Import', 'visualizer' ); ?>">
838 </form>
839 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'import-file' ); ?>
840 </div>
841 </div>
842 </li>
843 <!-- import from url -->
844 <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' ); ?> ">
845 <h2 class="viz-group-title viz-sub-group visualizer-src-tab" role="button" tabindex="0"><?php _e( 'Import data from URL', 'visualizer' ); ?><span class="dashicons dashicons-lock"></span></h2>
846 <ul class="viz-group-content">
847 <!-- import from csv url -->
848 <li class="viz-subsection">
849 <span class="viz-section-title" role="button" tabindex="0"><?php _e( 'Import from CSV / XLSX', 'visualizer' ); ?></span>
850 <div class="only-pro-anchor">
851 <div class="viz-section-items section-items">
852 <p class="viz-group-description">
853 <?php
854 echo sprintf(
855 // translators: %1$s - HTML link tag, %2$s - HTML closing link tag.
856 __( 'You can use this to import data from a remote CSV or Excel (XLSX) file, or %1$sGoogle Spreadsheet%2$s.', 'visualizer' ),
857 '<a href="https://docs.themeisle.com/article/607-how-can-i-populate-data-from-google-spreadsheet" target="_blank" >',
858 '</a>'
859 );
860 ?>
861 </p>
862 <p class="viz-group-description viz-info-msg">
863 <b>
864 <?php
865 echo sprintf(
866 // translators: %s - the chart type with the link attached.
867 __( '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' ),
868 '<a href="' . VISUALIZER_ABSURL . 'samples/' . $type . '.csv" target="_blank">' . $type . '.csv</a>'
869 );
870 ?>
871 </b>
872 </p>
873 <form id="vz-one-time-import" action="<?php echo $upload_link; ?>" method="post"
874 target="thehole" enctype="multipart/form-data">
875 <div class="remote-file-section">
876 <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 a CSV or XLSX file', 'visualizer' ); ?>" class="visualizer-input visualizer-remote-url">
877 </div>
878 <select name="vz-import-time" id="vz-import-time" class="visualizer-select">
879 <?php
880 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_SCHEDULE, true );
881 $schedules = apply_filters(
882 'visualizer_chart_schedules', array(
883 '-1' => __( 'One-time', 'visualizer' ),
884 ),
885 'csv',
886 $chart_id
887 );
888 foreach ( $schedules as $num => $name ) {
889 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
890 $extra = self::is_hour_selected( $hours, $num ) ? 'selected' : '';
891 ?>
892 <option value="<?php echo esc_attr( $num ); ?>" <?php echo esc_attr( $extra ); ?>><?php echo esc_html( $name ); ?></option>
893 <?php
894 }
895 do_action( 'visualizer_chart_schedules_spl', 'csv', $chart_id, 1 );
896 ?>
897 </select>
898
899 <?php
900 if ( ! Visualizer_Module::is_pro() ) {
901 ?>
902 <input type="button" id="view-remote-file" class="button button-primary" value="<?php _e( 'Import', 'visualizer' ); ?>">
903 <?php
904 } else {
905 ?>
906 <input type="button" id="vz-save-schedule" class="button button-primary" value="<?php _e( 'Import & Save schedule', 'visualizer' ); ?>">
907 <?php
908 }
909 ?>
910 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'import-url' ); ?>
911 </form>
912 </div>
913 </div>
914 </li>
915 <!-- import from json url -->
916 <li class="viz-subsection">
917 <span class="viz-section-title visualizer_source_json" role="button" tabindex="0"><?php _e( 'Import from JSON', 'visualizer' ); ?></span>
918 <div class="only-pro-anchor">
919 <div class="viz-section-items section-items">
920 <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>
921 <form id="vz-import-json" action="<?php echo $upload_link; ?>" method="post" target="thehole" enctype="multipart/form-data">
922 <div class="remote-file-section">
923 <?php
924 $bttn_label = 'visualizer_source_json' === $source_of_chart ? __( 'Modify Parameters', 'visualizer' ) : __( 'Create Parameters', 'visualizer' );
925 if ( Visualizer_Module::is_pro() ) {
926 ?>
927 <p class="viz-group-description"><?php _e( 'How often do you want to check the URL', 'visualizer' ); ?></p>
928 <select name="time" id="vz-json-time" class="visualizer-select json-form-element" data-chart="<?php echo $chart_id; ?>">
929 <?php
930 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, true );
931 $schedules = apply_filters(
932 'visualizer_chart_schedules', array(
933 '-1' => __( 'One-time', 'visualizer' ),
934 ),
935 'json',
936 $chart_id
937 );
938 foreach ( $schedules as $num => $name ) {
939 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
940 $extra = self::is_hour_selected( $hours, $num ) ? 'selected' : '';
941 ?>
942 <option value="<?php echo esc_attr( $num ); ?>" <?php echo esc_attr( $extra ); ?>><?php echo esc_html( $name ); ?></option>
943 <?php
944 }
945 do_action( 'visualizer_chart_schedules_spl', 'json', $chart_id, 1 );
946 ?>
947 </select>
948 <?php
949 }
950 ?>
951 </div>
952
953 <input type="button" id="json-chart-button" class="button button-secondary show-chart-toggle"
954 value="<?php echo $bttn_label; ?>" data-current="chart"
955 data-t-filter="<?php _e( 'Show Chart', 'visualizer' ); ?>"
956 data-t-chart="<?php echo $bttn_label; ?>">
957 <?php
958 if ( Visualizer_Module::is_pro() ) {
959 ?>
960 <input type="button" id="json-chart-save-button" class="button button-primary "
961 value="<?php _e( 'Save Schedule', 'visualizer' ); ?>">
962 <?php
963 }
964 ?>
965 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'import-url' ); ?>
966 </form>
967 </div>
968 </div>
969 </li>
970 </ul>
971 </li>
972 <!-- import from chart -->
973 <li class="viz-group viz-import-from-other <?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature' ); ?>">
974 <h2 class="viz-group-title viz-sub-group"
975 data-current="chart" role="button" tabindex="0"><?php _e( 'Import from other chart', 'visualizer' ); ?><span
976 class="dashicons dashicons-lock"></span></h2>
977 <div class="viz-group-content edit-data-content">
978 <div>
979 <p class="viz-group-description"><?php _e( 'You can import here data from your previously created charts', 'visualizer' ); ?></p>
980 <form>
981 <select name="vz-import-from-chart" id="chart-id" class="visualizer-select">
982 <?php
983 $fetch_link = esc_url(
984 add_query_arg(
985 array(
986 'action' => Visualizer_Module::is_pro() ? Visualizer_Pro::ACTION_FETCH_DATA : '',
987 'nonce' => Visualizer_Module::is_pro() ? wp_create_nonce( Visualizer_Pro::ACTION_FETCH_DATA ) : wp_create_nonce(),
988 ),
989 admin_url( 'admin-ajax.php' )
990 )
991 );
992 $query_args_charts = array(
993 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
994 'posts_per_page' => 300,
995 'no_found_rows' => true,
996 );
997 $charts = array();
998 $query = new WP_Query( $query_args_charts );
999 while ( $query->have_posts() ) {
1000 $chart = $query->next_post();
1001 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
1002
1003 $title = '#' . $chart->ID;
1004 if ( ! empty( $settings['title'] ) ) {
1005 $title = $settings['title'];
1006 }
1007 // for ChartJS, title is an array.
1008 if ( is_array( $title ) && isset( $title['text'] ) ) {
1009 $title = $title['text'];
1010 }
1011 if ( empty( $title ) ) {
1012 $title = '#' . $chart->ID;
1013 }
1014
1015 ?>
1016 <option value="<?php echo $chart->ID; ?>"><?php echo $title; ?></option>
1017 <?php
1018 }
1019 ?>
1020
1021 </select>
1022 </form>
1023 <input type="button" id="existing-chart" class="button button-primary"
1024 value="<?php _e( 'Import Chart', 'visualizer' ); ?>"
1025 data-viz-link="<?php echo $fetch_link; ?>">
1026 <?php
1027 if ( ! Visualizer_Module_Admin::proFeaturesEnabled() ) {
1028 echo apply_filters( 'visualizer_pro_upsell', '', 'import-chart' );
1029 }
1030 ?>
1031 </div>
1032 </div>
1033 </li>
1034
1035 <?php
1036 $save_filter = esc_url(
1037 add_query_arg(
1038 array(
1039 'action' => Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY,
1040 'security' => wp_create_nonce( Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY . Visualizer_Plugin::VERSION ),
1041 'chart' => $chart_id,
1042 ), admin_url( 'admin-ajax.php' )
1043 )
1044 );
1045 ?>
1046 <!-- import from WordPress -->
1047 <li class="viz-group visualizer_source_query_wp <?php echo esc_attr( apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'import-wp' ) ); ?> ">
1048 <h2 class="viz-group-title viz-sub-group" role="button" tabindex="0"><?php _e( 'Import from WordPress', 'visualizer' ); ?><span
1049 class="dashicons dashicons-lock"></span></h2>
1050 <div class="viz-group-content edit-data-content">
1051 <div>
1052 <p class="viz-group-description"><?php _e( 'You can import data from WordPress here.', 'visualizer' ); ?></p>
1053 <form id="vz-filter-wizard" action="<?php echo esc_url( $save_filter ); ?>" method="post" target="thehole">
1054 <?php
1055 $is_wp_source = 'visualizer_source_query_wp' === $source_of_chart;
1056 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, true );
1057 $bttn_label = $is_wp_source ? '1. ' . __( 'Modify Data Source', 'visualizer' ) : '1. ' . __( 'Choose Data Source', 'visualizer' );
1058 ?>
1059
1060 <!-- Step 1: Choose / modify data source -->
1061 <input type="button" id="filter-chart-button" class="button button-secondary show-chart-toggle vz-import-step-btn" value="<?php echo esc_attr( $bttn_label ); ?>" data-current="chart" data-t-filter="<?php esc_attr_e( 'Show Chart', 'visualizer' ); ?>" data-t-chart="<?php echo esc_attr( $bttn_label ); ?>">
1062
1063 <!-- Step 2: Sync schedule toggle -->
1064 <div id="vz-wp-sync-step">
1065 <button type="button" id="vz-wp-sync-btn" class="vz-import-step-toggle" aria-expanded="<?php echo $is_wp_source ? 'true' : 'false'; ?>">
1066 <?php echo '2. ' . __( 'Set Sync Schedule', 'visualizer' ); ?>
1067 <span class="dashicons dashicons-arrow-down-alt2"></span>
1068 </button>
1069 <div id="vz-wp-sync-options"<?php echo $is_wp_source ? '' : ' style="display:none"'; ?>>
1070 <select name="refresh" id="vz-filter-import-time" class="visualizer-select">
1071 <?php
1072 $schedules = apply_filters(
1073 'visualizer_chart_schedules', array(
1074 '-1' => __( 'One-time', 'visualizer' ),
1075 ),
1076 'wp',
1077 $chart_id
1078 );
1079 foreach ( $schedules as $num => $name ) {
1080 $extra = self::is_hour_selected( $hours, $num ) ? 'selected' : '';
1081 ?>
1082 <option value="<?php echo esc_attr( $num ); ?>" <?php echo esc_attr( $extra ); ?>><?php echo esc_html( $name ); ?></option>
1083 <?php
1084 }
1085 do_action( 'visualizer_chart_schedules_spl', 'wp', $chart_id, 1 );
1086 ?>
1087 </select>
1088 <input type="button" id="db-filter-save-button" class="button button-primary" value="<?php _e( 'Save Schedule', 'visualizer' ); ?>">
1089 </div>
1090 </div>
1091 </form>
1092 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'import-wp', 'https://docs.themeisle.com/article/1278-how-to-import-data-from-wordpress' ); ?>
1093 </div>
1094 </div>
1095 </li>
1096
1097 <!-- import from WooCommerce -->
1098 <?php
1099 if ( class_exists( 'WooCommerce', false ) ) :
1100 $wc_source = strtolower( get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_WOOCOMMERCE_SOURCE, true ) );
1101 $wc_source_list = apply_filters(
1102 'visualizer_woocommerce_report_endpoints',
1103 array(
1104 array(
1105 'name' => esc_html__( 'Sales', 'visualizer' ),
1106 'endpoint' => esc_attr( 'sales' ),
1107 ),
1108 array(
1109 'name' => esc_html__( 'Top Sellers', 'visualizer' ),
1110 'endpoint' => esc_attr( 'top_sellers' ),
1111 ),
1112 array(
1113 'name' => esc_html__( 'Coupons Totals', 'visualizer' ),
1114 'endpoint' => esc_attr( 'coupons/totals' ),
1115 ),
1116 array(
1117 'name' => esc_html__( 'Customers Totals', 'visualizer' ),
1118 'endpoint' => esc_attr( 'customers/totals' ),
1119 ),
1120 array(
1121 'name' => esc_html__( 'Orders Totals', 'visualizer' ),
1122 'endpoint' => esc_attr( 'orders/totals' ),
1123 ),
1124 array(
1125 'name' => esc_html__( 'Products Totals', 'visualizer' ),
1126 'endpoint' => esc_attr( 'products/totals' ),
1127 ),
1128 array(
1129 'name' => esc_html__( 'Reviews Totals', 'visualizer' ),
1130 'endpoint' => esc_attr( 'reviews/totals' ),
1131 ),
1132 )
1133 );
1134 ?>
1135 <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' ); ?> ">
1136 <h2 class="viz-group-title viz-sub-group" role="button" tabindex="0"><?php _e( 'Import from WooCommerce Reports', 'visualizer' ); ?><span class="dashicons dashicons-lock"></span></h2>
1137 <div class="viz-group-content edit-data-content">
1138 <div>
1139 <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>
1140 <form id="vz-import-woo-report" action="<?php echo $upload_link; ?>" method="post" target="thehole" enctype="multipart/form-data">
1141 <div class="remote-file-section">
1142 <?php
1143 $bttn_label = 'visualizer_source_json_wc' === $source_of_chart ? __( 'Modify Parameters', 'visualizer' ) : __( 'Create Parameters', 'visualizer' );
1144 ?>
1145 <p class="viz-group-description"><?php _e( 'How often do you want to check the URL', 'visualizer' ); ?></p>
1146 <select name="time" id="vz-woo-time" class="visualizer-select json-form-element" data-chart="<?php echo $chart_id; ?>">
1147 <?php
1148 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, true );
1149 $schedules = apply_filters(
1150 'visualizer_chart_schedules', array(
1151 '-1' => __( 'One-time', 'visualizer' ),
1152 ),
1153 'json',
1154 $chart_id
1155 );
1156 foreach ( $schedules as $num => $name ) {
1157 $extra = self::is_hour_selected( $hours, $num ) ? 'selected' : '';
1158 ?>
1159 <option value="<?php echo esc_attr( $num ); ?>" <?php echo esc_attr( $extra ); ?>><?php echo esc_html( $name ); ?></option>
1160 <?php
1161 }
1162 do_action( 'visualizer_chart_schedules_spl', 'json', $chart_id, 1 );
1163 ?>
1164 </select>
1165 <p class="viz-group-description"><?php _e( 'Select report endpoint', 'visualizer' ); ?></p>
1166 <select name="vz_woo_source" id="vz-woo-source" class="visualizer-select json-form-element" data-chart="<?php echo $chart_id; ?>">
1167 <option value=""></option>
1168 <?php
1169 if ( ! empty( $wc_source_list ) ) {
1170 foreach ( $wc_source_list as $api ) {
1171 if ( isset( $api['name'] ) && $api['endpoint'] ) {
1172 echo sprintf( '<option value="%2$s" %3$s>%1$s</option>', $api['name'], $api['endpoint'], selected( $wc_source, $api['endpoint'], false ) ); // phpcs:ignore
1173 }
1174 }
1175 }
1176 ?>
1177 </select>
1178 </div>
1179
1180 <input type="button" id="woo-chart-button" class="button button-secondary show-chart-toggle"
1181 value="<?php echo $bttn_label; ?>" data-current="chart"
1182 data-t-filter="<?php _e( 'Show Chart', 'visualizer' ); ?>"
1183 data-t-chart="<?php echo $bttn_label; ?>"
1184 <?php empty( $wc_source ) ? 'disabled' : ''; ?>
1185 >
1186 <input type="button" id="woo-chart-save-button" class="button button-primary "
1187 value="<?php _e( 'Save Schedule', 'visualizer' ); ?>" <?php empty( $wc_source ) ? 'disabled' : ''; ?>>
1188 </form>
1189 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'import-wc-report' ); ?>
1190 </div>
1191 </div>
1192 </li>
1193 <?php endif; ?>
1194 <?php
1195 $save_query = esc_url(
1196 add_query_arg(
1197 array(
1198 'action' => Visualizer_Plugin::ACTION_SAVE_DB_QUERY,
1199 'security' => wp_create_nonce( Visualizer_Plugin::ACTION_SAVE_DB_QUERY . Visualizer_Plugin::VERSION ),
1200 'chart' => $chart_id,
1201 ), admin_url( 'admin-ajax.php' )
1202 )
1203 );
1204 ?>
1205 <!-- import from db -->
1206 <li class="viz-group visualizer_source_query <?php echo esc_attr( apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'db-query' ) ); ?>">
1207 <h2 class="viz-group-title viz-sub-group" role="button" tabindex="0"><?php _e( 'Import from database', 'visualizer' ); ?><span
1208 class="dashicons dashicons-lock"></span></h2>
1209 <div class="viz-group-content edit-data-content">
1210 <div>
1211 <p class="viz-group-description"><?php _e( 'You can import data from the database here.', 'visualizer' ); ?></p>
1212 <form id="vz-db-wizard" action="<?php echo esc_url( $save_query ); ?>" method="post" target="thehole">
1213 <?php
1214 $is_db_source = 'visualizer_source_query' === $source_of_chart;
1215 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, true );
1216 $bttn_label = $is_db_source ? __( '1. Modify Data Source', 'visualizer' ) : __( '1. Choose Data Source', 'visualizer' );
1217 ?>
1218
1219 <!-- Step 1: Choose / modify data source -->
1220 <input type="hidden" name="params" id="viz-db-wizard-params">
1221 <input type="button" id="db-chart-button" class="button button-secondary show-chart-toggle vz-import-step-btn" value="<?php echo esc_attr( $bttn_label ); ?>" data-current="chart" data-t-filter="<?php esc_attr_e( 'Show Chart', 'visualizer' ); ?>" data-t-chart="<?php echo esc_attr( $bttn_label ); ?>">
1222
1223 <!-- Step 2: Sync schedule toggle -->
1224 <div id="vz-db-sync-step">
1225 <button type="button" id="vz-db-sync-btn" class="vz-import-step-toggle" aria-expanded="<?php echo $is_db_source ? 'true' : 'false'; ?>">
1226 <?php echo '2. ' . __( 'Set Sync Schedule', 'visualizer' ); ?>
1227 <span class="dashicons dashicons-arrow-down-alt2"></span>
1228 </button>
1229 <div id="vz-db-sync-options"<?php echo $is_db_source ? '' : ' style="display:none"'; ?>>
1230 <select name="refresh" id="vz-db-import-time" class="visualizer-select">
1231 <?php
1232 $schedules = apply_filters(
1233 'visualizer_chart_schedules', array(
1234 '-1' => __( 'One-time', 'visualizer' ),
1235 ),
1236 'db',
1237 $chart_id
1238 );
1239 foreach ( $schedules as $num => $name ) {
1240 $extra = self::is_hour_selected( $hours, $num ) ? 'selected' : '';
1241 ?>
1242 <option value="<?php echo esc_attr( $num ); ?>" <?php echo esc_attr( $extra ); ?>><?php echo esc_html( $name ); ?></option>
1243 <?php
1244 }
1245 do_action( 'visualizer_chart_schedules_spl', 'db', $chart_id, 1 );
1246 ?>
1247 </select>
1248 <input type="button" id="db-chart-save-button" class="button button-primary" value="<?php _e( 'Save Schedule', 'visualizer' ); ?>">
1249 </div>
1250 </div>
1251 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'db-query', 'https://docs.themeisle.com/article/1279-how-to-import-data-from-a-database' ); ?>
1252 </form>
1253 </div>
1254 </div>
1255 </li>
1256 </ul>
1257 </li>
1258 </ul>
1259 </ul>
1260
1261 <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>
1262 <iframe id="thehole" name="thehole"></iframe>
1263 <?php
1264 }
1265
1266 /**
1267 * Check if the given hour is selected.
1268 *
1269 * @param int|float|string $hour The hour.
1270 * @param int|float|string $reference The number.
1271 *
1272 * @return bool
1273 */
1274 public static function is_hour_selected( $hour, $reference ) {
1275
1276 if ( ! is_numeric( $hour ) || ! is_numeric( $reference ) ) {
1277 return false;
1278 }
1279
1280 $hour = floatval( $hour );
1281 $reference = floatval( $reference );
1282
1283 if ( self::is_live_update_option( $reference ) ) {
1284 $reference = self::$live_option_fallback_hour;
1285 }
1286
1287 return abs( $hour - $reference ) < 0.000001;
1288 }
1289
1290 /**
1291 * Check if the reference option is deprecated live update option.
1292 *
1293 * @param float $reference_hour The reference hour.
1294 *
1295 * @return bool
1296 */
1297 public static function is_live_update_option( $reference_hour ) {
1298 return abs( $reference_hour ) < 0.000001;
1299 }
1300 }
1301