PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 4.0.5
Visualizer – Tables & Charts Manager with Built-in AI Generator v4.0.5
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 4.0.5, at classes/Visualizer/Render/Layout.php

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