fictioneer-email-notifications/ajax.php

437 lines
13 KiB
PHP
Raw Permalink Normal View History

2024-03-11 02:51:58 +01:00
<?php
2024-05-05 15:34:57 +02:00
// =============================================================================
// FRONTEND
// =============================================================================
2024-03-11 02:51:58 +01:00
/**
* AJAX callback to retrieve the modal content
*
2024-03-13 14:18:53 +01:00
* Note: The "fictioneer_ajax_" prefix enables the plugin skipping
* in the theme's must-use-plugin.
*
2024-03-11 02:51:58 +01:00
* @since 0.1.0
*/
2024-03-13 14:18:53 +01:00
function fictioneer_ajax_fcnen_get_form_content() {
2024-03-11 02:51:58 +01:00
// Verify
if ( ! wp_doing_ajax() ) {
2024-03-11 22:11:50 +01:00
wp_send_json_error( __( 'Invalid request.', 'fcnen' ) );
2024-03-11 02:51:58 +01:00
}
// Get form
2024-03-11 22:11:50 +01:00
$html = fictioneer_minify_html( fcnen_get_modal_content() );
2024-03-11 02:51:58 +01:00
// Response
wp_send_json_success( array( 'html' => $html ) );
}
2024-03-13 14:18:53 +01:00
add_action( 'wp_ajax_fictioneer_ajax_fcnen_get_form_content', 'fictioneer_ajax_fcnen_get_form_content' );
add_action( 'wp_ajax_nopriv_fictioneer_ajax_fcnen_get_form_content', 'fictioneer_ajax_fcnen_get_form_content' );
2024-03-11 02:51:58 +01:00
/**
* AJAX callback to subscribe
*
2024-03-13 14:18:53 +01:00
* Note: The "fictioneer_ajax_" prefix enables the plugin skipping
* in the theme's must-use-plugin.
*
2024-03-11 02:51:58 +01:00
* @since 0.1.0
*/
2024-03-13 14:18:53 +01:00
function fictioneer_ajax_fcnen_subscribe_or_update() {
2024-03-11 02:51:58 +01:00
// Verify
if ( ! wp_doing_ajax() ) {
2024-03-11 22:11:50 +01:00
wp_send_json_error( __( 'Invalid request.', 'fcnen' ) );
2024-03-11 02:51:58 +01:00
}
2024-03-11 22:11:50 +01:00
if ( ! check_ajax_referer( 'fcnen-subscribe', 'nonce', false ) ) {
2024-03-11 10:22:59 +01:00
wp_send_json_error(
2024-03-11 22:11:50 +01:00
array( 'notice' => __( 'Nonce verification failed. Please reload and try again.', 'fcnen' ) )
2024-03-11 10:22:59 +01:00
);
}
2024-03-11 02:51:58 +01:00
// Setup
$email = sanitize_email( $_POST['email'] ?? '' );
$code = sanitize_text_field( $_POST['code'] ?? '' );
2024-03-12 02:16:04 +01:00
$scope_everything = boolval( absint( $_POST['scope-everything'] ?? 1 ) );
$scope_posts = boolval( absint( $_POST['scope-posts'] ?? 0 ) );
$scope_stories = boolval( absint( $_POST['scope-stories'] ?? 0 ) );
$scope_chapters = boolval( absint( $_POST['scope-chapters'] ?? 0 ) );
2024-03-13 12:14:24 +01:00
$post_ids = fcnen_get_array_from_post_string( 'post_id' );
2024-03-13 18:07:27 +01:00
$categories = fcnen_get_array_from_post_string( 'categories' );
$tags = fcnen_get_array_from_post_string( 'tags' );
$taxonomies = fcnen_get_array_from_post_string( 'taxonomies' );
2024-06-06 19:10:55 +02:00
$default_notice = __( 'Submission successful. If everything is in order, you will get an email.', 'fcnen' );
2024-03-11 02:51:58 +01:00
$result = false;
// Validate email
if ( empty( $email ) || ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
2024-03-11 22:11:50 +01:00
wp_send_json_error( array( 'notice' => __( 'Invalid email address.', 'fcnen' ) ) );
2024-03-11 02:51:58 +01:00
}
2024-03-13 03:30:50 +01:00
// Sanitize
2024-03-13 19:22:30 +01:00
if ( get_option( 'fcnen_flag_subscribe_to_stories' ) ) {
2024-03-14 03:24:14 +01:00
$post_ids = fcnen_prepare_id_array( $post_ids );
2024-03-13 19:22:30 +01:00
} else {
$post_ids = [];
}
if ( get_option( 'fcnen_flag_subscribe_to_taxonomies' ) ) {
2024-03-14 03:24:14 +01:00
$categories = fcnen_prepare_id_array( $categories );
$tags = fcnen_prepare_id_array( $tags );
$taxonomies = fcnen_prepare_id_array( $taxonomies );
2024-03-13 19:22:30 +01:00
} else {
$categories = [];
$tags = [];
$taxonomies = [];
}
2024-03-13 18:07:27 +01:00
2024-03-11 10:22:59 +01:00
// Arguments
$args = array(
2024-03-12 01:45:16 +01:00
'scope-everything' => $scope_everything,
'scope-posts' => $scope_posts,
'scope-stories' => $scope_stories,
2024-03-13 03:30:50 +01:00
'scope-chapters' => $scope_chapters,
2024-03-13 18:07:27 +01:00
'post_ids' => $post_ids,
'categories' => $categories,
'tags' => $tags,
'taxonomies' => $taxonomies
2024-03-11 10:22:59 +01:00
);
2024-03-11 02:51:58 +01:00
// New or update?
2024-03-11 22:11:50 +01:00
$is_new_subscriber = ! fcnen_subscriber_exists( $email );
2024-03-11 10:22:59 +01:00
// New subscriber!
if ( $is_new_subscriber ) {
2024-03-11 22:11:50 +01:00
$result = fcnen_add_subscriber( $email, $args );
2024-03-11 10:22:59 +01:00
}
// Update subscriber!
if ( ! $is_new_subscriber ) {
// Code?
if ( ! $code ) {
2024-03-11 22:11:50 +01:00
$notice = WP_DEBUG ? __( 'Code missing.', 'fcnen' ) : $default_notice;
2024-03-11 10:22:59 +01:00
wp_send_json_error( array( 'notice' => $notice ) );
}
// Query subscriber
2024-03-11 22:11:50 +01:00
$subscriber = fcnen_get_subscriber_by_email_and_code( $email, $code );
2024-03-11 10:22:59 +01:00
// Code did not match email
if ( empty( $subscriber ) ) {
2024-03-11 22:11:50 +01:00
$notice = WP_DEBUG ? __( 'Code did not match email.', 'fcnen' ) : $default_notice;
2024-03-11 10:22:59 +01:00
wp_send_json_error( array( 'notice' => $notice ) );
}
// Update
2024-03-11 22:11:50 +01:00
$result = fcnen_update_subscriber( $email, $args );
2024-03-11 02:51:58 +01:00
}
// Response
if ( $result ) {
2024-03-11 10:22:59 +01:00
wp_send_json_success( array( 'notice' => $default_notice ) );
2024-03-11 02:51:58 +01:00
} else {
2024-03-11 22:11:50 +01:00
$notice = WP_DEBUG ? __( 'Could not create or update subscription.', 'fcnen' ) : $default_notice;
2024-03-11 14:08:41 +01:00
// Do not expose informative errors to strangers
wp_send_json_success( array( 'notice' => $notice ) );
2024-03-11 02:51:58 +01:00
}
}
2024-03-13 14:18:53 +01:00
add_action( 'wp_ajax_fictioneer_ajax_fcnen_subscribe_or_update', 'fictioneer_ajax_fcnen_subscribe_or_update' );
add_action( 'wp_ajax_nopriv_fictioneer_ajax_fcnen_subscribe_or_update', 'fictioneer_ajax_fcnen_subscribe_or_update' );
2024-03-11 14:08:41 +01:00
/**
* AJAX callback to unsubscribe
*
2024-03-13 14:18:53 +01:00
* Note: The "fictioneer_ajax_" prefix enables the plugin skipping
* in the theme's must-use-plugin.
*
2024-03-11 14:08:41 +01:00
* @since 0.1.0
*/
2024-03-13 14:18:53 +01:00
function fictioneer_ajax_fcnen_unsubscribe() {
2024-03-11 14:08:41 +01:00
// Verify
if ( ! wp_doing_ajax() ) {
2024-03-11 22:11:50 +01:00
wp_send_json_error( __( 'Invalid request.', 'fcnen' ) );
2024-03-11 14:08:41 +01:00
}
2024-03-11 22:11:50 +01:00
if ( ! check_ajax_referer( 'fcnen-subscribe', 'nonce', false ) ) {
2024-03-11 14:08:41 +01:00
wp_send_json_error(
2024-03-11 22:11:50 +01:00
array( 'notice' => __( 'Nonce verification failed. Please reload and try again.', 'fcnen' ) )
2024-03-11 14:08:41 +01:00
);
}
// Setup
$email = sanitize_email( $_POST['email'] ?? '' );
$code = sanitize_text_field( $_POST['code'] ?? '' );
2024-03-11 22:11:50 +01:00
$default_notice = __( 'Successfully unsubscribed.', 'fcnen' );
2024-03-11 14:08:41 +01:00
$result = false;
// Validate email
if ( empty( $email ) || ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
2024-03-11 22:11:50 +01:00
wp_send_json_error( array( 'notice' => __( 'Invalid email address.', 'fcnen' ) ) );
2024-03-11 14:08:41 +01:00
}
// Email and code present?
if ( empty( $email ) || empty( $code ) ) {
2024-03-11 22:11:50 +01:00
wp_send_json_error( array( 'notice' => __( 'Email or code missing.', 'fcnen' ) ) );
2024-03-11 14:08:41 +01:00
}
// Query subscriber
2024-03-11 22:11:50 +01:00
$subscriber = fcnen_get_subscriber_by_email_and_code( $email, $code );
2024-03-11 14:08:41 +01:00
// Match found...
if ( ! $subscriber ) {
// ... no match
2024-03-11 22:11:50 +01:00
$notice = WP_DEBUG ? __( 'No matching subscription found.', 'fcnen' ) : $default_notice;
2024-03-11 14:08:41 +01:00
// Do not expose informative errors to strangers
wp_send_json_success( array( 'notice' => $notice ) );
} else {
// ... found
2024-03-11 22:11:50 +01:00
$result = fcnen_delete_subscriber( $email );
2024-03-11 14:08:41 +01:00
}
// Response
if ( $result ) {
wp_send_json_success( array( 'notice' => $default_notice ) );
} else {
2024-03-11 22:11:50 +01:00
$notice = WP_DEBUG ? __( 'Could not delete subscription.', 'fcnen' ) : $default_notice;
2024-03-11 14:08:41 +01:00
// Do not expose informative errors to strangers
wp_send_json_success( array( 'notice' => $notice ) );
}
}
2024-03-13 14:18:53 +01:00
add_action( 'wp_ajax_fictioneer_ajax_fcnen_unsubscribe', 'fictioneer_ajax_fcnen_unsubscribe' );
add_action( 'wp_ajax_nopriv_fictioneer_ajax_fcnen_unsubscribe', 'fictioneer_ajax_fcnen_unsubscribe' );
2024-03-13 00:25:05 +01:00
/**
* AJAX callback to search content
*
2024-03-13 14:18:53 +01:00
* Note: The "fictioneer_ajax_" prefix enables the plugin skipping
* in the theme's must-use-plugin.
*
2024-03-13 00:25:05 +01:00
* @since 0.1.0
*/
2024-03-13 14:18:53 +01:00
function fictioneer_ajax_fcnen_search_content() {
2024-03-13 00:25:05 +01:00
// Verify
if ( ! wp_doing_ajax() ) {
wp_send_json_error( __( 'Invalid request.', 'fcnen' ) );
}
if ( ! check_ajax_referer( 'fcnen-subscribe', 'nonce', false ) ) {
wp_send_json_error(
array( 'notice' => __( 'Nonce verification failed. Please reload and try again.', 'fcnen' ) )
);
}
// Setup
2024-03-13 14:09:43 +01:00
$filter = sanitize_text_field( $_REQUEST['filter'] ?? '' );
2024-03-13 00:25:05 +01:00
$search = sanitize_text_field( $_REQUEST['search'] ?? '' );
$page = absint( $_REQUEST['page'] ?? 1 );
2024-03-13 17:44:28 +01:00
$stories = null;
2024-06-29 19:29:24 +02:00
$terms = null;
2024-03-13 00:25:05 +01:00
$output = [];
2024-03-13 16:01:34 +01:00
// Query stories
2024-03-13 19:22:30 +01:00
if ( $filter === 'story' && get_option( 'fcnen_flag_subscribe_to_stories' ) ) {
$search_args = array(
'post_type' => 'fcn_story',
'post_status' => 'publish',
'orderby' => 'relevance modified',
'order' => 'desc',
'posts_per_page' => 25,
'paged' => $page,
's' => $search,
'update_post_meta_cache' => true, // We might need that
'update_post_term_cache' => false // Improve performance
2024-03-13 01:21:09 +01:00
);
if ( ! $search ) {
$search_args['orderby'] = 'modified';
}
$stories = new WP_Query( $search_args );
2024-03-13 17:44:28 +01:00
// Build and add items
foreach ( $stories->posts as $item ) {
// Add to output
2024-03-13 21:26:35 +01:00
$output[] = fcnen_get_source_node(
array(
'name' => 'post_id',
'type' => 'fcn_story',
'id' => $item->ID,
'label' => _x( 'Story', 'List item label.', 'fcnen' ),
'title' => fictioneer_get_safe_title( $item, 'fcnen-search-stories' )
)
);
2024-03-13 17:44:28 +01:00
}
}
// Query taxonomies
2024-03-13 19:22:30 +01:00
if ( $filter === 'taxonomies' && get_option( 'fcnen_flag_subscribe_to_taxonomies' ) ) {
2024-03-13 17:44:28 +01:00
$terms = get_terms(
array(
'taxonomy' => ['category', 'post_tag', 'fcn_genre', 'fcn_fandom', 'fcn_character', 'fcn_content_warning'],
'name__like' => $search,
'hide_empty' => false,
2024-06-29 19:29:24 +02:00
'number' => 51, // Paginate (if >50, this means there are still terms to query)
'offset' => ( $page - 1 ) * 50, // Paginate
2024-03-13 17:44:28 +01:00
'update_term_meta_cache' => false // Improve performance
)
);
// Build and add items
foreach ( $terms as $term ) {
$taxonomy = fcnen_get_term_html_attribute( $term->taxonomy );
2024-03-13 01:21:09 +01:00
// Add to output
2024-03-13 21:26:35 +01:00
$output[] = fcnen_get_source_node(
array(
'name' => $taxonomy,
'type' => $taxonomy,
'id' => $term->term_id,
'label' => fcnen_get_term_label( $term->taxonomy ),
'title' => $term->name
)
);
2024-03-13 01:21:09 +01:00
}
}
2024-03-13 10:40:34 +01:00
// Add observer?
2024-06-29 19:29:24 +02:00
if (
( $stories && $page < $stories->max_num_pages ) ||
( $terms && count( $terms ) > 50 )
) {
2024-03-13 10:40:34 +01:00
$page++;
$observer = '<li class="fcnen-dialog-modal__advanced-li _observer" data-target="fcnen-observer-item" data-page="' . $page . '"><i class="fa-solid fa-spinner fa-spin" style="--fa-animation-duration: .8s;"></i> ' . __( 'Loading…', 'fcnen' ) . '<span></span></li>';
$output[] = $observer;
}
// No results?
if ( empty( $output ) ) {
$no_matches = '<li class="fcnen-dialog-modal__advanced-li _disabled _no-match"><span>' . __( 'No matches found.', 'fcnen' ) . '</span></li>';
$output[] = $no_matches;
}
2024-03-13 00:25:05 +01:00
// Response
wp_send_json_success(
array(
'html' => implode( '', $output )
)
);
}
2024-03-13 14:18:53 +01:00
add_action( 'wp_ajax_fictioneer_ajax_fcnen_search_content', 'fictioneer_ajax_fcnen_search_content' );
add_action( 'wp_ajax_nopriv_fictioneer_ajax_fcnen_search_content', 'fictioneer_ajax_fcnen_search_content' );
2024-03-30 15:58:44 +01:00
2024-05-05 15:34:57 +02:00
// =============================================================================
// ADMIN
// =============================================================================
2024-03-30 15:58:44 +01:00
/**
* AJAX callback to process email queue
*
* Note: The "fictioneer_ajax_" prefix enables the plugin skipping
* in the theme's must-use-plugin.
*
* @since 0.1.0
*/
function fictioneer_ajax_fcnen_process_email_queue() {
// Verify
if ( ! wp_doing_ajax() ) {
wp_send_json_error(
array( 'error' => __( 'Invalid request.', 'fcnen' ) )
);
}
if ( ! check_ajax_referer( 'fcnen-process-email-queue', 'fcnen_queue_nonce', false ) ) {
wp_send_json_error(
array( 'error' => __( 'Nonce verification failed. Please reload and try again.', 'fcnen' ) )
);
}
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error(
2024-05-05 15:34:57 +02:00
array( 'error' => __( 'Insufficient permissions.', 'fcnen' ) )
2024-03-30 15:58:44 +01:00
);
}
// Setup
$index = absint( $_REQUEST['index'] ?? 0 );
2024-05-06 23:43:05 +02:00
$new = absint( $_REQUEST['new'] ?? 0 );
2024-03-30 15:58:44 +01:00
// Process
2024-05-06 23:43:05 +02:00
$result = fcnen_process_email_queue( $index, $new );
2024-03-30 15:58:44 +01:00
// Response
2024-05-06 23:43:05 +02:00
wp_send_json_success( $result );
2024-03-30 15:58:44 +01:00
}
add_action( 'wp_ajax_fictioneer_ajax_fcnen_process_email_queue', 'fictioneer_ajax_fcnen_process_email_queue' );
2024-05-31 01:12:35 +02:00
// =============================================================================
// FOLLOWS
// =============================================================================
/**
* AJAX Hook: Toggle story subscription by Follow
*
* @since 0.1.0
* @global wpdb $wpdb The WordPress database object.
*
* @param int $story_id ID of the toggled story Follow.
* @param bool $force Whether the Follow was added or removed.
*/
function fcnen_subscribe_by_follow( $story_id, $force ) {
global $wpdb;
// Setup
$table_name = $wpdb->prefix . 'fcnen_subscribers';
$user = wp_get_current_user();
$auth_email = get_user_meta( $user->ID, 'fcnen_subscription_email', true );
$auth_code = get_user_meta( $user->ID, 'fcnen_subscription_code', true );
// Subscription linked in profile?
if ( ! $auth_email || ! $auth_code || ! get_user_meta( $user->ID, 'fcnen_enable_subscribe_by_follow', true ) ) {
return;
}
// Valid subscriber?
$subscriber = fcnen_get_subscriber_by_email_and_code( $auth_email, $auth_code );
if ( ! $subscriber ) {
return;
}
// Update subscription post IDs
$stories = maybe_unserialize( $subscriber->post_ids );
if ( $force ) {
// Add story
$stories[] = strval( $story_id );
$stories = array_unique( $stories );
} else {
// Remove story (if set)
if ( ( $key = array_search( $story_id, $stories ) ) !== false ) {
unset( $stories[ $key ] );
}
}
// Update database
$wpdb->update(
$table_name,
array( 'post_ids' => serialize( $stories ) ),
array( 'email' => $auth_email ),
['%s'],
['%s']
);
}
2024-05-31 15:57:53 +02:00
if ( get_option( 'fictioneer_enable_follows' ) ) {
add_action( 'fictioneer_toggled_follow', 'fcnen_subscribe_by_follow', 10, 2 );
}