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

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