get_action_keys() as $key ) {
$key_underscore = self::_key( $key );
add_action( 'wp_ajax_' . $this->action_string( $key ), array( $this, 'action_' . $key_underscore ) );
}
}
/**
* Create or get nonce
*
* @param string $action The action for the nonce.
* @param string $key The key to create the nonce string from.
*/
protected function nonce_array( $action, $key ) {
if ( ! isset( $this->nonce_arrays[ $action ] ) ) {
$this->nonce_arrays[ $action ] = $this->nonce( $action, $key );
}
return $this->nonce_arrays[ $action ];
}
/**
* Enqueue scripts
*
* @return void
*/
public function admin_enqueue_scripts() {
if ( $this->is_screen( $this->admin_menu_hooks_dt ) ) {
wp_enqueue_script( 'jquery' );
$handle = Util::ns( 'dt-impexp' );
wp_register_script(
$handle,
AdCommanderTools::assets_url() . 'js/importexport.js',
array(
'jquery',
),
AdCommanderTools::version(),
array( 'in_footer' => true )
);
wp_enqueue_script( $handle );
Util::enqueue_script_data(
$handle,
array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'actions' => $this->get_ajax_actions(),
)
);
}
}
/**
* Get necessary action keys, which will be used to create wp_ajax hooks.
*
* @return array
*/
private function get_action_keys() {
return array(
'delete-bundle',
);
}
/**
* Creates an array of all of the necessary actions.
*
* @return array
*/
private function get_ajax_actions() {
$actions = array();
foreach ( $this->get_action_keys() as $key ) {
$actions[ self::_key( $key ) ] = array(
'action' => $this->action_string( $key ),
'security' => wp_create_nonce( $this->nonce_string( $key ) ),
);
}
return $actions;
}
/**
* Delete a bundle
*
* @return void
*/
public function action_delete_bundle() {
$action = 'delete-bundle';
check_ajax_referer( $this->nonce_string( $action ), 'security' );
if ( ! current_user_can( AdCommander::capability() ) ) {
wp_die();
}
$file = isset( $_REQUEST['file'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['file'] ) ) : false;
if ( Export::instance()->delete_bundle( $file ) ) {
wp_send_json_success(
array(
'action' => $action,
)
);
}
wp_die();
}
/**
* Enqueue styles if we're on a screen that needs them.
*
* @return void
*/
public function admin_print_styles() {
if ( $this->is_screen( $this->admin_menu_hooks_dt ) ) {
wp_enqueue_style( Util::ns( 'dt-tools' ), AdCommanderTools::assets_url() . 'css/admin.css', array(), AdCommanderTools::version() );
}
}
/**
* The admin_url for the tools page.
*
* @return string
*/
public static function tools_admin_url() {
return admin_url( self::admin_path( 'tools' ) );
}
/**
* The title of the Tools page
*
* @return string
*/
public function tools_title() {
return __( 'Tools', 'ad-commander-tools' );
}
/**
* Create admin menu.
*
* @return void
*/
public function create_admin_menu() {
$hook = add_submenu_page(
self::admin_slug(),
self::tools_title(),
self::tools_title(),
AdCommander::capability(),
self::admin_slug( 'tools' ),
array( $this, 'tools_page' ),
25
);
$this->admin_menu_hooks_dt[] = $hook;
}
/**
* Filter Ad Commander menu hooks and add this plugin.
*
* @param array $hooks The current hooks.
*
* @return array
*/
public function admin_menu_hooks( $hooks ) {
if ( is_array( $hooks ) && ! empty( $this->admin_menu_hooks_dt ) ) {
$hooks = array_merge( $hooks, $this->admin_menu_hooks_dt );
}
return $hooks;
}
/**
* The tools page.
*
* @return void
*/
public function tools_page() {
$this->sf()->start();
$this->sf()->title( __( 'Tools', 'ad-commander-tools' ) );
$tabs = array();
$tools['import'] = __( 'Import', 'ad-commander-tools' );
$tools['export'] = __( 'Export', 'ad-commander-tools' );
$tools['delete_stats'] = __( 'Delete Ad Stats', 'ad-commander-tools' );
$admin_url = self::tools_admin_url();
foreach ( $tools as $key => $text ) {
$opt_key = $this->sf()->key( $key );
$tabs[] = array(
'key' => $opt_key,
'text' => esc_html( $text ),
'url' => $this->sf()->get_tab_url( $opt_key, $admin_url ),
);
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification isn't needed for admin page added via add_submenu_page and processing no action.
$active_tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : $tabs[0]['key'];
$this->sf()->display_tabs( $tabs, $active_tab );
foreach ( $tabs as $tab ) {
if ( $active_tab !== $tab['key'] ) {
continue;
}
switch ( $tab['key'] ) {
case 'adcmdr_export':
$this->export_page();
break;
case 'adcmdr_import':
$this->import_page();
break;
case 'adcmdr_delete_stats':
$this->delete_stats_page();
break;
}
}
// Close .woforms-form-inner div from display_tabs().
?>
sf()->end();
}
/**
* Start a form tag.
*
* @param string $method Get or post method.
* @param bool $formdata Whether to accept file uploads.
*
* @return void
*/
private function form_start( $method = 'post', $formdata = false ) {
$this->sf()->form_start( admin_url( 'admin.php' ), $method, $formdata );
}
/**
* End a form.
*
* @return void
*/
private function form_end() {
?>
nonce_array( 'adcmdr-do_export', 'export' );
?>
info( esc_html__( "Your host doesn't appear to support the necessary libraries for exporting and compressing your data. We are unable to create export bundles at this time.", 'ad-commander-tools' ), array( 'adcmdr-metaitem__warning' ) );
} else {
$this->form_start();
?>
nonce_field( $export_nonce );
Html::admin_table_start();
?>
sf()->message( sprintf( esc_html__( 'A bundle will be created with your ads, groups, placements, and (optionally) stats.%1$sWhen importing this bundle into another site, you can choose which data to import.', 'ad-commander-tools' ), ' ' ) );
?>
sf()->message( esc_html__( "Upload a bundle zip created by Ad Commander's export tool. This zip will be processed and imported based on the options selected below.", 'ad-commander-tools' ) ); ?>
esc_html__( 'Draft', 'ad-commander-tools' ),
'match' => esc_html__( 'Match imported status and post date', 'ad-commander-tools' ),
);
$id = $this->sf()->key( 'import_set_status' );
$this->sf()->wo_forms->label( $id, esc_html__( 'Set the status of imported Ads and Placements to:', 'ad-commander-tools' ) );
$this->sf()->wo_forms->select(
$id,
$options,
'draft'
);
?>
form_end();
}
/**
* Create the manage stats page.
*
* @return void
*/
private function delete_stats_page() {
$this->delete_stats_specific_id();
$this->delete_stats_delete_rogue();
$this->delete_stats_delete_all();
}
/**
* Delete stats for a specific ad ID.
*
* @return void
*/
private function delete_stats_specific_id() {
$this->info( esc_html__( 'Warning: These are destructive actions. Please backup your database before proceeding.', 'ad-commander' ), array( 'classes' => 'adcmdr-notification adcmdr-notice-warning' ) );
?>
sf()->message( sprintf( esc_html__( 'Use this tool to delete stats for a specific ad ID.%1$sTo find the ID for an active ad, view the ad under Ad Commander -> Manage Ads. The ID is located in the URL of the ad, and displayed in the shortcode and template function.%2$sIDs for ads that no longer exist can be find in Reports. The ad will say "Ad Not Found (ID: #)".', 'ad-commander-tools' ), ' ', ' ' ) );
$delete_ad_stats_nonce = $this->nonce_array( 'adcmdr-do_delete_ad_stats', 'stats' );
$this->form_start( 'post', true );
?>
nonce_field( $delete_ad_stats_nonce );
Html::admin_table_start();
?>
sf()->key( 'ad_id' );
$this->sf()->wo_forms->input( $id, null, 'number' );
$this->sf()->message( esc_html__( 'Enter the ad ID to delete.', 'ad-commander-tools' ) );
?>
sf()->key( 'confirm_action' );
$this->sf()->wo_forms->checkbox( $id, 0, 1, array( 'id' => $id . '_ad' ) );
$this->sf()->wo_forms->label( $id . '_ad', esc_html__( 'I understand I am deleting statistics for an ad. This action cannot be undone.', 'ad-commander-tools' ) );
?>
form_end();
}
/**
* Delete rogue stats section.
*
* @return void
*/
private function delete_stats_delete_rogue() {
?>
sf()->message( sprintf( __( 'A stat is considered rogue if an ad no longer exists. Stats for ads in the trash are %1$snot%2$s considered rogue. Ads must be completely deleted.', 'ad-commander-tools' ), '', '' ) );
$rogue = StatsDelete::find_rogue_entries();
$total = count( $rogue['impressions'] ) + count( $rogue['clicks'] );
/* translators: %1$s the total number of query results */
$this->sf()->message( '' . sprintf( __( 'You currently have %1$s rogue stat entries.', 'ad-commander-tools' ), $total ) . '' );
$delete_all_stats_nonce = $this->nonce_array( 'adcmdr-do_delete_rogue_stats', 'stats' );
$this->form_start( 'post', true );
?>
nonce_field( $delete_all_stats_nonce );
Html::admin_table_start();
?>
sf()->key( 'confirm_action' );
$this->sf()->wo_forms->checkbox(
$id,
0,
1,
array(
'disabled' => $disabled,
'id' => $id . '_rogue',
)
);
$this->sf()->wo_forms->label( $id . '_rogue', __( 'I understand I am deleting statistics for ads that no longer exist. These stats will no longer be included in Reports. This action cannot be undone.', 'ad-commander-tools' ) );
?>
sf()->key( 'confirm_action' );
$this->sf()->wo_forms->checkbox( $id, 0, 1, array( 'id' => $id . '_all' ) );
$this->sf()->wo_forms->label( $id . '_all', esc_html__( 'I understand I am deleting statistics for all ads and that this action cannot be undone.', 'ad-commander-tools' ) );
?>