Make actions/filter no longer pluggable
You can remove them anyway, no need to sacrifice CPU cycles for this.
This commit is contained in:
parent
6f6b591543
commit
373baa55c9
@ -165,37 +165,35 @@ if ( FICTIONEER_RELATIONSHIP_PURGE_ASSIST ) {
|
||||
// REMEMBER WHEN CHAPTERS OF STORIES HAVE BEEN MODIFIED
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_remember_chapters_modified' ) ) {
|
||||
/**
|
||||
* Update story ACF field when associated chapter is updated
|
||||
*
|
||||
* The difference to the modified date is that this field is only updated when
|
||||
* the chapters list changes, not when a chapter or story is updated in general.
|
||||
*
|
||||
* @since 4.0
|
||||
* @link https://www.advancedcustomfields.com/resources/acf-update_value/
|
||||
*
|
||||
* @param mixed $value The field value.
|
||||
* @param int|string $post_id The post ID where the value is saved.
|
||||
*
|
||||
* @return mixed The modified value.
|
||||
*/
|
||||
/**
|
||||
* Update story ACF field when associated chapter is updated
|
||||
*
|
||||
* The difference to the modified date is that this field is only updated when
|
||||
* the chapters list changes, not when a chapter or story is updated in general.
|
||||
*
|
||||
* @since 4.0
|
||||
* @link https://www.advancedcustomfields.com/resources/acf-update_value/
|
||||
*
|
||||
* @param mixed $value The field value.
|
||||
* @param int|string $post_id The post ID where the value is saved.
|
||||
*
|
||||
* @return mixed The modified value.
|
||||
*/
|
||||
|
||||
function fictioneer_remember_chapters_modified( $value, $post_id ) {
|
||||
$previous = fictioneer_get_field( 'fictioneer_story_chapters', $post_id );
|
||||
$previous = is_array( $previous ) ? $previous : [];
|
||||
$new = is_array( $value ) ? $value : [];
|
||||
function fictioneer_remember_chapters_modified( $value, $post_id ) {
|
||||
$previous = fictioneer_get_field( 'fictioneer_story_chapters', $post_id );
|
||||
$previous = is_array( $previous ) ? $previous : [];
|
||||
$new = is_array( $value ) ? $value : [];
|
||||
|
||||
if ( $previous !== $value ) {
|
||||
update_post_meta( $post_id, 'fictioneer_chapters_modified', current_time( 'mysql' ) );
|
||||
}
|
||||
|
||||
if ( count( $previous ) < count( $new ) ) {
|
||||
update_post_meta( $post_id, 'fictioneer_chapters_added', current_time( 'mysql' ) );
|
||||
}
|
||||
|
||||
return $value;
|
||||
if ( $previous !== $value ) {
|
||||
update_post_meta( $post_id, 'fictioneer_chapters_modified', current_time( 'mysql' ) );
|
||||
}
|
||||
|
||||
if ( count( $previous ) < count( $new ) ) {
|
||||
update_post_meta( $post_id, 'fictioneer_chapters_added', current_time( 'mysql' ) );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
add_filter( 'acf/update_value/name=fictioneer_story_chapters', 'fictioneer_remember_chapters_modified', 10, 2 );
|
||||
|
||||
|
@ -203,103 +203,101 @@ add_filter( 'removable_query_args', 'fictioneer_removable_args' );
|
||||
// LIMIT DEFAULT BLOCKS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_allowed_block_types' ) ) {
|
||||
/**
|
||||
* Limit the available default blocks
|
||||
*
|
||||
* Fictioneer is has a particular and delicate content section, built around and
|
||||
* for the main purpose of displaying prose. Other features, such as the ePUB
|
||||
* converter heavily depend on _expected_ input or may break. There are certainly
|
||||
* more possible but the initial selection has been chosen carefully.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
/**
|
||||
* Limit the available default blocks
|
||||
*
|
||||
* Fictioneer is has a particular and delicate content section, built around and
|
||||
* for the main purpose of displaying prose. Other features, such as the ePUB
|
||||
* converter heavily depend on _expected_ input or may break. There are certainly
|
||||
* more possible but the initial selection has been chosen carefully.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
|
||||
function fictioneer_allowed_block_types() {
|
||||
$allowed = array(
|
||||
// WP Core
|
||||
'core/image',
|
||||
'core/paragraph',
|
||||
'core/heading',
|
||||
'core/list',
|
||||
'core/list-item',
|
||||
'core/gallery',
|
||||
'core/quote',
|
||||
'core/pullquote',
|
||||
'core/buttons',
|
||||
'core/button',
|
||||
'core/audio',
|
||||
'core/file',
|
||||
'core/video',
|
||||
'core/table',
|
||||
'core/code',
|
||||
'core/preformatted',
|
||||
'core/html',
|
||||
'core/separator',
|
||||
'core/spacer',
|
||||
'core/more',
|
||||
'core/embed',
|
||||
'core-embed/twitter',
|
||||
'core-embed/youtube',
|
||||
'core-embed/soundcloud',
|
||||
'core-embed/spotify',
|
||||
'core-embed/vimeo',
|
||||
// Known plugins
|
||||
'cloudinary/gallery',
|
||||
'jetpack/business-hours',
|
||||
'jetpack/button',
|
||||
'jetpack/calendly',
|
||||
'jetpack/contact-form',
|
||||
'jetpack/field-text',
|
||||
'jetpack/field-name',
|
||||
'jetpack/field-email',
|
||||
'jetpack/field-url',
|
||||
'jetpack/field-date',
|
||||
'jetpack/field-telephone',
|
||||
'jetpack/field-textarea',
|
||||
'jetpack/field-checkbox',
|
||||
'jetpack/field-consent',
|
||||
'jetpack/field-checkbox-multiple',
|
||||
'jetpack/field-radio',
|
||||
'jetpack/field-select',
|
||||
'jetpack/contact-info',
|
||||
'jetpack/address',
|
||||
'jetpack/email',
|
||||
'jetpack/phone',
|
||||
'jetpack/eventbrite',
|
||||
'jetpack/gif',
|
||||
'jetpack/google-calendar',
|
||||
'jetpack/image-compare',
|
||||
'jetpack/instagram-gallery',
|
||||
'jetpack/mailchimp',
|
||||
'jetpack/map',
|
||||
'jetpack/markdown',
|
||||
'jetpack/opentable',
|
||||
'jetpack/pinterest',
|
||||
'jetpack/podcast-player',
|
||||
'jetpack/rating-star',
|
||||
'jetpack/recurring-payments',
|
||||
'jetpack/repeat-visitor',
|
||||
'jetpack/revue',
|
||||
'jetpack/send-a-message',
|
||||
'jetpack/whatsapp-button',
|
||||
'jetpack/slideshow',
|
||||
'jetpack/story',
|
||||
'jetpack/subscriptions',
|
||||
'jetpack/tiled-gallery',
|
||||
'jetpack/payments-intro',
|
||||
'jetpack/payment-buttons'
|
||||
);
|
||||
function fictioneer_allowed_block_types() {
|
||||
$allowed = array(
|
||||
// WP Core
|
||||
'core/image',
|
||||
'core/paragraph',
|
||||
'core/heading',
|
||||
'core/list',
|
||||
'core/list-item',
|
||||
'core/gallery',
|
||||
'core/quote',
|
||||
'core/pullquote',
|
||||
'core/buttons',
|
||||
'core/button',
|
||||
'core/audio',
|
||||
'core/file',
|
||||
'core/video',
|
||||
'core/table',
|
||||
'core/code',
|
||||
'core/preformatted',
|
||||
'core/html',
|
||||
'core/separator',
|
||||
'core/spacer',
|
||||
'core/more',
|
||||
'core/embed',
|
||||
'core-embed/twitter',
|
||||
'core-embed/youtube',
|
||||
'core-embed/soundcloud',
|
||||
'core-embed/spotify',
|
||||
'core-embed/vimeo',
|
||||
// Known plugins
|
||||
'cloudinary/gallery',
|
||||
'jetpack/business-hours',
|
||||
'jetpack/button',
|
||||
'jetpack/calendly',
|
||||
'jetpack/contact-form',
|
||||
'jetpack/field-text',
|
||||
'jetpack/field-name',
|
||||
'jetpack/field-email',
|
||||
'jetpack/field-url',
|
||||
'jetpack/field-date',
|
||||
'jetpack/field-telephone',
|
||||
'jetpack/field-textarea',
|
||||
'jetpack/field-checkbox',
|
||||
'jetpack/field-consent',
|
||||
'jetpack/field-checkbox-multiple',
|
||||
'jetpack/field-radio',
|
||||
'jetpack/field-select',
|
||||
'jetpack/contact-info',
|
||||
'jetpack/address',
|
||||
'jetpack/email',
|
||||
'jetpack/phone',
|
||||
'jetpack/eventbrite',
|
||||
'jetpack/gif',
|
||||
'jetpack/google-calendar',
|
||||
'jetpack/image-compare',
|
||||
'jetpack/instagram-gallery',
|
||||
'jetpack/mailchimp',
|
||||
'jetpack/map',
|
||||
'jetpack/markdown',
|
||||
'jetpack/opentable',
|
||||
'jetpack/pinterest',
|
||||
'jetpack/podcast-player',
|
||||
'jetpack/rating-star',
|
||||
'jetpack/recurring-payments',
|
||||
'jetpack/repeat-visitor',
|
||||
'jetpack/revue',
|
||||
'jetpack/send-a-message',
|
||||
'jetpack/whatsapp-button',
|
||||
'jetpack/slideshow',
|
||||
'jetpack/story',
|
||||
'jetpack/subscriptions',
|
||||
'jetpack/tiled-gallery',
|
||||
'jetpack/payments-intro',
|
||||
'jetpack/payment-buttons'
|
||||
);
|
||||
|
||||
if (
|
||||
! get_option( 'fictioneer_strip_shortcodes_for_non_administrators' ) ||
|
||||
current_user_can( 'administrator' )
|
||||
) {
|
||||
$allowed[] = 'core/shortcode';
|
||||
}
|
||||
|
||||
return $allowed;
|
||||
if (
|
||||
! get_option( 'fictioneer_strip_shortcodes_for_non_administrators' ) ||
|
||||
current_user_can( 'administrator' )
|
||||
) {
|
||||
$allowed[] = 'core/shortcode';
|
||||
}
|
||||
|
||||
return $allowed;
|
||||
}
|
||||
|
||||
if ( ! get_option( 'fictioneer_enable_all_blocks' ) ) {
|
||||
@ -377,27 +375,25 @@ if ( get_option( 'fictioneer_admin_reduce_subscriber_profile' ) ) {
|
||||
// LIMIT AUTHORS TO OWN POSTS/PAGES
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_limit_authors_to_own_posts_and_pages' ) ) {
|
||||
/**
|
||||
* Limit authors to own posts and pages
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
/**
|
||||
* Limit authors to own posts and pages
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_limit_authors_to_own_posts_and_pages( $query ) {
|
||||
global $pagenow;
|
||||
function fictioneer_limit_authors_to_own_posts_and_pages( $query ) {
|
||||
global $pagenow;
|
||||
|
||||
// Abort conditions...
|
||||
if ( ! $query->is_admin || 'edit.php' != $pagenow ) return $query;
|
||||
// Abort conditions...
|
||||
if ( ! $query->is_admin || 'edit.php' != $pagenow ) return $query;
|
||||
|
||||
// Add author to query unless user is supposed to see other posts/pages
|
||||
if ( ! current_user_can( 'edit_others_posts' ) ) {
|
||||
$query->set( 'author', get_current_user_id() );
|
||||
}
|
||||
|
||||
// Return modified query
|
||||
return $query;
|
||||
// Add author to query unless user is supposed to see other posts/pages
|
||||
if ( ! current_user_can( 'edit_others_posts' ) ) {
|
||||
$query->set( 'author', get_current_user_id() );
|
||||
}
|
||||
|
||||
// Return modified query
|
||||
return $query;
|
||||
}
|
||||
add_filter( 'pre_get_posts', 'fictioneer_limit_authors_to_own_posts_and_pages' );
|
||||
|
||||
|
@ -34,132 +34,130 @@ if ( ! function_exists( 'fictioneer_discord_send_message' ) ) {
|
||||
// POST COMMENT TO DISCORD
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_post_comment_to_discord' ) ) {
|
||||
/**
|
||||
* Sends a comment as message to a Discord channel
|
||||
*
|
||||
* @since 4.0
|
||||
* @see fictioneer_discord_send_message()
|
||||
*
|
||||
* @param int $comment_id The comment ID.
|
||||
* @param int|string $comment_approved 1 if the comment is approved, 0 if not, 'spam' if spam.
|
||||
*/
|
||||
/**
|
||||
* Sends a comment as message to a Discord channel
|
||||
*
|
||||
* @since 4.0
|
||||
* @see fictioneer_discord_send_message()
|
||||
*
|
||||
* @param int $comment_id The comment ID.
|
||||
* @param int|string $comment_approved 1 if the comment is approved, 0 if not, 'spam' if spam.
|
||||
*/
|
||||
|
||||
function fictioneer_post_comment_to_discord( $comment_id, $comment_approved ) {
|
||||
// Exit conditions
|
||||
if ( empty( get_option( 'fictioneer_discord_channel_comments_webhook' ) ) ) return;
|
||||
function fictioneer_post_comment_to_discord( $comment_id, $comment_approved ) {
|
||||
// Exit conditions
|
||||
if ( empty( get_option( 'fictioneer_discord_channel_comments_webhook' ) ) ) return;
|
||||
|
||||
// Setup
|
||||
$comment = get_comment( $comment_id );
|
||||
$comment_type = ucfirst( get_comment_type( $comment_id ) );
|
||||
$comment_status = wp_get_comment_status( $comment );
|
||||
$comment_avatar_url = get_avatar_url( $comment );
|
||||
$post = get_post( $comment->comment_post_ID );
|
||||
$user = get_user_by( 'id', $comment->user_id );
|
||||
// Setup
|
||||
$comment = get_comment( $comment_id );
|
||||
$comment_type = ucfirst( get_comment_type( $comment_id ) );
|
||||
$comment_status = wp_get_comment_status( $comment );
|
||||
$comment_avatar_url = get_avatar_url( $comment );
|
||||
$post = get_post( $comment->comment_post_ID );
|
||||
$user = get_user_by( 'id', $comment->user_id );
|
||||
|
||||
if ( $user && ! empty( $user->fictioneer_external_avatar_url ) ) {
|
||||
$comment_avatar_url = $user->fictioneer_external_avatar_url;
|
||||
}
|
||||
if ( $user && ! empty( $user->fictioneer_external_avatar_url ) ) {
|
||||
$comment_avatar_url = $user->fictioneer_external_avatar_url;
|
||||
}
|
||||
|
||||
// Message
|
||||
$message = array(
|
||||
'content' => null,
|
||||
'username' => _x( 'Comment Stream', 'Discord message bot name.', 'fictioneer' ),
|
||||
'embeds' => array(
|
||||
array(
|
||||
'title' => html_entity_decode( get_the_title( $post ) ),
|
||||
'description' => html_entity_decode( get_comment_excerpt( $comment ) ),
|
||||
'url' => get_comment_link( $comment ),
|
||||
'color' => $comment_status == 'approved' ? '9692513' : '14112322',
|
||||
'fields' => array(
|
||||
array(
|
||||
'name' => _x( 'Status', 'Discord message "Status" field.', 'fictioneer' ),
|
||||
'value' => ucfirst( $comment_status ),
|
||||
'inline' => true
|
||||
),
|
||||
array(
|
||||
'name' => _x( 'Comment ID', 'Discord message "Comment ID" field.', 'fictioneer' ),
|
||||
'value' => $comment_id,
|
||||
'inline' => true
|
||||
)
|
||||
// Message
|
||||
$message = array(
|
||||
'content' => null,
|
||||
'username' => _x( 'Comment Stream', 'Discord message bot name.', 'fictioneer' ),
|
||||
'embeds' => array(
|
||||
array(
|
||||
'title' => html_entity_decode( get_the_title( $post ) ),
|
||||
'description' => html_entity_decode( get_comment_excerpt( $comment ) ),
|
||||
'url' => get_comment_link( $comment ),
|
||||
'color' => $comment_status == 'approved' ? '9692513' : '14112322',
|
||||
'fields' => array(
|
||||
array(
|
||||
'name' => _x( 'Status', 'Discord message "Status" field.', 'fictioneer' ),
|
||||
'value' => ucfirst( $comment_status ),
|
||||
'inline' => true
|
||||
),
|
||||
'author' => array(
|
||||
'name' => $comment->comment_author,
|
||||
'icon_url' => $comment_avatar_url
|
||||
),
|
||||
'timestamp' => date_format( date_create( $comment->comment_date ), 'c' )
|
||||
)
|
||||
array(
|
||||
'name' => _x( 'Comment ID', 'Discord message "Comment ID" field.', 'fictioneer' ),
|
||||
'value' => $comment_id,
|
||||
'inline' => true
|
||||
)
|
||||
),
|
||||
'author' => array(
|
||||
'name' => $comment->comment_author,
|
||||
'icon_url' => $comment_avatar_url
|
||||
),
|
||||
'timestamp' => date_format( date_create( $comment->comment_date ), 'c' )
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// Has parent comment?
|
||||
if ( $comment->comment_parent ) {
|
||||
$message['embeds'][0]['fields'][] = array(
|
||||
'name' => _x( 'Reply to', 'Discord message "Reply to" field.', 'fictioneer' ),
|
||||
'value' => get_comment( $comment->comment_parent )->comment_author,
|
||||
'inline' => true
|
||||
);
|
||||
} else {
|
||||
$message['embeds'][0]['fields'][] = array(
|
||||
'name' => _x( 'Reply to', 'Discord message "Reply to" field.', 'fictioneer' ),
|
||||
'value' => __( 'n/a', 'fictioneer' ),
|
||||
'inline' => true
|
||||
);
|
||||
}
|
||||
|
||||
// Is chapter with story?
|
||||
$story_id = fictioneer_get_field( 'fictioneer_chapter_story', $post->ID );
|
||||
|
||||
if ( $story_id ) {
|
||||
$message['embeds'][0]['footer'] = array(
|
||||
'text' => sprintf(
|
||||
_x( 'Story: %s', 'Discord message footer note.', 'fictioneer' ),
|
||||
get_the_title( $story_id )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Has parent comment?
|
||||
if ( $comment->comment_parent ) {
|
||||
$message['embeds'][0]['fields'][] = array(
|
||||
'name' => _x( 'Reply to', 'Discord message "Reply to" field.', 'fictioneer' ),
|
||||
'value' => get_comment( $comment->comment_parent )->comment_author,
|
||||
'inline' => true
|
||||
);
|
||||
} else {
|
||||
$message['embeds'][0]['fields'][] = array(
|
||||
'name' => _x( 'Reply to', 'Discord message "Reply to" field.', 'fictioneer' ),
|
||||
'value' => __( 'n/a', 'fictioneer' ),
|
||||
'inline' => true
|
||||
);
|
||||
}
|
||||
// Registered user?
|
||||
if ( $user ) {
|
||||
// Registered
|
||||
$role = translate_user_role( wp_roles()->roles[ $user->roles[0] ]['name'] );
|
||||
|
||||
// Is chapter with story?
|
||||
$story_id = fictioneer_get_field( 'fictioneer_chapter_story', $post->ID );
|
||||
|
||||
if ( $story_id ) {
|
||||
$message['embeds'][0]['footer'] = array(
|
||||
'text' => sprintf(
|
||||
_x( 'Story: %s', 'Discord message footer note.', 'fictioneer' ),
|
||||
get_the_title( $story_id )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Registered user?
|
||||
if ( $user ) {
|
||||
// Registered
|
||||
$role = translate_user_role( wp_roles()->roles[ $user->roles[0] ]['name'] );
|
||||
|
||||
$message['embeds'][0]['fields'][] = array(
|
||||
'name' => _x( 'User Role', 'Discord message "User Role" field.', 'fictioneer' ),
|
||||
'value' => $role,
|
||||
'inline' => true
|
||||
);
|
||||
|
||||
$message['embeds'][0]['fields'][] = array(
|
||||
'name' => _x( 'User ID', 'Discord message "User ID" field.', 'fictioneer' ),
|
||||
'value' => $comment->user_id,
|
||||
'inline' => true
|
||||
);
|
||||
} else {
|
||||
// Not registered
|
||||
$message['embeds'][0]['fields'][] = array(
|
||||
'name' => _x( 'User Role', 'Discord message "User Role" field.', 'fictioneer' ),
|
||||
'value' => __( 'Guest', 'fictioneer' ),
|
||||
'inline' => true
|
||||
);
|
||||
|
||||
$message['embeds'][0]['fields'][] = array(
|
||||
'name' => _x( 'User ID', 'Discord message "User ID" field.', 'fictioneer' ),
|
||||
'value' => __( 'n/a', 'fictioneer' ),
|
||||
'inline' => true
|
||||
);
|
||||
}
|
||||
|
||||
// Comment type
|
||||
$message['embeds'][0]['fields'][] = array(
|
||||
'name' => _x( 'Type', 'Discord message comment "Type" field.', 'fictioneer' ),
|
||||
'value' => $comment_type,
|
||||
'name' => _x( 'User Role', 'Discord message "User Role" field.', 'fictioneer' ),
|
||||
'value' => $role,
|
||||
'inline' => true
|
||||
);
|
||||
|
||||
// Send to Discord
|
||||
fictioneer_discord_send_message( get_option( 'fictioneer_discord_channel_comments_webhook' ), $message );
|
||||
$message['embeds'][0]['fields'][] = array(
|
||||
'name' => _x( 'User ID', 'Discord message "User ID" field.', 'fictioneer' ),
|
||||
'value' => $comment->user_id,
|
||||
'inline' => true
|
||||
);
|
||||
} else {
|
||||
// Not registered
|
||||
$message['embeds'][0]['fields'][] = array(
|
||||
'name' => _x( 'User Role', 'Discord message "User Role" field.', 'fictioneer' ),
|
||||
'value' => __( 'Guest', 'fictioneer' ),
|
||||
'inline' => true
|
||||
);
|
||||
|
||||
$message['embeds'][0]['fields'][] = array(
|
||||
'name' => _x( 'User ID', 'Discord message "User ID" field.', 'fictioneer' ),
|
||||
'value' => __( 'n/a', 'fictioneer' ),
|
||||
'inline' => true
|
||||
);
|
||||
}
|
||||
|
||||
// Comment type
|
||||
$message['embeds'][0]['fields'][] = array(
|
||||
'name' => _x( 'Type', 'Discord message comment "Type" field.', 'fictioneer' ),
|
||||
'value' => $comment_type,
|
||||
'inline' => true
|
||||
);
|
||||
|
||||
// Send to Discord
|
||||
fictioneer_discord_send_message( get_option( 'fictioneer_discord_channel_comments_webhook' ), $message );
|
||||
}
|
||||
add_action( 'comment_post', 'fictioneer_post_comment_to_discord', 99, 2 );
|
||||
|
||||
|
@ -4,16 +4,14 @@
|
||||
// ADD ROUTE
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_add_epub_download_endpoint' ) ) {
|
||||
/**
|
||||
* Add route to ePUB script
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*/
|
||||
/**
|
||||
* Add route to ePUB script
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*/
|
||||
|
||||
function fictioneer_add_epub_download_endpoint() {
|
||||
add_rewrite_endpoint( FICTIONEER_EPUB_ENDPOINT, EP_ROOT );
|
||||
}
|
||||
function fictioneer_add_epub_download_endpoint() {
|
||||
add_rewrite_endpoint( FICTIONEER_EPUB_ENDPOINT, EP_ROOT );
|
||||
}
|
||||
add_action( 'init', 'fictioneer_add_epub_download_endpoint', 10 );
|
||||
|
||||
|
@ -4,219 +4,217 @@
|
||||
// CONTACT FORM SUBMIT - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_submit_contact_form' ) ) {
|
||||
/**
|
||||
* Submit comment form via AJAX
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
*/
|
||||
/**
|
||||
* Submit comment form via AJAX
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_submit_contact_form() {
|
||||
// Nonce (die on failure)
|
||||
check_ajax_referer( 'fictioneer_nonce', 'nonce' );
|
||||
function fictioneer_ajax_submit_contact_form() {
|
||||
// Nonce (die on failure)
|
||||
check_ajax_referer( 'fictioneer_nonce', 'nonce' );
|
||||
|
||||
// Emergency stop
|
||||
if ( get_option( 'fictioneer_disable_contact_forms' ) ) {
|
||||
wp_send_json_error( ['error' => _x( 'Contact forms have been disabled.', 'Contact form.', 'fictioneer' )] );
|
||||
}
|
||||
// Emergency stop
|
||||
if ( get_option( 'fictioneer_disable_contact_forms' ) ) {
|
||||
wp_send_json_error( ['error' => _x( 'Contact forms have been disabled.', 'Contact form.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Validations
|
||||
if ( empty( $_POST['message'] ) ) {
|
||||
wp_send_json_error( ['error' => _x( 'Message field empty.', 'Contact form.', 'fictioneer' )] );
|
||||
}
|
||||
// Validations
|
||||
if ( empty( $_POST['message'] ) ) {
|
||||
wp_send_json_error( ['error' => _x( 'Message field empty.', 'Contact form.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
if ( ! empty( $_POST['phone'] ) || filter_var( $_POST['terms'] ?? 0, FILTER_VALIDATE_BOOLEAN ) ) {
|
||||
// Pretend the submission worked if honeypot is triggered
|
||||
wp_send_json_success( ['success' => _x( 'Submission received!', 'Contact form.', 'fictioneer' )] );
|
||||
}
|
||||
if ( ! empty( $_POST['phone'] ) || filter_var( $_POST['terms'] ?? 0, FILTER_VALIDATE_BOOLEAN ) ) {
|
||||
// Pretend the submission worked if honeypot is triggered
|
||||
wp_send_json_success( ['success' => _x( 'Submission received!', 'Contact form.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
if (
|
||||
$_POST['message'] != wp_strip_all_tags( $_POST['message'] ) ||
|
||||
( ! empty( $_POST['name'] ) && $_POST['name'] != wp_strip_all_tags( $_POST['name'] ) )
|
||||
) {
|
||||
// All fields are stripped of HTMl anyway, so this is only for the overly enthusiastic user.
|
||||
wp_send_json_error( ['error' => _x( 'Illegal HTML detected.', 'Contact form.', 'fictioneer' )] );
|
||||
}
|
||||
if (
|
||||
$_POST['message'] != wp_strip_all_tags( $_POST['message'] ) ||
|
||||
( ! empty( $_POST['name'] ) && $_POST['name'] != wp_strip_all_tags( $_POST['name'] ) )
|
||||
) {
|
||||
// All fields are stripped of HTMl anyway, so this is only for the overly enthusiastic user.
|
||||
wp_send_json_error( ['error' => _x( 'Illegal HTML detected.', 'Contact form.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
if ( ! empty( $_POST['email'] ) && ! is_email( $_POST['email'] ) ) {
|
||||
wp_send_json_error( ['error' => _x( 'Invalid email address.', 'Contact form.', 'fictioneer' )] );
|
||||
}
|
||||
if ( ! empty( $_POST['email'] ) && ! is_email( $_POST['email'] ) ) {
|
||||
wp_send_json_error( ['error' => _x( 'Invalid email address.', 'Contact form.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
if (
|
||||
filter_var( $_POST['require_privacy_policy'] ?? 0, FILTER_VALIDATE_BOOLEAN ) &&
|
||||
! filter_var( $_POST['privacy_policy'] ?? 0, FILTER_VALIDATE_BOOLEAN )
|
||||
) {
|
||||
// If the sender disables these fields, this is essentially acceptance
|
||||
// since they went out of their way to manipulate the form.
|
||||
wp_send_json_error( ['error' => _x( 'You need to accept the privacy policy.', 'Contact form.', 'fictioneer' )] );
|
||||
}
|
||||
if (
|
||||
filter_var( $_POST['require_privacy_policy'] ?? 0, FILTER_VALIDATE_BOOLEAN ) &&
|
||||
! filter_var( $_POST['privacy_policy'] ?? 0, FILTER_VALIDATE_BOOLEAN )
|
||||
) {
|
||||
// If the sender disables these fields, this is essentially acceptance
|
||||
// since they went out of their way to manipulate the form.
|
||||
wp_send_json_error( ['error' => _x( 'You need to accept the privacy policy.', 'Contact form.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Setup
|
||||
$user = wp_get_current_user();
|
||||
$title = sanitize_text_field( $_POST['title'] ?? _x( 'Nameless Form', 'Contact form.', 'fictioneer' ) );
|
||||
$message = sanitize_textarea_field( $_POST['message'] );
|
||||
$email = sanitize_email( $_POST['email'] ?? '' );
|
||||
$name = sanitize_text_field( $_POST['name'] ?? '' );
|
||||
$headers = ['Content-Type: text/html; charset=UTF-8'];
|
||||
$strings = [];
|
||||
// Setup
|
||||
$user = wp_get_current_user();
|
||||
$title = sanitize_text_field( $_POST['title'] ?? _x( 'Nameless Form', 'Contact form.', 'fictioneer' ) );
|
||||
$message = sanitize_textarea_field( $_POST['message'] );
|
||||
$email = sanitize_email( $_POST['email'] ?? '' );
|
||||
$name = sanitize_text_field( $_POST['name'] ?? '' );
|
||||
$headers = ['Content-Type: text/html; charset=UTF-8'];
|
||||
$strings = [];
|
||||
|
||||
// Strip HTML for good measure
|
||||
$title = wp_strip_all_tags( $title );
|
||||
$message = wpautop( wp_strip_all_tags( $message ) );
|
||||
$name = wp_strip_all_tags( $name );
|
||||
// Strip HTML for good measure
|
||||
$title = wp_strip_all_tags( $title );
|
||||
$message = wpautop( wp_strip_all_tags( $message ) );
|
||||
$name = wp_strip_all_tags( $name );
|
||||
|
||||
// Add to $strings
|
||||
$strings[] = $title;
|
||||
$strings[] = $message;
|
||||
$strings[] = $name;
|
||||
// Add to $strings
|
||||
$strings[] = $title;
|
||||
$strings[] = $message;
|
||||
$strings[] = $name;
|
||||
|
||||
// Email body...
|
||||
$html = '<p><strong>' . sprintf( _x( 'Form submission: %s', 'Contact form.', 'fictioneer' ), $title ) . '</strong></p>';
|
||||
$html .= '<fieldset>' . $message . '</fieldset>';
|
||||
// Email body...
|
||||
$html = '<p><strong>' . sprintf( _x( 'Form submission: %s', 'Contact form.', 'fictioneer' ), $title ) . '</strong></p>';
|
||||
$html .= '<fieldset>' . $message . '</fieldset>';
|
||||
|
||||
// ... email field
|
||||
if ( ! empty( $email ) ) {
|
||||
$html .= '<p>' . sprintf( _x( '<strong>Email Address:</strong> %s', 'Contact form.', 'fictioneer' ), $email ) . '</p>';
|
||||
}
|
||||
// ... email field
|
||||
if ( ! empty( $email ) ) {
|
||||
$html .= '<p>' . sprintf( _x( '<strong>Email Address:</strong> %s', 'Contact form.', 'fictioneer' ), $email ) . '</p>';
|
||||
}
|
||||
|
||||
// ... name field
|
||||
if ( ! empty( $name ) ) {
|
||||
$html .= '<p>' . sprintf( _x( '<strong>Name:</strong> %s', 'Contact form.', 'fictioneer' ), $name ) . '</p>';
|
||||
}
|
||||
// ... name field
|
||||
if ( ! empty( $name ) ) {
|
||||
$html .= '<p>' . sprintf( _x( '<strong>Name:</strong> %s', 'Contact form.', 'fictioneer' ), $name ) . '</p>';
|
||||
}
|
||||
|
||||
// ... text fields
|
||||
for ( $i = 1; $i <= 6; $i++ ) {
|
||||
// Get label and value (if any)
|
||||
$field_value = sanitize_text_field( $_POST[ "text_$i" ] ?? '' );
|
||||
$field_label = sanitize_text_field( $_POST[ "text_label_$i" ] ?? '' );
|
||||
// ... text fields
|
||||
for ( $i = 1; $i <= 6; $i++ ) {
|
||||
// Get label and value (if any)
|
||||
$field_value = sanitize_text_field( $_POST[ "text_$i" ] ?? '' );
|
||||
$field_label = sanitize_text_field( $_POST[ "text_label_$i" ] ?? '' );
|
||||
|
||||
// Skip if label is missing
|
||||
if ( empty( $field_label ) ) continue;
|
||||
|
||||
// Build field
|
||||
if ( ! empty( $field_value ) ) {
|
||||
// Strip HTML for good measure
|
||||
$field_value = wp_strip_all_tags( $field_value );
|
||||
$field_label = wp_strip_all_tags( $field_label );
|
||||
|
||||
// Add to $strings
|
||||
$strings[] = $field_value;
|
||||
$strings[] = $field_value;
|
||||
|
||||
// Add to email body
|
||||
$html .= '<p>' . sprintf(
|
||||
_x( '<strong>%1$s:</strong> %2$s', 'Contact form.', 'fictioneer' ),
|
||||
$field_label,
|
||||
$field_value
|
||||
) . '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
// ... checkboxes
|
||||
for ( $i = 1; $i <= 6; $i++ ) {
|
||||
// Get label and value (if any)
|
||||
$field_value = filter_var( $_POST[ "check_$i" ] ?? 0, FILTER_VALIDATE_BOOLEAN );
|
||||
$field_label = sanitize_text_field( $_POST[ "check_label_$i" ] ?? '' );
|
||||
|
||||
// Skip if label is missing
|
||||
if ( empty( $field_label ) ) continue;
|
||||
// Skip if label is missing
|
||||
if ( empty( $field_label ) ) continue;
|
||||
|
||||
// Build field
|
||||
if ( ! empty( $field_value ) ) {
|
||||
// Strip HTML for good measure
|
||||
$field_value = wp_strip_all_tags( $field_value );
|
||||
$field_label = wp_strip_all_tags( $field_label );
|
||||
|
||||
// Add to $strings
|
||||
$strings[] = $field_label;
|
||||
$strings[] = $field_value;
|
||||
$strings[] = $field_value;
|
||||
|
||||
// Build field
|
||||
// Add to email body
|
||||
$html .= '<p>' . sprintf(
|
||||
_x( '<strong>%1$s:</strong> %2$s', 'Contact form.', 'fictioneer' ),
|
||||
$field_label,
|
||||
$field_value ? __( 'True', 'fictioneer' ) : __( 'False', 'fictioneer' )
|
||||
$field_value
|
||||
) . '</p>';
|
||||
}
|
||||
|
||||
// Hook for additional spam protection
|
||||
do_action( 'fictioneer_contact_form_validation', $strings );
|
||||
|
||||
// ... IP and user agent if privacy policy acceptance is required
|
||||
if ( filter_var( $_POST['require_privacy_policy'] ?? 0, FILTER_VALIDATE_BOOLEAN ) ) {
|
||||
// IP (unreliable)
|
||||
$html .= '<p>' . sprintf(
|
||||
_x( '<strong>%1$s:</strong> %2$s', 'Contact form.', 'fictioneer' ),
|
||||
__( 'IP Address', 'fictioneer' ),
|
||||
$_SERVER['REMOTE_ADDR'] ?? ''
|
||||
) . '</p>';
|
||||
|
||||
// User agent (unreliable)
|
||||
$html .= '<p>' . sprintf(
|
||||
_x( '<strong>%1$s:</strong> %2$s', 'Contact form.', 'fictioneer' ),
|
||||
__( 'User Agent', 'fictioneer' ),
|
||||
$_SERVER['HTTP_USER_AGENT'] ?? ''
|
||||
) . '</p>';
|
||||
}
|
||||
|
||||
// ... user if logged in
|
||||
if ( is_user_logged_in() ) {
|
||||
$user_info = get_userdata( $user->ID );
|
||||
|
||||
$html .= '<p>' . sprintf(
|
||||
_x( '<strong>%1$s:</strong> %2$s', 'Contact form.', 'fictioneer' ),
|
||||
__( 'User', 'fictioneer' ),
|
||||
sprintf( _x( '%1$s (%2$s)', 'Contact form.', 'fictioneer' ), $user_info->user_login, $user->ID )
|
||||
) . '</p>';
|
||||
}
|
||||
|
||||
// Check against disallow list (Settings > Discussion)
|
||||
$offenders = fictioneer_check_comment_disallowed_list(
|
||||
$name,
|
||||
$email,
|
||||
'',
|
||||
$message,
|
||||
$_SERVER['REMOTE_ADDR'] ?? '',
|
||||
$_SERVER['HTTP_USER_AGENT'] ?? ''
|
||||
);
|
||||
|
||||
// Only show error for keys in content, trash anything else as usual later.
|
||||
// No need to tell someone his name or email address is blocked, etc.
|
||||
if ( FICTIONEER_DISALLOWED_KEY_NOTICE && $offenders[0] && $offenders[1] ) {
|
||||
wp_send_json_error( ['error' => __( 'Disallowed key found: "' . implode( ', ', $offenders[1] ) . '".', 'fictioneer' )] );
|
||||
} elseif ( $offenders[0] ) {
|
||||
wp_send_json_error( ['error' => __( 'Disallowed keys found.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Addresses
|
||||
$to_addresses = array_filter( explode( "\n", get_option( 'fictioneer_contact_email_addresses' ) ) );
|
||||
$to_addresses = empty( $to_addresses ) ? [get_bloginfo( 'admin_email' )] : $to_addresses;
|
||||
$from_address = get_option( 'fictioneer_system_email_address' );
|
||||
|
||||
// Headers
|
||||
if ( ! empty( $from_address ) ) {
|
||||
$from_name = get_option( 'fictioneer_system_email_name' );
|
||||
$from_name = empty ( $from_name ) ? FICTIONEER_SITE_NAME : $from_name;
|
||||
$headers[] = 'From: ' . trim( $from_name ) . ' <' . trim( $from_address ) . '>';
|
||||
}
|
||||
|
||||
// Send email to each recipient
|
||||
foreach ( $to_addresses as $to ) {
|
||||
$to = sanitize_email( $to );
|
||||
|
||||
// Skip if not valid email address
|
||||
if ( ! is_email( $to ) ) continue;
|
||||
|
||||
// Send email
|
||||
wp_mail(
|
||||
$to,
|
||||
sprintf( _x( 'Form submission: %s', 'Contact form.', 'fictioneer' ), $title ),
|
||||
$html,
|
||||
$headers
|
||||
);
|
||||
}
|
||||
|
||||
// Response
|
||||
wp_send_json_success( ['success' => _x( 'Submission received!', 'Contact form.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// ... checkboxes
|
||||
for ( $i = 1; $i <= 6; $i++ ) {
|
||||
// Get label and value (if any)
|
||||
$field_value = filter_var( $_POST[ "check_$i" ] ?? 0, FILTER_VALIDATE_BOOLEAN );
|
||||
$field_label = sanitize_text_field( $_POST[ "check_label_$i" ] ?? '' );
|
||||
|
||||
// Skip if label is missing
|
||||
if ( empty( $field_label ) ) continue;
|
||||
|
||||
// Strip HTML for good measure
|
||||
$field_label = wp_strip_all_tags( $field_label );
|
||||
|
||||
// Add to $strings
|
||||
$strings[] = $field_label;
|
||||
|
||||
// Build field
|
||||
$html .= '<p>' . sprintf(
|
||||
_x( '<strong>%1$s:</strong> %2$s', 'Contact form.', 'fictioneer' ),
|
||||
$field_label,
|
||||
$field_value ? __( 'True', 'fictioneer' ) : __( 'False', 'fictioneer' )
|
||||
) . '</p>';
|
||||
}
|
||||
|
||||
// Hook for additional spam protection
|
||||
do_action( 'fictioneer_contact_form_validation', $strings );
|
||||
|
||||
// ... IP and user agent if privacy policy acceptance is required
|
||||
if ( filter_var( $_POST['require_privacy_policy'] ?? 0, FILTER_VALIDATE_BOOLEAN ) ) {
|
||||
// IP (unreliable)
|
||||
$html .= '<p>' . sprintf(
|
||||
_x( '<strong>%1$s:</strong> %2$s', 'Contact form.', 'fictioneer' ),
|
||||
__( 'IP Address', 'fictioneer' ),
|
||||
$_SERVER['REMOTE_ADDR'] ?? ''
|
||||
) . '</p>';
|
||||
|
||||
// User agent (unreliable)
|
||||
$html .= '<p>' . sprintf(
|
||||
_x( '<strong>%1$s:</strong> %2$s', 'Contact form.', 'fictioneer' ),
|
||||
__( 'User Agent', 'fictioneer' ),
|
||||
$_SERVER['HTTP_USER_AGENT'] ?? ''
|
||||
) . '</p>';
|
||||
}
|
||||
|
||||
// ... user if logged in
|
||||
if ( is_user_logged_in() ) {
|
||||
$user_info = get_userdata( $user->ID );
|
||||
|
||||
$html .= '<p>' . sprintf(
|
||||
_x( '<strong>%1$s:</strong> %2$s', 'Contact form.', 'fictioneer' ),
|
||||
__( 'User', 'fictioneer' ),
|
||||
sprintf( _x( '%1$s (%2$s)', 'Contact form.', 'fictioneer' ), $user_info->user_login, $user->ID )
|
||||
) . '</p>';
|
||||
}
|
||||
|
||||
// Check against disallow list (Settings > Discussion)
|
||||
$offenders = fictioneer_check_comment_disallowed_list(
|
||||
$name,
|
||||
$email,
|
||||
'',
|
||||
$message,
|
||||
$_SERVER['REMOTE_ADDR'] ?? '',
|
||||
$_SERVER['HTTP_USER_AGENT'] ?? ''
|
||||
);
|
||||
|
||||
// Only show error for keys in content, trash anything else as usual later.
|
||||
// No need to tell someone his name or email address is blocked, etc.
|
||||
if ( FICTIONEER_DISALLOWED_KEY_NOTICE && $offenders[0] && $offenders[1] ) {
|
||||
wp_send_json_error( ['error' => __( 'Disallowed key found: "' . implode( ', ', $offenders[1] ) . '".', 'fictioneer' )] );
|
||||
} elseif ( $offenders[0] ) {
|
||||
wp_send_json_error( ['error' => __( 'Disallowed keys found.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Addresses
|
||||
$to_addresses = array_filter( explode( "\n", get_option( 'fictioneer_contact_email_addresses' ) ) );
|
||||
$to_addresses = empty( $to_addresses ) ? [get_bloginfo( 'admin_email' )] : $to_addresses;
|
||||
$from_address = get_option( 'fictioneer_system_email_address' );
|
||||
|
||||
// Headers
|
||||
if ( ! empty( $from_address ) ) {
|
||||
$from_name = get_option( 'fictioneer_system_email_name' );
|
||||
$from_name = empty ( $from_name ) ? FICTIONEER_SITE_NAME : $from_name;
|
||||
$headers[] = 'From: ' . trim( $from_name ) . ' <' . trim( $from_address ) . '>';
|
||||
}
|
||||
|
||||
// Send email to each recipient
|
||||
foreach ( $to_addresses as $to ) {
|
||||
$to = sanitize_email( $to );
|
||||
|
||||
// Skip if not valid email address
|
||||
if ( ! is_email( $to ) ) continue;
|
||||
|
||||
// Send email
|
||||
wp_mail(
|
||||
$to,
|
||||
sprintf( _x( 'Form submission: %s', 'Contact form.', 'fictioneer' ), $title ),
|
||||
$html,
|
||||
$headers
|
||||
);
|
||||
}
|
||||
|
||||
// Response
|
||||
wp_send_json_success( ['success' => _x( 'Submission received!', 'Contact form.', 'fictioneer' )] );
|
||||
}
|
||||
add_action( 'wp_ajax_fictioneer_ajax_submit_contact_form', 'fictioneer_ajax_submit_contact_form' );
|
||||
add_action( 'wp_ajax_nopriv_fictioneer_ajax_submit_contact_form', 'fictioneer_ajax_submit_contact_form' );
|
||||
|
@ -42,16 +42,14 @@ define(
|
||||
// SETUP
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_add_oauth2_endpoint' ) ) {
|
||||
/**
|
||||
* Add route to OAuth script
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*/
|
||||
/**
|
||||
* Add route to OAuth script
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*/
|
||||
|
||||
function fictioneer_add_oauth2_endpoint() {
|
||||
add_rewrite_endpoint( FICTIONEER_OAUTH_ENDPOINT, EP_ROOT );
|
||||
}
|
||||
function fictioneer_add_oauth2_endpoint() {
|
||||
add_rewrite_endpoint( FICTIONEER_OAUTH_ENDPOINT, EP_ROOT );
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_oauth' ) ) {
|
||||
@ -160,148 +158,146 @@ if ( ! function_exists( 'fictioneer_get_oauth_links' ) ) {
|
||||
// PROCESS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_handle_oauth' ) ) {
|
||||
/**
|
||||
* Handle OAuth2 requests made to the OAuth2 route
|
||||
*
|
||||
* After an initial validation, delegates to the current OAuth2 steps based on
|
||||
* the action (GET) and session variables. Each provider differs a bit, but the
|
||||
* protocol is the same. First, you have to request a CODE with the pre-defined
|
||||
* permissions (SCOPE) that requires user confirmation. This is secured with a
|
||||
* cryptic key (STATE). Once you got the CODE, you need to make another request
|
||||
* for a TOKEN, which is then used to make yet another request for the user data
|
||||
* to authenticate the user. The connection is severed after that.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @link https://developer.wordpress.org/reference/hooks/template_redirect/
|
||||
* @link https://dev.twitch.tv/docs/authentication
|
||||
* @link https://discord.com/developers/docs/topics/oauth2
|
||||
* @link https://docs.patreon.com/#step-1-registering-your-client
|
||||
* @link https://developers.google.com/identity/protocols/oauth2
|
||||
*/
|
||||
/**
|
||||
* Handle OAuth2 requests made to the OAuth2 route
|
||||
*
|
||||
* After an initial validation, delegates to the current OAuth2 steps based on
|
||||
* the action (GET) and session variables. Each provider differs a bit, but the
|
||||
* protocol is the same. First, you have to request a CODE with the pre-defined
|
||||
* permissions (SCOPE) that requires user confirmation. This is secured with a
|
||||
* cryptic key (STATE). Once you got the CODE, you need to make another request
|
||||
* for a TOKEN, which is then used to make yet another request for the user data
|
||||
* to authenticate the user. The connection is severed after that.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @link https://developer.wordpress.org/reference/hooks/template_redirect/
|
||||
* @link https://dev.twitch.tv/docs/authentication
|
||||
* @link https://discord.com/developers/docs/topics/oauth2
|
||||
* @link https://docs.patreon.com/#step-1-registering-your-client
|
||||
* @link https://developers.google.com/identity/protocols/oauth2
|
||||
*/
|
||||
|
||||
function fictioneer_handle_oauth() {
|
||||
// Check whether this is the OAuth2 route
|
||||
if ( is_null( get_query_var( FICTIONEER_OAUTH_ENDPOINT, null ) ) ) return;
|
||||
function fictioneer_handle_oauth() {
|
||||
// Check whether this is the OAuth2 route
|
||||
if ( is_null( get_query_var( FICTIONEER_OAUTH_ENDPOINT, null ) ) ) return;
|
||||
|
||||
// Setup
|
||||
fictioneer_set_oauth_constants();
|
||||
$note = '';
|
||||
// Setup
|
||||
fictioneer_set_oauth_constants();
|
||||
$note = '';
|
||||
|
||||
// Check nonce for initial call but not once a STATE is set
|
||||
if (
|
||||
! STATE &&
|
||||
(
|
||||
! isset( $_GET['oauth_nonce'] ) ||
|
||||
! wp_verify_nonce( $_GET['oauth_nonce'], 'authenticate' )
|
||||
// Check nonce for initial call but not once a STATE is set
|
||||
if (
|
||||
! STATE &&
|
||||
(
|
||||
! isset( $_GET['oauth_nonce'] ) ||
|
||||
! wp_verify_nonce( $_GET['oauth_nonce'], 'authenticate' )
|
||||
)
|
||||
) {
|
||||
fictioneer_oauth2_exit_and_return();
|
||||
}
|
||||
|
||||
// Exit on error
|
||||
if ( ERROR ) fictioneer_oauth2_exit_and_return();
|
||||
|
||||
// Logout
|
||||
if ( ACTION === 'logout' ) {
|
||||
wp_logout();
|
||||
fictioneer_oauth2_exit_and_return( ANCHOR ? RETURN_URL . '#' . ANCHOR : RETURN_URL );
|
||||
}
|
||||
|
||||
// Check whether oauth is working
|
||||
if (
|
||||
! get_option( 'fictioneer_enable_oauth' ) ||
|
||||
! OAUTH2_CLIENT_ID ||
|
||||
! OAUTH2_CLIENT_SECRET
|
||||
) {
|
||||
fictioneer_oauth2_exit_and_return();
|
||||
}
|
||||
|
||||
// Check for MERGE if user is not logged in
|
||||
if ( ! is_user_logged_in() && MERGE == '1' ) {
|
||||
fictioneer_oauth2_exit_and_return();
|
||||
}
|
||||
|
||||
// Check for MERGE if user is already logged in
|
||||
if (
|
||||
is_user_logged_in() &&
|
||||
(
|
||||
MERGE != '1' &&
|
||||
! isset( $_SESSION['current_user_id'] )
|
||||
)
|
||||
) {
|
||||
fictioneer_oauth2_exit_and_return();
|
||||
}
|
||||
|
||||
// Get code
|
||||
if ( ACTION === 'login' ) {
|
||||
fictioneer_get_oauth_code();
|
||||
}
|
||||
|
||||
// Security check
|
||||
if ( ! STATE || $_SESSION['state'] != STATE ) fictioneer_oauth2_exit_and_return();
|
||||
|
||||
// Get token and delegate to login/register
|
||||
if ( ! empty( CODE ) ) {
|
||||
$token = fictioneer_get_oauth_token(
|
||||
FICIONEER_OAUTH_API_ENDPOINTS[CHANNEL]['token'],
|
||||
array(
|
||||
'grant_type' => 'authorization_code',
|
||||
'client_id' => OAUTH2_CLIENT_ID,
|
||||
'client_secret' => OAUTH2_CLIENT_SECRET,
|
||||
'redirect_uri' => REDIRECT_URL,
|
||||
'code' => CODE,
|
||||
'scope' => FICIONEER_OAUTH_API_ENDPOINTS[CHANNEL]['scope']
|
||||
)
|
||||
) {
|
||||
fictioneer_oauth2_exit_and_return();
|
||||
);
|
||||
|
||||
// Access token successfully retrieved?
|
||||
$access_token = isset( $token->access_token ) ? $token->access_token : null;
|
||||
if ( ! $access_token ) fictioneer_oauth2_exit_and_return();
|
||||
|
||||
// Delegate to respective channel function
|
||||
switch ( CHANNEL ) {
|
||||
case 'discord':
|
||||
$note = fictioneer_process_oauth_discord( FICIONEER_OAUTH_API_ENDPOINTS[CHANNEL]['user'], $access_token );
|
||||
break;
|
||||
case 'twitch':
|
||||
$note = fictioneer_process_oauth_twitch( FICIONEER_OAUTH_API_ENDPOINTS[CHANNEL]['user'], $access_token );
|
||||
break;
|
||||
case 'google':
|
||||
$note = fictioneer_process_oauth_google( FICIONEER_OAUTH_API_ENDPOINTS[CHANNEL]['user'], $access_token );
|
||||
break;
|
||||
case 'patreon':
|
||||
$note = fictioneer_process_oauth_patreon( FICIONEER_OAUTH_API_ENDPOINTS[CHANNEL]['user'], $access_token );
|
||||
break;
|
||||
}
|
||||
|
||||
// Exit on error
|
||||
if ( ERROR ) fictioneer_oauth2_exit_and_return();
|
||||
|
||||
// Logout
|
||||
if ( ACTION === 'logout' ) {
|
||||
wp_logout();
|
||||
fictioneer_oauth2_exit_and_return( ANCHOR ? RETURN_URL . '#' . ANCHOR : RETURN_URL );
|
||||
// Error: Email already taken by another account
|
||||
if ( ! is_user_logged_in() ) {
|
||||
$return_url = ( $_SESSION['return_url'] ) ? urldecode( $_SESSION['return_url'] ) : RETURN_URL;
|
||||
$return_url .= '?failure=' . $note;
|
||||
$return_url = ( $_SESSION['anchor'] ) ? $return_url . '#' . $_SESSION['anchor'] : $return_url;
|
||||
fictioneer_oauth2_exit_and_return( $return_url );
|
||||
}
|
||||
|
||||
// Check whether oauth is working
|
||||
if (
|
||||
! get_option( 'fictioneer_enable_oauth' ) ||
|
||||
! OAUTH2_CLIENT_ID ||
|
||||
! OAUTH2_CLIENT_SECRET
|
||||
) {
|
||||
fictioneer_oauth2_exit_and_return();
|
||||
// Success: Merged into account
|
||||
if ( $note == 'merged' ) {
|
||||
$return_url = ( $_SESSION['return_url'] ) ? urldecode( $_SESSION['return_url'] ) : RETURN_URL;
|
||||
$return_url .= '?success=oauth_merged_' . CHANNEL;
|
||||
$return_url = ( $_SESSION['anchor'] ) ? $return_url . '#' . $_SESSION['anchor'] : $return_url;
|
||||
fictioneer_oauth2_exit_and_return( $return_url );
|
||||
}
|
||||
|
||||
// Check for MERGE if user is not logged in
|
||||
if ( ! is_user_logged_in() && MERGE == '1' ) {
|
||||
fictioneer_oauth2_exit_and_return();
|
||||
// Success: New user registered
|
||||
if ( $note == 'new' ) {
|
||||
$return_url = ( $_SESSION['return_url'] ) ? urldecode( $_SESSION['return_url'] ) : RETURN_URL;
|
||||
$return_url .= '?success=oauth_new_subscriber';
|
||||
$return_url = ( $_SESSION['anchor'] ) ? $return_url . '#' . $_SESSION['anchor'] : $return_url;
|
||||
fictioneer_oauth2_exit_and_return( $return_url );
|
||||
}
|
||||
|
||||
// Check for MERGE if user is already logged in
|
||||
if (
|
||||
is_user_logged_in() &&
|
||||
(
|
||||
MERGE != '1' &&
|
||||
! isset( $_SESSION['current_user_id'] )
|
||||
)
|
||||
) {
|
||||
fictioneer_oauth2_exit_and_return();
|
||||
}
|
||||
|
||||
// Get code
|
||||
if ( ACTION === 'login' ) {
|
||||
fictioneer_get_oauth_code();
|
||||
}
|
||||
|
||||
// Security check
|
||||
if ( ! STATE || $_SESSION['state'] != STATE ) fictioneer_oauth2_exit_and_return();
|
||||
|
||||
// Get token and delegate to login/register
|
||||
if ( ! empty( CODE ) ) {
|
||||
$token = fictioneer_get_oauth_token(
|
||||
FICIONEER_OAUTH_API_ENDPOINTS[CHANNEL]['token'],
|
||||
array(
|
||||
'grant_type' => 'authorization_code',
|
||||
'client_id' => OAUTH2_CLIENT_ID,
|
||||
'client_secret' => OAUTH2_CLIENT_SECRET,
|
||||
'redirect_uri' => REDIRECT_URL,
|
||||
'code' => CODE,
|
||||
'scope' => FICIONEER_OAUTH_API_ENDPOINTS[CHANNEL]['scope']
|
||||
)
|
||||
);
|
||||
|
||||
// Access token successfully retrieved?
|
||||
$access_token = isset( $token->access_token ) ? $token->access_token : null;
|
||||
if ( ! $access_token ) fictioneer_oauth2_exit_and_return();
|
||||
|
||||
// Delegate to respective channel function
|
||||
switch ( CHANNEL ) {
|
||||
case 'discord':
|
||||
$note = fictioneer_process_oauth_discord( FICIONEER_OAUTH_API_ENDPOINTS[CHANNEL]['user'], $access_token );
|
||||
break;
|
||||
case 'twitch':
|
||||
$note = fictioneer_process_oauth_twitch( FICIONEER_OAUTH_API_ENDPOINTS[CHANNEL]['user'], $access_token );
|
||||
break;
|
||||
case 'google':
|
||||
$note = fictioneer_process_oauth_google( FICIONEER_OAUTH_API_ENDPOINTS[CHANNEL]['user'], $access_token );
|
||||
break;
|
||||
case 'patreon':
|
||||
$note = fictioneer_process_oauth_patreon( FICIONEER_OAUTH_API_ENDPOINTS[CHANNEL]['user'], $access_token );
|
||||
break;
|
||||
}
|
||||
|
||||
// Error: Email already taken by another account
|
||||
if ( ! is_user_logged_in() ) {
|
||||
$return_url = ( $_SESSION['return_url'] ) ? urldecode( $_SESSION['return_url'] ) : RETURN_URL;
|
||||
$return_url .= '?failure=' . $note;
|
||||
$return_url = ( $_SESSION['anchor'] ) ? $return_url . '#' . $_SESSION['anchor'] : $return_url;
|
||||
fictioneer_oauth2_exit_and_return( $return_url );
|
||||
}
|
||||
|
||||
// Success: Merged into account
|
||||
if ( $note == 'merged' ) {
|
||||
$return_url = ( $_SESSION['return_url'] ) ? urldecode( $_SESSION['return_url'] ) : RETURN_URL;
|
||||
$return_url .= '?success=oauth_merged_' . CHANNEL;
|
||||
$return_url = ( $_SESSION['anchor'] ) ? $return_url . '#' . $_SESSION['anchor'] : $return_url;
|
||||
fictioneer_oauth2_exit_and_return( $return_url );
|
||||
}
|
||||
|
||||
// Success: New user registered
|
||||
if ( $note == 'new' ) {
|
||||
$return_url = ( $_SESSION['return_url'] ) ? urldecode( $_SESSION['return_url'] ) : RETURN_URL;
|
||||
$return_url .= '?success=oauth_new_subscriber';
|
||||
$return_url = ( $_SESSION['anchor'] ) ? $return_url . '#' . $_SESSION['anchor'] : $return_url;
|
||||
fictioneer_oauth2_exit_and_return( $return_url );
|
||||
}
|
||||
|
||||
// Finish
|
||||
fictioneer_oauth2_exit_and_return();
|
||||
}
|
||||
// Finish
|
||||
fictioneer_oauth2_exit_and_return();
|
||||
}
|
||||
}
|
||||
add_action( 'template_redirect', 'fictioneer_handle_oauth', 10 );
|
||||
|
@ -10,28 +10,26 @@
|
||||
// RESTRICT SUBSCRIBERS ROLE
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_block_subscribers_from_admin' ) ) {
|
||||
/**
|
||||
* Prevent subscribers from accessing the admin panel
|
||||
*
|
||||
* Subscribers have a custom frontend user profile and therefore no need to
|
||||
* access the admin panel at all. Only higher roles are granted access, although
|
||||
* admin-specific actions such as AJAX requests are still permitted.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*/
|
||||
/**
|
||||
* Prevent subscribers from accessing the admin panel
|
||||
*
|
||||
* Subscribers have a custom frontend user profile and therefore no need to
|
||||
* access the admin panel at all. Only higher roles are granted access, although
|
||||
* admin-specific actions such as AJAX requests are still permitted.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*/
|
||||
|
||||
function fictioneer_block_subscribers_from_admin() {
|
||||
// Redirect back to Home
|
||||
if (
|
||||
is_admin() &&
|
||||
! current_user_can( 'edit_posts' ) &&
|
||||
! current_user_can( 'moderate_comments' ) &&
|
||||
! ( defined( 'DOING_AJAX' ) && DOING_AJAX )
|
||||
) {
|
||||
wp_redirect( home_url() );
|
||||
exit;
|
||||
}
|
||||
function fictioneer_block_subscribers_from_admin() {
|
||||
// Redirect back to Home
|
||||
if (
|
||||
is_admin() &&
|
||||
! current_user_can( 'edit_posts' ) &&
|
||||
! current_user_can( 'moderate_comments' ) &&
|
||||
! ( defined( 'DOING_AJAX' ) && DOING_AJAX )
|
||||
) {
|
||||
wp_redirect( home_url() );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,37 +37,33 @@ if ( get_option( 'fictioneer_block_subscribers_from_admin' ) ) {
|
||||
add_action( 'init', 'fictioneer_block_subscribers_from_admin' );
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_reduce_subscriber_dashboard_widgets' ) ) {
|
||||
/**
|
||||
* Remove admin dashboard widgets for subscribers
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/apis/handbook/dashboard-widgets/
|
||||
*/
|
||||
/**
|
||||
* Remove admin dashboard widgets for subscribers
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/apis/handbook/dashboard-widgets/
|
||||
*/
|
||||
|
||||
function fictioneer_reduce_subscriber_dashboard_widgets() {
|
||||
global $wp_meta_boxes;
|
||||
function fictioneer_reduce_subscriber_dashboard_widgets() {
|
||||
global $wp_meta_boxes;
|
||||
|
||||
// Remove all
|
||||
$wp_meta_boxes['dashboard']['normal']['core'] = [];
|
||||
$wp_meta_boxes['dashboard']['side']['core'] = [];
|
||||
// Remove all
|
||||
$wp_meta_boxes['dashboard']['normal']['core'] = [];
|
||||
$wp_meta_boxes['dashboard']['side']['core'] = [];
|
||||
|
||||
// Remove actions
|
||||
remove_action( 'welcome_panel', 'wp_welcome_panel' );
|
||||
}
|
||||
// Remove actions
|
||||
remove_action( 'welcome_panel', 'wp_welcome_panel' );
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_reduce_subscriber_admin_panel' ) ) {
|
||||
/**
|
||||
* Remove admin menu pages for subscribers
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Remove admin menu pages for subscribers
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_reduce_subscriber_admin_panel() {
|
||||
// Remove menu pages
|
||||
remove_menu_page( 'index.php' ); // Dashboard
|
||||
}
|
||||
function fictioneer_reduce_subscriber_admin_panel() {
|
||||
// Remove menu pages
|
||||
remove_menu_page( 'index.php' ); // Dashboard
|
||||
}
|
||||
|
||||
// Apply restrictions to subscribers
|
||||
@ -83,108 +77,98 @@ if ( fictioneer_has_role( get_current_user_id(), 'subscriber' ) ) {
|
||||
// RESTRICT FICTIONEER MODERATOR ROLE
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_reduce_moderator_admin_panel' ) ) {
|
||||
/**
|
||||
* Remove admin menu pages for moderators
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Remove admin menu pages for moderators
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_reduce_moderator_admin_panel() {
|
||||
// Remove menu pages
|
||||
remove_menu_page( 'edit.php' );
|
||||
remove_menu_page( 'tools.php' );
|
||||
remove_menu_page( 'plugins.php' );
|
||||
remove_menu_page( 'themes.php' );
|
||||
function fictioneer_reduce_moderator_admin_panel() {
|
||||
// Remove menu pages
|
||||
remove_menu_page( 'edit.php' );
|
||||
remove_menu_page( 'tools.php' );
|
||||
remove_menu_page( 'plugins.php' );
|
||||
remove_menu_page( 'themes.php' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove admin dashboard widgets for moderators
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/apis/handbook/dashboard-widgets/
|
||||
*/
|
||||
|
||||
function fictioneer_reduce_moderator_dashboard_widgets() {
|
||||
global $wp_meta_boxes;
|
||||
|
||||
// Keep
|
||||
$activity = $wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'];
|
||||
|
||||
// Remove all
|
||||
$wp_meta_boxes['dashboard']['normal']['core'] = [];
|
||||
$wp_meta_boxes['dashboard']['side']['core'] = [];
|
||||
|
||||
// Re-add kept widgets
|
||||
$wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'] = $activity;
|
||||
|
||||
// Remove actions
|
||||
remove_action( 'welcome_panel', 'wp_welcome_panel' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove items from admin bar for moderators
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_reduce_moderator_admin_bar() {
|
||||
global $wp_admin_bar;
|
||||
|
||||
// Remove all [+New] items
|
||||
$wp_admin_bar->remove_node( 'new-content' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Restrict access to admin pages/actions for moderators
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_restrict_moderator_menu_access() {
|
||||
// Setup
|
||||
$screen = get_current_screen();
|
||||
|
||||
// Block access
|
||||
if (
|
||||
in_array(
|
||||
$screen->id,
|
||||
['tools', 'export', 'import', 'site-health', 'export-personal-data', 'erase-personal-data', 'themes', 'customize', 'nav-menus', 'theme-editor', 'users', 'user-new', 'options-general', 'post-new']
|
||||
) ||
|
||||
! empty( $screen->post_type )
|
||||
) {
|
||||
wp_die( __( 'Access denied.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_reduce_moderator_dashboard_widgets' ) ) {
|
||||
/**
|
||||
* Remove admin dashboard widgets for moderators
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/apis/handbook/dashboard-widgets/
|
||||
*/
|
||||
/**
|
||||
* Restrict access to admin pages/actions for moderators
|
||||
*
|
||||
* Prevent moderators from editing the comment content, which is rarely a good action.
|
||||
* Doing this via JS is a terrible solution but better than nothing.
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @todo Do this server-side to prevent savvy moderators from circumventing it.
|
||||
*/
|
||||
|
||||
function fictioneer_reduce_moderator_dashboard_widgets() {
|
||||
global $wp_meta_boxes;
|
||||
|
||||
// Keep
|
||||
$activity = $wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'];
|
||||
|
||||
// Remove all
|
||||
$wp_meta_boxes['dashboard']['normal']['core'] = [];
|
||||
$wp_meta_boxes['dashboard']['side']['core'] = [];
|
||||
|
||||
// Re-add kept widgets
|
||||
$wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'] = $activity;
|
||||
|
||||
// Remove actions
|
||||
remove_action( 'welcome_panel', 'wp_welcome_panel' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_reduce_moderator_admin_bar' ) ) {
|
||||
/**
|
||||
* Remove items from admin bar for moderators
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_reduce_moderator_admin_bar() {
|
||||
global $wp_admin_bar;
|
||||
|
||||
// Remove all [+New] items
|
||||
$wp_admin_bar->remove_node( 'new-content' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_restrict_moderator_menu_access' ) ) {
|
||||
/**
|
||||
* Restrict access to admin pages/actions for moderators
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_restrict_moderator_menu_access() {
|
||||
// Setup
|
||||
$screen = get_current_screen();
|
||||
|
||||
// Block access
|
||||
if (
|
||||
in_array(
|
||||
$screen->id,
|
||||
['tools', 'export', 'import', 'site-health', 'export-personal-data', 'erase-personal-data', 'themes', 'customize', 'nav-menus', 'theme-editor', 'users', 'user-new', 'options-general', 'post-new']
|
||||
) ||
|
||||
! empty( $screen->post_type )
|
||||
) {
|
||||
wp_die( __( 'Access denied.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_disable_moderator_comment_edit' ) ) {
|
||||
/**
|
||||
* Restrict access to admin pages/actions for moderators
|
||||
*
|
||||
* Prevent moderators from editing the comment content, which is rarely a good action.
|
||||
* Doing this via JS is a terrible solution but better than nothing.
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @todo Do this server-side to prevent savvy moderators from circumventing it.
|
||||
*/
|
||||
|
||||
function fictioneer_disable_moderator_comment_edit() {
|
||||
wp_add_inline_script(
|
||||
'fictioneer-admin-script',
|
||||
"jQuery(function($) {
|
||||
$('#qt_content_toolbar').remove();
|
||||
$('.wp-editor-area').prop('disabled', true);
|
||||
$('.wp-editor-area').prop('name', '');
|
||||
});"
|
||||
);
|
||||
}
|
||||
function fictioneer_disable_moderator_comment_edit() {
|
||||
wp_add_inline_script(
|
||||
'fictioneer-admin-script',
|
||||
"jQuery(function($) {
|
||||
$('#qt_content_toolbar').remove();
|
||||
$('.wp-editor-area').prop('disabled', true);
|
||||
$('.wp-editor-area').prop('name', '');
|
||||
});"
|
||||
);
|
||||
}
|
||||
|
||||
// Apply restrictions to fcn_moderators
|
||||
@ -203,92 +187,84 @@ if (
|
||||
// RESTRICT EDITOR ROLE
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_restrict_editor_menu_access' ) ) {
|
||||
/**
|
||||
* Restrict access to admin pages/actions for editors
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Restrict access to admin pages/actions for editors
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_restrict_editor_menu_access() {
|
||||
// Setup
|
||||
$screen = get_current_screen();
|
||||
function fictioneer_restrict_editor_menu_access() {
|
||||
// Setup
|
||||
$screen = get_current_screen();
|
||||
|
||||
// Block access
|
||||
if (
|
||||
in_array(
|
||||
$screen->id,
|
||||
['tools', 'export', 'import', 'site-health', 'export-personal-data', 'erase-personal-data', 'themes', 'customize', 'nav-menus', 'theme-editor', 'users', 'user-new', 'options-general', 'comment']
|
||||
)
|
||||
) {
|
||||
wp_die( __( 'Access denied.', 'fictioneer' ) );
|
||||
}
|
||||
// Block access
|
||||
if (
|
||||
in_array(
|
||||
$screen->id,
|
||||
['tools', 'export', 'import', 'site-health', 'export-personal-data', 'erase-personal-data', 'themes', 'customize', 'nav-menus', 'theme-editor', 'users', 'user-new', 'options-general', 'comment']
|
||||
)
|
||||
) {
|
||||
wp_die( __( 'Access denied.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_reduce_editor_admin_bar' ) ) {
|
||||
/**
|
||||
* Remove items from admin bar for editors
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Remove items from admin bar for editors
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_reduce_editor_admin_bar() {
|
||||
global $wp_admin_bar;
|
||||
function fictioneer_reduce_editor_admin_bar() {
|
||||
global $wp_admin_bar;
|
||||
|
||||
// Remove all [+New] items
|
||||
$wp_admin_bar->remove_node( 'new-content' );
|
||||
// Remove all [+New] items
|
||||
$wp_admin_bar->remove_node( 'new-content' );
|
||||
|
||||
// Remove comments
|
||||
$wp_admin_bar->remove_node( 'comments' );
|
||||
}
|
||||
// Remove comments
|
||||
$wp_admin_bar->remove_node( 'comments' );
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_reduce_editor_dashboard_widgets' ) ) {
|
||||
/**
|
||||
* Remove admin dashboard widgets for editors
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/apis/handbook/dashboard-widgets/
|
||||
*/
|
||||
/**
|
||||
* Remove admin dashboard widgets for editors
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/apis/handbook/dashboard-widgets/
|
||||
*/
|
||||
|
||||
function fictioneer_reduce_editor_dashboard_widgets() {
|
||||
global $wp_meta_boxes;
|
||||
function fictioneer_reduce_editor_dashboard_widgets() {
|
||||
global $wp_meta_boxes;
|
||||
|
||||
// Keep
|
||||
$right_now = $wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now'];
|
||||
$activity = $wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'];
|
||||
// Keep
|
||||
$right_now = $wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now'];
|
||||
$activity = $wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'];
|
||||
|
||||
// Remove all
|
||||
$wp_meta_boxes['dashboard']['normal']['core'] = [];
|
||||
$wp_meta_boxes['dashboard']['side']['core'] = [];
|
||||
// Remove all
|
||||
$wp_meta_boxes['dashboard']['normal']['core'] = [];
|
||||
$wp_meta_boxes['dashboard']['side']['core'] = [];
|
||||
|
||||
// Re-add kept widgets
|
||||
$wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now'] = $right_now;
|
||||
$wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'] = $activity;
|
||||
// Re-add kept widgets
|
||||
$wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now'] = $right_now;
|
||||
$wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'] = $activity;
|
||||
|
||||
// Remove actions
|
||||
remove_action( 'welcome_panel', 'wp_welcome_panel' );
|
||||
}
|
||||
// Remove actions
|
||||
remove_action( 'welcome_panel', 'wp_welcome_panel' );
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_hide_editor_comments_utilities' ) ) {
|
||||
/**
|
||||
* Hide comments utilities in admin dashboard for editors
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Hide comments utilities in admin dashboard for editors
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_hide_editor_comments_utilities() {
|
||||
wp_add_inline_script(
|
||||
'fictioneer-admin-script',
|
||||
"jQuery(function($) {
|
||||
$('.dashboard-comment-wrap > .row-actions').remove();
|
||||
$('#latest-comments > .subsubsub').remove();
|
||||
$('#dashboard_right_now .comment-count').remove();
|
||||
});"
|
||||
);
|
||||
}
|
||||
function fictioneer_hide_editor_comments_utilities() {
|
||||
wp_add_inline_script(
|
||||
'fictioneer-admin-script',
|
||||
"jQuery(function($) {
|
||||
$('.dashboard-comment-wrap > .row-actions').remove();
|
||||
$('#latest-comments > .subsubsub').remove();
|
||||
$('#dashboard_right_now .comment-count').remove();
|
||||
});"
|
||||
);
|
||||
}
|
||||
|
||||
// Apply restrictions to editors
|
||||
@ -306,69 +282,63 @@ if (
|
||||
// RESTRICT CONTRIBUTOR ROLE
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_reduce_contributor_dashboard_widgets' ) ) {
|
||||
/**
|
||||
* Remove admin dashboard widgets for contributors
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/apis/handbook/dashboard-widgets/
|
||||
*/
|
||||
/**
|
||||
* Remove admin dashboard widgets for contributors
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/apis/handbook/dashboard-widgets/
|
||||
*/
|
||||
|
||||
function fictioneer_reduce_contributor_dashboard_widgets() {
|
||||
global $wp_meta_boxes;
|
||||
function fictioneer_reduce_contributor_dashboard_widgets() {
|
||||
global $wp_meta_boxes;
|
||||
|
||||
// Keep
|
||||
$right_now = $wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now'];
|
||||
$activity = $wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'];
|
||||
// Keep
|
||||
$right_now = $wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now'];
|
||||
$activity = $wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'];
|
||||
|
||||
// Remove all
|
||||
$wp_meta_boxes['dashboard']['normal']['core'] = [];
|
||||
$wp_meta_boxes['dashboard']['side']['core'] = [];
|
||||
// Remove all
|
||||
$wp_meta_boxes['dashboard']['normal']['core'] = [];
|
||||
$wp_meta_boxes['dashboard']['side']['core'] = [];
|
||||
|
||||
// Re-add kept widgets
|
||||
$wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now'] = $right_now;
|
||||
$wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'] = $activity;
|
||||
// Re-add kept widgets
|
||||
$wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now'] = $right_now;
|
||||
$wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'] = $activity;
|
||||
|
||||
// Remove actions
|
||||
remove_action( 'welcome_panel', 'wp_welcome_panel' );
|
||||
}
|
||||
// Remove actions
|
||||
remove_action( 'welcome_panel', 'wp_welcome_panel' );
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_reduce_contributor_admin_bar' ) ) {
|
||||
/**
|
||||
* Remove items from admin bar for contributors
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Remove items from admin bar for contributors
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_reduce_contributor_admin_bar() {
|
||||
global $wp_admin_bar;
|
||||
function fictioneer_reduce_contributor_admin_bar() {
|
||||
global $wp_admin_bar;
|
||||
|
||||
// Remove all [+New] items
|
||||
$wp_admin_bar->remove_node( 'new-content' );
|
||||
// Remove all [+New] items
|
||||
$wp_admin_bar->remove_node( 'new-content' );
|
||||
|
||||
// Remove comments
|
||||
$wp_admin_bar->remove_node( 'comments' );
|
||||
}
|
||||
// Remove comments
|
||||
$wp_admin_bar->remove_node( 'comments' );
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_hide_contributor_comments_utilities' ) ) {
|
||||
/**
|
||||
* Hide comments utilities in admin dashboard for contributors
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Hide comments utilities in admin dashboard for contributors
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_hide_contributor_comments_utilities() {
|
||||
wp_add_inline_script(
|
||||
'fictioneer-admin-script',
|
||||
"jQuery(function($) {
|
||||
$('.dashboard-comment-wrap > .row-actions').remove();
|
||||
$('#latest-comments > .subsubsub').remove();
|
||||
$('#dashboard_right_now .comment-count').remove();
|
||||
});"
|
||||
);
|
||||
}
|
||||
function fictioneer_hide_contributor_comments_utilities() {
|
||||
wp_add_inline_script(
|
||||
'fictioneer-admin-script',
|
||||
"jQuery(function($) {
|
||||
$('.dashboard-comment-wrap > .row-actions').remove();
|
||||
$('#latest-comments > .subsubsub').remove();
|
||||
$('#dashboard_right_now .comment-count').remove();
|
||||
});"
|
||||
);
|
||||
}
|
||||
|
||||
// Apply restrictions to editors
|
||||
@ -385,66 +355,60 @@ if (
|
||||
// RESTRICT AUTHOR ROLE
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_reduce_author_dashboard_widgets' ) ) {
|
||||
/**
|
||||
* Remove admin dashboard widgets for authors
|
||||
*
|
||||
* @since Fictioneer 5.5.0
|
||||
* @link https://developer.wordpress.org/apis/handbook/dashboard-widgets/
|
||||
*/
|
||||
/**
|
||||
* Remove admin dashboard widgets for authors
|
||||
*
|
||||
* @since Fictioneer 5.5.0
|
||||
* @link https://developer.wordpress.org/apis/handbook/dashboard-widgets/
|
||||
*/
|
||||
|
||||
function fictioneer_reduce_author_dashboard_widgets() {
|
||||
global $wp_meta_boxes;
|
||||
function fictioneer_reduce_author_dashboard_widgets() {
|
||||
global $wp_meta_boxes;
|
||||
|
||||
// Keep
|
||||
$right_now = $wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now'];
|
||||
$activity = $wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'];
|
||||
// Keep
|
||||
$right_now = $wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now'];
|
||||
$activity = $wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'];
|
||||
|
||||
// Remove all
|
||||
$wp_meta_boxes['dashboard']['normal']['core'] = [];
|
||||
$wp_meta_boxes['dashboard']['side']['core'] = [];
|
||||
// Remove all
|
||||
$wp_meta_boxes['dashboard']['normal']['core'] = [];
|
||||
$wp_meta_boxes['dashboard']['side']['core'] = [];
|
||||
|
||||
// Re-add kept widgets
|
||||
$wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now'] = $right_now;
|
||||
$wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'] = $activity;
|
||||
// Re-add kept widgets
|
||||
$wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now'] = $right_now;
|
||||
$wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'] = $activity;
|
||||
|
||||
// Remove actions
|
||||
remove_action( 'welcome_panel', 'wp_welcome_panel' );
|
||||
}
|
||||
// Remove actions
|
||||
remove_action( 'welcome_panel', 'wp_welcome_panel' );
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_reduce_author_admin_bar' ) ) {
|
||||
/**
|
||||
* Remove items from admin bar for authors
|
||||
*
|
||||
* @since Fictioneer 5.5.0
|
||||
*/
|
||||
/**
|
||||
* Remove items from admin bar for authors
|
||||
*
|
||||
* @since Fictioneer 5.5.0
|
||||
*/
|
||||
|
||||
function fictioneer_reduce_author_admin_bar() {
|
||||
global $wp_admin_bar;
|
||||
function fictioneer_reduce_author_admin_bar() {
|
||||
global $wp_admin_bar;
|
||||
|
||||
// Remove comments
|
||||
$wp_admin_bar->remove_node( 'comments' );
|
||||
}
|
||||
// Remove comments
|
||||
$wp_admin_bar->remove_node( 'comments' );
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_hide_author_comments_utilities' ) ) {
|
||||
/**
|
||||
* Hide comments utilities in admin dashboard for authors
|
||||
*
|
||||
* @since Fictioneer 5.5.0
|
||||
*/
|
||||
/**
|
||||
* Hide comments utilities in admin dashboard for authors
|
||||
*
|
||||
* @since Fictioneer 5.5.0
|
||||
*/
|
||||
|
||||
function fictioneer_hide_author_comments_utilities() {
|
||||
wp_add_inline_script(
|
||||
'fictioneer-admin-script',
|
||||
"jQuery(function($) {
|
||||
$('.dashboard-comment-wrap > .row-actions').remove();
|
||||
$('#latest-comments > .subsubsub').remove();
|
||||
$('#dashboard_right_now .comment-count').remove();
|
||||
});"
|
||||
);
|
||||
}
|
||||
function fictioneer_hide_author_comments_utilities() {
|
||||
wp_add_inline_script(
|
||||
'fictioneer-admin-script',
|
||||
"jQuery(function($) {
|
||||
$('.dashboard-comment-wrap > .row-actions').remove();
|
||||
$('#latest-comments > .subsubsub').remove();
|
||||
$('#dashboard_right_now .comment-count').remove();
|
||||
});"
|
||||
);
|
||||
}
|
||||
|
||||
// Apply restrictions to authors
|
||||
|
@ -307,63 +307,61 @@ if ( ! function_exists( 'fictioneer_get_schema_node_list' ) ) {
|
||||
// OUTPUT SCHEMA
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_output_schemas' ) ) {
|
||||
/**
|
||||
* Output schema graph on selected pages
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $post_id Optional. The current post ID.
|
||||
*/
|
||||
/**
|
||||
* Output schema graph on selected pages
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $post_id Optional. The current post ID.
|
||||
*/
|
||||
|
||||
function fictioneer_output_schemas( $post_id = null ) {
|
||||
// Setup
|
||||
$post_id = $post_id ? $post_id : get_queried_object_id(); // In archives, this is the first post
|
||||
$schema = get_post_meta( $post_id, 'fictioneer_schema', true ); // Cached schema
|
||||
$skip = is_archive() || is_search() || is_home() || is_front_page();
|
||||
function fictioneer_output_schemas( $post_id = null ) {
|
||||
// Setup
|
||||
$post_id = $post_id ? $post_id : get_queried_object_id(); // In archives, this is the first post
|
||||
$schema = get_post_meta( $post_id, 'fictioneer_schema', true ); // Cached schema
|
||||
$skip = is_archive() || is_search() || is_home() || is_front_page();
|
||||
|
||||
// No schema found...
|
||||
if ( ! $schema && ! $skip ) {
|
||||
// Look at template first...
|
||||
switch ( get_page_template_slug() ) {
|
||||
case 'chapters.php':
|
||||
$schema = fictioneer_build_chapters_schema( $post_id );
|
||||
break;
|
||||
case 'stories.php':
|
||||
$schema = fictioneer_build_stories_schema( $post_id );
|
||||
break;
|
||||
case 'recommendations.php':
|
||||
$schema = fictioneer_build_recommendations_schema( $post_id );
|
||||
break;
|
||||
case 'collections.php':
|
||||
$schema = fictioneer_build_collections_schema( $post_id );
|
||||
break;
|
||||
}
|
||||
|
||||
// Look at post type if still no schema...
|
||||
if ( ! $schema ) {
|
||||
switch ( get_post_type() ) {
|
||||
case 'post':
|
||||
$schema = fictioneer_build_post_schema( $post_id );
|
||||
break;
|
||||
case 'fcn_story':
|
||||
$schema = fictioneer_build_story_schema( $post_id );
|
||||
break;
|
||||
case 'fcn_chapter':
|
||||
$schema = fictioneer_build_chapter_schema( $post_id );
|
||||
break;
|
||||
case 'fcn_recommendation':
|
||||
$schema = fictioneer_build_recommendation_schema( $post_id );
|
||||
break;
|
||||
}
|
||||
}
|
||||
// No schema found...
|
||||
if ( ! $schema && ! $skip ) {
|
||||
// Look at template first...
|
||||
switch ( get_page_template_slug() ) {
|
||||
case 'chapters.php':
|
||||
$schema = fictioneer_build_chapters_schema( $post_id );
|
||||
break;
|
||||
case 'stories.php':
|
||||
$schema = fictioneer_build_stories_schema( $post_id );
|
||||
break;
|
||||
case 'recommendations.php':
|
||||
$schema = fictioneer_build_recommendations_schema( $post_id );
|
||||
break;
|
||||
case 'collections.php':
|
||||
$schema = fictioneer_build_collections_schema( $post_id );
|
||||
break;
|
||||
}
|
||||
|
||||
// If schema has been found, echo for selected post types
|
||||
if ( $schema && ! $skip ) {
|
||||
echo $schema ? '<script type="application/ld+json">' . $schema . '</script>' : '';
|
||||
// Look at post type if still no schema...
|
||||
if ( ! $schema ) {
|
||||
switch ( get_post_type() ) {
|
||||
case 'post':
|
||||
$schema = fictioneer_build_post_schema( $post_id );
|
||||
break;
|
||||
case 'fcn_story':
|
||||
$schema = fictioneer_build_story_schema( $post_id );
|
||||
break;
|
||||
case 'fcn_chapter':
|
||||
$schema = fictioneer_build_chapter_schema( $post_id );
|
||||
break;
|
||||
case 'fcn_recommendation':
|
||||
$schema = fictioneer_build_recommendation_schema( $post_id );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If schema has been found, echo for selected post types
|
||||
if ( $schema && ! $skip ) {
|
||||
echo $schema ? '<script type="application/ld+json">' . $schema . '</script>' : '';
|
||||
}
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_seo' ) && ! fictioneer_seo_plugin_active() ) {
|
||||
|
@ -4,32 +4,30 @@
|
||||
// ADD SEO METABOX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_add_seo_metabox' ) ) {
|
||||
/**
|
||||
* Adds a SEO metabox to selected post types
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param string $post_type Post type.
|
||||
* @param string $post Post object.
|
||||
*/
|
||||
/**
|
||||
* Adds a SEO metabox to selected post types
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param string $post_type Post type.
|
||||
* @param string $post Post object.
|
||||
*/
|
||||
|
||||
function fictioneer_add_seo_metabox( $post_type, $post ) {
|
||||
// Setup
|
||||
$for_these_types = ['post', 'page', 'fcn_story', 'fcn_chapter', 'fcn_collection', 'fcn_recommendation'];
|
||||
$not_these_slugs = ['singular-bookshelf.php', 'singular-bookmarks.php', 'user-profile.php'];
|
||||
function fictioneer_add_seo_metabox( $post_type, $post ) {
|
||||
// Setup
|
||||
$for_these_types = ['post', 'page', 'fcn_story', 'fcn_chapter', 'fcn_collection', 'fcn_recommendation'];
|
||||
$not_these_slugs = ['singular-bookshelf.php', 'singular-bookmarks.php', 'user-profile.php'];
|
||||
|
||||
// Add meta box
|
||||
if ( in_array( $post_type, $for_these_types ) && ! in_array( get_page_template_slug( $post ), $not_these_slugs ) ) {
|
||||
add_meta_box(
|
||||
'fictioneer-search-engine-appearance',
|
||||
__( 'SEO & Meta Tags', 'fictioneer' ),
|
||||
'fictioneer_seo_fields',
|
||||
null,
|
||||
'normal',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
// Add meta box
|
||||
if ( in_array( $post_type, $for_these_types ) && ! in_array( get_page_template_slug( $post ), $not_these_slugs ) ) {
|
||||
add_meta_box(
|
||||
'fictioneer-search-engine-appearance',
|
||||
__( 'SEO & Meta Tags', 'fictioneer' ),
|
||||
'fictioneer_seo_fields',
|
||||
null,
|
||||
'normal',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,48 +145,46 @@ if ( ! function_exists( 'fictioneer_seo_fields' ) ) {
|
||||
// SAVE SEO METABOX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_save_seo_metabox' ) ) {
|
||||
/**
|
||||
* Save SEO metabox data
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
*/
|
||||
/**
|
||||
* Save SEO metabox data
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
*/
|
||||
|
||||
function fictioneer_save_seo_metabox( $post_id ) {
|
||||
// Validations
|
||||
if (
|
||||
! isset( $_POST['fictioneer_metabox_seo_nonce'] ) ||
|
||||
! wp_verify_nonce( $_POST['fictioneer_metabox_seo_nonce'], 'fictioneer-metabox-seo-save' ) ||
|
||||
! current_user_can( 'edit_post', $post_id ) ||
|
||||
wp_is_post_autosave( $post_id ) ||
|
||||
wp_is_post_revision( $post_id ) ||
|
||||
in_array( get_post_status( $post_id ), ['auto-draft'] )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save image
|
||||
if ( isset( $_POST['fictioneer_seo_og_image'] ) ) {
|
||||
update_post_meta( $post_id, 'fictioneer_seo_og_image', $_POST['fictioneer_seo_og_image'] );
|
||||
}
|
||||
|
||||
// Save title
|
||||
if ( isset( $_POST['fictioneer_seo_title'] ) ) {
|
||||
update_post_meta( $post_id, 'fictioneer_seo_title', $_POST['fictioneer_seo_title'] );
|
||||
}
|
||||
|
||||
// Save description
|
||||
if ( isset( $_POST['fictioneer_seo_description'] ) ) {
|
||||
update_post_meta( $post_id, 'fictioneer_seo_description', $_POST['fictioneer_seo_description'] );
|
||||
}
|
||||
|
||||
// Clear caches
|
||||
delete_post_meta( $post_id, 'fictioneer_seo_title_cache' );
|
||||
delete_post_meta( $post_id, 'fictioneer_seo_description_cache' );
|
||||
delete_post_meta( $post_id, 'fictioneer_seo_og_image_cache' );
|
||||
function fictioneer_save_seo_metabox( $post_id ) {
|
||||
// Validations
|
||||
if (
|
||||
! isset( $_POST['fictioneer_metabox_seo_nonce'] ) ||
|
||||
! wp_verify_nonce( $_POST['fictioneer_metabox_seo_nonce'], 'fictioneer-metabox-seo-save' ) ||
|
||||
! current_user_can( 'edit_post', $post_id ) ||
|
||||
wp_is_post_autosave( $post_id ) ||
|
||||
wp_is_post_revision( $post_id ) ||
|
||||
in_array( get_post_status( $post_id ), ['auto-draft'] )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save image
|
||||
if ( isset( $_POST['fictioneer_seo_og_image'] ) ) {
|
||||
update_post_meta( $post_id, 'fictioneer_seo_og_image', $_POST['fictioneer_seo_og_image'] );
|
||||
}
|
||||
|
||||
// Save title
|
||||
if ( isset( $_POST['fictioneer_seo_title'] ) ) {
|
||||
update_post_meta( $post_id, 'fictioneer_seo_title', $_POST['fictioneer_seo_title'] );
|
||||
}
|
||||
|
||||
// Save description
|
||||
if ( isset( $_POST['fictioneer_seo_description'] ) ) {
|
||||
update_post_meta( $post_id, 'fictioneer_seo_description', $_POST['fictioneer_seo_description'] );
|
||||
}
|
||||
|
||||
// Clear caches
|
||||
delete_post_meta( $post_id, 'fictioneer_seo_title_cache' );
|
||||
delete_post_meta( $post_id, 'fictioneer_seo_description_cache' );
|
||||
delete_post_meta( $post_id, 'fictioneer_seo_og_image_cache' );
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_seo' ) && ! fictioneer_seo_plugin_active() ) {
|
||||
@ -617,120 +613,118 @@ if ( ! function_exists( 'fictioneer_get_seo_image' ) ) {
|
||||
// OUTPUT HEAD SEO
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_output_head_seo' ) ) {
|
||||
/**
|
||||
* Output HTML <head> SEO meta
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Output HTML <head> SEO meta
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_output_head_seo() {
|
||||
global $wp;
|
||||
global $post;
|
||||
function fictioneer_output_head_seo() {
|
||||
global $wp;
|
||||
global $post;
|
||||
|
||||
// Setup
|
||||
$post_id = get_queried_object_id(); // In archives and search, this is the first post
|
||||
$post_type = get_post_type(); // In archives and search, this is the first post
|
||||
$post_author = $post->post_author ?? 0;
|
||||
$chapter_story_id = fictioneer_get_field( 'fictioneer_chapter_story' ) ?? 0;
|
||||
$canonical_url = wp_get_canonical_url(); // Unreliable on aggregated pages
|
||||
// Setup
|
||||
$post_id = get_queried_object_id(); // In archives and search, this is the first post
|
||||
$post_type = get_post_type(); // In archives and search, this is the first post
|
||||
$post_author = $post->post_author ?? 0;
|
||||
$chapter_story_id = fictioneer_get_field( 'fictioneer_chapter_story' ) ?? 0;
|
||||
$canonical_url = wp_get_canonical_url(); // Unreliable on aggregated pages
|
||||
|
||||
// Flags
|
||||
$is_page = is_page() || is_front_page() || is_home();
|
||||
$is_aggregated = is_archive() || is_search();
|
||||
$is_article = ! $is_page && in_array( $post_type, ['fcn_story', 'fcn_chapter', 'fcn_recommendation', 'post'] );
|
||||
$show_author = $is_article && is_single() && ! is_front_page() && ! is_home() && ! $is_aggregated;
|
||||
// Flags
|
||||
$is_page = is_page() || is_front_page() || is_home();
|
||||
$is_aggregated = is_archive() || is_search();
|
||||
$is_article = ! $is_page && in_array( $post_type, ['fcn_story', 'fcn_chapter', 'fcn_recommendation', 'post'] );
|
||||
$show_author = $is_article && is_single() && ! is_front_page() && ! is_home() && ! $is_aggregated;
|
||||
|
||||
// Derived
|
||||
$og_type = $is_article ? 'article' : 'website';
|
||||
$og_image = fictioneer_get_seo_image( $post_id );
|
||||
$og_title = fictioneer_get_seo_title( $post_id );
|
||||
$og_description = fictioneer_get_seo_description( $post_id );
|
||||
$article_author = $post_author && $show_author ? get_the_author_meta( 'display_name', $post_author ) : false;
|
||||
$article_twitter = $post_author && $show_author ? get_the_author_meta( 'twitter', $post_author ) : false;
|
||||
// Derived
|
||||
$og_type = $is_article ? 'article' : 'website';
|
||||
$og_image = fictioneer_get_seo_image( $post_id );
|
||||
$og_title = fictioneer_get_seo_title( $post_id );
|
||||
$og_description = fictioneer_get_seo_description( $post_id );
|
||||
$article_author = $post_author && $show_author ? get_the_author_meta( 'display_name', $post_author ) : false;
|
||||
$article_twitter = $post_author && $show_author ? get_the_author_meta( 'twitter', $post_author ) : false;
|
||||
|
||||
// Special Case: Recommendation author
|
||||
if ( $post_author && $show_author && $post_type == 'fcn_recommendation' ) {
|
||||
$article_author = fictioneer_get_field( 'fictioneer_recommendation_author', $post_id ) ?? $article_author;
|
||||
}
|
||||
|
||||
// Special Case: Archives
|
||||
if ( is_archive() ) $canonical_url = home_url( $wp->request );
|
||||
|
||||
// Special Case: Search
|
||||
if ( is_search() ) $canonical_url = add_query_arg( 's', '', home_url( $wp->request ) );
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<link rel="canonical" href="<?php echo $canonical_url; ?>">
|
||||
<meta name="description" content="<?php echo $og_description; ?>">
|
||||
<meta property="og:locale" content="<?php echo get_locale(); ?>">
|
||||
<meta property="og:type" content="<?php echo $og_type; ?>">
|
||||
<meta property="og:title" content="<?php echo $og_title; ?>">
|
||||
<meta property="og:description" content="<?php echo $og_description; ?>">
|
||||
<meta property="og:url" content="<?php echo $canonical_url; ?>">
|
||||
<meta property="og:site_name" content="<?php echo FICTIONEER_SITE_NAME; ?>">
|
||||
|
||||
<?php if ( ! $is_aggregated && $is_article ) : ?>
|
||||
|
||||
<meta property="article:published_time" content="<?php echo get_the_date( 'c' ); ?>">
|
||||
<meta property="article:modified_time" content="<?php echo get_the_modified_date( 'c' ); ?>">
|
||||
|
||||
<?php if ( $show_author && $article_author ) : ?>
|
||||
<?php
|
||||
// Get URL for primary author (if any)
|
||||
$article_author_url = get_the_author_meta( 'url', $post_author );
|
||||
$article_author_url = empty( $article_author_url ) ? get_author_posts_url( $post_author ) : $article_author_url;
|
||||
|
||||
// Prepare author array with either URL (required) or name (better than nothing)
|
||||
$all_authors = empty( $article_author_url ) ? [$article_author] : [$article_author_url];
|
||||
|
||||
// Get co-authors (if any)
|
||||
$co_authors = $post_type == 'fcn_story' ?
|
||||
fictioneer_get_field( 'fictioneer_story_co_authors', $post_id ) ?? [] :
|
||||
fictioneer_get_field( 'fictioneer_chapter_co_authors', $post_id ) ?? [];
|
||||
|
||||
// Add co-authors URL or name
|
||||
if ( ! empty( $co_authors ) ) {
|
||||
foreach ( $co_authors as $co_author_id ) {
|
||||
$co_author_name = get_the_author_meta( 'display_name', intval( $co_author_id ) );
|
||||
$co_author_url = get_the_author_meta( 'url', intval( $co_author_id ) );
|
||||
$co_author_url = empty( $co_author_url ) ? get_author_posts_url( $co_author_id ) : $co_author_url;
|
||||
$author_item = empty( $co_author_url ) ? $co_author_name : $co_author_url;
|
||||
if ( ! empty( $author_item ) && ! in_array( $author_item, $all_authors ) ) $all_authors[] = $author_item;
|
||||
}
|
||||
}
|
||||
|
||||
// Output og array
|
||||
foreach ( $all_authors as $author_name ) {
|
||||
echo "<meta property='article:author' content='$author_name'>";
|
||||
}
|
||||
?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( $post_type == 'fcn_chapter' && ! empty( $chapter_story_id ) ) : ?>
|
||||
<meta property="article:section" content="<?php echo get_the_title( $chapter_story_id ); ?>">
|
||||
<?php endif; ?>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( is_array( $og_image ) && count( $og_image ) >= 4 ) : ?>
|
||||
<meta property="og:image" content="<?php echo $og_image['url']; ?>">
|
||||
<meta property="og:image:width" content="<?php echo $og_image['width']; ?>">
|
||||
<meta property="og:image:height" content="<?php echo $og_image['height']; ?>">
|
||||
<meta property="og:image:type" content="<?php echo $og_image['type']; ?>">
|
||||
<meta name="twitter:image" content="<?php echo $og_image['url']; ?>">
|
||||
<?php endif; ?>
|
||||
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:title" content="<?php echo $og_title; ?>">
|
||||
<meta name="twitter:description" content="<?php echo $og_description; ?>">
|
||||
|
||||
<?php if ( $show_author && $article_twitter ) : ?>
|
||||
<meta name="twitter:creator" content="<?php echo '@' . $article_twitter; ?>">
|
||||
<meta name="twitter:site" content="<?php echo '@' . $article_twitter; ?>">
|
||||
<?php endif; ?>
|
||||
<?php // <--- End HTML
|
||||
// Special Case: Recommendation author
|
||||
if ( $post_author && $show_author && $post_type == 'fcn_recommendation' ) {
|
||||
$article_author = fictioneer_get_field( 'fictioneer_recommendation_author', $post_id ) ?? $article_author;
|
||||
}
|
||||
|
||||
// Special Case: Archives
|
||||
if ( is_archive() ) $canonical_url = home_url( $wp->request );
|
||||
|
||||
// Special Case: Search
|
||||
if ( is_search() ) $canonical_url = add_query_arg( 's', '', home_url( $wp->request ) );
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<link rel="canonical" href="<?php echo $canonical_url; ?>">
|
||||
<meta name="description" content="<?php echo $og_description; ?>">
|
||||
<meta property="og:locale" content="<?php echo get_locale(); ?>">
|
||||
<meta property="og:type" content="<?php echo $og_type; ?>">
|
||||
<meta property="og:title" content="<?php echo $og_title; ?>">
|
||||
<meta property="og:description" content="<?php echo $og_description; ?>">
|
||||
<meta property="og:url" content="<?php echo $canonical_url; ?>">
|
||||
<meta property="og:site_name" content="<?php echo FICTIONEER_SITE_NAME; ?>">
|
||||
|
||||
<?php if ( ! $is_aggregated && $is_article ) : ?>
|
||||
|
||||
<meta property="article:published_time" content="<?php echo get_the_date( 'c' ); ?>">
|
||||
<meta property="article:modified_time" content="<?php echo get_the_modified_date( 'c' ); ?>">
|
||||
|
||||
<?php if ( $show_author && $article_author ) : ?>
|
||||
<?php
|
||||
// Get URL for primary author (if any)
|
||||
$article_author_url = get_the_author_meta( 'url', $post_author );
|
||||
$article_author_url = empty( $article_author_url ) ? get_author_posts_url( $post_author ) : $article_author_url;
|
||||
|
||||
// Prepare author array with either URL (required) or name (better than nothing)
|
||||
$all_authors = empty( $article_author_url ) ? [$article_author] : [$article_author_url];
|
||||
|
||||
// Get co-authors (if any)
|
||||
$co_authors = $post_type == 'fcn_story' ?
|
||||
fictioneer_get_field( 'fictioneer_story_co_authors', $post_id ) ?? [] :
|
||||
fictioneer_get_field( 'fictioneer_chapter_co_authors', $post_id ) ?? [];
|
||||
|
||||
// Add co-authors URL or name
|
||||
if ( ! empty( $co_authors ) ) {
|
||||
foreach ( $co_authors as $co_author_id ) {
|
||||
$co_author_name = get_the_author_meta( 'display_name', intval( $co_author_id ) );
|
||||
$co_author_url = get_the_author_meta( 'url', intval( $co_author_id ) );
|
||||
$co_author_url = empty( $co_author_url ) ? get_author_posts_url( $co_author_id ) : $co_author_url;
|
||||
$author_item = empty( $co_author_url ) ? $co_author_name : $co_author_url;
|
||||
if ( ! empty( $author_item ) && ! in_array( $author_item, $all_authors ) ) $all_authors[] = $author_item;
|
||||
}
|
||||
}
|
||||
|
||||
// Output og array
|
||||
foreach ( $all_authors as $author_name ) {
|
||||
echo "<meta property='article:author' content='$author_name'>";
|
||||
}
|
||||
?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( $post_type == 'fcn_chapter' && ! empty( $chapter_story_id ) ) : ?>
|
||||
<meta property="article:section" content="<?php echo get_the_title( $chapter_story_id ); ?>">
|
||||
<?php endif; ?>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( is_array( $og_image ) && count( $og_image ) >= 4 ) : ?>
|
||||
<meta property="og:image" content="<?php echo $og_image['url']; ?>">
|
||||
<meta property="og:image:width" content="<?php echo $og_image['width']; ?>">
|
||||
<meta property="og:image:height" content="<?php echo $og_image['height']; ?>">
|
||||
<meta property="og:image:type" content="<?php echo $og_image['type']; ?>">
|
||||
<meta name="twitter:image" content="<?php echo $og_image['url']; ?>">
|
||||
<?php endif; ?>
|
||||
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:title" content="<?php echo $og_title; ?>">
|
||||
<meta name="twitter:description" content="<?php echo $og_description; ?>">
|
||||
|
||||
<?php if ( $show_author && $article_twitter ) : ?>
|
||||
<meta name="twitter:creator" content="<?php echo '@' . $article_twitter; ?>">
|
||||
<meta name="twitter:site" content="<?php echo '@' . $article_twitter; ?>">
|
||||
<?php endif; ?>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_seo' ) && ! fictioneer_seo_plugin_active() ) {
|
||||
|
@ -70,180 +70,178 @@ function fictioneer_url_node( $loc, $lastmod = null, $freq = null ) {
|
||||
return $node;
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_create_sitemap' ) ) {
|
||||
function fictioneer_create_sitemap( $last_saved_id ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $last_saved_id ) ) {
|
||||
return;
|
||||
function fictioneer_create_sitemap( $last_saved_id ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $last_saved_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only rebuild necessary part of the sitemap
|
||||
$last_saved_type = get_post_type( $last_saved_id );
|
||||
|
||||
// Only consider these post types
|
||||
$allowed_types = ['page', 'post', 'fcn_story', 'fcn_chapter', 'fcn_recommendation', 'fcn_collection'];
|
||||
|
||||
if ( in_array( $last_saved_type, $allowed_types ) ) {
|
||||
// Open
|
||||
$sitemap = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
|
||||
$sitemap .= '<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
|
||||
|
||||
// Blog and front page
|
||||
$sitemap .= fictioneer_url_node( esc_url( home_url( '/' ) ), current_time( 'c' ), 'daily' );
|
||||
$sitemap .= fictioneer_url_node( get_permalink( get_option( 'page_for_posts' ) ), current_time( 'c' ), 'daily' );
|
||||
|
||||
// Pages
|
||||
$pages = $last_saved_type == 'page' ? false : get_transient( 'fictioneer_sitemap_pages' );
|
||||
|
||||
if ( ! $pages ) {
|
||||
$pages = get_posts( array(
|
||||
'post_type' => 'page',
|
||||
'post_status' => array( 'publish' ),
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'numberposts' => '1000',
|
||||
'post__not_in' => [get_option( 'page_on_front' ), get_option( 'page_for_posts' )]
|
||||
));
|
||||
set_transient( 'fictioneer_sitemap_pages', $pages );
|
||||
}
|
||||
|
||||
// Only rebuild necessary part of the sitemap
|
||||
$last_saved_type = get_post_type( $last_saved_id );
|
||||
foreach( $pages as $post ) {
|
||||
$template = get_page_template_slug( $post->ID );
|
||||
if ( in_array( $template, ['user-profile.php', 'single-bookmarks.php'] ) ) continue;
|
||||
$frequency = 'yearly';
|
||||
$lastmod = get_the_modified_date( 'c', $post->ID );
|
||||
$sitemap .= fictioneer_url_node( get_permalink( $post->ID ), $lastmod, 'yearly' );
|
||||
}
|
||||
|
||||
// Only consider these post types
|
||||
$allowed_types = ['page', 'post', 'fcn_story', 'fcn_chapter', 'fcn_recommendation', 'fcn_collection'];
|
||||
// Blogposts
|
||||
$blogposts = $last_saved_type == 'post' ? false : get_transient( 'fictioneer_sitemap_posts' );
|
||||
|
||||
if ( in_array( $last_saved_type, $allowed_types ) ) {
|
||||
// Open
|
||||
$sitemap = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
|
||||
$sitemap .= '<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
|
||||
if ( ! $blogposts ) {
|
||||
$blogposts = get_posts( array(
|
||||
'post_type' => 'post',
|
||||
'post_status' => array( 'publish' ),
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'numberposts' => '1000'
|
||||
));
|
||||
set_transient( 'fictioneer_sitemap_posts', $blogposts );
|
||||
}
|
||||
|
||||
// Blog and front page
|
||||
$sitemap .= fictioneer_url_node( esc_url( home_url( '/' ) ), current_time( 'c' ), 'daily' );
|
||||
$sitemap .= fictioneer_url_node( get_permalink( get_option( 'page_for_posts' ) ), current_time( 'c' ), 'daily' );
|
||||
foreach( $blogposts as $post ) {
|
||||
$lastmod = get_the_modified_date( 'c', $post->ID );
|
||||
$sitemap .= fictioneer_url_node( get_permalink( $post->ID ), $lastmod, 'never' );
|
||||
}
|
||||
|
||||
// Pages
|
||||
$pages = $last_saved_type == 'page' ? false : get_transient( 'fictioneer_sitemap_pages' );
|
||||
// Collections
|
||||
$collections = $last_saved_type == 'fcn_collection' ? false : get_transient( 'fictioneer_sitemap_collections' );
|
||||
|
||||
if ( ! $pages ) {
|
||||
$pages = get_posts( array(
|
||||
'post_type' => 'page',
|
||||
if ( ! $collections ) {
|
||||
$collections = get_posts( array(
|
||||
'post_type' => 'fcn_collection',
|
||||
'post_status' => array( 'publish' ),
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'numberposts' => '1000'
|
||||
));
|
||||
set_transient( 'fictioneer_sitemap_collections', $collections );
|
||||
}
|
||||
|
||||
foreach( $collections as $post ) {
|
||||
$lastmod = get_the_modified_date( 'c', $post->ID );
|
||||
$sitemap .= fictioneer_url_node( get_permalink( $post->ID ), $lastmod, 'monthly' );
|
||||
}
|
||||
|
||||
// Stories
|
||||
$stories = $last_saved_type == 'fcn_story' ? false : get_transient( 'fictioneer_sitemap_stories' );
|
||||
|
||||
if ( ! $stories ) {
|
||||
$stories = get_posts(
|
||||
array(
|
||||
'post_type' => 'fcn_story',
|
||||
'post_status' => array( 'publish' ),
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'numberposts' => '1000',
|
||||
'post__not_in' => [get_option( 'page_on_front' ), get_option( 'page_for_posts' )]
|
||||
));
|
||||
set_transient( 'fictioneer_sitemap_pages', $pages );
|
||||
}
|
||||
|
||||
foreach( $pages as $post ) {
|
||||
$template = get_page_template_slug( $post->ID );
|
||||
if ( in_array( $template, ['user-profile.php', 'single-bookmarks.php'] ) ) continue;
|
||||
$frequency = 'yearly';
|
||||
$lastmod = get_the_modified_date( 'c', $post->ID );
|
||||
$sitemap .= fictioneer_url_node( get_permalink( $post->ID ), $lastmod, 'yearly' );
|
||||
}
|
||||
|
||||
// Blogposts
|
||||
$blogposts = $last_saved_type == 'post' ? false : get_transient( 'fictioneer_sitemap_posts' );
|
||||
|
||||
if ( ! $blogposts ) {
|
||||
$blogposts = get_posts( array(
|
||||
'post_type' => 'post',
|
||||
'post_status' => array( 'publish' ),
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'numberposts' => '1000'
|
||||
));
|
||||
set_transient( 'fictioneer_sitemap_posts', $blogposts );
|
||||
}
|
||||
|
||||
foreach( $blogposts as $post ) {
|
||||
$lastmod = get_the_modified_date( 'c', $post->ID );
|
||||
$sitemap .= fictioneer_url_node( get_permalink( $post->ID ), $lastmod, 'never' );
|
||||
}
|
||||
|
||||
// Collections
|
||||
$collections = $last_saved_type == 'fcn_collection' ? false : get_transient( 'fictioneer_sitemap_collections' );
|
||||
|
||||
if ( ! $collections ) {
|
||||
$collections = get_posts( array(
|
||||
'post_type' => 'fcn_collection',
|
||||
'post_status' => array( 'publish' ),
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'numberposts' => '1000'
|
||||
));
|
||||
set_transient( 'fictioneer_sitemap_collections', $collections );
|
||||
}
|
||||
|
||||
foreach( $collections as $post ) {
|
||||
$lastmod = get_the_modified_date( 'c', $post->ID );
|
||||
$sitemap .= fictioneer_url_node( get_permalink( $post->ID ), $lastmod, 'monthly' );
|
||||
}
|
||||
|
||||
// Stories
|
||||
$stories = $last_saved_type == 'fcn_story' ? false : get_transient( 'fictioneer_sitemap_stories' );
|
||||
|
||||
if ( ! $stories ) {
|
||||
$stories = get_posts(
|
||||
array(
|
||||
'post_type' => 'fcn_story',
|
||||
'post_status' => array( 'publish' ),
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'numberposts' => '2000',
|
||||
'meta_query' => array(
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'key' => 'fictioneer_story_hidden',
|
||||
'value' => '0'
|
||||
),
|
||||
array(
|
||||
'key' => 'fictioneer_story_hidden',
|
||||
'compare' => 'NOT EXISTS'
|
||||
)
|
||||
'numberposts' => '2000',
|
||||
'meta_query' => array(
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'key' => 'fictioneer_story_hidden',
|
||||
'value' => '0'
|
||||
),
|
||||
array(
|
||||
'key' => 'fictioneer_story_hidden',
|
||||
'compare' => 'NOT EXISTS'
|
||||
)
|
||||
)
|
||||
);
|
||||
set_transient( 'fictioneer_sitemap_stories', $stories );
|
||||
}
|
||||
|
||||
foreach ( $stories as $post ) {
|
||||
$lastmod = get_the_modified_date( 'c', $post->ID );
|
||||
$status = fictioneer_get_field( 'fictioneer_story_status', $post->ID );
|
||||
$frequency = $status == 'Ongoing' ? 'weekly' : 'monthly';
|
||||
$sitemap .= fictioneer_url_node( get_permalink( $post->ID ), $lastmod, $frequency );
|
||||
}
|
||||
|
||||
// Chapters
|
||||
$chapters = $last_saved_type == 'fcn_chapter' ? false : get_transient( 'fictioneer_sitemap_chapters' );
|
||||
|
||||
if ( ! $chapters ) {
|
||||
$chapters = get_posts( array(
|
||||
'post_type' => 'fcn_chapter',
|
||||
'post_status' => array( 'publish' ),
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'numberposts' => '10000',
|
||||
'meta_query' => array(
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'key' => 'fictioneer_chapter_hidden',
|
||||
'value' => '0'
|
||||
),
|
||||
array(
|
||||
'key' => 'fictioneer_chapter_hidden',
|
||||
'compare' => 'NOT EXISTS'
|
||||
)
|
||||
)
|
||||
));
|
||||
set_transient( 'fictioneer_sitemap_chapters', $chapters );
|
||||
}
|
||||
|
||||
foreach( $chapters as $post ) {
|
||||
$lastmod = get_the_modified_date( 'c', $post->ID );
|
||||
$sitemap .= fictioneer_url_node( get_permalink( $post->ID ), $lastmod, 'monthly' );
|
||||
}
|
||||
|
||||
// Recommendations
|
||||
$recommendations = $last_saved_type == 'fcn_recommendation' ? false : get_transient( 'fictioneer_sitemap_recommendations' );
|
||||
|
||||
if ( ! $recommendations ) {
|
||||
$recommendations = get_posts( array(
|
||||
'post_type' => 'fcn_recommendation',
|
||||
'post_status' => array( 'publish' ),
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'numberposts' => '1000'
|
||||
));
|
||||
set_transient( 'fictioneer_sitemap_recommendations', $recommendations );
|
||||
}
|
||||
|
||||
foreach( $recommendations as $post ) {
|
||||
$lastmod = get_the_modified_date( 'c', $post->ID );
|
||||
$sitemap .= fictioneer_url_node( get_permalink( $post->ID ), $lastmod, 'yearly' );
|
||||
}
|
||||
|
||||
// End
|
||||
$sitemap .= "\n" . '</urlset>';
|
||||
|
||||
// Save
|
||||
$file_path = fopen( ABSPATH . '/sitemap.xml', 'w' );
|
||||
fwrite( $file_path, $sitemap );
|
||||
fclose( $file_path );
|
||||
)
|
||||
);
|
||||
set_transient( 'fictioneer_sitemap_stories', $stories );
|
||||
}
|
||||
|
||||
foreach ( $stories as $post ) {
|
||||
$lastmod = get_the_modified_date( 'c', $post->ID );
|
||||
$status = fictioneer_get_field( 'fictioneer_story_status', $post->ID );
|
||||
$frequency = $status == 'Ongoing' ? 'weekly' : 'monthly';
|
||||
$sitemap .= fictioneer_url_node( get_permalink( $post->ID ), $lastmod, $frequency );
|
||||
}
|
||||
|
||||
// Chapters
|
||||
$chapters = $last_saved_type == 'fcn_chapter' ? false : get_transient( 'fictioneer_sitemap_chapters' );
|
||||
|
||||
if ( ! $chapters ) {
|
||||
$chapters = get_posts( array(
|
||||
'post_type' => 'fcn_chapter',
|
||||
'post_status' => array( 'publish' ),
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'numberposts' => '10000',
|
||||
'meta_query' => array(
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'key' => 'fictioneer_chapter_hidden',
|
||||
'value' => '0'
|
||||
),
|
||||
array(
|
||||
'key' => 'fictioneer_chapter_hidden',
|
||||
'compare' => 'NOT EXISTS'
|
||||
)
|
||||
)
|
||||
));
|
||||
set_transient( 'fictioneer_sitemap_chapters', $chapters );
|
||||
}
|
||||
|
||||
foreach( $chapters as $post ) {
|
||||
$lastmod = get_the_modified_date( 'c', $post->ID );
|
||||
$sitemap .= fictioneer_url_node( get_permalink( $post->ID ), $lastmod, 'monthly' );
|
||||
}
|
||||
|
||||
// Recommendations
|
||||
$recommendations = $last_saved_type == 'fcn_recommendation' ? false : get_transient( 'fictioneer_sitemap_recommendations' );
|
||||
|
||||
if ( ! $recommendations ) {
|
||||
$recommendations = get_posts( array(
|
||||
'post_type' => 'fcn_recommendation',
|
||||
'post_status' => array( 'publish' ),
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'numberposts' => '1000'
|
||||
));
|
||||
set_transient( 'fictioneer_sitemap_recommendations', $recommendations );
|
||||
}
|
||||
|
||||
foreach( $recommendations as $post ) {
|
||||
$lastmod = get_the_modified_date( 'c', $post->ID );
|
||||
$sitemap .= fictioneer_url_node( get_permalink( $post->ID ), $lastmod, 'yearly' );
|
||||
}
|
||||
|
||||
// End
|
||||
$sitemap .= "\n" . '</urlset>';
|
||||
|
||||
// Save
|
||||
$file_path = fopen( ABSPATH . '/sitemap.xml', 'w' );
|
||||
fwrite( $file_path, $sitemap );
|
||||
fclose( $file_path );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,15 +363,15 @@ add_action( 'get_footer', 'fictioneer_style_footer_queue' );
|
||||
// FONT AWESOME 6+
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Add Font Awesome 6+ to the site
|
||||
*
|
||||
* @since 4.5
|
||||
* @link https://fontawesome.com/docs/web/use-with/wordpress/install-manually
|
||||
* @link https://fontawesome.com/account/cdn
|
||||
*/
|
||||
|
||||
if ( ! function_exists( 'fa_custom_setup_cdn_webfont' ) ) {
|
||||
/**
|
||||
* Add Font Awesome 6+ to the site
|
||||
*
|
||||
* @since 4.5
|
||||
* @link https://fontawesome.com/docs/web/use-with/wordpress/install-manually
|
||||
* @link https://fontawesome.com/account/cdn
|
||||
*/
|
||||
|
||||
function fa_custom_setup_cdn_webfont( $cdn_url = '', $integrity = null ) {
|
||||
$matches = [];
|
||||
$match_result = preg_match( '|/([^/]+?)\.css$|', $cdn_url, $matches );
|
||||
|
@ -4,20 +4,18 @@
|
||||
// MAINTENANCE MODE
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_maintenance_mode' ) ) {
|
||||
/**
|
||||
* Toggle maintenance mode from settings with message
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
/**
|
||||
* Toggle maintenance mode from settings with message
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_maintenance_mode() {
|
||||
if ( get_option( 'fictioneer_enable_maintenance_mode' ) ) {
|
||||
if ( ! current_user_can( 'edit_themes' ) || ! is_user_logged_in() ) {
|
||||
$note = get_option( 'fictioneer_phrase_maintenance' );
|
||||
$note = ! empty( $note ) ? $note : __( 'Website under planned maintenance. Please check back later.', 'fictioneer' );
|
||||
wp_die( __( '<h1>Under Maintenance</h1><br>', 'fictioneer' ) . $note );
|
||||
}
|
||||
function fictioneer_maintenance_mode() {
|
||||
if ( get_option( 'fictioneer_enable_maintenance_mode' ) ) {
|
||||
if ( ! current_user_can( 'edit_themes' ) || ! is_user_logged_in() ) {
|
||||
$note = get_option( 'fictioneer_phrase_maintenance' );
|
||||
$note = ! empty( $note ) ? $note : __( 'Website under planned maintenance. Please check back later.', 'fictioneer' );
|
||||
wp_die( __( '<h1>Under Maintenance</h1><br>', 'fictioneer' ) . $note );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -56,14 +54,12 @@ if ( get_option( 'fictioneer_enable_sitemap' ) && ! fictioneer_seo_plugin_active
|
||||
// CUSTOM EXCERPT LENGTH
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_custom_excerpt_length' ) ) {
|
||||
/**
|
||||
* Change excerpt length
|
||||
*/
|
||||
/**
|
||||
* Change excerpt length
|
||||
*/
|
||||
|
||||
function fictioneer_custom_excerpt_length( $length ) {
|
||||
return 64;
|
||||
}
|
||||
function fictioneer_custom_excerpt_length( $length ) {
|
||||
return 64;
|
||||
}
|
||||
add_filter( 'excerpt_length', 'fictioneer_custom_excerpt_length', 999 );
|
||||
|
||||
@ -71,22 +67,20 @@ add_filter( 'excerpt_length', 'fictioneer_custom_excerpt_length', 999 );
|
||||
// FIX EXCERPT FORMATTING
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_fix_excerpt' ) ) {
|
||||
/**
|
||||
* Fix inconsistent line breaks in excerpts
|
||||
*
|
||||
* @since 4.0
|
||||
* @link https://github.com/WordPress/gutenberg/issues/15117
|
||||
*
|
||||
* @param string $excerpt The post excerpt.
|
||||
*/
|
||||
/**
|
||||
* Fix inconsistent line breaks in excerpts
|
||||
*
|
||||
* @since 4.0
|
||||
* @link https://github.com/WordPress/gutenberg/issues/15117
|
||||
*
|
||||
* @param string $excerpt The post excerpt.
|
||||
*/
|
||||
|
||||
function fictioneer_fix_excerpt( $excerpt ) {
|
||||
add_filter( 'the_content', 'fictioneer_replace_br_with_whitespace', 6 );
|
||||
$excerpt = wp_trim_excerpt( $excerpt );
|
||||
remove_filter( 'the_content', 'fictioneer_replace_br_with_whitespace', 6 );
|
||||
return $excerpt;
|
||||
}
|
||||
function fictioneer_fix_excerpt( $excerpt ) {
|
||||
add_filter( 'the_content', 'fictioneer_replace_br_with_whitespace', 6 );
|
||||
$excerpt = wp_trim_excerpt( $excerpt );
|
||||
remove_filter( 'the_content', 'fictioneer_replace_br_with_whitespace', 6 );
|
||||
return $excerpt;
|
||||
}
|
||||
remove_filter( 'get_the_excerpt', 'wp_trim_excerpt' );
|
||||
add_filter( 'get_the_excerpt', 'fictioneer_fix_excerpt' );
|
||||
@ -107,39 +101,37 @@ function fictioneer_replace_br_with_whitespace( $text ) {
|
||||
// UPDATE MODIFIED DATE OF STORY WHEN CHAPTER IS UPDATED
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_update_modified_date_on_story_for_chapter' ) ) {
|
||||
/**
|
||||
* Update modified date of story when chapter is updated
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
*/
|
||||
/**
|
||||
* Update modified date of story when chapter is updated
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
*/
|
||||
|
||||
function fictioneer_update_modified_date_on_story_for_chapter( $post_id ) {
|
||||
global $wpdb;
|
||||
function fictioneer_update_modified_date_on_story_for_chapter( $post_id ) {
|
||||
global $wpdb;
|
||||
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Chapter updated?
|
||||
if ( get_post_type( $post_id ) != 'fcn_chapter' ) return;
|
||||
|
||||
// Setup
|
||||
$story_id = fictioneer_get_field( 'fictioneer_chapter_story', $post_id );
|
||||
|
||||
// No linked story found
|
||||
if ( empty( $story_id ) ) return;
|
||||
|
||||
// Get current time for update (close enough to the chapter)
|
||||
$post_modified = current_time( 'mysql' );
|
||||
$post_modified_gmt = current_time( 'mysql', true );
|
||||
|
||||
// Update database
|
||||
$wpdb->query( "UPDATE $wpdb->posts SET post_modified = '{$post_modified}', post_modified_gmt = '{$post_modified_gmt}' WHERE ID = {$story_id}" );
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Chapter updated?
|
||||
if ( get_post_type( $post_id ) != 'fcn_chapter' ) return;
|
||||
|
||||
// Setup
|
||||
$story_id = fictioneer_get_field( 'fictioneer_chapter_story', $post_id );
|
||||
|
||||
// No linked story found
|
||||
if ( empty( $story_id ) ) return;
|
||||
|
||||
// Get current time for update (close enough to the chapter)
|
||||
$post_modified = current_time( 'mysql' );
|
||||
$post_modified_gmt = current_time( 'mysql', true );
|
||||
|
||||
// Update database
|
||||
$wpdb->query( "UPDATE $wpdb->posts SET post_modified = '{$post_modified}', post_modified_gmt = '{$post_modified_gmt}' WHERE ID = {$story_id}" );
|
||||
}
|
||||
add_action( 'save_post', 'fictioneer_update_modified_date_on_story_for_chapter' );
|
||||
add_action( 'trashed_post', 'fictioneer_update_modified_date_on_story_for_chapter' );
|
||||
@ -150,33 +142,31 @@ add_action( 'untrash_post', 'fictioneer_update_modified_date_on_story_for_chapte
|
||||
// STORE WORD COUNT AS CUSTOM FIELD
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_save_word_count' ) ) {
|
||||
/**
|
||||
* Store word count of posts as meta data
|
||||
*
|
||||
* @since 3.0
|
||||
* @see update_post_meta()
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
*/
|
||||
/**
|
||||
* Store word count of posts as meta data
|
||||
*
|
||||
* @since 3.0
|
||||
* @see update_post_meta()
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
*/
|
||||
|
||||
function fictioneer_save_word_count( $post_id ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare
|
||||
$content = get_post_field( 'post_content', $post_id );
|
||||
$content = strip_shortcodes( $content );
|
||||
$content = strip_tags( $content );
|
||||
|
||||
// Count
|
||||
$word_count = str_word_count( $content );
|
||||
|
||||
// Remember
|
||||
update_post_meta( $post_id, '_word_count', $word_count );
|
||||
function fictioneer_save_word_count( $post_id ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare
|
||||
$content = get_post_field( 'post_content', $post_id );
|
||||
$content = strip_shortcodes( $content );
|
||||
$content = strip_tags( $content );
|
||||
|
||||
// Count
|
||||
$word_count = str_word_count( $content );
|
||||
|
||||
// Remember
|
||||
update_post_meta( $post_id, '_word_count', $word_count );
|
||||
}
|
||||
add_action( 'save_post', 'fictioneer_save_word_count' );
|
||||
|
||||
@ -212,41 +202,39 @@ if ( get_option( 'fictioneer_reduce_admin_bar' ) ) {
|
||||
// LOGOUT REDIRECT
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_logout_redirect' ) ) {
|
||||
/**
|
||||
* Change redirect after logout
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @param string $logout_url The HTML-encoded logout URL.
|
||||
* @param string $redirect Path to redirect to on logout.
|
||||
*
|
||||
* @return string $logout_url The updated logout URL.
|
||||
*/
|
||||
/**
|
||||
* Change redirect after logout
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @param string $logout_url The HTML-encoded logout URL.
|
||||
* @param string $redirect Path to redirect to on logout.
|
||||
*
|
||||
* @return string $logout_url The updated logout URL.
|
||||
*/
|
||||
|
||||
function fictioneer_logout_redirect( $logout_url, $redirect ) {
|
||||
// Setup
|
||||
$args = [];
|
||||
function fictioneer_logout_redirect( $logout_url, $redirect ) {
|
||||
// Setup
|
||||
$args = [];
|
||||
|
||||
// Add redirect to args
|
||||
if ( empty( $redirect ) ) {
|
||||
$args['redirect_to'] = urlencode( get_permalink() );
|
||||
} else {
|
||||
$args['redirect_to'] = urlencode( $redirect );
|
||||
}
|
||||
|
||||
// Avoid login page
|
||||
if ( is_admin() || empty( $redirect ) ) {
|
||||
$args['redirect_to'] = urlencode( get_home_url() );
|
||||
}
|
||||
|
||||
// Rebuild logout URL
|
||||
$logout_url = add_query_arg( $args, site_url( 'wp-login.php?action=logout', 'login' ) );
|
||||
$logout_url = wp_nonce_url( $logout_url, 'log-out' );
|
||||
|
||||
// Return updated logout URL
|
||||
return $logout_url;
|
||||
// Add redirect to args
|
||||
if ( empty( $redirect ) ) {
|
||||
$args['redirect_to'] = urlencode( get_permalink() );
|
||||
} else {
|
||||
$args['redirect_to'] = urlencode( $redirect );
|
||||
}
|
||||
|
||||
// Avoid login page
|
||||
if ( is_admin() || empty( $redirect ) ) {
|
||||
$args['redirect_to'] = urlencode( get_home_url() );
|
||||
}
|
||||
|
||||
// Rebuild logout URL
|
||||
$logout_url = add_query_arg( $args, site_url( 'wp-login.php?action=logout', 'login' ) );
|
||||
$logout_url = wp_nonce_url( $logout_url, 'log-out' );
|
||||
|
||||
// Return updated logout URL
|
||||
return $logout_url;
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_logout_redirects_home' ) ) {
|
||||
@ -257,58 +245,54 @@ if ( get_option( 'fictioneer_logout_redirects_home' ) ) {
|
||||
// CUSTOM LOGOUT
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_add_logout_endpoint' ) ) {
|
||||
/**
|
||||
* Add route to logout script
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Add route to logout script
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_add_logout_endpoint() {
|
||||
add_rewrite_endpoint( FICTIONEER_LOGOUT_ENDPOINT, EP_ROOT );
|
||||
}
|
||||
function fictioneer_add_logout_endpoint() {
|
||||
add_rewrite_endpoint( FICTIONEER_LOGOUT_ENDPOINT, EP_ROOT );
|
||||
}
|
||||
|
||||
if ( FICTIONEER_LOGOUT_ENDPOINT && ! get_option( 'fictioneer_disable_theme_logout' ) ) {
|
||||
add_action( 'init', 'fictioneer_add_logout_endpoint', 10 );
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_logout' ) ) {
|
||||
/**
|
||||
* Logout without _wpnonce and no login screen
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
/**
|
||||
* Logout without _wpnonce and no login screen
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_logout() {
|
||||
global $wp;
|
||||
function fictioneer_logout() {
|
||||
global $wp;
|
||||
|
||||
// Abort if not on logout route
|
||||
if ( $wp->request != FICTIONEER_LOGOUT_ENDPOINT ) return;
|
||||
// Abort if not on logout route
|
||||
if ( $wp->request != FICTIONEER_LOGOUT_ENDPOINT ) return;
|
||||
|
||||
// Redirect home if not logged-in
|
||||
if ( ! is_user_logged_in() ) wp_safe_redirect( get_home_url() );
|
||||
// Redirect home if not logged-in
|
||||
if ( ! is_user_logged_in() ) wp_safe_redirect( get_home_url() );
|
||||
|
||||
// Setup
|
||||
$user = wp_get_current_user();
|
||||
// Setup
|
||||
$user = wp_get_current_user();
|
||||
|
||||
// Default WP logout
|
||||
wp_logout();
|
||||
// Default WP logout
|
||||
wp_logout();
|
||||
|
||||
// Redirect URL
|
||||
if ( empty( $_REQUEST['redirect_to'] ) ) {
|
||||
$redirect_to = get_home_url();
|
||||
} else {
|
||||
$redirect_to = $_REQUEST['redirect_to'];
|
||||
}
|
||||
|
||||
// Apply default filters
|
||||
$redirect_to = apply_filters( 'logout_redirect', $redirect_to, $redirect_to, $user );
|
||||
|
||||
// Redirect
|
||||
wp_safe_redirect( $redirect_to );
|
||||
exit;
|
||||
// Redirect URL
|
||||
if ( empty( $_REQUEST['redirect_to'] ) ) {
|
||||
$redirect_to = get_home_url();
|
||||
} else {
|
||||
$redirect_to = $_REQUEST['redirect_to'];
|
||||
}
|
||||
|
||||
// Apply default filters
|
||||
$redirect_to = apply_filters( 'logout_redirect', $redirect_to, $redirect_to, $user );
|
||||
|
||||
// Redirect
|
||||
wp_safe_redirect( $redirect_to );
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( FICTIONEER_LOGOUT_ENDPOINT && ! get_option( 'fictioneer_disable_theme_logout' ) ) {
|
||||
@ -350,21 +334,19 @@ if ( ! function_exists( 'fictioneer_get_logout_url' ) ) {
|
||||
// SHOW CUSTOM POST TYPES ON TAG/CATEGORY ARCHIVES
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_extend_taxonomy_pages' ) ) {
|
||||
/**
|
||||
* Show custom post types in tag and category archives
|
||||
*
|
||||
* @since 4.0
|
||||
* @link https://wordpress.stackexchange.com/a/28147/223620
|
||||
*
|
||||
* @param WP_Query $query The query.
|
||||
*/
|
||||
/**
|
||||
* Show custom post types in tag and category archives
|
||||
*
|
||||
* @since 4.0
|
||||
* @link https://wordpress.stackexchange.com/a/28147/223620
|
||||
*
|
||||
* @param WP_Query $query The query.
|
||||
*/
|
||||
|
||||
function fictioneer_extend_taxonomy_pages( $query ) {
|
||||
if ( ( is_tag() || is_tax( 'fcn_genre' ) || is_tax( 'fcn_fandom' ) || is_tax( 'fcn_character' ) || is_tax( 'fcn_content_warning' ) || is_category() ) && $query->is_main_query() && ! is_admin() ) {
|
||||
$post_types = array( 'post', 'fcn_story', 'fcn_chapter', 'fcn_recommendation', 'fcn_collection' );
|
||||
$query->set( 'post_type', $post_types );
|
||||
}
|
||||
function fictioneer_extend_taxonomy_pages( $query ) {
|
||||
if ( ( is_tag() || is_tax( 'fcn_genre' ) || is_tax( 'fcn_fandom' ) || is_tax( 'fcn_character' ) || is_tax( 'fcn_content_warning' ) || is_category() ) && $query->is_main_query() && ! is_admin() ) {
|
||||
$post_types = array( 'post', 'fcn_story', 'fcn_chapter', 'fcn_recommendation', 'fcn_collection' );
|
||||
$query->set( 'post_type', $post_types );
|
||||
}
|
||||
}
|
||||
add_filter( 'pre_get_posts', 'fictioneer_extend_taxonomy_pages' );
|
||||
@ -443,62 +425,60 @@ if ( get_option( 'fictioneer_enable_theme_rss' ) ) {
|
||||
// OUTPUT RSS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_output_rss' ) ) {
|
||||
/**
|
||||
* Output RSS feed
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $post_id Optional. The current post ID.
|
||||
*/
|
||||
/**
|
||||
* Output RSS feed
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $post_id Optional. The current post ID.
|
||||
*/
|
||||
|
||||
function fictioneer_output_rss( $post_id = null ) {
|
||||
// Setup
|
||||
$post_id = $post_id ? $post_id : get_queried_object_id(); // In archives, this is the first post
|
||||
$post_type = get_post_type(); // In archives, this is the first post
|
||||
$rss_link = '';
|
||||
$skip_to_default = is_archive() || is_search() || post_password_required( $post_id );
|
||||
function fictioneer_output_rss( $post_id = null ) {
|
||||
// Setup
|
||||
$post_id = $post_id ? $post_id : get_queried_object_id(); // In archives, this is the first post
|
||||
$post_type = get_post_type(); // In archives, this is the first post
|
||||
$rss_link = '';
|
||||
$skip_to_default = is_archive() || is_search() || post_password_required( $post_id );
|
||||
|
||||
// RSS Feed if story...
|
||||
if ( $post_type == 'fcn_story' && ! $skip_to_default ) {
|
||||
$title = sprintf(
|
||||
_x( '%1$s - %2$s Chapters', 'Story Feed: [Site] - [Story] Chapters.', 'fictioneer' ),
|
||||
FICTIONEER_SITE_NAME,
|
||||
get_the_title( get_the_ID() )
|
||||
);
|
||||
// RSS Feed if story...
|
||||
if ( $post_type == 'fcn_story' && ! $skip_to_default ) {
|
||||
$title = sprintf(
|
||||
_x( '%1$s - %2$s Chapters', 'Story Feed: [Site] - [Story] Chapters.', 'fictioneer' ),
|
||||
FICTIONEER_SITE_NAME,
|
||||
get_the_title( get_the_ID() )
|
||||
);
|
||||
|
||||
$url = esc_url( add_query_arg( 'story_id', get_the_ID(), home_url( 'feed/rss-chapters' ) ) );
|
||||
$rss_link = '<link rel="alternate" type="application/rss+xml" title="' . $title . '" href="' . $url . '" />';
|
||||
}
|
||||
|
||||
// RSS Feed if chapter...
|
||||
$story_id = fictioneer_get_field( 'fictioneer_chapter_story', $post_id );
|
||||
|
||||
if ( $post_type == 'fcn_chapter' && ! empty( $story_id ) && ! $skip_to_default ) {
|
||||
$title = sprintf(
|
||||
_x( '%1$s - %2$s Chapters', 'Story Feed: [Site] - [Story] Chapters.', 'fictioneer' ),
|
||||
FICTIONEER_SITE_NAME,
|
||||
get_the_title( $story_id )
|
||||
);
|
||||
|
||||
$url = esc_url( add_query_arg( 'story_id', $story_id, home_url( 'feed/rss-chapters' ) ) );
|
||||
$rss_link = '<link rel="alternate" type="application/rss+xml" title="' . $title . '" href="' . $url . '" />';
|
||||
}
|
||||
|
||||
// Default RSS Feed
|
||||
if ( empty( $rss_link ) ) {
|
||||
$title = sprintf(
|
||||
_x( '%s Feed', '[Site] Feed', 'fictioneer' ),
|
||||
FICTIONEER_SITE_NAME
|
||||
);
|
||||
|
||||
$url = esc_url( home_url( 'feed' ) );
|
||||
$rss_link = '<link rel="alternate" type="application/rss+xml" title="' . $title . '" href="' . $url . '" />';
|
||||
}
|
||||
|
||||
// Output
|
||||
echo $rss_link;
|
||||
$url = esc_url( add_query_arg( 'story_id', get_the_ID(), home_url( 'feed/rss-chapters' ) ) );
|
||||
$rss_link = '<link rel="alternate" type="application/rss+xml" title="' . $title . '" href="' . $url . '" />';
|
||||
}
|
||||
|
||||
// RSS Feed if chapter...
|
||||
$story_id = fictioneer_get_field( 'fictioneer_chapter_story', $post_id );
|
||||
|
||||
if ( $post_type == 'fcn_chapter' && ! empty( $story_id ) && ! $skip_to_default ) {
|
||||
$title = sprintf(
|
||||
_x( '%1$s - %2$s Chapters', 'Story Feed: [Site] - [Story] Chapters.', 'fictioneer' ),
|
||||
FICTIONEER_SITE_NAME,
|
||||
get_the_title( $story_id )
|
||||
);
|
||||
|
||||
$url = esc_url( add_query_arg( 'story_id', $story_id, home_url( 'feed/rss-chapters' ) ) );
|
||||
$rss_link = '<link rel="alternate" type="application/rss+xml" title="' . $title . '" href="' . $url . '" />';
|
||||
}
|
||||
|
||||
// Default RSS Feed
|
||||
if ( empty( $rss_link ) ) {
|
||||
$title = sprintf(
|
||||
_x( '%s Feed', '[Site] Feed', 'fictioneer' ),
|
||||
FICTIONEER_SITE_NAME
|
||||
);
|
||||
|
||||
$url = esc_url( home_url( 'feed' ) );
|
||||
$rss_link = '<link rel="alternate" type="application/rss+xml" title="' . $title . '" href="' . $url . '" />';
|
||||
}
|
||||
|
||||
// Output
|
||||
echo $rss_link;
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_theme_rss' ) ) {
|
||||
@ -573,37 +553,35 @@ add_filter( 'the_password_form', 'fictioneer_password_form', 10, 1 );
|
||||
// ADD ID TO CONTENT PARAGRAPHS IN CHAPTERS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_add_chapter_paragraph_id' ) ) {
|
||||
/**
|
||||
* Adds incrementing ID to chapter paragraphs
|
||||
*
|
||||
* @since 3.0
|
||||
* @license CC BY-SA 3.0
|
||||
* @link https://wordpress.stackexchange.com/a/152169/223620
|
||||
*
|
||||
* @param string $content The content.
|
||||
* @return string $content The modified content.
|
||||
*/
|
||||
/**
|
||||
* Adds incrementing ID to chapter paragraphs
|
||||
*
|
||||
* @since 3.0
|
||||
* @license CC BY-SA 3.0
|
||||
* @link https://wordpress.stackexchange.com/a/152169/223620
|
||||
*
|
||||
* @param string $content The content.
|
||||
* @return string $content The modified content.
|
||||
*/
|
||||
|
||||
function fictioneer_add_chapter_paragraph_id( $content ) {
|
||||
global $post;
|
||||
function fictioneer_add_chapter_paragraph_id( $content ) {
|
||||
global $post;
|
||||
|
||||
if (
|
||||
get_post_type() != 'fcn_chapter' ||
|
||||
! in_the_loop() ||
|
||||
! is_main_query() ||
|
||||
post_password_required()
|
||||
) return $content;
|
||||
if (
|
||||
get_post_type() != 'fcn_chapter' ||
|
||||
! in_the_loop() ||
|
||||
! is_main_query() ||
|
||||
post_password_required()
|
||||
) return $content;
|
||||
|
||||
return preg_replace_callback(
|
||||
'|<p|',
|
||||
function ( $matches ) {
|
||||
static $i = 0;
|
||||
return sprintf( '<p id="paragraph-%d" data-paragraph-id="%d" ', $i, $i++ );
|
||||
},
|
||||
$content
|
||||
);
|
||||
}
|
||||
return preg_replace_callback(
|
||||
'|<p|',
|
||||
function ( $matches ) {
|
||||
static $i = 0;
|
||||
return sprintf( '<p id="paragraph-%d" data-paragraph-id="%d" ', $i, $i++ );
|
||||
},
|
||||
$content
|
||||
);
|
||||
}
|
||||
add_filter( 'the_content', 'fictioneer_add_chapter_paragraph_id', 10, 1 );
|
||||
|
||||
@ -611,67 +589,65 @@ add_filter( 'the_content', 'fictioneer_add_chapter_paragraph_id', 10, 1 );
|
||||
// ADD LIGHTBOX TO POST IMAGES
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_add_lightbox_to_post_images' ) ) {
|
||||
/**
|
||||
* Adds lightbox data attributes to post images
|
||||
*
|
||||
* @since 3.0
|
||||
* @license CC BY-SA 3.0
|
||||
* @link https://wordpress.stackexchange.com/a/84542/223620
|
||||
* @link https://jhtechservices.com/changing-your-image-markup-in-wordpress/
|
||||
*
|
||||
* @param string $content The content.
|
||||
* @return string $content The modified content.
|
||||
*/
|
||||
/**
|
||||
* Adds lightbox data attributes to post images
|
||||
*
|
||||
* @since 3.0
|
||||
* @license CC BY-SA 3.0
|
||||
* @link https://wordpress.stackexchange.com/a/84542/223620
|
||||
* @link https://jhtechservices.com/changing-your-image-markup-in-wordpress/
|
||||
*
|
||||
* @param string $content The content.
|
||||
* @return string $content The modified content.
|
||||
*/
|
||||
|
||||
function fictioneer_add_lightbox_to_post_images( $content ) {
|
||||
if ( empty( $content ) ) return $content;
|
||||
function fictioneer_add_lightbox_to_post_images( $content ) {
|
||||
if ( empty( $content ) ) return $content;
|
||||
|
||||
// Setup
|
||||
libxml_use_internal_errors( true );
|
||||
$doc = new DOMDocument();
|
||||
$doc->loadHTML( mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' ) );
|
||||
$images = $doc->getElementsByTagName( 'img' );
|
||||
// Setup
|
||||
libxml_use_internal_errors( true );
|
||||
$doc = new DOMDocument();
|
||||
$doc->loadHTML( mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' ) );
|
||||
$images = $doc->getElementsByTagName( 'img' );
|
||||
|
||||
// Iterate over each img tag
|
||||
foreach ( $images as $img ) {
|
||||
$classes = $img->getAttribute( 'class' );
|
||||
$parent = $img->parentNode;
|
||||
$parent_classes = $parent->getAttribute( 'class' );
|
||||
$parent_href = strtolower( $parent->getAttribute( 'href' ) );
|
||||
// Iterate over each img tag
|
||||
foreach ( $images as $img ) {
|
||||
$classes = $img->getAttribute( 'class' );
|
||||
$parent = $img->parentNode;
|
||||
$parent_classes = $parent->getAttribute( 'class' );
|
||||
$parent_href = strtolower( $parent->getAttribute( 'href' ) );
|
||||
|
||||
// Abort if...
|
||||
if (
|
||||
str_contains( $classes . $parent_classes, 'no-auto-lightbox' ) ||
|
||||
$parent->hasAttribute( 'target' )
|
||||
) continue;
|
||||
// Abort if...
|
||||
if (
|
||||
str_contains( $classes . $parent_classes, 'no-auto-lightbox' ) ||
|
||||
$parent->hasAttribute( 'target' )
|
||||
) continue;
|
||||
|
||||
if (
|
||||
$parent->hasAttribute( 'href' ) &&
|
||||
! preg_match( '/(?<=\.jpg|jpeg|png|gif|webp|svg|avif|apng|tiff|ico)(?:$|[#?])/', $parent_href )
|
||||
) continue;
|
||||
if (
|
||||
$parent->hasAttribute( 'href' ) &&
|
||||
! preg_match( '/(?<=\.jpg|jpeg|png|gif|webp|svg|avif|apng|tiff|ico)(?:$|[#?])/', $parent_href )
|
||||
) continue;
|
||||
|
||||
$src = $img->getAttribute( 'src' );
|
||||
$id = preg_match( '/wp-image-([0-9]+)/i', $classes, $class_id );
|
||||
$src = $img->getAttribute( 'src' );
|
||||
$id = preg_match( '/wp-image-([0-9]+)/i', $classes, $class_id );
|
||||
|
||||
if ( $class_id ) {
|
||||
$id = absint( $class_id[1] );
|
||||
$img->setAttribute( 'data-attachment-id', $id );
|
||||
}
|
||||
if ( $class_id ) {
|
||||
$id = absint( $class_id[1] );
|
||||
$img->setAttribute( 'data-attachment-id', $id );
|
||||
}
|
||||
|
||||
if ( wp_get_attachment_image_url( $id, 'full' ) ) {
|
||||
$src = wp_get_attachment_image_url( $id, 'full' );
|
||||
}
|
||||
if ( wp_get_attachment_image_url( $id, 'full' ) ) {
|
||||
$src = wp_get_attachment_image_url( $id, 'full' );
|
||||
}
|
||||
|
||||
$img->setAttribute( 'data-src', $src );
|
||||
$img->setAttribute( 'data-lightbox', '' );
|
||||
$img->setAttribute( 'tabindex', '0' );
|
||||
};
|
||||
$img->setAttribute( 'data-src', $src );
|
||||
$img->setAttribute( 'data-lightbox', '' );
|
||||
$img->setAttribute( 'tabindex', '0' );
|
||||
};
|
||||
|
||||
$content = $doc->saveHTML();
|
||||
$content = $doc->saveHTML();
|
||||
|
||||
return $content;
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_lightbox' ) ) {
|
||||
@ -743,90 +719,88 @@ if ( get_option( 'fictioneer_remove_wp_svg_filters' ) ) {
|
||||
// ADD CONSENT WRAPPER TO EMBEDS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_embed_consent_wrappers' ) ) {
|
||||
/**
|
||||
* Wraps embeds into a consent box that must be clicked to load the embed.
|
||||
*
|
||||
* @since Fictioneer 3.0
|
||||
*
|
||||
* @param string $content The content.
|
||||
*
|
||||
* @return string The modified content.
|
||||
*/
|
||||
/**
|
||||
* Wraps embeds into a consent box that must be clicked to load the embed.
|
||||
*
|
||||
* @since Fictioneer 3.0
|
||||
*
|
||||
* @param string $content The content.
|
||||
*
|
||||
* @return string The modified content.
|
||||
*/
|
||||
|
||||
function fictioneer_embed_consent_wrappers( $content ) {
|
||||
if( empty( $content ) ) return $content;
|
||||
function fictioneer_embed_consent_wrappers( $content ) {
|
||||
if( empty( $content ) ) return $content;
|
||||
|
||||
libxml_use_internal_errors( true );
|
||||
$dom = new DOMDocument();
|
||||
$dom->loadHTML( mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' ) );
|
||||
$xpath = new DomXPath( $dom );
|
||||
libxml_use_internal_errors( true );
|
||||
$dom = new DOMDocument();
|
||||
$dom->loadHTML( mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' ) );
|
||||
$xpath = new DomXPath( $dom );
|
||||
|
||||
$iframes = $dom->getElementsByTagName( 'iframe' );
|
||||
$twitter_timelines = $xpath->query( "//a[@class='twitter-timeline']/following-sibling::*[1]" );
|
||||
$twitter_tweets = $xpath->query( "//blockquote[@class='twitter-tweet']/following-sibling::*[1]" );
|
||||
$iframes = $dom->getElementsByTagName( 'iframe' );
|
||||
$twitter_timelines = $xpath->query( "//a[@class='twitter-timeline']/following-sibling::*[1]" );
|
||||
$twitter_tweets = $xpath->query( "//blockquote[@class='twitter-tweet']/following-sibling::*[1]" );
|
||||
|
||||
// Process iframes
|
||||
foreach ( $iframes as $iframe ) {
|
||||
$src = $iframe->getAttribute( 'src' );
|
||||
$title = htmlspecialchars( $iframe->getAttribute( 'title' ) );
|
||||
$title = ( ! $title || $title == '') ? 'embedded content' : $title;
|
||||
// Process iframes
|
||||
foreach ( $iframes as $iframe ) {
|
||||
$src = $iframe->getAttribute( 'src' );
|
||||
$title = htmlspecialchars( $iframe->getAttribute( 'title' ) );
|
||||
$title = ( ! $title || $title == '') ? 'embedded content' : $title;
|
||||
|
||||
$iframe->removeAttribute('src');
|
||||
$iframe->removeAttribute('src');
|
||||
|
||||
$consent_element = $dom->createElement( 'button' );
|
||||
$consent_element->setAttribute( 'type', 'button' );
|
||||
$consent_element->setAttribute( 'class', 'iframe-consent' );
|
||||
$consent_element->setAttribute( 'data-src', $src );
|
||||
$consent_element->nodeValue = sprintf(
|
||||
__( 'Click to load %s with third-party consent.', 'fictioneer' ),
|
||||
$title
|
||||
);
|
||||
$consent_element = $dom->createElement( 'button' );
|
||||
$consent_element->setAttribute( 'type', 'button' );
|
||||
$consent_element->setAttribute( 'class', 'iframe-consent' );
|
||||
$consent_element->setAttribute( 'data-src', $src );
|
||||
$consent_element->nodeValue = sprintf(
|
||||
__( 'Click to load %s with third-party consent.', 'fictioneer' ),
|
||||
$title
|
||||
);
|
||||
|
||||
$embed_logo = $dom->createElement( 'div' );
|
||||
$embed_logo->setAttribute( 'class', 'embed-logo' );
|
||||
$embed_logo = $dom->createElement( 'div' );
|
||||
$embed_logo->setAttribute( 'class', 'embed-logo' );
|
||||
|
||||
$iframe->parentNode->insertBefore( $consent_element );
|
||||
$iframe->parentNode->insertBefore( $embed_logo );
|
||||
}
|
||||
|
||||
// Process Twitter timelines
|
||||
foreach ( $twitter_timelines as $twitter ) {
|
||||
$src = $twitter->getAttribute( 'src' );
|
||||
|
||||
$twitter->removeAttribute( 'src' );
|
||||
$twitter->previousSibling->nodeValue = '';
|
||||
|
||||
$consent_element = $dom->createElement( 'div' );
|
||||
$consent_element->setAttribute( 'class', 'twitter-consent' );
|
||||
$consent_element->setAttribute( 'data-src', $src );
|
||||
$consent_element->nodeValue = sprintf(
|
||||
__( 'Click to load %s with third-party consent.', 'fictioneer' ),
|
||||
__( 'Twitter', 'fictioneer' )
|
||||
);
|
||||
|
||||
$twitter->parentNode->insertBefore( $consent_element );
|
||||
}
|
||||
|
||||
// Process Twitter tweets
|
||||
foreach ( $twitter_tweets as $twitter ) {
|
||||
$src = $twitter->getAttribute( 'src' );
|
||||
|
||||
$twitter->removeAttribute( 'src' );
|
||||
|
||||
$consent_element = $dom->createElement( 'div' );
|
||||
$consent_element->setAttribute( 'class', 'twitter-consent' );
|
||||
$consent_element->setAttribute( 'data-src', $src );
|
||||
$consent_element->nodeValue = sprintf(
|
||||
__( 'Click to load %s with third-party consent.', 'fictioneer' ),
|
||||
__( 'Twitter', 'fictioneer' )
|
||||
);
|
||||
|
||||
$twitter->parentNode->insertBefore( $consent_element );
|
||||
}
|
||||
|
||||
return $dom->saveHTML();
|
||||
$iframe->parentNode->insertBefore( $consent_element );
|
||||
$iframe->parentNode->insertBefore( $embed_logo );
|
||||
}
|
||||
|
||||
// Process Twitter timelines
|
||||
foreach ( $twitter_timelines as $twitter ) {
|
||||
$src = $twitter->getAttribute( 'src' );
|
||||
|
||||
$twitter->removeAttribute( 'src' );
|
||||
$twitter->previousSibling->nodeValue = '';
|
||||
|
||||
$consent_element = $dom->createElement( 'div' );
|
||||
$consent_element->setAttribute( 'class', 'twitter-consent' );
|
||||
$consent_element->setAttribute( 'data-src', $src );
|
||||
$consent_element->nodeValue = sprintf(
|
||||
__( 'Click to load %s with third-party consent.', 'fictioneer' ),
|
||||
__( 'Twitter', 'fictioneer' )
|
||||
);
|
||||
|
||||
$twitter->parentNode->insertBefore( $consent_element );
|
||||
}
|
||||
|
||||
// Process Twitter tweets
|
||||
foreach ( $twitter_tweets as $twitter ) {
|
||||
$src = $twitter->getAttribute( 'src' );
|
||||
|
||||
$twitter->removeAttribute( 'src' );
|
||||
|
||||
$consent_element = $dom->createElement( 'div' );
|
||||
$consent_element->setAttribute( 'class', 'twitter-consent' );
|
||||
$consent_element->setAttribute( 'data-src', $src );
|
||||
$consent_element->nodeValue = sprintf(
|
||||
__( 'Click to load %s with third-party consent.', 'fictioneer' ),
|
||||
__( 'Twitter', 'fictioneer' )
|
||||
);
|
||||
|
||||
$twitter->parentNode->insertBefore( $consent_element );
|
||||
}
|
||||
|
||||
return $dom->saveHTML();
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_consent_wrappers' ) ) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,49 +4,47 @@
|
||||
// FIX COMMENT POST REDIRECT
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_redirect_comment' ) ) {
|
||||
/**
|
||||
* Fixes redirect after posting a comment
|
||||
*
|
||||
* Due to the modified query, after posting a comment, the commenter may be
|
||||
* redirected to the wrong comment page. This resolves the issue and also adds
|
||||
* a query argument with a comment's visibility code to allow guests without
|
||||
* email and cookies to preview their comment for a limited time as set in
|
||||
* fictioneer_theme_comment().
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
*
|
||||
* @param string $location Default redirect URI.
|
||||
* @param object $commentdata Comment data.
|
||||
*
|
||||
* @return string Either $location or a new redirect URI.
|
||||
*/
|
||||
|
||||
function fictioneer_redirect_comment( $location, $commentdata ) {
|
||||
if ( ! isset( $commentdata ) || empty( $commentdata->comment_post_ID ) ) {
|
||||
return $location;
|
||||
}
|
||||
|
||||
$visibility_code = get_comment_meta(
|
||||
$commentdata->comment_ID,
|
||||
'fictioneer_visibility_code',
|
||||
true
|
||||
);
|
||||
|
||||
if ( wp_get_referer() ) {
|
||||
if ( $visibility_code && ! $commentdata->comment_approved ) {
|
||||
return add_query_arg(
|
||||
'commentcode',
|
||||
$visibility_code['code'],
|
||||
wp_get_referer() . '#comment-' . $commentdata->comment_ID
|
||||
);
|
||||
} else {
|
||||
return wp_get_referer() . '#comment-' . $commentdata->comment_ID;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Fixes redirect after posting a comment
|
||||
*
|
||||
* Due to the modified query, after posting a comment, the commenter may be
|
||||
* redirected to the wrong comment page. This resolves the issue and also adds
|
||||
* a query argument with a comment's visibility code to allow guests without
|
||||
* email and cookies to preview their comment for a limited time as set in
|
||||
* fictioneer_theme_comment().
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
*
|
||||
* @param string $location Default redirect URI.
|
||||
* @param object $commentdata Comment data.
|
||||
*
|
||||
* @return string Either $location or a new redirect URI.
|
||||
*/
|
||||
|
||||
function fictioneer_redirect_comment( $location, $commentdata ) {
|
||||
if ( ! isset( $commentdata ) || empty( $commentdata->comment_post_ID ) ) {
|
||||
return $location;
|
||||
}
|
||||
|
||||
$visibility_code = get_comment_meta(
|
||||
$commentdata->comment_ID,
|
||||
'fictioneer_visibility_code',
|
||||
true
|
||||
);
|
||||
|
||||
if ( wp_get_referer() ) {
|
||||
if ( $visibility_code && ! $commentdata->comment_approved ) {
|
||||
return add_query_arg(
|
||||
'commentcode',
|
||||
$visibility_code['code'],
|
||||
wp_get_referer() . '#comment-' . $commentdata->comment_ID
|
||||
);
|
||||
} else {
|
||||
return wp_get_referer() . '#comment-' . $commentdata->comment_ID;
|
||||
}
|
||||
}
|
||||
|
||||
return $location;
|
||||
}
|
||||
|
||||
if ( ! get_option( 'fictioneer_disable_comment_query' ) ) {
|
||||
@ -71,90 +69,88 @@ if ( get_option( 'fictioneer_do_not_save_comment_ip' ) ) {
|
||||
// PREPROCESS COMMENTS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_preprocess_comment' ) ) {
|
||||
/**
|
||||
* Applies anti-spam measures, checks for flags, filters the content, etc.
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
*
|
||||
* @param array $commentdata Comment data.
|
||||
*
|
||||
* @return array $commentdata The preprocessed comment data.
|
||||
*/
|
||||
/**
|
||||
* Applies anti-spam measures, checks for flags, filters the content, etc.
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
*
|
||||
* @param array $commentdata Comment data.
|
||||
*
|
||||
* @return array $commentdata The preprocessed comment data.
|
||||
*/
|
||||
|
||||
function fictioneer_preprocess_comment( $commentdata ) {
|
||||
// Setup
|
||||
$current_user = wp_get_current_user();
|
||||
$user_id = $current_user ? $current_user->ID : false;
|
||||
$is_ajax = get_option( 'fictioneer_enable_ajax_comment_submit' );
|
||||
$is_admin = fictioneer_is_admin( $user_id );
|
||||
function fictioneer_preprocess_comment( $commentdata ) {
|
||||
// Setup
|
||||
$current_user = wp_get_current_user();
|
||||
$user_id = $current_user ? $current_user->ID : false;
|
||||
$is_ajax = get_option( 'fictioneer_enable_ajax_comment_submit' );
|
||||
$is_admin = fictioneer_is_admin( $user_id );
|
||||
|
||||
// Commenting disabled
|
||||
if ( fictioneer_is_commenting_disabled( $commentdata['comment_post_ID'] ) ) {
|
||||
if ( $is_ajax ) {
|
||||
wp_send_json_error( ['error' => __( 'Commenting disabled.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_die( __( 'Commenting disabled.', 'fictioneer' ) );
|
||||
}
|
||||
// Commenting disabled
|
||||
if ( fictioneer_is_commenting_disabled( $commentdata['comment_post_ID'] ) ) {
|
||||
if ( $is_ajax ) {
|
||||
wp_send_json_error( ['error' => __( 'Commenting disabled.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_die( __( 'Commenting disabled.', 'fictioneer' ) );
|
||||
}
|
||||
|
||||
// Require JS to comment unless the commenter is logged-in as
|
||||
// administrator, moderator, author, or editor.
|
||||
if (
|
||||
get_option( 'fictioneer_require_js_to_comment' ) &&
|
||||
(
|
||||
! $current_user ||
|
||||
(
|
||||
! $is_admin &&
|
||||
! fictioneer_is_author( $user_id ) &&
|
||||
! fictioneer_is_moderator( $user_id ) &&
|
||||
! fictioneer_is_editor( $user_id )
|
||||
)
|
||||
)
|
||||
) {
|
||||
if ( ! isset( $_POST['fictioneer_comment_validator'] ) || ! $_POST['fictioneer_comment_validator'] ) {
|
||||
if ( $is_ajax ) {
|
||||
wp_send_json_error( ['error' => __( 'Comment did not pass validation.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_die( __( 'Comment did not pass validation.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check fictioneer_admin_disable_commenting user flag
|
||||
if ( $current_user->fictioneer_admin_disable_commenting ) {
|
||||
if ( $is_ajax ) {
|
||||
wp_send_json_error( ['error' => __( 'Commenting capability disabled.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_die( __( 'Commenting capability disabled.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Count links in comment the non-sophisticated way...
|
||||
$link_count = substr_count( $commentdata['comment_content'], 'http' );
|
||||
|
||||
// No more than n links allowed (unless you are an administrator)
|
||||
if (
|
||||
get_option( 'fictioneer_enable_comment_link_limit' ) &&
|
||||
$link_count > get_option( 'fictioneer_comment_link_limit_threshold', 3 ) &&
|
||||
! fictioneer_is_admin( $current_user->ID )
|
||||
) {
|
||||
if ( $is_ajax ) {
|
||||
wp_send_json_error( ['error' => __( 'Too many links.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_die( __( 'Too many links.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Change allowed tags
|
||||
global $allowedtags;
|
||||
|
||||
if ( ! $is_admin && get_option( 'fictioneer_disable_html_in_comments' ) ) {
|
||||
$allowedtags = [];
|
||||
}
|
||||
|
||||
return $commentdata;
|
||||
}
|
||||
|
||||
// Require JS to comment unless the commenter is logged-in as
|
||||
// administrator, moderator, author, or editor.
|
||||
if (
|
||||
get_option( 'fictioneer_require_js_to_comment' ) &&
|
||||
(
|
||||
! $current_user ||
|
||||
(
|
||||
! $is_admin &&
|
||||
! fictioneer_is_author( $user_id ) &&
|
||||
! fictioneer_is_moderator( $user_id ) &&
|
||||
! fictioneer_is_editor( $user_id )
|
||||
)
|
||||
)
|
||||
) {
|
||||
if ( ! isset( $_POST['fictioneer_comment_validator'] ) || ! $_POST['fictioneer_comment_validator'] ) {
|
||||
if ( $is_ajax ) {
|
||||
wp_send_json_error( ['error' => __( 'Comment did not pass validation.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_die( __( 'Comment did not pass validation.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check fictioneer_admin_disable_commenting user flag
|
||||
if ( $current_user->fictioneer_admin_disable_commenting ) {
|
||||
if ( $is_ajax ) {
|
||||
wp_send_json_error( ['error' => __( 'Commenting capability disabled.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_die( __( 'Commenting capability disabled.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Count links in comment the non-sophisticated way...
|
||||
$link_count = substr_count( $commentdata['comment_content'], 'http' );
|
||||
|
||||
// No more than n links allowed (unless you are an administrator)
|
||||
if (
|
||||
get_option( 'fictioneer_enable_comment_link_limit' ) &&
|
||||
$link_count > get_option( 'fictioneer_comment_link_limit_threshold', 3 ) &&
|
||||
! fictioneer_is_admin( $current_user->ID )
|
||||
) {
|
||||
if ( $is_ajax ) {
|
||||
wp_send_json_error( ['error' => __( 'Too many links.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_die( __( 'Too many links.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Change allowed tags
|
||||
global $allowedtags;
|
||||
|
||||
if ( ! $is_admin && get_option( 'fictioneer_disable_html_in_comments' ) ) {
|
||||
$allowedtags = [];
|
||||
}
|
||||
|
||||
return $commentdata;
|
||||
}
|
||||
add_filter( 'preprocess_comment', 'fictioneer_preprocess_comment', 30, 1 );
|
||||
|
||||
@ -162,53 +158,66 @@ add_filter( 'preprocess_comment', 'fictioneer_preprocess_comment', 30, 1 );
|
||||
// VALIDATE COMMENT FORM
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_validate_comment_form' ) ) {
|
||||
/**
|
||||
* Validate comment form submission
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
* @link https://developer.wordpress.org/reference/hooks/preprocess_comment/
|
||||
*
|
||||
* @param array $commentdata Comment data.
|
||||
*/
|
||||
/**
|
||||
* Validate comment form submission
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
* @link https://developer.wordpress.org/reference/hooks/preprocess_comment/
|
||||
*
|
||||
* @param array $commentdata Comment data.
|
||||
*/
|
||||
|
||||
function fictioneer_validate_comment_form( $commentdata ) {
|
||||
// Setup
|
||||
$parent_id = absint( $commentdata['comment_parent'] ?? 0 );
|
||||
$is_ajax = get_option( 'fictioneer_enable_ajax_comment_submit' );
|
||||
function fictioneer_validate_comment_form( $commentdata ) {
|
||||
// Setup
|
||||
$parent_id = absint( $commentdata['comment_parent'] ?? 0 );
|
||||
$is_ajax = get_option( 'fictioneer_enable_ajax_comment_submit' );
|
||||
|
||||
// Check privacy consent for guests
|
||||
if ( ! is_user_logged_in() && ! $is_ajax && get_option( 'wp_page_for_privacy_policy' ) ) {
|
||||
// You cannot post a comment without accepting the privacy policy (Tested earlier on AJAX submit!)
|
||||
if (
|
||||
! isset( $_POST['fictioneer-privacy-policy-consent'] ) ||
|
||||
! filter_var( $_POST['fictioneer-privacy-policy-consent'], FILTER_VALIDATE_BOOLEAN )
|
||||
) {
|
||||
wp_die( __( 'You did not accept the privacy policy.', 'fictioneer' ) );
|
||||
}
|
||||
// Check privacy consent for guests
|
||||
if ( ! is_user_logged_in() && ! $is_ajax && get_option( 'wp_page_for_privacy_policy' ) ) {
|
||||
// You cannot post a comment without accepting the privacy policy (Tested earlier on AJAX submit!)
|
||||
if (
|
||||
! isset( $_POST['fictioneer-privacy-policy-consent'] ) ||
|
||||
! filter_var( $_POST['fictioneer-privacy-policy-consent'], FILTER_VALIDATE_BOOLEAN )
|
||||
) {
|
||||
wp_die( __( 'You did not accept the privacy policy.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Abort if direct parent comment is deleted
|
||||
if ( $parent_id && get_comment_meta( $parent_id, 'fictioneer_deleted_by_user', true ) ) {
|
||||
// Abort if direct parent comment is deleted
|
||||
if ( $parent_id && get_comment_meta( $parent_id, 'fictioneer_deleted_by_user', true ) ) {
|
||||
if ( $is_ajax ) {
|
||||
wp_send_json_error( ['error' => __( 'You cannot reply to deleted comments.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_die( __( 'You cannot reply to deleted comments.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Abort if direct parent comment is marked as offensive
|
||||
if ( $parent_id && get_comment_meta( $parent_id, 'fictioneer_marked_offensive', true ) ) {
|
||||
if ( $is_ajax ) {
|
||||
wp_send_json_error( ['error' => __( 'You cannot reply to comments marked as offensive.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_die( __( 'You cannot reply to comments marked as offensive.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Abort if parent comment or ancestors are closed
|
||||
if ( $parent_id && ! get_option( 'fictioneer_disable_comment_callback' ) ) {
|
||||
if ( get_comment_meta( $parent_id, 'fictioneer_thread_closed', true ) ) {
|
||||
if ( $is_ajax ) {
|
||||
wp_send_json_error( ['error' => __( 'You cannot reply to deleted comments.', 'fictioneer' )] );
|
||||
wp_send_json_error( ['error' => __( 'Comment thread is closed.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_die( __( 'You cannot reply to deleted comments.', 'fictioneer' ) );
|
||||
wp_die( __( 'Comment thread is closed.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Abort if direct parent comment is marked as offensive
|
||||
if ( $parent_id && get_comment_meta( $parent_id, 'fictioneer_marked_offensive', true ) ) {
|
||||
if ( $is_ajax ) {
|
||||
wp_send_json_error( ['error' => __( 'You cannot reply to comments marked as offensive.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_die( __( 'You cannot reply to comments marked as offensive.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
$ancestor = get_comment( $parent_id );
|
||||
|
||||
// Abort if parent comment or ancestors are closed
|
||||
if ( $parent_id && ! get_option( 'fictioneer_disable_comment_callback' ) ) {
|
||||
if ( get_comment_meta( $parent_id, 'fictioneer_thread_closed', true ) ) {
|
||||
while ( $ancestor ) {
|
||||
if ( ! is_object( $ancestor ) ) break;
|
||||
|
||||
// Ancestor closed?
|
||||
if ( get_comment_meta( $ancestor->comment_ID, 'fictioneer_thread_closed', true ) ) {
|
||||
if ( $is_ajax ) {
|
||||
wp_send_json_error( ['error' => __( 'Comment thread is closed.', 'fictioneer' )] );
|
||||
} else {
|
||||
@ -216,54 +225,39 @@ if ( ! function_exists( 'fictioneer_validate_comment_form' ) ) {
|
||||
}
|
||||
}
|
||||
|
||||
$ancestor = get_comment( $parent_id );
|
||||
|
||||
while ( $ancestor ) {
|
||||
if ( ! is_object( $ancestor ) ) break;
|
||||
|
||||
// Ancestor closed?
|
||||
if ( get_comment_meta( $ancestor->comment_ID, 'fictioneer_thread_closed', true ) ) {
|
||||
if ( $is_ajax ) {
|
||||
wp_send_json_error( ['error' => __( 'Comment thread is closed.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_die( __( 'Comment thread is closed.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Next ancestor if any
|
||||
$ancestor = $ancestor->comment_parent ? get_comment( $ancestor->comment_parent ) : false;
|
||||
}
|
||||
// Next ancestor if any
|
||||
$ancestor = $ancestor->comment_parent ? get_comment( $ancestor->comment_parent ) : false;
|
||||
}
|
||||
|
||||
// Mark comment as private
|
||||
if (
|
||||
get_option( 'fictioneer_enable_private_commenting' ) &&
|
||||
(
|
||||
isset( $_POST['fictioneer-private-comment-toggle'] ) &&
|
||||
filter_var( $_POST['fictioneer-private-comment-toggle'], FILTER_VALIDATE_BOOLEAN )
|
||||
)
|
||||
) {
|
||||
$commentdata['comment_type'] = 'private';
|
||||
}
|
||||
|
||||
// Mark private if parent is private
|
||||
if ( $parent_id && get_comment_type( $parent_id ) == 'private' ) {
|
||||
$commentdata['comment_type'] = 'private';
|
||||
}
|
||||
|
||||
// Enable email notification for replies
|
||||
if (
|
||||
get_option( 'fictioneer_enable_comment_notifications' ) &&
|
||||
(
|
||||
isset( $_POST['fictioneer-comment-notification-toggle'] ) &&
|
||||
filter_var( $_POST['fictioneer-comment-notification-toggle'], FILTER_VALIDATE_BOOLEAN )
|
||||
)
|
||||
) {
|
||||
$commentdata['notification'] = true;
|
||||
}
|
||||
|
||||
return $commentdata;
|
||||
}
|
||||
|
||||
// Mark comment as private
|
||||
if (
|
||||
get_option( 'fictioneer_enable_private_commenting' ) &&
|
||||
(
|
||||
isset( $_POST['fictioneer-private-comment-toggle'] ) &&
|
||||
filter_var( $_POST['fictioneer-private-comment-toggle'], FILTER_VALIDATE_BOOLEAN )
|
||||
)
|
||||
) {
|
||||
$commentdata['comment_type'] = 'private';
|
||||
}
|
||||
|
||||
// Mark private if parent is private
|
||||
if ( $parent_id && get_comment_type( $parent_id ) == 'private' ) {
|
||||
$commentdata['comment_type'] = 'private';
|
||||
}
|
||||
|
||||
// Enable email notification for replies
|
||||
if (
|
||||
get_option( 'fictioneer_enable_comment_notifications' ) &&
|
||||
(
|
||||
isset( $_POST['fictioneer-comment-notification-toggle'] ) &&
|
||||
filter_var( $_POST['fictioneer-comment-notification-toggle'], FILTER_VALIDATE_BOOLEAN )
|
||||
)
|
||||
) {
|
||||
$commentdata['notification'] = true;
|
||||
}
|
||||
|
||||
return $commentdata;
|
||||
}
|
||||
|
||||
if ( ! get_option( 'fictioneer_disable_comment_form' ) ) {
|
||||
@ -274,83 +268,81 @@ if ( ! get_option( 'fictioneer_disable_comment_form' ) ) {
|
||||
// COMMENT POST ACTION
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_comment_post' ) ) {
|
||||
/**
|
||||
* Fires after the comment has been inserted into the database
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
* @link https://developer.wordpress.org/reference/hooks/comment_post/
|
||||
* @link https://github.com/WordPress/WordPress/blob/master/wp-includes/comment.php
|
||||
* @see add_comment_meta()
|
||||
* @see filter_var()
|
||||
*
|
||||
* @param int $comment_id The comment ID.
|
||||
* @param int|string $comment_approved 1 if the comment is approved, 0 if not, 'spam' if spam.
|
||||
* @param array $commentdata Comment data.
|
||||
*/
|
||||
/**
|
||||
* Fires after the comment has been inserted into the database
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
* @link https://developer.wordpress.org/reference/hooks/comment_post/
|
||||
* @link https://github.com/WordPress/WordPress/blob/master/wp-includes/comment.php
|
||||
* @see add_comment_meta()
|
||||
* @see filter_var()
|
||||
*
|
||||
* @param int $comment_id The comment ID.
|
||||
* @param int|string $comment_approved 1 if the comment is approved, 0 if not, 'spam' if spam.
|
||||
* @param array $commentdata Comment data.
|
||||
*/
|
||||
|
||||
function fictioneer_comment_post( $comment_id, $comment_approved, $commentdata ) {
|
||||
// Store privacy policy agreement in case theme comments are turned off
|
||||
if (
|
||||
isset( $_POST['fictioneer-privacy-policy-consent'] ) &&
|
||||
filter_var( $_POST['fictioneer-privacy-policy-consent'], FILTER_VALIDATE_BOOLEAN )
|
||||
) {
|
||||
add_comment_meta( $comment_id, 'fictioneer_privacy_policy_accepted', true );
|
||||
}
|
||||
function fictioneer_comment_post( $comment_id, $comment_approved, $commentdata ) {
|
||||
// Store privacy policy agreement in case theme comments are turned off
|
||||
if (
|
||||
isset( $_POST['fictioneer-privacy-policy-consent'] ) &&
|
||||
filter_var( $_POST['fictioneer-privacy-policy-consent'], FILTER_VALIDATE_BOOLEAN )
|
||||
) {
|
||||
add_comment_meta( $comment_id, 'fictioneer_privacy_policy_accepted', true );
|
||||
}
|
||||
|
||||
// Store visibility code for unapproved comments based on Unix seconds
|
||||
add_comment_meta(
|
||||
$comment_id,
|
||||
'fictioneer_visibility_code',
|
||||
array(
|
||||
'timestamp' => time(),
|
||||
'code' => uniqid() // Sufficiently unique for this purpose
|
||||
),
|
||||
true
|
||||
);
|
||||
// Store visibility code for unapproved comments based on Unix seconds
|
||||
add_comment_meta(
|
||||
$comment_id,
|
||||
'fictioneer_visibility_code',
|
||||
array(
|
||||
'timestamp' => time(),
|
||||
'code' => uniqid() // Sufficiently unique for this purpose
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
// Hold for moderation if user is flagged
|
||||
if ( get_user_meta( $commentdata['user_id'], 'fictioneer_admin_always_moderate_comments', true ) ) {
|
||||
wp_set_comment_status( $comment_id, 'hold' );
|
||||
}
|
||||
// Hold for moderation if user is flagged
|
||||
if ( get_user_meta( $commentdata['user_id'], 'fictioneer_admin_always_moderate_comments', true ) ) {
|
||||
wp_set_comment_status( $comment_id, 'hold' );
|
||||
}
|
||||
|
||||
// Purge cache of post/page the comment is for
|
||||
if ( fictioneer_caching_active() && isset( $commentdata['comment_post_ID'] ) ) {
|
||||
fictioneer_purge_post_cache( $commentdata['comment_post_ID'] );
|
||||
}
|
||||
// Purge cache of post/page the comment is for
|
||||
if ( fictioneer_caching_active() && isset( $commentdata['comment_post_ID'] ) ) {
|
||||
fictioneer_purge_post_cache( $commentdata['comment_post_ID'] );
|
||||
}
|
||||
|
||||
// Notification validator determines whether a subscription is active; change the validator
|
||||
// and all associated comment reply subscriptions are terminated
|
||||
$notification_validator = get_user_meta( $commentdata['user_id'], 'fictioneer_comment_reply_validator', true );
|
||||
// Notification validator determines whether a subscription is active; change the validator
|
||||
// and all associated comment reply subscriptions are terminated
|
||||
$notification_validator = get_user_meta( $commentdata['user_id'], 'fictioneer_comment_reply_validator', true );
|
||||
|
||||
if ( empty( $notification_validator ) ) {
|
||||
$notification_validator = time();
|
||||
update_user_meta( $commentdata['user_id'], 'fictioneer_comment_reply_validator', $notification_validator );
|
||||
}
|
||||
if ( empty( $notification_validator ) ) {
|
||||
$notification_validator = time();
|
||||
update_user_meta( $commentdata['user_id'], 'fictioneer_comment_reply_validator', $notification_validator );
|
||||
}
|
||||
|
||||
// If user opted for email notifications
|
||||
if (
|
||||
isset( $_POST['fictioneer-comment-notification-toggle'] ) &&
|
||||
filter_var( $_POST['fictioneer-comment-notification-toggle'], FILTER_VALIDATE_BOOLEAN )
|
||||
) {
|
||||
add_comment_meta( $comment_id, 'fictioneer_send_notifications', $notification_validator );
|
||||
// Reset code to stop notifications (sufficiently unique for this purpose)
|
||||
add_comment_meta( $comment_id, 'fictioneer_notifications_reset', md5( wp_generate_password() ) );
|
||||
}
|
||||
// If user opted for email notifications
|
||||
if (
|
||||
isset( $_POST['fictioneer-comment-notification-toggle'] ) &&
|
||||
filter_var( $_POST['fictioneer-comment-notification-toggle'], FILTER_VALIDATE_BOOLEAN )
|
||||
) {
|
||||
add_comment_meta( $comment_id, 'fictioneer_send_notifications', $notification_validator );
|
||||
// Reset code to stop notifications (sufficiently unique for this purpose)
|
||||
add_comment_meta( $comment_id, 'fictioneer_notifications_reset', md5( wp_generate_password() ) );
|
||||
}
|
||||
|
||||
// Anything related to comment parent (if any)...
|
||||
$parent_comment = get_comment( $commentdata['comment_parent'] );
|
||||
// Anything related to comment parent (if any)...
|
||||
$parent_comment = get_comment( $commentdata['comment_parent'] );
|
||||
|
||||
if ( $parent_comment ) {
|
||||
$parent_notification_check = get_comment_meta( $commentdata['comment_parent'], 'fictioneer_send_notifications', true );
|
||||
$parent_notification_validator = get_user_meta( $parent_comment->user_id, 'fictioneer_comment_reply_validator', true );
|
||||
if ( $parent_comment ) {
|
||||
$parent_notification_check = get_comment_meta( $commentdata['comment_parent'], 'fictioneer_send_notifications', true );
|
||||
$parent_notification_validator = get_user_meta( $parent_comment->user_id, 'fictioneer_comment_reply_validator', true );
|
||||
|
||||
// Send notification to parent comment author (if wanted)
|
||||
if ( get_option( 'fictioneer_enable_comment_notifications' ) && ! empty( $parent_notification_check ) ) {
|
||||
// Parent comment user guest or member?
|
||||
if ( $parent_comment->user_id == 0 || $parent_notification_check == $parent_notification_validator ) {
|
||||
fictioneer_comment_notification( $parent_comment, $comment_id, $commentdata );
|
||||
}
|
||||
// Send notification to parent comment author (if wanted)
|
||||
if ( get_option( 'fictioneer_enable_comment_notifications' ) && ! empty( $parent_notification_check ) ) {
|
||||
// Parent comment user guest or member?
|
||||
if ( $parent_comment->user_id == 0 || $parent_notification_check == $parent_notification_validator ) {
|
||||
fictioneer_comment_notification( $parent_comment, $comment_id, $commentdata );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -364,17 +356,17 @@ if ( ! get_option( 'fictioneer_disable_comment_form' ) ) {
|
||||
// COMMENT NOTIFICATION EMAIL
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Send notification email about replies to commenter
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_Comment $parent Comment that was replied to.
|
||||
* @param int $comment_id ID of the reply comment.
|
||||
* @param array $commentdata Fields of the reply comment.
|
||||
*/
|
||||
|
||||
if ( ! function_exists( 'fictioneer_comment_notification' ) ) {
|
||||
/**
|
||||
* Send notification email about replies to commenter
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_Comment $parent Comment that was replied to.
|
||||
* @param int $comment_id ID of the reply comment.
|
||||
* @param array $commentdata Fields of the reply comment.
|
||||
*/
|
||||
|
||||
function fictioneer_comment_notification( WP_Comment $parent, int $comment_id, array $commentdata ) {
|
||||
// Abort if...
|
||||
if ( empty( $parent->comment_author_email ) || ! $comment_id || empty( $commentdata['comment_content'] ) ) {
|
||||
|
@ -41,72 +41,70 @@ if ( ! function_exists( 'fictioneer_get_comment_toolbar' ) ) {
|
||||
// COMMENT FORM FIELDS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_change_comment_fields' ) ) {
|
||||
/**
|
||||
* Change default fields of comment form
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
*
|
||||
* @param array $fields Array of the default comment fields.
|
||||
*
|
||||
* @return array $fields Modified array of the default comment fields.
|
||||
*/
|
||||
|
||||
function fictioneer_change_comment_fields( $fields ) {
|
||||
// Remove URL (website) field
|
||||
unset( $fields['url'] );
|
||||
|
||||
// Setup
|
||||
$commenter = wp_get_current_commenter();
|
||||
$cookie_checked_attribute = empty( $commenter['comment_author_email'] ) ? '' : ' checked';
|
||||
$required = get_option( 'require_name_email' );
|
||||
$required_attribute = $required ? ' required' : '';
|
||||
$name_placeholder = $required ? __( 'Name *', 'fictioneer' ) : __( 'Name', 'fictioneer' );
|
||||
$email_placeholder = $required ? __( 'Email (Gravatar) *', 'fictioneer' ) : __( 'Email (optional, Gravatar)', 'fictioneer' );
|
||||
$privacy_policy_link = get_option( 'wp_page_for_privacy_policy' ) ? esc_url( get_privacy_policy_url() ) : false;
|
||||
$hidden = FICTIONEER_COLLAPSE_COMMENT_FORM ? 'hidden' : '';
|
||||
|
||||
// Rebuild author field
|
||||
$fields['author'] = '<div class="comment-form-author"><input type="text" id="author" name="author" data-lpignore="true" value="' . esc_attr( $commenter['comment_author'] ) . '"' . $required_attribute . ' maxlength="245" placeholder="' . $name_placeholder . '"></div>';
|
||||
|
||||
// Rebuild email field
|
||||
$fields['email'] = '<div class="comment-form-email"><input type="text" id="email" name="email" data-lpignore="true" value="' . esc_attr( $commenter['comment_author_email'] ) . '" maxlength="100" aria-describedby="email-notes" placeholder="' . $email_placeholder . '"' . $required_attribute . '></div>';
|
||||
|
||||
// Open .fictioneer-respond__checkboxes wrapper
|
||||
$fields['checkboxes'] = '<div class="fictioneer-respond__form-checkboxes">';
|
||||
|
||||
// Rebuild cookies field (ignores 'show_comments_cookies_opt_in' and is always enabled)
|
||||
$fields['cookies'] = '<div class="comment-form-cookies-consent fictioneer-respond__checkbox-label-pair"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes"' . $cookie_checked_attribute . '><label for="wp-comment-cookies-consent">' . fcntr( 'save_in_cookie' ) . '</label></div>';
|
||||
|
||||
// Build new privacy policy field
|
||||
$privacy_policy = '';
|
||||
|
||||
if ( $privacy_policy_link ) {
|
||||
$privacy_policy = '<div class="comment-form-privacy-policy-consent fictioneer-respond__checkbox-label-pair"><input id="fictioneer-privacy-policy-consent" name="fictioneer-privacy-policy-consent" type="checkbox" value="1" required' . $cookie_checked_attribute . '><label for="fictioneer-privacy-policy-consent">' . sprintf( fcntr( 'accept_privacy_policy' ), $privacy_policy_link ) . '</label></div>';
|
||||
}
|
||||
|
||||
// Append checkboxes and close .fictioneer-respond__checkboxes wrapper
|
||||
if ( get_option( 'show_comments_cookies_opt_in' ) ) {
|
||||
$fields['checkboxes'] .= $fields['cookies'];
|
||||
}
|
||||
|
||||
$fields['checkboxes'] .= $privacy_policy . '</div>';
|
||||
|
||||
// Disable now redundant cookies field (do not unset, this can cause issues with cache plugins apparently)
|
||||
$fields['cookies'] = '';
|
||||
|
||||
/**
|
||||
* Change default fields of comment form
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
*
|
||||
* @param array $fields Array of the default comment fields.
|
||||
*
|
||||
* @return array $fields Modified array of the default comment fields.
|
||||
* Open the .fictioneer-respond__bottom wrapper around all input fields below
|
||||
* the textarea. It will be closed in the fictioneer_change_submit_field
|
||||
* method. Also added is the .fictioneer-respond__form-identity wrapper
|
||||
* around the author and email fields.
|
||||
*/
|
||||
|
||||
function fictioneer_change_comment_fields( $fields ) {
|
||||
// Remove URL (website) field
|
||||
unset( $fields['url'] );
|
||||
$fields['author'] = '<div class="fictioneer-respond__form-bottom ' . $hidden . '"><div class="fictioneer-respond__form-identity">' . $fields['author'];
|
||||
$fields['email'] = $fields['email'] . '</div>';
|
||||
|
||||
// Setup
|
||||
$commenter = wp_get_current_commenter();
|
||||
$cookie_checked_attribute = empty( $commenter['comment_author_email'] ) ? '' : ' checked';
|
||||
$required = get_option( 'require_name_email' );
|
||||
$required_attribute = $required ? ' required' : '';
|
||||
$name_placeholder = $required ? __( 'Name *', 'fictioneer' ) : __( 'Name', 'fictioneer' );
|
||||
$email_placeholder = $required ? __( 'Email (Gravatar) *', 'fictioneer' ) : __( 'Email (optional, Gravatar)', 'fictioneer' );
|
||||
$privacy_policy_link = get_option( 'wp_page_for_privacy_policy' ) ? esc_url( get_privacy_policy_url() ) : false;
|
||||
$hidden = FICTIONEER_COLLAPSE_COMMENT_FORM ? 'hidden' : '';
|
||||
|
||||
// Rebuild author field
|
||||
$fields['author'] = '<div class="comment-form-author"><input type="text" id="author" name="author" data-lpignore="true" value="' . esc_attr( $commenter['comment_author'] ) . '"' . $required_attribute . ' maxlength="245" placeholder="' . $name_placeholder . '"></div>';
|
||||
|
||||
// Rebuild email field
|
||||
$fields['email'] = '<div class="comment-form-email"><input type="text" id="email" name="email" data-lpignore="true" value="' . esc_attr( $commenter['comment_author_email'] ) . '" maxlength="100" aria-describedby="email-notes" placeholder="' . $email_placeholder . '"' . $required_attribute . '></div>';
|
||||
|
||||
// Open .fictioneer-respond__checkboxes wrapper
|
||||
$fields['checkboxes'] = '<div class="fictioneer-respond__form-checkboxes">';
|
||||
|
||||
// Rebuild cookies field (ignores 'show_comments_cookies_opt_in' and is always enabled)
|
||||
$fields['cookies'] = '<div class="comment-form-cookies-consent fictioneer-respond__checkbox-label-pair"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes"' . $cookie_checked_attribute . '><label for="wp-comment-cookies-consent">' . fcntr( 'save_in_cookie' ) . '</label></div>';
|
||||
|
||||
// Build new privacy policy field
|
||||
$privacy_policy = '';
|
||||
|
||||
if ( $privacy_policy_link ) {
|
||||
$privacy_policy = '<div class="comment-form-privacy-policy-consent fictioneer-respond__checkbox-label-pair"><input id="fictioneer-privacy-policy-consent" name="fictioneer-privacy-policy-consent" type="checkbox" value="1" required' . $cookie_checked_attribute . '><label for="fictioneer-privacy-policy-consent">' . sprintf( fcntr( 'accept_privacy_policy' ), $privacy_policy_link ) . '</label></div>';
|
||||
}
|
||||
|
||||
// Append checkboxes and close .fictioneer-respond__checkboxes wrapper
|
||||
if ( get_option( 'show_comments_cookies_opt_in' ) ) {
|
||||
$fields['checkboxes'] .= $fields['cookies'];
|
||||
}
|
||||
|
||||
$fields['checkboxes'] .= $privacy_policy . '</div>';
|
||||
|
||||
// Disable now redundant cookies field (do not unset, this can cause issues with cache plugins apparently)
|
||||
$fields['cookies'] = '';
|
||||
|
||||
/**
|
||||
* Open the .fictioneer-respond__bottom wrapper around all input fields below
|
||||
* the textarea. It will be closed in the fictioneer_change_submit_field
|
||||
* method. Also added is the .fictioneer-respond__form-identity wrapper
|
||||
* around the author and email fields.
|
||||
*/
|
||||
|
||||
$fields['author'] = '<div class="fictioneer-respond__form-bottom ' . $hidden . '"><div class="fictioneer-respond__form-identity">' . $fields['author'];
|
||||
$fields['email'] = $fields['email'] . '</div>';
|
||||
|
||||
return $fields;
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
if ( ! get_option( 'fictioneer_disable_comment_form' ) ) {
|
||||
@ -125,90 +123,88 @@ if ( ! get_option( 'fictioneer_disable_comment_bbcodes' ) && ! get_option( 'fict
|
||||
// COMMENT FORM SUBMIT
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_change_submit_field' ) ) {
|
||||
/**
|
||||
* Change the submit field and add the Cancel Reply link
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
* @link https://github.com/WordPress/WordPress/blob/master/wp-includes/comment-template.php
|
||||
* @link https://stackoverflow.com/a/57080105/17140970
|
||||
*
|
||||
* @param string $submit_field HTML markup for the submit field.
|
||||
* @param array $args Arguments passed to comment_form().
|
||||
*/
|
||||
|
||||
function fictioneer_change_submit_field( $submit_field, $args ) {
|
||||
remove_filter( 'cancel_comment_reply_link', '__return_empty_string' );
|
||||
|
||||
// Setup
|
||||
$close_bottom_container = is_user_logged_in() ? '' : '</div>';
|
||||
$is_ajax = get_option( 'fictioneer_enable_ajax_comment_form' ) || get_option( 'fictioneer_enable_ajax_comments' );
|
||||
$hidden = FICTIONEER_COLLAPSE_COMMENT_FORM ? 'hidden' : '';
|
||||
|
||||
/**
|
||||
* Change the submit field and add the Cancel Reply link
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
* @link https://github.com/WordPress/WordPress/blob/master/wp-includes/comment-template.php
|
||||
* @link https://stackoverflow.com/a/57080105/17140970
|
||||
*
|
||||
* @param string $submit_field HTML markup for the submit field.
|
||||
* @param array $args Arguments passed to comment_form().
|
||||
* Build the submit button with the comment_form arguments. Markup:
|
||||
* <input name="%1$s" type="submit" id="%2$s" class="%3$s" value="%4$s" />
|
||||
*/
|
||||
|
||||
function fictioneer_change_submit_field( $submit_field, $args ) {
|
||||
remove_filter( 'cancel_comment_reply_link', '__return_empty_string' );
|
||||
$submit_button = sprintf(
|
||||
'<input name="%1$s" type="submit" id="%2$s" class="%3$s" value="%4$s" data-enabled="%4$s" data-disabled="Posting…">',
|
||||
esc_attr( $args['name_submit'] ),
|
||||
esc_attr( $args['id_submit'] ),
|
||||
esc_attr( $args['class_submit'] ) . ' button fictioneer-respond__form-submit',
|
||||
esc_attr( $args['label_submit'] )
|
||||
);
|
||||
|
||||
// Setup
|
||||
$close_bottom_container = is_user_logged_in() ? '' : '</div>';
|
||||
$is_ajax = get_option( 'fictioneer_enable_ajax_comment_form' ) || get_option( 'fictioneer_enable_ajax_comments' );
|
||||
$hidden = FICTIONEER_COLLAPSE_COMMENT_FORM ? 'hidden' : '';
|
||||
// Private comment toggle
|
||||
$private_toggle = '';
|
||||
|
||||
/**
|
||||
* Build the submit button with the comment_form arguments. Markup:
|
||||
* <input name="%1$s" type="submit" id="%2$s" class="%3$s" value="%4$s" />
|
||||
*/
|
||||
|
||||
$submit_button = sprintf(
|
||||
'<input name="%1$s" type="submit" id="%2$s" class="%3$s" value="%4$s" data-enabled="%4$s" data-disabled="Posting…">',
|
||||
esc_attr( $args['name_submit'] ),
|
||||
esc_attr( $args['id_submit'] ),
|
||||
esc_attr( $args['class_submit'] ) . ' button fictioneer-respond__form-submit',
|
||||
esc_attr( $args['label_submit'] )
|
||||
);
|
||||
|
||||
// Private comment toggle
|
||||
$private_toggle = '';
|
||||
|
||||
if ( get_option( 'fictioneer_enable_private_commenting' ) ) {
|
||||
$hint = esc_attr_x( 'Toggle to mark as private. Hides the comment from uninvolved viewers.', 'Comment form private toggle.', 'fictioneer' );
|
||||
$private_toggle = '<div class="fictioneer-private-comment-toggle fictioneer-respond__form-toggle"><label class="comment-respond-option-toggle" tabindex="0" role="checkbox" aria-checked="false" aria-label="' . $hint . '"><input name="fictioneer-private-comment-toggle" id="fictioneer-private-comment-toggle" type="checkbox" tabindex="-1" onchange="fcn_ariaCheckedUpdate(this)" hidden><span class="tooltipped _mobile-tooltip" data-tooltip="' . $hint . '"><i class="fa-solid fa-eye off"></i><i class="fa-solid fa-eye-slash on"></i></span></label></div>';
|
||||
}
|
||||
|
||||
// Email subscriptions toggle
|
||||
$notification_toggle = '';
|
||||
$notifications_blocked = get_the_author_meta( 'fictioneer_admin_disable_comment_notifications', get_current_user_id() );
|
||||
$notification_checked = is_user_logged_in() && get_the_author_meta( 'fictioneer_comment_reply_notifications', get_current_user_id() ) && ! $notifications_blocked;
|
||||
$notification_checked = $notification_checked && ( ! get_option( 'fictioneer_enable_public_cache_compatibility' ) || $is_ajax );
|
||||
|
||||
if ( get_option( 'fictioneer_enable_comment_notifications' ) && ! $notifications_blocked ) {
|
||||
$hint = esc_attr_x( 'Toggle to get email notifications about direct replies.', 'Comment form email notification toggle.', 'fictioneer' );
|
||||
$aria_checked = $notification_checked ? 'true' : 'false';
|
||||
$notification_toggle = '<div class="fictioneer-comment-notification-toggle fictioneer-respond__form-toggle"><label class="comment-respond-option-toggle" tabindex="0" role="checkbox" aria-checked="' . $aria_checked . '" aria-label="' . $hint . '"><input name="fictioneer-comment-notification-toggle" id="fictioneer-comment-notification-toggle" type="checkbox" ' . checked( 1, $notification_checked, false ) . ' tabindex="-1" onchange="fcn_ariaCheckedUpdate(this)" hidden><span class="tooltipped _mobile-tooltip" data-tooltip="' . $hint . '"><i class="fa-solid fa-bell on"></i><i class="fa-solid fa-bell-slash off"></i></span></label></div>';
|
||||
}
|
||||
|
||||
// Hidden parent_comment field
|
||||
$parent_field = '<input type="hidden" name="comment_parent" id="comment_parent" value="0">';
|
||||
|
||||
// Hidden comment post ID field (fixed via JS)
|
||||
$comment_post_id = '<input type="hidden" name="comment_post_ID" value="0" id="comment_post_ID">';
|
||||
|
||||
// Private comment notice for guests
|
||||
$private_notice = '';
|
||||
|
||||
if ( ! is_user_logged_in() ) {
|
||||
if ( get_option( 'fictioneer_enable_comment_notifications' ) ) {
|
||||
$private_notice = __( '<div class="private-comment-notice hide-if-logged-in"><div><strong>Heads up!</strong> Your comment will be invisible to other guests and subscribers (except for replies), including you after a grace period. But if you submit an email address and toggle the bell icon, you will be sent replies until you cancel.</div></div>', 'fictioneer' );
|
||||
} else {
|
||||
$private_notice = __( '<div class="private-comment-notice hide-if-logged-in"><div><strong>Heads up!</strong> Your comment will be invisible to other guests and subscribers (except for replies), including you after a grace period.</div></div>', 'fictioneer' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enclose the submit fields in the .fictioneer-respond__form-actions wrapper,
|
||||
* which will also include the Cancel Reply button if visible. Also close the
|
||||
* .fictioneer-respond__bottom wrapper opened in fictioneer_change_comment_fields
|
||||
* _before_ the submit fields and append the Cancel Reply link.
|
||||
*/
|
||||
|
||||
return sprintf(
|
||||
$close_bottom_container . '<div class="form-submit fictioneer-respond__form-actions ' . $hidden . '"><div>' . $private_toggle . $notification_toggle . '%1$s %2$s</div>%3$s</div><div class="fictioneer-respond__notices">' . $private_notice . '</div>',
|
||||
$submit_button,
|
||||
get_the_ID() ? get_comment_id_fields( get_the_ID() ) : ( $parent_field . $comment_post_id ),
|
||||
preg_replace( '/<a/', '<a class="button _secondary"', get_cancel_comment_reply_link( 'Cancel' ) )
|
||||
);
|
||||
if ( get_option( 'fictioneer_enable_private_commenting' ) ) {
|
||||
$hint = esc_attr_x( 'Toggle to mark as private. Hides the comment from uninvolved viewers.', 'Comment form private toggle.', 'fictioneer' );
|
||||
$private_toggle = '<div class="fictioneer-private-comment-toggle fictioneer-respond__form-toggle"><label class="comment-respond-option-toggle" tabindex="0" role="checkbox" aria-checked="false" aria-label="' . $hint . '"><input name="fictioneer-private-comment-toggle" id="fictioneer-private-comment-toggle" type="checkbox" tabindex="-1" onchange="fcn_ariaCheckedUpdate(this)" hidden><span class="tooltipped _mobile-tooltip" data-tooltip="' . $hint . '"><i class="fa-solid fa-eye off"></i><i class="fa-solid fa-eye-slash on"></i></span></label></div>';
|
||||
}
|
||||
|
||||
// Email subscriptions toggle
|
||||
$notification_toggle = '';
|
||||
$notifications_blocked = get_the_author_meta( 'fictioneer_admin_disable_comment_notifications', get_current_user_id() );
|
||||
$notification_checked = is_user_logged_in() && get_the_author_meta( 'fictioneer_comment_reply_notifications', get_current_user_id() ) && ! $notifications_blocked;
|
||||
$notification_checked = $notification_checked && ( ! get_option( 'fictioneer_enable_public_cache_compatibility' ) || $is_ajax );
|
||||
|
||||
if ( get_option( 'fictioneer_enable_comment_notifications' ) && ! $notifications_blocked ) {
|
||||
$hint = esc_attr_x( 'Toggle to get email notifications about direct replies.', 'Comment form email notification toggle.', 'fictioneer' );
|
||||
$aria_checked = $notification_checked ? 'true' : 'false';
|
||||
$notification_toggle = '<div class="fictioneer-comment-notification-toggle fictioneer-respond__form-toggle"><label class="comment-respond-option-toggle" tabindex="0" role="checkbox" aria-checked="' . $aria_checked . '" aria-label="' . $hint . '"><input name="fictioneer-comment-notification-toggle" id="fictioneer-comment-notification-toggle" type="checkbox" ' . checked( 1, $notification_checked, false ) . ' tabindex="-1" onchange="fcn_ariaCheckedUpdate(this)" hidden><span class="tooltipped _mobile-tooltip" data-tooltip="' . $hint . '"><i class="fa-solid fa-bell on"></i><i class="fa-solid fa-bell-slash off"></i></span></label></div>';
|
||||
}
|
||||
|
||||
// Hidden parent_comment field
|
||||
$parent_field = '<input type="hidden" name="comment_parent" id="comment_parent" value="0">';
|
||||
|
||||
// Hidden comment post ID field (fixed via JS)
|
||||
$comment_post_id = '<input type="hidden" name="comment_post_ID" value="0" id="comment_post_ID">';
|
||||
|
||||
// Private comment notice for guests
|
||||
$private_notice = '';
|
||||
|
||||
if ( ! is_user_logged_in() ) {
|
||||
if ( get_option( 'fictioneer_enable_comment_notifications' ) ) {
|
||||
$private_notice = __( '<div class="private-comment-notice hide-if-logged-in"><div><strong>Heads up!</strong> Your comment will be invisible to other guests and subscribers (except for replies), including you after a grace period. But if you submit an email address and toggle the bell icon, you will be sent replies until you cancel.</div></div>', 'fictioneer' );
|
||||
} else {
|
||||
$private_notice = __( '<div class="private-comment-notice hide-if-logged-in"><div><strong>Heads up!</strong> Your comment will be invisible to other guests and subscribers (except for replies), including you after a grace period.</div></div>', 'fictioneer' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enclose the submit fields in the .fictioneer-respond__form-actions wrapper,
|
||||
* which will also include the Cancel Reply button if visible. Also close the
|
||||
* .fictioneer-respond__bottom wrapper opened in fictioneer_change_comment_fields
|
||||
* _before_ the submit fields and append the Cancel Reply link.
|
||||
*/
|
||||
|
||||
return sprintf(
|
||||
$close_bottom_container . '<div class="form-submit fictioneer-respond__form-actions ' . $hidden . '"><div>' . $private_toggle . $notification_toggle . '%1$s %2$s</div>%3$s</div><div class="fictioneer-respond__notices">' . $private_notice . '</div>',
|
||||
$submit_button,
|
||||
get_the_ID() ? get_comment_id_fields( get_the_ID() ) : ( $parent_field . $comment_post_id ),
|
||||
preg_replace( '/<a/', '<a class="button _secondary"', get_cancel_comment_reply_link( 'Cancel' ) )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! get_option( 'fictioneer_disable_comment_form' ) ) {
|
||||
|
@ -413,89 +413,87 @@ if ( ! function_exists( 'fictioneer_comment_mod_menu' ) ) {
|
||||
// PERFORM COMMENT MODERATION ACTION - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_moderate_comment' ) ) {
|
||||
/**
|
||||
* Performs comment moderation action via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
*/
|
||||
/**
|
||||
* Performs comment moderation action via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_moderate_comment() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_moderate_comment() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
if ( ! current_user_can( 'moderate_comments' ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Permission denied!', 'fictioneer' )] );
|
||||
}
|
||||
if ( ! current_user_can( 'moderate_comments' ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Permission denied!', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
$comment_id = isset( $_POST['id'] ) ? fictioneer_validate_id( $_POST['id'] ) : false;
|
||||
$comment_id = isset( $_POST['id'] ) ? fictioneer_validate_id( $_POST['id'] ) : false;
|
||||
|
||||
if ( empty( $_POST['operation'] ) || ! $comment_id ) {
|
||||
wp_send_json_error( ['error' => __( 'Missing arguments.', 'fictioneer' )] );
|
||||
}
|
||||
if ( empty( $_POST['operation'] ) || ! $comment_id ) {
|
||||
wp_send_json_error( ['error' => __( 'Missing arguments.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
$operation = sanitize_text_field( $_POST['operation'] );
|
||||
$operation = sanitize_text_field( $_POST['operation'] );
|
||||
|
||||
if ( ! in_array( $operation, ['spam', 'trash', 'approve', 'unapprove', 'close', 'open', 'sticky', 'unsticky'] ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Invalid operation.', 'fictioneer' )] );
|
||||
}
|
||||
if ( ! in_array( $operation, ['spam', 'trash', 'approve', 'unapprove', 'close', 'open', 'sticky', 'unsticky'] ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Invalid operation.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
$comment = get_comment( $comment_id );
|
||||
$comment = get_comment( $comment_id );
|
||||
|
||||
if ( ! $comment ) {
|
||||
wp_send_json_error( ['error' => __( 'Comment not found in database.', 'fictioneer' )] );
|
||||
}
|
||||
if ( ! $comment ) {
|
||||
wp_send_json_error( ['error' => __( 'Comment not found in database.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Process and update
|
||||
$result = false;
|
||||
// Process and update
|
||||
$result = false;
|
||||
|
||||
switch ( $operation ) {
|
||||
case 'spam':
|
||||
$result = wp_set_comment_status( $comment_id, 'spam' );
|
||||
switch ( $operation ) {
|
||||
case 'spam':
|
||||
$result = wp_set_comment_status( $comment_id, 'spam' );
|
||||
break;
|
||||
case 'trash':
|
||||
$result = wp_set_comment_status( $comment_id, 'trash' );
|
||||
break;
|
||||
case 'approve':
|
||||
$result = wp_set_comment_status( $comment_id, 'approve' );
|
||||
break;
|
||||
case 'unapprove':
|
||||
$result = wp_set_comment_status( $comment_id, 'hold' );
|
||||
break;
|
||||
case 'close':
|
||||
$result = update_comment_meta( $comment_id, 'fictioneer_thread_closed', true );
|
||||
break;
|
||||
case 'open':
|
||||
$result = update_comment_meta( $comment_id, 'fictioneer_thread_closed', false );
|
||||
break;
|
||||
case 'sticky':
|
||||
if ( $comment->comment_parent ) {
|
||||
wp_send_json_error( ['error' => __( 'Child comments cannot be sticky.', 'fictioneer' )] );
|
||||
break;
|
||||
case 'trash':
|
||||
$result = wp_set_comment_status( $comment_id, 'trash' );
|
||||
}
|
||||
if ( get_comment_meta( $comment->comment_ID, 'fictioneer_deleted_by_user', true ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Deleted comments cannot be sticky.', 'fictioneer' )] );
|
||||
break;
|
||||
case 'approve':
|
||||
$result = wp_set_comment_status( $comment_id, 'approve' );
|
||||
break;
|
||||
case 'unapprove':
|
||||
$result = wp_set_comment_status( $comment_id, 'hold' );
|
||||
break;
|
||||
case 'close':
|
||||
$result = update_comment_meta( $comment_id, 'fictioneer_thread_closed', true );
|
||||
break;
|
||||
case 'open':
|
||||
$result = update_comment_meta( $comment_id, 'fictioneer_thread_closed', false );
|
||||
break;
|
||||
case 'sticky':
|
||||
if ( $comment->comment_parent ) {
|
||||
wp_send_json_error( ['error' => __( 'Child comments cannot be sticky.', 'fictioneer' )] );
|
||||
break;
|
||||
}
|
||||
if ( get_comment_meta( $comment->comment_ID, 'fictioneer_deleted_by_user', true ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Deleted comments cannot be sticky.', 'fictioneer' )] );
|
||||
break;
|
||||
}
|
||||
$result = update_comment_meta( $comment_id, 'fictioneer_sticky', true );
|
||||
break;
|
||||
case 'unsticky':
|
||||
$result = update_comment_meta( $comment_id, 'fictioneer_sticky', false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
$result = update_comment_meta( $comment_id, 'fictioneer_sticky', true );
|
||||
break;
|
||||
case 'unsticky':
|
||||
$result = update_comment_meta( $comment_id, 'fictioneer_sticky', false );
|
||||
break;
|
||||
}
|
||||
|
||||
// Send result
|
||||
if ( $result ) {
|
||||
// Clear cache if necessary
|
||||
if ( fictioneer_caching_active() ) fictioneer_purge_post_cache( $comment->comment_post_ID );
|
||||
// Send result
|
||||
if ( $result ) {
|
||||
// Clear cache if necessary
|
||||
if ( fictioneer_caching_active() ) fictioneer_purge_post_cache( $comment->comment_post_ID );
|
||||
|
||||
wp_send_json_success( ['id' => $comment_id, 'operation' => $operation] );
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Comment could not be updated.', 'fictioneer' )] );
|
||||
}
|
||||
wp_send_json_success( ['id' => $comment_id, 'operation' => $operation] );
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Comment could not be updated.', 'fictioneer' )] );
|
||||
}
|
||||
}
|
||||
|
||||
@ -507,132 +505,126 @@ if ( get_option( 'fictioneer_enable_ajax_comment_moderation' ) ) {
|
||||
// REPORT COMMENTS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_report_comment' ) ) {
|
||||
/**
|
||||
* Adds user to a comment's reports list via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
*/
|
||||
/**
|
||||
* Adds user to a comment's reports list via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_report_comment() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_report_comment() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
if ( empty( $_POST['id'] ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Missing arguments.', 'fictioneer' )] );
|
||||
}
|
||||
if ( empty( $_POST['id'] ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Missing arguments.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
$comment_id = fictioneer_validate_id( $_POST['id'] );
|
||||
$dubious = empty( $_POST['dubious'] ) ? false : $_POST['dubious'] == 'true';
|
||||
$comment_id = fictioneer_validate_id( $_POST['id'] );
|
||||
$dubious = empty( $_POST['dubious'] ) ? false : $_POST['dubious'] == 'true';
|
||||
|
||||
// Get comment
|
||||
$comment = get_comment( $comment_id );
|
||||
// Get comment
|
||||
$comment = get_comment( $comment_id );
|
||||
|
||||
if ( ! $comment ) {
|
||||
wp_send_json_error( ['error' => __( 'Comment not found.', 'fictioneer' )] );
|
||||
}
|
||||
if ( ! $comment ) {
|
||||
wp_send_json_error( ['error' => __( 'Comment not found.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Check if user is allowed to flag comments
|
||||
if ( get_the_author_meta( 'fictioneer_admin_disable_reporting', $user->ID ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Reporting capability disabled.', 'fictioneer' )] );
|
||||
}
|
||||
// Check if user is allowed to flag comments
|
||||
if ( get_the_author_meta( 'fictioneer_admin_disable_reporting', $user->ID ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Reporting capability disabled.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Get current reports (array of user IDs)
|
||||
$reports = get_comment_meta( $comment_id, 'fictioneer_user_reports', true );
|
||||
$reports = $reports ? $reports : [];
|
||||
// Get current reports (array of user IDs)
|
||||
$reports = get_comment_meta( $comment_id, 'fictioneer_user_reports', true );
|
||||
$reports = $reports ? $reports : [];
|
||||
|
||||
// Dubious if state not clear due to caching
|
||||
if ( $dubious && array_key_exists( $user->ID, $reports ) ) {
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'id' => $comment_id,
|
||||
'flagged' => true,
|
||||
'resync' => __( 'You have already reported this comment. Click the flag again to retract the report.', 'fictioneer' )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Check whether to add or remove the user from the array
|
||||
if ( array_key_exists( $user->ID, $reports ) ) {
|
||||
unset( $reports[ $user->ID ] );
|
||||
} else {
|
||||
$user_data = get_userdata( $user->ID );
|
||||
$reports[ $user->ID ] = '<a href="' . get_edit_profile_url( $user->ID ) . '">' . $user_data->display_name . '</a>';
|
||||
}
|
||||
|
||||
// Update comment meta
|
||||
$result = update_comment_meta( $comment_id, 'fictioneer_user_reports', $reports );
|
||||
|
||||
if ( ! $result ) {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Report could not be saved.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Send back to moderation?
|
||||
$auto_moderation = get_comment_meta( $comment_id, 'fictioneer_auto_moderation', true );
|
||||
|
||||
if ( empty( $auto_moderation ) && count( $reports ) >= get_option( 'fictioneer_comment_report_threshold', 10 ) ) {
|
||||
// Only ever auto-moderate once!
|
||||
update_comment_meta( $comment_id, 'fictioneer_auto_moderation', time() );
|
||||
|
||||
// Set back to hold
|
||||
wp_set_comment_status( $comment_id, 'hold' );
|
||||
}
|
||||
|
||||
// Purge cache
|
||||
if ( fictioneer_caching_active() ) fictioneer_purge_post_cache( $comment->comment_post_ID );
|
||||
|
||||
// Return result
|
||||
// Dubious if state not clear due to caching
|
||||
if ( $dubious && array_key_exists( $user->ID, $reports ) ) {
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'id' => $comment_id,
|
||||
'flagged' => array_key_exists( $user->ID, $reports )
|
||||
'flagged' => true,
|
||||
'resync' => __( 'You have already reported this comment. Click the flag again to retract the report.', 'fictioneer' )
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_add_comments_report_column' ) ) {
|
||||
/**
|
||||
* Add comments reports column
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
* @link https://rudrastyh.com/wordpress/comments-table-columns.html
|
||||
*
|
||||
* @param array $cols Default columns.
|
||||
*
|
||||
* @return array Updated columns.
|
||||
*/
|
||||
|
||||
function fictioneer_add_comments_report_column( $cols ) {
|
||||
$new_cols = ['fictioneer_reports' => __( 'Reports', 'fictioneer' )];
|
||||
$new_cols = array_slice( $cols, 0, 3, true ) + $new_cols + array_slice( $cols, 3, NULL, true );
|
||||
return $new_cols;
|
||||
// Check whether to add or remove the user from the array
|
||||
if ( array_key_exists( $user->ID, $reports ) ) {
|
||||
unset( $reports[ $user->ID ] );
|
||||
} else {
|
||||
$user_data = get_userdata( $user->ID );
|
||||
$reports[ $user->ID ] = '<a href="' . get_edit_profile_url( $user->ID ) . '">' . $user_data->display_name . '</a>';
|
||||
}
|
||||
|
||||
// Update comment meta
|
||||
$result = update_comment_meta( $comment_id, 'fictioneer_user_reports', $reports );
|
||||
|
||||
if ( ! $result ) {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Report could not be saved.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Send back to moderation?
|
||||
$auto_moderation = get_comment_meta( $comment_id, 'fictioneer_auto_moderation', true );
|
||||
|
||||
if ( empty( $auto_moderation ) && count( $reports ) >= get_option( 'fictioneer_comment_report_threshold', 10 ) ) {
|
||||
// Only ever auto-moderate once!
|
||||
update_comment_meta( $comment_id, 'fictioneer_auto_moderation', time() );
|
||||
|
||||
// Set back to hold
|
||||
wp_set_comment_status( $comment_id, 'hold' );
|
||||
}
|
||||
|
||||
// Purge cache
|
||||
if ( fictioneer_caching_active() ) fictioneer_purge_post_cache( $comment->comment_post_ID );
|
||||
|
||||
// Return result
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'id' => $comment_id,
|
||||
'flagged' => array_key_exists( $user->ID, $reports )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_add_comments_report_column_content' ) ) {
|
||||
/**
|
||||
* Echo content for comments reports column
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
* @link https://rudrastyh.com/wordpress/comments-table-columns.html
|
||||
* @link https://developer.wordpress.org/reference/hooks/manage_comments_custom_column/
|
||||
*
|
||||
* @param string $column The custom column's name.
|
||||
* @param string $comment_id The comment ID as a numeric string.
|
||||
*/
|
||||
/**
|
||||
* Add comments reports column
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
* @link https://rudrastyh.com/wordpress/comments-table-columns.html
|
||||
*
|
||||
* @param array $cols Default columns.
|
||||
*
|
||||
* @return array Updated columns.
|
||||
*/
|
||||
|
||||
function fictioneer_add_comments_report_column_content( $column, $comment_id ) {
|
||||
$reports = get_comment_meta( $comment_id, 'fictioneer_user_reports', true );
|
||||
function fictioneer_add_comments_report_column( $cols ) {
|
||||
$new_cols = ['fictioneer_reports' => __( 'Reports', 'fictioneer' )];
|
||||
$new_cols = array_slice( $cols, 0, 3, true ) + $new_cols + array_slice( $cols, 3, NULL, true );
|
||||
return $new_cols;
|
||||
}
|
||||
|
||||
if ( $reports && is_array( $reports ) ) {
|
||||
echo count( $reports );
|
||||
} else {
|
||||
echo 0;
|
||||
}
|
||||
/**
|
||||
* Echo content for comments reports column
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
* @link https://rudrastyh.com/wordpress/comments-table-columns.html
|
||||
* @link https://developer.wordpress.org/reference/hooks/manage_comments_custom_column/
|
||||
*
|
||||
* @param string $column The custom column's name.
|
||||
* @param string $comment_id The comment ID as a numeric string.
|
||||
*/
|
||||
|
||||
function fictioneer_add_comments_report_column_content( $column, $comment_id ) {
|
||||
$reports = get_comment_meta( $comment_id, 'fictioneer_user_reports', true );
|
||||
|
||||
if ( $reports && is_array( $reports ) ) {
|
||||
echo count( $reports );
|
||||
} else {
|
||||
echo 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,66 +34,64 @@ add_filter( 'comment_reply_link', 'fictioneer_comment_login_to_reply', 10, 4 );
|
||||
// SHIFT STICKY COMMENTS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_shift_sticky_comments' ) ) {
|
||||
/**
|
||||
* Query sticky comments and merge them in first
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param array $comments Queried comments.
|
||||
* @param int $post_id The post ID.
|
||||
*
|
||||
* @return array Comments with sticky ones on top.
|
||||
*/
|
||||
/**
|
||||
* Query sticky comments and merge them in first
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param array $comments Queried comments.
|
||||
* @param int $post_id The post ID.
|
||||
*
|
||||
* @return array Comments with sticky ones on top.
|
||||
*/
|
||||
|
||||
function fictioneer_shift_sticky_comments( $comments, $post_id ) {
|
||||
// Query arguments
|
||||
$stick_comments_args = array(
|
||||
'status' => 'approve',
|
||||
'post_id' => $post_id,
|
||||
'parent' => 0,
|
||||
'meta_query' => array(
|
||||
'relation' => 'AND',
|
||||
function fictioneer_shift_sticky_comments( $comments, $post_id ) {
|
||||
// Query arguments
|
||||
$stick_comments_args = array(
|
||||
'status' => 'approve',
|
||||
'post_id' => $post_id,
|
||||
'parent' => 0,
|
||||
'meta_query' => array(
|
||||
'relation' => 'AND',
|
||||
array(
|
||||
'key' => 'fictioneer_sticky',
|
||||
'value' => 1,
|
||||
),
|
||||
array(
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'key' => 'fictioneer_sticky',
|
||||
'value' => 1,
|
||||
),
|
||||
array(
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'key' => 'fictioneer_marked_offensive',
|
||||
'compare' => 'NOT EXISTS',
|
||||
),
|
||||
array(
|
||||
'key' => 'fictioneer_marked_offensive',
|
||||
'value' => 1,
|
||||
'compare' => '!=',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'key' => 'fictioneer_deleted_by_user',
|
||||
'key' => 'fictioneer_marked_offensive',
|
||||
'compare' => 'NOT EXISTS',
|
||||
)
|
||||
),
|
||||
array(
|
||||
'key' => 'fictioneer_marked_offensive',
|
||||
'value' => 1,
|
||||
'compare' => '!=',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'key' => 'fictioneer_deleted_by_user',
|
||||
'compare' => 'NOT EXISTS',
|
||||
)
|
||||
);
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! get_option( 'fictioneer_disable_comment_query' ) ) {
|
||||
$stick_comments_args['type'] = ['comment', 'private'];
|
||||
$stick_comments_args['order'] = get_option( 'comment_order' );
|
||||
} else {
|
||||
$stick_comments_args['type'] = ['comment'];
|
||||
}
|
||||
|
||||
// Filter query arguments
|
||||
$query_args = apply_filters( 'fictioneer_filter_comments_query', $stick_comments_args, $post_id );
|
||||
|
||||
// Query comments
|
||||
$sticky_comments_query = new WP_Comment_Query( $query_args );
|
||||
$sticky_comments = $sticky_comments_query->comments;
|
||||
|
||||
// Return merged comment lists
|
||||
return array_merge( $sticky_comments, $comments );
|
||||
if ( ! get_option( 'fictioneer_disable_comment_query' ) ) {
|
||||
$stick_comments_args['type'] = ['comment', 'private'];
|
||||
$stick_comments_args['order'] = get_option( 'comment_order' );
|
||||
} else {
|
||||
$stick_comments_args['type'] = ['comment'];
|
||||
}
|
||||
|
||||
// Filter query arguments
|
||||
$query_args = apply_filters( 'fictioneer_filter_comments_query', $stick_comments_args, $post_id );
|
||||
|
||||
// Query comments
|
||||
$sticky_comments_query = new WP_Comment_Query( $query_args );
|
||||
$sticky_comments = $sticky_comments_query->comments;
|
||||
|
||||
// Return merged comment lists
|
||||
return array_merge( $sticky_comments, $comments );
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_sticky_comments' ) ) {
|
||||
@ -370,30 +368,28 @@ if ( ! function_exists( 'fictioneer_get_comment_badge' ) ) {
|
||||
// THEME COMMENT TEXT
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_replace_comment_line_breaks' ) ) {
|
||||
/**
|
||||
* Properly wrap empty lines into paragraphs
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @since Fictioneer 5.2.6 Updated and changed to not mess up some languages.
|
||||
*
|
||||
* @param string $comment_content The comment content.
|
||||
*
|
||||
* @return string $comment_content The modified comment content.
|
||||
*/
|
||||
/**
|
||||
* Properly wrap empty lines into paragraphs
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @since Fictioneer 5.2.6 Updated and changed to not mess up some languages.
|
||||
*
|
||||
* @param string $comment_content The comment content.
|
||||
*
|
||||
* @return string $comment_content The modified comment content.
|
||||
*/
|
||||
|
||||
function fictioneer_replace_comment_line_breaks( $comment_content ) {
|
||||
$lines = preg_split( '/\R/', $comment_content );
|
||||
function fictioneer_replace_comment_line_breaks( $comment_content ) {
|
||||
$lines = preg_split( '/\R/', $comment_content );
|
||||
|
||||
$wrapped = array_map( function( $line ) {
|
||||
if ( trim( $line ) === '' ) {
|
||||
return '<p></p>';
|
||||
}
|
||||
return $line;
|
||||
}, $lines );
|
||||
$wrapped = array_map( function( $line ) {
|
||||
if ( trim( $line ) === '' ) {
|
||||
return '<p></p>';
|
||||
}
|
||||
return $line;
|
||||
}, $lines );
|
||||
|
||||
return implode( PHP_EOL, $wrapped );
|
||||
}
|
||||
return implode( PHP_EOL, $wrapped );
|
||||
}
|
||||
|
||||
if ( ! get_option( 'fictioneer_disable_comment_callback' ) ) {
|
||||
@ -832,20 +828,18 @@ if ( ! function_exists( 'fictioneer_theme_comment' ) ) {
|
||||
// THEME COMMENT PAGINATION MARKUP
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_pagination_markup' ) ) {
|
||||
/**
|
||||
* Change comment pagination markup
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
*
|
||||
* @param string $template The default comment pagination template.
|
||||
*
|
||||
* @return string The modified comment pagination template.
|
||||
*/
|
||||
/**
|
||||
* Change comment pagination markup
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
*
|
||||
* @param string $template The default comment pagination template.
|
||||
*
|
||||
* @return string The modified comment pagination template.
|
||||
*/
|
||||
|
||||
function fictioneer_pagination_markup( $template ) {
|
||||
return '<nav class="pagination _padding-top %1$s" aria-label="%4$s" role="navigation">%3$s</nav>';
|
||||
}
|
||||
function fictioneer_pagination_markup( $template ) {
|
||||
return '<nav class="pagination _padding-top %1$s" aria-label="%4$s" role="navigation">%3$s</nav>';
|
||||
}
|
||||
|
||||
if ( ! get_option( 'fictioneer_disable_comment_pagination' ) ) {
|
||||
|
@ -83,149 +83,147 @@ if ( ! function_exists( 'fictioneer_build_story_comment' ) ) {
|
||||
// SEND STORY COMMENTS - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_request_story_comments' ) ) {
|
||||
/**
|
||||
* Sends a block of comments for a given story via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*/
|
||||
/**
|
||||
* Sends a block of comments for a given story via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*/
|
||||
|
||||
function fictioneer_request_story_comments() {
|
||||
// Nonce
|
||||
check_ajax_referer( 'fictioneer_nonce', 'nonce' );
|
||||
function fictioneer_request_story_comments() {
|
||||
// Nonce
|
||||
check_ajax_referer( 'fictioneer_nonce', 'nonce' );
|
||||
|
||||
// Validations
|
||||
$story_id = isset( $_GET['post_id'] ) ? fictioneer_validate_id( $_GET['post_id'], 'fcn_story' ) : false;
|
||||
// Validations
|
||||
$story_id = isset( $_GET['post_id'] ) ? fictioneer_validate_id( $_GET['post_id'], 'fcn_story' ) : false;
|
||||
|
||||
// Abort if not a story
|
||||
if ( ! $story_id ) {
|
||||
wp_send_json_error( ['error' => __( 'Comments could not be loaded.', 'fictioneer' )] );
|
||||
}
|
||||
// Abort if not a story
|
||||
if ( ! $story_id ) {
|
||||
wp_send_json_error( ['error' => __( 'Comments could not be loaded.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Setup
|
||||
$page = isset( $_GET['page'] ) ? absint( $_GET['page'] ) : 1;
|
||||
$story = fictioneer_get_story_data( $story_id, true, array( 'force_comment_count_refresh' => true ) );
|
||||
$chapter_ids = $story['chapter_ids']; // Only contains publicly visible chapters
|
||||
$comments_per_page = get_option( 'comments_per_page' );
|
||||
$chapter_data = [];
|
||||
$report_threshold = get_option( 'fictioneer_comment_report_threshold', 10 ) ?? 10;
|
||||
// Setup
|
||||
$page = isset( $_GET['page'] ) ? absint( $_GET['page'] ) : 1;
|
||||
$story = fictioneer_get_story_data( $story_id, true, array( 'force_comment_count_refresh' => true ) );
|
||||
$chapter_ids = $story['chapter_ids']; // Only contains publicly visible chapters
|
||||
$comments_per_page = get_option( 'comments_per_page' );
|
||||
$chapter_data = [];
|
||||
$report_threshold = get_option( 'fictioneer_comment_report_threshold', 10 ) ?? 10;
|
||||
|
||||
// Abort if no chapters have been found
|
||||
if ( count( $chapter_ids ) < 1 ) die();
|
||||
// Abort if no chapters have been found
|
||||
if ( count( $chapter_ids ) < 1 ) die();
|
||||
|
||||
// Collect titles and permalinks of all chapters
|
||||
foreach ( $chapter_ids as $chapter_id ) {
|
||||
$chapter_data[ $chapter_id ] = [get_the_title( $chapter_id ), get_the_permalink( $chapter_id )];
|
||||
}
|
||||
// Collect titles and permalinks of all chapters
|
||||
foreach ( $chapter_ids as $chapter_id ) {
|
||||
$chapter_data[ $chapter_id ] = [get_the_title( $chapter_id ), get_the_permalink( $chapter_id )];
|
||||
}
|
||||
|
||||
// Get comments
|
||||
$comments = get_comments(
|
||||
array(
|
||||
'status' => 'approve',
|
||||
'post_type' => ['fcn_chapter'],
|
||||
'post__in' => $chapter_ids,
|
||||
'number' => $comments_per_page,
|
||||
'paged' => $page,
|
||||
'meta_query' => array(
|
||||
// Get comments
|
||||
$comments = get_comments(
|
||||
array(
|
||||
'status' => 'approve',
|
||||
'post_type' => ['fcn_chapter'],
|
||||
'post__in' => $chapter_ids,
|
||||
'number' => $comments_per_page,
|
||||
'paged' => $page,
|
||||
'meta_query' => array(
|
||||
array(
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'key' => 'fictioneer_marked_offensive',
|
||||
'value' => [true, 1, '1'],
|
||||
'compare' => 'NOT IN'
|
||||
),
|
||||
array(
|
||||
'key' => 'fictioneer_marked_offensive',
|
||||
'compare' => 'NOT EXISTS'
|
||||
)
|
||||
'key' => 'fictioneer_marked_offensive',
|
||||
'value' => [true, 1, '1'],
|
||||
'compare' => 'NOT IN'
|
||||
),
|
||||
array(
|
||||
'key' => 'fictioneer_marked_offensive',
|
||||
'compare' => 'NOT EXISTS'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
)
|
||||
);
|
||||
|
||||
// Calculate how many more comments (if any) are there after this batch
|
||||
$remaining = $story['comment_count'] - $page * $comments_per_page;
|
||||
// Calculate how many more comments (if any) are there after this batch
|
||||
$remaining = $story['comment_count'] - $page * $comments_per_page;
|
||||
|
||||
// Start buffer
|
||||
ob_start();
|
||||
// Start buffer
|
||||
ob_start();
|
||||
|
||||
// Make sure there are comments to display...
|
||||
if ( count( $comments ) > 0 ) {
|
||||
foreach ( $comments as $comment ) {
|
||||
$reports = get_comment_meta( $comment->comment_ID, 'fictioneer_user_reports', true );
|
||||
|
||||
// Render empty if...
|
||||
if ( get_comment_meta( $comment->comment_ID, 'fictioneer_deleted_by_user', true ) ) {
|
||||
// Start HTML ---> ?>
|
||||
<li class="fictioneer-comment _deleted">
|
||||
<div class="fictioneer-comment__container">
|
||||
<div class="fictioneer-comment__hidden-notice"><?php _e( 'Comment has been deleted by user.', 'fictioneer' ); ?></div>
|
||||
</div>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Hidden by reports...
|
||||
if ( get_option( 'fictioneer_enable_comment_reporting' ) ) {
|
||||
if ( ! empty( $reports ) && count( $reports ) >= $report_threshold ) {
|
||||
// Start HTML ---> ?>
|
||||
<li class="fictioneer-comment _deleted">
|
||||
<div class="fictioneer-comment__container">
|
||||
<div class="fictioneer-comment__hidden-notice"><?php _e( 'Comment is hidden due to negative reports.', 'fictioneer' ); ?></div>
|
||||
</div>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
}
|
||||
// Make sure there are comments to display...
|
||||
if ( count( $comments ) > 0 ) {
|
||||
foreach ( $comments as $comment ) {
|
||||
$reports = get_comment_meta( $comment->comment_ID, 'fictioneer_user_reports', true );
|
||||
|
||||
// Render empty if...
|
||||
if ( get_comment_meta( $comment->comment_ID, 'fictioneer_deleted_by_user', true ) ) {
|
||||
// Start HTML ---> ?>
|
||||
<li class="fictioneer-comment _story-comment <?php echo $comment->comment_type; ?>">
|
||||
<li class="fictioneer-comment _deleted">
|
||||
<div class="fictioneer-comment__container">
|
||||
<?php fictioneer_build_story_comment( $comment, $chapter_data ); ?>
|
||||
<div class="fictioneer-comment__hidden-notice"><?php _e( 'Comment has been deleted by user.', 'fictioneer' ); ?></div>
|
||||
</div>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Load more button and loading placeholder if there are still comments left
|
||||
if ( $remaining > 0 ) {
|
||||
$load_n = $remaining > $comments_per_page ? $comments_per_page : $remaining;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<li class="load-more-list-item">
|
||||
<button class="load-more-comments-button"><?php
|
||||
printf(
|
||||
_n(
|
||||
'Load next comment (may contain spoilers)',
|
||||
'Load next %s comments (may contain spoilers)',
|
||||
$load_n,
|
||||
'fictioneer'
|
||||
),
|
||||
$load_n
|
||||
);
|
||||
?></button>
|
||||
</li>
|
||||
<div class="comments-loading-placeholder hidden"><i class="fas fa-spinner spinner"></i></div>
|
||||
<?php // <--- End HTML
|
||||
// Hidden by reports...
|
||||
if ( get_option( 'fictioneer_enable_comment_reporting' ) ) {
|
||||
if ( ! empty( $reports ) && count( $reports ) >= $report_threshold ) {
|
||||
// Start HTML ---> ?>
|
||||
<li class="fictioneer-comment _deleted">
|
||||
<div class="fictioneer-comment__container">
|
||||
<div class="fictioneer-comment__hidden-notice"><?php _e( 'Comment is hidden due to negative reports.', 'fictioneer' ); ?></div>
|
||||
</div>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<li class="fictioneer-comment private">
|
||||
<li class="fictioneer-comment _story-comment <?php echo $comment->comment_type; ?>">
|
||||
<div class="fictioneer-comment__container">
|
||||
<div class="fictioneer-comment__hidden-notice"><?php _e( 'No public comments to display.', 'fictioneer' ); ?></div>
|
||||
<?php fictioneer_build_story_comment( $comment, $chapter_data ); ?>
|
||||
</div>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
|
||||
// Get buffer
|
||||
$output = fictioneer_minify_html( ob_get_clean() );
|
||||
// Load more button and loading placeholder if there are still comments left
|
||||
if ( $remaining > 0 ) {
|
||||
$load_n = $remaining > $comments_per_page ? $comments_per_page : $remaining;
|
||||
|
||||
// Return buffer
|
||||
wp_send_json_success( ['html' => $output, 'postId' => $story_id, 'page' => $page] );
|
||||
// Start HTML ---> ?>
|
||||
<li class="load-more-list-item">
|
||||
<button class="load-more-comments-button"><?php
|
||||
printf(
|
||||
_n(
|
||||
'Load next comment (may contain spoilers)',
|
||||
'Load next %s comments (may contain spoilers)',
|
||||
$load_n,
|
||||
'fictioneer'
|
||||
),
|
||||
$load_n
|
||||
);
|
||||
?></button>
|
||||
</li>
|
||||
<div class="comments-loading-placeholder hidden"><i class="fas fa-spinner spinner"></i></div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
} else {
|
||||
// Start HTML ---> ?>
|
||||
<li class="fictioneer-comment private">
|
||||
<div class="fictioneer-comment__container">
|
||||
<div class="fictioneer-comment__hidden-notice"><?php _e( 'No public comments to display.', 'fictioneer' ); ?></div>
|
||||
</div>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
|
||||
// Get buffer
|
||||
$output = fictioneer_minify_html( ob_get_clean() );
|
||||
|
||||
// Return buffer
|
||||
wp_send_json_success( ['html' => $output, 'postId' => $story_id, 'page' => $page] );
|
||||
}
|
||||
add_action( 'wp_ajax_nopriv_fictioneer_request_story_comments', 'fictioneer_request_story_comments' );
|
||||
add_action( 'wp_ajax_fictioneer_request_story_comments', 'fictioneer_request_story_comments' );
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,81 +4,79 @@
|
||||
// LIST OF ALL COLLECTIONS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_collections_list' ) ) {
|
||||
/**
|
||||
* Outputs the paginated card list for all collections
|
||||
*
|
||||
* @since 5.0
|
||||
* @see collections.php
|
||||
*
|
||||
* @param int $args['current_page'] Current page number of pagination or 1.
|
||||
* @param int $args['post_id'] The post ID.
|
||||
* @param WP_Query $args['collections'] Paginated query of all published collections.
|
||||
* @param string $args['queried_type'] The queried post type ('fcn_collection').
|
||||
* @param array $args['query_args'] The query arguments used.
|
||||
* @param string $args['order'] Current order. Default 'desc'.
|
||||
* @param string $args['orderby'] Current orderby. Default 'modified'.
|
||||
* @param int|string $args['ago'] Current date query argument part. Default 0.
|
||||
*/
|
||||
/**
|
||||
* Outputs the paginated card list for all collections
|
||||
*
|
||||
* @since 5.0
|
||||
* @see collections.php
|
||||
*
|
||||
* @param int $args['current_page'] Current page number of pagination or 1.
|
||||
* @param int $args['post_id'] The post ID.
|
||||
* @param WP_Query $args['collections'] Paginated query of all published collections.
|
||||
* @param string $args['queried_type'] The queried post type ('fcn_collection').
|
||||
* @param array $args['query_args'] The query arguments used.
|
||||
* @param string $args['order'] Current order. Default 'desc'.
|
||||
* @param string $args['orderby'] Current orderby. Default 'modified'.
|
||||
* @param int|string $args['ago'] Current date query argument part. Default 0.
|
||||
*/
|
||||
|
||||
function fictioneer_collections_list( $args ) {
|
||||
// Start HTML ---> ?>
|
||||
<section class="collections__list spacing-top">
|
||||
<ul class="card-list" id="list-of-collections">
|
||||
function fictioneer_collections_list( $args ) {
|
||||
// Start HTML ---> ?>
|
||||
<section class="collections__list spacing-top">
|
||||
<ul class="card-list" id="list-of-collections">
|
||||
|
||||
<?php if ( $args['collections']->have_posts() ) : ?>
|
||||
|
||||
<?php
|
||||
// Card arguments
|
||||
$card_args = array(
|
||||
'cache' => fictioneer_caching_active() && ! fictioneer_private_caching_active(),
|
||||
'order' => $args['order'] ?? 'desc',
|
||||
'orderby' => $args['orderby'] ?? 'modified',
|
||||
'ago' => $args['ago'] ?? 0
|
||||
);
|
||||
|
||||
// Filter card arguments
|
||||
$card_args = apply_filters( 'fictioneer_filter_collections_card_args', $card_args, $args );
|
||||
|
||||
while ( $args['collections']->have_posts() ) {
|
||||
$args['collections']->the_post();
|
||||
get_template_part( 'partials/_card-collection', null, $card_args );
|
||||
}
|
||||
|
||||
// Actions at end of results
|
||||
do_action( 'fictioneer_collections_end_of_results', $args );
|
||||
?>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<?php do_action( 'fictioneer_collections_no_results', $args ); ?>
|
||||
|
||||
<li class="no-results">
|
||||
<span><?php _e( 'No collections found.', 'fictioneer' ) ?></span>
|
||||
</li>
|
||||
|
||||
<?php endif; wp_reset_postdata(); ?>
|
||||
<?php if ( $args['collections']->have_posts() ) : ?>
|
||||
|
||||
<?php
|
||||
$pag_args = array(
|
||||
'base' => add_query_arg( 'paged', '%#%' ),
|
||||
'format' => '?paged=%#%',
|
||||
'current' => max( 1, get_query_var( 'paged' ) ),
|
||||
'total' => $args['collections']->max_num_pages,
|
||||
'prev_text' => fcntr( 'previous' ),
|
||||
'next_text' => fcntr( 'next' ),
|
||||
'add_fragment' => '#list-of-collections'
|
||||
// Card arguments
|
||||
$card_args = array(
|
||||
'cache' => fictioneer_caching_active() && ! fictioneer_private_caching_active(),
|
||||
'order' => $args['order'] ?? 'desc',
|
||||
'orderby' => $args['orderby'] ?? 'modified',
|
||||
'ago' => $args['ago'] ?? 0
|
||||
);
|
||||
|
||||
// Filter card arguments
|
||||
$card_args = apply_filters( 'fictioneer_filter_collections_card_args', $card_args, $args );
|
||||
|
||||
while ( $args['collections']->have_posts() ) {
|
||||
$args['collections']->the_post();
|
||||
get_template_part( 'partials/_card-collection', null, $card_args );
|
||||
}
|
||||
|
||||
// Actions at end of results
|
||||
do_action( 'fictioneer_collections_end_of_results', $args );
|
||||
?>
|
||||
|
||||
<?php if ( $args['collections']->max_num_pages > 1 ) : ?>
|
||||
<li class="pagination"><?php echo fictioneer_paginate_links( $pag_args ); ?></li>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
|
||||
</ul>
|
||||
</section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
<?php do_action( 'fictioneer_collections_no_results', $args ); ?>
|
||||
|
||||
<li class="no-results">
|
||||
<span><?php _e( 'No collections found.', 'fictioneer' ) ?></span>
|
||||
</li>
|
||||
|
||||
<?php endif; wp_reset_postdata(); ?>
|
||||
|
||||
<?php
|
||||
$pag_args = array(
|
||||
'base' => add_query_arg( 'paged', '%#%' ),
|
||||
'format' => '?paged=%#%',
|
||||
'current' => max( 1, get_query_var( 'paged' ) ),
|
||||
'total' => $args['collections']->max_num_pages,
|
||||
'prev_text' => fcntr( 'previous' ),
|
||||
'next_text' => fcntr( 'next' ),
|
||||
'add_fragment' => '#list-of-collections'
|
||||
);
|
||||
?>
|
||||
|
||||
<?php if ( $args['collections']->max_num_pages > 1 ) : ?>
|
||||
<li class="pagination"><?php echo fictioneer_paginate_links( $pag_args ); ?></li>
|
||||
<?php endif; ?>
|
||||
|
||||
</ul>
|
||||
</section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_collections_after_content', 'fictioneer_collections_list', 30 );
|
||||
|
||||
@ -86,44 +84,42 @@ add_action( 'fictioneer_collections_after_content', 'fictioneer_collections_list
|
||||
// COLLECTION TAGS & WARNINGS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_collection_tags_and_warnings' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the collection page tags and warnings
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_Post $args['collection'] Collection post object.
|
||||
* @param int $args['collection_id'] The collection post ID.
|
||||
* @param string $args['title'] Safe collection title.
|
||||
* @param int $args['current_page'] Number of the current page or 1.
|
||||
* @param int $args['max_pages'] Total number of pages or 1.
|
||||
* @param array $args['featured_list'] IDs of featured items in the collection.
|
||||
* @param WP_Query $args['featured_query'] Paginated query of featured items.
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the collection page tags and warnings
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_Post $args['collection'] Collection post object.
|
||||
* @param int $args['collection_id'] The collection post ID.
|
||||
* @param string $args['title'] Safe collection title.
|
||||
* @param int $args['current_page'] Number of the current page or 1.
|
||||
* @param int $args['max_pages'] Total number of pages or 1.
|
||||
* @param array $args['featured_list'] IDs of featured items in the collection.
|
||||
* @param WP_Query $args['featured_query'] Paginated query of featured items.
|
||||
*/
|
||||
|
||||
function fictioneer_collection_tags_and_warnings( $args ) {
|
||||
// Setup
|
||||
$tags = get_the_tags( $args['collection_id'] );
|
||||
$warnings = get_the_terms( $args['collection_id'], 'fcn_content_warning' );
|
||||
function fictioneer_collection_tags_and_warnings( $args ) {
|
||||
// Setup
|
||||
$tags = get_the_tags( $args['collection_id'] );
|
||||
$warnings = get_the_terms( $args['collection_id'], 'fcn_content_warning' );
|
||||
|
||||
// Flags
|
||||
$tags_shown = $tags && ! get_option( 'fictioneer_hide_tags_on_pages' );
|
||||
$warnings_shown = $warnings && ! get_option( 'fictioneer_hide_content_warnings_on_pages' );
|
||||
// Flags
|
||||
$tags_shown = $tags && ! get_option( 'fictioneer_hide_tags_on_pages' );
|
||||
$warnings_shown = $warnings && ! get_option( 'fictioneer_hide_content_warnings_on_pages' );
|
||||
|
||||
// Abort conditions...
|
||||
if ( ! $tags_shown && ! $warnings_shown ) return;
|
||||
// Abort conditions...
|
||||
if ( ! $tags_shown && ! $warnings_shown ) return;
|
||||
|
||||
// Prepare
|
||||
$tag_args = [];
|
||||
if ( $tags_shown ) $tag_args[] = $tags;
|
||||
if ( $warnings_shown ) $tag_args[] = $warnings;
|
||||
// Prepare
|
||||
$tag_args = [];
|
||||
if ( $tags_shown ) $tag_args[] = $tags;
|
||||
if ( $warnings_shown ) $tag_args[] = $warnings;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<section class="collection__tags-and-warnings tag-group"><?php
|
||||
echo fictioneer_get_taxonomy_pills( $tag_args, '_secondary' );
|
||||
?></section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
// Start HTML ---> ?>
|
||||
<section class="collection__tags-and-warnings tag-group"><?php
|
||||
echo fictioneer_get_taxonomy_pills( $tag_args, '_secondary' );
|
||||
?></section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_collection_after_content', 'fictioneer_collection_tags_and_warnings', 10 );
|
||||
|
||||
@ -131,28 +127,26 @@ add_action( 'fictioneer_collection_after_content', 'fictioneer_collection_tags_a
|
||||
// COLLECTION STATISTICS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_collection_statistics' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the collection page statistics
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_Post $args['collection'] Collection post object.
|
||||
* @param int $args['collection_id'] The collection post ID.
|
||||
* @param string $args['title'] Safe collection title.
|
||||
* @param int $args['current_page'] Number of the current page or 1.
|
||||
* @param int $args['max_pages'] Total number of pages or 1.
|
||||
* @param array $args['featured_list'] IDs of featured items in the collection.
|
||||
* @param WP_Query $args['featured_query'] Paginated query of featured items.
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the collection page statistics
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_Post $args['collection'] Collection post object.
|
||||
* @param int $args['collection_id'] The collection post ID.
|
||||
* @param string $args['title'] Safe collection title.
|
||||
* @param int $args['current_page'] Number of the current page or 1.
|
||||
* @param int $args['max_pages'] Total number of pages or 1.
|
||||
* @param array $args['featured_list'] IDs of featured items in the collection.
|
||||
* @param WP_Query $args['featured_query'] Paginated query of featured items.
|
||||
*/
|
||||
|
||||
function fictioneer_collection_statistics( $args ) {
|
||||
// Abort if...
|
||||
if ( post_password_required() ) return;
|
||||
function fictioneer_collection_statistics( $args ) {
|
||||
// Abort if...
|
||||
if ( post_password_required() ) return;
|
||||
|
||||
// Render template
|
||||
get_template_part( 'partials/_collection-statistics', null, $args );
|
||||
}
|
||||
// Render template
|
||||
get_template_part( 'partials/_collection-statistics', null, $args );
|
||||
}
|
||||
add_action( 'fictioneer_collection_after_content', 'fictioneer_collection_statistics', 20 );
|
||||
|
||||
@ -160,68 +154,66 @@ add_action( 'fictioneer_collection_after_content', 'fictioneer_collection_statis
|
||||
// COLLECTION FEATURED LIST
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_collection_featured_list' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the collection page featured list
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_Post $args['collection'] Collection post object.
|
||||
* @param int $args['collection_id'] The collection post ID.
|
||||
* @param string $args['title'] Safe collection title.
|
||||
* @param int $args['current_page'] Number of the current page or 1.
|
||||
* @param int $args['max_pages'] Total number of pages or 1.
|
||||
* @param array $args['featured_list'] IDs of featured items in the collection.
|
||||
* @param WP_Query $args['featured_query'] Paginated query of featured items.
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the collection page featured list
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_Post $args['collection'] Collection post object.
|
||||
* @param int $args['collection_id'] The collection post ID.
|
||||
* @param string $args['title'] Safe collection title.
|
||||
* @param int $args['current_page'] Number of the current page or 1.
|
||||
* @param int $args['max_pages'] Total number of pages or 1.
|
||||
* @param array $args['featured_list'] IDs of featured items in the collection.
|
||||
* @param WP_Query $args['featured_query'] Paginated query of featured items.
|
||||
*/
|
||||
|
||||
function fictioneer_collection_featured_list( $args ) {
|
||||
// Abort if...
|
||||
if ( post_password_required() ) return;
|
||||
function fictioneer_collection_featured_list( $args ) {
|
||||
// Abort if...
|
||||
if ( post_password_required() ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<section class="collection__list spacing-top">
|
||||
<ul id="featured-list" class="card-list">
|
||||
<?php
|
||||
// Render cards...
|
||||
if ( $args['featured_query']->have_posts() ) {
|
||||
// Loop through featured posts...
|
||||
while ( $args['featured_query']->have_posts() ) {
|
||||
// Setup
|
||||
$args['featured_query']->the_post();
|
||||
$card_args = array( 'show_type' => true );
|
||||
// Start HTML ---> ?>
|
||||
<section class="collection__list spacing-top">
|
||||
<ul id="featured-list" class="card-list">
|
||||
<?php
|
||||
// Render cards...
|
||||
if ( $args['featured_query']->have_posts() ) {
|
||||
// Loop through featured posts...
|
||||
while ( $args['featured_query']->have_posts() ) {
|
||||
// Setup
|
||||
$args['featured_query']->the_post();
|
||||
$card_args = array( 'show_type' => true );
|
||||
|
||||
// Cached?
|
||||
if ( fictioneer_caching_active() && ! fictioneer_private_caching_active() ) $card_args['cache'] = true;
|
||||
// Cached?
|
||||
if ( fictioneer_caching_active() && ! fictioneer_private_caching_active() ) $card_args['cache'] = true;
|
||||
|
||||
// Echo correct card
|
||||
fictioneer_echo_card( $card_args );
|
||||
}
|
||||
|
||||
// Restore global query
|
||||
wp_reset_postdata();
|
||||
|
||||
// Setup pagination
|
||||
$pag_args = array(
|
||||
'base' => add_query_arg( 'pg', '%#%' ),
|
||||
'format' => '?pg=%#%',
|
||||
'current' => $args['current_page'],
|
||||
'total' => $args['max_pages'] ?? 1,
|
||||
'prev_text' => fcntr( 'previous' ),
|
||||
'next_text' => fcntr( 'next' ),
|
||||
'add_fragment' => '#featured-list'
|
||||
);
|
||||
|
||||
// Render pagination if necessary
|
||||
if ( $args['max_pages'] > 1 ) {
|
||||
?><li class="pagination"><?php echo fictioneer_paginate_links( $pag_args ); ?></li><?php
|
||||
}
|
||||
// Echo correct card
|
||||
fictioneer_echo_card( $card_args );
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
|
||||
// Restore global query
|
||||
wp_reset_postdata();
|
||||
|
||||
// Setup pagination
|
||||
$pag_args = array(
|
||||
'base' => add_query_arg( 'pg', '%#%' ),
|
||||
'format' => '?pg=%#%',
|
||||
'current' => $args['current_page'],
|
||||
'total' => $args['max_pages'] ?? 1,
|
||||
'prev_text' => fcntr( 'previous' ),
|
||||
'next_text' => fcntr( 'next' ),
|
||||
'add_fragment' => '#featured-list'
|
||||
);
|
||||
|
||||
// Render pagination if necessary
|
||||
if ( $args['max_pages'] > 1 ) {
|
||||
?><li class="pagination"><?php echo fictioneer_paginate_links( $pag_args ); ?></li><?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_collection_after_content', 'fictioneer_collection_featured_list', 30 );
|
||||
|
||||
|
@ -40,20 +40,18 @@ add_action( 'wp_head', 'fictioneer_add_fiction_css', 10 );
|
||||
// BREADCRUMBS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_breadcrumbs' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the breadcrumbs
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $args['post_id'] Optional. Post ID of the current page.
|
||||
* @param string|null $args['post_type'] Optional. Post type of the current page.
|
||||
* @param array $args['breadcrumbs'] Breadcrumb tuples with label (0) and link (1).
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the breadcrumbs
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $args['post_id'] Optional. Post ID of the current page.
|
||||
* @param string|null $args['post_type'] Optional. Post type of the current page.
|
||||
* @param array $args['breadcrumbs'] Breadcrumb tuples with label (0) and link (1).
|
||||
*/
|
||||
|
||||
function fictioneer_breadcrumbs( $args ) {
|
||||
echo fictioneer_get_breadcrumbs( $args );
|
||||
}
|
||||
function fictioneer_breadcrumbs( $args ) {
|
||||
echo fictioneer_get_breadcrumbs( $args );
|
||||
}
|
||||
add_action( 'fictioneer_site_footer', 'fictioneer_breadcrumbs', 10 );
|
||||
|
||||
@ -61,48 +59,46 @@ add_action( 'fictioneer_site_footer', 'fictioneer_breadcrumbs', 10 );
|
||||
// FOOTER MENU ROW
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_footer_menu_row' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the footer menu and theme copyright notice
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $args['post_id'] Optional. Post ID of the current page.
|
||||
* @param string|null $args['post_type'] Optional. Post type of the current page.
|
||||
* @param array $args['breadcrumbs'] Breadcrumb tuples with label (0) and link (1).
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the footer menu and theme copyright notice
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $args['post_id'] Optional. Post ID of the current page.
|
||||
* @param string|null $args['post_type'] Optional. Post type of the current page.
|
||||
* @param array $args['breadcrumbs'] Breadcrumb tuples with label (0) and link (1).
|
||||
*/
|
||||
|
||||
function fictioneer_footer_menu_row( $args ) {
|
||||
// Start HTML ---> ?>
|
||||
<div class="footer__split-row">
|
||||
<div class="footer__menu"><?php
|
||||
$menu = get_transient( 'fictioneer_footer_menu' );
|
||||
function fictioneer_footer_menu_row( $args ) {
|
||||
// Start HTML ---> ?>
|
||||
<div class="footer__split-row">
|
||||
<div class="footer__menu"><?php
|
||||
$menu = get_transient( 'fictioneer_footer_menu' );
|
||||
|
||||
if ( empty( $menu ) ) {
|
||||
$menu = wp_nav_menu(
|
||||
array(
|
||||
'theme_location' => 'footer_menu',
|
||||
'menu_class' => 'footer__menu-list',
|
||||
'container' => '',
|
||||
'echo' => false
|
||||
)
|
||||
);
|
||||
if ( empty( $menu ) ) {
|
||||
$menu = wp_nav_menu(
|
||||
array(
|
||||
'theme_location' => 'footer_menu',
|
||||
'menu_class' => 'footer__menu-list',
|
||||
'container' => '',
|
||||
'echo' => false
|
||||
)
|
||||
);
|
||||
|
||||
$menu = str_replace( 'class="', 'class="footer__menu-list-item ', $menu );
|
||||
$menu = str_replace( 'current_page_item', '', $menu );
|
||||
$menu = str_replace( 'current-menu-item', '', $menu );
|
||||
$menu = str_replace( 'aria-current="page"', '', $menu );
|
||||
$menu = preg_replace( '/<\/li>\s*<li/', '</li><li', $menu );
|
||||
$menu = str_replace( 'class="', 'class="footer__menu-list-item ', $menu );
|
||||
$menu = str_replace( 'current_page_item', '', $menu );
|
||||
$menu = str_replace( 'current-menu-item', '', $menu );
|
||||
$menu = str_replace( 'aria-current="page"', '', $menu );
|
||||
$menu = preg_replace( '/<\/li>\s*<li/', '</li><li', $menu );
|
||||
|
||||
set_transient( 'fictioneer_footer_menu', $menu );
|
||||
}
|
||||
set_transient( 'fictioneer_footer_menu', $menu );
|
||||
}
|
||||
|
||||
echo $menu;
|
||||
?></div>
|
||||
<div class="footer__copyright"><?php echo fictioneer_get_footer_copyright_note( $args ); ?></div>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
echo $menu;
|
||||
?></div>
|
||||
<div class="footer__copyright"><?php echo fictioneer_get_footer_copyright_note( $args ); ?></div>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_site_footer', 'fictioneer_footer_menu_row', 20 );
|
||||
|
||||
@ -110,64 +106,62 @@ add_action( 'fictioneer_site_footer', 'fictioneer_footer_menu_row', 20 );
|
||||
// OUTPUT MODALS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_output_modals' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the modals
|
||||
*
|
||||
* @since Fictioneer 5.0.0
|
||||
*
|
||||
* @param int|null $args['post_id'] Optional. Current post ID.
|
||||
* @param string|null $args['post_type'] Optional. Current post type.
|
||||
* @param array $args['breadcrumbs'] Array of breadcrumb tuples with label (0) and link (1).
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the modals
|
||||
*
|
||||
* @since Fictioneer 5.0.0
|
||||
*
|
||||
* @param int|null $args['post_id'] Optional. Current post ID.
|
||||
* @param string|null $args['post_type'] Optional. Current post type.
|
||||
* @param array $args['breadcrumbs'] Array of breadcrumb tuples with label (0) and link (1).
|
||||
*/
|
||||
|
||||
function fictioneer_output_modals( $args ) {
|
||||
// Formatting and suggestions
|
||||
if ( ! empty( $args['post_id'] ) && $args['post_type'] == 'fcn_chapter' ) {
|
||||
?><input id="modal-formatting-toggle" data-target="formatting-modal" type="checkbox" tabindex="-1" class="modal-toggle" autocomplete="off" hidden><?php
|
||||
get_template_part( 'partials/_modal-formatting' );
|
||||
function fictioneer_output_modals( $args ) {
|
||||
// Formatting and suggestions
|
||||
if ( ! empty( $args['post_id'] ) && $args['post_type'] == 'fcn_chapter' ) {
|
||||
?><input id="modal-formatting-toggle" data-target="formatting-modal" type="checkbox" tabindex="-1" class="modal-toggle" autocomplete="off" hidden><?php
|
||||
get_template_part( 'partials/_modal-formatting' );
|
||||
|
||||
?><input id="modal-tts-settings-toggle" data-target="tts-settings-modal" type="checkbox" tabindex="-1" class="modal-toggle" autocomplete="off" hidden><?php
|
||||
get_template_part( 'partials/_modal-tts-settings' );
|
||||
?><input id="modal-tts-settings-toggle" data-target="tts-settings-modal" type="checkbox" tabindex="-1" class="modal-toggle" autocomplete="off" hidden><?php
|
||||
get_template_part( 'partials/_modal-tts-settings' );
|
||||
|
||||
if (
|
||||
get_option( 'fictioneer_enable_suggestions' ) &&
|
||||
! fictioneer_get_field( 'fictioneer_disable_commenting' ) &&
|
||||
comments_open()
|
||||
) {
|
||||
?><input id="suggestions-modal-toggle" data-target="suggestions-modal" type="checkbox" tabindex="-1" class="modal-toggle" autocomplete="off" hidden><?php
|
||||
get_template_part( 'partials/_modal-suggestions' );
|
||||
}
|
||||
}
|
||||
|
||||
// OAuth2 login
|
||||
if ( get_option( 'fictioneer_enable_oauth' ) && ! is_user_logged_in() ) {
|
||||
?><input id="modal-login-toggle" data-target="login-modal" type="checkbox" tabindex="-1" class="modal-toggle" autocomplete="off" hidden><?php
|
||||
get_template_part( 'partials/_modal-login' );
|
||||
}
|
||||
|
||||
// Social sharing
|
||||
?><input id="modal-sharing-toggle" data-target="sharing-modal" type="checkbox" tabindex="-1" class="modal-toggle" autocomplete="off" hidden><?php
|
||||
get_template_part( 'partials/_modal-sharing' );
|
||||
|
||||
// Site settings
|
||||
?><input id="modal-site-settings-toggle" data-target="site-settings-modal" type="checkbox" tabindex="-1" class="modal-toggle" autocomplete="off" hidden><?php
|
||||
get_template_part( 'partials/_modal-site-settings' );
|
||||
|
||||
// BBCodes tutorial
|
||||
if (
|
||||
! empty( $args['post_id'] ) &&
|
||||
! post_password_required() &&
|
||||
comments_open() &&
|
||||
! fictioneer_is_commenting_disabled()
|
||||
get_option( 'fictioneer_enable_suggestions' ) &&
|
||||
! fictioneer_get_field( 'fictioneer_disable_commenting' ) &&
|
||||
comments_open()
|
||||
) {
|
||||
?><input id="modal-bbcodes-toggle" data-target="bbcodes-modal" type="checkbox" tabindex="-1" class="modal-toggle" autocomplete="off" hidden><?php
|
||||
get_template_part( 'partials/_modal-bbcodes' );
|
||||
?><input id="suggestions-modal-toggle" data-target="suggestions-modal" type="checkbox" tabindex="-1" class="modal-toggle" autocomplete="off" hidden><?php
|
||||
get_template_part( 'partials/_modal-suggestions' );
|
||||
}
|
||||
|
||||
// Action to add modals
|
||||
do_action( 'fictioneer_modals' );
|
||||
}
|
||||
|
||||
// OAuth2 login
|
||||
if ( get_option( 'fictioneer_enable_oauth' ) && ! is_user_logged_in() ) {
|
||||
?><input id="modal-login-toggle" data-target="login-modal" type="checkbox" tabindex="-1" class="modal-toggle" autocomplete="off" hidden><?php
|
||||
get_template_part( 'partials/_modal-login' );
|
||||
}
|
||||
|
||||
// Social sharing
|
||||
?><input id="modal-sharing-toggle" data-target="sharing-modal" type="checkbox" tabindex="-1" class="modal-toggle" autocomplete="off" hidden><?php
|
||||
get_template_part( 'partials/_modal-sharing' );
|
||||
|
||||
// Site settings
|
||||
?><input id="modal-site-settings-toggle" data-target="site-settings-modal" type="checkbox" tabindex="-1" class="modal-toggle" autocomplete="off" hidden><?php
|
||||
get_template_part( 'partials/_modal-site-settings' );
|
||||
|
||||
// BBCodes tutorial
|
||||
if (
|
||||
! empty( $args['post_id'] ) &&
|
||||
! post_password_required() &&
|
||||
comments_open() &&
|
||||
! fictioneer_is_commenting_disabled()
|
||||
) {
|
||||
?><input id="modal-bbcodes-toggle" data-target="bbcodes-modal" type="checkbox" tabindex="-1" class="modal-toggle" autocomplete="off" hidden><?php
|
||||
get_template_part( 'partials/_modal-bbcodes' );
|
||||
}
|
||||
|
||||
// Action to add modals
|
||||
do_action( 'fictioneer_modals' );
|
||||
}
|
||||
add_action( 'fictioneer_footer', 'fictioneer_output_modals' );
|
||||
|
||||
@ -175,21 +169,19 @@ add_action( 'fictioneer_footer', 'fictioneer_output_modals' );
|
||||
// OUTPUT NAVIGATION BAR
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_navigation_bar' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the navigation bar
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $args['post_id'] Optional. Current post ID.
|
||||
* @param int|null $args['story_id'] Optional. Current story ID (if chapter).
|
||||
* @param string|boolean $args['header_image_url'] URL of the filtered header image or false.
|
||||
* @param array $args['header_args'] Arguments passed to the header.php partial.
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the navigation bar
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $args['post_id'] Optional. Current post ID.
|
||||
* @param int|null $args['story_id'] Optional. Current story ID (if chapter).
|
||||
* @param string|boolean $args['header_image_url'] URL of the filtered header image or false.
|
||||
* @param array $args['header_args'] Arguments passed to the header.php partial.
|
||||
*/
|
||||
|
||||
function fictioneer_navigation_bar( $args ) {
|
||||
get_template_part( 'partials/_navigation', null, $args );
|
||||
}
|
||||
function fictioneer_navigation_bar( $args ) {
|
||||
get_template_part( 'partials/_navigation', null, $args );
|
||||
}
|
||||
add_action( 'fictioneer_site', 'fictioneer_navigation_bar', 10 );
|
||||
|
||||
@ -197,53 +189,48 @@ add_action( 'fictioneer_site', 'fictioneer_navigation_bar', 10 );
|
||||
// OUTPUT SITE HEADER
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_site_header' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the site header
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $args['post_id'] Optional. Current post ID.
|
||||
* @param int|null $args['story_id'] Optional. Current story ID (if chapter).
|
||||
* @param string|boolean $args['header_image_url'] URL of the filtered header image or false.
|
||||
* @param array $args['header_args'] Arguments passed to the header.php partial.
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the site header
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $args['post_id'] Optional. Current post ID.
|
||||
* @param int|null $args['story_id'] Optional. Current story ID (if chapter).
|
||||
* @param string|boolean $args['header_image_url'] URL of the filtered header image or false.
|
||||
* @param array $args['header_args'] Arguments passed to the header.php partial.
|
||||
*/
|
||||
|
||||
function fictioneer_site_header( $args ) {
|
||||
get_template_part( 'partials/_site-header', null, $args );
|
||||
}
|
||||
function fictioneer_site_header( $args ) {
|
||||
get_template_part( 'partials/_site-header', null, $args );
|
||||
}
|
||||
add_action( 'fictioneer_site', 'fictioneer_site_header', 20 );
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// OUTPUT HEADER BACKGROUND
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_header_background' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the header background
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $args['post_id'] Optional. Current post ID.
|
||||
* @param int|null $args['story_id'] Optional. Current story ID (if chapter).
|
||||
* @param string|boolean $args['header_image_url'] URL of the filtered header image or false.
|
||||
* @param array $args['header_args'] Arguments passed to the header.php partial.
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the header background
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $args['post_id'] Optional. Current post ID.
|
||||
* @param int|null $args['story_id'] Optional. Current story ID (if chapter).
|
||||
* @param string|boolean $args['header_image_url'] URL of the filtered header image or false.
|
||||
* @param array $args['header_args'] Arguments passed to the header.php partial.
|
||||
*/
|
||||
|
||||
function fictioneer_header_background( $args ) {
|
||||
// Abort if...
|
||||
if ( ! isset( $args['header_image_url'] ) || ! $args['header_image_url'] ) return;
|
||||
function fictioneer_header_background( $args ) {
|
||||
// Abort if...
|
||||
if ( ! isset( $args['header_image_url'] ) || ! $args['header_image_url'] ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<div class="header-background hide-on-fullscreen">
|
||||
<div class="header-background__wrapper">
|
||||
<img src="<?php echo $args['header_image_url']; ?>" alt="Header Background Image" class="header-background__image">
|
||||
</div>
|
||||
// Start HTML ---> ?>
|
||||
<div class="header-background hide-on-fullscreen">
|
||||
<div class="header-background__wrapper">
|
||||
<img src="<?php echo $args['header_image_url']; ?>" alt="Header Background Image" class="header-background__image">
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_header', 'fictioneer_header_background', 10 );
|
||||
|
||||
@ -251,241 +238,239 @@ add_action( 'fictioneer_header', 'fictioneer_header_background', 10 );
|
||||
// SORT, ORDER & FILTER QUERIES
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_sort_order_filter_interface' ) ) {
|
||||
/**
|
||||
* Renders interface to sort, order, and filter queries
|
||||
*
|
||||
* @since Fictioneer 5.4.0
|
||||
*
|
||||
* @param array $args {
|
||||
* Array of arguments.
|
||||
*
|
||||
* @type int $current_page Optional. Current page if paginated or `1`.
|
||||
* @type int $post_id Optional. Current post ID.
|
||||
* @type string $queried_type Optional. Queried post type.
|
||||
* @type array $query_args Optional. Query arguments used.
|
||||
* @type string $order Current order or `desc`.
|
||||
* @type string $orderby Current orderby or `'modified'`.
|
||||
* @type int|string $ago Current date query argument part or `0`.
|
||||
* }
|
||||
*/
|
||||
/**
|
||||
* Renders interface to sort, order, and filter queries
|
||||
*
|
||||
* @since Fictioneer 5.4.0
|
||||
*
|
||||
* @param array $args {
|
||||
* Array of arguments.
|
||||
*
|
||||
* @type int $current_page Optional. Current page if paginated or `1`.
|
||||
* @type int $post_id Optional. Current post ID.
|
||||
* @type string $queried_type Optional. Queried post type.
|
||||
* @type array $query_args Optional. Query arguments used.
|
||||
* @type string $order Current order or `desc`.
|
||||
* @type string $orderby Current orderby or `'modified'`.
|
||||
* @type int|string $ago Current date query argument part or `0`.
|
||||
* }
|
||||
*/
|
||||
|
||||
function fictioneer_sort_order_filter_interface( $args ) {
|
||||
// Setup
|
||||
$current_url = fictioneer_get_clean_url();
|
||||
$post_type = null;
|
||||
function fictioneer_sort_order_filter_interface( $args ) {
|
||||
// Setup
|
||||
$current_url = fictioneer_get_clean_url();
|
||||
$post_type = null;
|
||||
|
||||
// Archive?
|
||||
if ( is_archive() ) {
|
||||
$post_type = strtolower( sanitize_text_field( $_GET['post_type'] ?? '' ) );
|
||||
$post_type = array_intersect(
|
||||
[ $post_type ],
|
||||
['any', 'post', 'fcn_story', 'fcn_chapter', 'fcn_collection', 'fcn_recommendation']
|
||||
);
|
||||
$post_type = reset( $post_type ) ?: null;
|
||||
}
|
||||
|
||||
// Post type?
|
||||
if ( ! empty( $post_type ) ) {
|
||||
$current_url = add_query_arg(
|
||||
array( 'post_type' => $post_type ),
|
||||
$current_url
|
||||
);
|
||||
}
|
||||
|
||||
// Order?
|
||||
if ( ! empty( $args['order'] ) ) {
|
||||
$current_url = add_query_arg(
|
||||
array( 'order' => $args['order'] ),
|
||||
$current_url
|
||||
);
|
||||
}
|
||||
|
||||
// Orderby?
|
||||
if ( ! empty( $args['orderby'] ) ) {
|
||||
$current_url = add_query_arg(
|
||||
array( 'orderby' => $args['orderby'] ),
|
||||
$current_url
|
||||
);
|
||||
}
|
||||
|
||||
// Ago?
|
||||
if ( ! empty( $args['ago'] ) ) {
|
||||
// Validate
|
||||
if ( ! is_numeric( $args['ago'] ) && strtotime( $args['ago'] ) === false ) {
|
||||
$args['ago'] = '0';
|
||||
}
|
||||
|
||||
// Add if valid
|
||||
if ( $args['ago'] != '0' ) {
|
||||
$current_url = add_query_arg(
|
||||
array( 'ago' => $args['ago'] ),
|
||||
$current_url
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Post type menu options
|
||||
$post_type_menu = array(
|
||||
'any' => array(
|
||||
'label' => __( 'All Posts', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'post_type' => 'any' ), $current_url ) . '#sof'
|
||||
),
|
||||
'post' => array(
|
||||
'label' => __( 'Blog Posts', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'post_type' => 'post' ), $current_url ) . '#sof'
|
||||
),
|
||||
'fcn_story' => array(
|
||||
'label' => __( 'Stories', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'post_type' => 'fcn_story' ), $current_url ) . '#sof'
|
||||
),
|
||||
'fcn_chapter' => array(
|
||||
'label' => __( 'Chapters', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'post_type' => 'fcn_chapter' ), $current_url ) . '#sof'
|
||||
),
|
||||
'fcn_collection' => array(
|
||||
'label' => __( 'Collections', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'post_type' => 'fcn_collection' ), $current_url ) . '#sof'
|
||||
),
|
||||
'fcn_recommendation' => array(
|
||||
'label' => __( 'Recommendations', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'post_type' => 'fcn_recommendation' ), $current_url ) . '#sof'
|
||||
)
|
||||
// Archive?
|
||||
if ( is_archive() ) {
|
||||
$post_type = strtolower( sanitize_text_field( $_GET['post_type'] ?? '' ) );
|
||||
$post_type = array_intersect(
|
||||
[ $post_type ],
|
||||
['any', 'post', 'fcn_story', 'fcn_chapter', 'fcn_collection', 'fcn_recommendation']
|
||||
);
|
||||
|
||||
// Filter post type options
|
||||
$post_type_menu = apply_filters( 'fictioneer_filter_sof_post_type_options', $post_type_menu, $current_url, $args );
|
||||
|
||||
// Order menu options
|
||||
$orderby_menu = array(
|
||||
'modified' => array(
|
||||
'label' => __( 'Updated', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'orderby' => 'modified' ), $current_url ) . '#sof'
|
||||
),
|
||||
'date' => array(
|
||||
'label' => __( 'Published', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'orderby' => 'date' ), $current_url ) . '#sof'
|
||||
),
|
||||
'title' => array(
|
||||
'label' => __( 'By Title', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'orderby' => 'title' ), $current_url ) . '#sof'
|
||||
)
|
||||
);
|
||||
|
||||
// Filter orderby options
|
||||
$orderby_menu = apply_filters( 'fictioneer_filter_sof_orderby_options', $orderby_menu, $current_url, $args );
|
||||
|
||||
// Date menu options
|
||||
$date_menu = array(
|
||||
'0' => array(
|
||||
'label' => __( 'Any Date', 'fictioneer' ),
|
||||
'url' => remove_query_arg( 'ago', $current_url ) . '#sof'
|
||||
),
|
||||
'1' => array(
|
||||
'label' => __( 'Past 24 Hours', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'ago' => 1 ), $current_url ) . '#sof'
|
||||
),
|
||||
'3' => array(
|
||||
'label' => __( 'Past 3 Days', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'ago' => 3 ), $current_url ) . '#sof'
|
||||
),
|
||||
'1_week_ago' => array(
|
||||
'label' => __( 'Past Week', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'ago' => urlencode( '1 week ago' ) ), $current_url ) . '#sof'
|
||||
),
|
||||
'1_month_ago' => array(
|
||||
'label' => __( 'Past Month', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'ago' => urlencode( '1 month ago' ) ), $current_url ) . '#sof'
|
||||
),
|
||||
'3_months_ago' => array(
|
||||
'label' => __( 'Past 3 Months', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'ago' => urlencode( '3 months ago' ) ), $current_url ) . '#sof'
|
||||
),
|
||||
'6_months_ago' => array(
|
||||
'label' => __( 'Past 6 Months', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'ago' => urlencode( '6 months ago' ) ), $current_url ) . '#sof'
|
||||
),
|
||||
'1_year_ago' => array(
|
||||
'label' => __( 'Past Year', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'ago' => urlencode( '1 year ago' ) ), $current_url ) . '#sof'
|
||||
)
|
||||
);
|
||||
|
||||
// Filter date options
|
||||
$date_menu = apply_filters( 'fictioneer_filter_sof_date_options', $date_menu, $current_url, $args );
|
||||
|
||||
// Order toggle link
|
||||
$order_link = esc_url(
|
||||
add_query_arg(
|
||||
array( 'order' => $args['order'] === 'desc' ? 'asc' : 'desc' ),
|
||||
$current_url
|
||||
) . '#sof'
|
||||
);
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<div id="sof" class="sort-order-filter">
|
||||
|
||||
<?php if ( is_archive() && ! empty( $post_type_menu ) ) : ?>
|
||||
<div class="list-button _text popup-menu-toggle toggle-last-clicked" tabindex="0" role="button"><?php
|
||||
echo $post_type_menu[ $post_type ?? 'any' ]['label'] ?? __( 'Unknown', 'fictioneer' );
|
||||
echo '<div class="popup-menu _bottom _center">';
|
||||
echo '<div class="popup-heading">' . __( 'Post Type', 'fictioneer' ) . '</div>';
|
||||
|
||||
foreach( $post_type_menu as $tuple ) {
|
||||
$url = esc_url( $tuple['url'] );
|
||||
echo "<a href='{$url}'>{$tuple['label']}</a>";
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $orderby_menu ) ) : ?>
|
||||
<div class="list-button _text popup-menu-toggle toggle-last-clicked" tabindex="0" role="button"><?php
|
||||
echo $orderby_menu[ $args['orderby'] ]['label'] ?? __( 'Custom', 'fictioneer' );
|
||||
echo '<div class="popup-menu _bottom _center">';
|
||||
echo '<div class="popup-heading">' . __( 'Order By', 'fictioneer' ) . '</div>';
|
||||
|
||||
foreach( $orderby_menu as $tuple ) {
|
||||
$url = esc_url( $tuple['url'] );
|
||||
echo "<a href='{$url}'>{$tuple['label']}</a>";
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $date_menu ) ) : ?>
|
||||
<div class="list-button _text popup-menu-toggle toggle-last-clicked" tabindex="0" role="button"><?php
|
||||
$key = str_replace( ' ', '_', $args['ago'] ?? '' );
|
||||
|
||||
if ( empty( $date_menu[ $key ]['label'] ) ) {
|
||||
echo is_numeric( $args['ago'] ) ? sprintf(
|
||||
__( 'Past %s Days', 'fictioneer' ), $args['ago']
|
||||
) : urldecode( $args['ago'] );
|
||||
} else {
|
||||
echo $date_menu[ $key ]['label'];
|
||||
}
|
||||
|
||||
echo '<div class="popup-menu _bottom _center">';
|
||||
echo '<div class="popup-heading">' . __( 'Time Range', 'fictioneer' ) . '</div>';
|
||||
|
||||
foreach( $date_menu as $tuple ) {
|
||||
$url = esc_url( $tuple['url'] );
|
||||
echo "<a href='{$url}'>{$tuple['label']}</a>";
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<a class="list-button _order <?php echo $args['order'] === 'desc' ? '_on' : '_off'; ?>" href="<?php echo $order_link; ?>" aria-label="<?php esc_attr_e( 'Toggle between ascending and descending order', 'fictioneer' ); ?>">
|
||||
<i class="fa-solid fa-arrow-up-short-wide _off"></i><i class="fa-solid fa-arrow-down-wide-short _on"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
$post_type = reset( $post_type ) ?: null;
|
||||
}
|
||||
|
||||
// Post type?
|
||||
if ( ! empty( $post_type ) ) {
|
||||
$current_url = add_query_arg(
|
||||
array( 'post_type' => $post_type ),
|
||||
$current_url
|
||||
);
|
||||
}
|
||||
|
||||
// Order?
|
||||
if ( ! empty( $args['order'] ) ) {
|
||||
$current_url = add_query_arg(
|
||||
array( 'order' => $args['order'] ),
|
||||
$current_url
|
||||
);
|
||||
}
|
||||
|
||||
// Orderby?
|
||||
if ( ! empty( $args['orderby'] ) ) {
|
||||
$current_url = add_query_arg(
|
||||
array( 'orderby' => $args['orderby'] ),
|
||||
$current_url
|
||||
);
|
||||
}
|
||||
|
||||
// Ago?
|
||||
if ( ! empty( $args['ago'] ) ) {
|
||||
// Validate
|
||||
if ( ! is_numeric( $args['ago'] ) && strtotime( $args['ago'] ) === false ) {
|
||||
$args['ago'] = '0';
|
||||
}
|
||||
|
||||
// Add if valid
|
||||
if ( $args['ago'] != '0' ) {
|
||||
$current_url = add_query_arg(
|
||||
array( 'ago' => $args['ago'] ),
|
||||
$current_url
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Post type menu options
|
||||
$post_type_menu = array(
|
||||
'any' => array(
|
||||
'label' => __( 'All Posts', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'post_type' => 'any' ), $current_url ) . '#sof'
|
||||
),
|
||||
'post' => array(
|
||||
'label' => __( 'Blog Posts', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'post_type' => 'post' ), $current_url ) . '#sof'
|
||||
),
|
||||
'fcn_story' => array(
|
||||
'label' => __( 'Stories', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'post_type' => 'fcn_story' ), $current_url ) . '#sof'
|
||||
),
|
||||
'fcn_chapter' => array(
|
||||
'label' => __( 'Chapters', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'post_type' => 'fcn_chapter' ), $current_url ) . '#sof'
|
||||
),
|
||||
'fcn_collection' => array(
|
||||
'label' => __( 'Collections', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'post_type' => 'fcn_collection' ), $current_url ) . '#sof'
|
||||
),
|
||||
'fcn_recommendation' => array(
|
||||
'label' => __( 'Recommendations', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'post_type' => 'fcn_recommendation' ), $current_url ) . '#sof'
|
||||
)
|
||||
);
|
||||
|
||||
// Filter post type options
|
||||
$post_type_menu = apply_filters( 'fictioneer_filter_sof_post_type_options', $post_type_menu, $current_url, $args );
|
||||
|
||||
// Order menu options
|
||||
$orderby_menu = array(
|
||||
'modified' => array(
|
||||
'label' => __( 'Updated', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'orderby' => 'modified' ), $current_url ) . '#sof'
|
||||
),
|
||||
'date' => array(
|
||||
'label' => __( 'Published', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'orderby' => 'date' ), $current_url ) . '#sof'
|
||||
),
|
||||
'title' => array(
|
||||
'label' => __( 'By Title', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'orderby' => 'title' ), $current_url ) . '#sof'
|
||||
)
|
||||
);
|
||||
|
||||
// Filter orderby options
|
||||
$orderby_menu = apply_filters( 'fictioneer_filter_sof_orderby_options', $orderby_menu, $current_url, $args );
|
||||
|
||||
// Date menu options
|
||||
$date_menu = array(
|
||||
'0' => array(
|
||||
'label' => __( 'Any Date', 'fictioneer' ),
|
||||
'url' => remove_query_arg( 'ago', $current_url ) . '#sof'
|
||||
),
|
||||
'1' => array(
|
||||
'label' => __( 'Past 24 Hours', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'ago' => 1 ), $current_url ) . '#sof'
|
||||
),
|
||||
'3' => array(
|
||||
'label' => __( 'Past 3 Days', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'ago' => 3 ), $current_url ) . '#sof'
|
||||
),
|
||||
'1_week_ago' => array(
|
||||
'label' => __( 'Past Week', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'ago' => urlencode( '1 week ago' ) ), $current_url ) . '#sof'
|
||||
),
|
||||
'1_month_ago' => array(
|
||||
'label' => __( 'Past Month', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'ago' => urlencode( '1 month ago' ) ), $current_url ) . '#sof'
|
||||
),
|
||||
'3_months_ago' => array(
|
||||
'label' => __( 'Past 3 Months', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'ago' => urlencode( '3 months ago' ) ), $current_url ) . '#sof'
|
||||
),
|
||||
'6_months_ago' => array(
|
||||
'label' => __( 'Past 6 Months', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'ago' => urlencode( '6 months ago' ) ), $current_url ) . '#sof'
|
||||
),
|
||||
'1_year_ago' => array(
|
||||
'label' => __( 'Past Year', 'fictioneer' ),
|
||||
'url' => add_query_arg( array( 'ago' => urlencode( '1 year ago' ) ), $current_url ) . '#sof'
|
||||
)
|
||||
);
|
||||
|
||||
// Filter date options
|
||||
$date_menu = apply_filters( 'fictioneer_filter_sof_date_options', $date_menu, $current_url, $args );
|
||||
|
||||
// Order toggle link
|
||||
$order_link = esc_url(
|
||||
add_query_arg(
|
||||
array( 'order' => $args['order'] === 'desc' ? 'asc' : 'desc' ),
|
||||
$current_url
|
||||
) . '#sof'
|
||||
);
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<div id="sof" class="sort-order-filter">
|
||||
|
||||
<?php if ( is_archive() && ! empty( $post_type_menu ) ) : ?>
|
||||
<div class="list-button _text popup-menu-toggle toggle-last-clicked" tabindex="0" role="button"><?php
|
||||
echo $post_type_menu[ $post_type ?? 'any' ]['label'] ?? __( 'Unknown', 'fictioneer' );
|
||||
echo '<div class="popup-menu _bottom _center">';
|
||||
echo '<div class="popup-heading">' . __( 'Post Type', 'fictioneer' ) . '</div>';
|
||||
|
||||
foreach( $post_type_menu as $tuple ) {
|
||||
$url = esc_url( $tuple['url'] );
|
||||
echo "<a href='{$url}'>{$tuple['label']}</a>";
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $orderby_menu ) ) : ?>
|
||||
<div class="list-button _text popup-menu-toggle toggle-last-clicked" tabindex="0" role="button"><?php
|
||||
echo $orderby_menu[ $args['orderby'] ]['label'] ?? __( 'Custom', 'fictioneer' );
|
||||
echo '<div class="popup-menu _bottom _center">';
|
||||
echo '<div class="popup-heading">' . __( 'Order By', 'fictioneer' ) . '</div>';
|
||||
|
||||
foreach( $orderby_menu as $tuple ) {
|
||||
$url = esc_url( $tuple['url'] );
|
||||
echo "<a href='{$url}'>{$tuple['label']}</a>";
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $date_menu ) ) : ?>
|
||||
<div class="list-button _text popup-menu-toggle toggle-last-clicked" tabindex="0" role="button"><?php
|
||||
$key = str_replace( ' ', '_', $args['ago'] ?? '' );
|
||||
|
||||
if ( empty( $date_menu[ $key ]['label'] ) ) {
|
||||
echo is_numeric( $args['ago'] ) ? sprintf(
|
||||
__( 'Past %s Days', 'fictioneer' ), $args['ago']
|
||||
) : urldecode( $args['ago'] );
|
||||
} else {
|
||||
echo $date_menu[ $key ]['label'];
|
||||
}
|
||||
|
||||
echo '<div class="popup-menu _bottom _center">';
|
||||
echo '<div class="popup-heading">' . __( 'Time Range', 'fictioneer' ) . '</div>';
|
||||
|
||||
foreach( $date_menu as $tuple ) {
|
||||
$url = esc_url( $tuple['url'] );
|
||||
echo "<a href='{$url}'>{$tuple['label']}</a>";
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<a class="list-button _order <?php echo $args['order'] === 'desc' ? '_on' : '_off'; ?>" href="<?php echo $order_link; ?>" aria-label="<?php esc_attr_e( 'Toggle between ascending and descending order', 'fictioneer' ); ?>">
|
||||
<i class="fa-solid fa-arrow-up-short-wide _off"></i><i class="fa-solid fa-arrow-down-wide-short _on"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_stories_after_content', 'fictioneer_sort_order_filter_interface', 20 );
|
||||
add_action( 'fictioneer_chapters_after_content', 'fictioneer_sort_order_filter_interface', 20 );
|
||||
|
@ -4,37 +4,35 @@
|
||||
// OUTPUT MOBILE MENU
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_output_mobile_menu' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the mobile menu
|
||||
*
|
||||
* Outputs the HTML for the mobile menu. The mobile menu is structured into
|
||||
* sections (top|center|bottom) > frames > panels. Only one frame per section
|
||||
* should be displayed at a time, segmenting the menu.
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $args['post_id'] Optional. Current post ID.
|
||||
* @param int|null $args['story_id'] Optional. Current story ID (if chapter).
|
||||
* @param string|boolean $args['header_image_url'] URL of the filtered header image or false.
|
||||
* @param array $args['header_args'] Arguments passed to the header.php partial.
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the mobile menu
|
||||
*
|
||||
* Outputs the HTML for the mobile menu. The mobile menu is structured into
|
||||
* sections (top|center|bottom) > frames > panels. Only one frame per section
|
||||
* should be displayed at a time, segmenting the menu.
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int|null $args['post_id'] Optional. Current post ID.
|
||||
* @param int|null $args['story_id'] Optional. Current story ID (if chapter).
|
||||
* @param string|boolean $args['header_image_url'] URL of the filtered header image or false.
|
||||
* @param array $args['header_args'] Arguments passed to the header.php partial.
|
||||
*/
|
||||
|
||||
function fictioneer_output_mobile_menu( $args ) {
|
||||
// Start HTML ---> ?>
|
||||
<input id="mobile-menu-toggle" type="checkbox" autocomplete="off" tabindex="-1" hidden>
|
||||
<div class="mobile-menu">
|
||||
<div class="mobile-menu__top"><?php do_action( 'fictioneer_mobile_menu_top' ); ?></div>
|
||||
<div class="mobile-menu__center">
|
||||
<div class="mobile-menu__frame _active" data-frame="main"><?php
|
||||
do_action( 'fictioneer_mobile_menu_main_frame_panels' );
|
||||
?></div>
|
||||
<?php do_action( 'fictioneer_mobile_menu_center' ); ?>
|
||||
</div>
|
||||
<div class="mobile-menu__bottom"><?php do_action( 'fictioneer_mobile_menu_bottom' ); ?></div>
|
||||
function fictioneer_output_mobile_menu( $args ) {
|
||||
// Start HTML ---> ?>
|
||||
<input id="mobile-menu-toggle" type="checkbox" autocomplete="off" tabindex="-1" hidden>
|
||||
<div class="mobile-menu">
|
||||
<div class="mobile-menu__top"><?php do_action( 'fictioneer_mobile_menu_top' ); ?></div>
|
||||
<div class="mobile-menu__center">
|
||||
<div class="mobile-menu__frame _active" data-frame="main"><?php
|
||||
do_action( 'fictioneer_mobile_menu_main_frame_panels' );
|
||||
?></div>
|
||||
<?php do_action( 'fictioneer_mobile_menu_center' ); ?>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
<div class="mobile-menu__bottom"><?php do_action( 'fictioneer_mobile_menu_bottom' ); ?></div>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_body', 'fictioneer_output_mobile_menu', 20 );
|
||||
|
||||
@ -42,16 +40,14 @@ add_action( 'fictioneer_body', 'fictioneer_output_mobile_menu', 20 );
|
||||
// MOBILE MENU USER HEADER MENU
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_mobile_user_icon_menu' ) ) {
|
||||
/**
|
||||
* Adds the _icon-menu.php partial to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Adds the _icon-menu.php partial to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_mobile_user_icon_menu() {
|
||||
get_template_part( 'partials/_icon-menu', null, ['location' => 'in-mobile-menu'] );
|
||||
}
|
||||
function fictioneer_mobile_user_icon_menu() {
|
||||
get_template_part( 'partials/_icon-menu', null, ['location' => 'in-mobile-menu'] );
|
||||
}
|
||||
add_action( 'fictioneer_mobile_menu_top', 'fictioneer_mobile_user_icon_menu', 10 );
|
||||
|
||||
@ -59,94 +55,92 @@ add_action( 'fictioneer_mobile_menu_top', 'fictioneer_mobile_user_icon_menu', 10
|
||||
// MOBILE MENU QUICK BUTTONS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_mobile_quick_buttons' ) ) {
|
||||
/**
|
||||
* Adds quick buttons to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Adds quick buttons to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_mobile_quick_buttons() {
|
||||
// Setup
|
||||
$post_type = is_archive() ? 'archive' : get_post_type();
|
||||
$output = [];
|
||||
function fictioneer_mobile_quick_buttons() {
|
||||
// Setup
|
||||
$post_type = is_archive() ? 'archive' : get_post_type();
|
||||
$output = [];
|
||||
|
||||
// Build
|
||||
// Build
|
||||
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="site-setting-minimal" class="button _quick"><span><?php _e( 'Minimalist', 'fictioneer' ); ?></span></label>
|
||||
<?php // <--- End HTML
|
||||
$output['minimalist'] = ob_get_clean();
|
||||
|
||||
if ( $post_type === 'fcn_chapter' && ! is_search() ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<button class="button _quick button-change-lightness" value="-0.2"><?php _e( 'Darken', 'fictioneer' ) ;?></button>
|
||||
<?php // <--- End HTML
|
||||
$output['darken'] = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="site-setting-minimal" class="button _quick"><span><?php _e( 'Minimalist', 'fictioneer' ); ?></span></label>
|
||||
<button class="button _quick button-change-lightness" value="0.2"><?php _e( 'Brighten', 'fictioneer' ); ?></button>
|
||||
<?php // <--- End HTML
|
||||
$output['minimalist'] = ob_get_clean();
|
||||
$output['brighten'] = ob_get_clean();
|
||||
|
||||
if ( $post_type === 'fcn_chapter' && ! is_search() ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<button class="button _quick button-change-lightness" value="-0.2"><?php _e( 'Darken', 'fictioneer' ) ;?></button>
|
||||
<?php // <--- End HTML
|
||||
$output['darken'] = ob_get_clean();
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="reader-settings-justify-toggle" class="button _quick"><span><?php _e( 'Justify', 'fictioneer' ); ?></span></label>
|
||||
<?php // <--- End HTML
|
||||
$output['justify'] = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<button class="button _quick button-change-lightness" value="0.2"><?php _e( 'Brighten', 'fictioneer' ); ?></button>
|
||||
<?php // <--- End HTML
|
||||
$output['brighten'] = ob_get_clean();
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="reader-settings-indent-toggle" class="button _quick"><span><?php _e( 'Indent', 'fictioneer' ); ?></span></label>
|
||||
<?php // <--- End HTML
|
||||
$output['indent'] = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="reader-settings-justify-toggle" class="button _quick"><span><?php _e( 'Justify', 'fictioneer' ); ?></span></label>
|
||||
<?php // <--- End HTML
|
||||
$output['justify'] = ob_get_clean();
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="modal-formatting-toggle" class="button _quick"><span><?php echo fcntr( 'formatting' ); ?></span></label>
|
||||
<?php // <--- End HTML
|
||||
$output['formatting'] = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="reader-settings-indent-toggle" class="button _quick"><span><?php _e( 'Indent', 'fictioneer' ); ?></span></label>
|
||||
<?php // <--- End HTML
|
||||
$output['indent'] = ob_get_clean();
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<button class="button _quick button-change-font font-stepper" value="-1" id="quick-button-prev-font"><?php _e( 'Prev Font', 'fictioneer' ); ?></button>
|
||||
<?php // <--- End HTML
|
||||
$output['previous_font'] = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="modal-formatting-toggle" class="button _quick"><span><?php echo fcntr( 'formatting' ); ?></span></label>
|
||||
<?php // <--- End HTML
|
||||
$output['formatting'] = ob_get_clean();
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<button class="button _quick button-change-font font-stepper" value="1" id="quick-button-next-font"><?php _e( 'Next Font', 'fictioneer' ); ?></button>
|
||||
<?php // <--- End HTML
|
||||
$output['next_font'] = ob_get_clean();
|
||||
} else {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="site-setting-covers" class="button _quick"><span><?php _e( 'Covers', 'fictioneer' ); ?></span></label>
|
||||
<?php // <--- End HTML
|
||||
$output['covers'] = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<button class="button _quick button-change-font font-stepper" value="-1" id="quick-button-prev-font"><?php _e( 'Prev Font', 'fictioneer' ); ?></button>
|
||||
<?php // <--- End HTML
|
||||
$output['previous_font'] = ob_get_clean();
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="site-setting-background-textures" class="button _quick"><span><?php _e( 'Textures', 'fictioneer' ); ?></span></label>
|
||||
<?php // <--- End HTML
|
||||
$output['textures'] = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<button class="button _quick button-change-font font-stepper" value="1" id="quick-button-next-font"><?php _e( 'Next Font', 'fictioneer' ); ?></button>
|
||||
<?php // <--- End HTML
|
||||
$output['next_font'] = ob_get_clean();
|
||||
} else {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="site-setting-covers" class="button _quick"><span><?php _e( 'Covers', 'fictioneer' ); ?></span></label>
|
||||
<?php // <--- End HTML
|
||||
$output['covers'] = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="site-setting-background-textures" class="button _quick"><span><?php _e( 'Textures', 'fictioneer' ); ?></span></label>
|
||||
<?php // <--- End HTML
|
||||
$output['textures'] = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="site-setting-polygons" class="button _quick"><span><?php _e( 'Polygons', 'fictioneer' ); ?></span></label>
|
||||
<?php // <--- End HTML
|
||||
$output['polygons'] = ob_get_clean();
|
||||
}
|
||||
|
||||
// Apply filter
|
||||
$output = apply_filters( 'fictioneer_filter_mobile_quick_buttons', $output );
|
||||
|
||||
// Return
|
||||
echo implode( '', $output );
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="site-setting-polygons" class="button _quick"><span><?php _e( 'Polygons', 'fictioneer' ); ?></span></label>
|
||||
<?php // <--- End HTML
|
||||
$output['polygons'] = ob_get_clean();
|
||||
}
|
||||
|
||||
// Apply filter
|
||||
$output = apply_filters( 'fictioneer_filter_mobile_quick_buttons', $output );
|
||||
|
||||
// Return
|
||||
echo implode( '', $output );
|
||||
}
|
||||
add_action( 'fictioneer_mobile_menu_bottom', 'fictioneer_mobile_quick_buttons', 10 );
|
||||
|
||||
@ -154,34 +148,32 @@ add_action( 'fictioneer_mobile_menu_bottom', 'fictioneer_mobile_quick_buttons',
|
||||
// MOBILE MENU FOLLOWS FRAME
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_mobile_follows_frame' ) ) {
|
||||
/**
|
||||
* Adds the Follows frame to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Adds the Follows frame to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_mobile_follows_frame() {
|
||||
// Start HTML ---> ?>
|
||||
<div class="mobile-menu__frame" data-frame="follows">
|
||||
<div class="mobile-menu__panel mobile-menu__follows-panel">
|
||||
<div class="mobile-menu__panel-header">
|
||||
<button class="mobile-menu__back-button">
|
||||
<i class="fa-solid fa-caret-left mobile-menu__item-icon"></i> <?php _e( 'Back', 'fictioneer' ); ?>
|
||||
</button>
|
||||
<button class="mark-follows-read mobile-menu__panel-action-button">
|
||||
<i class="fa-solid fa-check"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div id="mobile-menu-follows-list" class="mobile-menu__list mobile-follow-notifications">
|
||||
<div class="mobile-content-is-loading">
|
||||
<i class="fa-solid fa-spinner fa-spin" style="--fa-animation-duration: .8s;"></i>
|
||||
</div>
|
||||
function fictioneer_mobile_follows_frame() {
|
||||
// Start HTML ---> ?>
|
||||
<div class="mobile-menu__frame" data-frame="follows">
|
||||
<div class="mobile-menu__panel mobile-menu__follows-panel">
|
||||
<div class="mobile-menu__panel-header">
|
||||
<button class="mobile-menu__back-button">
|
||||
<i class="fa-solid fa-caret-left mobile-menu__item-icon"></i> <?php _e( 'Back', 'fictioneer' ); ?>
|
||||
</button>
|
||||
<button class="mark-follows-read mobile-menu__panel-action-button">
|
||||
<i class="fa-solid fa-check"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div id="mobile-menu-follows-list" class="mobile-menu__list mobile-follow-notifications">
|
||||
<div class="mobile-content-is-loading">
|
||||
<i class="fa-solid fa-spinner fa-spin" style="--fa-animation-duration: .8s;"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_follows' ) ) {
|
||||
@ -192,32 +184,30 @@ if ( get_option( 'fictioneer_enable_follows' ) ) {
|
||||
// MOBILE MENU BOOKMARKS FRAME
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_mobile_bookmarks_frame' ) ) {
|
||||
/**
|
||||
* Adds the bookmarks frame to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Adds the bookmarks frame to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_mobile_bookmarks_frame() {
|
||||
get_template_part( 'partials/_template_mobile_bookmark' );
|
||||
function fictioneer_mobile_bookmarks_frame() {
|
||||
get_template_part( 'partials/_template_mobile_bookmark' );
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<div class="mobile-menu__frame" data-frame="bookmarks">
|
||||
<div class="mobile-menu__panel mobile-menu__bookmarks-panel" data-editing="false">
|
||||
<div class="mobile-menu__panel-header">
|
||||
<button class="mobile-menu__back-button">
|
||||
<i class="fa-solid fa-caret-left mobile-menu__item-icon"></i> <?php _e( 'Back', 'fictioneer' ); ?>
|
||||
</button>
|
||||
<button id="button-mobile-menu-toggle-bookmarks-edit" class="mobile-menu__panel-action-button">
|
||||
<i class="fa-solid fa-pen off"></i><i class="fa-solid fa-check on"></i>
|
||||
</button>
|
||||
</div>
|
||||
<ul class="mobile-menu__list mobile-menu__bookmark-list" data-empty="<?php echo fcntr( 'no_bookmarks', true ); ?>"></ul>
|
||||
// Start HTML ---> ?>
|
||||
<div class="mobile-menu__frame" data-frame="bookmarks">
|
||||
<div class="mobile-menu__panel mobile-menu__bookmarks-panel" data-editing="false">
|
||||
<div class="mobile-menu__panel-header">
|
||||
<button class="mobile-menu__back-button">
|
||||
<i class="fa-solid fa-caret-left mobile-menu__item-icon"></i> <?php _e( 'Back', 'fictioneer' ); ?>
|
||||
</button>
|
||||
<button id="button-mobile-menu-toggle-bookmarks-edit" class="mobile-menu__panel-action-button">
|
||||
<i class="fa-solid fa-pen off"></i><i class="fa-solid fa-check on"></i>
|
||||
</button>
|
||||
</div>
|
||||
<ul class="mobile-menu__list mobile-menu__bookmark-list" data-empty="<?php echo fcntr( 'no_bookmarks', true ); ?>"></ul>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_bookmarks' ) ) {
|
||||
@ -228,30 +218,28 @@ if ( get_option( 'fictioneer_enable_bookmarks' ) ) {
|
||||
// MOBILE MENU CHAPTERS FRAME
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_mobile_chapters_frame' ) ) {
|
||||
/**
|
||||
* Adds the chapters frame to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Adds the chapters frame to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_mobile_chapters_frame() {
|
||||
// Abort conditions
|
||||
if ( get_post_type() != 'fcn_chapter' || is_archive() || is_search() ) return;
|
||||
function fictioneer_mobile_chapters_frame() {
|
||||
// Abort conditions
|
||||
if ( get_post_type() != 'fcn_chapter' || is_archive() || is_search() ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<div class="mobile-menu__frame" data-frame="chapters">
|
||||
<div class="mobile-menu__panel mobile-menu__chapters-panel">
|
||||
<div class="mobile-menu__panel-header">
|
||||
<button class="mobile-menu__back-button">
|
||||
<i class="fa-solid fa-caret-left mobile-menu__item-icon"></i> <?php _e( 'Back', 'fictioneer' ); ?>
|
||||
</button>
|
||||
</div>
|
||||
<div id="mobile-menu-chapters-list" class="mobile-menu__list _chapters"></div>
|
||||
// Start HTML ---> ?>
|
||||
<div class="mobile-menu__frame" data-frame="chapters">
|
||||
<div class="mobile-menu__panel mobile-menu__chapters-panel">
|
||||
<div class="mobile-menu__panel-header">
|
||||
<button class="mobile-menu__back-button">
|
||||
<i class="fa-solid fa-caret-left mobile-menu__item-icon"></i> <?php _e( 'Back', 'fictioneer' ); ?>
|
||||
</button>
|
||||
</div>
|
||||
<div id="mobile-menu-chapters-list" class="mobile-menu__list _chapters"></div>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_mobile_menu_center', 'fictioneer_mobile_chapters_frame', 30 );
|
||||
|
||||
@ -259,20 +247,18 @@ add_action( 'fictioneer_mobile_menu_center', 'fictioneer_mobile_chapters_frame',
|
||||
// MOBILE MENU NAVIGATION PANEL
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_mobile_navigation_panel' ) ) {
|
||||
/**
|
||||
* Adds the navigation panel to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Adds the navigation panel to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_mobile_navigation_panel() {
|
||||
// Start HTML ---> ?>
|
||||
<nav id="mobile-navigation" class="mobile-navigation mobile-menu__panel"><?php
|
||||
// Cloned from the main navigation via JS
|
||||
?></nav>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
function fictioneer_mobile_navigation_panel() {
|
||||
// Start HTML ---> ?>
|
||||
<nav id="mobile-navigation" class="mobile-navigation mobile-menu__panel"><?php
|
||||
// Cloned from the main navigation via JS
|
||||
?></nav>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_mobile_menu_main_frame_panels', 'fictioneer_mobile_navigation_panel', 10 );
|
||||
|
||||
@ -280,55 +266,53 @@ add_action( 'fictioneer_mobile_menu_main_frame_panels', 'fictioneer_mobile_navig
|
||||
// MOBILE MENU LISTS PANEL
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_mobile_lists_panel' ) ) {
|
||||
/**
|
||||
* Adds the lists panel to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Adds the lists panel to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_mobile_lists_panel() {
|
||||
// Setup
|
||||
$post_type = is_archive() ? 'archive' : get_post_type();
|
||||
$output = [];
|
||||
function fictioneer_mobile_lists_panel() {
|
||||
// Setup
|
||||
$post_type = is_archive() ? 'archive' : get_post_type();
|
||||
$output = [];
|
||||
|
||||
// Chapters?
|
||||
if ( $post_type === 'fcn_chapter' && fictioneer_get_field( 'fictioneer_chapter_story' ) && ! is_search() ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<button class="mobile-menu__frame-button" data-frame-target="chapters">
|
||||
<i class="fa-solid fa-caret-right mobile-menu__item-icon"></i> <?php _e( 'Chapters', 'fictioneer' ); ?>
|
||||
</button>
|
||||
<?php // <--- End HTML
|
||||
$output['chapters'] = ob_get_clean();
|
||||
}
|
||||
// Chapters?
|
||||
if ( $post_type === 'fcn_chapter' && fictioneer_get_field( 'fictioneer_chapter_story' ) && ! is_search() ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<button class="mobile-menu__frame-button" data-frame-target="chapters">
|
||||
<i class="fa-solid fa-caret-right mobile-menu__item-icon"></i> <?php _e( 'Chapters', 'fictioneer' ); ?>
|
||||
</button>
|
||||
<?php // <--- End HTML
|
||||
$output['chapters'] = ob_get_clean();
|
||||
}
|
||||
|
||||
// Bookmarks?
|
||||
if ( get_option( 'fictioneer_enable_bookmarks' ) ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<button class="mobile-menu__frame-button" data-frame-target="bookmarks">
|
||||
<i class="fa-solid fa-caret-right mobile-menu__item-icon"></i> <?php echo fcntr( 'bookmarks' ); ?>
|
||||
</button>
|
||||
<?php // <--- End HTML
|
||||
$output['bookmarks'] = ob_get_clean();
|
||||
}
|
||||
// Bookmarks?
|
||||
if ( get_option( 'fictioneer_enable_bookmarks' ) ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<button class="mobile-menu__frame-button" data-frame-target="bookmarks">
|
||||
<i class="fa-solid fa-caret-right mobile-menu__item-icon"></i> <?php echo fcntr( 'bookmarks' ); ?>
|
||||
</button>
|
||||
<?php // <--- End HTML
|
||||
$output['bookmarks'] = ob_get_clean();
|
||||
}
|
||||
|
||||
// Follows?
|
||||
if ( get_option( 'fictioneer_enable_follows' ) ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<button class="mobile-menu__frame-button hide-if-logged-out follows-alert-number" data-frame-target="follows">
|
||||
<i class="fa-solid fa-caret-right mobile-menu__item-icon"></i> <?php echo fcntr( 'follows' ); ?>
|
||||
</button>
|
||||
<?php // <--- End HTML
|
||||
$output['follows'] = ob_get_clean();
|
||||
}
|
||||
// Follows?
|
||||
if ( get_option( 'fictioneer_enable_follows' ) ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<button class="mobile-menu__frame-button hide-if-logged-out follows-alert-number" data-frame-target="follows">
|
||||
<i class="fa-solid fa-caret-right mobile-menu__item-icon"></i> <?php echo fcntr( 'follows' ); ?>
|
||||
</button>
|
||||
<?php // <--- End HTML
|
||||
$output['follows'] = ob_get_clean();
|
||||
}
|
||||
|
||||
// Render (if content)
|
||||
if ( ! empty( $output ) ) {
|
||||
echo '<div class="mobile-menu__panel mobile-menu__lists-panel">' . implode( '', $output ) . '</div>';
|
||||
}
|
||||
// Render (if content)
|
||||
if ( ! empty( $output ) ) {
|
||||
echo '<div class="mobile-menu__panel mobile-menu__lists-panel">' . implode( '', $output ) . '</div>';
|
||||
}
|
||||
}
|
||||
add_action( 'fictioneer_mobile_menu_main_frame_panels', 'fictioneer_mobile_lists_panel', 20 );
|
||||
@ -337,167 +321,165 @@ add_action( 'fictioneer_mobile_menu_main_frame_panels', 'fictioneer_mobile_lists
|
||||
// MOBILE MENU USER NAVIGATION
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_mobile_user_menu' ) ) {
|
||||
/**
|
||||
* Adds the user menu to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
/**
|
||||
* Adds the user menu to the mobile menu
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_mobile_user_menu() {
|
||||
// Setup
|
||||
$post_type = is_archive() ? 'archive' : get_post_type();
|
||||
$bookmarks_link = fictioneer_get_assigned_page_link( 'fictioneer_bookmarks_page' );
|
||||
$bookshelf_link = fictioneer_get_assigned_page_link( 'fictioneer_bookshelf_page' );
|
||||
$discord_link = get_option( 'fictioneer_discord_invite_link' );
|
||||
$can_checkmarks = get_option( 'fictioneer_enable_checkmarks' );
|
||||
$can_follows = get_option( 'fictioneer_enable_follows' );
|
||||
$can_reminders = get_option( 'fictioneer_enable_reminders' );
|
||||
$profile_link = get_edit_profile_url();
|
||||
$profile_page_id = intval( get_option( 'fictioneer_user_profile_page', -1 ) ?: -1 );
|
||||
$output = [];
|
||||
function fictioneer_mobile_user_menu() {
|
||||
// Setup
|
||||
$post_type = is_archive() ? 'archive' : get_post_type();
|
||||
$bookmarks_link = fictioneer_get_assigned_page_link( 'fictioneer_bookmarks_page' );
|
||||
$bookshelf_link = fictioneer_get_assigned_page_link( 'fictioneer_bookshelf_page' );
|
||||
$discord_link = get_option( 'fictioneer_discord_invite_link' );
|
||||
$can_checkmarks = get_option( 'fictioneer_enable_checkmarks' );
|
||||
$can_follows = get_option( 'fictioneer_enable_follows' );
|
||||
$can_reminders = get_option( 'fictioneer_enable_reminders' );
|
||||
$profile_link = get_edit_profile_url();
|
||||
$profile_page_id = intval( get_option( 'fictioneer_user_profile_page', -1 ) ?: -1 );
|
||||
$output = [];
|
||||
|
||||
if ( $profile_page_id && $profile_page_id > 0 ) {
|
||||
$profile_link = fictioneer_get_assigned_page_link( 'fictioneer_user_profile_page' );
|
||||
}
|
||||
|
||||
// Build
|
||||
if ( ! empty( $profile_link ) && fictioneer_show_auth_content() ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<a href="<?php echo esc_url( $profile_link ); ?>" class="hide-if-logged-out">
|
||||
<i class="fa-solid fa-circle-user mobile-menu__item-icon"></i>
|
||||
<?php echo fcntr( 'account' ); ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['account'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if ( FICTIONEER_SHOW_SEARCH_IN_MENUS ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<a href="<?php echo esc_url( home_url( '/?s=' ) ); ?>">
|
||||
<i class="fa-solid fa-magnifying-glass mobile-menu__item-icon"></i>
|
||||
<?php _e( 'Search', 'fictioneer' ); ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['search'] = ob_get_clean();
|
||||
}
|
||||
if ( $profile_page_id && $profile_page_id > 0 ) {
|
||||
$profile_link = fictioneer_get_assigned_page_link( 'fictioneer_user_profile_page' );
|
||||
}
|
||||
|
||||
// Build
|
||||
if ( ! empty( $profile_link ) && fictioneer_show_auth_content() ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="modal-site-settings-toggle">
|
||||
<i class="fa-solid fa-tools mobile-menu__item-icon"></i>
|
||||
<?php echo fcntr( 'site_settings' ); ?>
|
||||
<a href="<?php echo esc_url( $profile_link ); ?>" class="hide-if-logged-out">
|
||||
<i class="fa-solid fa-circle-user mobile-menu__item-icon"></i>
|
||||
<?php echo fcntr( 'account' ); ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['account'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if ( FICTIONEER_SHOW_SEARCH_IN_MENUS ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<a href="<?php echo esc_url( home_url( '/?s=' ) ); ?>">
|
||||
<i class="fa-solid fa-magnifying-glass mobile-menu__item-icon"></i>
|
||||
<?php _e( 'Search', 'fictioneer' ); ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['search'] = ob_get_clean();
|
||||
}
|
||||
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="modal-site-settings-toggle">
|
||||
<i class="fa-solid fa-tools mobile-menu__item-icon"></i>
|
||||
<?php echo fcntr( 'site_settings' ); ?>
|
||||
</label>
|
||||
<?php // <--- End HTML
|
||||
$output['site_settings'] = ob_get_clean();
|
||||
|
||||
if ( ! empty( $discord_link ) ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<a href="<?php echo esc_url( $discord_link ); ?>" rel="noopener noreferrer nofollow">
|
||||
<i class="fa-brands fa-discord mobile-menu__item-icon"></i>
|
||||
<?php _e( 'Discord', 'fictioneer' ) ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['discord'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if ( $bookshelf_link && fictioneer_show_auth_content() && ( $can_checkmarks || $can_follows || $can_reminders ) ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<a href="<?php echo esc_url( $bookshelf_link ); ?>" rel="noopener noreferrer nofollow" class="hide-if-logged-out">
|
||||
<i class="fa-solid fa-list mobile-menu__item-icon"></i>
|
||||
<?php echo fcntr( 'bookshelf' ); ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['bookshelf'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if ( ! empty( $bookmarks_link ) && get_option( 'fictioneer_enable_bookmarks' ) ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<a href="<?php echo esc_url( $bookmarks_link ); ?>" rel="noopener noreferrer nofollow">
|
||||
<i class="fa-solid fa-bookmark mobile-menu__item-icon"></i>
|
||||
<?php echo fcntr( 'bookmarks' ); ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['bookmarks'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if ( $post_type === 'fcn_chapter' && ! is_search() ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="modal-formatting-toggle">
|
||||
<?php fictioneer_icon( 'font-settings', 'mobile-menu__item-icon' ); ?>
|
||||
<?php echo fcntr( 'formatting' ); ?>
|
||||
</label>
|
||||
<?php // <--- End HTML
|
||||
$output['site_settings'] = ob_get_clean();
|
||||
|
||||
if ( ! empty( $discord_link ) ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<a href="<?php echo esc_url( $discord_link ); ?>" rel="noopener noreferrer nofollow">
|
||||
<i class="fa-brands fa-discord mobile-menu__item-icon"></i>
|
||||
<?php _e( 'Discord', 'fictioneer' ) ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['discord'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if ( $bookshelf_link && fictioneer_show_auth_content() && ( $can_checkmarks || $can_follows || $can_reminders ) ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<a href="<?php echo esc_url( $bookshelf_link ); ?>" rel="noopener noreferrer nofollow" class="hide-if-logged-out">
|
||||
<i class="fa-solid fa-list mobile-menu__item-icon"></i>
|
||||
<?php echo fcntr( 'bookshelf' ); ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['bookshelf'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if ( ! empty( $bookmarks_link ) && get_option( 'fictioneer_enable_bookmarks' ) ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<a href="<?php echo esc_url( $bookmarks_link ); ?>" rel="noopener noreferrer nofollow">
|
||||
<i class="fa-solid fa-bookmark mobile-menu__item-icon"></i>
|
||||
<?php echo fcntr( 'bookmarks' ); ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['bookmarks'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if ( $post_type === 'fcn_chapter' && ! is_search() ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="modal-formatting-toggle">
|
||||
<?php fictioneer_icon( 'font-settings', 'mobile-menu__item-icon' ); ?>
|
||||
<?php echo fcntr( 'formatting' ); ?>
|
||||
</label>
|
||||
<?php // <--- End HTML
|
||||
$output['formatting'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if (
|
||||
$post_type === 'fcn_chapter' &&
|
||||
! is_search() &&
|
||||
comments_open() &&
|
||||
! fictioneer_is_commenting_disabled() &&
|
||||
! post_password_required()
|
||||
) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<a id="mobile-menu-comment-jump" class="comments-toggle" rel="noopener noreferrer nofollow">
|
||||
<i class="fa-solid fa-comments mobile-menu__item-icon"></i>
|
||||
<?php echo fcntr( 'jump_to_comments' ); ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['comment_jump'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if (
|
||||
$post_type === 'fcn_chapter' &&
|
||||
! is_search() &&
|
||||
get_option( 'fictioneer_enable_bookmarks' ) &&
|
||||
! post_password_required()
|
||||
) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<a id="mobile-menu-bookmark-jump" rel="noopener noreferrer nofollow" hidden>
|
||||
<i class="fa-solid fa-bookmark mobile-menu__item-icon"></i>
|
||||
<?php echo fcntr( 'jump_to_bookmark' ); ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['bookmark_jump'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if ( fictioneer_show_auth_content() ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<a href="<?php echo fictioneer_get_logout_url(); ?>" data-click="logout" rel="noopener noreferrer nofollow" class="hide-if-logged-out">
|
||||
<?php fictioneer_icon( 'fa-logout', 'mobile-menu__item-icon', '', 'style="transform: translateY(-1px);"' ); ?>
|
||||
<?php echo fcntr( 'logout' ); ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['logout'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_oauth' ) && ! is_user_logged_in() ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="modal-login-toggle" class="hide-if-logged-in subscriber-login">
|
||||
<?php fictioneer_icon( 'fa-login', 'mobile-menu__item-icon' ); ?>
|
||||
<?php echo fcntr( 'login' ); ?>
|
||||
</label>
|
||||
<?php // <--- End HTML
|
||||
$output['login'] = ob_get_clean();
|
||||
}
|
||||
|
||||
// Apply filter
|
||||
$output = apply_filters( 'fictioneer_filter_mobile_user_menu_items', $output );
|
||||
|
||||
// Return
|
||||
echo '<div id="mobile-menu-user-panel" class="mobile-menu__panel">' . implode( '', $output ) . '</div>';
|
||||
$output['formatting'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if (
|
||||
$post_type === 'fcn_chapter' &&
|
||||
! is_search() &&
|
||||
comments_open() &&
|
||||
! fictioneer_is_commenting_disabled() &&
|
||||
! post_password_required()
|
||||
) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<a id="mobile-menu-comment-jump" class="comments-toggle" rel="noopener noreferrer nofollow">
|
||||
<i class="fa-solid fa-comments mobile-menu__item-icon"></i>
|
||||
<?php echo fcntr( 'jump_to_comments' ); ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['comment_jump'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if (
|
||||
$post_type === 'fcn_chapter' &&
|
||||
! is_search() &&
|
||||
get_option( 'fictioneer_enable_bookmarks' ) &&
|
||||
! post_password_required()
|
||||
) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<a id="mobile-menu-bookmark-jump" rel="noopener noreferrer nofollow" hidden>
|
||||
<i class="fa-solid fa-bookmark mobile-menu__item-icon"></i>
|
||||
<?php echo fcntr( 'jump_to_bookmark' ); ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['bookmark_jump'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if ( fictioneer_show_auth_content() ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<a href="<?php echo fictioneer_get_logout_url(); ?>" data-click="logout" rel="noopener noreferrer nofollow" class="hide-if-logged-out">
|
||||
<?php fictioneer_icon( 'fa-logout', 'mobile-menu__item-icon', '', 'style="transform: translateY(-1px);"' ); ?>
|
||||
<?php echo fcntr( 'logout' ); ?>
|
||||
</a>
|
||||
<?php // <--- End HTML
|
||||
$output['logout'] = ob_get_clean();
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_oauth' ) && ! is_user_logged_in() ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<label for="modal-login-toggle" class="hide-if-logged-in subscriber-login">
|
||||
<?php fictioneer_icon( 'fa-login', 'mobile-menu__item-icon' ); ?>
|
||||
<?php echo fcntr( 'login' ); ?>
|
||||
</label>
|
||||
<?php // <--- End HTML
|
||||
$output['login'] = ob_get_clean();
|
||||
}
|
||||
|
||||
// Apply filter
|
||||
$output = apply_filters( 'fictioneer_filter_mobile_user_menu_items', $output );
|
||||
|
||||
// Return
|
||||
echo '<div id="mobile-menu-user-panel" class="mobile-menu__panel">' . implode( '', $output ) . '</div>';
|
||||
}
|
||||
add_action( 'fictioneer_mobile_menu_main_frame_panels', 'fictioneer_mobile_user_menu', 30 );
|
||||
|
||||
|
@ -4,34 +4,32 @@
|
||||
// ACCOUNT MODERATION MESSAGE SECTION
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_account_moderation_message' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the account moderation message section
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $args['user'] Current user.
|
||||
* @param boolean $args['is_admin'] True if the user is an administrator.
|
||||
* @param boolean $args['is_author'] True if the user is an author (by capabilities).
|
||||
* @param boolean $args['is_editor'] True if the user is an editor.
|
||||
* @param boolean $args['is_moderator'] True if the user is a moderator (by capabilities).
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the account moderation message section
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $args['user'] Current user.
|
||||
* @param boolean $args['is_admin'] True if the user is an administrator.
|
||||
* @param boolean $args['is_author'] True if the user is an author (by capabilities).
|
||||
* @param boolean $args['is_editor'] True if the user is an editor.
|
||||
* @param boolean $args['is_moderator'] True if the user is a moderator (by capabilities).
|
||||
*/
|
||||
|
||||
function fictioneer_account_moderation_message( $args ) {
|
||||
// Setup
|
||||
$message = get_the_author_meta( 'fictioneer_admin_moderation_message', $args['user']->ID );
|
||||
function fictioneer_account_moderation_message( $args ) {
|
||||
// Setup
|
||||
$message = get_the_author_meta( 'fictioneer_admin_moderation_message', $args['user']->ID );
|
||||
|
||||
// Abort conditions
|
||||
if ( empty( $message ) ) return;
|
||||
// Abort conditions
|
||||
if ( empty( $message ) ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<div class="profile__moderation-message profile__segment">
|
||||
<div class="infobox polygon">
|
||||
<p><?php echo $message; ?></p>
|
||||
</div>
|
||||
// Start HTML ---> ?>
|
||||
<div class="profile__moderation-message profile__segment">
|
||||
<div class="infobox polygon">
|
||||
<p><?php echo $message; ?></p>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_account_content', 'fictioneer_account_moderation_message', 5 );
|
||||
|
||||
@ -39,22 +37,20 @@ add_action( 'fictioneer_account_content', 'fictioneer_account_moderation_message
|
||||
// ACCOUNT PROFILE SECTION
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_account_profile' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the account profile section
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $args['user'] Current user.
|
||||
* @param boolean $args['is_admin'] True if the user is an administrator.
|
||||
* @param boolean $args['is_author'] True if the user is an author (by capabilities).
|
||||
* @param boolean $args['is_editor'] True if the user is an editor.
|
||||
* @param boolean $args['is_moderator'] True if the user is a moderator (by capabilities).
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the account profile section
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $args['user'] Current user.
|
||||
* @param boolean $args['is_admin'] True if the user is an administrator.
|
||||
* @param boolean $args['is_author'] True if the user is an author (by capabilities).
|
||||
* @param boolean $args['is_editor'] True if the user is an editor.
|
||||
* @param boolean $args['is_moderator'] True if the user is a moderator (by capabilities).
|
||||
*/
|
||||
|
||||
function fictioneer_account_profile( $args ) {
|
||||
get_template_part( 'partials/account/_profile', null, $args );
|
||||
}
|
||||
function fictioneer_account_profile( $args ) {
|
||||
get_template_part( 'partials/account/_profile', null, $args );
|
||||
}
|
||||
add_action( 'fictioneer_account_content', 'fictioneer_account_profile', 10 );
|
||||
|
||||
@ -62,22 +58,20 @@ add_action( 'fictioneer_account_content', 'fictioneer_account_profile', 10 );
|
||||
// ACCOUNT OAUTH BINDINGS SECTION
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_account_oauth' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the OAuth section
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $args['user'] Current user.
|
||||
* @param boolean $args['is_admin'] True if the user is an administrator.
|
||||
* @param boolean $args['is_author'] True if the user is an author (by capabilities).
|
||||
* @param boolean $args['is_editor'] True if the user is an editor.
|
||||
* @param boolean $args['is_moderator'] True if the user is a moderator (by capabilities).
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the OAuth section
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $args['user'] Current user.
|
||||
* @param boolean $args['is_admin'] True if the user is an administrator.
|
||||
* @param boolean $args['is_author'] True if the user is an author (by capabilities).
|
||||
* @param boolean $args['is_editor'] True if the user is an editor.
|
||||
* @param boolean $args['is_moderator'] True if the user is a moderator (by capabilities).
|
||||
*/
|
||||
|
||||
function fictioneer_account_oauth( $args ) {
|
||||
get_template_part( 'partials/account/_oauth', null, $args );
|
||||
}
|
||||
function fictioneer_account_oauth( $args ) {
|
||||
get_template_part( 'partials/account/_oauth', null, $args );
|
||||
}
|
||||
add_action( 'fictioneer_account_content', 'fictioneer_account_oauth', 20 );
|
||||
|
||||
@ -85,22 +79,20 @@ add_action( 'fictioneer_account_content', 'fictioneer_account_oauth', 20 );
|
||||
// ACCOUNT DATA SECTION
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_account_data' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the data section
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $args['user'] Current user.
|
||||
* @param boolean $args['is_admin'] True if the user is an administrator.
|
||||
* @param boolean $args['is_author'] True if the user is an author (by capabilities).
|
||||
* @param boolean $args['is_editor'] True if the user is an editor.
|
||||
* @param boolean $args['is_moderator'] True if the user is a moderator (by capabilities).
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the data section
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $args['user'] Current user.
|
||||
* @param boolean $args['is_admin'] True if the user is an administrator.
|
||||
* @param boolean $args['is_author'] True if the user is an author (by capabilities).
|
||||
* @param boolean $args['is_editor'] True if the user is an editor.
|
||||
* @param boolean $args['is_moderator'] True if the user is a moderator (by capabilities).
|
||||
*/
|
||||
|
||||
function fictioneer_account_data( $args ) {
|
||||
get_template_part( 'partials/account/_data', null, $args );
|
||||
}
|
||||
function fictioneer_account_data( $args ) {
|
||||
get_template_part( 'partials/account/_data', null, $args );
|
||||
}
|
||||
add_action( 'fictioneer_account_content', 'fictioneer_account_data', 30 );
|
||||
|
||||
@ -108,22 +100,20 @@ add_action( 'fictioneer_account_content', 'fictioneer_account_data', 30 );
|
||||
// ACCOUNT DISCUSSION SECTION
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_account_discussions' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the discussions section
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $args['user'] Current user.
|
||||
* @param boolean $args['is_admin'] True if the user is an administrator.
|
||||
* @param boolean $args['is_author'] True if the user is an author (by capabilities).
|
||||
* @param boolean $args['is_editor'] True if the user is an editor.
|
||||
* @param boolean $args['is_moderator'] True if the user is a moderator (by capabilities).
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the discussions section
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $args['user'] Current user.
|
||||
* @param boolean $args['is_admin'] True if the user is an administrator.
|
||||
* @param boolean $args['is_author'] True if the user is an author (by capabilities).
|
||||
* @param boolean $args['is_editor'] True if the user is an editor.
|
||||
* @param boolean $args['is_moderator'] True if the user is a moderator (by capabilities).
|
||||
*/
|
||||
|
||||
function fictioneer_account_discussions( $args ) {
|
||||
get_template_part( 'partials/account/_discussions', null, $args );
|
||||
}
|
||||
function fictioneer_account_discussions( $args ) {
|
||||
get_template_part( 'partials/account/_discussions', null, $args );
|
||||
}
|
||||
add_action( 'fictioneer_account_content', 'fictioneer_account_discussions', 40 );
|
||||
|
||||
@ -131,22 +121,20 @@ add_action( 'fictioneer_account_content', 'fictioneer_account_discussions', 40 )
|
||||
// ACCOUNT DANGER ZONE SECTION
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_account_danger_zone' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the danger zone section
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $args['user'] Current user.
|
||||
* @param boolean $args['is_admin'] True if the user is an administrator.
|
||||
* @param boolean $args['is_author'] True if the user is an author (by capabilities).
|
||||
* @param boolean $args['is_editor'] True if the user is an editor.
|
||||
* @param boolean $args['is_moderator'] True if the user is a moderator (by capabilities).
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the danger zone section
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $args['user'] Current user.
|
||||
* @param boolean $args['is_admin'] True if the user is an administrator.
|
||||
* @param boolean $args['is_author'] True if the user is an author (by capabilities).
|
||||
* @param boolean $args['is_editor'] True if the user is an editor.
|
||||
* @param boolean $args['is_moderator'] True if the user is a moderator (by capabilities).
|
||||
*/
|
||||
|
||||
function fictioneer_account_danger_zone( $args ) {
|
||||
get_template_part( 'partials/account/_danger-zone', null, $args );
|
||||
}
|
||||
function fictioneer_account_danger_zone( $args ) {
|
||||
get_template_part( 'partials/account/_danger-zone', null, $args );
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_subscriber_self_delete' ) ) {
|
||||
|
@ -4,79 +4,77 @@
|
||||
// LIST OF ALL RECOMMENDATIONS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_recommendations_list' ) ) {
|
||||
/**
|
||||
* Outputs the paginated card list for all recommendations
|
||||
*
|
||||
* @since 5.0
|
||||
* @see recommendations.php
|
||||
*
|
||||
* @param int $args['current_page'] Current page number of pagination or 1.
|
||||
* @param int $args['post_id'] The post ID.
|
||||
* @param WP_Query $args['recommendations'] Paginated query of all published recommendations.
|
||||
* @param string $args['queried_type'] The queried post type ('fcn_recommendation').
|
||||
* @param array $args['query_args'] The query arguments used.
|
||||
* @param string $args['order'] Current order. Default 'desc'.
|
||||
* @param string $args['orderby'] Current orderby. Default 'modified'.
|
||||
* @param int|string $args['ago'] Current date query argument part. Default 0.
|
||||
*/
|
||||
/**
|
||||
* Outputs the paginated card list for all recommendations
|
||||
*
|
||||
* @since 5.0
|
||||
* @see recommendations.php
|
||||
*
|
||||
* @param int $args['current_page'] Current page number of pagination or 1.
|
||||
* @param int $args['post_id'] The post ID.
|
||||
* @param WP_Query $args['recommendations'] Paginated query of all published recommendations.
|
||||
* @param string $args['queried_type'] The queried post type ('fcn_recommendation').
|
||||
* @param array $args['query_args'] The query arguments used.
|
||||
* @param string $args['order'] Current order. Default 'desc'.
|
||||
* @param string $args['orderby'] Current orderby. Default 'modified'.
|
||||
* @param int|string $args['ago'] Current date query argument part. Default 0.
|
||||
*/
|
||||
|
||||
function fictioneer_recommendations_list( $args ) {
|
||||
// Start HTML ---> ?>
|
||||
<section class="recommendations__list spacing-top">
|
||||
<ul class="card-list" id="list-of-recommendations">
|
||||
function fictioneer_recommendations_list( $args ) {
|
||||
// Start HTML ---> ?>
|
||||
<section class="recommendations__list spacing-top">
|
||||
<ul class="card-list" id="list-of-recommendations">
|
||||
|
||||
<?php if ( $args['recommendations']->have_posts() ) : ?>
|
||||
|
||||
<?php
|
||||
// Card arguments
|
||||
$card_args = array(
|
||||
'cache' => fictioneer_caching_active() && ! fictioneer_private_caching_active(),
|
||||
'order' => $args['order'] ?? 'desc',
|
||||
'orderby' => $args['orderby'] ?? 'modified',
|
||||
'ago' => $args['ago'] ?? 0
|
||||
);
|
||||
|
||||
// Filter card arguments
|
||||
$card_args = apply_filters( 'fictioneer_filter_recommendations_card_args', $card_args, $args );
|
||||
|
||||
while ( $args['recommendations']->have_posts() ) {
|
||||
$args['recommendations']->the_post();
|
||||
get_template_part( 'partials/_card-recommendation', null, $card_args );
|
||||
}
|
||||
|
||||
// Actions at end of results
|
||||
do_action( 'fictioneer_recommendations_end_of_results', $args );
|
||||
?>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<?php do_action( 'fictioneer_recommendations_no_results', $args ); ?>
|
||||
|
||||
<li class="no-results">
|
||||
<span><?php _e( 'No recommendations found.', 'fictioneer' ) ?></span>
|
||||
</li>
|
||||
|
||||
<?php endif; wp_reset_postdata(); ?>
|
||||
<?php if ( $args['recommendations']->have_posts() ) : ?>
|
||||
|
||||
<?php
|
||||
$pag_args = array(
|
||||
'current' => max( 1, get_query_var( 'paged' ) ),
|
||||
'total' => $args['recommendations']->max_num_pages,
|
||||
'prev_text' => fcntr( 'previous' ),
|
||||
'next_text' => fcntr( 'next' ),
|
||||
'add_fragment' => '#list-of-recommendations'
|
||||
// Card arguments
|
||||
$card_args = array(
|
||||
'cache' => fictioneer_caching_active() && ! fictioneer_private_caching_active(),
|
||||
'order' => $args['order'] ?? 'desc',
|
||||
'orderby' => $args['orderby'] ?? 'modified',
|
||||
'ago' => $args['ago'] ?? 0
|
||||
);
|
||||
|
||||
// Filter card arguments
|
||||
$card_args = apply_filters( 'fictioneer_filter_recommendations_card_args', $card_args, $args );
|
||||
|
||||
while ( $args['recommendations']->have_posts() ) {
|
||||
$args['recommendations']->the_post();
|
||||
get_template_part( 'partials/_card-recommendation', null, $card_args );
|
||||
}
|
||||
|
||||
// Actions at end of results
|
||||
do_action( 'fictioneer_recommendations_end_of_results', $args );
|
||||
?>
|
||||
|
||||
<?php if ( $args['recommendations']->max_num_pages > 1 ) : ?>
|
||||
<li class="pagination"><?php echo fictioneer_paginate_links( $pag_args ); ?></li>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
|
||||
</ul>
|
||||
</section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
<?php do_action( 'fictioneer_recommendations_no_results', $args ); ?>
|
||||
|
||||
<li class="no-results">
|
||||
<span><?php _e( 'No recommendations found.', 'fictioneer' ) ?></span>
|
||||
</li>
|
||||
|
||||
<?php endif; wp_reset_postdata(); ?>
|
||||
|
||||
<?php
|
||||
$pag_args = array(
|
||||
'current' => max( 1, get_query_var( 'paged' ) ),
|
||||
'total' => $args['recommendations']->max_num_pages,
|
||||
'prev_text' => fcntr( 'previous' ),
|
||||
'next_text' => fcntr( 'next' ),
|
||||
'add_fragment' => '#list-of-recommendations'
|
||||
);
|
||||
?>
|
||||
|
||||
<?php if ( $args['recommendations']->max_num_pages > 1 ) : ?>
|
||||
<li class="pagination"><?php echo fictioneer_paginate_links( $pag_args ); ?></li>
|
||||
<?php endif; ?>
|
||||
|
||||
</ul>
|
||||
</section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_recommendations_after_content', 'fictioneer_recommendations_list', 30 );
|
||||
|
||||
@ -84,44 +82,42 @@ add_action( 'fictioneer_recommendations_after_content', 'fictioneer_recommendati
|
||||
// RECOMMENDATION TAGS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_recommendation_tags' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the recommendation page tags
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_Post $args['recommendation'] The recommendation object.
|
||||
* @param int $args['recommendation_id'] The recommendation post ID.
|
||||
* @param int $args['title'] The safe recommendation title.
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the recommendation page tags
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_Post $args['recommendation'] The recommendation object.
|
||||
* @param int $args['recommendation_id'] The recommendation post ID.
|
||||
* @param int $args['title'] The safe recommendation title.
|
||||
*/
|
||||
|
||||
function fictioneer_recommendation_tags( $args ) {
|
||||
// Setup
|
||||
$tag_args = [];
|
||||
function fictioneer_recommendation_tags( $args ) {
|
||||
// Setup
|
||||
$tag_args = [];
|
||||
|
||||
// Show tags?
|
||||
if ( ! get_option( 'fictioneer_hide_tags_on_pages' ) ) {
|
||||
$tags = get_the_tags( $args['recommendation_id'] );
|
||||
// Show tags?
|
||||
if ( ! get_option( 'fictioneer_hide_tags_on_pages' ) ) {
|
||||
$tags = get_the_tags( $args['recommendation_id'] );
|
||||
|
||||
if ( ! empty( $tags ) ) $tag_args[] = $tags;
|
||||
}
|
||||
|
||||
// Show content warnings?
|
||||
if ( ! get_option( 'fictioneer_hide_content_warnings_on_pages' ) ) {
|
||||
$warnings = get_the_terms( $args['recommendation_id'], 'fcn_content_warning' );
|
||||
|
||||
if ( ! empty( $warnings ) ) $tag_args[] = $warnings;
|
||||
}
|
||||
|
||||
// Abort conditions...
|
||||
if ( empty( $tag_args ) ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<section class="recommendation__tags tag-group">
|
||||
<?php echo fictioneer_get_taxonomy_pills( $tag_args, '_secondary' ); ?>
|
||||
</section>
|
||||
<?php // <--- End HTML
|
||||
if ( ! empty( $tags ) ) $tag_args[] = $tags;
|
||||
}
|
||||
|
||||
// Show content warnings?
|
||||
if ( ! get_option( 'fictioneer_hide_content_warnings_on_pages' ) ) {
|
||||
$warnings = get_the_terms( $args['recommendation_id'], 'fcn_content_warning' );
|
||||
|
||||
if ( ! empty( $warnings ) ) $tag_args[] = $warnings;
|
||||
}
|
||||
|
||||
// Abort conditions...
|
||||
if ( empty( $tag_args ) ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<section class="recommendation__tags tag-group">
|
||||
<?php echo fictioneer_get_taxonomy_pills( $tag_args, '_secondary' ); ?>
|
||||
</section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_recommendation_after_content', 'fictioneer_recommendation_tags', 10 );
|
||||
|
||||
@ -129,43 +125,41 @@ add_action( 'fictioneer_recommendation_after_content', 'fictioneer_recommendatio
|
||||
// RECOMMENDATION LINKS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_recommendation_links' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the recommendation page links
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_Post $args['recommendation'] The recommendation object.
|
||||
* @param int $args['recommendation_id'] The recommendation post ID.
|
||||
* @param int $args['title'] The safe recommendation title.
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the recommendation page links
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_Post $args['recommendation'] The recommendation object.
|
||||
* @param int $args['recommendation_id'] The recommendation post ID.
|
||||
* @param int $args['title'] The safe recommendation title.
|
||||
*/
|
||||
|
||||
function fictioneer_recommendation_links( $args ) {
|
||||
// Setup
|
||||
$links = fictioneer_get_field( 'fictioneer_recommendation_urls', $args['recommendation_id'] );
|
||||
function fictioneer_recommendation_links( $args ) {
|
||||
// Setup
|
||||
$links = fictioneer_get_field( 'fictioneer_recommendation_urls', $args['recommendation_id'] );
|
||||
|
||||
// Abort conditions...
|
||||
if ( ! $links ) return;
|
||||
// Abort conditions...
|
||||
if ( ! $links ) return;
|
||||
|
||||
// Prepare
|
||||
$links = array_filter( explode( "\n", $links ) );
|
||||
$tuples = [];
|
||||
// Prepare
|
||||
$links = array_filter( explode( "\n", $links ) );
|
||||
$tuples = [];
|
||||
|
||||
foreach( $links as $tuple ) {
|
||||
$tuple = explode( '|', $tuple );
|
||||
$tuple = array_map( 'trim', $tuple );
|
||||
$tuples[] = '<li><i class="fa-solid fa-external-link-square-alt"></i><a href="' . esc_url( $tuple[1] ) . '" class="link" rel="noopener" target="_blank">' . wp_strip_all_tags( $tuple[0] ) . '</a></li>';
|
||||
}
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<div class="recommendation__read-on">
|
||||
<h5><?php _e( 'Read on', 'fictioneer' ) ?></h5>
|
||||
<div>
|
||||
<ul class="recommendation__list"><?php echo implode( '', $tuples ); ?></ul>
|
||||
</div>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
foreach( $links as $tuple ) {
|
||||
$tuple = explode( '|', $tuple );
|
||||
$tuple = array_map( 'trim', $tuple );
|
||||
$tuples[] = '<li><i class="fa-solid fa-external-link-square-alt"></i><a href="' . esc_url( $tuple[1] ) . '" class="link" rel="noopener" target="_blank">' . wp_strip_all_tags( $tuple[0] ) . '</a></li>';
|
||||
}
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<div class="recommendation__read-on">
|
||||
<h5><?php _e( 'Read on', 'fictioneer' ) ?></h5>
|
||||
<div>
|
||||
<ul class="recommendation__list"><?php echo implode( '', $tuples ); ?></ul>
|
||||
</div>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_recommendation_after_content', 'fictioneer_recommendation_links', 20 );
|
||||
|
||||
@ -173,48 +167,46 @@ add_action( 'fictioneer_recommendation_after_content', 'fictioneer_recommendatio
|
||||
// RECOMMENDATION AUTHOR LINKS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_recommendation_support_links' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the recommendation page author links
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_Post $args['recommendation'] The recommendation object.
|
||||
* @param int $args['recommendation_id'] The recommendation post ID.
|
||||
* @param int $args['title'] The safe recommendation title.
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the recommendation page author links
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_Post $args['recommendation'] The recommendation object.
|
||||
* @param int $args['recommendation_id'] The recommendation post ID.
|
||||
* @param int $args['title'] The safe recommendation title.
|
||||
*/
|
||||
|
||||
function fictioneer_recommendation_support_links( $args ) {
|
||||
// Setup
|
||||
$links = fictioneer_get_field( 'fictioneer_recommendation_support', $args['recommendation_id'] );
|
||||
function fictioneer_recommendation_support_links( $args ) {
|
||||
// Setup
|
||||
$links = fictioneer_get_field( 'fictioneer_recommendation_support', $args['recommendation_id'] );
|
||||
|
||||
// Abort conditions...
|
||||
if ( ! $links ) return;
|
||||
// Abort conditions...
|
||||
if ( ! $links ) return;
|
||||
|
||||
// Prepare
|
||||
$links = array_filter( explode( "\n", $links ) );
|
||||
$tuples = [];
|
||||
// Prepare
|
||||
$links = array_filter( explode( "\n", $links ) );
|
||||
$tuples = [];
|
||||
|
||||
foreach( $links as $tuple ) {
|
||||
$tuple = explode( '|', $tuple );
|
||||
$tuple = array_map( 'trim', $tuple );
|
||||
$tuples[] = '<li><i class="fa-solid fa-external-link-square-alt"></i><a href="' . esc_url( $tuple[1] ) . '" class="link" rel="noopener" target="_blank">' . wp_strip_all_tags( $tuple[0] ) . '</a></li>';
|
||||
}
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<div class="recommendation__support">
|
||||
<h5><?php
|
||||
printf(
|
||||
_x( 'Support <em>%s</em>', 'Support _author_', 'fictioneer' ),
|
||||
fictioneer_get_field( 'fictioneer_recommendation_author', $args['recommendation_id'] )
|
||||
)
|
||||
?></h5>
|
||||
<div>
|
||||
<ul class="recommendation__list"><?php echo implode( '', $tuples ); ?></ul>
|
||||
</div>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
foreach( $links as $tuple ) {
|
||||
$tuple = explode( '|', $tuple );
|
||||
$tuple = array_map( 'trim', $tuple );
|
||||
$tuples[] = '<li><i class="fa-solid fa-external-link-square-alt"></i><a href="' . esc_url( $tuple[1] ) . '" class="link" rel="noopener" target="_blank">' . wp_strip_all_tags( $tuple[0] ) . '</a></li>';
|
||||
}
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<div class="recommendation__support">
|
||||
<h5><?php
|
||||
printf(
|
||||
_x( 'Support <em>%s</em>', 'Support _author_', 'fictioneer' ),
|
||||
fictioneer_get_field( 'fictioneer_recommendation_author', $args['recommendation_id'] )
|
||||
)
|
||||
?></h5>
|
||||
<div>
|
||||
<ul class="recommendation__list"><?php echo implode( '', $tuples ); ?></ul>
|
||||
</div>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_recommendation_after_content', 'fictioneer_recommendation_support_links', 30 );
|
||||
|
||||
|
@ -4,68 +4,66 @@
|
||||
// STATISTICS FOR ALL STORIES
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_stories_statistics' ) ) {
|
||||
/**
|
||||
* Outputs the statistics section for all stories
|
||||
*
|
||||
* Renders a statistics block with the number of published stories as well as
|
||||
* word count, comments, and the estimated reading time for all stories. The
|
||||
* reading time divisor can be changed under Fictioneer > General (default: 200).
|
||||
*
|
||||
* @since 5.0
|
||||
* @see stories.php
|
||||
*
|
||||
* @param int $args['current_page'] Current page number of pagination or 1.
|
||||
* @param int $args['post_id'] The post ID.
|
||||
* @param WP_Query $args['stories'] Paginated query of all published stories.
|
||||
* @param string $args['queried_type'] The queried post type ('fcn_story').
|
||||
*/
|
||||
/**
|
||||
* Outputs the statistics section for all stories
|
||||
*
|
||||
* Renders a statistics block with the number of published stories as well as
|
||||
* word count, comments, and the estimated reading time for all stories. The
|
||||
* reading time divisor can be changed under Fictioneer > General (default: 200).
|
||||
*
|
||||
* @since 5.0
|
||||
* @see stories.php
|
||||
*
|
||||
* @param int $args['current_page'] Current page number of pagination or 1.
|
||||
* @param int $args['post_id'] The post ID.
|
||||
* @param WP_Query $args['stories'] Paginated query of all published stories.
|
||||
* @param string $args['queried_type'] The queried post type ('fcn_story').
|
||||
*/
|
||||
|
||||
function fictioneer_stories_statistics( $args ) {
|
||||
// Setup
|
||||
$words = fictioneer_get_stories_total_word_count();
|
||||
$statistics = array(
|
||||
'stories' => array(
|
||||
'label' => __( 'Stories', 'fictioneer' ),
|
||||
'content' => number_format_i18n( wp_count_posts( 'fcn_story' )->publish )
|
||||
),
|
||||
'words' => array(
|
||||
'label' => __( 'Words', 'fictioneer' ),
|
||||
'content' => fictioneer_shorten_number( $words )
|
||||
),
|
||||
'comments' => array(
|
||||
'label' => __( 'Comments', 'fictioneer' ),
|
||||
'content' => number_format_i18n(
|
||||
get_comments(
|
||||
array(
|
||||
'post_type' => 'fcn_chapter',
|
||||
'status' => 1,
|
||||
'count' => true,
|
||||
'update_comment_meta_cache' => false
|
||||
)
|
||||
function fictioneer_stories_statistics( $args ) {
|
||||
// Setup
|
||||
$words = fictioneer_get_stories_total_word_count();
|
||||
$statistics = array(
|
||||
'stories' => array(
|
||||
'label' => __( 'Stories', 'fictioneer' ),
|
||||
'content' => number_format_i18n( wp_count_posts( 'fcn_story' )->publish )
|
||||
),
|
||||
'words' => array(
|
||||
'label' => __( 'Words', 'fictioneer' ),
|
||||
'content' => fictioneer_shorten_number( $words )
|
||||
),
|
||||
'comments' => array(
|
||||
'label' => __( 'Comments', 'fictioneer' ),
|
||||
'content' => number_format_i18n(
|
||||
get_comments(
|
||||
array(
|
||||
'post_type' => 'fcn_chapter',
|
||||
'status' => 1,
|
||||
'count' => true,
|
||||
'update_comment_meta_cache' => false
|
||||
)
|
||||
)
|
||||
),
|
||||
'reading' => array(
|
||||
'label' => __( 'Reading', 'fictioneer' ),
|
||||
'content' => fictioneer_get_reading_time_nodes( $words )
|
||||
),
|
||||
);
|
||||
)
|
||||
),
|
||||
'reading' => array(
|
||||
'label' => __( 'Reading', 'fictioneer' ),
|
||||
'content' => fictioneer_get_reading_time_nodes( $words )
|
||||
),
|
||||
);
|
||||
|
||||
// Apply filter
|
||||
$statistics = apply_filters( 'fictioneer_filter_stories_statistics', $statistics, $args );
|
||||
// Apply filter
|
||||
$statistics = apply_filters( 'fictioneer_filter_stories_statistics', $statistics, $args );
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<div class="stories__statistics statistics spacing-top">
|
||||
<?php foreach ( $statistics as $stat ) : ?>
|
||||
<div class="statistics__inline-stat">
|
||||
<strong><?php echo $stat['label']; ?></strong>
|
||||
<span><?php echo $stat['content']; ?></span>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
// Start HTML ---> ?>
|
||||
<div class="stories__statistics statistics spacing-top">
|
||||
<?php foreach ( $statistics as $stat ) : ?>
|
||||
<div class="statistics__inline-stat">
|
||||
<strong><?php echo $stat['label']; ?></strong>
|
||||
<span><?php echo $stat['content']; ?></span>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_stories_after_content', 'fictioneer_stories_statistics', 10 );
|
||||
|
||||
@ -73,84 +71,82 @@ add_action( 'fictioneer_stories_after_content', 'fictioneer_stories_statistics',
|
||||
// LIST OF ALL STORIES
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_stories_list' ) ) {
|
||||
/**
|
||||
* Outputs the paginated card list for all stories
|
||||
*
|
||||
* @since 5.0
|
||||
* @see stories.php
|
||||
*
|
||||
* @param int $args['current_page'] Current page number of pagination or 1.
|
||||
* @param int $args['post_id'] The post ID.
|
||||
* @param WP_Query $args['stories'] Paginated query of all published stories.
|
||||
* @param string $args['queried_type'] The queried post type ('fcn_story').
|
||||
* @param array $args['query_args'] The query arguments used.
|
||||
* @param string $args['order'] Current order. Default 'desc'.
|
||||
* @param string $args['orderby'] Current orderby. Default 'modified'.
|
||||
* @param int|string $args['ago'] Current date query argument part. Default 0.
|
||||
*/
|
||||
/**
|
||||
* Outputs the paginated card list for all stories
|
||||
*
|
||||
* @since 5.0
|
||||
* @see stories.php
|
||||
*
|
||||
* @param int $args['current_page'] Current page number of pagination or 1.
|
||||
* @param int $args['post_id'] The post ID.
|
||||
* @param WP_Query $args['stories'] Paginated query of all published stories.
|
||||
* @param string $args['queried_type'] The queried post type ('fcn_story').
|
||||
* @param array $args['query_args'] The query arguments used.
|
||||
* @param string $args['order'] Current order. Default 'desc'.
|
||||
* @param string $args['orderby'] Current orderby. Default 'modified'.
|
||||
* @param int|string $args['ago'] Current date query argument part. Default 0.
|
||||
*/
|
||||
|
||||
function fictioneer_stories_list( $args ) {
|
||||
// Start HTML ---> ?>
|
||||
<section class="stories__list spacing-top">
|
||||
<ul class="card-list" id="list-of-stories">
|
||||
function fictioneer_stories_list( $args ) {
|
||||
// Start HTML ---> ?>
|
||||
<section class="stories__list spacing-top">
|
||||
<ul class="card-list" id="list-of-stories">
|
||||
|
||||
<?php if ( $args['stories']->have_posts() ) : ?>
|
||||
|
||||
<?php
|
||||
// Card arguments
|
||||
$card_args = array(
|
||||
'cache' => fictioneer_caching_active() && ! fictioneer_private_caching_active(),
|
||||
'order' => $args['order'] ?? 'desc',
|
||||
'orderby' => $args['orderby'] ?? 'modified',
|
||||
'ago' => $args['ago'] ?? 0
|
||||
);
|
||||
|
||||
// Filter card arguments
|
||||
$card_args = apply_filters( 'fictioneer_filter_stories_card_args', $card_args, $args );
|
||||
|
||||
while ( $args['stories']->have_posts() ) {
|
||||
$args['stories']->the_post();
|
||||
|
||||
if ( fictioneer_get_field( 'fictioneer_story_hidden' ) ) {
|
||||
get_template_part( 'partials/_card-hidden', null, $card_args );
|
||||
} else {
|
||||
get_template_part( 'partials/_card-story', null, $card_args );
|
||||
}
|
||||
}
|
||||
|
||||
// Actions at end of results
|
||||
do_action( 'fictioneer_stories_end_of_results', $args );
|
||||
?>
|
||||
|
||||
<?php else : ?>
|
||||
|
||||
<?php do_action( 'fictioneer_stories_no_results', $args ); ?>
|
||||
|
||||
<li class="no-results">
|
||||
<span><?php _e( 'No stories found.', 'fictioneer' ) ?></span>
|
||||
</li>
|
||||
|
||||
<?php endif; wp_reset_postdata(); ?>
|
||||
<?php if ( $args['stories']->have_posts() ) : ?>
|
||||
|
||||
<?php
|
||||
$pag_args = array(
|
||||
'current' => max( 1, get_query_var( 'paged' ) ),
|
||||
'total' => $args['stories']->max_num_pages,
|
||||
'prev_text' => fcntr( 'previous' ),
|
||||
'next_text' => fcntr( 'next' ),
|
||||
'add_fragment' => '#list-of-stories'
|
||||
// Card arguments
|
||||
$card_args = array(
|
||||
'cache' => fictioneer_caching_active() && ! fictioneer_private_caching_active(),
|
||||
'order' => $args['order'] ?? 'desc',
|
||||
'orderby' => $args['orderby'] ?? 'modified',
|
||||
'ago' => $args['ago'] ?? 0
|
||||
);
|
||||
|
||||
// Filter card arguments
|
||||
$card_args = apply_filters( 'fictioneer_filter_stories_card_args', $card_args, $args );
|
||||
|
||||
while ( $args['stories']->have_posts() ) {
|
||||
$args['stories']->the_post();
|
||||
|
||||
if ( fictioneer_get_field( 'fictioneer_story_hidden' ) ) {
|
||||
get_template_part( 'partials/_card-hidden', null, $card_args );
|
||||
} else {
|
||||
get_template_part( 'partials/_card-story', null, $card_args );
|
||||
}
|
||||
}
|
||||
|
||||
// Actions at end of results
|
||||
do_action( 'fictioneer_stories_end_of_results', $args );
|
||||
?>
|
||||
|
||||
<?php if ( $args['stories']->max_num_pages > 1 ) : ?>
|
||||
<li class="pagination"><?php echo fictioneer_paginate_links( $pag_args ); ?></li>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
|
||||
</ul>
|
||||
</section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
<?php do_action( 'fictioneer_stories_no_results', $args ); ?>
|
||||
|
||||
<li class="no-results">
|
||||
<span><?php _e( 'No stories found.', 'fictioneer' ) ?></span>
|
||||
</li>
|
||||
|
||||
<?php endif; wp_reset_postdata(); ?>
|
||||
|
||||
<?php
|
||||
$pag_args = array(
|
||||
'current' => max( 1, get_query_var( 'paged' ) ),
|
||||
'total' => $args['stories']->max_num_pages,
|
||||
'prev_text' => fcntr( 'previous' ),
|
||||
'next_text' => fcntr( 'next' ),
|
||||
'add_fragment' => '#list-of-stories'
|
||||
);
|
||||
?>
|
||||
|
||||
<?php if ( $args['stories']->max_num_pages > 1 ) : ?>
|
||||
<li class="pagination"><?php echo fictioneer_paginate_links( $pag_args ); ?></li>
|
||||
<?php endif; ?>
|
||||
|
||||
</ul>
|
||||
</section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_stories_after_content', 'fictioneer_stories_list', 30 );
|
||||
|
||||
@ -158,29 +154,27 @@ add_action( 'fictioneer_stories_after_content', 'fictioneer_stories_list', 30 );
|
||||
// STORY COPYRIGHT NOTICE
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_story_copyright_notice' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the story page copyright notice
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param array $args['story_data'] Collection of story data.
|
||||
* @param int $args['story_id'] The story post ID.
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the story page copyright notice
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param array $args['story_data'] Collection of story data.
|
||||
* @param int $args['story_id'] The story post ID.
|
||||
*/
|
||||
|
||||
function fictioneer_story_copyright_notice( $args ) {
|
||||
// Setup
|
||||
$copyright_notice = fictioneer_get_field( 'fictioneer_story_copyright_notice', $args['story_id'] );
|
||||
function fictioneer_story_copyright_notice( $args ) {
|
||||
// Setup
|
||||
$copyright_notice = fictioneer_get_field( 'fictioneer_story_copyright_notice', $args['story_id'] );
|
||||
|
||||
// Abort conditions...
|
||||
if ( empty( $copyright_notice ) ) return;
|
||||
// Abort conditions...
|
||||
if ( empty( $copyright_notice ) ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<section class="story__copyright-notice padding-left padding-right">
|
||||
<i class="fa-regular fa-copyright"></i> <?php echo $copyright_notice; ?>
|
||||
</section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
// Start HTML ---> ?>
|
||||
<section class="story__copyright-notice padding-left padding-right">
|
||||
<i class="fa-regular fa-copyright"></i> <?php echo $copyright_notice; ?>
|
||||
</section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_story_after_content', 'fictioneer_story_copyright_notice', 10 );
|
||||
|
||||
@ -188,33 +182,31 @@ add_action( 'fictioneer_story_after_content', 'fictioneer_story_copyright_notice
|
||||
// STORY TAGS & WARNINGS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_story_tags_and_warnings' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the story page tags and warnings
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param array $args['story_data'] Collection of story data.
|
||||
* @param int $args['story_id'] The story post ID.
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the story page tags and warnings
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param array $args['story_data'] Collection of story data.
|
||||
* @param int $args['story_id'] The story post ID.
|
||||
*/
|
||||
|
||||
function fictioneer_story_tags_and_warnings( $args ) {
|
||||
// Abort conditions...
|
||||
$tags_shown = $args['story_data']['tags'] && ! get_option( 'fictioneer_hide_tags_on_pages' ) && ! fictioneer_get_field( 'fictioneer_story_no_tags' );;
|
||||
$warnings_shown = $args['story_data']['warnings'] && ! get_option( 'fictioneer_hide_content_warnings_on_pages' );
|
||||
if ( ! $tags_shown && ! $warnings_shown ) return;
|
||||
function fictioneer_story_tags_and_warnings( $args ) {
|
||||
// Abort conditions...
|
||||
$tags_shown = $args['story_data']['tags'] && ! get_option( 'fictioneer_hide_tags_on_pages' ) && ! fictioneer_get_field( 'fictioneer_story_no_tags' );;
|
||||
$warnings_shown = $args['story_data']['warnings'] && ! get_option( 'fictioneer_hide_content_warnings_on_pages' );
|
||||
if ( ! $tags_shown && ! $warnings_shown ) return;
|
||||
|
||||
// Setup
|
||||
$tag_args = [];
|
||||
if ( $tags_shown ) $tag_args[] = $args['story_data']['tags'];
|
||||
if ( $warnings_shown ) $tag_args[] = $args['story_data']['warnings'];
|
||||
// Setup
|
||||
$tag_args = [];
|
||||
if ( $tags_shown ) $tag_args[] = $args['story_data']['tags'];
|
||||
if ( $warnings_shown ) $tag_args[] = $args['story_data']['warnings'];
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<section class="story__tags-and-warnings tag-group padding-left padding-right"><?php
|
||||
echo fictioneer_get_taxonomy_pills( $tag_args, '_secondary' );
|
||||
?></section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
// Start HTML ---> ?>
|
||||
<section class="story__tags-and-warnings tag-group padding-left padding-right"><?php
|
||||
echo fictioneer_get_taxonomy_pills( $tag_args, '_secondary' );
|
||||
?></section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_story_after_content', 'fictioneer_story_tags_and_warnings', 20 );
|
||||
|
||||
@ -222,27 +214,25 @@ add_action( 'fictioneer_story_after_content', 'fictioneer_story_tags_and_warning
|
||||
// STORY ACTIONS ROW
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_story_actions' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the story page actions row
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param array $args['story_data'] Collection of story data.
|
||||
* @param int $args['story_id'] The story post ID.
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the story page actions row
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param array $args['story_data'] Collection of story data.
|
||||
* @param int $args['story_id'] The story post ID.
|
||||
*/
|
||||
|
||||
function fictioneer_story_actions( $args ) {
|
||||
// Abort conditions...
|
||||
if ( post_password_required() ) return;
|
||||
function fictioneer_story_actions( $args ) {
|
||||
// Abort conditions...
|
||||
if ( post_password_required() ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<section class="story__after-summary padding-left padding-right">
|
||||
<?php get_template_part( 'partials/_share-buttons' ); ?>
|
||||
<div class="story__actions"><?php echo fictioneer_get_story_buttons( $args ); ?></div>
|
||||
</section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
// Start HTML ---> ?>
|
||||
<section class="story__after-summary padding-left padding-right">
|
||||
<?php get_template_part( 'partials/_share-buttons' ); ?>
|
||||
<div class="story__actions"><?php echo fictioneer_get_story_buttons( $args ); ?></div>
|
||||
</section>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_story_after_content', 'fictioneer_story_actions', 30 );
|
||||
|
||||
@ -250,23 +240,21 @@ add_action( 'fictioneer_story_after_content', 'fictioneer_story_actions', 30 );
|
||||
// STORY CHAPTERS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_story_content' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the story page actions row
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param array $args['story_data'] Collection of story data.
|
||||
* @param int $args['story_id'] The story post ID.
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the story page actions row
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param array $args['story_data'] Collection of story data.
|
||||
* @param int $args['story_id'] The story post ID.
|
||||
*/
|
||||
|
||||
function fictioneer_story_content( $args ) {
|
||||
// Abort conditions...
|
||||
if ( post_password_required() ) return;
|
||||
function fictioneer_story_content( $args ) {
|
||||
// Abort conditions...
|
||||
if ( post_password_required() ) return;
|
||||
|
||||
// Render partial
|
||||
get_template_part( 'partials/_story-content', null, $args );
|
||||
}
|
||||
// Render partial
|
||||
get_template_part( 'partials/_story-content', null, $args );
|
||||
}
|
||||
add_action( 'fictioneer_story_after_content', 'fictioneer_story_content', 40 );
|
||||
|
||||
@ -274,23 +262,21 @@ add_action( 'fictioneer_story_after_content', 'fictioneer_story_content', 40 );
|
||||
// STORY COMMENTS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_story_comment' ) ) {
|
||||
/**
|
||||
* Outputs the HTML for the story page comments
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param array $args['story_data'] Collection of story data.
|
||||
* @param int $args['story_id'] The story post ID.
|
||||
*/
|
||||
/**
|
||||
* Outputs the HTML for the story page comments
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param array $args['story_data'] Collection of story data.
|
||||
* @param int $args['story_id'] The story post ID.
|
||||
*/
|
||||
|
||||
function fictioneer_story_comment( $args ) {
|
||||
// Abort conditions...
|
||||
if ( post_password_required() ) return;
|
||||
function fictioneer_story_comment( $args ) {
|
||||
// Abort conditions...
|
||||
if ( post_password_required() ) return;
|
||||
|
||||
// Render partial
|
||||
get_template_part( 'partials/_story-comments', null, $args );
|
||||
}
|
||||
// Render partial
|
||||
get_template_part( 'partials/_story-comments', null, $args );
|
||||
}
|
||||
add_action( 'fictioneer_story_after_article', 'fictioneer_story_comment', 10 );
|
||||
|
||||
|
@ -4,35 +4,35 @@
|
||||
// REFRESH CHAPTER SCHEMA
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_refresh_chapter_schema' ) ) {
|
||||
/**
|
||||
* Refresh chapter schemas
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
/**
|
||||
* Refresh chapter schemas
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
|
||||
function fictioneer_refresh_chapter_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check what was updated
|
||||
if ( $post->post_type !== 'fcn_chapter' ) return;
|
||||
|
||||
// Setup
|
||||
$story_id = fictioneer_get_field( 'fictioneer_chapter_story', $post_id );
|
||||
|
||||
// Rebuild schema(s)
|
||||
fictioneer_build_chapter_schema( $post_id );
|
||||
if ( ! empty( $story_id ) ) fictioneer_build_story_schema( $story_id );
|
||||
function fictioneer_refresh_chapter_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check what was updated
|
||||
if ( $post->post_type !== 'fcn_chapter' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup
|
||||
$story_id = fictioneer_get_field( 'fictioneer_chapter_story', $post_id );
|
||||
|
||||
// Rebuild schema(s)
|
||||
fictioneer_build_chapter_schema( $post_id );
|
||||
if ( ! empty( $story_id ) ) fictioneer_build_story_schema( $story_id );
|
||||
}
|
||||
add_action( 'save_post', 'fictioneer_refresh_chapter_schema', 20, 2 );
|
||||
|
||||
|
@ -4,44 +4,46 @@
|
||||
// REFRESH CHAPTERS SUMMARY SCHEMA
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_refresh_chapters_schema' ) ) {
|
||||
/**
|
||||
* Refresh chapters summary schemas
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
/**
|
||||
* Refresh chapters summary schemas
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
|
||||
function fictioneer_refresh_chapters_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
function fictioneer_refresh_chapters_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check what was updated
|
||||
$sub_update = in_array( $post->post_type, ['fcn_chapter', 'fcn_collection'] );
|
||||
if ( get_page_template_slug() != 'chapters.php' && ! $sub_update ) return;
|
||||
// Check what was updated
|
||||
if (
|
||||
get_page_template_slug() != 'chapters.php' &&
|
||||
! in_array( $post->post_type, ['fcn_chapter', 'fcn_collection'] )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all pages with the chapters template
|
||||
$pages = get_posts(
|
||||
array(
|
||||
'post_type' => 'page',
|
||||
'numberposts' => -1,
|
||||
'meta_key' => '_wp_page_template',
|
||||
'meta_value' => 'chapters.php'
|
||||
)
|
||||
);
|
||||
// Get all pages with the chapters template
|
||||
$pages = get_posts(
|
||||
array(
|
||||
'post_type' => 'page',
|
||||
'numberposts' => -1,
|
||||
'meta_key' => '_wp_page_template',
|
||||
'meta_value' => 'chapters.php'
|
||||
)
|
||||
);
|
||||
|
||||
// Rebuild schemas
|
||||
if ( $pages ) {
|
||||
foreach ( $pages as $page ) {
|
||||
fictioneer_build_chapters_schema( $page->ID );
|
||||
}
|
||||
// Rebuild schemas
|
||||
if ( $pages ) {
|
||||
foreach ( $pages as $page ) {
|
||||
fictioneer_build_chapters_schema( $page->ID );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,44 +4,46 @@
|
||||
// REFRESH COLLECTIONS SUMMARY SCHEMA
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_refresh_collections_schema' ) ) {
|
||||
/**
|
||||
* Refresh collections summary schemas
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
/**
|
||||
* Refresh collections summary schemas
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
|
||||
function fictioneer_refresh_collections_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
function fictioneer_refresh_collections_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check what was updated
|
||||
$sub_update = in_array( $post->post_type, ['fcn_collection', 'fcn_story', 'fcn_chapter', 'fcn_recommendation', 'post'] );
|
||||
if ( get_page_template_slug() != 'collections.php' && ! $sub_update ) return;
|
||||
// Check what was updated
|
||||
if (
|
||||
get_page_template_slug() != 'collections.php' &&
|
||||
! in_array( $post->post_type, ['fcn_collection', 'fcn_story', 'fcn_chapter', 'fcn_recommendation', 'post'] )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all pages with the collections template
|
||||
$pages = get_posts(
|
||||
array(
|
||||
'post_type' => 'page',
|
||||
'numberposts' => -1,
|
||||
'meta_key' => '_wp_page_template',
|
||||
'meta_value' => 'collections.php'
|
||||
)
|
||||
);
|
||||
// Get all pages with the collections template
|
||||
$pages = get_posts(
|
||||
array(
|
||||
'post_type' => 'page',
|
||||
'numberposts' => -1,
|
||||
'meta_key' => '_wp_page_template',
|
||||
'meta_value' => 'collections.php'
|
||||
)
|
||||
);
|
||||
|
||||
// Rebuild schemas
|
||||
if ( $pages ) {
|
||||
foreach ( $pages as $page ) {
|
||||
fictioneer_build_collections_schema( $page->ID );
|
||||
}
|
||||
// Rebuild schemas
|
||||
if ( $pages ) {
|
||||
foreach ( $pages as $page ) {
|
||||
fictioneer_build_collections_schema( $page->ID );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,31 +4,31 @@
|
||||
// REFRESH POST SCHEMA
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_refresh_post_schema' ) ) {
|
||||
/**
|
||||
* Refresh post schema
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
/**
|
||||
* Refresh post schema
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
|
||||
function fictioneer_refresh_post_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check what was updated
|
||||
if ( $post->post_type !== 'post' ) return;
|
||||
|
||||
// Rebuild
|
||||
fictioneer_build_post_schema( $post_id );
|
||||
function fictioneer_refresh_post_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check what was updated
|
||||
if ( $post->post_type !== 'post' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Rebuild
|
||||
fictioneer_build_post_schema( $post_id );
|
||||
}
|
||||
add_action( 'save_post', 'fictioneer_refresh_post_schema', 20, 2 );
|
||||
|
||||
|
@ -4,31 +4,31 @@
|
||||
// REFRESH RECOMMENDATION SCHEMA
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_refresh_recommendation_schema' ) ) {
|
||||
/**
|
||||
* Refresh recommendation schema
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
/**
|
||||
* Refresh recommendation schema
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
|
||||
function fictioneer_refresh_recommendation_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check what was updated
|
||||
if ( $post->post_type !== 'fcn_recommendation' ) return;
|
||||
|
||||
// Rebuild
|
||||
fictioneer_build_recommendation_schema( $post_id );
|
||||
function fictioneer_refresh_recommendation_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check what was updated
|
||||
if ( $post->post_type !== 'fcn_recommendation' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Rebuild
|
||||
fictioneer_build_recommendation_schema( $post_id );
|
||||
}
|
||||
add_action( 'save_post', 'fictioneer_refresh_recommendation_schema', 20, 2 );
|
||||
|
||||
|
@ -4,44 +4,46 @@
|
||||
// REFRESH RECOMMENDATIONS SUMMARY SCHEMA
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_refresh_recommendations_schema' ) ) {
|
||||
/**
|
||||
* Refresh recommendations summary schemas
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
/**
|
||||
* Refresh recommendations summary schemas
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
|
||||
function fictioneer_refresh_recommendations_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
function fictioneer_refresh_recommendations_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check what was updated
|
||||
$sub_update = in_array( $post->post_type, ['fcn_recommendation', 'fcn_collection'] );
|
||||
if ( get_page_template_slug() != 'recommendations.php' && ! $sub_update ) return;
|
||||
// Check what was updated
|
||||
if (
|
||||
get_page_template_slug() != 'recommendations.php' &&
|
||||
! in_array( $post->post_type, ['fcn_recommendation', 'fcn_collection'] )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all pages with the recommendations template
|
||||
$pages = get_posts(
|
||||
array(
|
||||
'post_type' => 'page',
|
||||
'numberposts' => -1,
|
||||
'meta_key' => '_wp_page_template',
|
||||
'meta_value' => 'recommendations.php'
|
||||
)
|
||||
);
|
||||
// Get all pages with the recommendations template
|
||||
$pages = get_posts(
|
||||
array(
|
||||
'post_type' => 'page',
|
||||
'numberposts' => -1,
|
||||
'meta_key' => '_wp_page_template',
|
||||
'meta_value' => 'recommendations.php'
|
||||
)
|
||||
);
|
||||
|
||||
// Rebuild schemas
|
||||
if ( $pages ) {
|
||||
foreach ( $pages as $page ) {
|
||||
fictioneer_build_recommendations_schema( $page->ID );
|
||||
}
|
||||
// Rebuild schemas
|
||||
if ( $pages ) {
|
||||
foreach ( $pages as $page ) {
|
||||
fictioneer_build_recommendations_schema( $page->ID );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,44 +4,46 @@
|
||||
// REFRESH STORIES SUMMARY SCHEMA
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_refresh_stories_schema' ) ) {
|
||||
/**
|
||||
* Refresh stories summary schemas
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
/**
|
||||
* Refresh stories summary schemas
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
|
||||
function fictioneer_refresh_stories_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
function fictioneer_refresh_stories_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check what was updated
|
||||
$sub_update = in_array( $post->post_type, ['fcn_story', 'fcn_collection'] );
|
||||
if ( get_page_template_slug() != 'stories.php' && ! $sub_update ) return;
|
||||
// Check what was updated
|
||||
if (
|
||||
get_page_template_slug() != 'stories.php' &&
|
||||
! in_array( $post->post_type, ['fcn_story', 'fcn_collection'] )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all pages with the stories template
|
||||
$pages = get_posts(
|
||||
array(
|
||||
'post_type' => 'page',
|
||||
'numberposts' => -1,
|
||||
'meta_key' => '_wp_page_template',
|
||||
'meta_value' => 'stories.php'
|
||||
)
|
||||
);
|
||||
// Get all pages with the stories template
|
||||
$pages = get_posts(
|
||||
array(
|
||||
'post_type' => 'page',
|
||||
'numberposts' => -1,
|
||||
'meta_key' => '_wp_page_template',
|
||||
'meta_value' => 'stories.php'
|
||||
)
|
||||
);
|
||||
|
||||
// Rebuild schemas
|
||||
if ( $pages ) {
|
||||
foreach ( $pages as $page ) {
|
||||
fictioneer_build_stories_schema( $page->ID );
|
||||
}
|
||||
// Rebuild schemas
|
||||
if ( $pages ) {
|
||||
foreach ( $pages as $page ) {
|
||||
fictioneer_build_stories_schema( $page->ID );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,39 +4,39 @@
|
||||
// REFRESH STORY SCHEMA
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_refresh_story_schema' ) ) {
|
||||
/**
|
||||
* Refresh story schema
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
/**
|
||||
* Refresh story schema
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param int $post_id The ID of the saved post.
|
||||
* @param WP_Post $post The saved post object.
|
||||
*/
|
||||
|
||||
function fictioneer_refresh_story_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
function fictioneer_refresh_story_schema( $post_id, $post ) {
|
||||
// Prevent multi-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check what was updated
|
||||
if ( $post->post_type !== 'fcn_story' ) return;
|
||||
// Check what was updated
|
||||
if ( $post->post_type !== 'fcn_story' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Rebuild schema(s)
|
||||
fictioneer_build_story_schema( $post_id );
|
||||
// Rebuild schema(s)
|
||||
fictioneer_build_story_schema( $post_id );
|
||||
|
||||
// Get chapters of story
|
||||
$chapters = fictioneer_get_field( 'fictioneer_story_chapters', $post_id );
|
||||
// Get chapters of story
|
||||
$chapters = fictioneer_get_field( 'fictioneer_story_chapters', $post_id );
|
||||
|
||||
// Rebuild chapter schemas (if any)
|
||||
if ( ! empty( $chapters ) ) {
|
||||
foreach ( $chapters as $chapter_id ) {
|
||||
fictioneer_build_chapter_schema( $chapter_id );
|
||||
}
|
||||
// Rebuild chapter schemas (if any)
|
||||
if ( ! empty( $chapters ) ) {
|
||||
foreach ( $chapters as $chapter_id ) {
|
||||
fictioneer_build_chapter_schema( $chapter_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -647,74 +647,72 @@ add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_profile_fields_d
|
||||
* currently editing the profile!
|
||||
*/
|
||||
|
||||
if ( ! function_exists( 'fictioneer_admin_profile_moderation' ) ) {
|
||||
function fictioneer_admin_profile_moderation( $profile_user ) {
|
||||
// Setup
|
||||
$editing_user_is_admin = fictioneer_is_admin( get_current_user_id() );
|
||||
$editing_user_is_moderator = fictioneer_is_moderator( get_current_user_id() );
|
||||
function fictioneer_admin_profile_moderation( $profile_user ) {
|
||||
// Setup
|
||||
$editing_user_is_admin = fictioneer_is_admin( get_current_user_id() );
|
||||
$editing_user_is_moderator = fictioneer_is_moderator( get_current_user_id() );
|
||||
|
||||
// Abort conditions...
|
||||
if ( ! $editing_user_is_admin && ! $editing_user_is_moderator ) return;
|
||||
// Abort conditions...
|
||||
if ( ! $editing_user_is_admin && ! $editing_user_is_moderator ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-moderation-flags-wrap">
|
||||
<th><?php _e( 'Moderation Flags', 'fictioneer' ) ?></th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<div>
|
||||
<label for="fictioneer_admin_disable_avatar" class="checkbox-group">
|
||||
<input name="fictioneer_admin_disable_avatar" type="checkbox" id="fictioneer_admin_disable_avatar" <?php echo checked( 1, get_the_author_meta( 'fictioneer_admin_disable_avatar', $profile_user->ID ), false ); ?> value="1">
|
||||
<span><?php _e( 'Disable user avatar', 'fictioneer' ) ?></span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="fictioneer_admin_disable_reporting" class="checkbox-group">
|
||||
<input name="fictioneer_admin_disable_reporting" type="checkbox" id="fictioneer_admin_disable_reporting" <?php echo checked( 1, get_the_author_meta( 'fictioneer_admin_disable_reporting', $profile_user->ID ), false ); ?> value="1">
|
||||
<span><?php _e( 'Disable reporting capability', 'fictioneer' ) ?></span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="fictioneer_admin_disable_renaming" class="checkbox-group">
|
||||
<input name="fictioneer_admin_disable_renaming" type="checkbox" id="fictioneer_admin_disable_renaming" <?php echo checked( 1, get_the_author_meta( 'fictioneer_admin_disable_renaming', $profile_user->ID ), false ); ?> value="1">
|
||||
<span><?php _e( 'Disable renaming capability', 'fictioneer' ) ?></span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="fictioneer_admin_disable_commenting" class="checkbox-group">
|
||||
<input name="fictioneer_admin_disable_commenting" type="checkbox" id="fictioneer_admin_disable_commenting" <?php echo checked( 1, get_the_author_meta( 'fictioneer_admin_disable_commenting', $profile_user->ID ), false ); ?> value="1">
|
||||
<span><?php _e( 'Disable commenting capability', 'fictioneer' ) ?></span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="fictioneer_admin_disable_editing" class="checkbox-group">
|
||||
<input name="fictioneer_admin_disable_editing" type="checkbox" id="fictioneer_admin_disable_editing" <?php echo checked( 1, get_the_author_meta( 'fictioneer_admin_disable_editing', $profile_user->ID ), false ); ?> value="1">
|
||||
<span><?php _e( 'Disable comment editing capability', 'fictioneer' ) ?></span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="fictioneer_admin_disable_comment_notifications" class="checkbox-group">
|
||||
<input name="fictioneer_admin_disable_comment_notifications" type="checkbox" id="fictioneer_admin_disable_comment_notifications" <?php echo checked( 1, get_the_author_meta( 'fictioneer_admin_disable_comment_notifications', $profile_user->ID ), false ); ?> value="1">
|
||||
<span><?php _e( 'Disable comment reply notifications', 'fictioneer' ) ?></span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="fictioneer_admin_always_moderate_comments" class="checkbox-group">
|
||||
<input name="fictioneer_admin_always_moderate_comments" type="checkbox" id="fictioneer_admin_always_moderate_comments" <?php echo checked( 1, get_the_author_meta( 'fictioneer_admin_always_moderate_comments', $profile_user->ID ), false ); ?> value="1">
|
||||
<span><?php _e( 'Always hold comments for moderation', 'fictioneer' ) ?></span>
|
||||
</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="user-moderation-message-wrap">
|
||||
<th><label for="fictioneer_admin_moderation_message"><?php _e( 'Moderation Message', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
<textarea name="fictioneer_admin_moderation_message" id="fictioneer_admin_moderation_message" rows="8" cols="30"><?php echo esc_attr( get_the_author_meta( 'fictioneer_admin_moderation_message', $profile_user->ID ) ); ?></textarea>
|
||||
<p class="description"><?php _e( 'Custom message in the user profile, which may be a nice thing as well.', 'fictioneer' ) ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-moderation-flags-wrap">
|
||||
<th><?php _e( 'Moderation Flags', 'fictioneer' ) ?></th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<div>
|
||||
<label for="fictioneer_admin_disable_avatar" class="checkbox-group">
|
||||
<input name="fictioneer_admin_disable_avatar" type="checkbox" id="fictioneer_admin_disable_avatar" <?php echo checked( 1, get_the_author_meta( 'fictioneer_admin_disable_avatar', $profile_user->ID ), false ); ?> value="1">
|
||||
<span><?php _e( 'Disable user avatar', 'fictioneer' ) ?></span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="fictioneer_admin_disable_reporting" class="checkbox-group">
|
||||
<input name="fictioneer_admin_disable_reporting" type="checkbox" id="fictioneer_admin_disable_reporting" <?php echo checked( 1, get_the_author_meta( 'fictioneer_admin_disable_reporting', $profile_user->ID ), false ); ?> value="1">
|
||||
<span><?php _e( 'Disable reporting capability', 'fictioneer' ) ?></span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="fictioneer_admin_disable_renaming" class="checkbox-group">
|
||||
<input name="fictioneer_admin_disable_renaming" type="checkbox" id="fictioneer_admin_disable_renaming" <?php echo checked( 1, get_the_author_meta( 'fictioneer_admin_disable_renaming', $profile_user->ID ), false ); ?> value="1">
|
||||
<span><?php _e( 'Disable renaming capability', 'fictioneer' ) ?></span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="fictioneer_admin_disable_commenting" class="checkbox-group">
|
||||
<input name="fictioneer_admin_disable_commenting" type="checkbox" id="fictioneer_admin_disable_commenting" <?php echo checked( 1, get_the_author_meta( 'fictioneer_admin_disable_commenting', $profile_user->ID ), false ); ?> value="1">
|
||||
<span><?php _e( 'Disable commenting capability', 'fictioneer' ) ?></span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="fictioneer_admin_disable_editing" class="checkbox-group">
|
||||
<input name="fictioneer_admin_disable_editing" type="checkbox" id="fictioneer_admin_disable_editing" <?php echo checked( 1, get_the_author_meta( 'fictioneer_admin_disable_editing', $profile_user->ID ), false ); ?> value="1">
|
||||
<span><?php _e( 'Disable comment editing capability', 'fictioneer' ) ?></span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="fictioneer_admin_disable_comment_notifications" class="checkbox-group">
|
||||
<input name="fictioneer_admin_disable_comment_notifications" type="checkbox" id="fictioneer_admin_disable_comment_notifications" <?php echo checked( 1, get_the_author_meta( 'fictioneer_admin_disable_comment_notifications', $profile_user->ID ), false ); ?> value="1">
|
||||
<span><?php _e( 'Disable comment reply notifications', 'fictioneer' ) ?></span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="fictioneer_admin_always_moderate_comments" class="checkbox-group">
|
||||
<input name="fictioneer_admin_always_moderate_comments" type="checkbox" id="fictioneer_admin_always_moderate_comments" <?php echo checked( 1, get_the_author_meta( 'fictioneer_admin_always_moderate_comments', $profile_user->ID ), false ); ?> value="1">
|
||||
<span><?php _e( 'Always hold comments for moderation', 'fictioneer' ) ?></span>
|
||||
</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="user-moderation-message-wrap">
|
||||
<th><label for="fictioneer_admin_moderation_message"><?php _e( 'Moderation Message', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
<textarea name="fictioneer_admin_moderation_message" id="fictioneer_admin_moderation_message" rows="8" cols="30"><?php echo esc_attr( get_the_author_meta( 'fictioneer_admin_moderation_message', $profile_user->ID ) ); ?></textarea>
|
||||
<p class="description"><?php _e( 'Custom message in the user profile, which may be a nice thing as well.', 'fictioneer' ) ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_profile_moderation', 10 );
|
||||
|
||||
@ -731,80 +729,78 @@ add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_profile_moderati
|
||||
* currently editing the profile!
|
||||
*/
|
||||
|
||||
if ( ! function_exists( 'fictioneer_admin_profile_author' ) ) {
|
||||
function fictioneer_admin_profile_author( $profile_user ) {
|
||||
// Setup
|
||||
$is_owner = $profile_user->ID === get_current_user_id();
|
||||
$profile_user_is_author = fictioneer_is_author( $profile_user->ID );
|
||||
$editing_user_is_admin = fictioneer_is_admin( get_current_user_id() );
|
||||
function fictioneer_admin_profile_author( $profile_user ) {
|
||||
// Setup
|
||||
$is_owner = $profile_user->ID === get_current_user_id();
|
||||
$profile_user_is_author = fictioneer_is_author( $profile_user->ID );
|
||||
$editing_user_is_admin = fictioneer_is_admin( get_current_user_id() );
|
||||
|
||||
// Abort conditions...
|
||||
if ( ! $profile_user_is_author ) return;
|
||||
if ( ! $is_owner && ! $editing_user_is_admin ) return;
|
||||
// Abort conditions...
|
||||
if ( ! $profile_user_is_author ) return;
|
||||
if ( ! $is_owner && ! $editing_user_is_admin ) return;
|
||||
|
||||
// Has pages?
|
||||
$profile_user_has_pages = get_pages(
|
||||
array(
|
||||
'authors' => $profile_user->ID,
|
||||
'number' => 1
|
||||
)
|
||||
);
|
||||
// Has pages?
|
||||
$profile_user_has_pages = get_pages(
|
||||
array(
|
||||
'authors' => $profile_user->ID,
|
||||
'number' => 1
|
||||
)
|
||||
);
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-author-page-wrap">
|
||||
<th><label for="fictioneer_author_page"><?php _e( 'Author Page', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
<?php if ( $profile_user_has_pages ) : ?>
|
||||
<?php
|
||||
wp_dropdown_pages(
|
||||
array(
|
||||
'name' => 'fictioneer_author_page',
|
||||
'id' => 'fictioneer_author_page',
|
||||
'option_none_value' => __( 'None', 'fictioneer' ),
|
||||
'show_option_no_change' => __( 'None', 'fictioneer' ),
|
||||
'selected' => get_the_author_meta( 'fictioneer_author_page', $profile_user->ID ),
|
||||
'authors' => $profile_user->ID
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?php else : ?>
|
||||
<select disabled>
|
||||
<option value="-1"><?php _e( 'You have no published pages yet.', 'fictioneer' ); ?></option>
|
||||
</select>
|
||||
<?php endif; ?>
|
||||
<p class="description"><?php _e( 'Rendered inside your public author profile. This will override your biographical info.', 'fictioneer' ) ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="user-support-message-wrap">
|
||||
<th><label for="fictioneer_support_message"><?php _e( 'Support Message', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
<input name="fictioneer_support_message" type="text" id="fictioneer_support_message" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_support_message', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Rendered at the bottom of your chapters. This will override "You can support the author on".', 'fictioneer' ) ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="user-support-links-wrap">
|
||||
<th><?php _e( 'Support Links', 'fictioneer' ) ?></th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<input name="fictioneer_user_patreon_link" type="text" id="fictioneer_user_patreon_link" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_user_patreon_link', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Patreon link', 'fictioneer' ) ?></p>
|
||||
<br>
|
||||
<input name="fictioneer_user_kofi_link" type="text" id="fictioneer_user_kofi_link" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_user_kofi_link', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Ko-Fi link', 'fictioneer' ) ?></p>
|
||||
<br>
|
||||
<input name="fictioneer_user_subscribestar_link" type="text" id="fictioneer_user_subscribestar_link" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_user_subscribestar_link', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'SubscribeStar link', 'fictioneer' ) ?></p>
|
||||
<br>
|
||||
<input name="fictioneer_user_paypal_link" type="text" id="fictioneer_user_paypal_link" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_user_paypal_link', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'PayPal link', 'fictioneer' ) ?></p>
|
||||
<br>
|
||||
<input name="fictioneer_user_donation_link" type="text" id="fictioneer_user_donation_link" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_user_donation_link', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Generic donation link', 'fictioneer' ) ?></p>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-author-page-wrap">
|
||||
<th><label for="fictioneer_author_page"><?php _e( 'Author Page', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
<?php if ( $profile_user_has_pages ) : ?>
|
||||
<?php
|
||||
wp_dropdown_pages(
|
||||
array(
|
||||
'name' => 'fictioneer_author_page',
|
||||
'id' => 'fictioneer_author_page',
|
||||
'option_none_value' => __( 'None', 'fictioneer' ),
|
||||
'show_option_no_change' => __( 'None', 'fictioneer' ),
|
||||
'selected' => get_the_author_meta( 'fictioneer_author_page', $profile_user->ID ),
|
||||
'authors' => $profile_user->ID
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?php else : ?>
|
||||
<select disabled>
|
||||
<option value="-1"><?php _e( 'You have no published pages yet.', 'fictioneer' ); ?></option>
|
||||
</select>
|
||||
<?php endif; ?>
|
||||
<p class="description"><?php _e( 'Rendered inside your public author profile. This will override your biographical info.', 'fictioneer' ) ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="user-support-message-wrap">
|
||||
<th><label for="fictioneer_support_message"><?php _e( 'Support Message', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
<input name="fictioneer_support_message" type="text" id="fictioneer_support_message" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_support_message', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Rendered at the bottom of your chapters. This will override "You can support the author on".', 'fictioneer' ) ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="user-support-links-wrap">
|
||||
<th><?php _e( 'Support Links', 'fictioneer' ) ?></th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<input name="fictioneer_user_patreon_link" type="text" id="fictioneer_user_patreon_link" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_user_patreon_link', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Patreon link', 'fictioneer' ) ?></p>
|
||||
<br>
|
||||
<input name="fictioneer_user_kofi_link" type="text" id="fictioneer_user_kofi_link" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_user_kofi_link', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Ko-Fi link', 'fictioneer' ) ?></p>
|
||||
<br>
|
||||
<input name="fictioneer_user_subscribestar_link" type="text" id="fictioneer_user_subscribestar_link" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_user_subscribestar_link', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'SubscribeStar link', 'fictioneer' ) ?></p>
|
||||
<br>
|
||||
<input name="fictioneer_user_paypal_link" type="text" id="fictioneer_user_paypal_link" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_user_paypal_link', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'PayPal link', 'fictioneer' ) ?></p>
|
||||
<br>
|
||||
<input name="fictioneer_user_donation_link" type="text" id="fictioneer_user_donation_link" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_user_donation_link', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Generic donation link', 'fictioneer' ) ?></p>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_profile_author', 20 );
|
||||
|
||||
@ -821,35 +817,33 @@ add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_profile_author',
|
||||
* currently editing the profile!
|
||||
*/
|
||||
|
||||
if ( ! function_exists( 'fictioneer_admin_profile_oauth' ) ) {
|
||||
function fictioneer_admin_profile_oauth( $profile_user ) {
|
||||
// Setup
|
||||
$editing_user_is_admin = fictioneer_is_admin( get_current_user_id() );
|
||||
function fictioneer_admin_profile_oauth( $profile_user ) {
|
||||
// Setup
|
||||
$editing_user_is_admin = fictioneer_is_admin( get_current_user_id() );
|
||||
|
||||
// Abort conditions...
|
||||
if ( ! $editing_user_is_admin || ! get_option( 'fictioneer_enable_oauth' ) ) return;
|
||||
// Abort conditions...
|
||||
if ( ! $editing_user_is_admin || ! get_option( 'fictioneer_enable_oauth' ) ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-oauth-connections-wrap">
|
||||
<th><?php _e( 'Account Bindings', 'fictioneer' ) ?></th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<input name="fictioneer_discord_id_hash" type="text" id="fictioneer_discord_id_hash" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_discord_id_hash', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Discord ID Hash', 'fictioneer' ) ?></p>
|
||||
<br>
|
||||
<input name="fictioneer_twitch_id_hash" type="text" id="fictioneer_twitch_id_hash" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_twitch_id_hash', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Twitch ID Hash', 'fictioneer' ) ?></p>
|
||||
<br>
|
||||
<input name="fictioneer_google_id_hash" type="text" id="fictioneer_google_id_hash" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_google_id_hash', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Google ID Hash', 'fictioneer' ) ?></p>
|
||||
<br>
|
||||
<input name="fictioneer_patreon_id_hash" type="text" id="fictioneer_patreon_id_hash" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_patreon_id_hash', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Patreon ID Hash', 'fictioneer' ) ?></p>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-oauth-connections-wrap">
|
||||
<th><?php _e( 'Account Bindings', 'fictioneer' ) ?></th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<input name="fictioneer_discord_id_hash" type="text" id="fictioneer_discord_id_hash" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_discord_id_hash', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Discord ID Hash', 'fictioneer' ) ?></p>
|
||||
<br>
|
||||
<input name="fictioneer_twitch_id_hash" type="text" id="fictioneer_twitch_id_hash" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_twitch_id_hash', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Twitch ID Hash', 'fictioneer' ) ?></p>
|
||||
<br>
|
||||
<input name="fictioneer_google_id_hash" type="text" id="fictioneer_google_id_hash" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_google_id_hash', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Google ID Hash', 'fictioneer' ) ?></p>
|
||||
<br>
|
||||
<input name="fictioneer_patreon_id_hash" type="text" id="fictioneer_patreon_id_hash" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_patreon_id_hash', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Patreon ID Hash', 'fictioneer' ) ?></p>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
|
||||
if ( FICTIONEER_SHOW_OAUTH_HASHES ) {
|
||||
@ -869,24 +863,22 @@ if ( FICTIONEER_SHOW_OAUTH_HASHES ) {
|
||||
* currently editing the profile!
|
||||
*/
|
||||
|
||||
if ( ! function_exists( 'fictioneer_admin_profile_badge' ) ) {
|
||||
function fictioneer_admin_profile_badge( $profile_user ) {
|
||||
// Setup
|
||||
$editing_user_is_admin = fictioneer_is_admin( get_current_user_id() );
|
||||
function fictioneer_admin_profile_badge( $profile_user ) {
|
||||
// Setup
|
||||
$editing_user_is_admin = fictioneer_is_admin( get_current_user_id() );
|
||||
|
||||
// Abort conditions...
|
||||
if ( ! $editing_user_is_admin ) return;
|
||||
// Abort conditions...
|
||||
if ( ! $editing_user_is_admin ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-badge-override-wrap">
|
||||
<th><label for="fictioneer_badge_override"><?php _e( 'Badge Override', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
<input name="fictioneer_badge_override" type="text" id="fictioneer_badge_override" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_badge_override', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Override the user’s badge.', 'fictioneer' ) ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-badge-override-wrap">
|
||||
<th><label for="fictioneer_badge_override"><?php _e( 'Badge Override', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
<input name="fictioneer_badge_override" type="text" id="fictioneer_badge_override" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_badge_override', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'Override the user’s badge.', 'fictioneer' ) ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_profile_badge', 40 );
|
||||
|
||||
@ -903,96 +895,23 @@ add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_profile_badge',
|
||||
* currently editing the profile!
|
||||
*/
|
||||
|
||||
if ( ! function_exists( 'fictioneer_admin_profile_external_avatar' ) ) {
|
||||
function fictioneer_admin_profile_external_avatar( $profile_user ) {
|
||||
// Setup
|
||||
$editing_user_is_admin = fictioneer_is_admin( get_current_user_id() );
|
||||
function fictioneer_admin_profile_external_avatar( $profile_user ) {
|
||||
// Setup
|
||||
$editing_user_is_admin = fictioneer_is_admin( get_current_user_id() );
|
||||
|
||||
// Abort conditions...
|
||||
if ( ! $editing_user_is_admin ) return;
|
||||
// Abort conditions...
|
||||
if ( ! $editing_user_is_admin ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-external-avatar-wrap">
|
||||
<th><label for="fictioneer_external_avatar_url"><?php _e( 'External Avatar URL', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
<input name="fictioneer_external_avatar_url" type="text" id="fictioneer_external_avatar_url" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_external_avatar_url', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'There is no guarantee this URL remains valid!', 'fictioneer' ) ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-external-avatar-wrap">
|
||||
<th><label for="fictioneer_external_avatar_url"><?php _e( 'External Avatar URL', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
<input name="fictioneer_external_avatar_url" type="text" id="fictioneer_external_avatar_url" value="<?php echo esc_attr( get_the_author_meta( 'fictioneer_external_avatar_url', $profile_user->ID ) ); ?>" class="regular-text">
|
||||
<p class="description"><?php _e( 'There is no guarantee this URL remains valid!', 'fictioneer' ) ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_profile_external_avatar', 50 );
|
||||
|
||||
// =============================================================================
|
||||
// SHOW PATREON TIERS
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Adds HTML for the Patreon tiers section to the wp-admin user profile
|
||||
*
|
||||
* DISABLED!
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $profile_user The profile user object. Not necessarily the one
|
||||
* currently editing the profile!
|
||||
*/
|
||||
|
||||
if ( ! function_exists( 'fictioneer_admin_profile_patreon_tiers' ) ) {
|
||||
function fictioneer_admin_profile_patreon_tiers( $profile_user ) {
|
||||
// Setup
|
||||
$editing_user_is_admin = fictioneer_is_admin( get_current_user_id() );
|
||||
|
||||
// Abort conditions...
|
||||
if ( ! $editing_user_is_admin ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-patreon-tiers-wrap">
|
||||
<th><label for="fictioneer_patreon_tiers"><?php _e( 'Patreon Tiers', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
<input name="fictioneer_patreon_tiers" type="text" id="fictioneer_patreon_tiers" value="<?php echo esc_attr( json_encode( get_the_author_meta( 'fictioneer_patreon_tiers', $profile_user->ID ) ) ); ?>" class="regular-text" readonly>
|
||||
<p class="description"><?php _e( 'Patreon tiers for the linked Patreon client. Valid for two weeks after last login.', 'fictioneer' ) ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
}
|
||||
// add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_profile_patreon_tiers', 60 );
|
||||
|
||||
// =============================================================================
|
||||
// SHOW BOOKMARKS SECTION
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Adds HTML for the bookmarks section to the wp-admin user profile
|
||||
*
|
||||
* DISABLED!
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $profile_user The profile user object. Not necessarily the one
|
||||
* currently editing the profile!
|
||||
*/
|
||||
|
||||
if ( ! function_exists( 'fictioneer_admin_profile_bookmarks' ) ) {
|
||||
function fictioneer_admin_profile_bookmarks( $profile_user ) {
|
||||
// Setup
|
||||
$editing_user_is_admin = fictioneer_is_admin( get_current_user_id() );
|
||||
|
||||
// Abort conditions...
|
||||
if ( ! $editing_user_is_admin ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-bookmarks-wrap">
|
||||
<th><label for="user_bookmarks"><?php _e( 'Bookmarks JSON', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
<textarea name="user_bookmarks" id="user_bookmarks" rows="12" cols="30" style="font-family: monospace; font-size: 12px; word-break: break-all;" disabled><?php echo esc_attr( get_the_author_meta( 'fictioneer_bookmarks', $profile_user->ID ) ); ?></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
}
|
||||
// add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_profile_bookmarks', 70 );
|
||||
|
||||
?>
|
||||
|
@ -4,43 +4,41 @@
|
||||
// AVATAR FALLBACK
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_avatar_fallback' ) ) {
|
||||
/**
|
||||
* Add fallback inline script to avatars
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param string $avatar HTML for the avatar.
|
||||
* @param string $id_or_email ID or email of the user.
|
||||
*
|
||||
* @return string HTML with fallback script added.
|
||||
*/
|
||||
/**
|
||||
* Add fallback inline script to avatars
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param string $avatar HTML for the avatar.
|
||||
* @param string $id_or_email ID or email of the user.
|
||||
*
|
||||
* @return string HTML with fallback script added.
|
||||
*/
|
||||
|
||||
function fictioneer_avatar_fallback( $avatar, $id_or_email ) {
|
||||
$transient = get_transient( 'fictioneer_default_avatar' );
|
||||
function fictioneer_avatar_fallback( $avatar, $id_or_email ) {
|
||||
$transient = get_transient( 'fictioneer_default_avatar' );
|
||||
|
||||
// Check Transient
|
||||
if (
|
||||
empty( $transient ) ||
|
||||
! is_array( $transient ) ||
|
||||
$transient['timestamp'] + DAY_IN_SECONDS < time()
|
||||
) {
|
||||
$default_url = get_avatar_url( 'nonexistentemail@example.com' );
|
||||
// Check Transient
|
||||
if (
|
||||
empty( $transient ) ||
|
||||
! is_array( $transient ) ||
|
||||
$transient['timestamp'] + DAY_IN_SECONDS < time()
|
||||
) {
|
||||
$default_url = get_avatar_url( 'nonexistentemail@example.com' );
|
||||
|
||||
$transient = array(
|
||||
'url' => $default_url,
|
||||
'timestamp' => time()
|
||||
);
|
||||
$transient = array(
|
||||
'url' => $default_url,
|
||||
'timestamp' => time()
|
||||
);
|
||||
|
||||
set_transient( 'fictioneer_default_avatar', $transient );
|
||||
} else {
|
||||
$default_url = $transient['url'];
|
||||
}
|
||||
|
||||
return str_replace( '<img', '<img onerror="this.src=\'' . $default_url . '\';this.srcset=\'\';this.onerror=\'\';"', $avatar );
|
||||
set_transient( 'fictioneer_default_avatar', $transient );
|
||||
} else {
|
||||
$default_url = $transient['url'];
|
||||
}
|
||||
|
||||
return str_replace( '<img', '<img onerror="this.src=\'' . $default_url . '\';this.srcset=\'\';this.onerror=\'\';"', $avatar );
|
||||
}
|
||||
add_filter( 'get_avatar' , 'fictioneer_avatar_fallback' , 1 , 2 );
|
||||
add_filter( 'get_avatar', 'fictioneer_avatar_fallback', 1, 2 );
|
||||
|
||||
// =============================================================================
|
||||
// GET CUSTOM AVATAR URL
|
||||
@ -75,75 +73,71 @@ if ( ! function_exists( 'fictioneer_get_custom_avatar_url' ) ) {
|
||||
// GET CUSTOM AVATAR URL
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_get_avatar_url' ) ) {
|
||||
/**
|
||||
* Filter the avatar URL
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param string $url The default URL by WordPress.
|
||||
* @param int|string $id_or_email User ID or email address.
|
||||
* @param WP_User $args Additional arguments.
|
||||
*
|
||||
* @return string The avatar URL.
|
||||
*/
|
||||
/**
|
||||
* Filter the avatar URL
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param string $url The default URL by WordPress.
|
||||
* @param int|string $id_or_email User ID or email address.
|
||||
* @param WP_User $args Additional arguments.
|
||||
*
|
||||
* @return string The avatar URL.
|
||||
*/
|
||||
|
||||
function fictioneer_get_avatar_url( $url, $id_or_email, $args ) {
|
||||
// Abort conditions...
|
||||
if ( $args['force_default'] ?? false ) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
// Setup
|
||||
$user = fictioneer_get_user_by_id_or_email( $id_or_email );
|
||||
$custom_avatar = fictioneer_get_custom_avatar_url( $user );
|
||||
|
||||
// Check user and permissions
|
||||
if ( $user ) {
|
||||
$user_disabled = $user->fictioneer_disable_avatar;
|
||||
$admin_disabled = $user->fictioneer_admin_disable_avatar;
|
||||
|
||||
if ( $user_disabled || $admin_disabled ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Return custom avatar if set
|
||||
if ( ! empty( $custom_avatar ) ) {
|
||||
return $custom_avatar;
|
||||
}
|
||||
|
||||
// Return default avatar
|
||||
function fictioneer_get_avatar_url( $url, $id_or_email, $args ) {
|
||||
// Abort conditions...
|
||||
if ( $args['force_default'] ?? false ) {
|
||||
return $url;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Setup
|
||||
$user = fictioneer_get_user_by_id_or_email( $id_or_email );
|
||||
$custom_avatar = fictioneer_get_custom_avatar_url( $user );
|
||||
|
||||
// Check user and permissions
|
||||
if ( $user ) {
|
||||
$user_disabled = $user->fictioneer_disable_avatar;
|
||||
$admin_disabled = $user->fictioneer_admin_disable_avatar;
|
||||
|
||||
if ( $user_disabled || $admin_disabled ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Return custom avatar if set
|
||||
if ( ! empty( $custom_avatar ) ) {
|
||||
return $custom_avatar;
|
||||
}
|
||||
|
||||
// Return default avatar
|
||||
return $url;
|
||||
};
|
||||
add_filter( 'get_avatar_url', 'fictioneer_get_avatar_url', 10, 3 );
|
||||
|
||||
// =============================================================================
|
||||
// GET USER AVATAR URL - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_get_avatar' ) ) {
|
||||
/**
|
||||
* Get user avatar URL via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
/**
|
||||
* Get user avatar URL via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_get_avatar() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
function fictioneer_ajax_get_avatar() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
|
||||
if ( ! $user ) {
|
||||
wp_send_json_error( array( 'error' => __( 'Request did not pass validation.', 'fictioneer' ) ) );
|
||||
}
|
||||
|
||||
// Response
|
||||
wp_send_json_success( array( 'url' => get_avatar_url( $user->ID ) ) );
|
||||
if ( ! $user ) {
|
||||
wp_send_json_error( array( 'error' => __( 'Request did not pass validation.', 'fictioneer' ) ) );
|
||||
}
|
||||
|
||||
// Response
|
||||
wp_send_json_success( array( 'url' => get_avatar_url( $user->ID ) ) );
|
||||
}
|
||||
add_action( 'wp_ajax_fictioneer_ajax_get_avatar', 'fictioneer_ajax_get_avatar' );
|
||||
|
||||
|
@ -4,28 +4,26 @@
|
||||
// GET BOOKMARKS FOR USERS - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_get_bookmarks' ) ) {
|
||||
/**
|
||||
* Get an user's bookmarks via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
/**
|
||||
* Get an user's bookmarks via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_get_bookmarks() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_get_bookmarks() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
// Look for saved bookmarks on user...
|
||||
$bookmarks = get_user_meta( $user->ID, 'fictioneer_bookmarks', true );
|
||||
$bookmarks = $bookmarks ? $bookmarks : '{}';
|
||||
// Look for saved bookmarks on user...
|
||||
$bookmarks = get_user_meta( $user->ID, 'fictioneer_bookmarks', true );
|
||||
$bookmarks = $bookmarks ? $bookmarks : '{}';
|
||||
|
||||
// Response
|
||||
if ( $bookmarks ) wp_send_json_success( ['bookmarks' => $bookmarks] );
|
||||
}
|
||||
// Response
|
||||
if ( $bookmarks ) wp_send_json_success( ['bookmarks' => $bookmarks] );
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_bookmarks' ) ) {
|
||||
@ -36,52 +34,50 @@ if ( get_option( 'fictioneer_enable_bookmarks' ) ) {
|
||||
// SAVE BOOKMARKS FOR USERS - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_save_bookmarks' ) ) {
|
||||
/**
|
||||
* Save bookmarks JSON for user via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
/**
|
||||
* Save bookmarks JSON for user via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_save_bookmarks() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_save_bookmarks() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
if ( empty( $_POST['bookmarks'] ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Missing arguments.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Valid?
|
||||
$bookmarks = sanitize_text_field( $_POST['bookmarks'] );
|
||||
|
||||
if ( $bookmarks && fictioneer_is_valid_json( stripslashes( $bookmarks ) ) ) {
|
||||
// Inspect
|
||||
$decoded = json_decode( stripslashes( $bookmarks ), true );
|
||||
|
||||
if (
|
||||
! $decoded ||
|
||||
! isset( $decoded['data'] ) ||
|
||||
! isset( $decoded['lastLoaded'] ) ||
|
||||
count( $decoded ) != 2
|
||||
) {
|
||||
wp_send_json_error( ['error' => __( 'Invalid JSON.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Update and response
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_bookmarks', $bookmarks ) ) {
|
||||
wp_send_json_success();
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Bookmarks could not be updated', 'fictioneer' )] );
|
||||
}
|
||||
}
|
||||
|
||||
// Something went wrong if we end up here...
|
||||
wp_send_json_error( ['error' => __( 'Not a valid JSON string.', 'fictioneer' )] );
|
||||
if ( empty( $_POST['bookmarks'] ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Missing arguments.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Valid?
|
||||
$bookmarks = sanitize_text_field( $_POST['bookmarks'] );
|
||||
|
||||
if ( $bookmarks && fictioneer_is_valid_json( stripslashes( $bookmarks ) ) ) {
|
||||
// Inspect
|
||||
$decoded = json_decode( stripslashes( $bookmarks ), true );
|
||||
|
||||
if (
|
||||
! $decoded ||
|
||||
! isset( $decoded['data'] ) ||
|
||||
! isset( $decoded['lastLoaded'] ) ||
|
||||
count( $decoded ) != 2
|
||||
) {
|
||||
wp_send_json_error( ['error' => __( 'Invalid JSON.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Update and response
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_bookmarks', $bookmarks ) ) {
|
||||
wp_send_json_success();
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Bookmarks could not be updated', 'fictioneer' )] );
|
||||
}
|
||||
}
|
||||
|
||||
// Something went wrong if we end up here...
|
||||
wp_send_json_error( ['error' => __( 'Not a valid JSON string.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_bookmarks' ) ) {
|
||||
|
@ -102,29 +102,27 @@ if ( ! function_exists( 'fictioneer_count_chapter_checkmarks' ) ) {
|
||||
// GET CHECKMARKS - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_get_checkmarks' ) ) {
|
||||
/**
|
||||
* Sends the user's Checkmarks as JSON via Ajax
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
* @see fictioneer_load_checkmarks()
|
||||
*/
|
||||
/**
|
||||
* Sends the user's Checkmarks as JSON via Ajax
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
* @see fictioneer_load_checkmarks()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_get_checkmarks() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_get_checkmarks() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
// Prepare Checkmarks
|
||||
$checkmarks = fictioneer_load_checkmarks( $user );
|
||||
$checkmarks['timestamp'] = time() * 1000; // Compatible with Date.now() in JavaScript
|
||||
// Prepare Checkmarks
|
||||
$checkmarks = fictioneer_load_checkmarks( $user );
|
||||
$checkmarks['timestamp'] = time() * 1000; // Compatible with Date.now() in JavaScript
|
||||
|
||||
// Response
|
||||
wp_send_json_success( ['checkmarks' => json_encode( $checkmarks )] );
|
||||
}
|
||||
// Response
|
||||
wp_send_json_success( ['checkmarks' => json_encode( $checkmarks )] );
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_checkmarks' ) ) {
|
||||
@ -135,69 +133,67 @@ if ( get_option( 'fictioneer_enable_checkmarks' ) ) {
|
||||
// SET CHECKMARKS - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_set_checkmark' ) ) {
|
||||
/**
|
||||
* Set Checkmarks for a story via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
* @see fictioneer_validate_id()
|
||||
* @see fictioneer_get_story_data()
|
||||
* @see fictioneer_load_checkmarks()
|
||||
*/
|
||||
/**
|
||||
* Set Checkmarks for a story via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
* @see fictioneer_validate_id()
|
||||
* @see fictioneer_get_story_data()
|
||||
* @see fictioneer_load_checkmarks()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_set_checkmark() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_set_checkmark() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
if ( empty( $_POST['story_id'] ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Missing arguments.', 'fictioneer' )] );
|
||||
}
|
||||
if ( empty( $_POST['story_id'] ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Missing arguments.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
$story_id = fictioneer_validate_id( $_POST['story_id'], 'fcn_story' );
|
||||
$story_id = fictioneer_validate_id( $_POST['story_id'], 'fcn_story' );
|
||||
|
||||
if ( ! $story_id ) {
|
||||
wp_send_json_error( ['error' => __( 'Invalid story ID.', 'fictioneer' )] );
|
||||
}
|
||||
if ( ! $story_id ) {
|
||||
wp_send_json_error( ['error' => __( 'Invalid story ID.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
$story_data = fictioneer_get_story_data( $story_id, false ); // Does not refresh comment count!
|
||||
$story_data = fictioneer_get_story_data( $story_id, false ); // Does not refresh comment count!
|
||||
|
||||
// Prepare update
|
||||
$update = isset( $_POST['update'] ) ? explode( ' ', sanitize_text_field( $_POST['update'] ) ) : [];
|
||||
$update_ids = [];
|
||||
// Prepare update
|
||||
$update = isset( $_POST['update'] ) ? explode( ' ', sanitize_text_field( $_POST['update'] ) ) : [];
|
||||
$update_ids = [];
|
||||
|
||||
// Check update...
|
||||
if ( in_array( $story_id, $update ) ) {
|
||||
// If story ID in update, add all chapters and mark story as read
|
||||
$update_ids = array_map( function ( $a ) { return absint( $a ); }, $story_data['chapter_ids'] );
|
||||
$update_ids[] = absint( $story_id );
|
||||
} else {
|
||||
// Check if chapter IDs are part of the story
|
||||
foreach ( $update as $chapter_id ) {
|
||||
$chapter_id = absint( $chapter_id );
|
||||
// Check update...
|
||||
if ( in_array( $story_id, $update ) ) {
|
||||
// If story ID in update, add all chapters and mark story as read
|
||||
$update_ids = array_map( function ( $a ) { return absint( $a ); }, $story_data['chapter_ids'] );
|
||||
$update_ids[] = absint( $story_id );
|
||||
} else {
|
||||
// Check if chapter IDs are part of the story
|
||||
foreach ( $update as $chapter_id ) {
|
||||
$chapter_id = absint( $chapter_id );
|
||||
|
||||
if ( in_array( $chapter_id, $story_data['chapter_ids'] ) ) {
|
||||
$update_ids[] = $chapter_id;
|
||||
}
|
||||
if ( in_array( $chapter_id, $story_data['chapter_ids'] ) ) {
|
||||
$update_ids[] = $chapter_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare Checkmarks
|
||||
$checkmarks = fictioneer_load_checkmarks( $user );
|
||||
$checkmarks['updated'] = time() * 1000; // Compatible with Date.now() in JavaScript
|
||||
// Prepare Checkmarks
|
||||
$checkmarks = fictioneer_load_checkmarks( $user );
|
||||
$checkmarks['updated'] = time() * 1000; // Compatible with Date.now() in JavaScript
|
||||
|
||||
// Update checkmarks
|
||||
$checkmarks['data'][ $story_id ] = empty( $_POST['update'] ) ? [] : $update_ids;
|
||||
// Update checkmarks
|
||||
$checkmarks['data'][ $story_id ] = empty( $_POST['update'] ) ? [] : $update_ids;
|
||||
|
||||
// Update user
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_user_checkmarks', $checkmarks ) ) {
|
||||
wp_send_json_success();
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Checkmarks could not be updated.', 'fictioneer' )] );
|
||||
}
|
||||
// Update user
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_user_checkmarks', $checkmarks ) ) {
|
||||
wp_send_json_success();
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Checkmarks could not be updated.', 'fictioneer' )] );
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,27 +205,25 @@ if ( get_option( 'fictioneer_enable_checkmarks' ) ) {
|
||||
// CLEAR MY CHECKMARKS - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_clear_my_checkmarks' ) ) {
|
||||
/**
|
||||
* Clears Checkmarks for a story via AJAX
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
/**
|
||||
* Clears Checkmarks for a story via AJAX
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_clear_my_checkmarks() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user( 'nonce', 'fictioneer_clear_checkmarks' );
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_clear_my_checkmarks() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user( 'nonce', 'fictioneer_clear_checkmarks' );
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
// Update user
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_user_checkmarks', [] ) ) {
|
||||
wp_send_json_success( ['success' => __( 'Data has been cleared.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Checkmarks could not be updated.', 'fictioneer' )] );
|
||||
}
|
||||
// Update user
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_user_checkmarks', [] ) ) {
|
||||
wp_send_json_success( ['success' => __( 'Data has been cleared.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Checkmarks could not be updated.', 'fictioneer' )] );
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,83 +235,81 @@ if ( get_option( 'fictioneer_enable_checkmarks' ) ) {
|
||||
// GET FINISHED LIST - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_get_finished_list' ) ) {
|
||||
function fictioneer_ajax_get_finished_list() {
|
||||
// Validations
|
||||
$user = wp_get_current_user();
|
||||
function fictioneer_ajax_get_finished_list() {
|
||||
// Validations
|
||||
$user = wp_get_current_user();
|
||||
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Not logged in.', 'fictioneer' )] );
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Not logged in.', 'fictioneer' )] );
|
||||
|
||||
if ( ! check_ajax_referer( 'fictioneer_nonce', 'nonce', false ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Setup
|
||||
$checkmarks = fictioneer_load_checkmarks( $user );
|
||||
$post_ids = fictioneer_get_finished_checkmarks( $checkmarks );
|
||||
$page = isset( $_GET['page'] ) ? absint( $_GET['page'] ) : 1;
|
||||
$order = isset( $_GET['order'] ) ? strtolower( $_GET['order'] ) : 'desc';
|
||||
|
||||
// Sanitize
|
||||
$order = in_array( $order, ['desc', 'asc'] ) ? $order : 'desc';
|
||||
|
||||
// Query
|
||||
$list_items = fictioneer_get_card_list(
|
||||
'story',
|
||||
array(
|
||||
'post__in' => $post_ids,
|
||||
'paged' => $page,
|
||||
'order' => $order
|
||||
),
|
||||
__( 'You have not marked any stories as finished.', 'fictioneer' ),
|
||||
['show_latest' => true]
|
||||
);
|
||||
|
||||
// Total number of pages
|
||||
$max_pages = $list_items['query']->max_num_pages ?? 1;
|
||||
|
||||
// Navigation (if any)
|
||||
$navigation = '';
|
||||
|
||||
if ( $max_pages > 1 ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<li class="pagination bookshelf-pagination">
|
||||
<?php
|
||||
for ( $i = 1; $i <= $max_pages; $i++ ) {
|
||||
if ( $i == $page ) {
|
||||
?><span class="page-numbers current" aria-current="page"><?php echo $i; ?></span><?php
|
||||
} else {
|
||||
?><button class="page-numbers" data-page="<?php echo $i; ?>"><?php echo $i; ?></button><?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
|
||||
// Get buffered navigation
|
||||
$navigation = ob_get_clean();
|
||||
} elseif ( $page > 1 ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<li class="pagination bookshelf-pagination">
|
||||
<button class="page-numbers" data-page="1"><?php _e( 'First Page', 'fictioneer' ); ?></button>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
|
||||
// Get buffered back button
|
||||
$navigation = ob_get_clean();
|
||||
}
|
||||
|
||||
// Send result
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'html' => $list_items['html'] . $navigation,
|
||||
'count' => count( $post_ids ),
|
||||
'maxPages' => $max_pages
|
||||
)
|
||||
);
|
||||
if ( ! check_ajax_referer( 'fictioneer_nonce', 'nonce', false ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Setup
|
||||
$checkmarks = fictioneer_load_checkmarks( $user );
|
||||
$post_ids = fictioneer_get_finished_checkmarks( $checkmarks );
|
||||
$page = isset( $_GET['page'] ) ? absint( $_GET['page'] ) : 1;
|
||||
$order = isset( $_GET['order'] ) ? strtolower( $_GET['order'] ) : 'desc';
|
||||
|
||||
// Sanitize
|
||||
$order = in_array( $order, ['desc', 'asc'] ) ? $order : 'desc';
|
||||
|
||||
// Query
|
||||
$list_items = fictioneer_get_card_list(
|
||||
'story',
|
||||
array(
|
||||
'post__in' => $post_ids,
|
||||
'paged' => $page,
|
||||
'order' => $order
|
||||
),
|
||||
__( 'You have not marked any stories as finished.', 'fictioneer' ),
|
||||
['show_latest' => true]
|
||||
);
|
||||
|
||||
// Total number of pages
|
||||
$max_pages = $list_items['query']->max_num_pages ?? 1;
|
||||
|
||||
// Navigation (if any)
|
||||
$navigation = '';
|
||||
|
||||
if ( $max_pages > 1 ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<li class="pagination bookshelf-pagination">
|
||||
<?php
|
||||
for ( $i = 1; $i <= $max_pages; $i++ ) {
|
||||
if ( $i == $page ) {
|
||||
?><span class="page-numbers current" aria-current="page"><?php echo $i; ?></span><?php
|
||||
} else {
|
||||
?><button class="page-numbers" data-page="<?php echo $i; ?>"><?php echo $i; ?></button><?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
|
||||
// Get buffered navigation
|
||||
$navigation = ob_get_clean();
|
||||
} elseif ( $page > 1 ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<li class="pagination bookshelf-pagination">
|
||||
<button class="page-numbers" data-page="1"><?php _e( 'First Page', 'fictioneer' ); ?></button>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
|
||||
// Get buffered back button
|
||||
$navigation = ob_get_clean();
|
||||
}
|
||||
|
||||
// Send result
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'html' => $list_items['html'] . $navigation,
|
||||
'count' => count( $post_ids ),
|
||||
'maxPages' => $max_pages
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_checkmarks' ) ) {
|
||||
|
@ -48,42 +48,40 @@ if ( ! function_exists( 'fictioneer_load_follows' ) ) {
|
||||
// GET FOLLOWS - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_get_follows' ) ) {
|
||||
/**
|
||||
* Sends the user's Follows as JSON via Ajax
|
||||
*
|
||||
* @since Fictioneer 4.3
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
/**
|
||||
* Sends the user's Follows as JSON via Ajax
|
||||
*
|
||||
* @since Fictioneer 4.3
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_get_follows() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_get_follows() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
// Prepare Follows
|
||||
$user_follows = fictioneer_load_follows( $user );
|
||||
$user_follows['timestamp'] = time() * 1000; // Compatible with Date.now() in JavaScript
|
||||
$latest = 0;
|
||||
$new = false;
|
||||
// Prepare Follows
|
||||
$user_follows = fictioneer_load_follows( $user );
|
||||
$user_follows['timestamp'] = time() * 1000; // Compatible with Date.now() in JavaScript
|
||||
$latest = 0;
|
||||
$new = false;
|
||||
|
||||
// New notifications?
|
||||
if ( count( $user_follows['data'] ) > 0 ) {
|
||||
$latest = fictioneer_query_followed_chapters(
|
||||
array_keys( $user_follows['data'] ),
|
||||
wp_date( 'c', $user_follows['seen'] / 1000 )
|
||||
);
|
||||
// New notifications?
|
||||
if ( count( $user_follows['data'] ) > 0 ) {
|
||||
$latest = fictioneer_query_followed_chapters(
|
||||
array_keys( $user_follows['data'] ),
|
||||
wp_date( 'c', $user_follows['seen'] / 1000 )
|
||||
);
|
||||
|
||||
if ( $latest ) $new = count( $latest );
|
||||
}
|
||||
|
||||
$user_follows['new'] = $new;
|
||||
|
||||
// Response
|
||||
wp_send_json_success( ['follows' => json_encode( $user_follows )] );
|
||||
if ( $latest ) $new = count( $latest );
|
||||
}
|
||||
|
||||
$user_follows['new'] = $new;
|
||||
|
||||
// Response
|
||||
wp_send_json_success( ['follows' => json_encode( $user_follows )] );
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_follows' ) ) {
|
||||
@ -94,61 +92,59 @@ if ( get_option( 'fictioneer_enable_follows' ) ) {
|
||||
// TOGGLE FOLLOW - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_toggle_follow' ) ) {
|
||||
/**
|
||||
* Toggle Follow for a story via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.3
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
* @see fictioneer_load_follows()
|
||||
*/
|
||||
/**
|
||||
* Toggle Follow for a story via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.3
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
* @see fictioneer_load_follows()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_toggle_follow() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_toggle_follow() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
if ( empty( $_POST['story_id'] ) || empty( $_POST['set'] ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Missing arguments.', 'fictioneer' )] );
|
||||
}
|
||||
if ( empty( $_POST['story_id'] ) || empty( $_POST['set'] ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Missing arguments.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Valid story ID?
|
||||
$story_id = fictioneer_validate_id( $_POST['story_id'], 'fcn_story' );
|
||||
if ( ! $story_id ) {
|
||||
wp_send_json_error( ['error' => __( 'Invalid story ID.', 'fictioneer' )] );
|
||||
}
|
||||
// Valid story ID?
|
||||
$story_id = fictioneer_validate_id( $_POST['story_id'], 'fcn_story' );
|
||||
if ( ! $story_id ) {
|
||||
wp_send_json_error( ['error' => __( 'Invalid story ID.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Set or unset?
|
||||
$set = $_POST['set'] == 'true';
|
||||
// Set or unset?
|
||||
$set = $_POST['set'] == 'true';
|
||||
|
||||
// Prepare Follows
|
||||
$timestamp = time() * 1000; // Compatible with Date.now() in JavaScript
|
||||
$user_follows = fictioneer_load_follows( $user );
|
||||
$user_follows['updated'] = $timestamp;
|
||||
// Prepare Follows
|
||||
$timestamp = time() * 1000; // Compatible with Date.now() in JavaScript
|
||||
$user_follows = fictioneer_load_follows( $user );
|
||||
$user_follows['updated'] = $timestamp;
|
||||
|
||||
// Add/Remove story from Follows
|
||||
if ( ! array_key_exists( $story_id, $user_follows['data'] ) || $set ) {
|
||||
$item = array(
|
||||
'user_id' => $user->ID,
|
||||
'story_id' => $story_id,
|
||||
'timestamp' => $timestamp
|
||||
);
|
||||
// Add/Remove story from Follows
|
||||
if ( ! array_key_exists( $story_id, $user_follows['data'] ) || $set ) {
|
||||
$item = array(
|
||||
'user_id' => $user->ID,
|
||||
'story_id' => $story_id,
|
||||
'timestamp' => $timestamp
|
||||
);
|
||||
|
||||
$user_follows['data'][ $story_id ] = $item;
|
||||
} else {
|
||||
unset( $user_follows['data'][ $story_id ] );
|
||||
}
|
||||
$user_follows['data'][ $story_id ] = $item;
|
||||
} else {
|
||||
unset( $user_follows['data'][ $story_id ] );
|
||||
}
|
||||
|
||||
// Update database & response
|
||||
delete_user_meta( $user->ID, 'fictioneer_user_follows_cache' );
|
||||
// Update database & response
|
||||
delete_user_meta( $user->ID, 'fictioneer_user_follows_cache' );
|
||||
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_user_follows', $user_follows ) ) {
|
||||
wp_send_json_success();
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Follows could not be updated.', 'fictioneer' )] );
|
||||
}
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_user_follows', $user_follows ) ) {
|
||||
wp_send_json_success();
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Follows could not be updated.', 'fictioneer' )] );
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,28 +156,26 @@ if ( get_option( 'fictioneer_enable_follows' ) ) {
|
||||
// CLEAR MY FOLLOWS - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_clear_my_follows' ) ) {
|
||||
/**
|
||||
* Clears an user's Follows via AJAX
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
/**
|
||||
* Clears an user's Follows via AJAX
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_clear_my_follows() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user( 'nonce', 'fictioneer_clear_follows' );
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_clear_my_follows() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user( 'nonce', 'fictioneer_clear_follows' );
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
// Update user
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_user_follows', [] ) ) {
|
||||
update_user_meta( $user->ID, 'fictioneer_user_follows_cache', false );
|
||||
wp_send_json_success( ['success' => __( 'Data has been cleared.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Follows could not be cleared.', 'fictioneer' )] );
|
||||
}
|
||||
// Update user
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_user_follows', [] ) ) {
|
||||
update_user_meta( $user->ID, 'fictioneer_user_follows_cache', false );
|
||||
wp_send_json_success( ['success' => __( 'Data has been cleared.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Follows could not be cleared.', 'fictioneer' )] );
|
||||
}
|
||||
}
|
||||
|
||||
@ -193,44 +187,42 @@ if ( get_option( 'fictioneer_enable_follows' ) ) {
|
||||
// MARK FOLLOWS AS READ - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_mark_follows_read' ) ) {
|
||||
/**
|
||||
* Mark all Follows as read via AJAX
|
||||
*
|
||||
* Updates the 'seen' timestamp in the 'fictioneer_user_follows' meta data,
|
||||
* which is used to determine whether Follows are new. This will mark all
|
||||
* of them as read, you cannot mark single items in the list as read.
|
||||
*
|
||||
* @since Fictioneer 4.3
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
/**
|
||||
* Mark all Follows as read via AJAX
|
||||
*
|
||||
* Updates the 'seen' timestamp in the 'fictioneer_user_follows' meta data,
|
||||
* which is used to determine whether Follows are new. This will mark all
|
||||
* of them as read, you cannot mark single items in the list as read.
|
||||
*
|
||||
* @since Fictioneer 4.3
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_mark_follows_read() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_mark_follows_read() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
$user_follows = fictioneer_load_follows( $user );
|
||||
$user_follows = fictioneer_load_follows( $user );
|
||||
|
||||
if ( empty( $user_follows ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Follows are empty.', 'fictioneer' )] );
|
||||
}
|
||||
if ( empty( $user_follows ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Follows are empty.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Update 'seen' timestamp to now; compatible with Date.now() in JavaScript
|
||||
$user_follows['seen'] = time() * 1000;
|
||||
// Update 'seen' timestamp to now; compatible with Date.now() in JavaScript
|
||||
$user_follows['seen'] = time() * 1000;
|
||||
|
||||
// Update database
|
||||
update_user_meta( $user->ID, 'fictioneer_user_follows_cache', false );
|
||||
$result = update_user_meta( $user->ID, 'fictioneer_user_follows', $user_follows );
|
||||
// Update database
|
||||
update_user_meta( $user->ID, 'fictioneer_user_follows_cache', false );
|
||||
$result = update_user_meta( $user->ID, 'fictioneer_user_follows', $user_follows );
|
||||
|
||||
// Response
|
||||
if ( $result ) {
|
||||
wp_send_json_success();
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Follows could not be updated.', 'fictioneer' )] );
|
||||
}
|
||||
// Response
|
||||
if ( $result ) {
|
||||
wp_send_json_success();
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Follows could not be updated.', 'fictioneer' )] );
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,97 +289,95 @@ if ( ! function_exists( 'fictioneer_query_followed_chapters' ) ) {
|
||||
// GET FOLLOWS NOTIFICATIONS - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_get_follows_notifications' ) ) {
|
||||
/**
|
||||
* Sends the HTML for Follows notifications via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.3
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
/**
|
||||
* Sends the HTML for Follows notifications via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.3
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_get_follows_notifications() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error(
|
||||
array(
|
||||
'error' => __( 'Not logged in.', 'fictioneer' ),
|
||||
'html' => '<div class="follow-item"><div class="follow-wrapper"><div class="follow-placeholder truncate _1-1">' . __( 'Not logged in.', 'fictioneer' ) . '</div></div></div>'
|
||||
)
|
||||
);
|
||||
function fictioneer_ajax_get_follows_notifications() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error(
|
||||
array(
|
||||
'error' => __( 'Not logged in.', 'fictioneer' ),
|
||||
'html' => '<div class="follow-item"><div class="follow-wrapper"><div class="follow-placeholder truncate _1-1">' . __( 'Not logged in.', 'fictioneer' ) . '</div></div></div>'
|
||||
)
|
||||
);
|
||||
|
||||
// Follows
|
||||
$user_follows = fictioneer_load_follows( $user );
|
||||
// Follows
|
||||
$user_follows = fictioneer_load_follows( $user );
|
||||
|
||||
// Last story/chapter update on site
|
||||
$last_update = fictioneer_get_last_fiction_update();
|
||||
// Last story/chapter update on site
|
||||
$last_update = fictioneer_get_last_fiction_update();
|
||||
|
||||
// Check for cached HTML
|
||||
if ( ! empty( $last_update ) ) {
|
||||
$cache = get_user_meta( $user->ID, 'fictioneer_user_follows_cache', true );
|
||||
if ( ! empty( $cache ) && array_key_exists( $last_update, $cache ) ) {
|
||||
$html = $cache[ $last_update ] . '<!-- Cached on ' . $cache['timestamp'] . ' -->';
|
||||
wp_send_json_success( ['html' => $html] );
|
||||
}
|
||||
// Check for cached HTML
|
||||
if ( ! empty( $last_update ) ) {
|
||||
$cache = get_user_meta( $user->ID, 'fictioneer_user_follows_cache', true );
|
||||
if ( ! empty( $cache ) && array_key_exists( $last_update, $cache ) ) {
|
||||
$html = $cache[ $last_update ] . '<!-- Cached on ' . $cache['timestamp'] . ' -->';
|
||||
wp_send_json_success( ['html' => $html] );
|
||||
}
|
||||
}
|
||||
|
||||
// Chapters for notifications
|
||||
$chapters = count( $user_follows['data'] ) > 0 ? fictioneer_query_followed_chapters( array_keys( $user_follows['data'] ) ) : false;
|
||||
// Chapters for notifications
|
||||
$chapters = count( $user_follows['data'] ) > 0 ? fictioneer_query_followed_chapters( array_keys( $user_follows['data'] ) ) : false;
|
||||
|
||||
// Build notifications
|
||||
ob_start();
|
||||
// Build notifications
|
||||
ob_start();
|
||||
|
||||
if ( $chapters ) {
|
||||
foreach ( $chapters as $chapter ) {
|
||||
$date = get_the_date(
|
||||
sprintf(
|
||||
_x( '%1$s \a\t %2$s', 'Date in Follows update list.', 'fictioneer' ),
|
||||
get_option('date_format'),
|
||||
get_option('time_format')
|
||||
), $chapter->ID
|
||||
);
|
||||
$chapter_timestamp = get_post_timestamp( $chapter->ID ) * 1000; // Compatible with Date.now() in JavaScript
|
||||
$story_id = fictioneer_get_field( 'fictioneer_chapter_story', $chapter->ID );
|
||||
$new = $user_follows['seen'] < $chapter_timestamp ? '_new' : '';
|
||||
if ( $chapters ) {
|
||||
foreach ( $chapters as $chapter ) {
|
||||
$date = get_the_date(
|
||||
sprintf(
|
||||
_x( '%1$s \a\t %2$s', 'Date in Follows update list.', 'fictioneer' ),
|
||||
get_option('date_format'),
|
||||
get_option('time_format')
|
||||
), $chapter->ID
|
||||
);
|
||||
$chapter_timestamp = get_post_timestamp( $chapter->ID ) * 1000; // Compatible with Date.now() in JavaScript
|
||||
$story_id = fictioneer_get_field( 'fictioneer_chapter_story', $chapter->ID );
|
||||
$new = $user_follows['seen'] < $chapter_timestamp ? '_new' : '';
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<div class="follow-item <?php echo $new; ?>" data-chapter-id="<?php echo $chapter->ID; ?>" data-story-id="<?php echo $story_id; ?>" data-timestamp="<?php echo $chapter_timestamp; ?>">
|
||||
<div class="follow-wrapper">
|
||||
<div class="follow-title truncate _1-1">
|
||||
<a href="<?php echo get_the_permalink( $chapter->ID ); ?>"><?php echo fictioneer_get_safe_title( $chapter->ID ); ?></a>
|
||||
</div>
|
||||
<div class="follow-meta truncate _1-1"><?php echo $date ; ?> in <?php echo fictioneer_get_safe_title( $story_id ); ?></div>
|
||||
<div class="follow-marker">•</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
} else {
|
||||
// Start HTML ---> ?>
|
||||
<div class="follow-item">
|
||||
<div class="follow-item <?php echo $new; ?>" data-chapter-id="<?php echo $chapter->ID; ?>" data-story-id="<?php echo $story_id; ?>" data-timestamp="<?php echo $chapter_timestamp; ?>">
|
||||
<div class="follow-wrapper">
|
||||
<div class="follow-placeholder truncate _1-1"><?php _e( 'You are not following any stories.', 'fictioneer' ); ?></div>
|
||||
<div class="follow-title truncate _1-1">
|
||||
<a href="<?php echo get_the_permalink( $chapter->ID ); ?>"><?php echo fictioneer_get_safe_title( $chapter->ID ); ?></a>
|
||||
</div>
|
||||
<div class="follow-meta truncate _1-1"><?php echo $date ; ?> in <?php echo fictioneer_get_safe_title( $story_id ); ?></div>
|
||||
<div class="follow-marker">•</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
|
||||
$html = fictioneer_minify_html( ob_get_clean() );
|
||||
|
||||
// Cache for next time
|
||||
if ( ! empty( $last_update ) ) {
|
||||
update_user_meta(
|
||||
$user->ID,
|
||||
'fictioneer_user_follows_cache',
|
||||
array(
|
||||
$last_update => $html,
|
||||
'timestamp' => time() * 1000
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Return HTML
|
||||
wp_send_json_success( array( 'html' => $html ) );
|
||||
} else {
|
||||
// Start HTML ---> ?>
|
||||
<div class="follow-item">
|
||||
<div class="follow-wrapper">
|
||||
<div class="follow-placeholder truncate _1-1"><?php _e( 'You are not following any stories.', 'fictioneer' ); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
|
||||
$html = fictioneer_minify_html( ob_get_clean() );
|
||||
|
||||
// Cache for next time
|
||||
if ( ! empty( $last_update ) ) {
|
||||
update_user_meta(
|
||||
$user->ID,
|
||||
'fictioneer_user_follows_cache',
|
||||
array(
|
||||
$last_update => $html,
|
||||
'timestamp' => time() * 1000
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Return HTML
|
||||
wp_send_json_success( array( 'html' => $html ) );
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_follows' ) ) {
|
||||
@ -398,91 +388,89 @@ if ( get_option( 'fictioneer_enable_follows' ) ) {
|
||||
// GET FOLLOWS LIST - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_get_follows_list' ) ) {
|
||||
/**
|
||||
* Sends the HTML for Follows list via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.3
|
||||
*/
|
||||
/**
|
||||
* Sends the HTML for Follows list via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.3
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_get_follows_list() {
|
||||
// Validations
|
||||
$user = wp_get_current_user();
|
||||
function fictioneer_ajax_get_follows_list() {
|
||||
// Validations
|
||||
$user = wp_get_current_user();
|
||||
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Not logged in.', 'fictioneer' )] );
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Not logged in.', 'fictioneer' )] );
|
||||
|
||||
if ( ! check_ajax_referer( 'fictioneer_nonce', 'nonce', false ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Setup
|
||||
$follows = fictioneer_load_follows( $user );
|
||||
$post_ids = array_keys( $follows['data'] );
|
||||
$page = isset( $_GET['page'] ) ? absint( $_GET['page'] ) : 1;
|
||||
$order = isset( $_GET['order'] ) ? strtolower( $_GET['order'] ) : 'desc';
|
||||
|
||||
// Sanitize
|
||||
$order = in_array( $order, ['desc', 'asc'] ) ? $order : 'desc';
|
||||
|
||||
// Query
|
||||
$list_items = fictioneer_get_card_list(
|
||||
'story',
|
||||
array(
|
||||
'post__in' => $post_ids,
|
||||
'paged' => $page,
|
||||
'order' => $order
|
||||
),
|
||||
__( 'You are not following any stories.', 'fictioneer' ),
|
||||
array(
|
||||
'show_latest' => true
|
||||
)
|
||||
);
|
||||
|
||||
// Total number of pages
|
||||
$max_pages = $list_items['query']->max_num_pages ?? 1;
|
||||
|
||||
// Navigation (if any)
|
||||
$navigation = '';
|
||||
|
||||
if ( $max_pages > 1 ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<li class="pagination bookshelf-pagination">
|
||||
<?php
|
||||
for ( $i = 1; $i <= $max_pages; $i++ ) {
|
||||
if ( $i == $page ) {
|
||||
?><span class="page-numbers current" aria-current="page"><?php echo $i; ?></span><?php
|
||||
} else {
|
||||
?><button class="page-numbers" data-page="<?php echo $i; ?>"><?php echo $i; ?></button><?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
|
||||
// Get buffered navigation
|
||||
$navigation = ob_get_clean();
|
||||
} elseif ( $page > 1 ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<li class="pagination bookshelf-pagination">
|
||||
<button class="page-numbers" data-page="1"><?php _e( 'First Page', 'fictioneer' ); ?></button>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
|
||||
// Get buffered back button
|
||||
$navigation = ob_get_clean();
|
||||
}
|
||||
|
||||
// Send result
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'html' => fictioneer_minify_html( $list_items['html'] ) . $navigation,
|
||||
'count' => count( $post_ids ),
|
||||
'maxPages' => $max_pages
|
||||
)
|
||||
);
|
||||
if ( ! check_ajax_referer( 'fictioneer_nonce', 'nonce', false ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Setup
|
||||
$follows = fictioneer_load_follows( $user );
|
||||
$post_ids = array_keys( $follows['data'] );
|
||||
$page = isset( $_GET['page'] ) ? absint( $_GET['page'] ) : 1;
|
||||
$order = isset( $_GET['order'] ) ? strtolower( $_GET['order'] ) : 'desc';
|
||||
|
||||
// Sanitize
|
||||
$order = in_array( $order, ['desc', 'asc'] ) ? $order : 'desc';
|
||||
|
||||
// Query
|
||||
$list_items = fictioneer_get_card_list(
|
||||
'story',
|
||||
array(
|
||||
'post__in' => $post_ids,
|
||||
'paged' => $page,
|
||||
'order' => $order
|
||||
),
|
||||
__( 'You are not following any stories.', 'fictioneer' ),
|
||||
array(
|
||||
'show_latest' => true
|
||||
)
|
||||
);
|
||||
|
||||
// Total number of pages
|
||||
$max_pages = $list_items['query']->max_num_pages ?? 1;
|
||||
|
||||
// Navigation (if any)
|
||||
$navigation = '';
|
||||
|
||||
if ( $max_pages > 1 ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<li class="pagination bookshelf-pagination">
|
||||
<?php
|
||||
for ( $i = 1; $i <= $max_pages; $i++ ) {
|
||||
if ( $i == $page ) {
|
||||
?><span class="page-numbers current" aria-current="page"><?php echo $i; ?></span><?php
|
||||
} else {
|
||||
?><button class="page-numbers" data-page="<?php echo $i; ?>"><?php echo $i; ?></button><?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
|
||||
// Get buffered navigation
|
||||
$navigation = ob_get_clean();
|
||||
} elseif ( $page > 1 ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<li class="pagination bookshelf-pagination">
|
||||
<button class="page-numbers" data-page="1"><?php _e( 'First Page', 'fictioneer' ); ?></button>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
|
||||
// Get buffered back button
|
||||
$navigation = ob_get_clean();
|
||||
}
|
||||
|
||||
// Send result
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'html' => fictioneer_minify_html( $list_items['html'] ) . $navigation,
|
||||
'count' => count( $post_ids ),
|
||||
'maxPages' => $max_pages
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_follows' ) ) {
|
||||
|
@ -43,29 +43,27 @@ if ( ! function_exists( 'fictioneer_load_reminders' ) ) {
|
||||
// GET REMINDERS - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_get_reminders' ) ) {
|
||||
/**
|
||||
* Sends the user's Reminders as JSON via Ajax
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
* @see fictioneer_load_reminders()
|
||||
*/
|
||||
/**
|
||||
* Sends the user's Reminders as JSON via Ajax
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
* @see fictioneer_load_reminders()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_get_reminders() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_get_reminders() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
// Prepare Reminders
|
||||
$reminders = fictioneer_load_reminders( $user );
|
||||
$reminders['timestamp'] = time() * 1000; // Compatible with Date.now() in JavaScript
|
||||
// Prepare Reminders
|
||||
$reminders = fictioneer_load_reminders( $user );
|
||||
$reminders['timestamp'] = time() * 1000; // Compatible with Date.now() in JavaScript
|
||||
|
||||
// Response
|
||||
wp_send_json_success( ['reminders' => json_encode( $reminders )] );
|
||||
}
|
||||
// Response
|
||||
wp_send_json_success( ['reminders' => json_encode( $reminders )] );
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_reminders' ) ) {
|
||||
@ -76,57 +74,55 @@ if ( get_option( 'fictioneer_enable_reminders' ) ) {
|
||||
// TOGGLE REMINDER - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_toggle_reminder' ) ) {
|
||||
/**
|
||||
* Set Reminder for a story via AJAX
|
||||
*
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
/**
|
||||
* Set Reminder for a story via AJAX
|
||||
*
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_toggle_reminder() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_toggle_reminder() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
if ( empty( $_POST['story_id'] ) || empty( $_POST['set'] ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Missing arguments.', 'fictioneer' )] );
|
||||
}
|
||||
if ( empty( $_POST['story_id'] ) || empty( $_POST['set'] ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Missing arguments.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Valid story ID?
|
||||
$story_id = fictioneer_validate_id( $_POST['story_id'], 'fcn_story' );
|
||||
if ( ! $story_id ) wp_send_json_error( ['error' => __( 'Invalid story ID.', 'fictioneer' )] );
|
||||
// Valid story ID?
|
||||
$story_id = fictioneer_validate_id( $_POST['story_id'], 'fcn_story' );
|
||||
if ( ! $story_id ) wp_send_json_error( ['error' => __( 'Invalid story ID.', 'fictioneer' )] );
|
||||
|
||||
// Set or unset?
|
||||
$set = $_POST['set'] == 'true';
|
||||
// Set or unset?
|
||||
$set = $_POST['set'] == 'true';
|
||||
|
||||
// Prepare Reminders
|
||||
$timestamp = time() * 1000; // Compatible with Date.now() in JavaScript
|
||||
$user_reminders = fictioneer_load_reminders( $user );
|
||||
$user_reminders['updated'] = $timestamp;
|
||||
// Prepare Reminders
|
||||
$timestamp = time() * 1000; // Compatible with Date.now() in JavaScript
|
||||
$user_reminders = fictioneer_load_reminders( $user );
|
||||
$user_reminders['updated'] = $timestamp;
|
||||
|
||||
// Add/Remove story from Reminders
|
||||
if ( ! array_key_exists( $story_id, $user_reminders['data'] ) || $set ) {
|
||||
$item = array(
|
||||
'user_id' => $user->ID,
|
||||
'story_id' => $story_id,
|
||||
'timestamp' => $timestamp
|
||||
);
|
||||
// Add/Remove story from Reminders
|
||||
if ( ! array_key_exists( $story_id, $user_reminders['data'] ) || $set ) {
|
||||
$item = array(
|
||||
'user_id' => $user->ID,
|
||||
'story_id' => $story_id,
|
||||
'timestamp' => $timestamp
|
||||
);
|
||||
|
||||
$user_reminders['data'][ $story_id ] = $item;
|
||||
} else {
|
||||
unset( $user_reminders['data'][ $story_id ] );
|
||||
}
|
||||
$user_reminders['data'][ $story_id ] = $item;
|
||||
} else {
|
||||
unset( $user_reminders['data'][ $story_id ] );
|
||||
}
|
||||
|
||||
// Update database & response
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_user_reminders', $user_reminders ) ) {
|
||||
wp_send_json_success();
|
||||
} {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Reminders could not be updated.', 'fictioneer' )] );
|
||||
}
|
||||
// Update database & response
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_user_reminders', $user_reminders ) ) {
|
||||
wp_send_json_success();
|
||||
} {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Reminders could not be updated.', 'fictioneer' )] );
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,27 +134,25 @@ if ( get_option( 'fictioneer_enable_reminders' ) ) {
|
||||
// CLEAR MY REMINDERS - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_clear_my_reminders' ) ) {
|
||||
/**
|
||||
* Clears an user's Reminders via AJAX
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
/**
|
||||
* Clears an user's Reminders via AJAX
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_clear_my_reminders() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user( 'nonce', 'fictioneer_clear_reminders' );
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_clear_my_reminders() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user( 'nonce', 'fictioneer_clear_reminders' );
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
// Update user
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_user_reminders', [] ) ) {
|
||||
wp_send_json_success( ['success' => __( 'Data has been cleared.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Reminders could not be cleared.', 'fictioneer' )] );
|
||||
}
|
||||
// Update user
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_user_reminders', [] ) ) {
|
||||
wp_send_json_success( ['success' => __( 'Data has been cleared.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Reminders could not be cleared.', 'fictioneer' )] );
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,83 +164,81 @@ if ( get_option( 'fictioneer_enable_reminders' ) ) {
|
||||
// GET FOLLOWS LIST - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_get_reminders_list' ) ) {
|
||||
function fictioneer_ajax_get_reminders_list() {
|
||||
// Validations
|
||||
$user = wp_get_current_user();
|
||||
function fictioneer_ajax_get_reminders_list() {
|
||||
// Validations
|
||||
$user = wp_get_current_user();
|
||||
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Not logged in.', 'fictioneer' )] );
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Not logged in.', 'fictioneer' )] );
|
||||
|
||||
if ( ! check_ajax_referer( 'fictioneer_nonce', 'nonce', false ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Setup
|
||||
$reminders = fictioneer_load_reminders( $user );
|
||||
$post_ids = array_keys( $reminders['data'] );
|
||||
$page = isset( $_GET['page'] ) ? absint( $_GET['page'] ) : 1;
|
||||
$order = isset( $_GET['order'] ) ? strtolower( $_GET['order'] ) : 'desc';
|
||||
|
||||
// Sanitize
|
||||
$order = in_array( $order, ['desc', 'asc'] ) ? $order : 'desc';
|
||||
|
||||
// Query
|
||||
$list_items = fictioneer_get_card_list(
|
||||
'story',
|
||||
array(
|
||||
'post__in' => $post_ids,
|
||||
'paged' => $page,
|
||||
'order' => $order
|
||||
),
|
||||
__( 'You have not marked any stories to be read later.', 'fictioneer' ),
|
||||
['show_latest' => true]
|
||||
);
|
||||
|
||||
// Total number of pages
|
||||
$max_pages = $list_items['query']->max_num_pages ?? 1;
|
||||
|
||||
// Navigation (if any)
|
||||
$navigation = '';
|
||||
|
||||
if ( $max_pages > 1 ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<li class="pagination bookshelf-pagination">
|
||||
<?php
|
||||
for ( $i = 1; $i <= $max_pages; $i++ ) {
|
||||
if ( $i == $page ) {
|
||||
?><span class="page-numbers current" aria-current="page"><?php echo $i; ?></span><?php
|
||||
} else {
|
||||
?><button class="page-numbers" data-page="<?php echo $i; ?>"><?php echo $i; ?></button><?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
|
||||
// Get buffered navigation
|
||||
$navigation = ob_get_clean();
|
||||
} elseif ( $page > 1 ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<li class="pagination bookshelf-pagination">
|
||||
<button class="page-numbers" data-page="1"><?php _e( 'First Page', 'fictioneer' ); ?></button>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
|
||||
// Get buffered back button
|
||||
$navigation = ob_get_clean();
|
||||
}
|
||||
|
||||
// Send result
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'html' => $list_items['html'] . $navigation,
|
||||
'count' => count( $post_ids ),
|
||||
'maxPages' => $max_pages
|
||||
)
|
||||
);
|
||||
if ( ! check_ajax_referer( 'fictioneer_nonce', 'nonce', false ) ) {
|
||||
wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Setup
|
||||
$reminders = fictioneer_load_reminders( $user );
|
||||
$post_ids = array_keys( $reminders['data'] );
|
||||
$page = isset( $_GET['page'] ) ? absint( $_GET['page'] ) : 1;
|
||||
$order = isset( $_GET['order'] ) ? strtolower( $_GET['order'] ) : 'desc';
|
||||
|
||||
// Sanitize
|
||||
$order = in_array( $order, ['desc', 'asc'] ) ? $order : 'desc';
|
||||
|
||||
// Query
|
||||
$list_items = fictioneer_get_card_list(
|
||||
'story',
|
||||
array(
|
||||
'post__in' => $post_ids,
|
||||
'paged' => $page,
|
||||
'order' => $order
|
||||
),
|
||||
__( 'You have not marked any stories to be read later.', 'fictioneer' ),
|
||||
['show_latest' => true]
|
||||
);
|
||||
|
||||
// Total number of pages
|
||||
$max_pages = $list_items['query']->max_num_pages ?? 1;
|
||||
|
||||
// Navigation (if any)
|
||||
$navigation = '';
|
||||
|
||||
if ( $max_pages > 1 ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<li class="pagination bookshelf-pagination">
|
||||
<?php
|
||||
for ( $i = 1; $i <= $max_pages; $i++ ) {
|
||||
if ( $i == $page ) {
|
||||
?><span class="page-numbers current" aria-current="page"><?php echo $i; ?></span><?php
|
||||
} else {
|
||||
?><button class="page-numbers" data-page="<?php echo $i; ?>"><?php echo $i; ?></button><?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
|
||||
// Get buffered navigation
|
||||
$navigation = ob_get_clean();
|
||||
} elseif ( $page > 1 ) {
|
||||
ob_start();
|
||||
// Start HTML ---> ?>
|
||||
<li class="pagination bookshelf-pagination">
|
||||
<button class="page-numbers" data-page="1"><?php _e( 'First Page', 'fictioneer' ); ?></button>
|
||||
</li>
|
||||
<?php // <--- End HTML
|
||||
|
||||
// Get buffered back button
|
||||
$navigation = ob_get_clean();
|
||||
}
|
||||
|
||||
// Send result
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'html' => $list_items['html'] . $navigation,
|
||||
'count' => count( $post_ids ),
|
||||
'maxPages' => $max_pages
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_reminders' ) ) {
|
||||
|
@ -519,7 +519,7 @@ if ( ! function_exists( 'fictioneer_get_user_fingerprint' ) ) {
|
||||
* @param int $user_id User ID to get the hash for.
|
||||
*
|
||||
* @return string The unique fingerprint hash or empty string if not found.
|
||||
*/
|
||||
*/
|
||||
|
||||
function fictioneer_get_user_fingerprint( $user_id ) {
|
||||
// Setup
|
||||
@ -547,48 +547,46 @@ if ( ! function_exists( 'fictioneer_get_user_fingerprint' ) ) {
|
||||
// SELF-UNSET OAUTH CONNECTIONS - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_unset_my_oauth' ) ) {
|
||||
/**
|
||||
* Unset one of the user's OAuth bindings via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
*/
|
||||
/**
|
||||
* Unset one of the user's OAuth bindings via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_unset_my_oauth() {
|
||||
// Setup
|
||||
$sender_id = isset( $_POST['id'] ) ? fictioneer_validate_id( $_POST['id'] ) : false;
|
||||
$channel = isset( $_POST['channel'] ) ? sanitize_text_field( $_POST['channel'] ) : false;
|
||||
$user = fictioneer_get_validated_ajax_user( 'nonce', 'fictioneer_unset_oauth' );
|
||||
function fictioneer_ajax_unset_my_oauth() {
|
||||
// Setup
|
||||
$sender_id = isset( $_POST['id'] ) ? fictioneer_validate_id( $_POST['id'] ) : false;
|
||||
$channel = isset( $_POST['channel'] ) ? sanitize_text_field( $_POST['channel'] ) : false;
|
||||
$user = fictioneer_get_validated_ajax_user( 'nonce', 'fictioneer_unset_oauth' );
|
||||
|
||||
// Validations
|
||||
if (
|
||||
! $user ||
|
||||
! $sender_id ||
|
||||
! $channel ||
|
||||
! in_array( $channel, ['discord', 'twitch', 'patreon', 'google'] ) ||
|
||||
$sender_id !== $user->ID
|
||||
) {
|
||||
wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
}
|
||||
// Validations
|
||||
if (
|
||||
! $user ||
|
||||
! $sender_id ||
|
||||
! $channel ||
|
||||
! in_array( $channel, ['discord', 'twitch', 'patreon', 'google'] ) ||
|
||||
$sender_id !== $user->ID
|
||||
) {
|
||||
wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Delete connection
|
||||
if ( delete_user_meta( $user->ID, "fictioneer_{$channel}_id_hash" ) ) {
|
||||
// Success response
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'channel' => $channel,
|
||||
'label' => sprintf(
|
||||
__( '%s disconnected', 'fictioneer' ),
|
||||
ucfirst( $channel )
|
||||
)
|
||||
// Delete connection
|
||||
if ( delete_user_meta( $user->ID, "fictioneer_{$channel}_id_hash" ) ) {
|
||||
// Success response
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'channel' => $channel,
|
||||
'label' => sprintf(
|
||||
__( '%s disconnected', 'fictioneer' ),
|
||||
ucfirst( $channel )
|
||||
)
|
||||
);
|
||||
} else {
|
||||
// Failure response
|
||||
wp_send_json_error( ['error' => __( 'Database error. Please ask an administrator.', 'fictioneer' )] );
|
||||
}
|
||||
)
|
||||
);
|
||||
} else {
|
||||
// Failure response
|
||||
wp_send_json_error( ['error' => __( 'Database error. Please ask an administrator.', 'fictioneer' )] );
|
||||
}
|
||||
}
|
||||
add_action( 'wp_ajax_fictioneer_ajax_unset_my_oauth', 'fictioneer_ajax_unset_my_oauth' );
|
||||
@ -613,7 +611,7 @@ if ( ! function_exists( 'fictioneer_soft_delete_user_comments' ) ) {
|
||||
* for completeness, partial success, and errors. Includes
|
||||
* 'complete' (boolean), 'failure' (boolean), 'success' (boolean),
|
||||
* 'comment_count' (int), and 'updated_count' (int). Or false.
|
||||
*/
|
||||
*/
|
||||
|
||||
function fictioneer_soft_delete_user_comments( $user_id ) {
|
||||
// Setup
|
||||
@ -673,65 +671,63 @@ if ( ! function_exists( 'fictioneer_soft_delete_user_comments' ) ) {
|
||||
// SELF-CLEAR USER COMMENTS - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_clear_my_comments' ) ) {
|
||||
/**
|
||||
* Clears all the user's comments via AJAX
|
||||
*
|
||||
* Queries all comments of the user and overrides the comment data with
|
||||
* garbage, preserving the comment thread integrity.
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
/**
|
||||
* Clears all the user's comments via AJAX
|
||||
*
|
||||
* Queries all comments of the user and overrides the comment data with
|
||||
* garbage, preserving the comment thread integrity.
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_clear_my_comments() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user( 'nonce', 'fictioneer_clear_comments' );
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_clear_my_comments() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user( 'nonce', 'fictioneer_clear_comments' );
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
if (
|
||||
fictioneer_is_admin( $user->ID ) ||
|
||||
fictioneer_is_author( $user->ID ) ||
|
||||
fictioneer_is_moderator( $user->ID ) )
|
||||
{
|
||||
wp_send_json_error( ['error' => __( 'User role too high. Please ask an administrator.', 'fictioneer' )] );
|
||||
}
|
||||
if (
|
||||
fictioneer_is_admin( $user->ID ) ||
|
||||
fictioneer_is_author( $user->ID ) ||
|
||||
fictioneer_is_moderator( $user->ID ) )
|
||||
{
|
||||
wp_send_json_error( ['error' => __( 'User role too high. Please ask an administrator.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Soft-delete comments
|
||||
$result = fictioneer_soft_delete_user_comments( $user->ID );
|
||||
// Soft-delete comments
|
||||
$result = fictioneer_soft_delete_user_comments( $user->ID );
|
||||
|
||||
if ( ! $result ) {
|
||||
wp_send_json_error( ['error' => __( 'Database error. No comments found.', 'fictioneer' )] );
|
||||
}
|
||||
if ( ! $result ) {
|
||||
wp_send_json_error( ['error' => __( 'Database error. No comments found.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
if ( $result['failure'] && ! $result['complete'] ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'error' => sprintf(
|
||||
__( 'Partial database error. Only %1$s of %2$s comments could be cleared.', 'fictioneer' ),
|
||||
$result['updated_count'],
|
||||
$result['comment_count']
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( $result['failure'] ) {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Comments could not be cleared.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Report success
|
||||
wp_send_json_success(
|
||||
if ( $result['failure'] && ! $result['complete'] ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'success' => sprintf(
|
||||
__( '%s comments have been cleared.', 'fictioneer' ),
|
||||
$result['updated_count']
|
||||
'error' => sprintf(
|
||||
__( 'Partial database error. Only %1$s of %2$s comments could be cleared.', 'fictioneer' ),
|
||||
$result['updated_count'],
|
||||
$result['comment_count']
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( $result['failure'] ) {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Comments could not be cleared.', 'fictioneer' )] );
|
||||
}
|
||||
|
||||
// Report success
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'success' => sprintf(
|
||||
__( '%s comments have been cleared.', 'fictioneer' ),
|
||||
$result['updated_count']
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
add_action( 'wp_ajax_fictioneer_ajax_clear_my_comments', 'fictioneer_ajax_clear_my_comments' );
|
||||
|
||||
@ -739,31 +735,29 @@ add_action( 'wp_ajax_fictioneer_ajax_clear_my_comments', 'fictioneer_ajax_clear_
|
||||
// SELF-CLEAR USER COMMENT SUBSCRIPTIONS - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_clear_my_comment_subscriptions' ) ) {
|
||||
/**
|
||||
* Clears all the user's comment subscriptions via AJAX
|
||||
*
|
||||
* Changes the comment notification validation timestamp, effectively terminating
|
||||
* all associated previous comment subscriptions. This is far cheaper than looping
|
||||
* and updating all comments.
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
/**
|
||||
* Clears all the user's comment subscriptions via AJAX
|
||||
*
|
||||
* Changes the comment notification validation timestamp, effectively terminating
|
||||
* all associated previous comment subscriptions. This is far cheaper than looping
|
||||
* and updating all comments.
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_clear_my_comment_subscriptions() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user( 'nonce', 'fictioneer_clear_comment_subscriptions' );
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_clear_my_comment_subscriptions() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user( 'nonce', 'fictioneer_clear_comment_subscriptions' );
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
// Change validator
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_comment_reply_validator', time() ) ) {
|
||||
wp_send_json_success( ['success' => __( 'Data has been cleared.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Comment subscriptions could not be cleared.', 'fictioneer' )] );
|
||||
}
|
||||
// Change validator
|
||||
if ( update_user_meta( $user->ID, 'fictioneer_comment_reply_validator', time() ) ) {
|
||||
wp_send_json_success( ['success' => __( 'Data has been cleared.', 'fictioneer' )] );
|
||||
} else {
|
||||
wp_send_json_error( ['error' => __( 'Database error. Comment subscriptions could not be cleared.', 'fictioneer' )] );
|
||||
}
|
||||
}
|
||||
add_action( 'wp_ajax_fictioneer_ajax_clear_my_comment_subscriptions', 'fictioneer_ajax_clear_my_comment_subscriptions' );
|
||||
@ -772,78 +766,76 @@ add_action( 'wp_ajax_fictioneer_ajax_clear_my_comment_subscriptions', 'fictionee
|
||||
// SELF-DELETE USER - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_delete_my_account' ) ) {
|
||||
/**
|
||||
* Delete an user's account via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.5
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_validate_id()
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
/**
|
||||
* Delete an user's account via AJAX
|
||||
*
|
||||
* @since Fictioneer 4.5
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_validate_id()
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_delete_my_account() {
|
||||
// Setup
|
||||
$sender_id = isset( $_POST['id'] ) ? fictioneer_validate_id( $_POST['id'] ) : false;
|
||||
$current_user = fictioneer_get_validated_ajax_user( 'nonce', 'fictioneer_delete_account' );
|
||||
function fictioneer_ajax_delete_my_account() {
|
||||
// Setup
|
||||
$sender_id = isset( $_POST['id'] ) ? fictioneer_validate_id( $_POST['id'] ) : false;
|
||||
$current_user = fictioneer_get_validated_ajax_user( 'nonce', 'fictioneer_delete_account' );
|
||||
|
||||
// Extra validations
|
||||
if (
|
||||
! $sender_id ||
|
||||
! $current_user ||
|
||||
$sender_id !== $current_user->ID ||
|
||||
$current_user == 1 ||
|
||||
in_array( 'administrator', $current_user->roles ) ||
|
||||
current_user_can( 'edit_posts' ) ||
|
||||
current_user_can( 'publish_posts' ) ||
|
||||
current_user_can( 'moderate_comments' )
|
||||
) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'error' => __( 'User role too high.', 'fictioneer' ),
|
||||
'button' => __( 'Denied', 'fictioneer' )
|
||||
)
|
||||
);
|
||||
die(); // Just to be sure
|
||||
}
|
||||
// Extra validations
|
||||
if (
|
||||
! $sender_id ||
|
||||
! $current_user ||
|
||||
$sender_id !== $current_user->ID ||
|
||||
$current_user == 1 ||
|
||||
in_array( 'administrator', $current_user->roles ) ||
|
||||
current_user_can( 'edit_posts' ) ||
|
||||
current_user_can( 'publish_posts' ) ||
|
||||
current_user_can( 'moderate_comments' )
|
||||
) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'error' => __( 'User role too high.', 'fictioneer' ),
|
||||
'button' => __( 'Denied', 'fictioneer' )
|
||||
)
|
||||
);
|
||||
die(); // Just to be sure
|
||||
}
|
||||
|
||||
// Update comments
|
||||
$comments = get_comments( array( 'user_id' => $current_user->ID ) );
|
||||
// Update comments
|
||||
$comments = get_comments( array( 'user_id' => $current_user->ID ) );
|
||||
|
||||
foreach ( $comments as $comment ) {
|
||||
wp_update_comment(
|
||||
array(
|
||||
'comment_ID' => $comment->comment_ID,
|
||||
'user_ID' => 0,
|
||||
'comment_author' => fcntr( 'deleted_user' ),
|
||||
'comment_author_email' => '',
|
||||
'comment_author_IP' => '',
|
||||
'comment_agent' => '',
|
||||
'comment_author_url' => ''
|
||||
)
|
||||
);
|
||||
foreach ( $comments as $comment ) {
|
||||
wp_update_comment(
|
||||
array(
|
||||
'comment_ID' => $comment->comment_ID,
|
||||
'user_ID' => 0,
|
||||
'comment_author' => fcntr( 'deleted_user' ),
|
||||
'comment_author_email' => '',
|
||||
'comment_author_IP' => '',
|
||||
'comment_agent' => '',
|
||||
'comment_author_url' => ''
|
||||
)
|
||||
);
|
||||
|
||||
// Make absolutely sure no comment subscriptions remain
|
||||
update_comment_meta( $comment->comment_ID, 'fictioneer_send_notifications', false );
|
||||
// Make absolutely sure no comment subscriptions remain
|
||||
update_comment_meta( $comment->comment_ID, 'fictioneer_send_notifications', false );
|
||||
|
||||
// Retain some (redacted) data in case there was a mistake
|
||||
add_comment_meta( $comment->comment_ID, 'fictioneer_deleted_user_id', $current_user->ID );
|
||||
add_comment_meta( $comment->comment_ID, 'fictioneer_deleted_username_substr', substr( $current_user->user_login, 0, 3 ) );
|
||||
add_comment_meta( $comment->comment_ID, 'fictioneer_deleted_email_substr', substr( $comment->comment_author_email, 0, 3 ) );
|
||||
}
|
||||
// Retain some (redacted) data in case there was a mistake
|
||||
add_comment_meta( $comment->comment_ID, 'fictioneer_deleted_user_id', $current_user->ID );
|
||||
add_comment_meta( $comment->comment_ID, 'fictioneer_deleted_username_substr', substr( $current_user->user_login, 0, 3 ) );
|
||||
add_comment_meta( $comment->comment_ID, 'fictioneer_deleted_email_substr', substr( $comment->comment_author_email, 0, 3 ) );
|
||||
}
|
||||
|
||||
// Delete user
|
||||
if ( wp_delete_user( $current_user->ID ) ) {
|
||||
wp_send_json_success();
|
||||
} else {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'error' => __( 'Database error. Account could not be deleted.', 'fictioneer' ),
|
||||
'button' => __( 'Failure', 'fictioneer' )
|
||||
)
|
||||
);
|
||||
}
|
||||
// Delete user
|
||||
if ( wp_delete_user( $current_user->ID ) ) {
|
||||
wp_send_json_success();
|
||||
} else {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'error' => __( 'Database error. Account could not be deleted.', 'fictioneer' ),
|
||||
'button' => __( 'Failure', 'fictioneer' )
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -855,24 +847,22 @@ if ( get_option( 'fictioneer_enable_subscriber_self_delete' ) ) {
|
||||
// FETCH FINGERPRINT - AJAX
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_ajax_get_fingerprint' ) ) {
|
||||
/**
|
||||
* Sends the user's fingerprint via AJAX
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
/**
|
||||
* Sends the user's fingerprint via AJAX
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_error/
|
||||
* @see fictioneer_get_validated_ajax_user()
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_get_fingerprint() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
function fictioneer_ajax_get_fingerprint() {
|
||||
// Setup and validations
|
||||
$user = fictioneer_get_validated_ajax_user();
|
||||
if ( ! $user ) wp_send_json_error( ['error' => __( 'Request did not pass validation.', 'fictioneer' )] );
|
||||
|
||||
// Response
|
||||
wp_send_json_success( ['fingerprint' => fictioneer_get_user_fingerprint( $user->ID )] );
|
||||
}
|
||||
// Response
|
||||
wp_send_json_success( ['fingerprint' => fictioneer_get_user_fingerprint( $user->ID )] );
|
||||
}
|
||||
add_action( 'wp_ajax_fictioneer_ajax_get_fingerprint', 'fictioneer_ajax_get_fingerprint' );
|
||||
|
||||
|
@ -22,5 +22,71 @@ function fictioneer_display_render_time() {
|
||||
}
|
||||
// add_action( 'shutdown', 'fictioneer_display_render_time' );
|
||||
|
||||
// =============================================================================
|
||||
// SHOW PATREON TIERS
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Adds HTML for the Patreon tiers section to the wp-admin user profile
|
||||
*
|
||||
* DISABLED!
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $profile_user The profile user object. Not necessarily the one
|
||||
* currently editing the profile!
|
||||
*/
|
||||
|
||||
function fictioneer_admin_profile_patreon_tiers( $profile_user ) {
|
||||
// Setup
|
||||
$editing_user_is_admin = fictioneer_is_admin( get_current_user_id() );
|
||||
|
||||
// Abort conditions...
|
||||
if ( ! $editing_user_is_admin ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-patreon-tiers-wrap">
|
||||
<th><label for="fictioneer_patreon_tiers"><?php _e( 'Patreon Tiers', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
<input name="fictioneer_patreon_tiers" type="text" id="fictioneer_patreon_tiers" value="<?php echo esc_attr( json_encode( get_the_author_meta( 'fictioneer_patreon_tiers', $profile_user->ID ) ) ); ?>" class="regular-text" readonly>
|
||||
<p class="description"><?php _e( 'Patreon tiers for the linked Patreon client. Valid for two weeks after last login.', 'fictioneer' ) ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
// add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_profile_patreon_tiers', 60 );
|
||||
|
||||
// =============================================================================
|
||||
// SHOW BOOKMARKS SECTION
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Adds HTML for the bookmarks section to the wp-admin user profile
|
||||
*
|
||||
* DISABLED!
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $profile_user The profile user object. Not necessarily the one
|
||||
* currently editing the profile!
|
||||
*/
|
||||
|
||||
function fictioneer_admin_profile_bookmarks( $profile_user ) {
|
||||
// Setup
|
||||
$editing_user_is_admin = fictioneer_is_admin( get_current_user_id() );
|
||||
|
||||
// Abort conditions...
|
||||
if ( ! $editing_user_is_admin ) return;
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-bookmarks-wrap">
|
||||
<th><label for="user_bookmarks"><?php _e( 'Bookmarks JSON', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
<textarea name="user_bookmarks" id="user_bookmarks" rows="12" cols="30" style="font-family: monospace; font-size: 12px; word-break: break-all;" disabled><?php echo esc_attr( get_the_author_meta( 'fictioneer_bookmarks', $profile_user->ID ) ); ?></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
// add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_profile_bookmarks', 70 );
|
||||
|
||||
?>
|
||||
|
Loading…
x
Reference in New Issue
Block a user