Skip to content

Commit

Permalink
Nonces for importing.
Browse files Browse the repository at this point in the history
  • Loading branch information
samwilson committed Feb 17, 2016
1 parent ffcedb7 commit ac516c6
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 55 deletions.
4 changes: 2 additions & 2 deletions src/Controllers/GrantsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function __construct( $wpdb ) {
parent::__construct( $wpdb );
if ( ! current_user_can( 'promote_users' ) ) {
$url = admin_url( 'admin.php?page=tabulate' );
wp_redirect( $url );
wp_safe_redirect( $url );
exit;
}
$db = new \WordPress\Tabulate\DB\Database( $this->wpdb );
Expand Down Expand Up @@ -82,7 +82,7 @@ public function save() {
// Save the grants and return to the granting table.
$grants->set( $new_grants );
$this->template->add_notice( 'updated', 'Grants saved.' );
wp_redirect( $this->get_url( 'index' ) );
wp_safe_redirect( $this->get_url( 'index' ) );
exit;
}

Expand Down
6 changes: 3 additions & 3 deletions src/Controllers/RecordController.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public function save( $args ) {
}
// Redirect back to the edit form.
$return_to = ( ! empty( $_REQUEST['return_to'] ) ) ? $_REQUEST['return_to'] : $template->record->get_url();
wp_redirect( $return_to );
wp_safe_redirect( $return_to );
exit;
}

Expand All @@ -138,7 +138,7 @@ public function delete( $args ) {
$table = $db->get_table( $args['table'] );
$record_ident = isset( $args['ident'] ) ? $args['ident'] : false;
if ( ! $record_ident ) {
wp_redirect( $table->get_url() );
wp_safe_redirect( $table->get_url() );
exit;
}
check_admin_referer( 'tabulate-record-' . $record_ident );
Expand All @@ -163,7 +163,7 @@ public function delete( $args ) {
return $template->render();
}

wp_redirect( $table->get_url() );
wp_safe_redirect( $table->get_url() );
exit;
}
}
10 changes: 5 additions & 5 deletions src/Controllers/SchemaController.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public function newtable( $args ) {
$template = new Template( 'table/schema.html' );
$template->add_notice( 'updated', 'New table created' );
$url = 'admin.php?page=tabulate&controller=schema&table='.$table->get_name();
wp_redirect( admin_url( $url ) );
wp_safe_redirect( admin_url( $url ) );
exit;
}

Expand All @@ -67,13 +67,13 @@ public function newtable( $args ) {
public function save( $args ) {
if ( ! isset( $args['table'] ) || ! current_user_can( 'promote_users' ) ) {
$url = admin_url( 'admin.php?page=tabulate' );
wp_redirect( $url );
wp_safe_redirect( $url );
exit;
}
$db = new Database( $this->wpdb );
$table = $db->get_table( $args['table'] );
if ( isset( $args['delete'] ) ) {
wp_redirect( $table->get_url( 'delete', null, 'schema' ) );
wp_safe_redirect( $table->get_url( 'delete', null, 'schema' ) );
exit;
}

Expand Down Expand Up @@ -123,7 +123,7 @@ public function save( $args ) {
$template = new Template( 'table/schema.html' );
$template->add_notice( 'updated', 'Schema updated.' );
$url = admin_url( 'admin.php?page=tabulate&controller=schema&table=' . $new_name );
wp_redirect( $url );
wp_safe_redirect( $url );
exit;
}

Expand All @@ -146,7 +146,7 @@ public function delete( $args ) {
// Carry out deletion.
$table->drop();
$template->add_notice( 'updated', 'Table dropped.' );
wp_redirect( admin_url( 'admin.php?page=tabulate' ) );
wp_safe_redirect( admin_url( 'admin.php?page=tabulate' ) );
exit;
}
}
127 changes: 82 additions & 45 deletions src/Controllers/TableController.php
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
<?php
/**
* This file contains only a single class.
*
* @file
* @package Tabulate
*/

namespace WordPress\Tabulate\Controllers;

use WordPress\Tabulate\Util;
use \WordPress\Tabulate\Util;
use \WordPress\Tabulate\DB\Grants;
use \WordPress\Tabulate\DB\Database;
use \WordPress\Tabulate\DB\Table;
use \WordPress\Tabulate\CSV;

/**
* The table controller handles viewing, exporting, and importing table data.
*/
class TableController extends ControllerBase {

/**
* Get a Table object for a given table, or an error message and the
* Tabulate overview page.
* @param string $table_name
*
* @param string $table_name The name of the table to get.
*/
protected function get_table( $table_name ) {
$db = new Database( $this->wpdb );
$table = $db->get_table( $table_name );
if ( ! $table ) {
add_action( 'admin_notices', function($table_name) use ($table_name) {
$err = __('Table "%s" not found.', 'tabulate');
add_action( 'admin_notices', function( $table_name ) use ( $table_name ) {
$err = __( 'Table "%s" not found.', 'tabulate' );
echo "<div class='error'><p>" . sprintf( $err, $table_name ) . "</p></div>";
} );
$home = new HomeController( $this->wpdb );
Expand All @@ -28,6 +39,12 @@ protected function get_table( $table_name ) {
return $table;
}

/**
* View and search a table's data.
*
* @param string[] $args The request arguments.
* @return string
*/
public function index( $args ) {
$table = $this->get_table( $args['table'] );
if ( ! $table instanceof Table ) {
Expand All @@ -38,7 +55,7 @@ public function index( $args ) {
$page_num = (isset( $args['p'] ) && is_numeric( $args['p'] ) ) ? abs( $args['p'] ) : 1;
$table->set_current_page_num( $page_num );
if ( isset( $args['psize'] ) ) {
$table->set_records_per_page( $args[ 'psize' ] );
$table->set_records_per_page( $args['psize'] );
}

// Ordering.
Expand All @@ -50,7 +67,7 @@ public function index( $args ) {
}

// Filters.
$filter_param = (isset( $args[ 'filter' ] )) ? $args[ 'filter' ] : array();
$filter_param = (isset( $args['filter'] )) ? $args['filter'] : array();
$table->add_filters( $filter_param );

// Give it all to the template.
Expand Down Expand Up @@ -84,10 +101,11 @@ public function index( $args ) {
* If a column is not present in the import the database will (obviously) use the default value if there is one;
* this will be shown in the preview.
* 4. When the user accepts the preview, the actual **import** of data is carried out.
* Rows are saved to the database using the usual [WebDB_DBMS_Table::save()](api/Webdb_DBMS_Table#save_row),
* Rows are saved to the database using the usual Table::save() method
* and a message presented to the user to indicate successful completion.
*
* @return void
* @param string[] $args The request parameters.
* @return string
*/
public function import( $args ) {
$template = new \WordPress\Tabulate\Template( 'import.html' );
Expand All @@ -105,7 +123,7 @@ public function import( $args ) {
$template->record = $table->get_default_record();
$template->action = 'import';
$template->table = $table;
$template->maxsize = size_format(wp_max_upload_size());
$template->maxsize = size_format( wp_max_upload_size() );
if ( ! Grants::current_user_can( Grants::IMPORT, $table->get_name() ) ) {
$template->add_notice( 'error', 'You do not have permission to import data into this table.' );
return $template->render();
Expand All @@ -114,33 +132,39 @@ public function import( $args ) {
/*
* Stage 1 of 4: Uploading.
*/
require_once ABSPATH.'/wp-admin/includes/file.php';
$template->form_action = $table->get_url( 'import' );
try {
$hash = isset( $_GET[ 'hash' ] ) ? $_GET[ 'hash' ] : false;
$uploaded = isset( $_FILES['file'] ) ? wp_handle_upload( $_FILES['file'], array( 'action' => $template->action ) ) : false;
$csv_file = new \WordPress\Tabulate\CSV( $hash, $uploaded );
$hash = isset( $_GET['hash'] ) ? $_GET['hash'] : false;
$uploaded = false;
if ( isset( $_FILES['file'] ) ) {
check_admin_referer( 'import-upload' );
$uploaded = wp_handle_upload( $_FILES['file'], array( 'action' => $template->action ) );
}
$csv_file = new CSV( $hash, $uploaded );
} catch ( \Exception $e ) {
$template->add_notice( 'error', $e->getMessage() );
return $template->render();
}

/*
* Stage 2 of 4: Matching fields
* Stage 2 of 4: Matching fields.
*/
if ( $csv_file->loaded() ) {
$template->file = $csv_file;
$template->stage = $template->stages[ 1 ];
$template->stage = $template->stages[1];
$template->form_action .= "&hash=" . $csv_file->hash;
}

/*
* Stage 3 of 4: Previewing
* Stage 3 of 4: Previewing.
*/
if ( $csv_file->loaded() AND isset( $_POST[ 'preview' ] ) ) {
$template->stage = $template->stages[ 2 ];
$template->columns = serialize( $_POST[ 'columns' ] );
if ( $csv_file->loaded() && isset( $_POST['preview'] ) ) {
check_admin_referer( 'import-preview' );
$template->stage = $template->stages[2];
$template->columns = serialize( $_POST['columns'] );
$errors = array();
// Make sure all required columns are selected
// Make sure all required columns are selected.
foreach ( $table->get_columns() as $col ) {
// Handle missing columns separately; other column errors are
// done in the CSV class. Missing columns don't matter if importing
Expand All @@ -161,10 +185,11 @@ public function import( $args ) {
}

/*
* Stage 4 of 4: Import
* Stage 4 of 4: Import.
*/
if ( $csv_file->loaded() AND isset( $_POST['import'] ) ) {
$template->stage = $template->stages[ 3 ];
if ( $csv_file->loaded() && isset( $_POST['import'] ) ) {
check_admin_referer( 'import-finish' );
$template->stage = $template->stages[3];
$this->wpdb->query( 'BEGIN' );
$result = $csv_file->import_data( $table, unserialize( wp_unslash( $_POST['columns'] ) ) );
$this->wpdb->query( 'COMMIT' );
Expand All @@ -174,10 +199,16 @@ public function import( $args ) {
return $template->render();
}

/**
* A calendar for tables with a date column.
*
* @param string[] $args The request parameters.
* @return type
*/
public function calendar( $args ) {
// @todo Validate args.
$yearNum = (isset( $args['year'] )) ? $args['year'] : date( 'Y' );
$monthNum = (isset( $args['month'] )) ? $args['month'] : date( 'm' );
$year_num = (isset( $args['year'] )) ? $args['year'] : date( 'Y' );
$month_num = (isset( $args['month'] )) ? $args['month'] : date( 'm' );

$template = new \WordPress\Tabulate\Template( 'calendar.html' );
$table = $this->get_table( $args['table'] );
Expand All @@ -188,26 +219,26 @@ public function calendar( $args ) {

$factory = new \CalendR\Calendar();
$template->weekdays = $factory->getWeek( new \DateTime( 'Monday this week' ) );
$month = $factory->getMonth( new \DateTime( $yearNum . '-' . $monthNum . '-01' ) );
$month = $factory->getMonth( new \DateTime( $year_num . '-' . $month_num . '-01' ) );
$template->month = $month;
$records = array();
foreach ( $table->get_columns( 'date' ) as $dateCol ) {
$dateColName = $dateCol->get_name();
foreach ( $table->get_columns( 'date' ) as $date_col ) {
$date_col_name = $date_col->get_name();
// Filter to the just the requested month.
$table->add_filter( $dateColName, '>=', $month->getBegin()->format( 'Y-m-d' ) );
$table->add_filter( $dateColName, '<=', $month->getEnd()->format( 'Y-m-d' ) );
$table->add_filter( $date_col_name, '>=', $month->getBegin()->format( 'Y-m-d' ) );
$table->add_filter( $date_col_name, '<=', $month->getEnd()->format( 'Y-m-d' ) );
foreach ( $table->get_records() as $rec ) {
$dateVal = $rec->$dateColName();
$date_val = $rec->$date_col_name();
// Initialise the day's list of records.
if ( ! isset( $records[ $dateVal ] ) ) {
$records[ $dateVal ] = array();
if ( ! isset( $records[ $date_val ] ) ) {
$records[ $date_val ] = array();
}
// Add this record to the day's list.
$records[ $dateVal ][] = $rec;
$records[ $date_val ][] = $rec;
}
}
// $records is grouped by date, with each item in a single date being
// an array like: ['record'=>Record, 'column'=>$name_of_date_column]
// an array with 'record' and 'column' keys.
$template->records = $records;

return $template->render();
Expand All @@ -217,10 +248,10 @@ public function calendar( $args ) {
* Export the current table with the current filters applied.
* Filters are passed as request parameters, just as for the index action.
*
* @param string[] $args The request parameters.
* @return void
*/
public function export( $args )
{
public function export( $args ) {
// Get table.
$table = $this->get_table( $args['table'] );

Expand All @@ -241,6 +272,7 @@ public function export( $args )

/**
* Download a CSV of given titles that could not be found in this table.
*
* @param string[] $args The request parameters.
*/
public function notfound( $args ) {
Expand All @@ -263,7 +295,7 @@ public function notfound( $args ) {
$recs = $table->get_records( false );
foreach ( $recs as $rec ) {
$key = array_search( $rec->get_title(), $values );
if ( $key !== false ) {
if ( false !== $key ) {
unset( $values[ $key ] );
}
}
Expand All @@ -277,6 +309,12 @@ public function notfound( $args ) {
exit;
}

/**
* Display a horizontal timeline of any table with a date field.
*
* @param string[] $args Request arguments.
* @return string
*/
public function timeline( $args ) {
$table = $this->get_table( $args['table'] );
$template = new \WordPress\Tabulate\Template( 'timeline.html' );
Expand All @@ -286,23 +324,22 @@ public function timeline( $args ) {
$end_date_arg = (isset( $args['end_date'] )) ? $args['end_date'] : date( 'Y-m-d' );
$start_date = new \DateTime( $start_date_arg );
$end_date = new \DateTime( $end_date_arg );
if ($start_date->diff($end_date, true)->d < 7) {
if ( $start_date->diff( $end_date, true )->d < 7 ) {
// Add two weeks to the end date.
$end_date->add(new \DateInterval('P14D'));
$end_date->add( new \DateInterval( 'P14D' ) );
}
$date_period = new \DatePeriod($start_date, new \DateInterval('P1D'), $end_date);
$template->start_date = $start_date->format('Y-m-d');
$template->end_date = $end_date->format('Y-m-d');
$date_period = new \DatePeriod( $start_date, new \DateInterval( 'P1D' ), $end_date );
$template->start_date = $start_date->format( 'Y-m-d' );
$template->end_date = $end_date->format( 'Y-m-d' );
$template->date_period = $date_period;
$data = array();
foreach ($table->get_records(false) as $record) {
if ( ! isset( $data[ $record->get_title() ] )) {
foreach ( $table->get_records( false ) as $record ) {
if ( ! isset( $data[ $record->get_title() ] ) ) {
$data[ $record->get_title() ] = array();
}
$data[ $record->get_title() ][] = $record;
}
$template->data = $data;
return $template->render();
}

}

0 comments on commit ac516c6

Please sign in to comment.