( $success ) ? Util::ns( 'export_success' ) : Util::ns( 'export_fail' ), $nonce['name'] => wp_create_nonce( $nonce['action'] ), 'tab' => 'adcmdr_export', ), $url ); wp_safe_redirect( sanitize_url( $url ) ); exit; } /** * Determine if we are capable of export. * * @return bool */ public static function can_export() { return class_exists( 'ZipArchive' ) && class_exists( 'DateTime' ); } /** * Create a suffix if one does not exist. */ private function export_suffix() { if ( ! $this->export_suffix ) { $dt = Util::datetime_wp_timezone( 'now' ); $this->export_suffix = '_' . $dt->format( 'YmdHis' ) . '_' . preg_replace( '/[^a-z0-9]/i', '', strtolower( wp_generate_password( 5, false ) ) ); } return $this->export_suffix; } /** * Add admin notice on export success. */ public function export_success() { if ( isset( $_GET['action'] ) && sanitize_text_field( wp_unslash( $_GET['action'] ) ) === Util::ns( 'export_success' ) ) { $export_nonce = $this->nonce_array( 'adcmdr-do_export', 'export' ); if ( check_admin_referer( $export_nonce['action'], $export_nonce['name'] ) && current_user_can( AdCommander::capability() ) ) { ?>

nonce_array( 'adcmdr-do_export', 'export' ); if ( check_admin_referer( $export_nonce['action'], $export_nonce['name'] ) && current_user_can( AdCommander::capability() ) ) { ?>

init_wp_filesystem() ) { return false; } global $wp_filesystem; $filelist = $wp_filesystem->dirlist( self::export_dir(), false ); if ( is_array( $filelist ) ) { $bundles = array_filter( $filelist, function ( $file ) use ( $filters ) { if ( $file['type'] !== 'f' ) { return false; } foreach ( $filters as $filter ) { if ( stripos( $file['name'], $filter ) === false ) { return false; } } return true; } ); usort( $bundles, function ( $a, $b ) { return isset( $a['lastmodunix'] ) && isset( $b['lastmodunix'] ) ? $b['lastmodunix'] <=> $a['lastmodunix'] : 0; } ); } Filesystem::instance()->end_wp_filesystem(); return $bundles; } /** * Perform an export. * * @return void|bool */ public function do_export() { $export_nonce = $this->nonce_array( 'adcmdr-do_export', 'export' ); if ( ! isset( $_REQUEST['action'] ) || ! check_admin_referer( $export_nonce['action'], $export_nonce['name'] ) || ! current_user_can( AdCommander::capability() ) ) { wp_die(); } if ( sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ) !== Util::ns( 'do_export' ) ) { return false; } $this->wo_meta = new WOMeta( AdCommander::ns() ); $ads = $this->process_ads(); $groups = $this->process_groups(); $campaigns = $this->process_campaigns(); $advertisers = $this->process_advertisers(); $placements = $this->process_placements(); $bundles = array( 'adcmdr_ads' => $ads, 'adcmdr_groups' => $groups, 'adcmdr_campaigns' => $campaigns, 'adcmdr_advertisers' => $advertisers, 'adcmdr_placements' => $placements, ); if ( isset( $_REQUEST['adcmdr_export_include_stats'] ) && Util::truthy( sanitize_text_field( wp_unslash( $_REQUEST['adcmdr_export_include_stats'] ) ) ) ) { $bundles['adcmdr_stats'] = $this->process_stats( $ads ); } if ( $this->create_bundle( $bundles ) ) { $this->redirect( $export_nonce, true ); } $this->redirect( $export_nonce, false ); } /** * Delete a bundle file. * * @param string $file The filename to delete. * * @return bool */ public function delete_bundle( $file ) { if ( ! $file ) { return false; } $dir = self::export_dir(); if ( file_exists( $dir . $file ) ) { wp_delete_file( $dir . $file ); } return true; } /** * Create a bundle from arrays. * * @param array $bundle Bundle of data. * * @return bool|void */ private function create_bundle( $bundle ) { if ( empty( $bundle ) ) { return false; } $dir = Filesystem::instance()->maybe_create_dir( self::export_dir() ); if ( ! $dir ) { return false; } $csvs = array(); foreach ( $bundle as $file => $data ) { if ( ! isset( $data['headings'] ) || ! $data['headings'] ) { continue; } $filename = sanitize_title( $file . $this->export_suffix() ) . '.csv'; $full_path = $dir . $filename; $fd = fopen( $full_path, 'w' ); if ( $fd ) { $headings = $data['headings']; fputcsv( $fd, $headings ); foreach ( $data['rows'] as $row ) { $this_row = array(); foreach ( $headings as $heading ) { if ( isset( $row[ $heading ] ) ) { $this_row[] = $row[ $heading ]; } else { $this_row[] = ''; } } fputcsv( $fd, $this_row ); } fclose( $fd ); $csvs[] = $full_path; } } if ( ! empty( $csvs ) ) { $zip = new \ZipArchive(); $zip_filename = 'bundle' . $this->export_suffix() . '.zip'; if ( file_exists( $dir . $zip_filename ) ) { wp_delete_file( $dir . $zip_filename ); } if ( $zip->open( $dir . $zip_filename, \ZipArchive::CREATE ) !== true ) { return false; } foreach ( $csvs as $csv ) { $zip->addFile( $csv, basename( $csv ) ); } $zip->close(); foreach ( $csvs as $csv ) { wp_delete_file( $csv ); } return true; } return false; } /** * Query and prepare groups for export. * * @return array */ private function process_groups() { $headings = array_keys( UtilTools::headings( 'groups' ) ); $processed_groups = array(); $groups = Query::groups(); if ( $groups ) { $home_url = home_url(); foreach ( $groups as $group ) { $meta = $this->wo_meta->get_term_meta( $group->term_id, GroupTermMeta::tax_group_meta_keys() ); $this_group = array( 'source' => 'adcmdr_export', 'source_site' => $home_url, ); foreach ( $headings as $heading ) { if ( isset( $this_group[ $heading ] ) ) { continue; } $value = ''; if ( isset( $group->$heading ) ) { $value = $group->$heading; } elseif ( isset( $meta[ $heading ] ) ) { $value = $meta[ $heading ]; } $this_group[ $heading ] = maybe_serialize( $value ); } $processed_groups[] = $this_group; } } return array( 'headings' => $headings, 'rows' => $processed_groups, ); } /** * Query and prepare campaigns for export. * * @return array */ private function process_campaigns() { $headings = array_keys( UtilTools::headings( 'campaigns' ) ); $processed_campaigns = array(); $campaigns = Query::campaigns(); if ( $campaigns ) { $home_url = home_url(); foreach ( $campaigns as $campaign ) { $meta = array(); $this_campaign = array( 'source' => 'adcmdr_export', 'source_site' => $home_url, ); foreach ( $headings as $heading ) { if ( isset( $this_campaign[ $heading ] ) ) { continue; } $value = ''; if ( isset( $campaign->$heading ) ) { $value = $campaign->$heading; } elseif ( isset( $meta[ $heading ] ) ) { $value = $meta[ $heading ]; } $this_campaign[ $heading ] = maybe_serialize( $value ); } $processed_campaigns[] = $this_campaign; } } return array( 'headings' => $headings, 'rows' => $processed_campaigns, ); } /** * Query and prepare advertisers for export. * * @return array */ private function process_advertisers() { $headings = array_keys( UtilTools::headings( 'advertisers' ) ); $processed_advertisers = array(); $advertisers = Query::advertisers(); if ( $advertisers ) { $home_url = home_url(); foreach ( $advertisers as $advertiser ) { $meta = array(); $this_advertiser = array( 'source' => 'adcmdr_export', 'source_site' => $home_url, ); foreach ( $headings as $heading ) { if ( isset( $this_advertiser[ $heading ] ) ) { continue; } $value = ''; if ( isset( $advertiser->$heading ) ) { $value = $advertiser->$heading; } elseif ( isset( $meta[ $heading ] ) ) { $value = $meta[ $heading ]; } $this_advertiser[ $heading ] = maybe_serialize( $value ); } $processed_advertisers[] = $this_advertiser; } } return array( 'headings' => $headings, 'rows' => $processed_advertisers, ); } /** * Query and prepare ads for export. * * @return array */ private function process_ads() { $headings = array_keys( UtilTools::headings( 'ads' ) ); $processed_ads = array(); $ads = Query::ads( 'post_title', 'asc', Util::any_post_status( array( 'trash' ) ) ); if ( $ads ) { $home_url = home_url(); foreach ( $ads as $ad ) { $meta = $this->wo_meta->get_post_meta( $ad->ID, AdPostMeta::post_meta_keys() ); $terms_groups = get_the_terms( $ad->ID, AdCommander::tax_group() ); $terms_groups_export = array(); if ( $terms_groups && ! empty( $terms_groups ) ) { foreach ( $terms_groups as $term ) { $terms_groups_export[ $term->term_id ] = $term->name; } } $terms_campaigns = get_the_terms( $ad->ID, AdCommander::tax_campaign() ); $terms_campaigns_export = array(); if ( $terms_campaigns && ! empty( $terms_campaigns ) ) { foreach ( $terms_campaigns as $term ) { $terms_campaigns_export[ $term->term_id ] = $term->name; } } $terms_advertisers = get_the_terms( $ad->ID, AdCommander::tax_advertiser() ); $terms_advertisers_export = array(); if ( $terms_advertisers && ! empty( $terms_advertisers ) ) { foreach ( $terms_advertisers as $term ) { $terms_advertisers_export[ $term->term_id ] = $term->name; } } $featured_image_url = ''; $thumbnail_id = ''; if ( has_post_thumbnail( $ad->ID ) ) { $thumbnail_id = get_post_thumbnail_id( $ad->ID ); $featured_image_url = get_the_post_thumbnail_url( $ad->ID, 'full' ); } $this_ad = array( 'source' => 'adcmdr_export', 'source_site' => $home_url, 'featured_image_url' => $featured_image_url, 'thumbnail_id' => $thumbnail_id, 'groups' => maybe_serialize( $terms_groups_export ), 'campaigns' => maybe_serialize( $terms_campaigns_export ), 'advertisers' => maybe_serialize( $terms_advertisers_export ), ); foreach ( $headings as $heading ) { if ( isset( $this_ad[ $heading ] ) ) { continue; } $value = ''; if ( isset( $ad->$heading ) ) { $value = $ad->$heading; } elseif ( isset( $meta[ $heading ] ) ) { $value = $meta[ $heading ]; } $this_ad[ $heading ] = maybe_serialize( $value ); } $processed_ads[] = $this_ad; } } return array( 'headings' => $headings, 'rows' => $processed_ads, ); } /** * Query and prepare placements for export. * * @return array */ private function process_placements() { $headings = array_keys( UtilTools::headings( 'placements' ) ); $processed_placements = array(); $placements = Query::placements( Util::any_post_status( array( 'trash' ) ) ); if ( $placements ) { $home_url = home_url(); foreach ( $placements as $placement ) { $meta = $this->wo_meta->get_post_meta( $placement->ID, PlacementPostMeta::post_meta_keys() ); $this_placement = array( 'source' => 'adcmdr_export', 'source_site' => $home_url, ); foreach ( $headings as $heading ) { if ( isset( $this_placement[ $heading ] ) ) { continue; } $value = ''; if ( isset( $placement->$heading ) ) { $value = $placement->$heading; } elseif ( isset( $meta[ $heading ] ) ) { $value = $meta[ $heading ]; } $this_placement[ $heading ] = maybe_serialize( $value ); } $processed_placements[] = $this_placement; } } return array( 'headings' => $headings, 'rows' => $processed_placements, ); } /** * Process an individual stat (impression or click). * * @param array $this_stat The individual stat. * @param object $stat The stat to process. * @param array $headings The CSV headings/keys. * * @return array */ private function process_stat( $this_stat, $stat, $headings ) { foreach ( $headings as $heading ) { if ( isset( $this_stat[ $heading ] ) ) { continue; } $value = ''; if ( isset( $stat->$heading ) ) { $value = $stat->$heading; } $this_stat[ $heading ] = $value; } return $this_stat; } /** * Process all stats. * * @param array $ads The ads that were exported in this bundle. * * @return array */ private function process_stats( $ads ) { $headings = array_keys( UtilTools::headings( 'stats' ) ); if ( ! $ads['rows'] || empty( $ads['rows'] ) ) { return array( 'headings' => $headings, 'rows' => array(), ); } $ad_ids = wp_list_pluck( $ads['rows'], 'ID' ); if ( ! $ad_ids || empty( $ad_ids ) ) { return array( 'headings' => $headings, 'rows' => array(), ); } global $wpdb; $home_url = home_url(); $processed_stats = array(); $ad_ids = array_map( 'absint', $ad_ids ); $ad_ids_placeholder = implode( ', ', array_fill( 0, count( $ad_ids ), '%d' ) ); $args = array( TrackingLocal::get_tracking_table( 'impressions' ) ); $impressions = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %i WHERE ad_id IN ($ad_ids_placeholder)", array_merge( $args, $ad_ids ) ) ); $args = array( TrackingLocal::get_tracking_table( 'clicks' ) ); $clicks = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %i WHERE ad_id IN ($ad_ids_placeholder)", array_merge( $args, $ad_ids ) ) ); if ( ! empty( $impressions ) ) { foreach ( $impressions as $impression ) { $processed_stats[] = $this->process_stat( array( 'source' => 'adcmdr_export', 'source_site' => $home_url, 'stat_type' => 'impression', ), $impression, $headings ); } } if ( ! empty( $clicks ) ) { foreach ( $clicks as $click ) { $processed_stats[] = $this->process_stat( array( 'source' => 'adcmdr_export', 'source_site' => $home_url, 'stat_type' => 'click', ), $click, $headings ); } } return array( 'headings' => $headings, 'rows' => $processed_stats, ); } /** * Get the local path to the export folder. * * @return string */ public static function export_path() { return apply_filters( 'adcmdr_export_uploads_path', '/ad-commander/export' ); } /** * Get the full URL for the export folder. * * @return string */ public static function export_url() { $wp_upload_dir = wp_upload_dir(); if ( ! isset( $wp_upload_dir['baseurl'] ) ) { return false; } return $wp_upload_dir['baseurl'] . trailingslashit( self::export_path() ); } /** * Get the full directory for the export folder. * * @return string */ public static function export_dir() { $wp_upload_dir = wp_upload_dir(); if ( ! isset( $wp_upload_dir['basedir'] ) ) { return false; } return $wp_upload_dir['basedir'] . trailingslashit( self::export_path() ); } }