tablepress-pods/tablepress-pods.php

236 lines
10 KiB
PHP

<?php
/*
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.4.0
Author: Glen Whitney
Author URI: http://studioinfinity.org/
*/
/* Copyright (C) 2018-2019 Glen Whitney
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301 , USA.
*/
/*
* Usage and possible parameters:
* [table id=1 pod_name="mypod" pod_where="t.myfield = 'important'" /]
*
* Each row of the table which contains a Pods "magic tag" anywhere is expanded
* into one row for each of the pod records returned by
* pods(<pod_name>)->find(<pod_where>), with all of the magic tags in the row
* expanded for the corresponding record.
*
* The expansion can be controlled by the following "pseudo-shortcodes" which
* must occur at the beginning of the first column of the row (you may want to
* dedicate a hidden column just for this purpose if you are making use of these)
* [once] -- this row expands only into a single row (corresponding to the
* first record returned by the find() call), with magic
* tags expanded
* [literal] -- do not expand this row, except for removing the [literal]
* designation, even though it contains magic tags; hence, the
* magic tags will appear in the result.
*
* Note that in the pod_name and pod_where parameters, `((` and `))` are
* replaced by `[` and `]` respectively and do_shortcode() is run on the
* result, to facilitate the use of shortcodes to specify the values of these
* parameters.
*
* [table id=1 pod_name="mypod" pod_dump=true pod_where="t.myfield = 3" /]
*
* *Ignores* the contents of the table altogether, and replaces it with a
* simple dump of the ID, date, title, author, permalink, and all custom
* Pods fields for each record in a Pods custom post type. Note that the
* taxonomies, if any, of the post type will not be shown. Useful mainly for
* seeing what is present in your Pod; for any presentation tables you will
* most likely want to use the first form.
*
*/
add_filter( 'tablepress_shortcode_table_default_shortcode_atts',
'tbp_pods_add_shortcode_parameter_pods' );
add_filter( 'tablepress_table_raw_render_data', 'tbp_pods_expand_pod', 10, 2 );
add_filter( 'tablepress_admin_view_actions', 'tbp_pods_add_export_pod_action');
add_filter( 'tablepress_load_file_full_path', 'tbp_pods_exportpods_path', 10, 3);
add_filter( 'tablepress_view_data', 'tbp_pods_exportpods_data', 10, 2);
add_action( 'admin_post_tablepress_exportpods', 'tbp_pods_handle_exportpods');
function tbp_pods_add_shortcode_parameter_pods( $default_atts ) {
$default_atts['pod_name'] = '';
$default_atts['pod_dump'] = '';
$default_atts['pod_where'] = '';
return $default_atts;
}
function tbp_pods_add_export_pod_action( $view_actions ) {
$view_actions['exportpods'] = array(
'show_entry' => true,
'page_title' => __( 'Export Pods Table', 'tablepress' ),
'admin_menu_title' => __( 'Export Pods Table', 'tablepress' ),
'nav_tab_title' => _x( 'Export Pods', 'navigation bar', 'tablepress' ),
'required_cap' => 'tablepress_export_tables',
);
return $view_actions;
}
function tbp_pods_exportpods_path( $fullpath, $filename, $directory ) {
if ($filename !== 'view-exportpods.php') return $fullpath;
return plugin_dir_path( __FILE__ ) . $filename;
}
function tbp_pods_exportpods_data( $data, $act ) {
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();
if ( ! empty( $_GET['table_id'] ) ) {
$data['export_ids'] = explode( ',', $_GET['table_id'] );
} else {
// Just show empty export form.
$data['export_ids'] = array();
}
$exporter = TablePress::load_class( 'TablePress_Export', 'class-export.php', 'classes' );
$data['zip_support_available'] = false;
$data['export_formats'] = $exporter->export_formats;
$data['export_format'] = ( ! empty( $_GET['export_format'] ) ) ? $_GET['export_format'] : false;
$data['csv_delimiters'] = $exporter->csv_delimiters;
$data['csv_delimiter'] = ( ! empty( $_GET['csv_delimiter'] ) ) ? $_GET['csv_delimiter'] : _x( ',', 'Default CSV delimiter in the translated language (";", ",", or "tab")', 'tablepress' );
$data['pods'] = pods_api()->load_pods();
$data['pod_name'] = ( ! empty( $_GET['pod_name'] ) ) ? $_GET['pod_name'] : false;
return $data;
}
function tbp_pods_maybe_shortcodes($value) {
$bracketed = str_replace(array('((', '))'), array('[', ']'));
return do_shortcode($bracketed);
}
function tbp_pods_expand_pod( $table, $render_options) {
if (empty($render_options['pod_name'])) return $table;
$final_pod_name = tbp_pods_maybe_shortcodes($render_options['pod_name']);
$pod_params = array('limit'=>-1);
if (!empty($render_options['pod_where'])) {
$pod_params['where'] =
tbp_pods_maybe_shortcodes($render_options['pod_where']);
}
$pod = pods($final_pod_name, $pod_params);
$ndata = array();
$rvis = array();
$cvis = array();
if (empty($render_options['pod_dump'])) {
# Standard case: expand rows with magic tags into multiple rows,
# one for each record in $pod, controlled by the pseudo-shortcodes
$cvis = $table['visibility']['columns'];
$orig_rvis = $table['visibility']['rows'];
foreach ($table['data'] as $row_idx => $row) {
# First, check for the [literal] code since nothing much to do then
if (0 === strpos($row[0], '[literal]')) {
$row[0] = substr($row[0], 9);
$ndata[] = $row;
$rvis[] = $orig_rvis[$row_idx];
continue;
}
# Similarly, if no magic tags, just copy the row.
$wholerow = implode('',$row);
if (!preg_match('/{@.*}/', $wholerow)) {
$ndata[] = $row;
$rvis[] = $orig_rvis[$row_idx];
continue;
}
# OK, we need to expand magic tags in the row. First check for
# the [once] pseudo-shortcode:
$one_timer = FALSE;
if (0 === strpos($row[0], '[once]')) {
$row[0] = substr($row[0], 6);
$one_timer = TRUE;
}
# Here's the expansion loop
$pod->reset();
while ($pod->fetch()) {
$ndata[] = array_map(function($c) use($pod) {
return $pod->do_magic_tags($c);
}, $row);
$rvis[] = $orig_rvis[$row_idx];
if ($one_timer) { break; }
}
} # for each row of the original table
} else { # pod_dump is specified.
$flds = $pod->fields();
$hrow = array('ID','Date','Title','Author','Permalink');
$cvis = array(TRUE, TRUE, TRUE, TRUE, TRUE);
$frow = array();
foreach ($flds as $fkey => $finfo) {
$hrow[] = $finfo['label'];
$cvis[] = TRUE;
$frow[] = $fkey;
}
$ndata[] = $hrow;
$rvis = array(TRUE);
while ($pod->fetch()) {
$nrow = array();
$nrow[] = $pod->field('id');
$nrow[] = $pod->display('post_date');
$nrow[] = $pod->field('title');
$nrow[] = get_the_author_meta('display_name', $pod->field('author'));
$nrow[] = $pod->field('permalink');
foreach ($frow as $field_slug) {
$nrow[] = $pod->display($field_slug);
}
$ndata[] = $nrow;
$rvis[] = TRUE;
}
} # do a pod dump
# OK, install the new table information
$table['data'] = $ndata;
$table['visibility']['rows'] = $rvis;
$table['visibility']['columns'] = $cvis;
return $table;
}
function tbp_pods_handle_exportpods () {
TablePress::check_nonce( 'exportpods' );
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'] );
}
/* Reset the nonce for forwarding the action */
$_REQUEST['_wpnonce'] = wp_create_nonce( TablePress::nonce( 'export' ) );
/* Set up the filter using the pod params */
$r_opts = array('pod_name' => $export['pod_name'],
'pod_where' => $export['pod_where']
);
if ( isset( $export['pod_dump'] ) ) {
$r_opts['pod_dump'] = true;
}
$filter = function( $data, $tab, $fmt, $delim ) use ($r_opts) {
$newtab = tbp_pods_expand_pod($tab, $r_opts);
$exporter = TablePress::load_class( 'TablePress_Export', 'class-export.php', 'classes' );
return $exporter->export_table( $newtab, $fmt, $delim );
};
/* Temporarily set a filter on exporting */
add_filter( 'tablepress_export_data', $filter, 10, 4);
do_action( 'admin_post_tablepress_export' );
remove_filter( 'tablepress_export_data', $filter, 10 );
}