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

1,018 lines 44.0 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 * Renders template.
32 *
33 * @since 1.0.0
34 *
35 * @abstract
36 * @access protected
37 */
38 protected function _toHTML() {
39 // empty.
40 }
41
42 /**
43 * Show the layout by delegating the call to the layout-specific method with the params.
44 *
45 * @access public
46 */
47 public static function show( $layout ) {
48 return call_user_func( array( __CLASS__, '_render' . str_replace( ' ', '', ucwords( str_replace( '-', ' ', $layout ) ) ) ), func_get_args() );
49 }
50
51 /**
52 * Show the DB query box.
53 *
54 * @access public
55 */
56 public static function _renderDbQuery( $args ) {
57 $query = $args[1];
58 ?>
59 <div id='visualizer-db-query' style="display: none">
60 <div class="visualizer-db-query-form">
61 <div>
62 <form id='db-query-form'>
63 <input type="hidden" name="chart_id" value="<?php echo $args[2]; ?>">
64 <?php do_action( 'visualizer_db_query_add_layout', $args ); ?>
65 <textarea name='query' class='visualizer-db-query' placeholder="<?php _e( 'Your query goes here', 'visualizer' ); ?>"><?php echo $query; ?></textarea>
66 </form>
67 <div class='db-wizard-error'></div>
68 </div>
69 <div>
70 <input type="button" class="button button-primary" id='visualizer-query-fetch' value='<?php _e( 'Show Results', 'visualizer' ); ?>'>
71 </div>
72 </div>
73 <div class='db-wizard-hints'>
74 <ul>
75 <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>
76 <li><?php echo sprintf( __( 'Use %1$sControl+Space%2$s for autocompleting keywords or table names.', 'visualizer' ), '<span class="visualizer-emboss">', '</span>' ); ?></li>
77 <?php do_action( 'visualizer_db_query_add_hints', $args ); ?>
78 </ul>
79 </div>
80 <div class='db-wizard-results'></div>
81
82 </div>
83 <?php
84 }
85
86 /**
87 * Show the DB wizard's results table.
88 *
89 * @access public
90 */
91 public static function _renderDbWizardResults( $args ) {
92 $headers = $args[1];
93 $results = $args[2];
94 ob_start();
95 ?>
96 <table cellspacing="0" width="100%" id="results">
97 <thead>
98 <tr>
99 <?php
100 foreach ( $headers as $header ) {
101 echo '<th>' . $header['label'] . '</th>';
102 }
103 ?>
104 </tr>
105 </thead>
106 <tfoot>
107 </tfoot>
108 <tbody>
109 <?php
110 foreach ( $results as $result ) {
111 echo '<tr>';
112 foreach ( $result as $r ) {
113 echo '<td>' . $r . '</td>';
114 }
115 echo '</tr>';
116 }
117 ?>
118 </tbody>
119 </table>
120 <?php
121 return ob_get_clean();
122 }
123
124 /**
125 * Show the JSON/REST parameters boxes.
126 *
127 * @access public
128 */
129 public static function _renderJsonScreen( $args ) {
130 $id = $args[1];
131 $action = add_query_arg(
132 array(
133 'action' => Visualizer_Plugin::ACTION_JSON_SET_DATA,
134 'security' => wp_create_nonce( Visualizer_Plugin::ACTION_JSON_SET_DATA . Visualizer_Plugin::VERSION ),
135 'chart' => $id,
136 ),
137 admin_url( 'admin-ajax.php' )
138 );
139
140 $url = get_post_meta( $id, Visualizer_Plugin::CF_JSON_URL, true );
141 $root = get_post_meta( $id, Visualizer_Plugin::CF_JSON_ROOT, true );
142 $paging = get_post_meta( $id, Visualizer_Plugin::CF_JSON_PAGING, true );
143 $headers = get_post_meta( $id, Visualizer_Plugin::CF_JSON_HEADERS, true );
144 if ( empty( $headers ) ) {
145 $headers = array();
146 }
147 if ( $headers && empty( $headers['method'] ) ) {
148 $headers['method'] = 'get';
149 }
150 $methods = apply_filters( 'visualizer_json_request_methods', array( 'GET', 'POST' ) );
151
152 // open the headers by default?
153 $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'] ) );
154 ?>
155 <div id="visualizer-json-screen" style="display: none">
156 <div class="visualizer-json-form">
157 <h3 class="viz-step step1"><?php _e( 'STEP 1: Specify the JSON endpoint/URL', 'visualizer' ); ?></h3>
158 <div>
159 <form id="json-endpoint-form">
160 <div class="json-wizard-hints">
161 <ul class="info">
162 <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>
163 </ul>
164 </div>
165
166 <input
167 type="url"
168 id="vz-import-json-url"
169 name="url"
170 value="<?php echo esc_url( $url ); ?>"
171 placeholder="<?php esc_html_e( 'Please enter the URL', 'visualizer' ); ?>"
172 class="visualizer-input json-form-element">
173 <button class="button button-secondary button-small" id="visualizer-json-fetch"><?php esc_html_e( 'Fetch Endpoint', 'visualizer' ); ?></button>
174
175 <div class="visualizer-json-subform">
176 <h3 class="viz-substep <?php echo $headers_open ? 'open' : ''; ?>"><?php _e( 'Headers', 'visualizer' ); ?></h3>
177 <div class="json-wizard-headers">
178 <div class="json-wizard-header">
179 <div><?php _e( 'Request Type', 'visualizer' ); ?></div>
180 <div>
181 <select name="method" class="json-form-element">
182 <?php foreach ( $methods as $method ) { ?>
183 <option value="<?php echo $method; ?>" <?php $headers && selected( $headers['method'], $method ); ?>><?php echo $method; ?></option>
184 <?php } ?>
185 </select>
186 </div>
187 </div>
188 <div class="json-wizard-header">
189 <div><?php _e( 'Credentials', 'visualizer' ); ?></div>
190 <div>
191 <input
192 type="text"
193 id="vz-import-json-username"
194 name="username"
195 value="<?php echo ( array_key_exists( 'auth', $headers ) && array_key_exists( 'username', $headers['auth'] ) ? $headers['auth']['username'] : '' ); ?>"
196 placeholder="<?php esc_html_e( 'Username/Access Key', 'visualizer' ); ?>"
197 class="json-form-element">
198 &
199 <input
200 type="password"
201 id="vz-import-json-password"
202 name="password"
203 value="<?php echo ( array_key_exists( 'auth', $headers ) && array_key_exists( 'password', $headers['auth'] ) ? $headers['auth']['password'] : '' ); ?>"
204 placeholder="<?php esc_html_e( 'Password/Secret Key', 'visualizer' ); ?>"
205 class="json-form-element">
206 </div>
207 </div>
208 <div class="json-wizard-header">
209 <div></div>
210 <div><?php esc_html_e( 'OR', 'visualizer' ); ?></div>
211 </div>
212 <div class="json-wizard-header">
213 <div><?php esc_html_e( 'Authorization', 'visualizer' ); ?></div>
214 <div>
215 <input
216 type="text"
217 id="vz-import-json-auth"
218 name="auth"
219 value="<?php echo ( array_key_exists( 'auth', $headers ) && is_string( $headers['auth'] ) ? $headers['auth'] : '' ); ?>"
220 placeholder="<?php esc_html_e( 'e.g. SharedKey <AccountName>:<Signature>', 'visualizer' ); ?>"
221 class="visualizer-input json-form-element">
222 </div>
223 </div>
224 <div class="json-wizard-header">
225 <div class="field-title"><?php esc_html_e( 'Additional headers', 'visualizer' ); ?></div>
226 <div>
227 <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>
228 </div>
229 </div>
230 </div>
231 </div>
232 </form>
233 </div>
234 <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>
235 <div>
236 <form id="json-root-form">
237 <input type="hidden" name="chart" value="<?php echo $id; ?>">
238 <select name="root" id="vz-import-json-root" class="json-form-element">
239 <?php
240 if ( ! empty( $root ) ) {
241 ?>
242 <option value="<?php echo esc_attr( $root ); ?>"><?php echo str_replace( Visualizer_Source_Json::TAG_SEPARATOR, Visualizer_Source_Json::TAG_SEPARATOR_VIEW, $root ); ?></option>
243 <?php
244 }
245 ?>
246 </select>
247 <button class="button button-secondary button-small" id="visualizer-json-parse"><?php esc_html_e( 'Parse Endpoint', 'visualizer' ); ?></button>
248 </form>
249 </div>
250 <h3 class="viz-step step3 <?php echo empty( $root ) ? 'ui-state-disabled' : ''; ?>"><?php _e( 'STEP 3: Specify miscellaneous parameters', 'visualizer' ); ?></h3>
251 <div>
252 <form id="json-conclude-form-helper">
253 <div class="<?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature' ); ?>">
254 <div class="json-pagination">
255 <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 ), '?' ); ?>'>
256 <option value="0" class="static"><?php _e( 'Get results from the first page only', 'visualizer' ); ?></option>
257 <?php
258 if ( ! empty( $paging ) ) {
259 ?>
260 <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>
261 <?php
262 }
263 ?>
264 </select>
265 <?php
266 if ( ! Visualizer_Module::is_pro() ) {
267 ?>
268 <br/>
269 <br/>
270 <br/>
271 <br/>
272 <?php
273 }
274 ?>
275 <?php echo apply_filters( 'visualizer_pro_upsell', '' ); ?>
276 </div>
277 </div>
278 </form>
279 </div>
280 <h3 class="viz-step step4 ui-state-disabled"><?php _e( 'STEP 4: Select the data to display in the chart', 'visualizer' ); ?></h3>
281 <div>
282 <form id="json-conclude-form" action="<?php echo $action; ?>" method="post" target="thehole">
283 <div class="json-wizard-hints html-table-editor-hints">
284 <ul class="info">
285 <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>
286 <li><?php _e( 'Select whether to include the data in the chart. Each column selected will form one series.', 'visualizer' ); ?></li>
287 <li><?php _e( 'If a column is selected to be included, specify its data type.', 'visualizer' ); ?></li>
288 <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>
289 <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>
290 <li><?php _e( 'Once you have made your selection, click \'Show Chart\' on the right to view the chart.', 'visualizer' ); ?></li>
291 </ul>
292 </div>
293 <div class="json-table"></div>
294 <button class="button button-primary" style="display: none" id="visualizer-json-conclude"></button>
295 </form>
296 </div>
297 </div>
298 </div>
299 <?php
300 }
301
302 /**
303 * Show the simple editor(s).
304 *
305 * @access public
306 */
307 public static function _renderSimpleEditorScreen( $args ) {
308 $chart_id = $args[1];
309 $action = add_query_arg(
310 array(
311 'action' => Visualizer_Plugin::ACTION_UPLOAD_DATA,
312 'nonce' => wp_create_nonce(),
313 'chart' => $chart_id,
314 ),
315 admin_url( 'admin-ajax.php' )
316 );
317 ?>
318 <div class="viz-simple-editor">
319 <div class="viz-simple-editor-type viz-table-editor">
320 <form id="table-editor-form" action="<?php echo $action; ?>" method="post" target="thehole">
321 <div class="html-table-editor-hints">
322 <ul class="info">
323 <li><?php _e( 'Select whether to include the data in the chart. Each column selected will form one series.', 'visualizer' ); ?></li>
324 <li><?php _e( 'If a column is selected to be included, specify its data type.', 'visualizer' ); ?></li>
325 <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>
326 <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>
327 </ul>
328 </div>
329 <div class="viz-html-table">
330 <?php Visualizer_Render_Layout::show( 'editor-table', null, $chart_id, 'viz-html-table', true, true ); ?>
331 </div>
332 <input type="hidden" name="table_data" value="yes">
333 <input type="hidden" name="editor-type" value="table">
334 </form>
335 </div>
336
337 <?php Visualizer_Render_Layout::show( 'text-editor', $chart_id ); ?>
338
339 </div>
340 <?php
341
342 }
343
344 /**
345 * Show the text area editor.
346 *
347 * @access public
348 */
349 public static function _renderTextEditor( $args ) {
350 $chart_id = $args[1];
351 $csv = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA_AS, array(), $chart_id, 'csv-display' );
352 $data = '';
353 if ( ! empty( $csv ) && isset( $csv['string'] ) ) {
354 $data = str_replace( PHP_EOL, "\n", stripslashes( $csv['string'] ) );
355 }
356 ?>
357 <div class="viz-simple-editor-type viz-text-editor">
358 <textarea id="edited_text"><?php echo $data; ?></textarea>
359 </div>
360 <?php
361 }
362
363 /**
364 * Show the JSON endpoint's parsed table.
365 *
366 * @access public
367 */
368 public static function _renderEditorTable( $args ) {
369 $data = $args[1];
370 $chart_id = $args[2];
371 $class = $args[3];
372 $echo = $args[4];
373 $editable_data = $args[5];
374 $series = get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true );
375 $headers = array();
376
377 if ( is_null( $data ) ) {
378 foreach ( $series as $column ) {
379 $headers[] = $column['label'];
380 }
381 $chart = get_post( $chart_id );
382 $type = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true );
383 $data = Visualizer_Module::get_chart_data( $chart, $type );
384 } else {
385 $headers = array_keys( $data[0] );
386 }
387
388 $classes = implode( ' ', array( 'viz-editor-table', $class ) );
389
390 if ( $series ) {
391 $temp = $series;
392 $series = array();
393 foreach ( $temp as $array ) {
394 $series[ $array['label'] ] = $array['type'];
395 }
396 }
397 if ( ! $echo ) {
398 ob_start();
399 }
400 ?>
401 <table cellspacing="0" width="100%" class="results cell-border stripe <?php echo $classes; ?>">
402 <thead>
403 <tr>
404 <th><?php _e( 'Label', 'visualizer' ); ?></th>
405 <?php
406 foreach ( $headers as $header ) {
407 if ( $editable_data ) {
408 echo '<th><input type="text" name="header[]" value="' . esc_attr( $header ) . '"></th>';
409 } else {
410 echo '<th>' . $header . '</th>';
411 }
412 }
413 ?>
414 </tr>
415 </thead>
416 <tbody>
417 <tr>
418 <th><?php _e( 'Data Type', 'visualizer' ); ?></th>
419 <?php
420 $index = 0;
421 foreach ( $headers as $header ) {
422 echo '<td>';
423 if ( $editable_data ) {
424 echo '<select name="type[]">';
425 } else {
426 echo '<input name="header[]" type="hidden" value="' . $header . '">';
427 echo '<select name="type[' . $header . ']" class="viz-select-data-type">';
428 }
429 echo '<option value="" title="' . __( 'Exclude from chart', 'visualizer' ) . '">' . __( 'Exclude', 'visualizer' ) . '</option>';
430 echo '<option value="0" disabled title="' . __( 'Include in chart and select data type', 'visualizer' ) . '">--' . __( 'OR', 'visualizer' ) . '--</option>';
431
432 foreach ( Visualizer_Source::getAllowedTypes() as $type ) {
433 $selected = array_key_exists( $header, $series ) && $type === $series[ $header ] ? 'selected' : '';
434 echo '<option value="' . $type . '" ' . $selected . '>' . $type . '</option>';
435 }
436
437 echo '</select></td>';
438 }
439 ?>
440 </tr>
441 <?php
442 // for remote sources, the data exists inside 'data'.
443 if ( array_key_exists( 'data', $data ) ) {
444 $data = $data['data'];
445 }
446
447 foreach ( $data as $row ) {
448 echo '<tr>';
449 echo '<th>' . __( 'Value', 'visualizer' ) . '</th>';
450 $index = 0;
451 if ( empty( $row ) ) {
452 echo '<td></td>';
453 continue;
454 }
455 foreach ( array_values( $row ) as $value ) {
456 if ( $editable_data ) {
457 echo '<td><input type="text" name="data' . $index++ . '[]" value="' . esc_attr( stripslashes( $value ) ) . '"></td>';
458 } else {
459 echo '<td>' . ( is_array( $value ) ? __( 'Invalid Data', 'visualizer' ) : $value ) . '</td>';
460 }
461 }
462
463 echo '</tr>';
464 }
465 ?>
466 </tbody>
467 </table>
468 <?php
469 if ( ! $echo ) {
470 return ob_get_clean();
471 }
472 }
473
474 /**
475 * Generates the permissions tab.
476 *
477 * @access private
478 */
479 private static function _renderPermissions( $args ) {
480 $chart_id = $args[1];
481
482 // ignore for unit tests because Travis throws the error "Indirect modification of overloaded property Visualizer_Render_Page_Data::$permissions has no effect".
483 if ( defined( 'WP_TESTS_DOMAIN' ) ) {
484 return;
485 }
486
487 $permissions = apply_filters( 'visualizer_pro_get_permissions', null, $chart_id );
488 if ( is_array( $permissions ) ) {
489 $permissions = $permissions['permissions'];
490 } else {
491 $permissions = array();
492 }
493 if ( ! isset( $permissions['read'] ) ) {
494 $permissions['read'] = 'all';
495 }
496 if ( ! isset( $permissions['edit'] ) ) {
497 $permissions['edit'] = 'roles';
498 $permissions['edit-specific'] = 'administrator';
499 }
500
501 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' );
502 echo '<div style="position: relative">';
503 Visualizer_Render_Sidebar::_renderSectionStart();
504 Visualizer_Render_Sidebar::_renderSectionDescription( esc_html__( 'Configure permissions for the chart.', 'visualizer' ) );
505 Visualizer_Render_Sidebar::_renderSectionEnd();
506
507 Visualizer_Render_Sidebar::_renderSectionStart( esc_html__( 'Who can see this chart?', 'visualizer' ), false );
508 Visualizer_Render_Sidebar::_renderSelectItem(
509 '',
510 'permissions[read]',
511 $permissions['read'],
512 array(
513 'all' => esc_html__( 'All Users', 'visualizer' ),
514 'users' => esc_html__( 'Select Users', 'visualizer' ),
515 'roles' => esc_html__( 'Select Roles', 'visualizer' ),
516 ),
517 '',
518 false,
519 array( 'visualizer-permission', 'visualizer-permission-type', 'visualizer-permission-read' ),
520 array(
521 'permission-type' => 'read',
522 )
523 );
524
525 $options = apply_filters( 'visualizer_pro_get_permissions_data', array(), isset( $permissions['read'] ) ? $permissions['read'] : 'roles' );
526
527 Visualizer_Render_Sidebar::_renderSelectItem(
528 '',
529 'permissions[read-specific][]',
530 isset( $permissions['read-specific'] ) ? $permissions['read-specific'] : array(),
531 $options,
532 '',
533 true,
534 array( 'visualizer-permission', 'visualizer-permission-specific', 'visualizer-permission-read-specific' )
535 );
536 Visualizer_Render_Sidebar::_renderSectionEnd();
537
538 Visualizer_Render_Sidebar::_renderSectionStart( esc_html__( 'Who can edit this chart?', 'visualizer' ), false );
539 Visualizer_Render_Sidebar::_renderSelectItem(
540 '',
541 'permissions[edit]',
542 $permissions['edit'],
543 array(
544 'all' => esc_html__( 'All Users', 'visualizer' ),
545 'users' => esc_html__( 'Select Users', 'visualizer' ),
546 'roles' => esc_html__( 'Select Roles', 'visualizer' ),
547 ),
548 '',
549 false,
550 array( 'visualizer-permission', 'visualizer-permission-type', 'visualizer-permission-edit' ),
551 array(
552 'permission-type' => 'edit',
553 )
554 );
555
556 $options = apply_filters( 'visualizer_pro_get_permissions_data', array(), isset( $permissions['edit'] ) ? $permissions['edit'] : 'roles' );
557
558 Visualizer_Render_Sidebar::_renderSelectItem(
559 '',
560 'permissions[edit-specific][]',
561 isset( $permissions['edit-specific'] ) ? $permissions['edit-specific'] : array(),
562 $options,
563 '',
564 true,
565 array( 'visualizer-permission', 'visualizer-permission-specific', 'visualizer-permission-edit-specific' )
566 );
567 Visualizer_Render_Sidebar::_renderSectionEnd();
568 echo apply_filters( 'visualizer_pro_upsell', '', 'chart-permissions' );
569 echo '</div>';
570 Visualizer_Render_Sidebar::_renderGroupEnd();
571 }
572
573 /**
574 * Show the Settings tab for this chart.
575 *
576 * @access public
577 */
578 public static function _renderTabAdvanced( $args ) {
579 $sidebar = $args[2];
580 ?>
581 <ul class="viz-group-wrapper full-height">
582 <li class="viz-group open" id="vz-chart-settings">
583 <ul class="viz-group-content">
584 <ul class="viz-group-wrapper">
585 <form id="settings-form" action="<?php echo add_query_arg( 'nonce', wp_create_nonce() ); ?>" method="post">
586 <input type="hidden" id="chart-img" name="chart-img">
587 <?php echo $sidebar; ?>
588 <?php self::_renderPermissions( $args ); ?>
589 <input type="hidden" name="save" value="1">
590 </form>
591 <form id="cancel-form" action="<?php echo add_query_arg( 'nonce', wp_create_nonce() ); ?>" method="post">
592 <input type="hidden" name="cancel" value="1">
593 </form>
594 </ul>
595 </ul>
596 </li>
597 <?php
598 }
599
600 /**
601 * Show the Docs tab for this chart.
602 *
603 * @access public
604 */
605 public static function _renderTabHelp( $args ) {
606 $chart_id = $args[1];
607 $type = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true );
608 switch ( $type ) {
609 case 'tabular':
610 $type = 'table';
611 break;
612 case 'polarArea':
613 $type = 'polar-area';
614 break;
615 case 'radar':
616 $type = 'radar-spider';
617 break;
618 }
619
620 $displayType = str_replace( '-', '/', $type );
621 ?>
622 <ul class="viz-group-wrapper full-height">
623 <li class="viz-group open" id="vz-chart-help">
624 <ul class="viz-group-wrapper">
625 <?php
626 // open this tab by default.
627 Visualizer_Render_Sidebar::_renderGroupStart( esc_html__( 'Documentation', 'visualizer' ), '', 'open' );
628 Visualizer_Render_Sidebar::_renderSectionStart( esc_html__( 'General', 'visualizer' ), true );
629 ?>
630 <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>
631 <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>
632 <?php
633 Visualizer_Render_Sidebar::_renderSectionEnd();
634 Visualizer_Render_Sidebar::_renderSectionStart( sprintf( __( '%s chart', 'visualizer' ), ucwords( $displayType ) ), true );
635 ?>
636 <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>
637 <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>
638 <?php
639 Visualizer_Render_Sidebar::_renderSectionEnd();
640 Visualizer_Render_Sidebar::_renderGroupEnd();
641 ?>
642 </ul>
643 </li>
644 </ul>
645
646 <?php
647 }
648
649 /**
650 * Show the Data Source tab for this chart.
651 *
652 * @access public
653 */
654 public static function _renderTabBasic( $args ) {
655 $chart_id = $args[1];
656
657 $upload_link = add_query_arg(
658 array(
659 'action' => Visualizer_Plugin::ACTION_UPLOAD_DATA,
660 'nonce' => wp_create_nonce(),
661 'chart' => $chart_id,
662 ),
663 admin_url( 'admin-ajax.php' )
664 );
665
666 // this will allow us to open the correct source tab by default.
667 $source_of_chart = strtolower( get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true ) );
668 // both import from wp and import from db have the same source so we need to differentiate.
669 $filter_config = get_post_meta( $chart_id, Visualizer_Plugin::CF_FILTER_CONFIG, true );
670 // if filter config is present, then its import from wp.
671 if ( ! empty( $filter_config ) ) {
672 $source_of_chart .= '_wp';
673 }
674 $editor_type = get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, true );
675 if ( $editor_type ) {
676 $source_of_chart = 'visualizer_source_manual';
677 }
678
679 $type = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true );
680 $lib = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_LIBRARY, true );
681 ?>
682 <ul class="viz-group-wrapper full-height">
683 <li class="viz-group open" id="vz-chart-source">
684 <ul class="viz-group-content">
685 <ul class="viz-group-wrapper">
686 <!-- import from file -->
687 <li class="viz-group visualizer_source_csv">
688 <h2 class="viz-group-title viz-sub-group visualizer-src-tab"><?php _e( 'Import data from file', 'visualizer' ); ?></h2>
689 <div class="viz-group-content">
690 <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>
691 <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>
692 <form id="vz-csv-file-form" action="<?php echo $upload_link; ?>" method="post"
693 target="thehole" enctype="multipart/form-data">
694 <input type="hidden" id="remote-data" name="remote_data">
695 <div class="">
696 <input type="file" id="csv-file" name="local_data">
697 </div>
698 <input type="button" class="button button-primary" id="vz-import-file"
699 value="<?php _e( 'Import', 'visualizer' ); ?>">
700 </form>
701 </div>
702 </li>
703 <!-- import from url -->
704 <li class="viz-group visualizer-import-url visualizer_source_csv_remote visualizer_source_json">
705 <h2 class="viz-group-title viz-sub-group visualizer-src-tab"><?php _e( 'Import data from URL', 'visualizer' ); ?></h2>
706 <ul class="viz-group-content">
707 <!-- import from csv url -->
708 <li class="viz-subsection">
709 <span class="viz-section-title"><?php _e( 'Import from CSV', 'visualizer' ); ?></span>
710 <div class="viz-section-items section-items">
711 <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>
712 <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>
713 <form id="vz-one-time-import" action="<?php echo $upload_link; ?>" method="post"
714 target="thehole" enctype="multipart/form-data">
715 <div class="remote-file-section">
716 <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">
717 </div>
718 <select name="vz-import-time" id="vz-import-time" class="visualizer-select">
719 <?php
720 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_SCHEDULE, true );
721 $schedules = apply_filters(
722 'visualizer_chart_schedules', array(
723 '-1' => __( 'One-time', 'visualizer' ),
724 ),
725 'csv',
726 $chart_id
727 );
728 foreach ( $schedules as $num => $name ) {
729 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
730 $extra = $num == $hours ? 'selected' : '';
731 ?>
732 <option value="<?php echo $num; ?>" <?php echo $extra; ?>><?php echo $name; ?></option>
733 <?php
734 }
735 do_action( 'visualizer_chart_schedules_spl', 'csv', $chart_id, 1 );
736 ?>
737 </select>
738
739 <?php
740 if ( ! Visualizer_Module::is_pro() ) {
741 ?>
742 <input type="button" id="view-remote-file" class="button button-primary" value="<?php _e( 'Import', 'visualizer' ); ?>">
743 <?php
744 } else {
745 ?>
746 <input type="button" id="vz-save-schedule" class="button button-primary" value="<?php _e( 'Import & Save schedule', 'visualizer' ); ?>">
747 <?php
748 }
749 ?>
750 </form>
751 </div>
752 </li>
753 <!-- import from json url -->
754 <li class="viz-subsection">
755 <span class="viz-section-title visualizer_source_json"><?php _e( 'Import from JSON', 'visualizer' ); ?></span>
756 <div class="viz-section-items section-items">
757 <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>
758 <form id="vz-import-json" action="<?php echo $upload_link; ?>" method="post" target="thehole" enctype="multipart/form-data">
759 <div class="remote-file-section">
760 <?php
761 $bttn_label = 'visualizer_source_json' === $source_of_chart ? __( 'Modify Parameters', 'visualizer' ) : __( 'Create Parameters', 'visualizer' );
762 if ( Visualizer_Module::is_pro() ) {
763 ?>
764 <p class="viz-group-description"><?php _e( 'How often do you want to check the URL', 'visualizer' ); ?></p>
765 <select name="time" id="vz-json-time" class="visualizer-select json-form-element" data-chart="<?php echo $chart_id; ?>">
766 <?php
767 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, true );
768 $schedules = apply_filters(
769 'visualizer_chart_schedules', array(
770 '-1' => __( 'One-time', 'visualizer' ),
771 ),
772 'json',
773 $chart_id
774 );
775 foreach ( $schedules as $num => $name ) {
776 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
777 $extra = $num == $hours ? 'selected' : '';
778 ?>
779 <option value="<?php echo $num; ?>" <?php echo $extra; ?>><?php echo $name; ?></option>
780 <?php
781 }
782 do_action( 'visualizer_chart_schedules_spl', 'json', $chart_id, 1 );
783 ?>
784 </select>
785 <?php
786 }
787 ?>
788 </div>
789
790 <input type="button" id="json-chart-button" class="button button-secondary show-chart-toggle"
791 value="<?php echo $bttn_label; ?>" data-current="chart"
792 data-t-filter="<?php _e( 'Show Chart', 'visualizer' ); ?>"
793 data-t-chart="<?php echo $bttn_label; ?>">
794 <?php
795 if ( Visualizer_Module::is_pro() ) {
796 ?>
797 <input type="button" id="json-chart-save-button" class="button button-primary "
798 value="<?php _e( 'Save Schedule', 'visualizer' ); ?>">
799 <?php
800 }
801 ?>
802 </form>
803 </div>
804 </li>
805 </ul>
806 </li>
807 <!-- import from chart -->
808 <li class="viz-group viz-import-from-other <?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature' ); ?>">
809 <h2 class="viz-group-title viz-sub-group"
810 data-current="chart"><?php _e( 'Import from other chart', 'visualizer' ); ?><span
811 class="dashicons dashicons-lock"></span></h2>
812 <div class="viz-group-content edit-data-content">
813 <div>
814 <p class="viz-group-description"><?php _e( 'You can import here data from your previously created charts', 'visualizer' ); ?></p>
815 <form>
816 <select name="vz-import-from-chart" id="chart-id" class="visualizer-select">
817 <?php
818 $fetch_link = add_query_arg(
819 array(
820 'action' => Visualizer_Module::is_pro() ? Visualizer_Pro::ACTION_FETCH_DATA : '',
821 'nonce' => wp_create_nonce(),
822 ),
823 admin_url( 'admin-ajax.php' )
824 );
825 $query_args_charts = array(
826 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
827 'posts_per_page' => 300,
828 'no_found_rows' => true,
829 );
830 $charts = array();
831 $query = new WP_Query( $query_args_charts );
832 while ( $query->have_posts() ) {
833 $chart = $query->next_post();
834 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
835
836 $title = '#' . $chart->ID;
837 if ( ! empty( $settings['title'] ) ) {
838 $title = $settings['title'];
839 }
840 // for ChartJS, title is an array.
841 if ( is_array( $title ) && isset( $title['text'] ) ) {
842 $title = $title['text'];
843 }
844 if ( empty( $title ) ) {
845 $title = '#' . $chart->ID;
846 }
847
848 ?>
849 <option value="<?php echo $chart->ID; ?>"><?php echo $title; ?></option>
850 <?php
851 }
852 ?>
853
854 </select>
855 </form>
856 <input type="button" id="existing-chart" class="button button-primary"
857 value="<?php _e( 'Import Chart', 'visualizer' ); ?>"
858 data-viz-link="<?php echo $fetch_link; ?>">
859 <?php echo apply_filters( 'visualizer_pro_upsell', '' ); ?>
860 </div>
861 </div>
862 </li>
863
864 <?php
865 $save_filter = add_query_arg(
866 array(
867 'action' => Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY,
868 'security' => wp_create_nonce( Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY . Visualizer_Plugin::VERSION ),
869 'chart' => $chart_id,
870 ), admin_url( 'admin-ajax.php' )
871 );
872 ?>
873 <!-- import from WordPress -->
874 <li class="viz-group visualizer_source_query_wp <?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'import-wp' ); ?> ">
875 <h2 class="viz-group-title viz-sub-group"><?php _e( 'Import from WordPress', 'visualizer' ); ?><span
876 class="dashicons dashicons-lock"></span></h2>
877 <div class="viz-group-content edit-data-content">
878 <div>
879 <p class="viz-group-description"><?php _e( 'You can import data from WordPress here.', 'visualizer' ); ?></p>
880 <form id="vz-filter-wizard" action="<?php echo $save_filter; ?>" method="post" target="thehole">
881 <p class="viz-group-description"><?php _e( 'How often do you want to refresh the data from WordPress.', 'visualizer' ); ?></p>
882 <select name="refresh" id="vz-filter-import-time" class="visualizer-select">
883 <?php
884 $bttn_label = 'visualizer_source_query_wp' === $source_of_chart ? __( 'Modify Filter', 'visualizer' ) : __( 'Create Filter', 'visualizer' );
885 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, true );
886 $schedules = apply_filters(
887 'visualizer_chart_schedules', array(
888 '-1' => __( 'One-time', 'visualizer' ),
889 ),
890 'wp',
891 $chart_id
892 );
893 foreach ( $schedules as $num => $name ) {
894 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
895 $extra = $num == $hours ? 'selected' : '';
896 ?>
897 <option value="<?php echo $num; ?>" <?php echo $extra; ?>><?php echo $name; ?></option>
898 <?php
899 }
900 do_action( 'visualizer_chart_schedules_spl', 'wp', $chart_id, 1 );
901 ?>
902 </select>
903
904 <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; ?>">
905 <input type="button" id="db-filter-save-button" class="button button-primary" value="<?php _e( 'Save Schedule', 'visualizer' ); ?>">
906 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'db-query' ); ?>
907 </form>
908 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'import-wp' ); ?>
909 </div>
910 </div>
911 </li>
912
913 <?php
914 $save_query = add_query_arg(
915 array(
916 'action' => Visualizer_Plugin::ACTION_SAVE_DB_QUERY,
917 'security' => wp_create_nonce( Visualizer_Plugin::ACTION_SAVE_DB_QUERY . Visualizer_Plugin::VERSION ),
918 'chart' => $chart_id,
919 ), admin_url( 'admin-ajax.php' )
920 );
921 ?>
922 <!-- import from db -->
923 <li class="viz-group visualizer_source_query <?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'db-query' ); ?>">
924 <h2 class="viz-group-title viz-sub-group"><?php _e( 'Import from database', 'visualizer' ); ?><span
925 class="dashicons dashicons-lock"></span></h2>
926 <div class="viz-group-content edit-data-content">
927 <div>
928 <p class="viz-group-description"><?php _e( 'You can import data from the database here.', 'visualizer' ); ?></p>
929 <form id="vz-db-wizard" action="<?php echo $save_query; ?>" method="post" target="thehole">
930 <p class="viz-group-description"><?php _e( 'How often do you want to refresh the data from the database.', 'visualizer' ); ?></p>
931 <select name="refresh" id="vz-db-import-time" class="visualizer-select">
932 <?php
933 $bttn_label = 'visualizer_source_query' === $source_of_chart ? __( 'Modify Query', 'visualizer' ) : __( 'Create Query', 'visualizer' );
934 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, true );
935 $schedules = apply_filters(
936 'visualizer_chart_schedules', array(
937 '-1' => __( 'One-time', 'visualizer' ),
938 ),
939 'db',
940 $chart_id
941 );
942 foreach ( $schedules as $num => $name ) {
943 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
944 $extra = $num == $hours ? 'selected' : '';
945 ?>
946 <option value="<?php echo $num; ?>" <?php echo $extra; ?>><?php echo $name; ?></option>
947 <?php
948 }
949 do_action( 'visualizer_chart_schedules_spl', 'db', $chart_id, 1 );
950 ?>
951 </select>
952 <input type="hidden" name="params" id="viz-db-wizard-params">
953
954 <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; ?>">
955 <input type="button" id="db-chart-save-button" class="button button-primary" value="<?php _e( 'Save Schedule', 'visualizer' ); ?>">
956 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'db-query' ); ?>
957 </form>
958 </div>
959 </div>
960 </li>
961
962 <!-- manual -->
963 <li class="viz-group visualizer_source_manual">
964 <h2 class="viz-group-title viz-sub-group visualizer-editor-tab" data-current="chart"><?php _e( 'Manual Data', 'visualizer' ); ?>
965 <span class="dashicons dashicons-lock"></span>
966 </h2>
967 <div class="viz-group-content edit-data-content">
968 <form id="editor-form" action="<?php echo $upload_link; ?>" method="post" target="thehole">
969 <input type="hidden" id="chart-data" name="chart_data">
970 <input type="hidden" id="chart-data-src" name="chart_data_src">
971
972 <?php if ( Visualizer_Module::can_show_feature( 'simple-editor' ) ) { ?>
973 <div>
974 <p class="viz-group-description viz-editor-selection">
975 <?php _e( 'Use the', 'visualizer' ); ?>
976 <select name="editor-type" id="viz-editor-type">
977 <?php
978 if ( empty( $editor_type ) ) {
979 $editor_type = Visualizer_Module::is_pro() ? 'excel' : 'text';
980 }
981 foreach ( apply_filters( 'visualizer_editors', array( 'text' => __( 'Text', 'visualizer' ), 'table' => __( 'Simple', 'visualizer' ) ) ) as $e_type => $e_label ) {
982 ?>
983 <option value="<?php echo $e_type; ?>" <?php selected( $editor_type, $e_type ); ?> ><?php echo $e_label; ?></option>
984 <?php } ?>
985 </select>
986 <?php _e( 'editor to manually edit the chart data.', 'visualizer' ); ?>
987 </p>
988 <input type="button" id="editor-undo" class="button button-secondary" style="display: none" value="<?php _e( 'Undo Changes', 'visualizer' ); ?>">
989 <input type="button" id="editor-button" class="button button-primary "
990 value="<?php _e( 'Edit Data', 'visualizer' ); ?>" data-current="chart"
991 data-t-editor="<?php _e( 'Show Chart', 'visualizer' ); ?>"
992 data-t-chart="<?php _e( 'Edit Data', 'visualizer' ); ?>"
993 >
994 <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>
995 </div>
996 <?php } else { ?>
997 <input type="button" id="editor-undo" class="button button-secondary" style="display: none" value="<?php _e( 'Undo Changes', 'visualizer' ); ?>">
998 <input type="button" id="editor-chart-button" class="button button-primary "
999 value="<?php _e( 'View Editor', 'visualizer' ); ?>" data-current="chart"
1000 data-t-editor="<?php _e( 'Show Chart', 'visualizer' ); ?>"
1001 data-t-chart="<?php _e( 'View Editor', 'visualizer' ); ?>"
1002 >
1003 <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>
1004 <?php } ?>
1005 </form>
1006 </div>
1007 </li>
1008 </ul>
1009 </li>
1010 </ul>
1011 </ul>
1012
1013 <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>
1014 <iframe id="thehole" name="thehole"></iframe>
1015 <?php
1016 }
1017 }
1018