admin_page_url = 'edit.php?post_type=' . Tribe__Events__Main::POSTTYPE;
$this->admin_page_slug = 'events-importer';
}
/**
* Returns the main admin settings URL.
*
* @return string
*/
public function get_url( array $args = [] ) {
$defaults = [
'page' => $this->admin_page_slug,
];
// Allow the link to be "changed" on the fly
$args = wp_parse_args( $args, $defaults );
$url = admin_url( $this->admin_page_url );
return esc_url( apply_filters( 'tribe_importer_url', add_query_arg( $args, $url ), $args, $url ) );
}
public function register_admin_page() {
// only add this if they have Eventbrite, iCal, or Facebook
if ( apply_filters( 'tribe_events_hide_legacy_imports', '__return_true' )
&& ! class_exists( 'Tribe__Events__Tickets__Eventbrite__Main' )
&& ! class_exists( 'Tribe__Events__Facebook__Importer' )
&& ! class_exists( 'Tribe__Events__Ical_Importer__Main' ) ) {
return;
}
add_submenu_page(
$this->admin_page_url,
esc_html__( 'Legacy Import', 'the-events-calendar' ),
esc_html__( 'Legacy Import', 'the-events-calendar' ),
'import',
$this->admin_page_slug,
[ $this, 'render_admin_page_contents' ]
);
}
public function add_settings_fields( $fields = [] ) {
$newfields = [
'csv-title' => [
'type' => 'html',
'html' => '
' . esc_html__( 'CSV Import Settings', 'the-events-calendar' ) . '
',
],
'csv-form-content-start' => [
'type' => 'html',
'html' => '',
],
'imported_post_status[csv]' => [
'type' => 'dropdown',
'label' => __( 'Default status to use for imported events', 'the-events-calendar' ),
'options' => Tribe__Events__Importer__Options::get_possible_stati(),
'validation_type' => 'options',
'parent_option' => Tribe__Events__Main::OPTIONNAME,
],
'imported_encoding_status[csv]' => [
'type' => 'dropdown',
'label' => __( 'Default encoding for imported csv file', 'the-events-calendar' ),
'options' => Tribe__Events__Importer__Options::get_encoding_status(),
'validation_type' => 'options',
'parent_option' => Tribe__Events__Main::OPTIONNAME,
],
'csv-form-content-end' => [
'type' => 'html',
'html' => '
',
],
];
return array_merge( $fields, $newfields );
}
public function render_admin_page_contents() {
$tab = $this->get_active_tab();
switch ( $tab ) {
case 'general' :
$this->render_general_tab();
break;
case 'csv-importer':
$this->render_csv_tab();
break;
default:
include Tribe__Events__Importer__Plugin::path( 'src/io/csv/admin-views/header.php' );
if ( has_action( 'tribe-import-render-tab-' . $tab ) ) {
/**
* Remove this Action on 4.3
* @deprecated
*/
_doing_it_wrong(
'tribe-import-render-tab-' . $tab,
sprintf(
esc_html__( 'This Action has been deprecated, to comply with WordPress Standards we are now using Underscores (_) instead of Dashes (-). From: "%s" To: "%s"', 'the-events-calendar' ),
'tribe-import-render-tab-' . $tab,
'tribe_import_render_tab_' . $tab
),
'4.0'
);
do_action( 'tribe-import-render-tab-' . $tab );
}
do_action( 'tribe_import_render_tab_' . $tab );
include Tribe__Events__Importer__Plugin::path( 'src/io/csv/admin-views/footer.php' );
break;
}
}
public function render_general_tab() {
include Tribe__Events__Importer__Plugin::path( 'src/io/csv/admin-views/general.php' );
}
public function render_csv_tab() {
switch ( $this->state ) {
case 'map':
try {
$file = new Tribe__Events__Importer__File_Reader( Tribe__Events__Importer__File_Uploader::get_file_path() );
} catch ( RuntimeException $e ) {
$this->errors[] = esc_html__( 'The file went away. Please try again.', 'the-events-calendar' );
$this->state = '';
return $this->render_admin_page_contents();
}
$header = $file->get_header();
if ( get_option( 'tribe_events_importer_has_header', 0 ) == 0 ) {
$letter = 'A';
$size = count( $header );
$header = [];
for ( $i = 0; $i < $size; $i++ ) {
$header[] = $letter++;
}
}
$import_type = get_option( 'tribe_events_import_type' );
$import_type_titles_map = [];
/**
* Allows filtering the import type titles to go from a slug to a pretty title.
*
* @param array $import_type_titles_map
*/
$import_type_titles_map = apply_filters( 'tribe_events_import_type_titles_map', $import_type_titles_map );
$import_type_title = isset( $import_type_titles_map[ $import_type ] ) ? $import_type_titles_map[ $import_type ] : ucwords( $import_type );
$messages = $this->errors;
include Tribe__Events__Importer__Plugin::path( 'src/io/csv/admin-views/columns.php' );
break;
case 'importing':
$messages = $this->messages;
include Tribe__Events__Importer__Plugin::path( 'src/io/csv/admin-views/in-progress.php' );
break;
case 'complete':
$log = get_option( 'tribe_events_import_log' );
$skipped = get_option( 'tribe_events_import_failed_rows', [] );
$encoded = get_option( 'tribe_events_import_encoded_rows', [] );
include Tribe__Events__Importer__Plugin::path( 'src/io/csv/admin-views/result.php' );
break;
default:
$messages = $this->errors;
$import_options = [
'venues' => esc_html__( 'Venues', 'the-events-calendar' ),
'organizers' => esc_html__( 'Organizers', 'the-events-calendar' ),
'events' => esc_html__( 'Events', 'the-events-calendar' ),
];
/**
* Filters the CSV import options available to the user.
*
* @param array $import_options An associative array of option values and labels.
*/
$import_options = apply_filters( 'tribe_events_import_options_rows', $import_options );
$default_selected_import_option = 'events';
/**
* Filters the default selected option for the import options.
*
* @param string $default_selected_import_option
*/
$default_selected_import_option = apply_filters( 'tribe_events_import_options_default_selected', $default_selected_import_option );
include Tribe__Events__Importer__Plugin::path( 'src/io/csv/admin-views/import.php' );
break;
}
}
public function get_active_tab() {
$tabs = (array) $this->get_available_tabs();
$default = array_shift( $tabs );
return empty( $_REQUEST[ 'tab' ] ) ? $default : $_REQUEST[ 'tab' ];
}
public function get_available_tabs() {
$tabs = [
esc_html__( 'Import Settings', 'the-events-calendar' ) => 'general',
esc_html__( 'CSV', 'the-events-calendar' ) => 'csv-importer',
];
if ( has_filter( 'tribe-import-tabs' ) ) {
/**
* Remove this Filter on 4.3
* @deprecated
*/
_doing_it_wrong(
'tribe-import-tabs',
sprintf(
esc_html__( 'This Filter has been deprecated, to comply with WordPress Standards we are now using Underscores (_) instead of Dashes (-). From: "%s" To: "%s"', 'the-events-calendar' ),
'tribe-import-tabs',
'tribe_import_tabs'
),
'4.0'
);
$tabs = apply_filters( 'tribe-import-tabs', $tabs );
}
return apply_filters( 'tribe_import_tabs', $tabs );
}
public function handle_submission() {
$action = $this->get_action();
if ( empty( $action ) ) {
return;
}
ob_start();
switch ( $action ) {
case 'map':
$this->handle_file_submission();
break;
case 'import':
if ( $this->handle_column_mapping() ) {
$this->begin_import();
} else {
$this->state = 'map';
}
break;
case 'continue':
// This test guards against a fatal error that can occur if the action=continue
// screen is refreshed after the import completes
if ( Tribe__Events__Importer__File_Uploader::has_valid_csv_file() ) {
$this->continue_import();
}
break;
default:
// Should never get here.
break;
}
$this->output = ob_get_clean();
}
private function get_action() {
$action = '';
if ( isset( $_POST[ 'ecp_import_action' ] ) ) {
$action = trim( $_POST[ 'ecp_import_action' ] );
}
if ( isset( $_GET['action'] ) ) {
$action = trim( $_GET[ 'action' ] );
}
if ( ! empty( $action ) ) {
if ( ! in_array( $action, [ 'import', 'map', 'continue' ] ) ) {
$action = '';
}
}
return $action;
}
private function handle_file_submission() {
$this->state = 'map';
if ( empty( $_POST['import_type'] ) || empty( $_FILES['import_file']['name'] ) ) {
$this->errors[] = esc_html__( 'We were unable to process your request. Please try again.', 'the-events-calendar' );
$this->state = '';
return;
}
$import_type = $_POST[ 'import_type' ];
update_option( 'tribe_events_import_type', $import_type );
try {
$file_handler = new Tribe__Events__Importer__File_Uploader( $_FILES['import_file'] );
$file_handler->save_file();
} catch ( RuntimeException $e ) {
$this->errors[] = $e->getMessage();
$this->state = '';
return;
}
if ( isset( $_POST[ 'import_header' ] ) && $_POST[ 'import_header' ] ) {
update_option( 'tribe_events_importer_has_header', 1 );
} else {
update_option( 'tribe_events_importer_has_header', 0 );
}
}
private function handle_column_mapping() {
// Deconstruct mapping.
if ( empty( $_POST['column_map'] ) ) {
return false;
}
$column_mapping = $_POST['column_map'];
try {
$importer = $this->get_importer();
} catch ( RuntimeException $e ) {
$this->errors[] = esc_html__( 'The file went away. Please try again.', 'the-events-calendar' );
return false;
}
$required_fields = $importer->get_required_fields();
$missing = array_diff( $required_fields, $column_mapping );
if ( ! empty( $missing ) ) {
$mapper = new Tribe__Events__Importer__Column_Mapper( get_option( 'tribe_events_import_type' ) );
$message = '' . esc_html__( 'The following fields are required for a successful import:', 'the-events-calendar' ) . '
';
$message .= '';
foreach ( $missing as $key ) {
$message .= '- ' . $mapper->get_column_label( $key ) . '
';
}
$message .= '
';
$this->errors[] = $message;
return false;
}
update_option( 'tribe_events_import_column_mapping_' . $importer->get_type(), $column_mapping );
return true;
}
private function begin_import() {
$this->reset_tracking_options();
$this->continue_import();
}
private function reset_tracking_options() {
update_option( 'tribe_events_importer_offset', get_option( 'tribe_events_importer_has_header', 0 ) );
update_option( 'tribe_events_import_log', [ 'updated' => 0, 'created' => 0, 'skipped' => 0, 'encoding' => 0 ] );
update_option( 'tribe_events_import_failed_rows', [] );
update_option( 'tribe_events_import_encoded_rows', [] );
}
private function continue_import() {
$importer = $this->get_importer();
$offset = get_option( 'tribe_events_importer_offset' );
if ( $offset == -1 ) {
$this->state = 'complete';
$this->clean_up_after_import();
} else {
$this->state = 'importing';
$importer->set_offset( $offset );
$this->do_import( $importer );
$this->log_import_results( $importer );
}
}
private function do_import( Tribe__Events__Importer__File_Importer $importer ) {
$importer->do_import();
$this->messages = $importer->get_log_messages();
$new_offset = $importer->import_complete() ? -1 : $importer->get_last_completed_row();
update_option( 'tribe_events_importer_offset', $new_offset );
if ( -1 === $new_offset ) do_action( 'tribe_events_csv_import_complete' );
}
private function get_importer() {
$type = get_option( 'tribe_events_import_type' );
$file_reader = new Tribe__Events__Importer__File_Reader( Tribe__Events__Importer__File_Uploader::get_file_path() );
$importer = Tribe__Events__Importer__File_Importer::get_importer( $type, $file_reader );
$importer->set_map( get_option( 'tribe_events_import_column_mapping_' . $type, [] ) );
$importer->set_type( get_option( 'tribe_events_import_type' ) );
$importer->set_limit( absint( apply_filters( 'tribe_events_csv_batch_size', 100 ) ) );
$importer->set_offset( get_option( 'tribe_events_importer_has_header', 0 ) );
return $importer;
}
private function log_import_results( Tribe__Events__Importer__File_Importer $importer ) {
$log = get_option( 'tribe_events_import_log' );
$log['updated'] += $importer->get_updated_post_count();
$log['created'] += $importer->get_new_post_count();
$log['skipped'] += $importer->get_skipped_row_count();
$log['encoding'] += $importer->get_encoding_changes_row_count();
update_option( 'tribe_events_import_log', $log );
$skipped_rows = $importer->get_skipped_row_numbers();
$previously_skipped_rows = get_option( 'tribe_events_import_failed_rows', [] );
$skipped_rows = $previously_skipped_rows + $skipped_rows;
update_option( 'tribe_events_import_failed_rows', $skipped_rows );
$encoded_rows = $importer->get_encoding_changes_row_numbers();
$previously_encoded_rows = get_option( 'tribe_events_import_encoded_rows', [] );
$encoded_rows = $previously_encoded_rows + $encoded_rows;
update_option( 'tribe_events_import_encoded_rows', $encoded_rows );
}
private function clean_up_after_import() {
Tribe__Events__Importer__File_Uploader::clear_old_files();
}
}