Skip to content

Commit a5abe96

Browse files
add actions buttons #192
1 parent f4d7766 commit a5abe96

File tree

18 files changed

+695
-286
lines changed

18 files changed

+695
-286
lines changed

classes/Visualizer/Module.php

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,177 @@ protected function _addShortcode( $tag, $method ) {
143143
return $this;
144144
}
145145

146+
/**
147+
* Extracts the data for a chart and prepares it for the given type.
148+
*
149+
* @access protected
150+
* @param int $chart_id The chart id.
151+
* @param string $type The exported type.
152+
*/
153+
protected function _getDataAs( $chart_id, $type ) {
154+
$final = null;
155+
$success = false;
156+
if ( $chart_id ) {
157+
$chart = get_post( $chart_id );
158+
$success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
159+
}
160+
if ( $success ) {
161+
$settings = get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true );
162+
$rows = array();
163+
$series = get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true );
164+
$data = unserialize( $chart->post_content );
165+
if ( ! empty( $series ) ) {
166+
$row = array();
167+
foreach ( $series as $array ) {
168+
$row[] = $array['label'];
169+
}
170+
$rows[] = $row;
171+
$row = array();
172+
foreach ( $series as $array ) {
173+
$row[] = $array['type'];
174+
}
175+
$rows[] = $row;
176+
}
177+
if ( ! empty( $data ) ) {
178+
foreach ( $data as $array ) {
179+
// ignore strings
180+
if ( ! is_array( $array ) ) {
181+
continue;
182+
}
183+
// if this is an array of arrays...
184+
if ( is_array( $array[0] ) ) {
185+
foreach ( $array as $arr ) {
186+
$rows[] = $arr;
187+
}
188+
} else {
189+
// just an array
190+
$rows[] = $array;
191+
}
192+
}
193+
}
194+
195+
$filename = isset( $settings['title'] ) && ! empty( $settings['title'] ) ? $settings['title'] : 'visualizer#' . $chart_id;
196+
197+
switch ( $type ) {
198+
case 'csv':
199+
$final = $this->_getCSV( $rows, $filename );
200+
break;
201+
case 'xls':
202+
$final = $this->_getExcel( $rows, $filename );
203+
break;
204+
case 'print':
205+
$final = $this->_getHTML( $rows );
206+
break;
207+
}
208+
}
209+
return $final;
210+
}
211+
212+
/**
213+
* Prepares a CSV.
214+
*
215+
* @access private
216+
* @param array $rows The array of data.
217+
* @param string $filename The name of the file to use.
218+
*/
219+
private function _getCSV( $rows, $filename ) {
220+
$filename .= '.csv';
221+
222+
$fp = tmpfile();
223+
// support for MS Excel
224+
fprintf( $fp, $bom = ( chr( 0xEF ) . chr( 0xBB ) . chr( 0xBF ) ) );
225+
foreach ( $rows as $row ) {
226+
fputcsv( $fp, $row );
227+
}
228+
rewind( $fp );
229+
$csv = '';
230+
while ( ( $array = fgetcsv( $fp ) ) !== false ) {
231+
if ( strlen( $csv ) > 0 ) {
232+
$csv .= PHP_EOL;
233+
}
234+
$csv .= implode( ',', $array );
235+
}
236+
fclose( $fp );
237+
238+
return array(
239+
'csv' => $csv,
240+
'name' => $filename,
241+
);
242+
}
243+
244+
/**
245+
* Prepares an Excel file.
246+
*
247+
* @access private
248+
* @param array $rows The array of data.
249+
* @param string $filename The name of the file to use.
250+
*/
251+
private function _getExcel( $rows, $filename ) {
252+
$chart = $filename;
253+
$filename .= '.xlsx';
254+
255+
$doc = new PHPExcel();
256+
$doc->getActiveSheet()->fromArray( $rows, null, 'A1' );
257+
$doc->getActiveSheet()->setTitle( $chart );
258+
$doc = apply_filters( 'visualizer_excel_doc', $doc );
259+
$writer = PHPExcel_IOFactory::createWriter( $doc, 'Excel2007' );
260+
ob_start();
261+
$writer->save( 'php://output' );
262+
$xlsData = ob_get_contents();
263+
ob_end_clean();
264+
return array(
265+
'csv' => 'data:application/vnd.ms-excel;base64,' . base64_encode( $xlsData ),
266+
'name' => $filename,
267+
);
268+
}
269+
270+
/**
271+
* Prepares an HTML table.
272+
*
273+
* @access private
274+
* @param array $rows The array of data.
275+
*/
276+
private function _getHTML( $rows ) {
277+
$css = '
278+
table.visualizer-print {
279+
border-collapse: collapse;
280+
}
281+
table.visualizer-print, table.visualizer-print th, table.visualizer-print td {
282+
border: 1px solid #000;
283+
}
284+
';
285+
$html = '';
286+
$html .= '
287+
<html>
288+
<head>
289+
<style>
290+
' . apply_filters( 'visualizer_print_css', $css ) . '
291+
</style>
292+
</head>
293+
<body>';
294+
295+
$table = '<table class="visualizer-print">';
296+
$index = 0;
297+
foreach ( $rows as $row ) {
298+
$table .= '<tr>';
299+
foreach ( $row as $col ) {
300+
if ( $index === 0 ) {
301+
$table .= '<th>' . $col . '</th>';
302+
} else {
303+
$table .= '<td>' . $col . '</td>';
304+
}
305+
}
306+
$table .= '</tr>';
307+
$index++;
308+
}
309+
$table .= '</table>';
310+
311+
$html .= apply_filters( 'visualizer_print_table', $table ) . '
312+
</body>
313+
</html>';
314+
return array(
315+
'csv' => $html,
316+
);
317+
}
318+
146319
}

classes/Visualizer/Module/Chart.php

Lines changed: 5 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,6 @@ public function cloneChart() {
509509
*/
510510
public function exportData() {
511511
check_ajax_referer( Visualizer_Plugin::ACTION_EXPORT_DATA . Visualizer_Plugin::VERSION, 'security' );
512-
$chart_id = $success = false;
513512
$capable = current_user_can( 'edit_posts' );
514513
if ( $capable ) {
515514
$chart_id = isset( $_GET['chart'] ) ? filter_var(
@@ -520,72 +519,13 @@ public function exportData() {
520519
)
521520
) : '';
522521
if ( $chart_id ) {
523-
$chart = get_post( $chart_id );
524-
$success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
525-
}
526-
}
527-
if ( $success ) {
528-
$settings = get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true );
529-
$filename = isset( $settings['title'] ) ? $settings['title'] : '';
530-
if ( empty( $filename ) ) {
531-
$filename = 'export.csv';
532-
} else {
533-
$filename .= '.csv';
534-
}
535-
$rows = array();
536-
$series = get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true );
537-
$data = unserialize( $chart->post_content );
538-
if ( ! empty( $series ) ) {
539-
$row = array();
540-
foreach ( $series as $array ) {
541-
$row[] = $array['label'];
522+
$data = $this->_getDataAs( $chart_id, 'csv' );
523+
if ( $data ) {
524+
echo wp_send_json_success( $data );
542525
}
543-
$rows[] = $row;
544-
$row = array();
545-
foreach ( $series as $array ) {
546-
$row[] = $array['type'];
547-
}
548-
$rows[] = $row;
549526
}
550-
if ( ! empty( $data ) ) {
551-
foreach ( $data as $array ) {
552-
// ignore strings
553-
if ( ! is_array( $array ) ) {
554-
continue;
555-
}
556-
// if this is an array of arrays...
557-
if ( is_array( $array[0] ) ) {
558-
foreach ( $array as $arr ) {
559-
$rows[] = $arr;
560-
}
561-
} else {
562-
// just an array
563-
$rows[] = $array;
564-
}
565-
}
566-
}
567-
$fp = tmpfile();
568-
// support for MS Excel
569-
fprintf( $fp, $bom = ( chr( 0xEF ) . chr( 0xBB ) . chr( 0xBF ) ) );
570-
foreach ( $rows as $row ) {
571-
fputcsv( $fp, $row );
572-
}
573-
rewind( $fp );
574-
$csv = '';
575-
while ( ( $array = fgetcsv( $fp ) ) !== false ) {
576-
if ( strlen( $csv ) > 0 ) {
577-
$csv .= PHP_EOL;
578-
}
579-
$csv .= implode( ',', $array );
580-
}
581-
fclose( $fp );
582-
echo wp_send_json_success(
583-
array(
584-
'csv' => $csv,
585-
'name' => $filename,
586-
)
587-
);
588-
}// End if().
527+
}
528+
589529
defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
590530
}
591531

classes/Visualizer/Module/Frontend.php

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,76 @@ public function __construct( Visualizer_Plugin $plugin ) {
6565
if ( ! has_filter( 'term_description', 'do_shortcode' ) ) {
6666
add_filter( 'term_description', 'do_shortcode' );
6767
}
68+
69+
add_action( 'rest_api_init', array( $this, 'endpoint_register' ) );
70+
}
71+
72+
/**
73+
* Registers the endpoints
74+
*/
75+
function endpoint_register() {
76+
register_rest_route(
77+
'visualizer/v' . VISUALIZER_REST_VERSION,
78+
'/action/(?P<chart>\d+)/(?P<type>.+)/',
79+
array(
80+
'methods' => 'GET',
81+
'callback' => array( $this, 'perform_action' ),
82+
)
83+
);
84+
}
85+
86+
/**
87+
* All possible actions and their labels
88+
*
89+
* @access private
90+
*/
91+
private function get_actions() {
92+
return apply_filters(
93+
'visualizer_action_buttons', array(
94+
'print' => __( 'Print', 'visualizer' ),
95+
'csv' => __( 'CSV', 'visualizer' ),
96+
'xls' => __( 'Excel', 'visualizer' ),
97+
'copy' => __( 'Copy', 'visualizer' ),
98+
)
99+
);
100+
}
101+
102+
/**
103+
* The print button
104+
*
105+
* @since 1.0.0
106+
*
107+
* @access public
108+
*/
109+
public function perform_action( WP_REST_Request $params ) {
110+
$chart_id = filter_var( sanitize_text_field( $params['chart'] ), FILTER_VALIDATE_INT );
111+
$type = sanitize_text_field( $params['type'] );
112+
$data = null;
113+
114+
if ( ! $chart_id ) {
115+
return new WP_REST_Response( array( 'error' => new WP_Error( __( 'Invalid chart ID', 'visualizer' ) ) ) );
116+
}
117+
118+
if ( ! $type ) {
119+
return new WP_REST_Response( array( 'error' => new WP_Error( __( 'Invalid action', 'visualizer' ) ) ) );
120+
}
121+
122+
switch ( $type ) {
123+
case 'print':
124+
$data = $this->_getDataAs( $chart_id, 'print' );
125+
break;
126+
case 'csv':
127+
$data = $this->_getDataAs( $chart_id, 'csv' );
128+
break;
129+
case 'xls':
130+
$data = $this->_getDataAs( $chart_id, 'xls' );
131+
break;
132+
default:
133+
$data = apply_filters( 'visualizer_action_data', $data, $chart_id, $type );
134+
break;
135+
}
136+
137+
return new WP_REST_Response( array( 'data' => $data ) );
68138
}
69139

70140
/**
@@ -79,6 +149,8 @@ public function enqueueScripts() {
79149
wp_register_script( 'visualizer-google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
80150
wp_register_script( 'visualizer-google-jsapi-old', '//www.google.com/jsapi', array( 'visualizer-google-jsapi-new' ), null, true );
81151
wp_register_script( 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array( 'visualizer-google-jsapi-old', 'jquery' ), Visualizer_Plugin::VERSION, true );
152+
wp_register_script( 'visualizer-clipboardjs', VISUALIZER_ABSURL . 'vendor/clipboardjs/clipboard.min.js', array( 'jquery' ), Visualizer_Plugin::VERSION, true );
153+
wp_enqueue_script( 'visualizer-clipboardjs' );
82154
}
83155

84156
/**
@@ -157,11 +229,41 @@ public function renderChart( $atts ) {
157229
'visualizer-render', 'visualizer', array(
158230
'charts' => $this->_charts,
159231
'map_api_key' => get_option( 'visualizer-map-api-key' ),
232+
'rest_url' => rest_url( 'visualizer/v' . VISUALIZER_REST_VERSION . '/action/#id#/#type#/' ),
233+
'i10n' => array(
234+
'copied' => __( 'Copied!', 'visualizer' ),
235+
),
160236
)
161237
);
162238

239+
$actions_div = '';
240+
if ( ! empty( $settings['actions'] ) ) {
241+
$actions = $this->get_actions();
242+
$actions_div = '<div class="visualizer-actions">';
243+
foreach ( $settings['actions'] as $action_type ) {
244+
$key = $action_type;
245+
$mime = '';
246+
if ( strpos( $action_type, ';' ) !== false ) {
247+
$array = explode( ';', $action_type );
248+
$key = $array[0];
249+
$mime = end( $array );
250+
}
251+
$label = $actions[ $key ];
252+
$actions_div .= '<a href="#" class="visualizer-action visualizer-action-' . $key . '" data-visualizer-type="' . $key . '" data-visualizer-chart-id="' . $atts['id'] . '" data-visualizer-mime="' . $mime . '" title="' . $label . '" ';
253+
254+
if ( 'copy' === $key ) {
255+
$copy = $this->_getDataAs( $atts['id'], 'copy' );
256+
$actions_div .= ' data-clipboard-text="' . esc_attr( $copy['csv'] ) . '"';
257+
}
258+
259+
$actions_div .= apply_filters( 'visualizer_action_attributes', '', $key, $atts['id'] );
260+
$actions_div .= '>' . $label . '</a>';
261+
}
262+
263+
$actions_div .= '</div>';
264+
}
163265
// return placeholder div
164-
return '<div id="' . $id . '"' . $class . '></div>';
266+
return $actions_div . '<div id="' . $id . '"' . $class . '></div>';
165267
}
166268

167269
}

0 commit comments

Comments
 (0)