fix: add an exportpods handler

This commit is contained in:
Glen Whitney 2021-02-08 12:33:53 -08:00
parent 30d8b4cd55
commit 8ccabf59a1
1 changed files with 142 additions and 3 deletions

View File

@ -3,9 +3,9 @@
Plugin Name: TablePress Extension: Pods tables
Plugin URI: https://code.studioinfinity.org/glen/tablepress-pods
Description: Custom Extension for TablePress to incorporate Pods information in tables
Version: 0.2.7
Version: 0.2.8
Author: Glen Whitney
Author URI: http ://studioinfinity.org/
Author URI: http://studioinfinity.org/
*/
/* Copyright (C) 2018-2019 Glen Whitney
@ -61,6 +61,7 @@ add_filter( 'tablepress_table_raw_render_data', 'playground_expand_pod', 10, 2 )
add_filter( 'tablepress_admin_view_actions', 'playground_add_export_pod_action');
add_filter( 'tablepress_load_file_full_path', 'playground_exportpods_path', 10, 3);
add_filter( 'tablepress_view_data', 'playground_exportpods_data', 10, 2);
add_action( 'admin_post_tablepress_exportpods', 'playground_handle_exportpods');
function playground_add_shortcode_parameter_pods( $default_atts ) {
$default_atts['pod_name'] = '';
@ -86,7 +87,7 @@ function playground_exportpods_path( $fullpath, $filename, $directory ) {
}
function playground_exportpods_data( $data, $act ) {
if ($action !== 'exportpods') return $data;
if ($act !== 'exportpods') return $data;
// Load all table IDs without priming the post meta cache, as table options/visibility are not needed.
$data['table_ids'] = TablePress::$model_table->load_all( false );
$data['tables_count'] = TablePress::$model_table->count_tables();
@ -184,3 +185,141 @@ function playground_expand_pod( $table, $render_options) {
$table['visibility']['columns'] = $cvis;
return $table;
}
function playground_handle_exportpods () {
TablePress::check_nonce( 'export' );
if ( ! current_user_can( 'tablepress_export_tables' ) ) {
wp_die( __( 'Sorry, you are not allowed to access this page.', 'default' ), 403 );
}
if ( empty( $_POST['export'] ) || ! is_array( $_POST['export'] ) ) {
TablePress::redirect( array( 'action' => 'export', 'message' => 'error_export' ) );
} else {
$export = wp_unslash( $_POST['export'] );
}
$exporter = TablePress::load_class( 'TablePress_Export', 'class-export.php', 'classes' );
if ( empty( $export['tables'] ) ) {
TablePress::redirect( array( 'action' => 'export', 'message' => 'error_export' ) );
}
if ( empty( $export['format'] ) || ! isset( $exporter->export_formats[ $export['format'] ] ) ) {
TablePress::redirect( array( 'action' => 'export', 'message' => 'error_export' ) );
}
if ( empty( $export['csv_delimiter'] ) ) {
// Set a value, so that the variable exists.
$export['csv_delimiter'] = '';
}
if ( 'csv' === $export['format'] && ! isset( $exporter->csv_delimiters[ $export['csv_delimiter'] ] ) ) {
TablePress::redirect( array( 'action' => 'export', 'message' => 'error_export' ) );
}
// Use list of tables from concatenated field if available (as that's hopefully not truncated by Suhosin, which is possible for $export['tables']).
$tables = ( ! empty( $export['tables_list'] ) ) ? explode( ',', $export['tables_list'] ) : $export['tables'];
// Determine if ZIP file support is available.
if ( $exporter->zip_support_available
&& ( ( isset( $export['zip_file'] ) && 'true' === $export['zip_file'] ) || count( $tables ) > 1 ) ) {
// Export to ZIP only if ZIP is desired or if more than one table were selected (mandatory then).
$export_to_zip = true;
} else {
$export_to_zip = false;
}
if ( ! $export_to_zip ) {
// This is only possible for one table, so take the first one.
if ( ! current_user_can( 'tablepress_export_table', $tables[0] ) ) {
wp_die( __( 'Sorry, you are not allowed to access this page.', 'default' ), 403 );
}
// Load table, with table data, options, and visibility settings.
$table = TablePress::$model_table->load( $tables[0], true, true );
if ( is_wp_error( $table ) ) {
TablePress::redirect( array( 'action' => 'export', 'message' => 'error_load_table', 'export_format' => $export['format'], 'csv_delimiter' => $export['csv_delimiter'] ) );
}
if ( isset( $table['is_corrupted'] ) && $table['is_corrupted'] ) {
TablePress::redirect( array( 'action' => 'export', 'message' => 'error_table_corrupted', 'export_format' => $export['format'], 'csv_delimiter' => $export['csv_delimiter'] ) );
}
$download_filename = sprintf( '%1$s-%2$s-%3$s.%4$s', $table['id'], $table['name'], date( 'Y-m-d' ), $export['format'] );
$download_filename = sanitize_file_name( $download_filename );
// Export the table.
$export_data = $exporter->export_table( $table, $export['format'], $export['csv_delimiter'] );
/**
* Filter the exported table data.
*
* @since 1.6.0
*
* @param string $export_data The exported table data.
* @param array $table Table to be exported.
* @param string $export_format Format for the export ('csv', 'html', 'json').
* @param string $csv_delimiter Delimiter for CSV export.
*/
$export_data = apply_filters( 'tablepress_export_data', $export_data, $table, $export['format'], $export['csv_delimiter'] );
$download_data = $export_data;
} else {
// Zipping can use a lot of memory and execution time, but not this much hopefully.
/** This filter is documented in the WordPress file wp-admin/admin.php */
@ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
@set_time_limit( 300 );
$zip_file = new ZipArchive();
$download_filename = sprintf( 'tablepress-export-%1$s-%2$s.zip', date_i18n( 'Y-m-d-H-i-s' ), $export['format'] );
$download_filename = sanitize_file_name( $download_filename );
$full_filename = wp_tempnam( $download_filename );
if ( true !== $zip_file->open( $full_filename, ZIPARCHIVE::OVERWRITE ) ) {
@unlink( $full_filename );
TablePress::redirect( array( 'action' => 'export', 'message' => 'error_create_zip_file', 'export_format' => $export['format'], 'csv_delimiter' => $export['csv_delimiter'] ) );
}
foreach ( $tables as $table_id ) {
// Don't export tables for which the user doesn't have the necessary export rights.
if ( ! current_user_can( 'tablepress_export_table', $table_id ) ) {
continue;
}
// Load table, with table data, options, and visibility settings.
$table = TablePress::$model_table->load( $table_id, true, true );
// Don't export if the table could not be loaded.
if ( is_wp_error( $table ) ) {
continue;
}
// Don't export if the table is corrupted.
if ( isset( $table['is_corrupted'] ) && $table['is_corrupted'] ) {
continue;
}
$export_data = $exporter->export_table( $table, $export['format'], $export['csv_delimiter'] );
/** This filter is documented in controllers/controller-admin.php */
$export_data = apply_filters( 'tablepress_export_data', $export_data, $table, $export['format'], $export['csv_delimiter'] );
$export_filename = sprintf( '%1$s-%2$s-%3$s.%4$s', $table['id'], $table['name'], date( 'Y-m-d' ), $export['format'] );
$export_filename = sanitize_file_name( $export_filename );
$zip_file->addFromString( $export_filename, $export_data );
}
// If something went wrong, or no files were added to the ZIP file, bail out.
if ( ! ZIPARCHIVE::ER_OK === $zip_file->status || 0 === $zip_file->numFiles ) {
$zip_file->close();
@unlink( $full_filename );
TablePress::redirect( array( 'action' => 'export', 'message' => 'error_create_zip_file', 'export_format' => $export['format'], 'csv_delimiter' => $export['csv_delimiter'] ) );
}
$zip_file->close();
// Load contents of the ZIP file, to send it as a download.
$download_data = file_get_contents( $full_filename );
@unlink( $full_filename );
}
// Send download headers for export file.
header( 'Content-Description: File Transfer' );
header( 'Content-Type: application/octet-stream' );
header( "Content-Disposition: attachment; filename=\"{$download_filename}\"" );
header( 'Content-Transfer-Encoding: binary' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate' );
header( 'Pragma: public' );
header( 'Content-Length: ' . strlen( $download_data ) );
// $filetype = text/csv, text/html, application/json
// header( 'Content-Type: ' . $filetype. '; charset=' . get_option( 'blog_charset' ) );
@ob_end_clean();
flush();
echo $download_data;
exit;
}