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

1,017 lines 43.9 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 <?php echo $sidebar; ?>
587 <?php self::_renderPermissions( $args ); ?>
588 <input type="hidden" name="save" value="1">
589 </form>
590 <form id="cancel-form" action="<?php echo add_query_arg( 'nonce', wp_create_nonce() ); ?>" method="post">
591 <input type="hidden" name="cancel" value="1">
592 </form>
593 </ul>
594 </ul>
595 </li>
596 <?php
597 }
598
599 /**
600 * Show the Docs tab for this chart.
601 *
602 * @access public
603 */
604 public static function _renderTabHelp( $args ) {
605 $chart_id = $args[1];
606 $type = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true );
607 switch ( $type ) {
608 case 'tabular':
609 $type = 'table';
610 break;
611 case 'polarArea':
612 $type = 'polar-area';
613 break;
614 case 'radar':
615 $type = 'radar-spider';
616 break;
617 }
618
619 $displayType = str_replace( '-', '/', $type );
620 ?>
621 <ul class="viz-group-wrapper full-height">
622 <li class="viz-group open" id="vz-chart-help">
623 <ul class="viz-group-wrapper">
624 <?php
625 // open this tab by default.
626 Visualizer_Render_Sidebar::_renderGroupStart( esc_html__( 'Documentation', 'visualizer' ), '', 'open' );
627 Visualizer_Render_Sidebar::_renderSectionStart( esc_html__( 'General', 'visualizer' ), true );
628 ?>
629 <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>
630 <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>
631 <?php
632 Visualizer_Render_Sidebar::_renderSectionEnd();
633 Visualizer_Render_Sidebar::_renderSectionStart( sprintf( __( '%s chart', 'visualizer' ), ucwords( $displayType ) ), true );
634 ?>
635 <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>
636 <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>
637 <?php
638 Visualizer_Render_Sidebar::_renderSectionEnd();
639 Visualizer_Render_Sidebar::_renderGroupEnd();
640 ?>
641 </ul>
642 </li>
643 </ul>
644
645 <?php
646 }
647
648 /**
649 * Show the Data Source tab for this chart.
650 *
651 * @access public
652 */
653 public static function _renderTabBasic( $args ) {
654 $chart_id = $args[1];
655
656 $upload_link = add_query_arg(
657 array(
658 'action' => Visualizer_Plugin::ACTION_UPLOAD_DATA,
659 'nonce' => wp_create_nonce(),
660 'chart' => $chart_id,
661 ),
662 admin_url( 'admin-ajax.php' )
663 );
664
665 // this will allow us to open the correct source tab by default.
666 $source_of_chart = strtolower( get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true ) );
667 // both import from wp and import from db have the same source so we need to differentiate.
668 $filter_config = get_post_meta( $chart_id, Visualizer_Plugin::CF_FILTER_CONFIG, true );
669 // if filter config is present, then its import from wp.
670 if ( ! empty( $filter_config ) ) {
671 $source_of_chart .= '_wp';
672 }
673 $editor_type = get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, true );
674 if ( $editor_type ) {
675 $source_of_chart = 'visualizer_source_manual';
676 }
677
678 $type = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true );
679 $lib = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_LIBRARY, true );
680 ?>
681 <ul class="viz-group-wrapper full-height">
682 <li class="viz-group open" id="vz-chart-source">
683 <ul class="viz-group-content">
684 <ul class="viz-group-wrapper">
685 <!-- import from file -->
686 <li class="viz-group visualizer_source_csv">
687 <h2 class="viz-group-title viz-sub-group visualizer-src-tab"><?php _e( 'Import data from file', 'visualizer' ); ?></h2>
688 <div class="viz-group-content">
689 <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>
690 <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>
691 <form id="vz-csv-file-form" action="<?php echo $upload_link; ?>" method="post"
692 target="thehole" enctype="multipart/form-data">
693 <input type="hidden" id="remote-data" name="remote_data">
694 <div class="">
695 <input type="file" id="csv-file" name="local_data">
696 </div>
697 <input type="button" class="button button-primary" id="vz-import-file"
698 value="<?php _e( 'Import', 'visualizer' ); ?>">
699 </form>
700 </div>
701 </li>
702 <!-- import from url -->
703 <li class="viz-group visualizer-import-url visualizer_source_csv_remote visualizer_source_json">
704 <h2 class="viz-group-title viz-sub-group visualizer-src-tab"><?php _e( 'Import data from URL', 'visualizer' ); ?></h2>
705 <ul class="viz-group-content">
706 <!-- import from csv url -->
707 <li class="viz-subsection">
708 <span class="viz-section-title"><?php _e( 'Import from CSV', 'visualizer' ); ?></span>
709 <div class="viz-section-items section-items">
710 <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>
711 <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>
712 <form id="vz-one-time-import" action="<?php echo $upload_link; ?>" method="post"
713 target="thehole" enctype="multipart/form-data">
714 <div class="remote-file-section">
715 <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">
716 </div>
717 <select name="vz-import-time" id="vz-import-time" class="visualizer-select">
718 <?php
719 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_SCHEDULE, true );
720 $schedules = apply_filters(
721 'visualizer_chart_schedules', array(
722 '-1' => __( 'One-time', 'visualizer' ),
723 ),
724 'csv',
725 $chart_id
726 );
727 foreach ( $schedules as $num => $name ) {
728 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
729 $extra = $num == $hours ? 'selected' : '';
730 ?>
731 <option value="<?php echo $num; ?>" <?php echo $extra; ?>><?php echo $name; ?></option>
732 <?php
733 }
734 do_action( 'visualizer_chart_schedules_spl', 'csv', $chart_id, 1 );
735 ?>
736 </select>
737
738 <?php
739 if ( ! Visualizer_Module::is_pro() ) {
740 ?>
741 <input type="button" id="view-remote-file" class="button button-primary" value="<?php _e( 'Import', 'visualizer' ); ?>">
742 <?php
743 } else {
744 ?>
745 <input type="button" id="vz-save-schedule" class="button button-primary" value="<?php _e( 'Import & Save schedule', 'visualizer' ); ?>">
746 <?php
747 }
748 ?>
749 </form>
750 </div>
751 </li>
752 <!-- import from json url -->
753 <li class="viz-subsection">
754 <span class="viz-section-title visualizer_source_json"><?php _e( 'Import from JSON', 'visualizer' ); ?></span>
755 <div class="viz-section-items section-items">
756 <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>
757 <form id="vz-import-json" action="<?php echo $upload_link; ?>" method="post" target="thehole" enctype="multipart/form-data">
758 <div class="remote-file-section">
759 <?php
760 $bttn_label = 'visualizer_source_json' === $source_of_chart ? __( 'Modify Parameters', 'visualizer' ) : __( 'Create Parameters', 'visualizer' );
761 if ( Visualizer_Module::is_pro() ) {
762 ?>
763 <p class="viz-group-description"><?php _e( 'How often do you want to check the URL', 'visualizer' ); ?></p>
764 <select name="time" id="vz-json-time" class="visualizer-select json-form-element" data-chart="<?php echo $chart_id; ?>">
765 <?php
766 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, true );
767 $schedules = apply_filters(
768 'visualizer_chart_schedules', array(
769 '-1' => __( 'One-time', 'visualizer' ),
770 ),
771 'json',
772 $chart_id
773 );
774 foreach ( $schedules as $num => $name ) {
775 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
776 $extra = $num == $hours ? 'selected' : '';
777 ?>
778 <option value="<?php echo $num; ?>" <?php echo $extra; ?>><?php echo $name; ?></option>
779 <?php
780 }
781 do_action( 'visualizer_chart_schedules_spl', 'json', $chart_id, 1 );
782 ?>
783 </select>
784 <?php
785 }
786 ?>
787 </div>
788
789 <input type="button" id="json-chart-button" class="button button-secondary show-chart-toggle"
790 value="<?php echo $bttn_label; ?>" data-current="chart"
791 data-t-filter="<?php _e( 'Show Chart', 'visualizer' ); ?>"
792 data-t-chart="<?php echo $bttn_label; ?>">
793 <?php
794 if ( Visualizer_Module::is_pro() ) {
795 ?>
796 <input type="button" id="json-chart-save-button" class="button button-primary "
797 value="<?php _e( 'Save Schedule', 'visualizer' ); ?>">
798 <?php
799 }
800 ?>
801 </form>
802 </div>
803 </li>
804 </ul>
805 </li>
806 <!-- import from chart -->
807 <li class="viz-group viz-import-from-other <?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature' ); ?>">
808 <h2 class="viz-group-title viz-sub-group"
809 data-current="chart"><?php _e( 'Import from other chart', 'visualizer' ); ?><span
810 class="dashicons dashicons-lock"></span></h2>
811 <div class="viz-group-content edit-data-content">
812 <div>
813 <p class="viz-group-description"><?php _e( 'You can import here data from your previously created charts', 'visualizer' ); ?></p>
814 <form>
815 <select name="vz-import-from-chart" id="chart-id" class="visualizer-select">
816 <?php
817 $fetch_link = add_query_arg(
818 array(
819 'action' => Visualizer_Module::is_pro() ? Visualizer_Pro::ACTION_FETCH_DATA : '',
820 'nonce' => wp_create_nonce(),
821 ),
822 admin_url( 'admin-ajax.php' )
823 );
824 $query_args_charts = array(
825 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
826 'posts_per_page' => 300,
827 'no_found_rows' => true,
828 );
829 $charts = array();
830 $query = new WP_Query( $query_args_charts );
831 while ( $query->have_posts() ) {
832 $chart = $query->next_post();
833 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
834
835 $title = '#' . $chart->ID;
836 if ( ! empty( $settings['title'] ) ) {
837 $title = $settings['title'];
838 }
839 // for ChartJS, title is an array.
840 if ( is_array( $title ) && isset( $title['text'] ) ) {
841 $title = $title['text'];
842 }
843 if ( empty( $title ) ) {
844 $title = '#' . $chart->ID;
845 }
846
847 ?>
848 <option value="<?php echo $chart->ID; ?>"><?php echo $title; ?></option>
849 <?php
850 }
851 ?>
852
853 </select>
854 </form>
855 <input type="button" id="existing-chart" class="button button-primary"
856 value="<?php _e( 'Import Chart', 'visualizer' ); ?>"
857 data-viz-link="<?php echo $fetch_link; ?>">
858 <?php echo apply_filters( 'visualizer_pro_upsell', '' ); ?>
859 </div>
860 </div>
861 </li>
862
863 <?php
864 $save_filter = add_query_arg(
865 array(
866 'action' => Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY,
867 'security' => wp_create_nonce( Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY . Visualizer_Plugin::VERSION ),
868 'chart' => $chart_id,
869 ), admin_url( 'admin-ajax.php' )
870 );
871 ?>
872 <!-- import from WordPress -->
873 <li class="viz-group visualizer_source_query_wp <?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'import-wp' ); ?> ">
874 <h2 class="viz-group-title viz-sub-group"><?php _e( 'Import from WordPress', 'visualizer' ); ?><span
875 class="dashicons dashicons-lock"></span></h2>
876 <div class="viz-group-content edit-data-content">
877 <div>
878 <p class="viz-group-description"><?php _e( 'You can import data from WordPress here.', 'visualizer' ); ?></p>
879 <form id="vz-filter-wizard" action="<?php echo $save_filter; ?>" method="post" target="thehole">
880 <p class="viz-group-description"><?php _e( 'How often do you want to refresh the data from WordPress.', 'visualizer' ); ?></p>
881 <select name="refresh" id="vz-filter-import-time" class="visualizer-select">
882 <?php
883 $bttn_label = 'visualizer_source_query_wp' === $source_of_chart ? __( 'Modify Filter', 'visualizer' ) : __( 'Create Filter', 'visualizer' );
884 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, true );
885 $schedules = apply_filters(
886 'visualizer_chart_schedules', array(
887 '-1' => __( 'One-time', 'visualizer' ),
888 ),
889 'wp',
890 $chart_id
891 );
892 foreach ( $schedules as $num => $name ) {
893 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
894 $extra = $num == $hours ? 'selected' : '';
895 ?>
896 <option value="<?php echo $num; ?>" <?php echo $extra; ?>><?php echo $name; ?></option>
897 <?php
898 }
899 do_action( 'visualizer_chart_schedules_spl', 'wp', $chart_id, 1 );
900 ?>
901 </select>
902
903 <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; ?>">
904 <input type="button" id="db-filter-save-button" class="button button-primary" value="<?php _e( 'Save Schedule', 'visualizer' ); ?>">
905 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'db-query' ); ?>
906 </form>
907 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'import-wp' ); ?>
908 </div>
909 </div>
910 </li>
911
912 <?php
913 $save_query = add_query_arg(
914 array(
915 'action' => Visualizer_Plugin::ACTION_SAVE_DB_QUERY,
916 'security' => wp_create_nonce( Visualizer_Plugin::ACTION_SAVE_DB_QUERY . Visualizer_Plugin::VERSION ),
917 'chart' => $chart_id,
918 ), admin_url( 'admin-ajax.php' )
919 );
920 ?>
921 <!-- import from db -->
922 <li class="viz-group visualizer_source_query <?php echo apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'db-query' ); ?>">
923 <h2 class="viz-group-title viz-sub-group"><?php _e( 'Import from database', 'visualizer' ); ?><span
924 class="dashicons dashicons-lock"></span></h2>
925 <div class="viz-group-content edit-data-content">
926 <div>
927 <p class="viz-group-description"><?php _e( 'You can import data from the database here.', 'visualizer' ); ?></p>
928 <form id="vz-db-wizard" action="<?php echo $save_query; ?>" method="post" target="thehole">
929 <p class="viz-group-description"><?php _e( 'How often do you want to refresh the data from the database.', 'visualizer' ); ?></p>
930 <select name="refresh" id="vz-db-import-time" class="visualizer-select">
931 <?php
932 $bttn_label = 'visualizer_source_query' === $source_of_chart ? __( 'Modify Query', 'visualizer' ) : __( 'Create Query', 'visualizer' );
933 $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, true );
934 $schedules = apply_filters(
935 'visualizer_chart_schedules', array(
936 '-1' => __( 'One-time', 'visualizer' ),
937 ),
938 'db',
939 $chart_id
940 );
941 foreach ( $schedules as $num => $name ) {
942 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
943 $extra = $num == $hours ? 'selected' : '';
944 ?>
945 <option value="<?php echo $num; ?>" <?php echo $extra; ?>><?php echo $name; ?></option>
946 <?php
947 }
948 do_action( 'visualizer_chart_schedules_spl', 'db', $chart_id, 1 );
949 ?>
950 </select>
951 <input type="hidden" name="params" id="viz-db-wizard-params">
952
953 <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; ?>">
954 <input type="button" id="db-chart-save-button" class="button button-primary" value="<?php _e( 'Save Schedule', 'visualizer' ); ?>">
955 <?php echo apply_filters( 'visualizer_pro_upsell', '', 'db-query' ); ?>
956 </form>
957 </div>
958 </div>
959 </li>
960
961 <!-- manual -->
962 <li class="viz-group visualizer_source_manual">
963 <h2 class="viz-group-title viz-sub-group visualizer-editor-tab" data-current="chart"><?php _e( 'Manual Data', 'visualizer' ); ?>
964 <span class="dashicons dashicons-lock"></span>
965 </h2>
966 <div class="viz-group-content edit-data-content">
967 <form id="editor-form" action="<?php echo $upload_link; ?>" method="post" target="thehole">
968 <input type="hidden" id="chart-data" name="chart_data">
969 <input type="hidden" id="chart-data-src" name="chart_data_src">
970
971 <?php if ( Visualizer_Module::can_show_feature( 'simple-editor' ) ) { ?>
972 <div>
973 <p class="viz-group-description viz-editor-selection">
974 <?php _e( 'Use the', 'visualizer' ); ?>
975 <select name="editor-type" id="viz-editor-type">
976 <?php
977 if ( empty( $editor_type ) ) {
978 $editor_type = Visualizer_Module::is_pro() ? 'excel' : 'text';
979 }
980 foreach ( apply_filters( 'visualizer_editors', array( 'text' => __( 'Text', 'visualizer' ), 'table' => __( 'Simple', 'visualizer' ) ) ) as $e_type => $e_label ) {
981 ?>
982 <option value="<?php echo $e_type; ?>" <?php selected( $editor_type, $e_type ); ?> ><?php echo $e_label; ?></option>
983 <?php } ?>
984 </select>
985 <?php _e( 'editor to manually edit the chart data.', 'visualizer' ); ?>
986 </p>
987 <input type="button" id="editor-undo" class="button button-secondary" style="display: none" value="<?php _e( 'Undo Changes', 'visualizer' ); ?>">
988 <input type="button" id="editor-button" class="button button-primary "
989 value="<?php _e( 'Edit Data', 'visualizer' ); ?>" data-current="chart"
990 data-t-editor="<?php _e( 'Show Chart', 'visualizer' ); ?>"
991 data-t-chart="<?php _e( 'Edit Data', 'visualizer' ); ?>"
992 >
993 <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>
994 </div>
995 <?php } else { ?>
996 <input type="button" id="editor-undo" class="button button-secondary" style="display: none" value="<?php _e( 'Undo Changes', 'visualizer' ); ?>">
997 <input type="button" id="editor-chart-button" class="button button-primary "
998 value="<?php _e( 'View Editor', 'visualizer' ); ?>" data-current="chart"
999 data-t-editor="<?php _e( 'Show Chart', 'visualizer' ); ?>"
1000 data-t-chart="<?php _e( 'View Editor', 'visualizer' ); ?>"
1001 >
1002 <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>
1003 <?php } ?>
1004 </form>
1005 </div>
1006 </li>
1007 </ul>
1008 </li>
1009 </ul>
1010 </ul>
1011
1012 <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>
1013 <iframe id="thehole" name="thehole"></iframe>
1014 <?php
1015 }
1016 }
1017