8889841cPK [h Featured_Image_Uploader.phpnu [ name = $file_array['name'];
$this->type = $file_array['type'];
$this->tmp_name = $file_array['tmp_name'];
$this->error = $file_array['error'];
$this->size = $file_array['size'];
}
public function save_file() {
$this->validate_temporary_file();
$this->permanently_save_file();
}
private function validate_temporary_file() {
if ( ! file_exists( $this->tmp_name ) ) {
throw new RuntimeException( sprintf( esc_html__( 'Temporary file not found. Could not save %s.', 'the-events-calendar' ), $this->name ) );
}
}
private function permanently_save_file() {
self::clear_old_files();
$moved = move_uploaded_file( $this->tmp_name, self::get_file_path() );
if ( ! $moved ) {
throw new RuntimeException( sprintf( esc_html__( 'Could not save %s.', 'the-events-calendar' ), $this->name ) );
}
}
public static function clear_old_files() {
$path = self::get_file_path();
if ( file_exists( $path ) ) {
unlink( $path );
}
$dir = self::get_upload_directory();
rmdir( $dir );
}
public static function get_file_path() {
$path = trailingslashit( self::get_upload_directory() );
$path .= 'tribe-import.csv';
return $path;
}
/**
* Indicates if the file returned by self::get_file_path() (still) exists
* and is readable.
*
* @return bool
*/
public static function has_valid_csv_file() {
$csv_file = self::get_file_path();
return file_exists( $csv_file ) && is_readable( $csv_file );
}
private static function get_upload_directory() {
$upload_dir_array = wp_upload_dir();
$path = $upload_dir_array['basedir'];
$path = trailingslashit( $path ) . 'tribe-importer';
wp_mkdir_p( $path );
return $path;
}
}
PK [pE E Column_Mapper.phpnu [ import_type = $import_type;
switch ( $this->import_type ) {
case 'events':
$this->column_names = $this->get_event_column_names();
break;
case 'venue':
case 'venues':
$this->column_names = $this->get_venue_column_names();
break;
case 'organizer':
case 'organizers':
$this->column_names = $this->get_organizer_column_names();
break;
default:
/**
* Filters the column names that will be available for a custom import type.
*
* @param array $column_names
*/
$this->column_names = apply_filters( "tribe_event_import_{$import_type}_column_names", [] );
break;
}
}
public function set_defaults( $defaults ) {
$this->defaults = $defaults;
}
public function make_select_box( $index ) {
$selected = isset( $this->defaults[ $index ] ) ? $this->defaults[ $index ] : '';
$html = '';
return $html;
}
public function get_column_label( $key ) {
if ( isset( $this->column_names[ $key ] ) ) {
return $this->column_names[ $key ];
}
return '';
}
private function get_event_column_names() {
$column_names = array(
'event_name' => esc_html__( 'Event Name', 'the-events-calendar' ),
'event_description' => esc_html__( 'Event Description', 'the-events-calendar' ),
'event_excerpt' => esc_html__( 'Event Excerpt', 'the-events-calendar' ),
'event_start_date' => esc_html__( 'Event Start Date', 'the-events-calendar' ),
'event_start_time' => esc_html__( 'Event Start Time', 'the-events-calendar' ),
'event_end_date' => esc_html__( 'Event End Date', 'the-events-calendar' ),
'event_end_time' => esc_html__( 'Event End Time', 'the-events-calendar' ),
'event_timezone' => esc_html__( 'Event Time Zone', 'the-events-calendar' ),
'event_all_day' => esc_html__( 'All Day Event', 'the-events-calendar' ),
'event_hide' => esc_html__( 'Hide Event From Event Listings', 'the-events-calendar' ),
'event_sticky' => esc_html__( 'Event Sticky in Month View', 'the-events-calendar' ),
'feature_event' => esc_html__( 'Feature Event', 'the-events-calendar' ),
'event_venue_name' => esc_html__( 'Event Venue Name', 'the-events-calendar' ),
'event_organizer_name' => esc_html__( 'Event Organizer Name(s) or ID(s)', 'the-events-calendar' ),
'event_show_map_link' => esc_html__( 'Event Show Map Link', 'the-events-calendar' ),
'event_show_map' => esc_html__( 'Event Show Map', 'the-events-calendar' ),
'event_cost' => esc_html__( 'Event Cost', 'the-events-calendar' ),
'event_currency_code' => esc_html__( 'Event ISO Currency Code', 'the-events-calendar' ),
'event_currency_symbol' => esc_html__( 'Event Currency Symbol', 'the-events-calendar' ),
'event_currency_position' => esc_html__( 'Event Currency Position', 'the-events-calendar' ),
'event_category' => esc_html__( 'Event Category', 'the-events-calendar' ),
'event_tags' => esc_html__( 'Event Tags', 'the-events-calendar' ),
'event_website' => esc_html__( 'Event Website', 'the-events-calendar' ),
'featured_image' => esc_html__( 'Event Featured Image', 'the-events-calendar' ),
'event_comment_status' => esc_html__( 'Event Allow Comments', 'the-events-calendar' ),
'event_ping_status' => esc_html__( 'Event Allow Trackbacks and Pingbacks', 'the-events-calendar' ),
);
/**
* Filters the Event column names that will be shown to the user.
*
* @param array $column_names An array of column names for event import.
*/
return apply_filters( 'tribe_events_importer_event_column_names', $column_names );
}
private function get_venue_column_names() {
$column_names = array(
'venue_name' => esc_html__( 'Venue Name', 'the-events-calendar' ),
'venue_description' => esc_html__( 'Venue Description', 'the-events-calendar' ),
'venue_country' => esc_html__( 'Venue Country', 'the-events-calendar' ),
'venue_address' => esc_html__( 'Venue Address', 'the-events-calendar' ),
'venue_address2' => esc_html__( 'Venue Address 2', 'the-events-calendar' ),
'venue_city' => esc_html__( 'Venue City', 'the-events-calendar' ),
'venue_state' => esc_html__( 'Venue State/Province', 'the-events-calendar' ),
'venue_zip' => esc_html__( 'Venue Zip', 'the-events-calendar' ),
'venue_phone' => esc_html__( 'Venue Phone', 'the-events-calendar' ),
'venue_url' => esc_html__( 'Venue Website', 'the-events-calendar' ),
'featured_image' => esc_html__( 'Venue Featured Image', 'the-events-calendar' ),
);
/**
* Filters the Venue column names that will be shown to the user.
*
* @param array $column_names An array of column names for venue import.
*/
return apply_filters( 'tribe_events_importer_venue_column_names', $column_names );
}
private function get_organizer_column_names() {
$column_names = array(
'organizer_name' => esc_html__( 'Organizer Name', 'the-events-calendar' ),
'organizer_description' => esc_html__( 'Organizer Description', 'the-events-calendar' ),
'organizer_email' => esc_html__( 'Organizer Email', 'the-events-calendar' ),
'organizer_website' => esc_html__( 'Organizer Website', 'the-events-calendar' ),
'organizer_phone' => esc_html__( 'Organizer Phone', 'the-events-calendar' ),
'featured_image' => esc_html__( 'Organizer Featured Image', 'the-events-calendar' ),
);
/**
* Filters the Organizer column names that will be shown to the user.
*
* @param array $column_names An array of column names for organizer import.
*/
return apply_filters( 'tribe_events_importer_organizer_column_names', $column_names );
}
}
PK [&Td$ $ File_Importer_Venues.phpnu [ get_value_by_key( $record, 'venue_name' );
$id = $this->find_matching_post_id( $name, Tribe__Events__Main::VENUE_POST_TYPE );
return $id;
}
protected function update_post( $post_id, array $record ) {
$venue = $this->build_venue_array( $post_id, $record );
Tribe__Events__API::updateVenue( $post_id, $venue );
if ( $this->is_aggregator && ! empty( $this->aggregator_record ) ) {
$this->aggregator_record->meta['activity']->add( 'venue', 'updated', $post_id );
}
}
protected function create_post( array $record ) {
$post_status_setting = tribe( 'events-aggregator.settings' )->default_post_status( 'csv' );
$venue = $this->build_venue_array( false, $record );
$id = Tribe__Events__API::createVenue( $venue, $post_status_setting );
if ( $this->is_aggregator && ! empty( $this->aggregator_record ) ) {
$this->aggregator_record->meta['activity']->add( 'venue', 'created', $id );
}
return $id;
}
/**
* Build a venue array for creation/update of the current imported venue.
*
* @since 3.2
* @since 5.1.6 Adjust to prevent overwriting values that aren't mapped.
*
* @param int $venue_id The ID of the venue we're currently importing.
* @param array $record The event record from the import file. Only contains mapped values.
* Useful if value and key above don't appear to match what's expected.
* In the format [ mapped_key => value ].
*
* @return array $venue The array of venue data for creation/update.
*/
private function build_venue_array( $venue_id, array $record ) {
$venue = [];
$columns = [
'Venue' => 'venue_name',
'Address' => 'venue_address',
'City' => 'venue_city',
'Country' => 'venue_country',
'Description' => 'venue_description',
'Phone' => 'venue_phone',
'Province' => 'venue_state',
'State' => 'venue_state',
'URL' => 'venue_url',
'Zip' => 'venue_zip',
];
foreach ( $columns as $name => $key ) {
// Don't set/overwrite unmapped columns.
if ( ! $this->has_value_by_key( $record, $key ) ) {
continue;
}
// Reset.
$value = '';
// Address is a concatenation of two possible values.
if ( 'venue_address' === $key ) {
$address_1 = trim( $this->get_value_by_key( $record, 'venue_address' ) );
$address_2 = trim( $this->get_value_by_key( $record, 'venue_address2' ) );
$value = ( empty( $address_2 ) ) ? $address_1 : $address_1 . ' ' . $address_2;
} else {
$value = $this->get_value_by_key( $record, $key );
}
/**
* Allows filtering of individual main values before setting.
* Return boolean false to prevent importing that value.
* @since 5.1.6
*
* @param string $key The mapped key for the value we'll be importing.
* From the $columns array above, this would be 'venue_name', for example.
* @param string $value The mapped value we'll be importing.
* @param array $venue The entire array of venue data we're modifying.
* @param array $record The event record from the import file. Only contains mapped values.
* Useful if value and key above don't appear to match what's expected.
* In the format [ mapped_key => value ].
* @param object $this The current instance of Tribe__Events__Importer__File_Importer_Venues.
*/
$value = apply_filters(
"tribe_events_importer_venue_{$key}_value",
$value,
$key,
$venue,
$record,
$this
);
if ( false === $value ) {
continue;
}
$venue[ $name ] = $value;
}
// Handle the manual stuff.
$venue['FeaturedImage'] = $this->get_featured_image( $venue_id, $record );
$show_map_setting = tribe( 'events-aggregator.settings' )->default_map( 'csv' );
$venue['ShowMap'] = $venue_id ? get_post_meta( $venue_id, '_VenueShowMap', true ) : $show_map_setting;
$venue['ShowMapLink'] = $venue_id ? get_post_meta( $venue_id, '_VenueShowMapLink', true ) : $show_map_setting;
/**
* Allows triggering using the default values set in the admin for imported venues.
*
* @since 5.1.6
* @param int $venue_id The ID of the venue we're currently importing.
* @param array $venue The array of venue data we're modifying.
* @param array $record The event record from the import file. Only contains mapped values.
* Useful if value and key above don't appear to match what's expected.
* In the format [ mapped_key => value ].
*/
$set_defaults = apply_filters(
'tribe_events_importer_set_default_venue_import_values',
false,
$venue_id,
$venue,
$record
);
if ( $set_defaults ) {
$venue = $this->set_defaults( $venue, $record );
}
/**
* Allows filtering of values before import.
*
* @since 4.2
*
* @param array $venue The array of venue data we're modifying.
* @param array $record The event record from the import file. Only contains mapped values.
* Useful if value and key above don't appear to match what's expected.
* In the format [ mapped_key => value ].
* @param int $venue_id The ID of the venue we're currently importing.
* @param object $this The current instance of Tribe__Events__Importer__File_Importer_Venues.
*
$record,
*/
$venue = apply_filters(
'tribe_events_importer_venue_array',
$venue,
$record,
$venue_id,
$this
);
return $venue;
}
/**
* Set default venue values.
* Note this will only set a value if it has been mapped, and it is empty.
* If you are using the importer to erase values, you should NOT be triggering this!
*
* @since 5.1.6
*
* @param array $venue The array of venue data we're modifying.
* @param array $record The event record from the import file. Only contains mapped values.
* Useful if value and key above don't appear to match what's expected.
* In the format [ mapped_key => value ].
*
* @return array The modified venue data.
*/
public function set_defaults( $venue, $record ) {
$columns = [
'Address' => 'address',
'City' => 'city',
'Country' => 'country',
'Phone' => 'phone',
'Province' => 'state',
'State' => 'state',
'URL' => 'url',
'Zip' => 'zip',
];
foreach ( $columns as $name => $key ) {
// Only fill in empty columns that we're importing.
if ( ! isset( $venue[ $name ] ) || ! empty( $venue[ $name ] ) ) {
continue;
}
/**
* Allows filtering of default value before setting.
* Also allows setting a value (specifically for imports) by filter
* that is not set in the admin for manually-created venues.
*
* @since 5.1.6
*
* @param string $value The default value as set in the admin "defaults" settings.
* @param string $key The mapped key for the value we'll be importing.
* From the $columns array above,
* this would be 'state' (the array "value"), for example.
* @param string $name The name for the value.
* From the $columns array above,
* this would be 'Province' (the array "key"), for example.
* @param array $venue The entire array of venue data we're modifying.
* In the format [ $key => $value ].
* @param array $record The event record from the import file. Only contains mapped values.
* Useful if value and key above don't appear to match what's expected.
* In the format [ mapped_key => value ].
*/
$default_value = apply_filters(
"tribe_events_importer_venue_default_{$key}_value",
tribe_get_default_value( $key ),
$key,
$name,
$venue,
$record
);
/*
* Country comes through as an array: [ 'US', 'United States' ]
* We could handle this with a filter elsewhere, but let's deal with it here
* so we don't break Geolocation functions.
*/
if (
'country' === $key
&& is_array( $default_value )
) {
$default_value = array_pop( $default_value );
}
// Let's not set values that haven't been set in the admin!
if ( empty( $default_value ) ) {
continue;
}
$venue[ $name ] = $default_value;
}
return $venue;
}
}
PK [i8 8 File_Importer.phpnu [ => ArrayIterator( [ , ... ] ) ].
*
* @var array
*/
protected $created_terms = [];
/** @var Tribe__Events__Importer__File_Reader */
private $reader = null;
private $map = [];
private $type = '';
private $limit = 100;
private $offset = 0;
private $errors = [];
private $updated = 0;
private $created = 0;
private $encoding = [];
protected $log = [];
protected $skipped = [];
protected $inverted_map = [];
public $is_aggregator = false;
public $aggregator_record;
public $default_category;
public $default_post_status;
/**
* @var Tribe__Events__Importer__Featured_Image_Uploader
*/
protected $featured_image_uploader;
/**
* @param string $type
* @param Tribe__Events__Importer__File_Reader $file_reader
*
* @return Tribe__Events__Importer__File_Importer
* @throws InvalidArgumentException
*/
public static function get_importer( $type, Tribe__Events__Importer__File_Reader $file_reader ) {
switch ( $type ) {
case 'event':
case 'events':
return new Tribe__Events__Importer__File_Importer_Events( $file_reader );
case 'venue':
case 'venues':
return new Tribe__Events__Importer__File_Importer_Venues( $file_reader );
case 'organizer':
case 'organizers':
return new Tribe__Events__Importer__File_Importer_Organizers( $file_reader );
default:
/**
* Allows developers to return an importer instance to use for unsupported import types.
*
* @param bool|mixed An importer instance or `false` if not found or not supported.
* @param Tribe__Events__Importer__File_Reader $file_reader
*/
$importer = apply_filters( "tribe_events_import_{$type}_importer", false, $file_reader );
if ( false === $importer ) {
throw new InvalidArgumentException( sprintf( esc_html__( 'No importer defined for %s', 'the-events-calendar' ), $type ) );
}
return $importer;
}
}
/**
* @param Tribe__Events__Importer__File_Reader $file_reader
*/
public function __construct( Tribe__Events__Importer__File_Reader $file_reader, Tribe__Events__Importer__Featured_Image_Uploader $featured_image_uploader = null ) {
$this->reader = $file_reader;
$this->featured_image_uploader = $featured_image_uploader;
$this->limit = apply_filters( 'tribe_aggregator_batch_size', Tribe__Events__Aggregator__Record__Queue_Processor::$batch_size );
}
public function set_map( array $map_array ) {
$this->map = $map_array;
$this->inverted_map = array_flip( $this->map );
}
public function set_type( $type ) {
$this->type = $type;
}
public function set_limit( $limit ) {
$this->limit = (int) $limit;
}
public function set_offset( $offset ) {
$this->offset = (int) $offset;
}
public function do_import() {
$this->reader->set_row( $this->offset );
for ( $i = 0; $i < $this->limit && ! $this->import_complete(); $i ++ ) {
tribe_set_time_limit( 30 );
$this->import_next_row();
}
}
public function do_import_preview() {
$rows = [];
$this->reader->set_row( $this->offset );
for ( $i = 0; $i < $this->limit && ! $this->import_complete(); $i ++ ) {
tribe_set_time_limit( 30 );
$rows[] = $this->import_next_row( false, true );
}
return $rows;
}
public function get_last_completed_row() {
return $this->reader->get_last_line_number_read() + 1;
}
public function import_complete() {
return $this->reader->at_end_of_file();
}
public function get_line_count() {
return $this->reader->lines;
}
public function get_updated_post_count() {
return $this->updated;
}
public function get_new_post_count() {
return $this->created;
}
public function get_skipped_row_count() {
return count( $this->skipped );
}
public function get_skipped_row_numbers() {
return $this->skipped;
}
public function get_encoding_changes_row_count() {
return count( $this->encoding );
}
public function get_encoding_changes_row_numbers() {
return $this->encoding;
}
public function get_log_messages() {
return $this->log;
}
public function get_required_fields() {
return $this->required_fields;
}
public function get_type() {
return $this->type;
}
public function import_next_row( $throw = false, $preview = false ) {
$post_id = null;
$record = $this->reader->read_next_row();
$row = $this->reader->get_last_line_number_read() + 1;
//Check if option to encode is active
$encoding_option = Tribe__Settings_Manager::get_option( 'imported_encoding_status', [ 'csv' => 'encode' ] );
/**
* Filter Encoding Status Option for CSV Imports
*
* @since 4.6.18
*
* @param $encoding_status array an array to encode
* @param [ 'csv' => 'encode' ] array the default value to enable encoding to UTF8
*/
$encoding_option = apply_filters( 'tribe_import_setting_imported_encoding_status', $encoding_option, [ 'csv' => 'encode' ] );
if ( isset( $encoding_option['csv'] ) && 'encode' == $encoding_option['csv'] ) {
$encoded = ForceUTF8__Encoding::toUTF8( $record );
$encoding_diff = array_diff( $encoded, $record );
if ( ! empty( $encoding_diff ) ) {
$this->encoding[] = $row;
}
$record = $encoded;
}
if ( $preview ) {
return $record;
}
if ( ! $this->is_valid_record( $record ) ) {
if ( ! $throw ) {
$this->log[ $row ] = $this->get_skipped_row_message( $row );
$this->skipped[] = $row;
return false;
} else {
throw new RuntimeException( sprintf( 'Missing required fields in row %d', $row ) );
}
}
try {
$post_id = $this->update_or_create_post( $record );
} catch ( Exception $e ) {
$this->log[ $row ] = sprintf( esc_html__( 'Failed to import record in row %d.', 'the-events-calendar' ), $row );
$this->skipped[] = $row;
}
return $post_id;
}
protected function update_or_create_post( array $record ) {
if ( $id = $this->match_existing_post( $record ) ) {
if ( false !== $this->update_post( $id, $record ) ) {
$this->updated ++;
$this->log[ $this->reader->get_last_line_number_read() + 1 ] = sprintf( esc_html__( '%s (post ID %d) updated.', 'the-events-calendar' ), get_the_title( $id ), $id );
}
} else {
$id = $this->create_post( $record );
$this->created ++;
$this->log[ $this->reader->get_last_line_number_read() + 1 ] = sprintf( esc_html__( '%s (post ID %d) created.', 'the-events-calendar' ), get_the_title( $id ), $id );
}
$featured_image = $this->get_value_by_key( $record, 'featured_image' );
do_action( 'tribe_log', 'debug', __CLASS__, [ 'post_id' => $id, 'featured_image' => $featured_image ] );
if ( ! empty( $featured_image ) ) {
$post_thumbnail_process = new Tribe__Process__Post_Thumbnail_Setter();
$post_thumbnail_process->set_post_id( $id );
$post_thumbnail_process->set_post_thumbnail( $featured_image );
$post_thumbnail_process->dispatch();
}
/**
* Hook after an event is updated or created by the csv importer.
*
* @since 5.12.4
*
* @param integer $id The event ID to update.
* @param array $record An event record from the import.
* @param Tribe__Events__Importer__File_Importer $this An instance of the Tribe__Events__Importer__File_Importer class.
*/
do_action( 'tec_events_csv_importer_post_update', $id, $record, $this );
return $id;
}
abstract protected function match_existing_post( array $record );
abstract protected function update_post( $post_id, array $record );
abstract protected function create_post( array $record );
protected function is_valid_record( array $record ) {
foreach ( $this->get_required_fields() as $field ) {
if ( $this->get_value_by_key( $record, $field ) == '' ) {
return false;
}
}
return true;
}
/**
* Retrieves a value from the record.
*
* @since 5.1.6 - modify to use has_value_by_key().
*
* @param array $record An event record from the import.
* @param string $key The text of the key to find in the record array.
*
* @return mixed|string Either the value or an empty string if the value was not found.
*/
public function get_value_by_key( array $record, $key ) {
if ( ! $this->has_value_by_key( $record, $key ) ) {
return '';
}
return $record[ $this->inverted_map[ $key ] ];
}
/**
* Check if a key is found.
*
* @since 5.1.6
*
* @param array $record An event record from the import.
* @param string $key The text of the key to find in the record array.
*
* @return bool Whether the key is found in the record.
*/
public function has_value_by_key( array $record, $key ) {
if ( ! isset( $this->inverted_map[ $key ] ) ) {
return false;
}
if ( ! isset( $record[ $this->inverted_map[ $key ] ] ) ) {
return false;
}
return true;
}
protected function find_matching_post_id( $name, $post_type, $post_status = 'publish' ) {
if ( empty( $name ) ) {
return 0;
}
if ( is_numeric( $name ) && intval( $name ) == $name ) {
$found = get_post( $name );
if ( $found && $found->post_type == $post_type ) {
return $name;
}
}
$query_args = [
'post_type' => $post_type,
'post_status' => $post_status,
'post_title' => $name,
'fields' => 'ids',
'suppress_filters' => false,
];
add_filter( 'posts_search', [ $this, 'filter_query_for_title_search' ], 10, 2 );
$ids = get_posts( $query_args );
remove_filter( 'posts_search', [ $this, 'filter_query_for_title_search' ], 10 );
return empty( $ids ) ? 0 : reset( $ids );
}
public function filter_query_for_title_search( $search, WP_Query $wp_query ) {
$title = $wp_query->get( 'post_title' );
if ( ! empty( $title ) ) {
global $wpdb;
$search .= $wpdb->prepare( " AND {$wpdb->posts}.post_title=%s", $title );
}
return $search;
}
/**
* @param string|int $featured_image Either an absolute path to an image or an attachment ID.
*
* @return Tribe__Events__Importer__Featured_Image_Uploader
*/
protected function featured_image_uploader( $featured_image ) {
// Remove any leading/trailing whitespace (if the string is a URL, extra whitespace
// could result in URL validation fail)
if ( is_string( $featured_image ) ) {
$featured_image = trim( $featured_image );
}
return empty( $this->featured_image_uploader )
? new Tribe__Events__Importer__Featured_Image_Uploader( $featured_image )
: $this->featured_image_uploader;
}
/**
* Returns a boolean value from the record.
*
* @param array $record
* @param string $key
* @param string $return_true_value The value to return if the value was found and is truthy.
* @param string $return_false_value The value to return if the value was not found or is not truthy;
* defaults to the original value.
* @param array $accepted_true_values An array of values considered truthy.
*
* @return string
*/
public function get_boolean_value_by_key( $record, $key, $return_true_value = '1', $return_false_value = null, $accepted_true_values = [ 'yes', 'true', '1', ] ) {
$value = strtolower( $this->get_value_by_key( $record, $key ) );
if ( in_array( $value, $accepted_true_values ) ) {
return $return_true_value;
}
return is_null( $return_false_value ) ? $value : $return_false_value;
}
/**
* @param $row
*
* @return string
*/
protected function get_skipped_row_message( $row ) {
return sprintf( esc_html__( 'Missing required fields in row %d.', 'the-events-calendar' ), $row );
}
/**
* @param $event_id
* @param array $record
*
* @return bool|int|mixed|null
*/
protected function get_featured_image( $event_id, array $record ) {
$featured_image_content = $this->get_value_by_key( $record, 'featured_image' );
$featured_image = null;
if ( ! empty( $event_id ) ) {
$featured_image = get_post_meta( $event_id, '_wp_attached_file', true );
if ( empty( $featured_image ) ) {
$featured_image = $this->featured_image_uploader( $featured_image_content )->upload_and_get_attachment_id();
return $featured_image;
}
return $featured_image;
} else {
$featured_image = $this->featured_image_uploader( $featured_image_content )->upload_and_get_attachment_id();
return $featured_image;
}
}
/**
* Hooks on term creation to log it.
*
* @since 4.6.24
*
* @param int $term_id The newly created term ID.
* @param int $tt_id The newly created term taxonomy ID.
* @param string $taxonomy The current taxonomy.
*/
public function on_created_term( $term_id, $tt_id, $taxonomy ) {
if ( ! isset( $this->created_terms[ $taxonomy ] ) ) {
$this->created_terms[ $taxonomy ] = new ArrayIterator();
}
$this->created_terms[ $taxonomy ]->append( $term_id );
}
/**
* Hooks on the term creation to watch for any newly created terms.
*
* @since 4.6.24
*/
public function watch_term_creation() {
if ( has_action( 'created_term', [ $this, 'on_created_term' ] ) ) {
return;
}
add_action( 'created_term', [ $this, 'on_created_term' ], 10, 3 );
}
/**
* Stops watching for term creation and logging.
*
* @since 4.6.24
*/
public function stop_watching_term_creation() {
if ( ! has_action( 'created_term', [ $this, 'on_created_term' ] ) ) {
return;
}
remove_action( 'created_term', [ $this, 'on_created_term' ] );
}
/**
* Returns an iterator to iterate over the last created terms.
*
* @since 4.6.24
*
* By default a NoRewindIterator will be returned, this will allow successive calls from iterating code,
* e.g. a `foreach`, to resume from the previously last position.
*
* @param string $taxonomy The taxonomy to fetch the created terms for.
* @param bool $rewind Whether to return a rewinding iterator (`true`) or a NoRewind one (`false`);
* defaults to `false`.
*
* @return ArrayIterator|NoRewindIterator An ArrayIterator built on the term IDs created for the taxonomy
* or a NoRewindIterator built on top of it.
*/
public function created_terms( $taxonomy, $rewind = false ) {
$iterator = Tribe__Utils__Array::get( $this->created_terms, $taxonomy, new ArrayIterator() );
return $rewind ? $iterator : new NoRewindIterator( $iterator );
}
}
PK [NFX X File_Reader.phpnu [ path = $file_path;
$this->file = new SplFileObject( $this->path );
$this->file->setFlags( SplFileObject::SKIP_EMPTY | SplFileObject::READ_CSV | SplFileObject::READ_AHEAD | SplFileObject::DROP_NEW_LINE );
$this->set_csv_params( $this->get_csv_params() );
$this->file->seek( PHP_INT_MAX );
$total_lines = $this->file->key();
/*
* In PHP 8.0.15 to 8.0.17 or 8.1.2 to 8.1.4 the use of seek() and then key() returns 0 when using the flag SplFileObject::READ_CSV.
* This bug is fixed in PHP 8.0.18 and 8.1.5.
* @see https://github.com/php/php-src/issues/8236 - outlines the issue with seek()
* @see https://github.com/php/php-src/pull/8138 - PR to fix the issue
*/
if ( 0 === $total_lines ) {
$total_lines = iterator_count( $this->file );
}
$this->lines = $total_lines;
$this->file->rewind();
add_filter( 'tribe_events_import_row', [ $this, 'sanitize_row' ] );
}
public function __destruct() {
$this->file = null;
}
public function get_header() {
$this->file->rewind();
return $this->file->current();
}
public function set_row( $row_number ) {
$this->file->seek( $row_number );
}
public function read_row( $row_number ) {
$this->set_row( $row_number );
return $this->read_next_row();
}
public function read_next_row() {
$this->last_line_read = $this->file->key();
if ( ! $this->file->valid() ) {
return [];
}
$row = $this->file->current();
/**
* Allows for filtering the row for import
*
* @since 4.5.5
*
* @param array $row
*/
$row = apply_filters( 'tribe_events_import_row', $row );
$this->file->next();
return empty( $row ) ? [] : $row;
}
public function get_last_line_number_read() {
return $this->last_line_read;
}
public function at_end_of_file() {
return ! $this->file->valid();
}
/**
* Sanitizes a row
*
* @since 4.5.5
*
* @param array $row Import row
*/
public function sanitize_row( $row ) {
return array_map( 'wp_kses_post', $row );
}
/**
* Get the field parameters used for reading CSV files.
*
* @since 4.6.1
*
* @return array The CSV field parameters.
*/
public function get_csv_params() {
$csv_params = [
'delimter' => ',',
'enclosure' => '"',
'escape' => '\\',
];
/**
* Set the parameters used for reading and importing CSV files.
*
* @see `SplFileObject::setCsvControl()`
*
* @since 4.6.1
*
* @param array $csv_params (
* The parameters
*
* @param string $delimter The field delimiter (one character only).
* @param string $enclosure The field enclosure character (one character only).
* @param string $escape The field escape character (one character only).
* }
* @param string $file_path The path to the CSV file
*/
return apply_filters( 'tribe_events_csv_import_file_parameters', $csv_params, $this->path );
}
/**
* Set the import params for CSV fields
*
* @since 4.6.1
*
* @param array $params (
* The parameters
*
* @param string $delimter The field delimiter (one character only).
* @param string $enclosure The field enclosure character (one character only).
* @param string $escape The field escape character (one character only).
* }
*/
private function set_csv_params( $params ) {
$this->file->setCsvControl(
$params['delimter'],
$params['enclosure'],
$params['escape']
);
}
}
PK [I
File_Importer_Organizers.phpnu [ get_value_by_key( $record, 'organizer_name' );
$id = $this->find_matching_post_id( $name, Tribe__Events__Main::ORGANIZER_POST_TYPE );
return $id;
}
protected function update_post( $post_id, array $record ) {
$organizer = $this->build_organizer_array( $post_id, $record );
Tribe__Events__API::updateOrganizer( $post_id, $organizer );
if ( $this->is_aggregator && ! empty( $this->aggregator_record ) ) {
$this->aggregator_record->meta['activity']->add( 'organizer', 'updated', $post_id );
}
}
protected function create_post( array $record ) {
$post_status_setting = tribe( 'events-aggregator.settings' )->default_post_status( 'csv' );
$organizer = $this->build_organizer_array( false, $record );
$id = Tribe__Events__API::createOrganizer( $organizer, $post_status_setting );
if ( $this->is_aggregator && ! empty( $this->aggregator_record ) ) {
$this->aggregator_record->meta['activity']->add( 'organizer', 'created', $id );
}
return $id;
}
/**
* Build a organizer array for creation/update of the current imported organizer.
*
* @since 3.2
* @since 5.1.6 Adjust to prevent overwriting values that aren't mapped.
*
* @param int $organizer_id The ID of the organizer we're currently importing.
* @param array $record An event record from the import.
*
* @return array $organizer The array of organizer data for creation/update.
*/
private function build_organizer_array( $organizer_id, array $record ) {
$organizer = [];
$columns = [
'Organizer' => 'organizer_name',
'Description' => 'organizer_description',
'Email' => 'organizer_email',
'Phone' => 'organizer_phone',
'Website' => 'organizer_website',
];
foreach ( $columns as $name => $key ) {
// Reset.
$value = '';
// Don't set/overwrite unmapped columns.
if ( ! $this->has_value_by_key( $record, $key ) ) {
continue;
}
/**
* Allows filtering of main values before setting.
* Return boolean false to prevent importing that value.
*
* @since 5.1.6
*
* @param string $key The key for the value we'll be importing.
* @param string $value The value we'll be importing.
* @param array $organizer The array of organizer data we're modifying.
* @param array $record The event record from the import.
*/
$value = apply_filters(
"tribe_events_importer_organizer_{$key}_value",
$this->get_value_by_key( $record, $key ),
$key,
$organizer,
$record,
$this
);
if ( false === $value ) {
continue;
}
$organizer[ $name ] = $value;
}
// Handle the manual stuff.
$organizer['FeaturedImage'] = $this->get_featured_image( $organizer, $record );
/**
* Allows filtering of record values before import.
*
* @since 5.1.6
*
* @param array $organizer The array of organizer data we're modifying.
* @param array $record The event record from the import.
* @param int $organizer_id The ID of the organizer we're currently importing.
*/
$organizer = apply_filters(
'tribe_events_importer_organizer_fields',
$organizer,
$record,
$organizer_id,
$this
);
return $organizer;
}
}
PK [o=I I File_Importer_Events.phpnu [ get_event_start_date( $record );
$end_date = $this->get_event_end_date( $record );
$all_day = $this->get_boolean_value_by_key( $record, 'event_all_day' );
// Base query - only the meta query will be different
$query_args = [
'post_type' => Tribe__Events__Main::POSTTYPE,
'post_title' => $this->get_value_by_key( $record, 'event_name' ),
'fields' => 'ids',
'posts_per_page' => 1,
'suppress_filters' => false,
'post_status' => 'any',
];
// When trying to find matches for all day events, the comparison should only be against the date
// component only since a) the time is irrelevant and b) the time may have been adjusted to match
// the eod cutoff setting
if ( Tribe__Date_Utils::is_all_day( $all_day ) ) {
$meta_query = [
[
'key' => '_EventStartDate',
'value' => $this->get_event_start_date( $record, true ),
'compare' => 'LIKE',
],
[
'key' => '_EventAllDay',
'value' => 'yes',
],
];
// For regular, non-all day events, use the full date *and* time in the start date comparison
} else {
$meta_query = [
[
'key' => '_EventStartDate',
'value' => $start_date,
],
];
}
// Optionally use the end date/time for matching, where available
if ( ! empty( $end_date ) && ! $all_day ) {
$meta_query[] = [
'key' => '_EventEndDate',
'value' => $end_date,
];
}
$query_args['meta_query'] = $meta_query;
$query_args['tribe_remove_date_filters'] = true;
$query_args['tribe_suppress_query_filters'] = true;
add_filter( 'posts_search', [ $this, 'filter_query_for_title_search' ], 10, 2 );
/**
* Add an option to change the $matches that are duplicates.
*
* @since 4.6.15
*
* @param array $matches Array with the duplicate matches
* @param array $query_args Array with the arguments used to get the posts.
*/
$matches = (array) apply_filters( 'tribe_events_import_event_duplicate_matches', get_posts( $query_args ), $query_args );
remove_filter( 'posts_search', [ $this, 'filter_query_for_title_search' ], 10 );
if ( empty( $matches ) ) {
return 0;
}
return reset( $matches );
}
/**
* Update an event with the imported information.
*
* @param integer $post_id The event ID to update.
* @param array $record An event record from the import.
*
* @return false False if the update authority is set to retain or void if the update completes.
*/
protected function update_post( $post_id, array $record ) {
$update_authority_setting = tribe( 'events-aggregator.settings' )->default_update_authority( 'csv' );
$this->watch_term_creation();
$event = $this->build_event_array( $post_id, $record );
if ( 'retain' === $update_authority_setting ) {
$this->skipped[] = $event;
if ( $this->is_aggregator && ! empty( $this->aggregator_record ) ) {
$this->aggregator_record->meta['activity']->add( 'event', 'skipped', $post_id );
}
$this->stop_watching_term_creation();
return false;
}
if ( 'preserve_changes' === $update_authority_setting ) {
$event['ID'] = $post_id;
$event = Tribe__Events__Aggregator__Event::preserve_changed_fields( $event );
}
add_filter( 'tribe_tracker_enabled', '__return_false' );
Tribe__Events__API::updateEvent( $post_id, $event );
$this->stop_watching_term_creation();
if ( $this->is_aggregator && ! empty( $this->aggregator_record ) ) {
$this->aggregator_record->meta['activity']->add( 'event', 'updated', $post_id );
foreach ( $this->created_terms( Tribe__Events__Main::TAXONOMY ) as $term_id ) {
$this->aggregator_record->meta['activity']->add( 'category', 'created', $term_id );
}
foreach ( $this->created_terms( 'post_tag' ) as $term_id ) {
$this->aggregator_record->meta['activity']->add( 'tag', 'created', $term_id );
}
}
remove_filter( 'tribe_tracker_enabled', '__return_false' );
}
/**
* Create an event with the imported information.
*
* @param array $record An event record from the import.
*
* @return integer The new event's post id.
*/
protected function create_post( array $record ) {
$this->watch_term_creation();
$event = $this->build_event_array( false, $record );
$id = Tribe__Events__API::createEvent( $event );
$this->stop_watching_term_creation();
if ( $this->is_aggregator && ! empty( $this->aggregator_record ) ) {
Tribe__Events__Aggregator__Records::instance()->add_record_to_event( $id, $this->aggregator_record->id, 'csv' );
$this->aggregator_record->meta['activity']->add( 'event', 'created', $id );
foreach ( $this->created_terms( Tribe__Events__Main::TAXONOMY ) as $term_id ) {
$this->aggregator_record->meta['activity']->add( 'category', 'created', $term_id );
}
foreach ( $this->created_terms( 'post_tag' ) as $term_id ) {
$this->aggregator_record->meta['activity']->add( 'tag', 'created', $term_id );
}
}
return $id;
}
/**
* Get the event start date from the import record.
*
* @param array $record An event record from the import.
* @param boolean $date_only An optional setting to incude the date only and no time.
*
* @return string $start_date The start date time string.
*/
private function get_event_start_date( array $record, $date_only = false ) {
$start_date = $this->get_value_by_key( $record, 'event_start_date' );
$start_time = $this->get_value_by_key( $record, 'event_start_time' );
if ( ! $date_only && ! empty( $start_time ) ) {
$start_date .= ' ' . $start_time;
}
$start_date = $date_only
? date( Tribe__Date_Utils::DBDATEFORMAT, strtotime( $start_date ) )
: date( Tribe__Date_Utils::DBDATETIMEFORMAT, strtotime( $start_date ) );
return $start_date;
}
/**
* Get the event end date from the import record.
*
* @param array $record An event record from the import.
*
* @return string $end_date The end date time string.
*/
private function get_event_end_date( array $record ) {
$start_date = $this->get_event_start_date( $record );
$end_date = $this->get_value_by_key( $record, 'event_end_date' );
$end_time = $this->get_value_by_key( $record, 'event_end_time' );
if ( empty( $end_date ) ) {
$end_date = $start_date;
}
if ( ! empty( $end_time ) ) {
$end_date .= ' ' . $end_time;
}
if ( ! empty( $end_date ) ) {
$end_date = date( 'Y-m-d H:i:s', strtotime( $end_date ) );
}
if ( $end_date < $start_date ) {
$end_date = $start_date;
}
return $end_date;
}
/**
* Build an event array from import record.
*
* @param integer $post_id The event ID to update.
* @param array $record An event record from the import.
*
* @return array An array of information to save or update an event.
*/
private function build_event_array( $event_id, array $record ) {
$start_date = strtotime( $this->get_event_start_date( $record ) );
$end_date = strtotime( $this->get_event_end_date( $record ) );
if ( $this->default_post_status ) {
$post_status_setting = $this->default_post_status;
} else {
$post_status_setting = tribe( 'events-aggregator.settings' )->default_post_status( 'csv' );
}
$event = [
'post_type' => Tribe__Events__Main::POSTTYPE,
'post_title' => $this->get_value_by_key( $record, 'event_name' ),
'post_status' => $post_status_setting,
'post_content' => $this->get_post_text_field( $event_id, $record, 'event_description', 'post_content' ),
'comment_status' => $this->get_boolean_value_by_key( $record, 'event_comment_status', 'open', 'closed' ),
'ping_status' => $this->get_boolean_value_by_key( $record, 'event_ping_status', 'open', 'closed' ),
'post_excerpt' => $this->get_post_text_field( $event_id, $record, 'event_excerpt', 'post_excerpt' ),
'menu_order' => $this->get_boolean_value_by_key( $record, 'event_sticky', '-1', '0' ),
'EventStartDate' => date( 'Y-m-d', $start_date ),
'EventStartHour' => date( 'h', $start_date ),
'EventStartMinute' => date( 'i', $start_date ),
'EventStartMeridian' => date( 'a', $start_date ),
'EventEndDate' => date( 'Y-m-d', $end_date ),
'EventEndHour' => date( 'h', $end_date ),
'EventEndMinute' => date( 'i', $end_date ),
'EventEndMeridian' => date( 'a', $end_date ),
'EventShowMapLink' => $this->get_boolean_value_by_key( $record, 'event_show_map_link', '1', '' ),
'EventShowMap' => $this->get_boolean_value_by_key( $record, 'event_show_map', '1', '' ),
'EventCost' => $this->get_value_by_key( $record, 'event_cost' ),
'EventCurrencyCode' => $this->get_value_by_key( $record, 'event_currency_code' ),
'EventAllDay' => $this->get_boolean_value_by_key( $record, 'event_all_day', 'yes' ),
'EventHideFromUpcoming' => $this->get_boolean_value_by_key( $record, 'event_hide', 'yes', '' ),
'EventURL' => $this->get_value_by_key( $record, 'event_website' ),
'EventCurrencySymbol' => $this->get_value_by_key( $record, 'event_currency_symbol' ),
'EventCurrencyPosition' => $this->get_currency_position( $record ),
'EventTimezone' => $this->get_timezone( $this->get_value_by_key( $record, 'event_timezone' ) ),
'feature_event' => $this->get_boolean_value_by_key( $record, 'feature_event', '1', '' ),
];
if ( $organizer_id = $this->find_matching_organizer_id( $record ) ) {
$event['organizer'] = is_array( $organizer_id ) ? $organizer_id : [ 'OrganizerID' => $organizer_id ];
}
if ( $venue_id = $this->find_matching_venue_id( $record ) ) {
$event['venue'] = [ 'VenueID' => $venue_id ];
}
$cats = $this->get_value_by_key( $record, 'event_category' );
if ( $this->is_aggregator && ! empty( $this->default_category ) ) {
$cats = $cats ? $cats . ',' . $this->default_category : $this->default_category;
} elseif ( $category_setting = tribe( 'events-aggregator.settings' )->default_category( 'csv' ) ) {
$cats = $cats ? $cats . ',' . $category_setting : $category_setting;
}
if ( $cats ) {
$events_cat = Tribe__Events__Main::TAXONOMY;
$event['tax_input'][ $events_cat ] = Tribe__Terms::translate_terms_to_ids( explode( ',', $cats ), $events_cat );
}
if ( $tags = $this->get_value_by_key( $record, 'event_tags' ) ) {
$event['tax_input']['post_tag'] = $tags;
}
// don't create the _EventHideFromUpcoming meta key/value pair if it doesn't need to be created
if ( ! $event['EventHideFromUpcoming'] ) {
unset( $event['EventHideFromUpcoming'] );
}
if ( $event['menu_order'] == '-1' ) {
$event['EventShowInCalendar'] = 'yes';
}
$additional_fields = apply_filters( 'tribe_events_csv_import_event_additional_fields', [] );
if ( ! empty ( $additional_fields ) ) {
foreach ( $additional_fields as $key => $csv_column ) {
$value = $this->get_value_by_key( $record, $key );
if ( strpos( $value, '|' ) > -1 ) {
$event[ $key ] = explode( '|', $value );
} else {
$event[ $key ] = $value;
}
}
}
/**
* Filter the csv event import event meta.
*
* @since 5.12.4
*
* @param array $event An array event meta fields.
*
* @return array An array of the autodetect results.
*/
return apply_filters( 'tec_events_csv_import_event_meta', $event, $record, $this );
}
/**
* Filter allowing user to customize the separator used for organizers
* Defaults to comma ','
* @since 4.6.19
*
* @return mixed
*/
private function get_separator() {
return apply_filters( 'tribe_get_event_import_organizer_separator', ',' );
}
/**
* Find organizer matches from separated string
* Attempts to compensate for names with separators in them - Like "Woodhouse, Chelsea S."
* @since 4.6.19
* @param $organizers
*
* @return array
*/
private function match_organizers( $organizers ) {
$matches = [];
$separator = $this->get_separator(); // We allow this to be filtered
$skip = false; // For concatenation checks
for ( $i = 0, $len = count( $organizers ); $i < $len; $i++ ) {
if ( $skip ) {
$skip = false;
continue;
}
$potential_match = $this->find_matching_post_id( trim( $organizers[ $i ] ), Tribe__Events__Organizer::POSTTYPE, 'any' );
// We've got a match so we add it and move on
if ( ! empty( $potential_match ) ) {
$matches[] = $potential_match;
$skip = false;
continue;
}
// No match - test for separator in name by grabbing the next item and concatenating
$test_organizer = trim( $organizers[ $i ] ) . $separator . ' ' . trim( $organizers[ $i + 1 ] );
$potential_match = $this->find_matching_post_id( $test_organizer, Tribe__Events__Organizer::POSTTYPE, 'any' );
// Still no match, skip this item and move on
if ( empty( $potential_match ) ) {
$skip = false;
continue;
}
// we got a match when combined with the next, so we flag to skip the next item
$skip = true;
$matches[] = $potential_match;
}
$matches = array_filter( array_unique( $matches ) );
// If we get something outlandish - like no organizers or more organizers than expected, bail
if ( empty( $matches ) || count( $matches ) > count( $organizers ) ) {
return [];
}
$organizer_ids = [ 'OrganizerID' => [] ];
foreach ( $matches as $id ) {
$organizer_ids[ 'OrganizerID' ][] = $id;
}
return $organizer_ids;
}
/**
* Determine if organizer is a list of space-separated IDs
* @param $organizer
*
* @return array[]|bool|false|string[]
*/
private function organizer_is_space_separated_ids( $organizer ) {
$pattern = '/\s+/';
if (
preg_match( $pattern, $organizer )
&& is_numeric( preg_replace( $pattern, '', $organizer ) )
) {
return preg_split( $pattern, $organizer );
}
return false;
}
/**
* * Determine if organizer is a list of $separator-separated IDs
* @param $organizer
*
* @return array[]|bool|false|string[]
*/
private function maybe_organizer_is_separated_list( $organizer ) {
$separator = $this->get_separator();
// When we require php > 5.5 we can combine these
$cleared_separator = trim( $separator );// clear whitespace
$pattern = ! empty( $cleared_separator ) ? '/' . $cleared_separator . '+/' : '/\s+/';
// event_organizer_name is a list of $separator-separated names and/or IDs
if ( false !== stripos( $organizer, $separator ) ) {
return preg_split( $pattern, $organizer );
}
return false;
}
/**
* Handle finding the matching organizer(s) for the event
* @since 4.6.19
* @param $record - the event record from the import
*
* @return array
*/
private function find_matching_organizer_id( $record ) {
$organizer = $this->get_value_by_key( $record, 'event_organizer_name' );
// Test for space-separated IDs separately
if ( $maybe_spaced_organizers = $this->organizer_is_space_separated_ids( $organizer ) ) {
return $this->match_organizers( $maybe_spaced_organizers );
}
// Check for $separator list
if ( $maybe_separated_organizers = $this->maybe_organizer_is_separated_list( $organizer ) ) {
return $this->match_organizers( $maybe_separated_organizers );
}
// Just in case something went wrong
// We've likely got a single item - either a number or a name (with optional spaces)
$matching_post_ids = $this->find_matching_post_id( $organizer, Tribe__Events__Organizer::POSTTYPE, 'any' );
if ( ! is_array( $matching_post_ids ) ) {
$matching_post_ids = [ $matching_post_ids ];
}
return [ 'OrganizerID' => $matching_post_ids ];
}
private function find_matching_venue_id( $record ) {
$name = $this->get_value_by_key( $record, 'event_venue_name' );
return $this->find_matching_post_id( $name, Tribe__Events__Venue::POSTTYPE, 'any' );
}
/**
* Parses a timezone string candidate and returns a TEC supported timezone string.
*
* @param string $timezone_candidate
*
* @return bool|string Either the timezone string or `false` if the timezone candidate is invalid.
*/
private function get_timezone( $timezone_candidate ) {
if ( Tribe__Timezones::is_utc_offset( $timezone_candidate ) ) {
return $timezone_candidate;
}
return Tribe__Timezones::get_timezone( $timezone_candidate, false ) ? $timezone_candidate : false;
}
/**
* Get Post Text from Import or Existing Value using the provided field name and post field.
*
* @since 5.1.6
*
* @param int $event_id The event id being updated by import.
* @param array $record An event record from the import.
* @param string $field The import field name.
* @param string $post_field The post field name.
*
* @return string The description value to update the event with.
*/
protected function get_post_text_field( $event_id, $record, $field, $post_field ) {
$import_exists = $this->has_value_by_key( $record, $field );
// If the import field is not being imported and there is no id, return an empty string.
if ( ! $import_exists && empty( $event_id ) ) {
return '';
}
// If the import field is not being imported and there is an id, return current description.
if ( ! $import_exists && $event_id ) {
$post = get_post( $event_id );
if ( ! $post instanceof \WP_Post ) {
return '';
}
return $post->{$post_field};
}
$import_description = $this->get_value_by_key( $record, $field );
// If there is no event id we return the imported description, even if empty.
return $import_description;
}
/**
* Allows the user to specify the currency position using alias terms.
*
* @param array $record
*
* @return string Either `prefix` or `suffix`; will fall back on the first if the specified position is not
* a recognized alias.
*/
private function get_currency_position( array $record ) {
$currency_position = $this->get_value_by_key( $record, 'event_currency_position' );
$after_aliases = [ 'suffix', 'after' ];
foreach ( $after_aliases as $after_alias ) {
if ( preg_match( '/' . $after_alias . '/i', $currency_position ) ) {
return 'suffix';
}
}
return 'prefix';
}
}
PK [h Featured_Image_Uploader.phpnu [ PK [6 F File_Uploader.phpnu [ PK [pE E M Column_Mapper.phpnu [ PK [&Td$ $ " File_Importer_Venues.phpnu [ PK [i8 8 G File_Importer.phpnu [ PK [NFX X File_Reader.phpnu [ PK [I
File_Importer_Organizers.phpnu [ PK [o=I I File_Importer_Events.phpnu [ PK