Column header labels.
*/
private static function get_csv_headers() {
return array(
__( 'Title', 'adfusion-ad-manager-and-monetization' ),
__( 'Link URL', 'adfusion-ad-manager-and-monetization' ),
__( 'Desktop Image URL', 'adfusion-ad-manager-and-monetization' ),
__( 'Mobile Image URL', 'adfusion-ad-manager-and-monetization' ),
__( 'Start Date', 'adfusion-ad-manager-and-monetization' ),
__( 'End Date', 'adfusion-ad-manager-and-monetization' ),
__( 'Weight', 'adfusion-ad-manager-and-monetization' ),
__( 'Whitelisted Category IDs', 'adfusion-ad-manager-and-monetization' ),
);
}
/**
* Constructor.
*/
public function __construct() {
add_action( 'admin_post_adfusion_export_ads_csv', array( $this, 'handle_export' ) );
add_action( 'admin_post_adfusion_import_ads_csv', array( $this, 'handle_import' ) );
add_action( 'admin_post_adfusion_sync_destination_urls', array( $this, 'handle_sync_destination_urls' ) );
}
/**
* Render the Tools tab content.
*
* @return void
*/
public function render_tools_tab() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
?>
'adfusion_ad',
'posts_per_page' => -1,
'post_status' => 'any',
'orderby' => 'title',
'order' => 'ASC',
)
);
header( 'Content-Type: text/csv; charset=utf-8' );
header( 'Content-Disposition: attachment; filename=adfusion-ads-' . gmdate( 'Y-m-d' ) . '.csv' );
$output = fopen( 'php://output', 'w' );
if ( false === $output ) {
wp_die( esc_html__( 'Could not create export file.', 'adfusion-ad-manager-and-monetization' ) );
}
fputcsv( $output, self::get_csv_headers() );
foreach ( $ads as $ad ) {
$start = get_post_meta( $ad->ID, '_adf_start_datetime', true );
if ( empty( $start ) ) {
$start = get_post_meta( $ad->ID, '_adf_start_date', true );
}
$end = get_post_meta( $ad->ID, '_adf_end_datetime', true );
if ( empty( $end ) ) {
$end = get_post_meta( $ad->ID, '_adf_end_date', true );
}
$target_cats = get_post_meta( $ad->ID, '_adf_target_categories', true );
$cat_ids = is_array( $target_cats ) ? implode( ',', array_map( 'absint', $target_cats ) ) : '';
fputcsv(
$output,
array(
$ad->post_title,
get_post_meta( $ad->ID, '_adf_destination_url', true ),
get_post_meta( $ad->ID, '_adf_ad_image', true ),
get_post_meta( $ad->ID, '_adf_ad_image_mobile', true ),
$start ? substr( $start, 0, 10 ) : '',
$end ? substr( $end, 0, 10 ) : '',
$this->get_weight_for_export( $ad->ID ),
$cat_ids,
)
);
}
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- Streaming to php://output for CSV download.
fclose( $output );
exit;
}
/**
* Get weight value for CSV export (default 1 if empty).
*
* @param int $post_id Post ID.
* @return string Weight as string.
*/
private function get_weight_for_export( $post_id ) {
$weight = get_post_meta( $post_id, '_adf_weight', true );
return ! empty( $weight ) ? (string) $weight : '1';
}
/**
* Handle CSV import.
*
* @return void
*/
public function handle_import() {
check_admin_referer( 'adfusion_import_ads_csv', 'adfusion_import_nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'adfusion-ad-manager-and-monetization' ) );
}
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- tmp_name validated by is_uploaded_file; path is server-generated.
$tmp_path = isset( $_FILES['adfusion_csv_file']['tmp_name'] ) ? $_FILES['adfusion_csv_file']['tmp_name'] : '';
if ( empty( $tmp_path ) || ! is_uploaded_file( $tmp_path ) ) {
wp_safe_redirect(
add_query_arg(
array(
'page' => 'adfusion-settings',
'tab' => 'tools',
'adfusion_import' => 'error',
'adfusion_import_msg' => 'no_file',
),
admin_url( 'edit.php?post_type=adfusion_ad' )
)
);
exit;
}
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen -- CSV import requires fopen for fgetcsv.
$handle = fopen( $tmp_path, 'r' );
if ( false === $handle ) {
wp_safe_redirect(
add_query_arg(
array(
'page' => 'adfusion-settings',
'tab' => 'tools',
'adfusion_import' => 'error',
'adfusion_import_msg' => 'read_failed',
),
admin_url( 'edit.php?post_type=adfusion_ad' )
)
);
exit;
}
$created = 0;
$updated = 0;
// Skip header row.
$header = fgetcsv( $handle );
if ( false === $header ) {
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- Standard PHP file handle.
fclose( $handle );
wp_safe_redirect(
add_query_arg(
array(
'page' => 'adfusion-settings',
'tab' => 'tools',
'adfusion_import' => 'error',
'adfusion_import_msg' => 'empty_file',
),
admin_url( 'edit.php?post_type=adfusion_ad' )
)
);
exit;
}
$row = fgetcsv( $handle );
while ( false !== $row ) {
if ( empty( $row[0] ) ) {
continue;
}
$title = sanitize_text_field( $row[0] );
$link_url = isset( $row[1] ) ? esc_url_raw( trim( $row[1] ) ) : '';
$desktop_img = isset( $row[2] ) ? esc_url_raw( trim( $row[2] ) ) : '';
$mobile_img = isset( $row[3] ) ? esc_url_raw( trim( $row[3] ) ) : '';
$start_date = isset( $row[4] ) ? sanitize_text_field( trim( $row[4] ) ) : '';
$end_date = isset( $row[5] ) ? sanitize_text_field( trim( $row[5] ) ) : '';
$weight = isset( $row[6] ) ? max( 1, min( 10, (int) $row[6] ) ) : 1;
$cat_ids_raw = isset( $row[7] ) ? trim( $row[7] ) : '';
global $wpdb;
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Single lookup by title; caching not practical.
$post_id = $wpdb->get_var(
$wpdb->prepare(
"SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_title = %s AND post_status != 'trash' LIMIT 1",
'adfusion_ad',
$title
)
);
$existing = $post_id ? get_post( $post_id ) : null;
if ( $existing ) {
$post_id = $existing->ID;
++$updated;
} else {
$post_id = wp_insert_post(
array(
'post_title' => $title,
'post_type' => 'adfusion_ad',
'post_status' => 'publish',
)
);
if ( is_wp_error( $post_id ) ) {
continue;
}
++$created;
}
if ( ! $post_id ) {
continue;
}
update_post_meta( $post_id, '_adf_destination_url', $link_url );
update_post_meta( $post_id, '_adf_ad_url', $link_url );
update_post_meta( $post_id, '_adf_ad_image', $desktop_img );
update_post_meta( $post_id, '_adf_ad_image_mobile', $mobile_img );
update_post_meta( $post_id, '_adf_ad_type', 'image' );
update_post_meta( $post_id, '_adf_weight', (string) $weight );
if ( ! empty( $start_date ) ) {
$start_val = preg_match( '/^\d{4}-\d{2}-\d{2}$/', $start_date ) ? $start_date . ' 00:00:00' : $start_date;
update_post_meta( $post_id, '_adf_start_datetime', $start_val );
}
if ( ! empty( $end_date ) ) {
$end_val = preg_match( '/^\d{4}-\d{2}-\d{2}$/', $end_date ) ? $end_date . ' 23:59:59' : $end_date;
update_post_meta( $post_id, '_adf_end_datetime', $end_val );
}
$target_cats = array();
if ( ! empty( $cat_ids_raw ) ) {
$target_cats = array_filter( array_map( 'absint', array_map( 'trim', explode( ',', $cat_ids_raw ) ) ) );
}
update_post_meta( $post_id, '_adf_target_categories', $target_cats );
$row = fgetcsv( $handle );
}
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- Standard PHP file handle.
fclose( $handle );
wp_safe_redirect(
add_query_arg(
array(
'page' => 'adfusion-settings',
'tab' => 'tools',
'adfusion_import' => 'success',
'adfusion_created' => $created,
'adfusion_updated' => $updated,
),
admin_url( 'edit.php?post_type=adfusion_ad' )
)
);
exit;
}
/**
* Sync _adf_destination_url and _adf_ad_url for all ads en masse.
* Ensures both meta keys have the destination URL so click redirects work.
*
* @return void
*/
public function handle_sync_destination_urls() {
check_admin_referer( 'adfusion_sync_destination_urls', 'adfusion_sync_urls_nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'adfusion-ad-manager-and-monetization' ) );
}
$ads = get_posts(
array(
'post_type' => 'adfusion_ad',
'posts_per_page' => -1,
'post_status' => 'any',
)
);
$updated = 0;
foreach ( $ads as $ad ) {
$dest = get_post_meta( $ad->ID, '_adf_destination_url', true );
$url = get_post_meta( $ad->ID, '_adf_ad_url', true );
$canonical = ! empty( $dest ) ? $dest : $url;
if ( empty( $canonical ) ) {
continue;
}
$changed = false;
if ( $dest !== $canonical ) {
update_post_meta( $ad->ID, '_adf_destination_url', $canonical );
$changed = true;
}
if ( $url !== $canonical ) {
update_post_meta( $ad->ID, '_adf_ad_url', $canonical );
$changed = true;
}
if ( $changed ) {
++$updated;
}
}
wp_safe_redirect(
add_query_arg(
array(
'page' => 'adfusion-settings',
'tab' => 'tools',
'adfusion_sync_urls' => 'success',
'adfusion_sync_count' => $updated,
),
admin_url( 'edit.php?post_type=adfusion_ad' )
)
);
exit;
}
}