Role Manager #9
@ -210,44 +210,45 @@ Fictioneer customizes WordPress by using as many standard action and filter hook
|
||||
| ---: | :--- |
|
||||
| `add_meta_boxes` | `fictioneer_add_seo_metabox`
|
||||
| `add_meta_boxes_comment` | `fictioneer_add_comment_meta_box`
|
||||
| `admin_bar_menu` | `fictioneer_reduce_author_admin_bar`, `fictioneer_reduce_contributor_admin_bar`, `fictioneer_reduce_editor_admin_bar`, `fictioneer_reduce_moderator_admin_bar`
|
||||
| `admin_enqueue_scripts` | `fictioneer_admin_scripts`, `fictioneer_admin_styles`, `fictioneer_disable_moderator_comment_edit`, `fictioneer_hide_contributor_comments_utilities`, `fictioneer_hide_editor_comments_utilities`, `fictioneer_hide_private_data`, `fictioneer_hide_author_comments_utilities`
|
||||
| `admin_head` | `fictioneer_limit_update_notice`
|
||||
| `admin_head-profile.php` | `fictioneer_hide_subscriber_profile_blocks`
|
||||
| `admin_init` | `fictioneer_reduce_subscriber_profile`, `fictioneer_register_settings`
|
||||
| `admin_menu` | `fictioneer_add_admin_menu`, `fictioneer_reduce_moderator_admin_panel`, `fictioneer_reduce_subscriber_admin_panel`, `fictioneer_remove_menu_pages`
|
||||
| `admin_bar_menu` | `fictioneer_remove_comments_from_admin_bar`
|
||||
| `admin_enqueue_scripts` | `fictioneer_admin_scripts`, `fictioneer_admin_styles`, `fictioneer_disable_moderator_comment_edit`, `fictioneer_hide_private_data`
|
||||
| `admin_head` | `fictioneer_remove_update_notice`
|
||||
| `admin_head-profile.php` | `fictioneer_remove_profile_blocks`
|
||||
| `admin_init` | `fictioneer_register_settings`, `fictioneer_skip_dashboard`
|
||||
| `admin_menu` | `fictioneer_add_admin_menu`, `fictioneer_remove_dashboard_menu`, `fictioneer_remove_comments_menu_page`
|
||||
| `admin_notices` | `fictioneer_admin_profile_notices`, `fictioneer_admin_settings_notices`, `fictioneer_admin_update_notice`
|
||||
| `admin_post_*` | `fictioneer_purge_all_epubs`, `admin_post_purge_all_seo_schemas`, `fictioneer_purge_seo_meta_caches`, `fictioneer_tools_add_moderator_role`, `fictioneer_tools_remove_moderator_role`, `fictioneer_tools_upgrade_author_role`, `fictioneer_tools_reset_author_role`, `fictioneer_tools_upgrade_contributor_role`, `fictioneer_tools_reset_contributor_role`, `fictioneer_tools_limit_editor_role`, `fictioneer_tools_reset_editor_role`, `fictioneer_tools_move_story_tags_to_genres`, `fictioneer_tools_duplicate_story_tags_to_genres`, `fictioneer_tools_purge_story_data_caches`, `fictioneer_tools_move_chapter_tags_to_genres`, `fictioneer_tools_duplicate_chapter_tags_to_genres`, `fictioneer_tools_append_default_genres`, `fictioneer_tools_append_default_tags`, `fictioneer_tools_remove_unused_tags`, `fictioneer_tools_reset_post_relationship_registry`, `fictioneer_tools_fix_users`, `fictioneer_tools_fix_stories`, `fictioneer_tools_fix_chapters`, `fictioneer_tools_fix_collections`, `fictioneer_tools_fix_pages`, `fictioneer_tools_fix_posts`, `fictioneer_tools_fix_recommendations`, `fictioneer_admin_profile_unset_oauth`, `fictioneer_admin_profile_clear_data_node`, `fictioneer_update_frontend_profile`, `fictioneer_cancel_frontend_email_change`
|
||||
| `admin_post_*` | `fictioneer_purge_all_epubs`, `admin_post_purge_all_seo_schemas`, `fictioneer_purge_seo_meta_caches`, `fictioneer_tools_add_moderator_role`, `fictioneer_tools_move_story_tags_to_genres`, `fictioneer_tools_duplicate_story_tags_to_genres`, `fictioneer_tools_purge_story_data_caches`, `fictioneer_tools_move_chapter_tags_to_genres`, `fictioneer_tools_duplicate_chapter_tags_to_genres`, `fictioneer_tools_append_default_genres`, `fictioneer_tools_append_default_tags`, `fictioneer_tools_remove_unused_tags`, `fictioneer_tools_reset_post_relationship_registry`, `fictioneer_tools_fix_users`, `fictioneer_tools_fix_stories`, `fictioneer_tools_fix_chapters`, `fictioneer_tools_fix_collections`, `fictioneer_tools_fix_pages`, `fictioneer_tools_fix_posts`, `fictioneer_tools_fix_recommendations`, `fictioneer_admin_profile_unset_oauth`, `fictioneer_admin_profile_clear_data_node`, `fictioneer_update_frontend_profile`, `fictioneer_cancel_frontend_email_change`, `fictioneer_add_role`, `fictioneer_remove_role`, `fictioneer_rename_role`
|
||||
| `after_setup_theme` | `fictioneer_theme_setup`
|
||||
| `comment_post` | `fictioneer_comment_post`, `fictioneer_post_comment_to_discord`
|
||||
| `current_screen` | `fictioneer_restrict_editor_menu_access`, `fictioneer_restrict_menu_access`, `fictioneer_restrict_moderator_menu_access`
|
||||
| `current_screen` | , `fictioneer_restrict_admin_only_pages`, `fictioneer_restrict_comment_edit`
|
||||
| `customize_register` | `fictioneer_add_customizers`
|
||||
| `customize_save_after` | `fictioneer_watch_for_customer_updates`
|
||||
| `delete_post` | `fictioneer_refresh_post_caches`, `fictioneer_track_chapter_and_story_updates`, `fictioneer_update_modified_date_on_story_for_chapter`, `fictioneer_purge_cache_transients`
|
||||
| `delete_post` | `fictioneer_refresh_post_caches`, `fictioneer_track_chapter_and_story_updates`, `fictioneer_update_modified_date_on_story_for_chapter`, `fictioneer_purge_cache_transients`, `fictioneer_flush_object_cache`
|
||||
| `do_feed_rss2` | `fictioneer_main_rss_template`
|
||||
| `edit_comment` | `fictioneer_comment_edit`, `fictioneer_edit_comment`
|
||||
| `edit_user_profile` | `fictioneer_custom_profile_fields`
|
||||
| `edit_user_profile_update` | `fictioneer_update_admin_user_profile`, `fictioneer_update_my_user_profile`
|
||||
| `get_header` | `fictioneer_maintenance_mode`
|
||||
| `init` | `fictioneer_add_character_taxonomy`, `fictioneer_add_content_warning_taxonomy`, `fictioneer_add_epub_download_endpoint`, `fictioneer_add_fandom_taxonomy`, `fictioneer_add_genre_taxonomy`, `fictioneer_add_logout_endpoint`, `fictioneer_add_oauth2_endpoint`, `fictioneer_block_subscribers_from_admin`, `fictioneer_disable_heartbeat`, `fictioneer_fcn_chapter_post_type`, `fictioneer_fcn_collection_post_type`, `fictioneer_fcn_recommendation_post_type`, `fictioneer_fcn_story_post_type`, `fictioneer_modify_allowed_tags`, `fictioneer_story_rss`
|
||||
| `init` | `fictioneer_add_character_taxonomy`, `fictioneer_add_content_warning_taxonomy`, `fictioneer_add_epub_download_endpoint`, `fictioneer_add_fandom_taxonomy`, `fictioneer_add_genre_taxonomy`, `fictioneer_add_logout_endpoint`, `fictioneer_add_oauth2_endpoint`, `fictioneer_restrict_admin_panel`, `fictioneer_disable_heartbeat`, `fictioneer_fcn_chapter_post_type`, `fictioneer_fcn_collection_post_type`, `fictioneer_fcn_recommendation_post_type`, `fictioneer_fcn_story_post_type`, `fictioneer_modify_allowed_tags`, `fictioneer_story_rss`, `fictioneer_initialize_roles`
|
||||
| `kses_allowed_protocols` | `fictioneer_extend_allowed_protocols`
|
||||
| `login_form` | `fictioneer_after_logout_cleanup`
|
||||
| `manage_comments_custom_column` | `fictioneer_add_comments_report_column_content`
|
||||
| `personal_options_update` | `fictioneer_update_admin_user_profile`, `fictioneer_update_my_user_profile`
|
||||
| `pre_get_posts` | `fictioneer_extend_search_query`, `fictioneer_remove_unlisted_from_search`, `fictioneer_scope_media_to_uploader`
|
||||
| `save_post` | `fictioneer_create_sitemap`, `fictioneer_refresh_chapters_schema`, `fictioneer_refresh_chapter_schema`, `fictioneer_refresh_collections_schema`, `fictioneer_refresh_post_caches`, `fictioneer_refresh_post_schema`, `fictioneer_refresh_recommendations_schema`, `fictioneer_refresh_recommendation_schema`, `fictioneer_refresh_stories_schema`, `fictioneer_refresh_story_schema`, `fictioneer_save_seo_metabox`, `fictioneer_save_word_count`, `fictioneer_track_chapter_and_story_updates`, `fictioneer_update_modified_date_on_story_for_chapter`, `fictioneer_update_shortcode_relationships`, `fictioneer_purge_cache_transients`
|
||||
| `pre_get_posts` | `fictioneer_extend_search_query`, `fictioneer_remove_unlisted_from_search`, `fictioneer_read_others_files`, `fictioneer_read_others_files_list_view`
|
||||
| `save_post` | `fictioneer_create_sitemap`, `fictioneer_refresh_chapters_schema`, `fictioneer_refresh_chapter_schema`, `fictioneer_refresh_collections_schema`, `fictioneer_refresh_post_caches`, `fictioneer_refresh_post_schema`, `fictioneer_refresh_recommendations_schema`, `fictioneer_refresh_recommendation_schema`, `fictioneer_refresh_stories_schema`, `fictioneer_refresh_story_schema`, `fictioneer_save_seo_metabox`, `fictioneer_save_word_count`, `fictioneer_track_chapter_and_story_updates`, `fictioneer_update_modified_date_on_story_for_chapter`, `fictioneer_update_shortcode_relationships`, `fictioneer_purge_cache_transients`, `fictioneer_restrict_page_templates`, `fictioneer_flush_object_cache`
|
||||
| `show_user_profile` | `fictioneer_custom_profile_fields`
|
||||
| `switch_theme` | `fictioneer_theme_deactivation`
|
||||
| `template_redirect` | `fictioneer_disable_date_archives`, `fictioneer_generate_epub`, `fictioneer_handle_oauth`, `fictioneer_logout`, `fictioneer_disable_attachment_pages`
|
||||
| `trashed_post` | `fictioneer_refresh_post_caches`, `fictioneer_track_chapter_and_story_updates`, `fictioneer_update_modified_date_on_story_for_chapter`, `fictioneer_purge_cache_transients`
|
||||
| `untrash_post` | `fictioneer_refresh_post_caches`, `fictioneer_track_chapter_and_story_updates`, `fictioneer_update_modified_date_on_story_for_chapter`, `fictioneer_purge_cache_transients`
|
||||
| `trashed_post` | `fictioneer_refresh_post_caches`, `fictioneer_track_chapter_and_story_updates`, `fictioneer_update_modified_date_on_story_for_chapter`, `fictioneer_purge_cache_transients`, `fictioneer_flush_object_cache`
|
||||
| `untrash_post` | `fictioneer_refresh_post_caches`, `fictioneer_track_chapter_and_story_updates`, `fictioneer_update_modified_date_on_story_for_chapter`, `fictioneer_purge_cache_transients`, `fictioneer_flush_object_cache`
|
||||
| `wp_ajax_*` | `fictioneer_ajax_clear_my_checkmarks`, `fictioneer_ajax_clear_my_comments`, `fictioneer_ajax_clear_my_comment_subscriptions`, `fictioneer_ajax_clear_my_follows`, `fictioneer_ajax_clear_my_reminders`, `fictioneer_ajax_delete_epub`, `fictioneer_ajax_delete_my_account`, `fictioneer_ajax_delete_my_comment`, `fictioneer_ajax_edit_comment`, `fictioneer_ajax_get_avatar`, `fictioneer_ajax_get_bookmarks`, `fictioneer_ajax_get_checkmarks`, `fictioneer_ajax_get_comment_form`, `fictioneer_ajax_get_comment_section`, `fictioneer_ajax_get_fingerprint`, `fictioneer_ajax_get_finished_list`, `fictioneer_ajax_get_follows`, `fictioneer_ajax_get_follows_list`, `fictioneer_ajax_get_follows_notifications`, `fictioneer_ajax_get_nonce`, `fictioneer_ajax_get_reminders`, `fictioneer_ajax_get_reminders_list`, `fictioneer_ajax_is_user_logged_in`, `fictioneer_ajax_mark_follows_read`, `fictioneer_ajax_moderate_comment`, `fictioneer_ajax_purge_schema`, `fictioneer_ajax_report_comment`, `fictioneer_ajax_save_bookmarks`, `fictioneer_ajax_set_checkmark`, `fictioneer_ajax_submit_comment`, `fictioneer_ajax_toggle_follow`, `fictioneer_ajax_toggle_reminder`, `fictioneer_ajax_unset_my_oauth`, `fictioneer_request_story_comments`
|
||||
| `wp_ajax_nopriv_*` | `fictioneer_ajax_get_comment_form`, `fictioneer_ajax_get_comment_section`, `fictioneer_ajax_get_nonce`, `fictioneer_ajax_is_user_logged_in`, `fictioneer_ajax_submit_comment`, `fictioneer_request_story_comments`
|
||||
| `wp_before_admin_bar_render` | `fictioneer_remove_admin_bar_links`
|
||||
| `wp_dashboard_setup` | `fictioneer_reduce_contributor_dashboard_widgets`, `fictioneer_reduce_editor_dashboard_widgets`, `fictioneer_reduce_moderator_dashboard_widgets`, `fictioneer_reduce_subscriber_dashboard_widgets`, `fictioneer_reduce_author_dashboard_widgets`
|
||||
| `wp_before_admin_bar_render` | `fictioneer_remove_admin_bar_links`, `fictioneer_remove_dashboard_from_admin_bar`
|
||||
| `wp_dashboard_setup` | `fictioneer_remove_dashboard_widgets`
|
||||
| `wp_default_scripts` | `fictioneer_remove_jquery_migrate`
|
||||
| `wp_enqueue_scripts` | `fictioneer_add_custom_scripts`, `fictioneer_customizer_queue`, `fictioneer_style_queue`
|
||||
| `wp_head` | `fictioneer_output_head_seo`, `fictioneer_output_rss`, `fictioneer_output_schemas`, `fictioneer_add_fiction_css`
|
||||
| `wp_update_nav_menu` | `purge_nav_menu_transients`
|
||||
|
||||
<br>
|
||||
|
||||
@ -266,7 +267,7 @@ Fictioneer customizes WordPress by using as many standard action and filter hook
|
||||
| `comment_reply_link` | `fictioneer_comment_login_to_reply`
|
||||
| `comment_row_actions` | `fictioneer_remove_quick_edit`
|
||||
| `comment_text` | `fictioneer_bbcodes`
|
||||
| `content_save_pre` | `fictioneer_strip_shortcodes_for_non_administrators`
|
||||
| `content_save_pre` | `fictioneer_strip_shortcodes`
|
||||
| `excerpt_length` | `fictioneer_custom_excerpt_length`
|
||||
| `excerpt_more` | `fictioneer_excerpt_ellipsis`
|
||||
| `get_avatar` | `fictioneer_avatar_fallback`
|
||||
@ -277,14 +278,16 @@ Fictioneer customizes WordPress by using as many standard action and filter hook
|
||||
| `kses_allowed_protocols` | `fictioneer_extend_allowed_protocols`
|
||||
| `logout_url` | `fictioneer_logout_redirect`
|
||||
| `manage_edit-comments_columns` | `fictioneer_add_comments_report_column`
|
||||
| `manage_pages_columns` | `fictioneer_restrict_comments_column`
|
||||
| `manage_posts_columns` | `fictioneer_restrict_comments_column`
|
||||
| `manage_pages_columns` | `fictioneer_remove_comments_column`
|
||||
| `manage_posts_columns` | `fictioneer_remove_comments_column`
|
||||
| `manage_users_columns` | `fictioneer_hide_users_columns`
|
||||
| `map_meta_cap` | `fictioneer_restrict_media_edit_delete`
|
||||
| `map_meta_cap` | `fcn_read_others_files`, `fictioneer_edit_others_files`, `fictioneer_delete_others_files`, `fictioneer_override_default_taxonomy_capability_check`
|
||||
| `navigation_markup_template` | `fictioneer_pagination_markup`
|
||||
| `nav_menu_link_attributes` | `fictioneer_add_menu_link_attributes`
|
||||
| `post_stuck` | `unstick_post`
|
||||
| `pre_comment_user_ip` | `__return_empty_string`
|
||||
| `pre_get_posts` | `fictioneer_extend_taxonomy_pages`, `fictioneer_limit_authors_to_own_posts_and_pages`, `fictioneer_add_sof_to_taxonomy_query`
|
||||
| `pre_get_posts` | `fictioneer_extend_taxonomy_pages`, `fictioneer_edit_others_fictioneer_posts`, `fictioneer_add_sof_to_taxonomy_query`
|
||||
| `pre_insert_term` | `fictioneer_restrict_tag_creation`
|
||||
| `preprocess_comment` | `fictioneer_preprocess_comment`, `fictioneer_validate_comment_form`
|
||||
| `protected_title_format` | `fictioneer_remove_protected_text`
|
||||
| `query_vars` | `fictioneer_query_vars`
|
||||
@ -294,8 +297,12 @@ Fictioneer customizes WordPress by using as many standard action and filter hook
|
||||
| `show_admin_bar` | `__return_false`
|
||||
| `the_content` | `fictioneer_embed_consent_wrappers`, `fictioneer_add_lightbox_to_post_images`, `fictioneer_add_chapter_paragraph_id`
|
||||
| `the_password_form` | `fictioneer_password_form`
|
||||
| `theme_page_templates` | `fictioneer_disallow_page_template_select`
|
||||
| `upload_size_limit` | `fictioneer_upload_size_limit`
|
||||
| `user_contactmethods` | `fictioneer_user_contact_methods`
|
||||
| `user_has_cap` | `fictioneer_edit_only_comments`
|
||||
| `wp_list_comments_args` | `fictioneer_comment_list_args`
|
||||
| `wp_handle_upload_prefilter` | `fictioneer_upload_restrictions`
|
||||
| `wp_is_application_passwords_available` | `__return_false`
|
||||
| `wp_robots` | `fictioneer_add_noindex_to_robots`
|
||||
| `wp_sitemaps_enabled` | `__return_false`
|
||||
@ -306,8 +313,14 @@ Fictioneer customizes WordPress by using as many standard action and filter hook
|
||||
| ---: | :--- |
|
||||
| `acf/fields/post_object/query/name=fictioneer_chapter_story` | `fictioneer_acf_scope_chapter_story`
|
||||
| `acf/fields/post_object/query/name=fictioneer_post_story_blogs` | `fictioneer_acf_scope_blog_posts`
|
||||
| `acf/fields/wysiwyg/toolbars` | `fictioneer_acf_reduce_wysiwyg`
|
||||
| `acf/pre_render_fields` | `fictioneer_remove_filter_search_id_input`, `fictioneer_remove_custom_page_css_inputs`, `fictioneer_remove_custom_epub_css_input`
|
||||
| `acf/save_post` | `fictioneer_update_post_relationships`, `fictioneer_acf_append_chapter_to_story`
|
||||
| `acf/update_value/name=fictioneer_custom_css` | `fictioneer_acf_prevent_value_update`
|
||||
| `acf/update_value/name=fictioneer_filter_and_search_id` | `fictioneer_acf_prevent_value_update`
|
||||
| `acf/update_value/name=fictioneer_story_chapters` | `fictioneer_remember_chapters_modified`
|
||||
| `acf/update_value/name=fictioneer_story_css` | `fictioneer_acf_prevent_value_update`
|
||||
| `acf/update_value/name=fictioneer_story_sticky` | `fictioneer_acf_prevent_value_update`
|
||||
|
||||
## Caching
|
||||
|
||||
|
13
FILTERS.md
13
FILTERS.md
@ -240,13 +240,18 @@ Filters the queried comments in the `comments.php` template and `fictioneer_ajax
|
||||
|
||||
---
|
||||
|
||||
### `apply_filters( 'fictioneer_filter_comment_badge', $output, $badge, $badge_class )`
|
||||
### `apply_filters( 'fictioneer_filter_comment_badge', $output, $user, $args )`
|
||||
Filters the HTML of the `fictioneer_get_comment_badge( $user, $comment, $post_author_id )` function before it is returned for rendering. The badge class and label are inserted into `<div class="fictioneer-comment__badge CLASS"><span>LABEL</span></div>`. Possible label classes are `is-author`, `is-admin`, `is-moderator`, `is-supporter`, and `badge-override`.
|
||||
|
||||
**Parameters:**
|
||||
* $output (string) – Complete HTML of the comment badge.
|
||||
* $badge (string) – Label of the badge.
|
||||
* $badge_class (string) – Class of the badge.
|
||||
* $output (string) – Complete HTML of the comment badge or empty string.
|
||||
* $user (WP_User|null) – The user object. Unsafe.
|
||||
|
||||
**$args:**
|
||||
* $badge (string) – Label of the badge or empty string.
|
||||
* $class (string) – Class of the badge or empty string.
|
||||
* $comment (WP_Comment|null) – Comment object or null if called outside a comment.
|
||||
* $post_author_id (int) – ID of the author of the post the comment is for or `0`.
|
||||
|
||||
---
|
||||
|
||||
|
@ -565,7 +565,23 @@ Most of the theme’s configuration is found here, the options being largely sel
|
||||
* **Enable OAuth 2.0 authentication:** Allow visitors to register with social media accounts, but be aware of the implications!
|
||||
* **Enable AJAX comment form/section:** If you have trouble with caching. Try the form first to save resources.
|
||||
* **Enable AJAX nonce deferment:** [Nonces](https://developer.wordpress.org/apis/security/nonces/) can conflict with caching. Use this as *last resort* to bypass the cache.
|
||||
* **Disable theme comment \*:** If you want to use different comments. Disables most of the other comment options as well.
|
||||
* **Disable theme comment {…}:** If you want to use different comments. Disables most of the other comment options as well.
|
||||
|
||||
<br>
|
||||
|
||||

|
||||
|
||||
### Roles
|
||||
|
||||
The integrated role manager to add and, edit, and remove roles. Not the most sophisticated compared to dedicated plugins, but it comes with custom capabilities tailored to the theme. Because Fictioneer offers some powerful options and tools you may want to keep away from certain roles. If the roles have not been properly initialized when you activated the theme, you can do that under the **Tools** tab. A few example capabilities:
|
||||
|
||||
* **Edit Only Others Comments:** Limits moderators to only editing comments, despite being able to edit posts from others.
|
||||
* **Shortcodes:** Without this capability, shortcodes are stripped when you save a post.
|
||||
* **Select Page Template:** You cannot change the page template without this capability.
|
||||
|
||||
<br>
|
||||
|
||||

|
||||
|
||||
### Connections Tab
|
||||
|
||||
@ -578,10 +594,18 @@ Anything that connects with external service providers goes here, such as the Cl
|
||||
|
||||
The OAuth request redirect URI should be akin to `https://your-domain.com/oauth2`, the important part being the `/oauth2` endpoint. Note that the service providers can be picky, such as rejecting an URI that includes "www" if that is not actually part of your website’s address. Use the _exact_ string you see in your browser’s address bar.
|
||||
|
||||
<br>
|
||||
|
||||

|
||||
|
||||
### Phrases Tab
|
||||
|
||||
Allows for some minor translations and changes, such as the cookie notice banner or comment reply notification email. More customization can be achieved with the theme’s [translation filter](FILTERS.md#apply_filters-fictioneer_filter_translations-strings-). But if you want to translate the theme into a new language, you will need to include the proper [translation files](https://developer.wordpress.org/plugins/internationalization/localization/) or use a plugin.
|
||||
|
||||
<br>
|
||||
|
||||

|
||||
|
||||
### ePUBs Tab
|
||||
|
||||
Lists all generated ePUBs with statistics, download links, and options to delete them. File names are equal to the story’s `post_name`, which is the slug inside the permalink and *not* the title. They are cleaned of any special characters and are also used to query associated stories. If you change the permalink, they will no longer match and a new ePUB will be generated, leaving the old one orphaned. This is not terrible but takes up space.
|
||||
@ -594,7 +618,9 @@ Only available if you enable the SEO features and no (known) SEO plugin is runni
|
||||
|
||||
### Tools Tab
|
||||
|
||||
A collection of actions to add, update, revert, fix, or purge certain items. For example, you can add a proper moderator role that WordPress somehow lacks and fix the permissions of other roles — or revert these changes. Everything is thoroughly explained. But the only action you will most likely need more than once is **Purge Story Data Caches**, which should be done whenever you change chapter or story settings.
|
||||
A collection of actions to add, update, revert, fix, or purge certain items. For example, you can add a proper moderator role if missing or convert tags into genres. Everything is thoroughly explained. But the only action you will most likely need more than once is **Purge Story Data Caches**, which should be done whenever you change chapter or story settings.
|
||||
|
||||
If the user roles lack permissions, such as authors not being able to add stories and chapters, use the **Initialize Roles** action. This also restores the defaults if you mess something up, although it will not reset capabilities outside the theme’s scope. Most administrative capabilities are left untouched for security reasons.
|
||||
|
||||
### Log
|
||||
|
||||
@ -760,3 +786,4 @@ define( 'CONSTANT_NAME', value );
|
||||
| FICTIONEER_API_STORYGRAPH_TRANSIENTS | boolean | Whether to cache Storygraph responses as Transients. Default `true`.
|
||||
| FICTIONEER_DISABLE_ACF_JSON_IMPORT | boolean | Whether to disable the ACF JSON field import. Dangerous. Default `false`.
|
||||
| FICTIONEER_ENABLE_STICKY_CARDS | boolean | Whether to allow sticky cards. Expensive. Default `true`.
|
||||
| FICTIONEER_ENABLE_STORY_DATA_META_CACHE | boolean | Whether to "cache" story data in a meta field. Default `true`.
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -77,6 +77,12 @@ if ( ! defined( 'FICTIONEER_TTS_REGEX' ) ) {
|
||||
define( 'FICTIONEER_TTS_REGEX', '([.!?:"\'\u201C\u201D])\s+(?=[A-Z"\'\u201C\u201D])' );
|
||||
}
|
||||
|
||||
// String: Default list of allowed mime types for upload restrictions
|
||||
define(
|
||||
'FICTIONEER_DEFAULT_UPLOAD_MIME_TYPE_RESTRICTIONS',
|
||||
'image/jpeg, image/png, image/webp, image/avif, image/gif, application/pdf, application/epub+zip, application/rtf, text/plain, image/svg+xml'
|
||||
);
|
||||
|
||||
/*
|
||||
* Date Strings
|
||||
*/
|
||||
@ -293,6 +299,11 @@ if ( ! defined( 'FICTIONEER_ENABLE_STICKY_CARDS' ) ) {
|
||||
define( 'FICTIONEER_ENABLE_STICKY_CARDS', true );
|
||||
}
|
||||
|
||||
// Boolean: Enable story data meta cache
|
||||
if ( ! defined( 'FICTIONEER_ENABLE_STORY_DATA_META_CACHE' ) ) {
|
||||
define( 'FICTIONEER_ENABLE_STORY_DATA_META_CACHE', true );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// GLOBAL
|
||||
// =============================================================================
|
||||
@ -460,12 +471,6 @@ if ( get_option( 'fictioneer_enable_bookmarks' ) && is_admin() ) {
|
||||
require_once __DIR__ . '/includes/functions/users/_bookmarks.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add privacy and security measures.
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/includes/functions/users/_privacy_security.php';
|
||||
|
||||
/**
|
||||
* Add content helper functions.
|
||||
*/
|
||||
|
@ -214,7 +214,7 @@ add_filter( 'acf/update_value/name=fictioneer_story_chapters', 'fictioneer_remem
|
||||
*/
|
||||
|
||||
function fictioneer_acf_scope_blog_posts( $args, $field, $post_id ) {
|
||||
if ( ! current_user_can( 'administrator' ) ) {
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
$args['author'] = get_post_field( 'post_author', $post_id );
|
||||
}
|
||||
|
||||
@ -239,7 +239,7 @@ add_filter( 'acf/fields/post_object/query/name=fictioneer_post_story_blogs', 'fi
|
||||
*/
|
||||
|
||||
function fictioneer_acf_scope_chapter_story( $args, $field, $post_id ) {
|
||||
if ( ! current_user_can( 'administrator' ) ) {
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
$args['author'] = get_post_field( 'post_author', $post_id );
|
||||
}
|
||||
|
||||
@ -290,7 +290,7 @@ function fictioneer_acf_append_chapter_to_story( $post_id ) {
|
||||
$story_author_id = get_post_field( 'post_author', $story_id );
|
||||
|
||||
// Abort if the author IDs do not match unless it's an administrator
|
||||
if ( ! current_user_can( 'administrator' ) && $chapter_author_id != $story_author_id ) {
|
||||
if ( ! current_user_can( 'manage_options' ) && $chapter_author_id != $story_author_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -327,4 +327,51 @@ if ( get_option( 'fictioneer_enable_chapter_appending' ) ) {
|
||||
add_action( 'acf/save_post', 'fictioneer_acf_append_chapter_to_story', 10 );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// PREVENT ACF FIELD FROM BEING SAVED
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Prevents updating the value of an ACF field
|
||||
*
|
||||
* When an attempt is made to update an ACF field, this function returns the
|
||||
* current value of the field, effectively discarding the new one.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param mixed $value The new value to be saved,
|
||||
* @param int $post_id The post ID.
|
||||
* @param array $field The ACF field settings array.
|
||||
*
|
||||
* @return mixed The current value of the ACF field.
|
||||
*/
|
||||
|
||||
function fictioneer_acf_prevent_value_update( $value, $post_id, $field ) {
|
||||
return get_field( $field['name'], $post_id );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// REDUCE TINYMCE TOOLBAR
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Reduce items in the TinyMCE toolbar
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param array $toolbars The toolbar configuration.
|
||||
*
|
||||
* @return array The modified toolbar configuration.
|
||||
*/
|
||||
|
||||
function fictioneer_acf_reduce_wysiwyg( $toolbars ) {
|
||||
unset( $toolbars['Full'][1][0] ); // Formselect
|
||||
unset( $toolbars['Full'][1][10] ); // WP More
|
||||
unset( $toolbars['Full'][1][12] ); // Fullscreen
|
||||
unset( $toolbars['Full'][1][13] ); // WP Adv.
|
||||
|
||||
return $toolbars;
|
||||
}
|
||||
add_filter( 'acf/fields/wysiwyg/toolbars', 'fictioneer_acf_reduce_wysiwyg' );
|
||||
|
||||
?>
|
||||
|
@ -34,10 +34,7 @@ require_once __DIR__ . '/users/_admin_profile.php';
|
||||
|
||||
function fictioneer_admin_styles() {
|
||||
wp_register_style( 'fictioneer-admin-panel', get_template_directory_uri() . '/css/admin.css' );
|
||||
|
||||
if ( is_admin() ) {
|
||||
wp_enqueue_style( 'fictioneer-admin-panel' );
|
||||
}
|
||||
wp_enqueue_style( 'fictioneer-admin-panel' );
|
||||
}
|
||||
add_action( 'admin_enqueue_scripts', 'fictioneer_admin_styles' );
|
||||
|
||||
@ -153,9 +150,6 @@ function fictioneer_admin_update_notice() {
|
||||
$last_notice = (int) get_option( 'fictioneer_update_notice_timestamp', 0 );
|
||||
$is_updates_page = $pagenow == 'update-core.php';
|
||||
|
||||
// Abort if...
|
||||
if ( ! current_user_can( 'manage_options' ) ) return;
|
||||
|
||||
// Show only once every n seconds
|
||||
if ( $last_notice + FICTIONEER_UPDATE_CHECK_TIMEOUT > time() && ! $is_updates_page ) return;
|
||||
|
||||
@ -174,7 +168,10 @@ function fictioneer_admin_update_notice() {
|
||||
// Remember notice
|
||||
update_option( 'fictioneer_update_notice_timestamp', time() );
|
||||
}
|
||||
add_action( 'admin_notices', 'fictioneer_admin_update_notice' );
|
||||
|
||||
if ( current_user_can( 'install_themes' ) ) {
|
||||
add_action( 'admin_notices', 'fictioneer_admin_update_notice' );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// ADD REMOVABLE QUERY ARGS
|
||||
@ -290,10 +287,7 @@ function fictioneer_allowed_block_types() {
|
||||
'jetpack/payment-buttons'
|
||||
);
|
||||
|
||||
if (
|
||||
! get_option( 'fictioneer_strip_shortcodes_for_non_administrators' ) ||
|
||||
current_user_can( 'administrator' )
|
||||
) {
|
||||
if ( current_user_can( 'fcn_shortcodes' ) || current_user_can( 'manage_options' ) ) {
|
||||
$allowed[] = 'core/shortcode';
|
||||
}
|
||||
|
||||
@ -304,101 +298,6 @@ if ( ! get_option( 'fictioneer_enable_all_blocks' ) ) {
|
||||
add_filter( 'allowed_block_types_all', 'fictioneer_allowed_block_types' );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// HIDE UPDATE NOTICE FOR NON-ADMINS
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Hide update notice for non-admins
|
||||
*
|
||||
* @since Fictioneer 5.5.3
|
||||
*/
|
||||
|
||||
function fictioneer_limit_update_notice(){
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
remove_action( 'admin_notices', 'update_nag', 3 );
|
||||
}
|
||||
}
|
||||
add_action( 'admin_head', 'fictioneer_limit_update_notice' );
|
||||
|
||||
// =============================================================================
|
||||
// REDUCE SUBSCRIBER ADMIN PROFILE
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Reduce subscriber profile in admin panel
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_reduce_subscriber_profile() {
|
||||
// Setup
|
||||
$user = wp_get_current_user();
|
||||
|
||||
// Abort if administrator
|
||||
if ( fictioneer_is_admin( $user->ID ) ) return;
|
||||
|
||||
// Remove application password
|
||||
add_filter( 'wp_is_application_passwords_available', '__return_false' );
|
||||
|
||||
// Abort if not a subscriber (higher role)
|
||||
if ( ! in_array( 'subscriber', $user->roles ) ) return;
|
||||
|
||||
// Reduce profile...
|
||||
remove_action( 'admin_color_scheme_picker', 'admin_color_scheme_picker' );
|
||||
add_filter( 'user_contactmethods', '__return_empty_array', 20 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide subscriber profile blocks in admin panel
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_hide_subscriber_profile_blocks() {
|
||||
// Setup
|
||||
$user = wp_get_current_user();
|
||||
|
||||
// Abort if not a subscriber (higher role)
|
||||
if ( ! in_array( 'subscriber', $user->roles ) ) return;
|
||||
|
||||
// Add CSS to hide blocks...
|
||||
echo '<style>.user-url-wrap, .user-description-wrap, .user-first-name-wrap, .user-last-name-wrap, .user-language-wrap, .user-admin-bar-front-wrap, .user-pass1-wrap, .user-pass2-wrap, .user-generate-reset-link-wrap, #contextual-help-link-wrap, #your-profile > h2:first-of-type { display: none; }</style>';
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_admin_reduce_subscriber_profile' ) ) {
|
||||
add_action( 'admin_init', 'fictioneer_reduce_subscriber_profile' );
|
||||
add_action( 'admin_head-profile.php', 'fictioneer_hide_subscriber_profile_blocks' );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// LIMIT USERS TO OWN POSTS/PAGES
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Limit users to own posts and pages
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_limit_users_to_own_posts_and_pages( $query ) {
|
||||
global $pagenow;
|
||||
|
||||
// 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_filter( 'pre_get_posts', 'fictioneer_limit_users_to_own_posts_and_pages' );
|
||||
|
||||
// =============================================================================
|
||||
// ADD OR UPDATE TERM
|
||||
// =============================================================================
|
||||
@ -524,127 +423,4 @@ if ( ! function_exists( 'fictioneer_convert_taxonomies' ) ) {
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// ROLE CUSTOMIZATION ACTIONS
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Add custom moderator role
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_add_moderator_role() {
|
||||
return add_role(
|
||||
'fcn_moderator',
|
||||
__( 'Moderator', 'fictioneer' ),
|
||||
array(
|
||||
'read' => true,
|
||||
'edit_posts' => true,
|
||||
'edit_others_posts' => true,
|
||||
'edit_published_posts' => true,
|
||||
'moderate_comments' => true,
|
||||
'edit_comment' => true,
|
||||
'delete_posts' => false,
|
||||
'delete_others_posts' => false
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade author role with additional capabilities
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_upgrade_author_role() {
|
||||
$role = get_role( 'author' );
|
||||
$role->add_cap( 'delete_pages' );
|
||||
$role->add_cap( 'delete_published_pages' );
|
||||
$role->add_cap( 'edit_pages' );
|
||||
$role->add_cap( 'edit_published_pages' );
|
||||
$role->add_cap( 'publish_pages' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset author role to WordPress defaults
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_reset_author_role() {
|
||||
$role = get_role( 'author' );
|
||||
$role->remove_cap( 'delete_pages' );
|
||||
$role->remove_cap( 'delete_published_pages' );
|
||||
$role->remove_cap( 'edit_pages' );
|
||||
$role->remove_cap( 'edit_published_pages' );
|
||||
$role->remove_cap( 'publish_pages' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade contributor role with additional capabilities
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_upgrade_contributor_role() {
|
||||
$role = get_role( 'contributor' );
|
||||
$role->add_cap( 'delete_pages' );
|
||||
$role->add_cap( 'edit_pages' );
|
||||
$role->add_cap( 'edit_published_pages' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset contributor role to WordPress defaults
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_reset_contributor_role() {
|
||||
$role = get_role( 'contributor' );
|
||||
$role->remove_cap( 'delete_pages' );
|
||||
$role->remove_cap( 'edit_pages' );
|
||||
$role->remove_cap( 'edit_published_pages' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit editor role to less capabilities
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_limit_editor_role() {
|
||||
$role = get_role( 'editor' );
|
||||
$role->remove_cap( 'delete_pages' );
|
||||
$role->remove_cap( 'delete_published_pages' );
|
||||
$role->remove_cap( 'delete_published_posts' );
|
||||
$role->remove_cap( 'delete_others_pages' );
|
||||
$role->remove_cap( 'delete_others_posts' );
|
||||
$role->remove_cap( 'publish_pages' );
|
||||
$role->remove_cap( 'publish_posts' );
|
||||
$role->remove_cap( 'manage_categories' );
|
||||
$role->remove_cap( 'unfiltered_html' );
|
||||
$role->remove_cap( 'manage_links' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset editor role to WordPress defaults
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*/
|
||||
|
||||
function fictioneer_reset_editor_role() {
|
||||
$role = get_role( 'editor' );
|
||||
$role->add_cap( 'delete_pages' );
|
||||
$role->add_cap( 'delete_published_pages' );
|
||||
$role->add_cap( 'delete_published_posts' );
|
||||
$role->add_cap( 'delete_others_pages' );
|
||||
$role->add_cap( 'delete_others_posts' );
|
||||
$role->add_cap( 'publish_pages' );
|
||||
$role->add_cap( 'publish_posts' );
|
||||
$role->add_cap( 'manage_categories' );
|
||||
$role->add_cap( 'unfiltered_html' );
|
||||
$role->add_cap( 'manage_links' );
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -204,9 +204,9 @@ if ( ! function_exists( 'fictioneer_refresh_post_caches' ) ) {
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
* @since Fictioneer 5.0.0
|
||||
*
|
||||
* @param int $post_id Updated post ID.
|
||||
* @param int $post_id Updated post ID.
|
||||
*/
|
||||
|
||||
function fictioneer_refresh_post_caches( $post_id ) {
|
||||
@ -240,9 +240,14 @@ if ( ! function_exists( 'fictioneer_refresh_post_caches' ) ) {
|
||||
}
|
||||
|
||||
// Purge parent story (if any)
|
||||
fictioneer_purge_post_cache(
|
||||
fictioneer_get_field( 'fictioneer_chapter_story', $post_id )
|
||||
);
|
||||
if ( get_post_type( $post_id ) == 'fcn_chapter' ) {
|
||||
$story_id = fictioneer_get_field( 'fictioneer_chapter_story', $post_id );
|
||||
|
||||
if ( ! empty( $story_id ) ) {
|
||||
update_post_meta( $story_id, 'fictioneer_story_data_collection', false );
|
||||
fictioneer_purge_post_cache( $story_id );
|
||||
}
|
||||
}
|
||||
|
||||
// Purge associated list pages
|
||||
if ( in_array( get_post_type( $post_id ), ['fcn_chapter', 'fcn_story'] ) ) {
|
||||
@ -349,11 +354,11 @@ function fictioneer_toggle_refresh_hooks( $add = true ) {
|
||||
|
||||
if ( $add ) {
|
||||
foreach( $hooks as $hook ) {
|
||||
add_action( $hook, 'fictioneer_refresh_post_caches' );
|
||||
add_action( $hook, 'fictioneer_refresh_post_caches', 20 );
|
||||
}
|
||||
} else {
|
||||
foreach( $hooks as $hook ) {
|
||||
remove_action( $hook, 'fictioneer_refresh_post_caches' );
|
||||
remove_action( $hook, 'fictioneer_refresh_post_caches', 20 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -362,6 +367,34 @@ if ( FICTIONEER_CACHE_PURGE_ASSIST && fictioneer_caching_active() ) {
|
||||
fictioneer_toggle_refresh_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush object cache
|
||||
*
|
||||
* "There are only two hard things in Computer Science: cache invalidation and
|
||||
* naming things" -- Phil Karlton.
|
||||
*
|
||||
* @since Fictioneer 5.6.0
|
||||
*
|
||||
* @param int $post_id Updated post ID.
|
||||
*/
|
||||
|
||||
function fictioneer_flush_object_cache( $post_id ) {
|
||||
// Prevent miss-fire
|
||||
if ( fictioneer_multi_save_guard( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Nuclear option
|
||||
wp_cache_flush();
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_flush_object_cache' ) ) {
|
||||
add_action( 'save_post', 'fictioneer_flush_object_cache', 9 );
|
||||
add_action( 'untrash_post', 'fictioneer_flush_object_cache', 9 );
|
||||
add_action( 'trashed_post', 'fictioneer_flush_object_cache', 9 );
|
||||
add_action( 'delete_post', 'fictioneer_flush_object_cache', 9 );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// RELATIONSHIP REGISTRY
|
||||
//
|
||||
@ -515,11 +548,11 @@ function fictioneer_toggle_update_tracker_hooks( $add = true ) {
|
||||
|
||||
if ( $add ) {
|
||||
foreach( $hooks as $hook ) {
|
||||
add_action( $hook, 'fictioneer_track_chapter_and_story_updates' );
|
||||
add_action( $hook, 'fictioneer_track_chapter_and_story_updates', 10 );
|
||||
}
|
||||
} else {
|
||||
foreach( $hooks as $hook ) {
|
||||
remove_action( $hook, 'fictioneer_track_chapter_and_story_updates' );
|
||||
remove_action( $hook, 'fictioneer_track_chapter_and_story_updates', 10 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -573,8 +606,7 @@ function fictioneer_purge_cache_transients( $post_id ) {
|
||||
$post_type = get_post_type( $post_id ); // Not all hooks get the $post object!
|
||||
|
||||
// Menus
|
||||
delete_transient( 'fictioneer_main_nav_menu' );
|
||||
delete_transient( 'fictioneer_footer_menu' );
|
||||
purge_nav_menu_transients();
|
||||
|
||||
// Shortcode...
|
||||
if ( FICTIONEER_SHORTCODE_TRANSIENT_EXPIRATION > -1 ) {
|
||||
@ -613,4 +645,15 @@ function fictioneer_toggle_transient_purge_hooks( $add = true ) {
|
||||
|
||||
fictioneer_toggle_transient_purge_hooks();
|
||||
|
||||
/**
|
||||
* Purge nav menu Transients on menu updates
|
||||
*
|
||||
* @since Fictioneer 5.6.0
|
||||
*/
|
||||
|
||||
function purge_nav_menu_transients() {
|
||||
delete_transient( 'fictioneer_main_nav_menu' );
|
||||
delete_transient( 'fictioneer_footer_menu' );
|
||||
}
|
||||
add_action( 'wp_update_nav_menu', 'purge_nav_menu_transients' );
|
||||
?>
|
||||
|
@ -102,9 +102,6 @@ function fictioneer_theme_deactivation() {
|
||||
|
||||
// Reset user roles
|
||||
remove_role( 'fcn_moderator' );
|
||||
fictioneer_reset_author_role();
|
||||
fictioneer_reset_editor_role();
|
||||
fictioneer_reset_contributor_role();
|
||||
}
|
||||
}
|
||||
add_action( 'switch_theme', 'fictioneer_theme_deactivation' );
|
||||
|
@ -1,5 +1,104 @@
|
||||
<?php
|
||||
|
||||
// =============================================================================
|
||||
// CUSTOM CAPABILITIES (DO NOT CHANGE ORDER!)
|
||||
// =============================================================================
|
||||
|
||||
define(
|
||||
'FICTIONEER_WP_CAPABILITIES',
|
||||
array(
|
||||
'edit_post',
|
||||
'read_post',
|
||||
'delete_post',
|
||||
'edit_posts',
|
||||
'edit_others_posts',
|
||||
'publish_posts',
|
||||
'read_private_posts',
|
||||
'delete_posts',
|
||||
'delete_private_posts',
|
||||
'delete_published_posts',
|
||||
'delete_others_posts',
|
||||
'edit_private_posts',
|
||||
'edit_published_posts'
|
||||
)
|
||||
);
|
||||
|
||||
define(
|
||||
'FICTIONEER_STORY_CAPABILITIES',
|
||||
array(
|
||||
'edit_fcn_story',
|
||||
'read_fcn_story',
|
||||
'delete_fcn_story',
|
||||
'edit_fcn_stories',
|
||||
'edit_others_fcn_stories',
|
||||
'publish_fcn_stories',
|
||||
'read_private_fcn_stories',
|
||||
'delete_fcn_stories',
|
||||
'delete_private_fcn_stories',
|
||||
'delete_published_fcn_stories',
|
||||
'delete_others_fcn_stories',
|
||||
'edit_private_fcn_stories',
|
||||
'edit_published_fcn_stories'
|
||||
)
|
||||
);
|
||||
|
||||
define(
|
||||
'FICTIONEER_CHAPTER_CAPABILITIES',
|
||||
array(
|
||||
'edit_fcn_chapter',
|
||||
'read_fcn_chapter',
|
||||
'delete_fcn_chapter',
|
||||
'edit_fcn_chapters',
|
||||
'edit_others_fcn_chapters',
|
||||
'publish_fcn_chapters',
|
||||
'read_private_fcn_chapters',
|
||||
'delete_fcn_chapters',
|
||||
'delete_private_fcn_chapters',
|
||||
'delete_published_fcn_chapters',
|
||||
'delete_others_fcn_chapters',
|
||||
'edit_private_fcn_chapters',
|
||||
'edit_published_fcn_chapters'
|
||||
)
|
||||
);
|
||||
|
||||
define(
|
||||
'FICTIONEER_COLLECTION_CAPABILITIES',
|
||||
array(
|
||||
'edit_fcn_collection',
|
||||
'read_fcn_collection',
|
||||
'delete_fcn_collection',
|
||||
'edit_fcn_collections',
|
||||
'edit_others_fcn_collections',
|
||||
'publish_fcn_collections',
|
||||
'read_private_fcn_collections',
|
||||
'delete_fcn_collections',
|
||||
'delete_private_fcn_collections',
|
||||
'delete_published_fcn_collections',
|
||||
'delete_others_fcn_collections',
|
||||
'edit_private_fcn_collections',
|
||||
'edit_published_fcn_collections'
|
||||
)
|
||||
);
|
||||
|
||||
define(
|
||||
'FICTIONEER_RECOMMENDATION_CAPABILITIES',
|
||||
array(
|
||||
'edit_fcn_recommendation',
|
||||
'read_fcn_recommendation',
|
||||
'delete_fcn_recommendation',
|
||||
'edit_fcn_recommendations',
|
||||
'edit_others_fcn_recommendations',
|
||||
'publish_fcn_recommendations',
|
||||
'read_private_fcn_recommendations',
|
||||
'delete_fcn_recommendations',
|
||||
'delete_private_fcn_recommendations',
|
||||
'delete_published_fcn_recommendations',
|
||||
'delete_others_fcn_recommendations',
|
||||
'edit_private_fcn_recommendations',
|
||||
'edit_published_fcn_recommendations'
|
||||
)
|
||||
);
|
||||
|
||||
// =============================================================================
|
||||
// CUSTOM POST TYPE: FCN_STORY
|
||||
// =============================================================================
|
||||
@ -41,26 +140,28 @@ function fictioneer_fcn_story_post_type() {
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'label' => __( 'Story', 'fictioneer' ),
|
||||
'description' => __( 'Holds stories and details about them.', 'fictioneer' ),
|
||||
'labels' => $labels,
|
||||
'menu_icon' => 'dashicons-book',
|
||||
'supports' => array( 'title', 'author', 'editor', 'excerpt', 'thumbnail', 'revisions' ),
|
||||
'taxonomies' => array( 'category', 'post_tag', 'fcn_fandom', 'fcn_character', 'fcn_genre', 'fcn_content_warning' ),
|
||||
'hierarchical' => false,
|
||||
'public' => true,
|
||||
'rewrite' => array( 'slug' => 'story' ),
|
||||
'show_in_rest' => true,
|
||||
'show_ui' => true,
|
||||
'show_in_menu' => true,
|
||||
'menu_position' => 5,
|
||||
'show_in_admin_bar' => true,
|
||||
'show_in_nav_menus' => true,
|
||||
'can_export' => true,
|
||||
'has_archive' => false,
|
||||
'exclude_from_search' => false,
|
||||
'publicly_queryable' => true,
|
||||
'capability_type' => 'page',
|
||||
'label' => __( 'Story', 'fictioneer' ),
|
||||
'description' => __( 'Holds stories and details about them.', 'fictioneer' ),
|
||||
'labels' => $labels,
|
||||
'menu_icon' => 'dashicons-book',
|
||||
'supports' => ['title', 'author', 'editor', 'excerpt', 'thumbnail', 'revisions'],
|
||||
'taxonomies' => ['category', 'post_tag', 'fcn_fandom', 'fcn_character', 'fcn_genre', 'fcn_content_warning'],
|
||||
'hierarchical' => false,
|
||||
'public' => current_user_can( 'fcn_edit_permalink' ), // Edit permalink in editor
|
||||
'rewrite' => array( 'slug' => 'story' ),
|
||||
'show_in_rest' => true,
|
||||
'show_ui' => true,
|
||||
'show_in_menu' => true,
|
||||
'menu_position' => 5,
|
||||
'show_in_admin_bar' => true,
|
||||
'show_in_nav_menus' => true,
|
||||
'can_export' => true,
|
||||
'has_archive' => false,
|
||||
'exclude_from_search' => false,
|
||||
'publicly_queryable' => true,
|
||||
'capability_type' => ['fcn_story', 'fcn_stories'],
|
||||
'capabilities' => array_combine( FICTIONEER_WP_CAPABILITIES, FICTIONEER_STORY_CAPABILITIES ),
|
||||
'map_meta_cap' => true
|
||||
);
|
||||
|
||||
register_post_type( 'fcn_story', $args );
|
||||
@ -106,28 +207,32 @@ function fictioneer_fcn_chapter_post_type() {
|
||||
'items_list_navigation' => __( 'Chapters list navigation', 'fictioneer' ),
|
||||
'filter_items_list' => __( 'Filter chapters list', 'fictioneer' ),
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'label' => __( 'Chapter', 'fictioneer' ),
|
||||
'description' => __( 'Holds chapters and details about them.', 'fictioneer' ),
|
||||
'labels' => $labels,
|
||||
'menu_icon' => 'dashicons-text-page',
|
||||
'supports' => array( 'title', 'author', 'editor', 'excerpt', 'thumbnail', 'comments', 'revisions' ),
|
||||
'taxonomies' => array( 'category', 'post_tag', 'fcn_fandom', 'fcn_character', 'fcn_genre', 'fcn_content_warning' ),
|
||||
'hierarchical' => false,
|
||||
'public' => true,
|
||||
'rewrite' => array( 'slug' => 'chapter' ),
|
||||
'show_in_rest' => true,
|
||||
'show_ui' => true,
|
||||
'show_in_menu' => true,
|
||||
'menu_position' => 6,
|
||||
'show_in_admin_bar' => true,
|
||||
'show_in_nav_menus' => true,
|
||||
'can_export' => true,
|
||||
'has_archive' => false,
|
||||
'exclude_from_search' => false,
|
||||
'publicly_queryable' => true,
|
||||
'capability_type' => 'page',
|
||||
'label' => __( 'Chapter', 'fictioneer' ),
|
||||
'description' => __( 'Holds chapters and details about them.', 'fictioneer' ),
|
||||
'labels' => $labels,
|
||||
'menu_icon' => 'dashicons-text-page',
|
||||
'supports' => ['title', 'author', 'editor', 'excerpt', 'thumbnail', 'comments', 'revisions'],
|
||||
'taxonomies' => ['category', 'post_tag', 'fcn_fandom', 'fcn_character', 'fcn_genre', 'fcn_content_warning'],
|
||||
'hierarchical' => false,
|
||||
'public' => current_user_can( 'fcn_edit_permalink' ), // Edit permalink in editor
|
||||
'rewrite' => array( 'slug' => 'chapter' ),
|
||||
'show_in_rest' => true,
|
||||
'show_ui' => true,
|
||||
'show_in_menu' => true,
|
||||
'menu_position' => 6,
|
||||
'show_in_admin_bar' => true,
|
||||
'show_in_nav_menus' => true,
|
||||
'can_export' => true,
|
||||
'has_archive' => false,
|
||||
'exclude_from_search' => false,
|
||||
'publicly_queryable' => true,
|
||||
'capability_type' => ['fcn_chapter', 'fcn_chapters'],
|
||||
'capabilities' => array_combine( FICTIONEER_WP_CAPABILITIES, FICTIONEER_CHAPTER_CAPABILITIES ),
|
||||
'map_meta_cap' => true
|
||||
);
|
||||
|
||||
register_post_type( 'fcn_chapter', $args );
|
||||
}
|
||||
add_action( 'init', 'fictioneer_fcn_chapter_post_type', 0 );
|
||||
@ -171,28 +276,32 @@ function fictioneer_fcn_collection_post_type() {
|
||||
'items_list_navigation' => __( 'Collections list navigation', 'fictioneer' ),
|
||||
'filter_items_list' => __( 'Filter collections list', 'fictioneer' ),
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'label' => __( 'Collection', 'fictioneer' ),
|
||||
'description' => __( 'Collections of stories, chapters, and recommendations.', 'fictioneer' ),
|
||||
'labels' => $labels,
|
||||
'menu_icon' => 'dashicons-category',
|
||||
'supports' => array( 'title', 'author', 'editor', 'thumbnail' ),
|
||||
'taxonomies' => array( 'category', 'post_tag', 'fcn_fandom', 'fcn_character', 'fcn_genre', 'fcn_content_warning' ),
|
||||
'hierarchical' => false,
|
||||
'public' => true,
|
||||
'rewrite' => array( 'slug' => 'collection' ),
|
||||
'show_in_rest' => true,
|
||||
'show_ui' => true,
|
||||
'show_in_menu' => true,
|
||||
'menu_position' => 7,
|
||||
'show_in_admin_bar' => true,
|
||||
'show_in_nav_menus' => true,
|
||||
'can_export' => true,
|
||||
'has_archive' => false,
|
||||
'exclude_from_search' => false,
|
||||
'publicly_queryable' => true,
|
||||
'capability_type' => 'page',
|
||||
'label' => __( 'Collection', 'fictioneer' ),
|
||||
'description' => __( 'Collections of stories, chapters, and recommendations.', 'fictioneer' ),
|
||||
'labels' => $labels,
|
||||
'menu_icon' => 'dashicons-category',
|
||||
'supports' => ['title', 'author', 'editor', 'thumbnail'],
|
||||
'taxonomies' => ['category', 'post_tag', 'fcn_fandom', 'fcn_character', 'fcn_genre', 'fcn_content_warning'],
|
||||
'hierarchical' => false,
|
||||
'public' => current_user_can( 'fcn_edit_permalink' ), // Edit permalink in editor
|
||||
'rewrite' => array( 'slug' => 'collection' ),
|
||||
'show_in_rest' => true,
|
||||
'show_ui' => true,
|
||||
'show_in_menu' => true,
|
||||
'menu_position' => 7,
|
||||
'show_in_admin_bar' => true,
|
||||
'show_in_nav_menus' => true,
|
||||
'can_export' => true,
|
||||
'has_archive' => false,
|
||||
'exclude_from_search' => false,
|
||||
'publicly_queryable' => true,
|
||||
'capability_type' => ['fcn_collection', 'fcn_collections'],
|
||||
'capabilities' => array_combine( FICTIONEER_WP_CAPABILITIES, FICTIONEER_COLLECTION_CAPABILITIES ),
|
||||
'map_meta_cap' => true
|
||||
);
|
||||
|
||||
register_post_type( 'fcn_collection', $args );
|
||||
}
|
||||
add_action( 'init', 'fictioneer_fcn_collection_post_type', 0 );
|
||||
@ -236,28 +345,32 @@ function fictioneer_fcn_recommendation_post_type() {
|
||||
'items_list_navigation' => __( 'Recommendations list navigation', 'fictioneer' ),
|
||||
'filter_items_list' => __( 'Filter recommendations list', 'fictioneer' ),
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'label' => __( 'Recommendation', 'fictioneer' ),
|
||||
'description' => __( 'Recommendations for external stories.', 'fictioneer' ),
|
||||
'labels' => $labels,
|
||||
'menu_icon' => 'dashicons-star-filled',
|
||||
'supports' => array( 'title', 'author', 'editor', 'excerpt', 'thumbnail' ),
|
||||
'taxonomies' => array( 'category', 'post_tag', 'fcn_fandom', 'fcn_character', 'fcn_genre', 'fcn_content_warning' ),
|
||||
'hierarchical' => false,
|
||||
'public' => true,
|
||||
'rewrite' => array( 'slug' => 'recommendation' ),
|
||||
'show_in_rest' => true,
|
||||
'show_ui' => true,
|
||||
'show_in_menu' => true,
|
||||
'menu_position' => 8,
|
||||
'show_in_admin_bar' => true,
|
||||
'show_in_nav_menus' => false,
|
||||
'can_export' => true,
|
||||
'has_archive' => false,
|
||||
'exclude_from_search' => false,
|
||||
'publicly_queryable' => true,
|
||||
'capability_type' => 'page',
|
||||
'label' => __( 'Recommendation', 'fictioneer' ),
|
||||
'description' => __( 'Recommendations for external stories.', 'fictioneer' ),
|
||||
'labels' => $labels,
|
||||
'menu_icon' => 'dashicons-star-filled',
|
||||
'supports' => ['title', 'author', 'editor', 'excerpt', 'thumbnail'],
|
||||
'taxonomies' => ['category', 'post_tag', 'fcn_fandom', 'fcn_character', 'fcn_genre', 'fcn_content_warning'],
|
||||
'hierarchical' => false,
|
||||
'public' => current_user_can( 'fcn_edit_permalink' ), // Edit permalink in editor
|
||||
'rewrite' => array( 'slug' => 'recommendation' ),
|
||||
'show_in_rest' => true,
|
||||
'show_ui' => true,
|
||||
'show_in_menu' => true,
|
||||
'menu_position' => 8,
|
||||
'show_in_admin_bar' => true,
|
||||
'show_in_nav_menus' => false,
|
||||
'can_export' => true,
|
||||
'has_archive' => false,
|
||||
'exclude_from_search' => false,
|
||||
'publicly_queryable' => true,
|
||||
'capability_type' => ['fcn_recommendation', 'fcn_recommendations'],
|
||||
'capabilities' => array_combine( FICTIONEER_WP_CAPABILITIES, FICTIONEER_RECOMMENDATION_CAPABILITIES ),
|
||||
'map_meta_cap' => true
|
||||
);
|
||||
|
||||
register_post_type( 'fcn_recommendation', $args );
|
||||
}
|
||||
add_action( 'init', 'fictioneer_fcn_recommendation_post_type', 0 );
|
||||
@ -286,6 +399,7 @@ function fictioneer_add_genre_taxonomy() {
|
||||
'add_new_item' => __( 'Add New Genre', 'textdomain' ),
|
||||
'new_item_name' => __( 'New Genre Name', 'textdomain' )
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'hierarchical' => true,
|
||||
'labels' => $labels,
|
||||
@ -294,8 +408,15 @@ function fictioneer_add_genre_taxonomy() {
|
||||
'show_in_rest' => true,
|
||||
'query_var' => true,
|
||||
'rewrite' => array( 'slug' => 'genre' ),
|
||||
'capabilities' => array(
|
||||
'manage_terms' => 'manage_fcn_genres',
|
||||
'edit_terms' => 'edit_fcn_genres',
|
||||
'delete_terms' => 'delete_fcn_genres',
|
||||
'assign_terms' => 'assign_fcn_genres'
|
||||
)
|
||||
);
|
||||
register_taxonomy( 'fcn_genre', array( 'fcn_chapter', 'fcn_story', 'fcn_collection', 'fcn_recommendation' ), $args );
|
||||
|
||||
register_taxonomy( 'fcn_genre', ['fcn_chapter', 'fcn_story', 'fcn_collection', 'fcn_recommendation'], $args );
|
||||
}
|
||||
add_action( 'init', 'fictioneer_add_genre_taxonomy', 0 );
|
||||
|
||||
@ -323,6 +444,7 @@ function fictioneer_add_fandom_taxonomy() {
|
||||
'add_new_item' => __( 'Add New Fandom', 'textdomain' ),
|
||||
'new_item_name' => __( 'New Fandom Name', 'textdomain' )
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'hierarchical' => true,
|
||||
'labels' => $labels,
|
||||
@ -331,8 +453,15 @@ function fictioneer_add_fandom_taxonomy() {
|
||||
'show_in_rest' => true,
|
||||
'query_var' => true,
|
||||
'rewrite' => array( 'slug' => 'fandom' ),
|
||||
'capabilities' => array(
|
||||
'manage_terms' => 'manage_fcn_fandoms',
|
||||
'edit_terms' => 'edit_fcn_fandoms',
|
||||
'delete_terms' => 'delete_fcn_fandoms',
|
||||
'assign_terms' => 'assign_fcn_fandoms'
|
||||
)
|
||||
);
|
||||
register_taxonomy( 'fcn_fandom', array( 'fcn_chapter', 'fcn_story', 'fcn_collection', 'fcn_recommendation' ), $args );
|
||||
|
||||
register_taxonomy( 'fcn_fandom', ['fcn_chapter', 'fcn_story', 'fcn_collection', 'fcn_recommendation'], $args );
|
||||
}
|
||||
add_action( 'init', 'fictioneer_add_fandom_taxonomy', 0 );
|
||||
|
||||
@ -360,6 +489,7 @@ function fictioneer_add_character_taxonomy() {
|
||||
'add_new_item' => __( 'Add New Character', 'textdomain' ),
|
||||
'new_item_name' => __( 'New Character Name', 'textdomain' )
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'hierarchical' => true,
|
||||
'labels' => $labels,
|
||||
@ -368,8 +498,15 @@ function fictioneer_add_character_taxonomy() {
|
||||
'show_in_rest' => true,
|
||||
'query_var' => true,
|
||||
'rewrite' => array( 'slug' => 'character' ),
|
||||
'capabilities' => array(
|
||||
'manage_terms' => 'manage_fcn_characters',
|
||||
'edit_terms' => 'edit_fcn_characters',
|
||||
'delete_terms' => 'delete_fcn_characters',
|
||||
'assign_terms' => 'assign_fcn_characters'
|
||||
)
|
||||
);
|
||||
register_taxonomy( 'fcn_character', array( 'fcn_chapter', 'fcn_story', 'fcn_collection', 'fcn_recommendation' ), $args );
|
||||
|
||||
register_taxonomy( 'fcn_character', ['fcn_chapter', 'fcn_story', 'fcn_collection', 'fcn_recommendation'], $args );
|
||||
}
|
||||
add_action( 'init', 'fictioneer_add_character_taxonomy', 0 );
|
||||
|
||||
@ -397,6 +534,7 @@ function fictioneer_add_content_warning_taxonomy() {
|
||||
'add_new_item' => __( 'Add New Content Warning', 'textdomain' ),
|
||||
'new_item_name' => __( 'New Content Warning Name', 'textdomain' )
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'hierarchical' => true,
|
||||
'labels' => $labels,
|
||||
@ -405,9 +543,102 @@ function fictioneer_add_content_warning_taxonomy() {
|
||||
'show_in_rest' => true,
|
||||
'query_var' => true,
|
||||
'rewrite' => array( 'slug' => 'content-warning' ),
|
||||
'capabilities' => array(
|
||||
'manage_terms' => 'manage_fcn_content_warnings',
|
||||
'edit_terms' => 'edit_fcn_content_warnings',
|
||||
'delete_terms' => 'delete_fcn_content_warnings',
|
||||
'assign_terms' => 'assign_fcn_content_warnings'
|
||||
)
|
||||
);
|
||||
register_taxonomy( 'fcn_content_warning', array( 'fcn_chapter', 'fcn_story', 'fcn_collection', 'fcn_recommendation' ), $args );
|
||||
|
||||
register_taxonomy( 'fcn_content_warning', ['fcn_chapter', 'fcn_story', 'fcn_collection', 'fcn_recommendation'], $args );
|
||||
}
|
||||
add_action( 'init', 'fictioneer_add_content_warning_taxonomy', 0 );
|
||||
|
||||
// =============================================================================
|
||||
// MODIFY DEFAULT CATEGORIES AND POST TAGS
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Overrides the default taxonomy capability check for categories and post tags
|
||||
*
|
||||
* @since Fictioneer 5.6.0
|
||||
*
|
||||
* @param array $caps Primitive capabilities required of the user.
|
||||
* @param string $cap Capability being checked.
|
||||
*
|
||||
* @return array Filtered primitive capabilities.
|
||||
*/
|
||||
|
||||
function fictioneer_override_default_taxonomy_capability_check( $caps, $cap ) {
|
||||
$targets = [
|
||||
'manage_categories',
|
||||
'edit_categories',
|
||||
'delete_categories',
|
||||
'assign_categories',
|
||||
'manage_post_tags',
|
||||
'edit_post_tags',
|
||||
'delete_post_tags',
|
||||
'assign_post_tags',
|
||||
];
|
||||
|
||||
if ( in_array( $cap, $targets ) ) {
|
||||
$caps = [ $cap ];
|
||||
}
|
||||
|
||||
return $caps;
|
||||
}
|
||||
add_filter( 'map_meta_cap', 'fictioneer_override_default_taxonomy_capability_check', 9999, 2 );
|
||||
|
||||
/**
|
||||
* Restricts tag creation for the 'post_tag' taxonomy
|
||||
*
|
||||
* @since Fictioneer 5.6.0
|
||||
*
|
||||
* @param mixed $term The term to be added.
|
||||
* @param string $taxonomy The taxonomy type of the term.
|
||||
*
|
||||
* @return mixed Either the original term or a WP_Error object.
|
||||
*/
|
||||
|
||||
function fictioneer_restrict_tag_creation( $term, $taxonomy ) {
|
||||
if ( $taxonomy == 'post_tag' ) {
|
||||
return new WP_Error( 'term_addition_blocked', __( 'You are unauthorized to add new terms.' ) );
|
||||
}
|
||||
|
||||
return $term;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'edit_post_tags' ) && ! current_user_can( 'manage_options' ) ) {
|
||||
add_filter( 'pre_insert_term', 'fictioneer_restrict_tag_creation', 9999, 2 );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// RESTRICT URL FIELD FOR POSTS AND PAGES
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Modify post type registration arguments for the "post" and "page" types
|
||||
*
|
||||
* @param array $args Array of arguments for registering a post type.
|
||||
* @param string $post_type The post type slug.
|
||||
*
|
||||
* @return array Modified arguments.
|
||||
*/
|
||||
|
||||
function fictioneer_modify_post_type_args( $args, $post_type ) {
|
||||
if ( 'post' === $post_type || 'page' === $post_type ) {
|
||||
$args['public'] = current_user_can( 'fcn_edit_permalink' ); // Edit permalink in editor
|
||||
$args['show_ui'] = true;
|
||||
$args['show_in_menu'] = true;
|
||||
$args['show_in_admin_bar'] = true;
|
||||
$args['publicly_queryable'] = true;
|
||||
$args['show_in_nav_menus'] = true;
|
||||
$args['exclude_from_search'] = false;
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
add_filter( 'register_post_type_args', 'fictioneer_modify_post_type_args', 10, 2 );
|
||||
|
||||
?>
|
||||
|
@ -684,7 +684,6 @@ if ( ! function_exists( 'fictioneer_make_oauth_user' ) ) {
|
||||
|
||||
// Nice name, and hide admin bar for new subscribers
|
||||
if ( $new ) {
|
||||
update_user_meta( $wp_user->ID, 'show_admin_bar_front', false );
|
||||
update_user_meta( $wp_user->ID, 'nickname', $args['nickname'] );
|
||||
wp_update_user( array( 'ID' => $wp_user->ID, 'display_name' => $args['nickname'] ) );
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,8 +9,8 @@
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param string $post_type Post type.
|
||||
* @param string $post Post object.
|
||||
* @param string $post_type Post type.
|
||||
* @param WP_Post $post Post object.
|
||||
*/
|
||||
|
||||
function fictioneer_add_seo_metabox( $post_type, $post ) {
|
||||
@ -31,7 +31,11 @@ function fictioneer_add_seo_metabox( $post_type, $post ) {
|
||||
}
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_seo' ) && ! fictioneer_seo_plugin_active() ) {
|
||||
if (
|
||||
get_option( 'fictioneer_enable_seo' ) &&
|
||||
! fictioneer_seo_plugin_active() &&
|
||||
current_user_can( 'fcn_seo_meta' )
|
||||
) {
|
||||
add_action( 'add_meta_boxes', 'fictioneer_add_seo_metabox', 10, 2 );
|
||||
}
|
||||
|
||||
@ -187,7 +191,11 @@ function fictioneer_save_seo_metabox( $post_id ) {
|
||||
delete_post_meta( $post_id, 'fictioneer_seo_og_image_cache' );
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_seo' ) && ! fictioneer_seo_plugin_active() ) {
|
||||
if (
|
||||
get_option( 'fictioneer_enable_seo' ) &&
|
||||
! fictioneer_seo_plugin_active() &&
|
||||
current_user_can( 'fcn_seo_meta' )
|
||||
) {
|
||||
add_action( 'save_post', 'fictioneer_save_seo_metabox', 10 );
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,35 @@
|
||||
<?php
|
||||
|
||||
// =============================================================================
|
||||
// LEGACY CLEANUP
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Clean up obsolete database entries
|
||||
*
|
||||
* @since 5.6.0
|
||||
*/
|
||||
|
||||
function fictioneer_bring_out_legacy_trash() {
|
||||
// Setup
|
||||
$options = wp_cache_get( 'alloptions', 'options' );
|
||||
$obsolete = ['fictioneer_disable_html_in_comments', 'fictioneer_block_subscribers_from_admin', 'fictioneer_admin_restrict_menus', 'fictioneer_admin_restrict_private_data', 'fictioneer_admin_reduce_subscriber_profile', 'fictioneer_enable_subscriber_self_delete', 'fictioneer_strip_shortcodes_for_non_administrators', 'fictioneer_restrict_media_access', 'fictioneer_subscription_enabled', 'fictioneer_patreon_badge_map', 'fictioneer_patreon_tier_as_badge', 'fictioneer_patreon_campaign_ids', 'fictioneer_patreon_campaign_id', 'fictioneer_mount_wpdiscuz_theme_styles', 'fictioneer_base_site_width', 'fictioneer_comment_form_selector', 'fictioneer_featherlight_enabled', 'fictioneer_tts_enabled', 'fictioneer_log'];
|
||||
|
||||
// Check for most recent obsolete option, run a delete for everything
|
||||
if ( isset( $options['fictioneer_disable_html_in_comments'] ) ) {
|
||||
foreach ( $obsolete as $trash ) {
|
||||
delete_option( $trash );
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action( 'init', 'fictioneer_bring_out_legacy_trash' );
|
||||
|
||||
// =============================================================================
|
||||
// THEME SETUP
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Sets up theme defaults and registers support for various WordPress features.
|
||||
* Sets up theme defaults and registers support for various WordPress features
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@ -146,7 +170,7 @@ function fictioneer_custom_background() {
|
||||
*
|
||||
* @since 4.7
|
||||
*
|
||||
* @global array $allowedtags Array of allowed tags.
|
||||
* @global array $allowedtags Array of allowed tags.
|
||||
*/
|
||||
|
||||
function fictioneer_modify_allowed_tags() {
|
||||
@ -222,9 +246,6 @@ function fictioneer_root_attributes() {
|
||||
*/
|
||||
|
||||
function fictioneer_style_queue() {
|
||||
// Cache busting
|
||||
$version = FICTIONEER_VERSION;
|
||||
|
||||
// Either load separate small style files on demand or the complete one
|
||||
if ( ! get_option( 'fictioneer_bundle_stylesheets' ) ) {
|
||||
// Setup
|
||||
@ -237,7 +258,7 @@ function fictioneer_style_queue() {
|
||||
'fictioneer-properties',
|
||||
get_template_directory_uri() . '/css/properties.css',
|
||||
[],
|
||||
$version
|
||||
FICTIONEER_VERSION
|
||||
);
|
||||
$application_dependencies[] = 'fictioneer-properties';
|
||||
}
|
||||
@ -247,7 +268,7 @@ function fictioneer_style_queue() {
|
||||
'fictioneer-application',
|
||||
get_template_directory_uri() . '/css/application.css',
|
||||
$application_dependencies,
|
||||
$version
|
||||
FICTIONEER_VERSION
|
||||
);
|
||||
|
||||
// If NOT an archive or search page...
|
||||
@ -258,7 +279,7 @@ function fictioneer_style_queue() {
|
||||
'fictioneer-collections',
|
||||
get_template_directory_uri() . '/css/collections.css',
|
||||
['fictioneer-application'],
|
||||
$version
|
||||
FICTIONEER_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
@ -268,7 +289,7 @@ function fictioneer_style_queue() {
|
||||
'fictioneer-chapter',
|
||||
get_template_directory_uri() . '/css/chapter.css',
|
||||
['fictioneer-application'],
|
||||
$version
|
||||
FICTIONEER_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
@ -278,7 +299,7 @@ function fictioneer_style_queue() {
|
||||
'fictioneer-story',
|
||||
get_template_directory_uri() . '/css/story.css',
|
||||
['fictioneer-application'],
|
||||
$version
|
||||
FICTIONEER_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
@ -288,7 +309,7 @@ function fictioneer_style_queue() {
|
||||
'fictioneer-recommendation',
|
||||
get_template_directory_uri() . '/css/recommendation.css',
|
||||
['fictioneer-application'],
|
||||
$version
|
||||
FICTIONEER_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
@ -298,7 +319,7 @@ function fictioneer_style_queue() {
|
||||
'fictioneer-comments',
|
||||
get_template_directory_uri() . '/css/comments.css',
|
||||
['fictioneer-application'],
|
||||
$version
|
||||
FICTIONEER_VERSION
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -309,7 +330,7 @@ function fictioneer_style_queue() {
|
||||
'fictioneer-archive',
|
||||
get_template_directory_uri() . '/css/taxonomies.css',
|
||||
['fictioneer-application'],
|
||||
$version
|
||||
FICTIONEER_VERSION
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@ -318,7 +339,7 @@ function fictioneer_style_queue() {
|
||||
'fictioneer-complete',
|
||||
get_template_directory_uri() . '/css/complete.css',
|
||||
[],
|
||||
$version
|
||||
FICTIONEER_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
@ -429,63 +450,62 @@ if ( ! function_exists( 'fa_custom_setup_cdn_webfont' ) ) {
|
||||
function fictioneer_add_custom_scripts() {
|
||||
// Setup
|
||||
$post_type = get_post_type();
|
||||
$version = FICTIONEER_VERSION; // Cache busting
|
||||
|
||||
// Utility
|
||||
wp_register_script( 'fictioneer-utility-scripts', get_template_directory_uri() . '/js/utility.min.js', [], $version, true );
|
||||
wp_register_script( 'fictioneer-utility-scripts', get_template_directory_uri() . '/js/utility.min.js', [], FICTIONEER_VERSION, true );
|
||||
|
||||
// Application
|
||||
wp_register_script( 'fictioneer-application-scripts', get_template_directory_uri() . '/js/application.min.js', [ 'fictioneer-utility-scripts', 'wp-i18n'], $version, true );
|
||||
wp_register_script( 'fictioneer-application-scripts', get_template_directory_uri() . '/js/application.min.js', [ 'fictioneer-utility-scripts', 'wp-i18n'], FICTIONEER_VERSION, true );
|
||||
|
||||
// Lightbox
|
||||
if ( get_option( 'fictioneer_enable_lightbox' ) ) {
|
||||
wp_enqueue_script( 'fictioneer-lightbox', get_template_directory_uri() . '/js/lightbox.min.js', ['fictioneer-application-scripts'], $version, true );
|
||||
wp_enqueue_script( 'fictioneer-lightbox', get_template_directory_uri() . '/js/lightbox.min.js', ['fictioneer-application-scripts'], FICTIONEER_VERSION, true );
|
||||
}
|
||||
|
||||
// Mobile menu
|
||||
wp_register_script( 'fictioneer-mobile-menu-scripts', get_template_directory_uri() . '/js/mobile-menu.min.js', [ 'fictioneer-application-scripts'], $version, true );
|
||||
wp_register_script( 'fictioneer-mobile-menu-scripts', get_template_directory_uri() . '/js/mobile-menu.min.js', [ 'fictioneer-application-scripts'], FICTIONEER_VERSION, true );
|
||||
|
||||
// Bookmarks
|
||||
wp_register_script( 'fictioneer-bookmarks-scripts', get_template_directory_uri() . '/js/bookmarks.min.js', [ 'fictioneer-application-scripts'], $version, true );
|
||||
wp_register_script( 'fictioneer-bookmarks-scripts', get_template_directory_uri() . '/js/bookmarks.min.js', [ 'fictioneer-application-scripts'], FICTIONEER_VERSION, true );
|
||||
|
||||
// Consent
|
||||
wp_register_script( 'fictioneer-consent-scripts', get_template_directory_uri() . '/js/consent.min.js', [ 'fictioneer-application-scripts'], $version, true );
|
||||
wp_register_script( 'fictioneer-consent-scripts', get_template_directory_uri() . '/js/consent.min.js', [ 'fictioneer-application-scripts'], FICTIONEER_VERSION, true );
|
||||
|
||||
// Chapter
|
||||
wp_register_script( 'fictioneer-chapter-scripts', get_template_directory_uri() . '/js/chapter.min.js', [ 'fictioneer-application-scripts'], $version, true );
|
||||
wp_register_script( 'fictioneer-chapter-scripts', get_template_directory_uri() . '/js/chapter.min.js', [ 'fictioneer-application-scripts'], FICTIONEER_VERSION, true );
|
||||
|
||||
// Suggestions
|
||||
wp_register_script( 'fictioneer-suggestion-scripts', get_template_directory_uri() . '/js/suggestion.min.js', [ 'fictioneer-chapter-scripts'], $version, true );
|
||||
wp_register_script( 'fictioneer-suggestion-scripts', get_template_directory_uri() . '/js/suggestion.min.js', [ 'fictioneer-chapter-scripts'], FICTIONEER_VERSION, true );
|
||||
|
||||
// Text-To-Speech
|
||||
wp_register_script( 'fictioneer-tts-scripts', get_template_directory_uri() . '/js/tts.min.js', [ 'fictioneer-chapter-scripts'], $version, true );
|
||||
wp_register_script( 'fictioneer-tts-scripts', get_template_directory_uri() . '/js/tts.min.js', [ 'fictioneer-chapter-scripts'], FICTIONEER_VERSION, true );
|
||||
|
||||
// Story
|
||||
wp_register_script( 'fictioneer-story-scripts', get_template_directory_uri() . '/js/story.min.js', [ 'fictioneer-application-scripts'], $version, true );
|
||||
wp_register_script( 'fictioneer-story-scripts', get_template_directory_uri() . '/js/story.min.js', [ 'fictioneer-application-scripts'], FICTIONEER_VERSION, true );
|
||||
|
||||
// User
|
||||
wp_register_script( 'fictioneer-user-scripts', get_template_directory_uri() . '/js/user.min.js', [ 'fictioneer-application-scripts'], $version, true );
|
||||
wp_register_script( 'fictioneer-user-scripts', get_template_directory_uri() . '/js/user.min.js', [ 'fictioneer-application-scripts'], FICTIONEER_VERSION, true );
|
||||
|
||||
// User Profile
|
||||
wp_register_script( 'fictioneer-user-profile-scripts', get_template_directory_uri() . '/js/user-profile.min.js', [ 'fictioneer-application-scripts'], $version, true );
|
||||
wp_register_script( 'fictioneer-user-profile-scripts', get_template_directory_uri() . '/js/user-profile.min.js', [ 'fictioneer-application-scripts'], FICTIONEER_VERSION, true );
|
||||
|
||||
// Follows
|
||||
wp_register_script( 'fictioneer-follows-scripts', get_template_directory_uri() . '/js/follows.min.js', [ 'fictioneer-user-scripts'], $version, true );
|
||||
wp_register_script( 'fictioneer-follows-scripts', get_template_directory_uri() . '/js/follows.min.js', [ 'fictioneer-user-scripts'], FICTIONEER_VERSION, true );
|
||||
|
||||
// Checkmarks
|
||||
wp_register_script( 'fictioneer-checkmarks-scripts', get_template_directory_uri() . '/js/checkmarks.min.js', [ 'fictioneer-application-scripts'], $version, true );
|
||||
wp_register_script( 'fictioneer-checkmarks-scripts', get_template_directory_uri() . '/js/checkmarks.min.js', [ 'fictioneer-application-scripts'], FICTIONEER_VERSION, true );
|
||||
|
||||
// Reminders
|
||||
wp_register_script( 'fictioneer-reminders-scripts', get_template_directory_uri() . '/js/reminders.min.js', [ 'fictioneer-user-scripts'], $version, true );
|
||||
wp_register_script( 'fictioneer-reminders-scripts', get_template_directory_uri() . '/js/reminders.min.js', [ 'fictioneer-user-scripts'], FICTIONEER_VERSION, true );
|
||||
|
||||
// Comments
|
||||
wp_register_script( 'fictioneer-comments-scripts', get_template_directory_uri() . '/js/comments.min.js', [ 'fictioneer-application-scripts'], $version, true );
|
||||
wp_register_script( 'fictioneer-comments-scripts', get_template_directory_uri() . '/js/comments.min.js', [ 'fictioneer-application-scripts'], FICTIONEER_VERSION, true );
|
||||
|
||||
// AJAX Comments
|
||||
wp_register_script( 'fictioneer-ajax-comments-scripts', get_template_directory_uri() . '/js/ajax-comments.min.js', [ 'fictioneer-comments-scripts'], $version, true );
|
||||
wp_register_script( 'fictioneer-ajax-comments-scripts', get_template_directory_uri() . '/js/ajax-comments.min.js', [ 'fictioneer-comments-scripts'], FICTIONEER_VERSION, true );
|
||||
|
||||
// AJAX Bookshelf
|
||||
wp_register_script( 'fictioneer-ajax-bookshelf-scripts', get_template_directory_uri() . '/js/ajax-bookshelf.min.js', [ 'fictioneer-application-scripts'], $version, true );
|
||||
wp_register_script( 'fictioneer-ajax-bookshelf-scripts', get_template_directory_uri() . '/js/ajax-bookshelf.min.js', [ 'fictioneer-application-scripts'], FICTIONEER_VERSION, true );
|
||||
|
||||
// Enqueue utility
|
||||
wp_enqueue_script( 'fictioneer-utility-scripts' );
|
||||
@ -606,6 +626,31 @@ function fictioneer_add_custom_scripts() {
|
||||
}
|
||||
add_action( 'wp_enqueue_scripts', 'fictioneer_add_custom_scripts' );
|
||||
|
||||
/**
|
||||
* Enqueue block editor scripts
|
||||
*
|
||||
* @since 5.6.0
|
||||
*/
|
||||
|
||||
function fictioneer_enqueue_block_editor_scripts() {
|
||||
$current_user = wp_get_current_user();
|
||||
|
||||
wp_register_script(
|
||||
'fictioneer-block-editor-scripts',
|
||||
get_template_directory_uri() . '/js/block-editor.min.js',
|
||||
['wp-blocks', 'wp-element', 'wp-components', 'wp-editor', 'wp-data', 'jquery'],
|
||||
FICTIONEER_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_enqueue_script( 'fictioneer-block-editor-scripts' );
|
||||
|
||||
wp_localize_script( 'fictioneer-block-editor-scripts', 'fictioneerData', array(
|
||||
'userCapabilities' => $current_user->allcaps
|
||||
));
|
||||
}
|
||||
add_action( 'enqueue_block_editor_assets', 'fictioneer_enqueue_block_editor_scripts' );
|
||||
|
||||
// =============================================================================
|
||||
// LOAD TRANSLATIONS FOR JAVASCRIPT
|
||||
// =============================================================================
|
||||
|
@ -150,11 +150,16 @@ if ( ! function_exists( 'fictioneer_get_story_data' ) ) {
|
||||
|
||||
function fictioneer_get_story_data( $story_id, $refresh_comment_count = true, $args = [] ) {
|
||||
$story_id = fictioneer_validate_id( $story_id, 'fcn_story' );
|
||||
$old_data = false;
|
||||
|
||||
if ( ! $story_id ) return false;
|
||||
if ( empty( $story_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check cache
|
||||
$old_data = get_post_meta( $story_id, 'fictioneer_story_data_collection', true );
|
||||
if ( FICTIONEER_ENABLE_STORY_DATA_META_CACHE ) {
|
||||
$old_data = get_post_meta( $story_id, 'fictioneer_story_data_collection', true );
|
||||
}
|
||||
|
||||
if ( ! empty( $old_data ) && $old_data['last_modified'] >= get_the_modified_time( 'U', $story_id ) ) {
|
||||
// Return cached data without refreshing the comment count
|
||||
@ -284,7 +289,9 @@ if ( ! function_exists( 'fictioneer_get_story_data' ) ) {
|
||||
'comment_count_timestamp' => time()
|
||||
);
|
||||
|
||||
update_post_meta( $story_id, 'fictioneer_story_data_collection', $result );
|
||||
if ( FICTIONEER_ENABLE_STORY_DATA_META_CACHE ) {
|
||||
update_post_meta( $story_id, 'fictioneer_story_data_collection', $result );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
@ -1365,6 +1372,9 @@ if ( ! function_exists( 'fictioneer_get_font_colors' ) ) {
|
||||
/**
|
||||
* Explodes string into an array
|
||||
*
|
||||
* Strips lines breaks, trims whitespaces, and removes empty elements.
|
||||
* Values might not be unique.
|
||||
*
|
||||
* @since 5.1.3
|
||||
*
|
||||
* @param string $string The string to explode.
|
||||
@ -1373,8 +1383,11 @@ if ( ! function_exists( 'fictioneer_get_font_colors' ) ) {
|
||||
*/
|
||||
|
||||
function fictioneer_explode_list( $string ) {
|
||||
if ( empty( $string ) ) return [];
|
||||
if ( empty( $string ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$string = str_replace( ["\n", "\r"], '', $string ); // Remove line breaks
|
||||
$array = explode( ',', $string );
|
||||
$array = array_map( 'trim', $array ); // Remove extra whitespaces
|
||||
$array = array_filter( $array, 'strlen' ); // Remove empty elements
|
||||
@ -1666,4 +1679,64 @@ if ( ! function_exists( 'fictioneer_get_stories_total_word_count' ) ) {
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// USER SELF-DELETE
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Deletes the current user's account and anonymized their comments
|
||||
*
|
||||
* @since Fictioneer 5.6.0
|
||||
*
|
||||
* @return bool True if the user was successfully deleted, false otherwise.
|
||||
*/
|
||||
|
||||
function fictioneer_delete_my_account() {
|
||||
// Setup
|
||||
$current_user = wp_get_current_user();
|
||||
|
||||
// Guard
|
||||
if (
|
||||
! $current_user ||
|
||||
$current_user->ID === 1 ||
|
||||
in_array( 'administrator', $current_user->roles ) ||
|
||||
! current_user_can( 'fcn_allow_self_delete' )
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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' => ''
|
||||
)
|
||||
);
|
||||
|
||||
// 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 ) );
|
||||
}
|
||||
|
||||
// Delete user
|
||||
if ( wp_delete_user( $current_user->ID ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Failure
|
||||
return false;
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -978,32 +978,6 @@ function fictioneer_add_menu_link_attributes( $attributes, $item ) {
|
||||
}
|
||||
add_filter( 'nav_menu_link_attributes', 'fictioneer_add_menu_link_attributes', 10, 2 );
|
||||
|
||||
// =============================================================================
|
||||
// STRIP SHORTCODES FROM NON-ADMIN POSTS
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Strip shortcodes for non-admins
|
||||
*
|
||||
* @since Fictioneer 5.4.9
|
||||
*
|
||||
* @param string $content The content to be saved.
|
||||
*
|
||||
* @return string The cleaned content.
|
||||
*/
|
||||
|
||||
function fictioneer_strip_shortcodes_for_non_administrators( $content ) {
|
||||
if ( ! current_user_can( 'administrator' ) ) {
|
||||
$content = strip_shortcodes( $content );
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_strip_shortcodes_for_non_administrators' ) ) {
|
||||
add_filter( 'content_save_pre', 'fictioneer_strip_shortcodes_for_non_administrators' );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// DISABLE WIDGETS
|
||||
// =============================================================================
|
||||
@ -1024,4 +998,27 @@ if ( get_option( 'fictioneer_disable_all_widgets' ) ) {
|
||||
add_action( 'widgets_init', 'fictioneer_disable_widgets', 99 );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// EXTEND ALLOWED FILE TYPES
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Extend the list of allowed types for file uploads
|
||||
*
|
||||
* @since Fictioneer 5.6.0
|
||||
*
|
||||
* @param array $mimes Key-value pairs of file extensions and their MIME types.
|
||||
*
|
||||
* @return array Updated MIME types array.
|
||||
*/
|
||||
|
||||
function fictioneer_extend_allowed_upload_types( $mimes ) {
|
||||
$mimes['svg'] = 'image/svg+xml';
|
||||
$mimes['epub'] = 'application/epub+zip';
|
||||
$mimes['avif'] = 'image/avif';
|
||||
|
||||
return $mimes;
|
||||
}
|
||||
add_filter( 'upload_mimes', 'fictioneer_extend_allowed_upload_types' );
|
||||
|
||||
?>
|
||||
|
@ -146,7 +146,7 @@ function fictioneer_preprocess_comment( $commentdata ) {
|
||||
// Change allowed tags
|
||||
global $allowedtags;
|
||||
|
||||
if ( ! $is_admin && get_option( 'fictioneer_disable_html_in_comments' ) ) {
|
||||
if ( ! current_user_can( 'fcn_simple_comment_html' ) && ! current_user_can( 'unfiltered_html' ) ) {
|
||||
$allowedtags = [];
|
||||
}
|
||||
|
||||
|
@ -9,10 +9,10 @@
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param string $link The HTML markup for the comment reply link.
|
||||
* @param array $args An array of arguments overriding the defaults.
|
||||
* @param WP_Comment $comment The object of the comment being replied.
|
||||
* @param WP_Post $post The WP_Post object.
|
||||
* @param string $link The HTML markup for the comment reply link.
|
||||
* @param array $args An array of arguments overriding the defaults.
|
||||
* @param WP_Comment $comment The object of the comment being replied.
|
||||
* @param WP_Post $post The WP_Post object.
|
||||
*
|
||||
* @return string Reply link.
|
||||
*/
|
||||
@ -108,7 +108,7 @@ if ( ! function_exists( 'fictioneer_comment_header' ) ) {
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int $comment_count Total number of comments.
|
||||
* @param int $comment_count Total number of comments.
|
||||
*/
|
||||
|
||||
function fictioneer_comment_header( $comment_count ) {
|
||||
@ -144,7 +144,7 @@ if ( ! function_exists( 'fictioneer_comments_ajax_skeleton' ) ) {
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int $comments_count Total number of comments.
|
||||
* @param int $comments_count Total number of comments.
|
||||
*/
|
||||
|
||||
function fictioneer_comments_ajax_skeleton( $comments_count ) {
|
||||
@ -205,9 +205,9 @@ if ( ! function_exists( 'fictioneer_ajax_list_comments' ) ) {
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param array $comments Collection of comments to display.
|
||||
* @param int $page Current page number of the comments.
|
||||
* @param array $args With 'commentcode', 'post_author_id', and 'post_id'.
|
||||
* @param array $comments Collection of comments to display.
|
||||
* @param int $page Current page number of the comments.
|
||||
* @param array $args With 'commentcode', 'post_author_id', and 'post_id'.
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_list_comments( $comments, $page, $args = [] ) {
|
||||
@ -253,7 +253,7 @@ if ( ! function_exists( 'fictioneer_ajax_list_comments' ) ) {
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param array $parsed_args Default list arguments.
|
||||
* @param array $parsed_args Default list arguments.
|
||||
*
|
||||
* @return array Modified arguments.
|
||||
*/
|
||||
@ -294,76 +294,6 @@ if ( ! get_option( 'fictioneer_enable_ajax_comments' ) ) {
|
||||
add_filter( 'wp_list_comments_args', 'fictioneer_comment_list_args' );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// GET COMMENT BADGE
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_get_comment_badge' ) ) {
|
||||
/**
|
||||
* Get HTML for comment badge
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $user The current user object.
|
||||
* @param WP_Comment $comment The comment object.
|
||||
* @param int $post_author_id ID of the author of the post the comment is for.
|
||||
*
|
||||
* @return string Badge HTML or empty string.
|
||||
*/
|
||||
|
||||
function fictioneer_get_comment_badge( $user, $comment, $post_author_id ) {
|
||||
// Abort conditions...
|
||||
if ( $user && get_the_author_meta( 'fictioneer_hide_badge', $comment->user_id ) ) return '';
|
||||
|
||||
// Setup
|
||||
$comment_user = get_user_by( 'id', $comment->user_id );
|
||||
$is_post_author = $comment->user_id == $post_author_id;
|
||||
$is_moderator = fictioneer_is_moderator( $comment->user_id );
|
||||
$is_admin = fictioneer_is_admin( $comment->user_id );
|
||||
$badge_body = '<div class="fictioneer-comment__badge %1$s">%2$s</div>';
|
||||
$badge_class = '';
|
||||
$badge = '';
|
||||
|
||||
// Role badge
|
||||
if ( $is_post_author ) {
|
||||
$badge = fcntr( 'author' );
|
||||
$badge_class = 'is-author';
|
||||
} elseif ( $is_admin ) {
|
||||
$badge = fcntr( 'admin' );
|
||||
$badge_class = 'is-admin';
|
||||
} elseif ( $is_moderator ) {
|
||||
$badge = fcntr( 'moderator' );
|
||||
$badge_class = 'is-moderator';
|
||||
}
|
||||
|
||||
// Patreon badge (if no higher badge set yet)
|
||||
if ( empty( $badge ) ) {
|
||||
$badge = fictioneer_get_patreon_badge( $comment_user );
|
||||
$badge_class = 'is-supporter';
|
||||
}
|
||||
|
||||
// Custom badge (can override all)
|
||||
if (
|
||||
get_option( 'fictioneer_enable_custom_badges' ) &&
|
||||
! get_the_author_meta( 'fictioneer_disable_badge_override', $comment->user_id )
|
||||
) {
|
||||
$custom_badge = fictioneer_get_override_badge( $comment_user );
|
||||
|
||||
if ( $custom_badge ) {
|
||||
$badge = $custom_badge;
|
||||
$badge_class = 'badge-override';
|
||||
}
|
||||
}
|
||||
|
||||
// Apply filters
|
||||
$output = empty( $badge ) ? '' : sprintf( $badge_body, $badge_class, $badge );
|
||||
$output = apply_filters( 'fictioneer_filter_comment_badge', $output, $badge, $badge_class );
|
||||
|
||||
// Return badge or empty sting
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// THEME COMMENT TEXT
|
||||
// =============================================================================
|
||||
@ -445,7 +375,7 @@ if ( ! function_exists( 'fictioneer_theme_comment' ) ) {
|
||||
}
|
||||
|
||||
// Badge
|
||||
$badge = fictioneer_get_comment_badge( $current_user, $comment, $post_author_id );
|
||||
$badge = fictioneer_get_comment_badge( get_user_by( 'id', $comment->user_id ), $comment, $post_author_id );
|
||||
|
||||
// Flags
|
||||
$is_caching = fictioneer_caching_active();
|
||||
|
@ -137,7 +137,7 @@ function fictioneer_account_danger_zone( $args ) {
|
||||
get_template_part( 'partials/account/_danger-zone', null, $args );
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_subscriber_self_delete' ) ) {
|
||||
if ( current_user_can( 'fcn_allow_self_delete' ) ) {
|
||||
add_action( 'fictioneer_account_content', 'fictioneer_account_danger_zone', 100 );
|
||||
}
|
||||
|
||||
|
@ -306,13 +306,6 @@ define( 'FICTIONEER_OPTIONS', array(
|
||||
'sanitize_callback' => 'fictioneer_sanitize_checkbox',
|
||||
'label' => __( 'Do not save comment IP addresses', 'fictioneer' ),
|
||||
'default' => false
|
||||
),
|
||||
'fictioneer_block_subscribers_from_admin' => array(
|
||||
'name' => 'fictioneer_block_subscribers_from_admin',
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
'sanitize_callback' => 'fictioneer_sanitize_checkbox',
|
||||
'label' => __( 'Block admin panel access for subscribers', 'fictioneer' ),
|
||||
'default' => false
|
||||
),
|
||||
'fictioneer_logout_redirects_home' => array(
|
||||
'name' => 'fictioneer_logout_redirects_home',
|
||||
@ -334,20 +327,6 @@ define( 'FICTIONEER_OPTIONS', array(
|
||||
'sanitize_callback' => 'fictioneer_sanitize_checkbox',
|
||||
'label' => __( 'Add consent wrappers to embedded content', 'fictioneer' ),
|
||||
'default' => false
|
||||
),
|
||||
'fictioneer_admin_restrict_menus' => array(
|
||||
'name' => 'fictioneer_admin_restrict_menus',
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
'sanitize_callback' => 'fictioneer_sanitize_checkbox',
|
||||
'label' => __( 'Restrict admin menus for non-administrators', 'fictioneer' ),
|
||||
'default' => false
|
||||
),
|
||||
'fictioneer_admin_restrict_private_data' => array(
|
||||
'name' => 'fictioneer_admin_restrict_private_data',
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
'sanitize_callback' => 'fictioneer_sanitize_checkbox',
|
||||
'label' => __( 'Restrict personal data for non-administrators', 'fictioneer' ),
|
||||
'default' => false
|
||||
),
|
||||
'fictioneer_cookie_banner' => array(
|
||||
'name' => 'fictioneer_cookie_banner',
|
||||
@ -538,13 +517,6 @@ define( 'FICTIONEER_OPTIONS', array(
|
||||
'label' => __( 'Enable AJAX user authentication', 'fictioneer' ),
|
||||
'default' => false
|
||||
),
|
||||
'fictioneer_admin_reduce_subscriber_profile' => array(
|
||||
'name' => 'fictioneer_admin_reduce_subscriber_profile',
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
'sanitize_callback' => 'fictioneer_sanitize_checkbox',
|
||||
'label' => __( 'Reduce subscriber user profile', 'fictioneer' ),
|
||||
'default' => false
|
||||
),
|
||||
'fictioneer_disable_application_passwords' => array(
|
||||
'name' => 'fictioneer_disable_application_passwords',
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
@ -559,20 +531,6 @@ define( 'FICTIONEER_OPTIONS', array(
|
||||
'label' => __( 'Enable comment editing', 'fictioneer' ),
|
||||
'default' => false
|
||||
),
|
||||
'fictioneer_enable_subscriber_self_delete' => array(
|
||||
'name' => 'fictioneer_enable_subscriber_self_delete',
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
'sanitize_callback' => 'fictioneer_sanitize_checkbox',
|
||||
'label' => __( 'Allow subscribers to delete their account', 'fictioneer' ),
|
||||
'default' => false
|
||||
),
|
||||
'fictioneer_disable_html_in_comments' => array(
|
||||
'name' => 'fictioneer_disable_html_in_comments',
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
'sanitize_callback' => 'fictioneer_sanitize_checkbox',
|
||||
'label' => __( 'Disable HTML in comments for non-administrators', 'fictioneer' ),
|
||||
'default' => false
|
||||
),
|
||||
'fictioneer_enable_ajax_comment_form' => array(
|
||||
'name' => 'fictioneer_enable_ajax_comment_form',
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
@ -643,13 +601,6 @@ define( 'FICTIONEER_OPTIONS', array(
|
||||
'label' => __( 'Limit chapter stories by author', 'fictioneer' ),
|
||||
'default' => false
|
||||
),
|
||||
'fictioneer_strip_shortcodes_for_non_administrators' => array(
|
||||
'name' => 'fictioneer_strip_shortcodes_for_non_administrators',
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
'sanitize_callback' => 'fictioneer_sanitize_checkbox',
|
||||
'label' => __( 'Disable shortcodes for non-administrators', 'fictioneer' ),
|
||||
'default' => false
|
||||
),
|
||||
'fictioneer_disable_all_widgets' => array(
|
||||
'name' => 'fictioneer_disable_all_widgets',
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
@ -657,11 +608,11 @@ define( 'FICTIONEER_OPTIONS', array(
|
||||
'label' => __( 'Disable all widgets', 'fictioneer' ),
|
||||
'default' => false
|
||||
),
|
||||
'fictioneer_restrict_media_access' => array(
|
||||
'name' => 'fictioneer_restrict_media_access',
|
||||
'fictioneer_flush_object_cache' => array(
|
||||
'name' => 'fictioneer_flush_object_cache',
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
'sanitize_callback' => 'fictioneer_sanitize_checkbox',
|
||||
'label' => __( 'Limit media file management by uploader', 'fictioneer' ),
|
||||
'sanitize_callback' => 'fictioneer_sanitize_disable_widget_checkbox',
|
||||
'label' => __( 'Flush object cache on content updates', 'fictioneer' ),
|
||||
'default' => false
|
||||
)
|
||||
),
|
||||
@ -749,6 +700,13 @@ define( 'FICTIONEER_OPTIONS', array(
|
||||
'sanitize_callback' => 'fictioneer_sanitize_integer',
|
||||
'label' => __( 'Minutes a comment can be edited. -1 for no limit.', 'fictioneer' ),
|
||||
'default' => 15
|
||||
),
|
||||
'fictioneer_upload_size_limit' => array(
|
||||
'name' => 'fictioneer_upload_size_limit',
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
'sanitize_callback' => 'fictioneer_sanitize_integer',
|
||||
'label' => __( '<span>Limit file uploads to</span> %s <span>MB or less for user roles with the "Upload Limit" restriction.</span>', 'fictioneer' ),
|
||||
'default' => 5
|
||||
)
|
||||
),
|
||||
'strings' => array(
|
||||
@ -919,6 +877,14 @@ define( 'FICTIONEER_OPTIONS', array(
|
||||
'label' => __( 'Contact Form Receivers (one email address per line)', 'fictioneer' ),
|
||||
'default' => '',
|
||||
'placeholder' => ''
|
||||
),
|
||||
'fictioneer_upload_mime_types' => array(
|
||||
'name' => 'fictioneer_upload_mime_types',
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
'sanitize_callback' => 'sanitize_textarea_field',
|
||||
'label' => __( 'Comma-separated list of allowed <a href="%s" target="_blank" rel="noreferrer">mime types</a> for user roles with the "Upload Restriction". Must be among the allowed mime type and file extensions of WordPress.', 'fictioneer' ),
|
||||
'default' => FICTIONEER_DEFAULT_UPLOAD_MIME_TYPE_RESTRICTIONS,
|
||||
'placeholder' => FICTIONEER_DEFAULT_UPLOAD_MIME_TYPE_RESTRICTIONS
|
||||
)
|
||||
)
|
||||
));
|
||||
|
@ -39,6 +39,15 @@ function fictioneer_add_admin_menu() {
|
||||
'fictioneer_settings_general'
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'fictioneer',
|
||||
__( 'Roles', 'fictioneer' ),
|
||||
__( 'Roles', 'fictioneer' ),
|
||||
'manage_options',
|
||||
'fictioneer_roles',
|
||||
'fictioneer_settings_roles'
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'fictioneer',
|
||||
__( 'Connections', 'fictioneer' ),
|
||||
@ -167,6 +176,9 @@ if ( ! function_exists( 'fictioneer_settings_header' ) ) {
|
||||
// General tab
|
||||
$output['general'] = '<a href="?page=fictioneer" class="tab' . ( $tab == 'general' ? ' active' : '' ) . '">' . __( 'General', 'fictioneer' ) . '</a>';
|
||||
|
||||
// Roles tab
|
||||
$output['roles'] = '<a href="?page=fictioneer_roles" class="tab' . ( $tab == 'roles' ? ' active' : '' ) . '">' . __( 'Roles', 'fictioneer' ) . '</a>';
|
||||
|
||||
// Connections tab
|
||||
$output['connections'] = '<a href="?page=fictioneer_connections" class="tab' . ( $tab == 'connections' ? ' active' : '' ) . '">' . __( 'Connections', 'fictioneer' ) . '</a>';
|
||||
|
||||
@ -216,7 +228,7 @@ if ( ! function_exists( 'fictioneer_settings_header' ) ) {
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// ADMIN HTML
|
||||
// ADMIN MENU PAGE HTML
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
@ -239,6 +251,16 @@ function fictioneer_settings_general() {
|
||||
get_template_part( 'includes/functions/settings/_settings_page_general' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for general settings page
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
*/
|
||||
|
||||
function fictioneer_settings_roles() {
|
||||
get_template_part( 'includes/functions/settings/_settings_page_roles' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for epubs settings page
|
||||
*
|
||||
@ -288,3 +310,70 @@ function fictioneer_settings_tools() {
|
||||
function fictioneer_settings_logs() {
|
||||
get_template_part( 'includes/functions/settings/_settings_page_logs' );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// ADMIN CONTENT HELPERS
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Renders a role settings capability card
|
||||
*
|
||||
* @since Fictioneer 5.6.0
|
||||
*
|
||||
* @param string $title The title of the card.
|
||||
* @param array $caps An array of capabilities.
|
||||
* @param array $role The WP_Role or equivalent array for the role being checked.
|
||||
*/
|
||||
|
||||
function fictioneer_admin_capability_card( $title, $caps, $role ) {
|
||||
// Start HTML ---> ?>
|
||||
<div class="card">
|
||||
<div class="card-wrapper">
|
||||
<h3 class="card-header"><?php echo $title; ?></h3>
|
||||
<div class="card-content">
|
||||
<div class="card-capabilities row">
|
||||
<?php
|
||||
foreach ( $caps as $cap ) {
|
||||
$role_caps = $role['capabilities'];
|
||||
$set = in_array( $cap, $role_caps ) && ( $role_caps[ $cap ] ?? 0 );
|
||||
$name = str_replace( '_', ' ', $cap );
|
||||
$name = str_replace( 'fcn ', '', $name );
|
||||
$name = ucwords( $name );
|
||||
|
||||
// Special cases
|
||||
$name = $name == 'Unfiltered Html' ? 'Unfiltered HTML' : $name;
|
||||
$name = str_replace( 'Recommendations', 'Recommend.', $name );
|
||||
$name = str_replace( 'Custom Css', 'Custom CSS', $name );
|
||||
$name = str_replace( 'Seo Meta', 'SEO Meta', $name );
|
||||
$name = str_replace( 'Custom Page Css', 'Custom Page CSS', $name );
|
||||
$name = str_replace( 'Custom Epub Css', 'Custom ePUB CSS', $name );
|
||||
|
||||
fictioneer_capability_checkbox( $cap, $name, $set );
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a checkbox for a specific capability
|
||||
*
|
||||
* @since Fictioneer 5.6.0
|
||||
*
|
||||
* @param string $cap The capability slug/string.
|
||||
* @param string $name Human-readable name for the capability.
|
||||
* @param bool $set Whether the checkbox should be checked or not.
|
||||
*/
|
||||
|
||||
function fictioneer_capability_checkbox( $cap, $name, $set ) {
|
||||
// Start HTML ---> ?>
|
||||
<label class="capability-checkbox">
|
||||
<input type="hidden" name="caps[<?php echo $cap; ?>]" value="0">
|
||||
<input class="capability-checkbox__input" name="caps[<?php echo $cap; ?>]" type="checkbox" <?php echo $set ? 'checked' : ''; ?> value="1">
|
||||
<div class="capability-checkbox__name"><?php echo $name; ?></div>
|
||||
</label>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ function fictioneer_verify_tool_action( $action ) {
|
||||
}
|
||||
|
||||
// Guard
|
||||
if ( ! current_user_can( 'administrator' ) || ! is_admin() ) {
|
||||
if ( ! current_user_can( 'manage_options' ) || ! is_admin() ) {
|
||||
wp_die( __( 'You do not have permission to access this page.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
@ -94,12 +94,6 @@ if ( ! defined( 'FICTIONEER_ADMIN_SETTINGS_NOTICES' ) ) {
|
||||
'fictioneer-added-moderator-role' => __( 'Moderator role has been added.', 'fictioneer' ),
|
||||
'fictioneer-not-added-moderator-role' => __( 'Moderator role could not be added or already exists.', 'fictioneer' ),
|
||||
'fictioneer-removed-moderator-role' => __( 'Moderator role has been removed.', 'fictioneer' ),
|
||||
'fictioneer-upgraded-author-role' => __( 'Author role has been upgraded.', 'fictioneer' ),
|
||||
'fictioneer-reset-author-role' => __( 'Author role has been reset.', 'fictioneer' ),
|
||||
'fictioneer-limit-editor-role' => __( 'Editor role has been limited.', 'fictioneer' ),
|
||||
'fictioneer-reset-editor-role' => __( 'Editor role has been reset.', 'fictioneer' ),
|
||||
'fictioneer-upgraded-contributor-role' => __( 'Contributor role has been upgraded.', 'fictioneer' ),
|
||||
'fictioneer-reset-contributor-role' => __( 'Contributor role has been reset.', 'fictioneer' ),
|
||||
'fictioneer-reset-post-relationship-registry' => __( 'Post relationship registry reset.', 'fictioneer' ),
|
||||
'fictioneer-fix-users' => __( 'This function does currently not cover any issues.', 'fictioneer' ),
|
||||
'fictioneer-fix-stories' => __( 'This function does currently not cover any issues.', 'fictioneer' ),
|
||||
@ -107,7 +101,21 @@ if ( ! defined( 'FICTIONEER_ADMIN_SETTINGS_NOTICES' ) ) {
|
||||
'fictioneer-fix-recommendations' => __( 'This function does currently not cover any issues.', 'fictioneer' ),
|
||||
'fictioneer-fix-collections' => __( 'This function does currently not cover any issues.', 'fictioneer' ),
|
||||
'fictioneer-fix-pages' => __( 'This function does currently not cover any issues.', 'fictioneer' ),
|
||||
'fictioneer-fix-posts' => __( 'This function does currently not cover any issues.', 'fictioneer' )
|
||||
'fictioneer-fix-posts' => __( 'This function does currently not cover any issues.', 'fictioneer' ),
|
||||
'fictioneer-updated-role-caps' => __( 'Role capabilities have been updated.', 'fictioneer' ),
|
||||
'fictioneer-updated-editor-caps' => __( 'Editor capabilities have been updated.', 'fictioneer' ),
|
||||
'fictioneer-updated-moderator-caps' => __( 'Moderator capabilities have been updated.', 'fictioneer' ),
|
||||
'fictioneer-updated-author-caps' => __( 'Author capabilities have been updated.', 'fictioneer' ),
|
||||
'fictioneer-updated-contributor-caps' => __( 'Contributor capabilities have been updated.', 'fictioneer' ),
|
||||
'fictioneer-updated-subscriber-caps' => __( 'Subscriber capabilities have been updated.', 'fictioneer' ),
|
||||
'fictioneer-roles-initialized' => __( 'Theme roles initialized.', 'fictioneer' ),
|
||||
'fictioneer-added-role' => __( 'Role added.', 'fictioneer' ),
|
||||
'fictioneer-not-added-role' => __( 'Error. Role could not be added.', 'fictioneer' ),
|
||||
'fictioneer-role-already-exists' => __( 'Error. Role (or sanitized role slug) already exists.', 'fictioneer' ),
|
||||
'fictioneer-renamed-role' => __( 'Role renamed.', 'fictioneer' ),
|
||||
'fictioneer-not-renamed-role' => __( 'Error. Role could not be renamed.', 'fictioneer' ),
|
||||
'fictioneer-removed-role' => __( 'Role removed.', 'fictioneer' ),
|
||||
'fictioneer-not-removed-role' => __( 'Error. Role could not be removed.', 'fictioneer' )
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -312,151 +320,22 @@ function fictioneer_tools_add_moderator_role() {
|
||||
add_action( 'admin_post_fictioneer_add_moderator_role', 'fictioneer_tools_add_moderator_role' );
|
||||
|
||||
/**
|
||||
* Remove a moderator role
|
||||
* Initialize roles
|
||||
*
|
||||
* @since Fictioneer 5.2.5
|
||||
* @since Fictioneer 5.6.0
|
||||
*/
|
||||
|
||||
function fictioneer_tools_remove_moderator_role() {
|
||||
function fictioneer_tools_initialize_roles() {
|
||||
// Verify request
|
||||
fictioneer_verify_tool_action( 'fictioneer_remove_moderator_role' );
|
||||
fictioneer_verify_tool_action( 'fictioneer_initialize_roles' );
|
||||
|
||||
// Remove role
|
||||
remove_role( 'fcn_moderator' );
|
||||
|
||||
// Log
|
||||
fictioneer_log( __( 'Moderator role removed.', 'fictioneer' ) );
|
||||
// Force role initialization
|
||||
fictioneer_initialize_roles( true );
|
||||
|
||||
// Finish
|
||||
fictioneer_finish_tool_action( 'fictioneer-removed-moderator-role' );
|
||||
fictioneer_finish_tool_action( 'fictioneer-roles-initialized' );
|
||||
}
|
||||
add_action( 'admin_post_fictioneer_remove_moderator_role', 'fictioneer_tools_remove_moderator_role' );
|
||||
|
||||
/**
|
||||
* Upgrade author role
|
||||
*
|
||||
* @since Fictioneer 5.2.5
|
||||
*/
|
||||
|
||||
function fictioneer_tools_upgrade_author_role() {
|
||||
// Verify request
|
||||
fictioneer_verify_tool_action( 'fictioneer_upgrade_author_role' );
|
||||
|
||||
// Upgrade role
|
||||
fictioneer_upgrade_author_role();
|
||||
|
||||
// Log
|
||||
fictioneer_log( __( 'Author role upgraded.', 'fictioneer' ) );
|
||||
|
||||
// Finish
|
||||
fictioneer_finish_tool_action( 'fictioneer-upgraded-author-role' );
|
||||
}
|
||||
add_action( 'admin_post_fictioneer_upgrade_author_role', 'fictioneer_tools_upgrade_author_role' );
|
||||
|
||||
/**
|
||||
* Reset author role
|
||||
*
|
||||
* @since Fictioneer 5.2.5
|
||||
*/
|
||||
|
||||
function fictioneer_tools_reset_author_role() {
|
||||
// Verify request
|
||||
fictioneer_verify_tool_action( 'fictioneer_reset_author_role' );
|
||||
|
||||
// Reset role
|
||||
fictioneer_reset_author_role();
|
||||
|
||||
// Log
|
||||
fictioneer_log( __( 'Author role reset.', 'fictioneer' ) );
|
||||
|
||||
// Finish
|
||||
fictioneer_finish_tool_action( 'fictioneer-reset-author-role' );
|
||||
}
|
||||
add_action( 'admin_post_fictioneer_reset_author_role', 'fictioneer_tools_reset_author_role' );
|
||||
|
||||
/**
|
||||
* Upgrade contributor role
|
||||
*
|
||||
* @since Fictioneer 5.2.5
|
||||
*/
|
||||
|
||||
function fictioneer_tools_upgrade_contributor_role() {
|
||||
// Verify request
|
||||
fictioneer_verify_tool_action( 'fictioneer_upgrade_contributor_role' );
|
||||
|
||||
// Upgrade role
|
||||
fictioneer_upgrade_contributor_role();
|
||||
|
||||
// Log
|
||||
fictioneer_log( __( 'Contributor role upgraded.', 'fictioneer' ) );
|
||||
|
||||
// Finish
|
||||
fictioneer_finish_tool_action( 'fictioneer-upgraded-contributor-role' );
|
||||
}
|
||||
add_action( 'admin_post_fictioneer_upgrade_contributor_role', 'fictioneer_tools_upgrade_contributor_role' );
|
||||
|
||||
/**
|
||||
* Reset contributor role
|
||||
*
|
||||
* @since Fictioneer 5.2.5
|
||||
*/
|
||||
|
||||
function fictioneer_tools_reset_contributor_role() {
|
||||
// Verify request
|
||||
fictioneer_verify_tool_action( 'fictioneer_reset_contributor_role' );
|
||||
|
||||
// Reset role
|
||||
fictioneer_reset_contributor_role();
|
||||
|
||||
// Log
|
||||
fictioneer_log( __( 'Contributor role reset.', 'fictioneer' ) );
|
||||
|
||||
// Finish
|
||||
fictioneer_finish_tool_action( 'fictioneer-reset-contributor-role' );
|
||||
}
|
||||
add_action( 'admin_post_fictioneer_reset_contributor_role', 'fictioneer_tools_reset_contributor_role' );
|
||||
|
||||
/**
|
||||
* Limit editor role
|
||||
*
|
||||
* @since Fictioneer 5.2.5
|
||||
*/
|
||||
|
||||
function fictioneer_tools_limit_editor_role() {
|
||||
// Verify request
|
||||
fictioneer_verify_tool_action( 'fictioneer_limit_editor_role' );
|
||||
|
||||
// Limit role
|
||||
fictioneer_limit_editor_role();
|
||||
|
||||
// Log
|
||||
fictioneer_log( __( 'Editor role limited.', 'fictioneer' ) );
|
||||
|
||||
// Finish
|
||||
fictioneer_finish_tool_action( 'fictioneer-limit-editor-role' );
|
||||
}
|
||||
add_action( 'admin_post_fictioneer_limit_editor_role', 'fictioneer_tools_limit_editor_role' );
|
||||
|
||||
/**
|
||||
* Reset editor role
|
||||
*
|
||||
* @since Fictioneer 5.2.5
|
||||
*/
|
||||
|
||||
function fictioneer_tools_reset_editor_role() {
|
||||
// Verify request
|
||||
fictioneer_verify_tool_action( 'fictioneer_reset_editor_role' );
|
||||
|
||||
// Reset role
|
||||
fictioneer_reset_editor_role();
|
||||
|
||||
// Log
|
||||
fictioneer_log( __( 'Editor role reset.', 'fictioneer' ) );
|
||||
|
||||
// Finish
|
||||
fictioneer_finish_tool_action( 'fictioneer-reset-editor-role' );
|
||||
}
|
||||
add_action( 'admin_post_fictioneer_reset_editor_role', 'fictioneer_tools_reset_editor_role' );
|
||||
add_action( 'admin_post_fictioneer_initialize_roles', 'fictioneer_tools_initialize_roles' );
|
||||
|
||||
/**
|
||||
* Convert story tags to genres
|
||||
@ -836,4 +715,274 @@ function fictioneer_tools_fix_recommendations() {
|
||||
}
|
||||
add_action( 'admin_post_fictioneer_fix_recommendations', 'fictioneer_tools_fix_recommendations' );
|
||||
|
||||
// =============================================================================
|
||||
// UPDATE ROLE
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Update role
|
||||
*
|
||||
* @since Fictioneer 5.6.0
|
||||
*/
|
||||
|
||||
function fictioneer_update_role() {
|
||||
// Verify request
|
||||
fictioneer_verify_tool_action( 'fictioneer_update_role' );
|
||||
|
||||
// Permissions?
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_die( __( 'Insufficient permissions.', 'fictioneer' ) );
|
||||
}
|
||||
|
||||
// Setup
|
||||
$role_name = $_REQUEST['role'] ?? '';
|
||||
$role = get_role( $role_name );
|
||||
$notice = 'fictioneer-updated-role-caps';
|
||||
|
||||
// Guard administrators
|
||||
if ( $role_name == 'administrator' ) {
|
||||
wp_die( __( 'Insufficient permissions.', 'fictioneer' ) );
|
||||
}
|
||||
|
||||
// Role not found?
|
||||
if ( empty( $role ) ) {
|
||||
wp_safe_redirect( add_query_arg( array( 'fictioneer-subnav' => $role_name ), wp_get_referer() ) );
|
||||
exit();
|
||||
}
|
||||
|
||||
// Update capabilities
|
||||
foreach ( ( $_POST['caps'] ?? [] ) as $cap => $val ) {
|
||||
if ( empty( $val ) ) {
|
||||
$role->remove_cap( $cap );
|
||||
} else {
|
||||
$role->add_cap( $cap );
|
||||
}
|
||||
}
|
||||
|
||||
if ( in_array( $role_name, ['editor', 'moderator', 'author', 'contributor', 'subscriber'] ) ) {
|
||||
$notice = "fictioneer-updated-{$role_name}-caps";
|
||||
}
|
||||
|
||||
// Redirect
|
||||
wp_safe_redirect(
|
||||
add_query_arg( array( 'success' => $notice, 'fictioneer-subnav' => $role_name ), wp_get_referer() )
|
||||
);
|
||||
|
||||
exit();
|
||||
}
|
||||
add_action( 'admin_post_fictioneer_update_role', 'fictioneer_update_role' );
|
||||
|
||||
// =============================================================================
|
||||
// ROLES
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Add role
|
||||
*
|
||||
* @since Fictioneer 5.6.0
|
||||
*/
|
||||
|
||||
function fictioneer_add_role() {
|
||||
// Verify request
|
||||
fictioneer_verify_tool_action( 'fictioneer_add_role' );
|
||||
|
||||
// Permissions?
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_die( __( 'Insufficient permissions.', 'fictioneer' ) );
|
||||
}
|
||||
|
||||
// Setup
|
||||
$new_role = $_REQUEST['new_role'] ?? '';
|
||||
|
||||
// Name missing
|
||||
if ( empty( $new_role ) ) {
|
||||
wp_safe_redirect(
|
||||
add_query_arg( array( 'failure' => 'fictioneer-not-added-role' ), wp_get_referer() )
|
||||
);
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
// Prepare strings
|
||||
$name = sanitize_text_field( $new_role );
|
||||
$name = wp_strip_all_tags( $new_role );
|
||||
$slug = strtolower( $name );
|
||||
$slug = str_replace( ' ', '_', $slug );
|
||||
$slug = preg_replace( '/[^a-zA-Z0-9 _]/', '', $slug );
|
||||
|
||||
$existing_role = get_role( $slug );
|
||||
$existing_fictioneer_role = get_role( "fcn_{$slug}" );
|
||||
|
||||
// Role already exists
|
||||
if ( ! empty( $existing_role ) || ! empty( $existing_fictioneer_role ) ) {
|
||||
wp_safe_redirect(
|
||||
add_query_arg( array( 'failure' => 'fictioneer-role-already-exists' ), wp_get_referer() )
|
||||
);
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
// Params faulty
|
||||
if ( empty( $name ) || empty( $slug ) ) {
|
||||
wp_safe_redirect(
|
||||
add_query_arg( array( 'failure' => 'fictioneer-not-added-role' ), wp_get_referer() )
|
||||
);
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
// Add role
|
||||
$role = add_role( "fcn_{$slug}", $name );
|
||||
|
||||
// Redirect
|
||||
if ( empty( $role ) ) {
|
||||
wp_safe_redirect(
|
||||
add_query_arg( array( 'failure' => 'fictioneer-not-added-role' ), wp_get_referer() )
|
||||
);
|
||||
} else {
|
||||
wp_safe_redirect(
|
||||
add_query_arg( array( 'success' => 'fictioneer-added-role', 'fictioneer-subnav' => "fcn_{$slug}" ), wp_get_referer() )
|
||||
);
|
||||
}
|
||||
|
||||
exit();
|
||||
}
|
||||
add_action( 'admin_post_fictioneer_add_role', 'fictioneer_add_role' );
|
||||
|
||||
/**
|
||||
* Remove role
|
||||
*
|
||||
* @since Fictioneer 5.6.0
|
||||
*/
|
||||
|
||||
function fictioneer_remove_role() {
|
||||
// Verify request
|
||||
fictioneer_verify_tool_action( 'fictioneer_remove_role' );
|
||||
|
||||
// Permissions?
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_die( __( 'Insufficient permissions.', 'fictioneer' ) );
|
||||
}
|
||||
|
||||
// Setup
|
||||
$role = $_REQUEST['role'] ?? '';
|
||||
$role = sanitize_text_field( $role );
|
||||
$role = wp_strip_all_tags( $role );
|
||||
$role = strtolower( $role );
|
||||
$role = str_replace( ' ', '_', $role );
|
||||
$role = preg_replace( '/[^a-zA-Z0-9 _]/', '', $role );
|
||||
|
||||
// Guard
|
||||
if ( in_array( $role, ['administrator', 'editor', 'author', 'contributor', 'subscriber'] ) ) {
|
||||
wp_die( __( 'This role cannot be removed.', 'fictioneer' ) );
|
||||
}
|
||||
|
||||
// Get users with role
|
||||
$role_holders = new WP_User_Query( array( 'role' => $role ) );
|
||||
|
||||
// Change role to subscriber
|
||||
if ( ! empty( $role_holders->results )) {
|
||||
foreach ( $role_holders->results as $user ) {
|
||||
$user->remove_role( $role );
|
||||
$user->add_role( 'subscriber' );
|
||||
}
|
||||
}
|
||||
|
||||
// Remove role
|
||||
remove_role( $role );
|
||||
|
||||
// Redirect
|
||||
wp_safe_redirect(
|
||||
add_query_arg( array( 'success' => 'fictioneer-removed-role', 'fictioneer-subnav' => '' ), wp_get_referer() )
|
||||
);
|
||||
|
||||
exit();
|
||||
}
|
||||
add_action( 'admin_post_fictioneer_remove_role', 'fictioneer_remove_role' );
|
||||
|
||||
/**
|
||||
* Rename role
|
||||
*
|
||||
* @since Fictioneer 5.6.0
|
||||
*/
|
||||
|
||||
function fictioneer_rename_role() {
|
||||
// Verify request
|
||||
fictioneer_verify_tool_action( 'fictioneer_rename_role' );
|
||||
|
||||
// Permissions?
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_die( __( 'Insufficient permissions.', 'fictioneer' ) );
|
||||
}
|
||||
|
||||
// Setup
|
||||
$role_slug = $_REQUEST['role'] ?? '';
|
||||
$new_name = $_REQUEST['new_name'] ?? '';
|
||||
|
||||
// Params missing
|
||||
if ( empty( $role_slug ) || empty( $new_name ) ) {
|
||||
wp_safe_redirect(
|
||||
add_query_arg( array( 'failure' => 'fictioneer-not-renamed-role' ), wp_get_referer() )
|
||||
);
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
// Prepare strings
|
||||
$new_name = sanitize_text_field( $new_name );
|
||||
$new_name = wp_strip_all_tags( $new_name );
|
||||
$role_slug = strtolower( $role_slug );
|
||||
$role_slug = str_replace( ' ', '_', $role_slug );
|
||||
$role_slug = preg_replace( '/[^a-zA-Z0-9 _]/', '', $role_slug );
|
||||
|
||||
// Guard
|
||||
if ( in_array( $role_slug, ['administrator', 'editor', 'author', 'contributor', 'subscriber'] ) ) {
|
||||
wp_die( __( 'This role cannot be renamed.', 'fictioneer' ) );
|
||||
}
|
||||
|
||||
// Name or slug faulty
|
||||
if ( empty( $new_name ) || empty( $role_slug ) ) {
|
||||
wp_safe_redirect(
|
||||
add_query_arg( array( 'failure' => 'fictioneer-not-renamed-role' ), wp_get_referer() )
|
||||
);
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
// Get role to be renamed
|
||||
$target_role = get_role( $role_slug );
|
||||
|
||||
// Role does not exist
|
||||
if ( empty( $target_role ) ) {
|
||||
wp_safe_redirect(
|
||||
add_query_arg( array( 'failure' => 'fictioneer-not-renamed-role' ), wp_get_referer() )
|
||||
);
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
// Remove old role with old name
|
||||
remove_role( $role_slug );
|
||||
|
||||
// Add new role with new name but old slug
|
||||
$role = add_role( $role_slug, $new_name, $target_role->capabilities );
|
||||
|
||||
// Redirect
|
||||
if ( empty( $role ) ) {
|
||||
// Try to restore old role
|
||||
add_role( $role_slug, $target_role->name, $target_role->capabilities );
|
||||
|
||||
wp_safe_redirect(
|
||||
add_query_arg( array( 'failure' => 'fictioneer-not-renamed-role' ), wp_get_referer() )
|
||||
);
|
||||
} else {
|
||||
wp_safe_redirect(
|
||||
add_query_arg( array( 'success' => 'fictioneer-renamed-role', 'fictioneer-subnav' => $role_slug ), wp_get_referer() )
|
||||
);
|
||||
}
|
||||
|
||||
exit();
|
||||
}
|
||||
add_action( 'admin_post_fictioneer_rename_role', 'fictioneer_rename_role' );
|
||||
|
||||
?>
|
||||
|
@ -18,7 +18,7 @@
|
||||
function fictioneer_validate_settings_ajax() {
|
||||
return is_admin() &&
|
||||
wp_doing_ajax() &&
|
||||
current_user_can( 'administrator' ) &&
|
||||
current_user_can( 'manage_options' ) &&
|
||||
! empty( $_POST['nonce'] ) &&
|
||||
check_admin_referer( 'fictioneer_settings_actions', 'nonce' );
|
||||
}
|
||||
|
@ -50,12 +50,12 @@ $current_epubs = array_slice( $epubs, $offset, $epubs_per_page, true );
|
||||
<div class="card">
|
||||
<div class="card-wrapper">
|
||||
<h3 class="card-header"><?php _e( 'Generated ePUBs', 'fictioneer' ) ?></h3>
|
||||
<div class="card-content">
|
||||
<div class="card-content" style="padding-top: 0;">
|
||||
<div class="overflow-horizontal overflow-table">
|
||||
<div class="table image-cover">
|
||||
<table class="th-no-wrap">
|
||||
|
||||
<thead>
|
||||
<thead style="border-top: 0;">
|
||||
<tr>
|
||||
<th><?php _e( 'Story', 'fictioneer' ) ?></th>
|
||||
<th><?php _e( 'File Name (.epub)', 'fictioneer' ) ?></th>
|
||||
|
@ -109,12 +109,6 @@
|
||||
<div class="text-input row">
|
||||
<label for="fictioneer_system_email_address">
|
||||
<input name="fictioneer_system_email_address" placeholder="<?php echo FICTIONEER_OPTIONS['strings']['fictioneer_system_email_address']['placeholder']; ?>" type="email" id="fictioneer_system_email_address" value="<?php echo esc_attr( get_option( 'fictioneer_system_email_address' ) ); ?>">
|
||||
<div class="popup-note floating invalid dismissable">
|
||||
<div>
|
||||
<span><?php _e( 'Please enter a valid email address or none', 'fictioneer' ) ?></span>
|
||||
<span class="dismiss" data-click="dismiss-popup-note"><i class="fa-solid fa-xmark"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="sub-label"><?php echo FICTIONEER_OPTIONS['strings']['fictioneer_system_email_address']['label']; ?></p>
|
||||
</label>
|
||||
</div>
|
||||
@ -664,7 +658,7 @@
|
||||
</div>
|
||||
|
||||
<div class="textarea row">
|
||||
<textarea name="fictioneer_comments_notice" id="fictioneer_comments_notice" rows="4" style="height: 277px;"><?php echo get_option( 'fictioneer_comments_notice' ); ?></textarea>
|
||||
<textarea name="fictioneer_comments_notice" id="fictioneer_comments_notice" rows="4" style="height: 160px;"><?php echo get_option( 'fictioneer_comments_notice' ); ?></textarea>
|
||||
<p class="sub-label"><?php _e( 'Notice above comments. Leave empty to hide. HTML allowed.', 'fictioneer' ) ?></p>
|
||||
</div>
|
||||
|
||||
@ -753,46 +747,6 @@
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="fictioneer_block_subscribers_from_admin" class="label-wrapped-checkbox row">
|
||||
<input name="fictioneer_block_subscribers_from_admin" type="checkbox" id="fictioneer_block_subscribers_from_admin" <?php echo checked( 1, get_option( 'fictioneer_block_subscribers_from_admin' ), false ); ?> value="1">
|
||||
<div>
|
||||
<span><?php echo FICTIONEER_OPTIONS['booleans']['fictioneer_block_subscribers_from_admin']['label']; ?></span>
|
||||
<p class="sub-label"><?php _e( 'For when you have a frontend account page set up.', 'fictioneer' ) ?></p>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="fictioneer_enable_subscriber_self_delete" class="label-wrapped-checkbox row">
|
||||
<input name="fictioneer_enable_subscriber_self_delete" type="checkbox" id="fictioneer_enable_subscriber_self_delete" <?php echo checked( 1, get_option( 'fictioneer_enable_subscriber_self_delete' ), false ); ?> value="1">
|
||||
<div>
|
||||
<span><?php echo FICTIONEER_OPTIONS['booleans']['fictioneer_enable_subscriber_self_delete']['label']; ?></span>
|
||||
<p class="sub-label"><?php _e( 'Convenient compliance with the “right to erasure”. Roles with higher privileges still need manual deletion.', 'fictioneer' ) ?></p>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="fictioneer_admin_reduce_subscriber_profile" class="label-wrapped-checkbox row">
|
||||
<input name="fictioneer_admin_reduce_subscriber_profile" type="checkbox" id="fictioneer_admin_reduce_subscriber_profile" <?php echo checked( 1, get_option( 'fictioneer_admin_reduce_subscriber_profile' ), false ); ?> value="1">
|
||||
<div>
|
||||
<span><?php echo FICTIONEER_OPTIONS['booleans']['fictioneer_admin_reduce_subscriber_profile']['label']; ?></span>
|
||||
<p class="sub-label"><?php _e( 'Removes superfluous blocks from subscriber profile, such as personal options and application passwords.', 'fictioneer' ) ?></p>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="fictioneer_restrict_media_access" class="label-wrapped-checkbox row">
|
||||
<input name="fictioneer_restrict_media_access" type="checkbox" id="fictioneer_restrict_media_access" <?php echo checked( 1, get_option( 'fictioneer_restrict_media_access' ), false ); ?> value="1">
|
||||
<div>
|
||||
<span><?php echo FICTIONEER_OPTIONS['booleans']['fictioneer_restrict_media_access']['label']; ?></span>
|
||||
<p class="sub-label"><?php _e( 'Users can only see and edit their own uploads in the media library unless they have the "edit_users" capability.', 'fictioneer' ) ?></p>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="fictioneer_strip_shortcodes_for_non_administrators" class="label-wrapped-checkbox row">
|
||||
<input name="fictioneer_strip_shortcodes_for_non_administrators" type="checkbox" id="fictioneer_strip_shortcodes_for_non_administrators" <?php echo checked( 1, get_option( 'fictioneer_strip_shortcodes_for_non_administrators' ), false ); ?> value="1">
|
||||
<div>
|
||||
<span><?php echo FICTIONEER_OPTIONS['booleans']['fictioneer_strip_shortcodes_for_non_administrators']['label']; ?></span>
|
||||
<p class="sub-label"><?php _e( 'Beware! Strips shortcodes from the content when a post is saved by a non-administrator.', 'fictioneer' ) ?></p>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="fictioneer_disable_application_passwords" class="label-wrapped-checkbox row">
|
||||
<input name="fictioneer_disable_application_passwords" type="checkbox" id="fictioneer_disable_application_passwords" <?php echo checked( 1, get_option( 'fictioneer_disable_application_passwords' ), false ); ?> value="1">
|
||||
<div>
|
||||
@ -801,14 +755,6 @@
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="fictioneer_disable_html_in_comments" class="label-wrapped-checkbox row">
|
||||
<input name="fictioneer_disable_html_in_comments" type="checkbox" id="fictioneer_disable_html_in_comments" <?php echo checked( 1, get_option( 'fictioneer_disable_html_in_comments' ), false ); ?> value="1">
|
||||
<div>
|
||||
<span><?php echo FICTIONEER_OPTIONS['booleans']['fictioneer_disable_html_in_comments']['label']; ?></span>
|
||||
<p class="sub-label"><?php _e( 'BBCodes still work and are easier to use anyway.', 'fictioneer' ) ?></p>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="fictioneer_logout_redirects_home" class="label-wrapped-checkbox row">
|
||||
<input name="fictioneer_logout_redirects_home" type="checkbox" id="fictioneer_logout_redirects_home" <?php echo checked( 1, get_option( 'fictioneer_logout_redirects_home' ), false ); ?> value="1">
|
||||
<div>
|
||||
@ -825,27 +771,11 @@
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="fictioneer_admin_restrict_menus" class="label-wrapped-checkbox row">
|
||||
<input name="fictioneer_admin_restrict_menus" type="checkbox" id="fictioneer_admin_restrict_menus" <?php echo checked( 1, get_option( 'fictioneer_admin_restrict_menus' ), false ); ?> value="1">
|
||||
<div>
|
||||
<span><?php echo FICTIONEER_OPTIONS['booleans']['fictioneer_admin_restrict_menus']['label']; ?></span>
|
||||
<p class="sub-label"><?php _e( 'Hides more menus and plugins known to the theme as additional security layer.', 'fictioneer' ) ?></p>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="fictioneer_admin_restrict_private_data" class="label-wrapped-checkbox row">
|
||||
<input name="fictioneer_admin_restrict_private_data" type="checkbox" id="fictioneer_admin_restrict_private_data" <?php echo checked( 1, get_option( 'fictioneer_admin_restrict_private_data' ), false ); ?> value="1">
|
||||
<div>
|
||||
<span><?php echo FICTIONEER_OPTIONS['booleans']['fictioneer_admin_restrict_private_data']['label']; ?></span>
|
||||
<p class="sub-label"><?php _e( 'Hides names, emails, IPs, comment quick edit, and more privacy sensitive data sources.', 'fictioneer' ) ?></p>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="fictioneer_cookie_banner" class="label-wrapped-checkbox row">
|
||||
<input name="fictioneer_cookie_banner" type="checkbox" id="fictioneer_cookie_banner" <?php echo checked( 1, get_option( 'fictioneer_cookie_banner' ), false ); ?> value="1">
|
||||
<div>
|
||||
<span><?php echo FICTIONEER_OPTIONS['booleans']['fictioneer_cookie_banner']['label']; ?></span>
|
||||
<p class="sub-label"><?php _e( "Shows a generic cookie consent banner and activates the <code>fictioneer_get_consent()</code> theme function that returns either false, 'necessary', or 'full'.", 'fictioneer' ) ?></p>
|
||||
<p class="sub-label"><?php _e( "Shows a generic cookie consent banner and activates the <code>fictioneer_get_consent()</code> theme function that returns either false, \"necessary\", or \"full\".", 'fictioneer' ) ?></p>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
@ -853,6 +783,33 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-wrapper">
|
||||
<h3 class="card-header"><?php _e( 'File Uploads', 'fictioneer' ) ?></h3>
|
||||
<div class="card-content">
|
||||
|
||||
<div class="text-input-inline row"><?php
|
||||
printf(
|
||||
FICTIONEER_OPTIONS['integers']['fictioneer_upload_size_limit']['label'],
|
||||
'<input name="fictioneer_upload_size_limit" type="text" id="fictioneer_upload_size_limit" value="' . esc_attr( get_option( 'fictioneer_upload_size_limit', 5 ) ?: 5 ) . '" style="font-family: Consolas, Monaco, monospace; font-size: 87.5%;" class="text-center" size="5" placeholder="5">'
|
||||
)
|
||||
?></div>
|
||||
|
||||
<div class="textarea row">
|
||||
<?php
|
||||
$mime_types = get_option( 'fictioneer_upload_mime_types', FICTIONEER_DEFAULT_UPLOAD_MIME_TYPE_RESTRICTIONS ) ?: FICTIONEER_DEFAULT_UPLOAD_MIME_TYPE_RESTRICTIONS;
|
||||
?>
|
||||
<textarea name="fictioneer_upload_mime_types" id="fictioneer_upload_mime_types" rows="4" style="height: 100px;" placeholder="<?php echo FICTIONEER_DEFAULT_UPLOAD_MIME_TYPE_RESTRICTIONS; ?>"><?php echo $mime_types; ?></textarea>
|
||||
<p class="sub-label"><?php printf(
|
||||
FICTIONEER_OPTIONS['strings']['fictioneer_upload_mime_types']['label'],
|
||||
'https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types'
|
||||
); ?></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-wrapper">
|
||||
<h3 class="card-header"><?php _e( 'Compatibility', 'fictioneer' ) ?></h3>
|
||||
@ -883,6 +840,14 @@
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="fictioneer_flush_object_cache" class="label-wrapped-checkbox row">
|
||||
<input name="fictioneer_flush_object_cache" type="checkbox" id="fictioneer_flush_object_cache" <?php echo checked( 1, get_option( 'fictioneer_flush_object_cache' ), false ); ?> value="1">
|
||||
<div>
|
||||
<span><?php echo FICTIONEER_OPTIONS['booleans']['fictioneer_flush_object_cache']['label']; ?></span>
|
||||
<p class="sub-label"><?php _e( 'The nuclear option if persistent object caches (Memcached, Redis, etc.) act up. Included in the "purge all" setting.', 'fictioneer' ) ?></p>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="fictioneer_enable_cache_compatibility" class="label-wrapped-checkbox row">
|
||||
<input name="fictioneer_enable_cache_compatibility" type="checkbox" id="fictioneer_enable_cache_compatibility" <?php echo checked( 1, get_option( 'fictioneer_enable_cache_compatibility' ), false ); ?> value="1">
|
||||
<div>
|
||||
|
354
includes/functions/settings/_settings_page_roles.php
Normal file
354
includes/functions/settings/_settings_page_roles.php
Normal file
@ -0,0 +1,354 @@
|
||||
<?php
|
||||
/**
|
||||
* Partial: Role Settings
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Fictioneer
|
||||
* @since 5.6.0
|
||||
*/
|
||||
?>
|
||||
|
||||
<?php
|
||||
|
||||
global $pagenow;
|
||||
|
||||
// Setup
|
||||
$roles = wp_roles()->roles;
|
||||
$current_url = add_query_arg( $_GET, admin_url( $pagenow ) );
|
||||
$current_url = remove_query_arg( array( 'success', 'failure' ), $current_url );
|
||||
|
||||
$admin_url = admin_url( 'admin-post.php' );
|
||||
$update_role_nonce = wp_nonce_field( 'fictioneer_update_role', 'fictioneer_nonce', true, false );
|
||||
$add_role_nonce = wp_nonce_field( 'fictioneer_add_role', 'fictioneer_nonce', true, false );
|
||||
$rename_role_nonce = wp_nonce_field( 'fictioneer_rename_role', 'fictioneer_nonce', true, false );
|
||||
|
||||
$remove_message = __( 'Are you sure you want to remove the %s role? All current holders will become Subscribers. Enter %s to confirm.', 'fictioneer' );
|
||||
$remove_confirm = __( 'DELETE', 'fictioneer' );
|
||||
|
||||
$protected_roles = ['administrator', 'editor', 'author', 'contributor', 'subscriber'];
|
||||
|
||||
$editor_caps = array(
|
||||
'fcn_shortcodes',
|
||||
'fcn_select_page_template',
|
||||
'fcn_custom_page_css',
|
||||
'fcn_custom_epub_css',
|
||||
'fcn_seo_meta',
|
||||
'fcn_make_sticky',
|
||||
'fcn_edit_permalink'
|
||||
);
|
||||
|
||||
$restrictions = array(
|
||||
'fcn_reduced_profile',
|
||||
'fcn_edit_only_others_comments',
|
||||
'fcn_upload_limit',
|
||||
'fcn_upload_restrictions'
|
||||
);
|
||||
|
||||
$advanced_caps = array(
|
||||
'fcn_adminbar_access',
|
||||
'fcn_admin_panel_access',
|
||||
'fcn_dashboard_access',
|
||||
'fcn_show_badge',
|
||||
'upload_files',
|
||||
'edit_files',
|
||||
'fcn_allow_self_delete',
|
||||
'unfiltered_html'
|
||||
);
|
||||
|
||||
$admin_caps = array(
|
||||
'fcn_privacy_clearance',
|
||||
'fcn_read_others_files',
|
||||
'fcn_edit_others_files',
|
||||
'fcn_delete_others_files',
|
||||
'list_users',
|
||||
'create_users',
|
||||
'edit_users',
|
||||
'remove_users',
|
||||
'switch_themes',
|
||||
'edit_theme_options',
|
||||
'edit_themes'
|
||||
);
|
||||
|
||||
$taxonomy_caps = array(
|
||||
// Categories
|
||||
'manage_categories',
|
||||
'assign_categories',
|
||||
'edit_categories',
|
||||
'delete_categories',
|
||||
// Tags
|
||||
'manage_post_tags',
|
||||
'assign_post_tags',
|
||||
'edit_post_tags',
|
||||
'delete_post_tags',
|
||||
// Genres
|
||||
'manage_fcn_genres',
|
||||
'assign_fcn_genres',
|
||||
'edit_fcn_genres',
|
||||
'delete_fcn_genres',
|
||||
// Fandoms
|
||||
'manage_fcn_fandoms',
|
||||
'assign_fcn_fandoms',
|
||||
'edit_fcn_fandoms',
|
||||
'delete_fcn_fandoms',
|
||||
// Characters
|
||||
'manage_fcn_characters',
|
||||
'assign_fcn_characters',
|
||||
'edit_fcn_characters',
|
||||
'delete_fcn_characters',
|
||||
// Warnings
|
||||
'manage_fcn_content_warnings',
|
||||
'assign_fcn_content_warnings',
|
||||
'edit_fcn_content_warnings',
|
||||
'delete_fcn_content_warnings'
|
||||
);
|
||||
|
||||
$post_caps = array(
|
||||
'publish_posts',
|
||||
'edit_posts',
|
||||
'delete_posts',
|
||||
'edit_published_posts',
|
||||
'delete_published_posts',
|
||||
'edit_others_posts',
|
||||
'delete_others_posts',
|
||||
'read_private_posts',
|
||||
'edit_private_posts',
|
||||
'delete_private_posts'
|
||||
);
|
||||
|
||||
$page_caps = array(
|
||||
'publish_pages',
|
||||
'edit_pages',
|
||||
'delete_pages',
|
||||
'edit_published_pages',
|
||||
'delete_published_pages',
|
||||
'edit_others_pages',
|
||||
'delete_others_pages',
|
||||
'read_private_pages',
|
||||
'edit_private_pages',
|
||||
'delete_private_pages'
|
||||
);
|
||||
|
||||
$story_caps = array(
|
||||
'publish_fcn_stories',
|
||||
'edit_fcn_stories',
|
||||
'delete_fcn_stories',
|
||||
'edit_published_fcn_stories',
|
||||
'delete_published_fcn_stories',
|
||||
'edit_others_fcn_stories',
|
||||
'delete_others_fcn_stories',
|
||||
'read_private_fcn_stories',
|
||||
'edit_private_fcn_stories',
|
||||
'delete_private_fcn_stories'
|
||||
);
|
||||
|
||||
$chapter_caps = array(
|
||||
'publish_fcn_chapters',
|
||||
'edit_fcn_chapters',
|
||||
'delete_fcn_chapters',
|
||||
'edit_published_fcn_chapters',
|
||||
'delete_published_fcn_chapters',
|
||||
'edit_others_fcn_chapters',
|
||||
'delete_others_fcn_chapters',
|
||||
'read_private_fcn_chapters',
|
||||
'edit_private_fcn_chapters',
|
||||
'delete_private_fcn_chapters'
|
||||
);
|
||||
|
||||
$collection_caps = array(
|
||||
'publish_fcn_collections',
|
||||
'edit_fcn_collections',
|
||||
'delete_fcn_collections',
|
||||
'edit_published_fcn_collections',
|
||||
'delete_published_fcn_collections',
|
||||
'edit_others_fcn_collections',
|
||||
'delete_others_fcn_collections',
|
||||
'read_private_fcn_collections',
|
||||
'edit_private_fcn_collections',
|
||||
'delete_private_fcn_collections'
|
||||
);
|
||||
|
||||
$recommendation_caps = array(
|
||||
'publish_fcn_recommendations',
|
||||
'edit_fcn_recommendations',
|
||||
'delete_fcn_recommendations',
|
||||
'edit_published_fcn_recommendations',
|
||||
'delete_published_fcn_recommendations',
|
||||
'edit_others_fcn_recommendations',
|
||||
'delete_others_fcn_recommendations',
|
||||
'read_private_fcn_recommendations',
|
||||
'edit_private_fcn_recommendations',
|
||||
'delete_private_fcn_recommendations'
|
||||
);
|
||||
|
||||
$all_caps = array(
|
||||
[ __( 'Editor Capabilities', 'fictioneer' ), $editor_caps ],
|
||||
[ __( 'Restricted Capabilities', 'fictioneer' ), $restrictions ],
|
||||
[ __( 'Advanced Capabilities', 'fictioneer' ), $advanced_caps ],
|
||||
[ __( 'Admin Capabilities (Danger)', 'fictioneer' ), $admin_caps ],
|
||||
[ __( 'Taxonomy Capabilities', 'fictioneer' ), $taxonomy_caps ],
|
||||
[ __( 'Post Capabilities', 'fictioneer' ), $post_caps ],
|
||||
[ __( 'Page Capabilities', 'fictioneer' ), $page_caps ],
|
||||
[ __( 'Story Capabilities', 'fictioneer' ), $story_caps ],
|
||||
[ __( 'Chapter Capabilities', 'fictioneer' ), $chapter_caps ],
|
||||
[ __( 'Collection Capabilities', 'fictioneer' ), $collection_caps ],
|
||||
[ __( 'Recommendation Capabilities', 'fictioneer' ), $recommendation_caps ]
|
||||
);
|
||||
|
||||
// Remove administrators (do not touch them!)
|
||||
unset( $roles['administrator'] );
|
||||
|
||||
// Order roles
|
||||
$order = [
|
||||
'editor' => 0,
|
||||
'fcn_moderator' => 1,
|
||||
'author' => 2,
|
||||
'contributor' => 3,
|
||||
'subscriber' => 99
|
||||
];
|
||||
|
||||
uksort(
|
||||
$roles,
|
||||
function( $a, $b ) use ( $order ) {
|
||||
$aVal = $order[ $a ] ?? PHP_INT_MAX;
|
||||
$bVal = $order[ $b ] ?? PHP_INT_MAX;
|
||||
|
||||
return $aVal <=> $bVal;
|
||||
}
|
||||
);
|
||||
|
||||
// Current role
|
||||
$current_role_slug = ( $_GET['fictioneer-subnav'] ?? 0 ) ?: array_keys( $roles )[0];
|
||||
$current_role = $roles[ $current_role_slug ];
|
||||
|
||||
?>
|
||||
|
||||
<div class="fictioneer-ui fictioneer-settings">
|
||||
|
||||
<?php fictioneer_settings_header( 'roles' ); ?>
|
||||
|
||||
<ul class="fictioneer-settings__subnav">
|
||||
<?php
|
||||
foreach ( $roles as $key => $role ) {
|
||||
$role['type'] = $key;
|
||||
$class = $current_role_slug == $key ? ' class="tab active"' : ' class="tab"';
|
||||
$link = add_query_arg( 'fictioneer-subnav', $key, $current_url );
|
||||
|
||||
echo '<a href="' . $link . '" ' . $class . '>' . $role['name'] . '</a>';
|
||||
}
|
||||
?>
|
||||
<button type="button" class="" data-dialog-target="add-role-dialog"><span class="dashicons dashicons-plus"></span></button>
|
||||
</ul>
|
||||
|
||||
<div class="fictioneer-settings__content">
|
||||
<div class="tab-content">
|
||||
|
||||
<form method="post" action="<?php echo $admin_url; ?>">
|
||||
|
||||
<input type="hidden" name="action" value="fictioneer_update_role">
|
||||
<input type="hidden" name="role" value="<?php echo $current_role_slug; ?>">
|
||||
<?php echo $update_role_nonce; ?>
|
||||
|
||||
<div class="columns-layout two-columns">
|
||||
<?php
|
||||
foreach ( $all_caps as $caps ) {
|
||||
fictioneer_admin_capability_card( $caps[0], $caps[1], $current_role );
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap gap-8 space-between">
|
||||
|
||||
<div class="flex flex-wrap gap-8">
|
||||
<button type="submit" class="button button-primary">
|
||||
<?php printf( _x( 'Update %s', 'Update {Role}', 'fictioneer' ), $current_role['name'] ); ?>
|
||||
</button>
|
||||
<?php if ( ! in_array( $current_role_slug, $protected_roles ) ) : ?>
|
||||
<button type="button" class="button" data-dialog-target="rename-role-dialog">
|
||||
<?php _ex( 'Rename', 'Rename role', 'fictioneer' ); ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap gap-8">
|
||||
|
||||
<?php if ( ! in_array( $current_role_slug, $protected_roles ) ) : ?>
|
||||
|
||||
<?php
|
||||
$remove_action = 'fictioneer_remove_role';
|
||||
$remove_link = wp_nonce_url(
|
||||
add_query_arg(
|
||||
'role',
|
||||
$current_role_slug,
|
||||
admin_url( "admin-post.php?action={$remove_action}" )
|
||||
),
|
||||
$remove_action,
|
||||
'fictioneer_nonce'
|
||||
);
|
||||
?>
|
||||
|
||||
<a href="<?php echo $remove_link; ?>" class="button button-secondary confirm-dialog" data-dialog-message="<?php printf( $remove_message, $current_role['name'], $remove_confirm ); ?>" data-dialog-confirm="<?php echo $remove_confirm; ?>">
|
||||
<?php printf( _x( 'Remove %s', 'Remove {Role}', 'fictioneer' ), $current_role['name'] ); ?>
|
||||
</a>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<dialog class="fictioneer-dialog" id="add-role-dialog">
|
||||
<div class="fictioneer-dialog__header">
|
||||
<span><?php _e( 'Add Role', 'fictioneer' ); ?></span>
|
||||
</div>
|
||||
<div class="fictioneer-dialog__content">
|
||||
<form method="post" action="<?php echo $admin_url; ?>">
|
||||
<input type="hidden" name="action" value="fictioneer_add_role">
|
||||
<?php echo $add_role_nonce; ?>
|
||||
<div class="text-input">
|
||||
<label for="fictioneer_add_role">
|
||||
<input id="fictioneer_add_role" name="new_role" placeholder="<?php _ex( 'Role Name', 'fictioneer' ); ?>" type="text" required>
|
||||
<p class="sub-label"><?php _e( 'Enter the name of the new role.', 'fictioneer' ) ?></p>
|
||||
</label>
|
||||
</div>
|
||||
<div class="fictioneer-dialog__actions">
|
||||
<button value="" class="button button-primary"><?php _e( 'Add', 'fictioneer' ); ?></button>
|
||||
<button value="cancel" formmethod="dialog" class="button"><?php _e( 'Cancel', 'fictioneer' ); ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog class="fictioneer-dialog" id="rename-role-dialog">
|
||||
<div class="fictioneer-dialog__header">
|
||||
<span><?php printf( __( 'Rename %s Role', 'fictioneer' ), $current_role['name'] ); ?></span>
|
||||
</div>
|
||||
<div class="fictioneer-dialog__content">
|
||||
<form method="post" action="<?php echo $admin_url; ?>">
|
||||
<input type="hidden" name="action" value="fictioneer_rename_role">
|
||||
<input type="hidden" name="role" value="<?php echo $current_role_slug; ?>">
|
||||
<?php echo $rename_role_nonce; ?>
|
||||
<div class="text-input">
|
||||
<label for="fictioneer_add_role">
|
||||
<input id="fictioneer_add_role" name="new_name" placeholder="<?php _ex( 'New Name', 'fictioneer' ); ?>" type="text" required>
|
||||
<p class="sub-label"><?php _e( 'Enter the new name for the role.', 'fictioneer' ) ?></p>
|
||||
</label>
|
||||
</div>
|
||||
<div class="text-input mt-12">
|
||||
<label for="fictioneer_add_role">
|
||||
<input id="fictioneer_add_role" name="role_slug" placeholder="<?php echo $current_role_slug; ?>" type="text" disabled>
|
||||
<p class="sub-label"><?php _e( 'Slug of the role. Must not be changed.', 'fictioneer' ) ?></p>
|
||||
</label>
|
||||
</div>
|
||||
<div class="fictioneer-dialog__actions">
|
||||
<button value="" class="button button-primary"><?php _e( 'Rename', 'fictioneer' ); ?></button>
|
||||
<button value="cancel" formmethod="dialog" class="button"><?php _e( 'Cancel', 'fictioneer' ); ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
</div>
|
@ -36,14 +36,12 @@ $purge_meta_url = wp_nonce_url( admin_url( 'admin-post.php?action=fictioneer_pur
|
||||
|
||||
<div class="card-content">
|
||||
|
||||
<?php if ( $page_number < 2 ) : ?>
|
||||
<p class="description row"><?php
|
||||
printf(
|
||||
__( 'The following table lists the generated Open Graph metadata used for rich snippets in search engine results and social media embeds. Whether these services actually display the offered data is entirely up to them. You cannot force Google to show your custom description, for example. After all, you could write anything in there. Schemas are generated when a post is first visited and cached until modified or purged. Note that not all post types get a schema. You can set a default OG image under Site Identity in the <a href="%s" target="_blank">customizer</a>.', 'fictioneer' ),
|
||||
wp_customize_url()
|
||||
);
|
||||
?></p>
|
||||
<?php endif; ?>
|
||||
<p class="description row"><?php
|
||||
printf(
|
||||
__( 'The following table lists the generated Open Graph metadata used for rich snippets in search engine results and social media embeds. Whether these services actually display the offered data is entirely up to them. You cannot force Google to show your custom description, for example. After all, you could write anything in there. Schemas are generated when a post is first visited and cached until modified or purged. Note that not all post types get a schema. You can set a default OG image under Site Identity in the <a href="%s" target="_blank">customizer</a>.', 'fictioneer' ),
|
||||
wp_customize_url()
|
||||
);
|
||||
?></p>
|
||||
|
||||
<div class="overflow-horizontal overflow-table">
|
||||
<div class="table image-cover">
|
||||
|
@ -20,28 +20,14 @@
|
||||
<div class="card-wrapper">
|
||||
<h3 class="card-header"><?php _e( 'Role Tools', 'fictioneer' ) ?></h3>
|
||||
<div class="card-content">
|
||||
<p class="description row"><?php _e( '<strong>Add or remove Fictioneer moderator</strong> role that is limited to moderating comments. This role has been stripped of access to most other menus and settings, although it does not necessarily account for changes to the admin interface made by you. <strong>Note:</strong> Removing the moderator role may leave previous owners without a role.', 'fictioneer' ) ?></p>
|
||||
<div class="row flex wrap gap-6">
|
||||
<p class="description row"><?php _e( '<strong>Add or restore moderator role</strong> that is limited to only moderating comments. It has been stripped of access to most other menus and settings, although this does not necessarily account for changes to the admin panel made by you.', 'fictioneer' ) ?></p>
|
||||
<div class="row flex flex-wrap gap-6">
|
||||
<a class="button button--secondary" id="button-move-tags-to-genres" href="<?php echo fictioneer_tool_action( 'fictioneer_add_moderator_role' ); ?>"><?php _e( 'Add Moderator Role', 'fictioneer' ) ?></a>
|
||||
<a class="button button--secondary" id="button-duplicate-tags-to-genres" href="<?php echo fictioneer_tool_action( 'fictioneer_remove_moderator_role' ); ?>"><?php _e( 'Remove Moderator Role', 'fictioneer' ) ?></a>
|
||||
</div>
|
||||
<hr>
|
||||
<p class="description row"><?php _e( '<strong>Upgrade or reset author role.</strong> The default author role lacks the permissions to work with Fictioneer’s custom post types, which require page editing capabilities. You can amend this here for a multi-author website, or reset the permissions.', 'fictioneer' ) ?></p>
|
||||
<div class="row flex gap-6">
|
||||
<a class="button button--secondary" id="upgrade-author-role" href="<?php echo fictioneer_tool_action( 'fictioneer_upgrade_author_role' ); ?>"><?php _e( 'Upgrade Author Role', 'fictioneer' ) ?></a>
|
||||
<a class="button button--secondary" id="reset-author-role" href="<?php echo fictioneer_tool_action( 'fictioneer_reset_author_role' ); ?>"><?php _e( 'Reset Author Role', 'fictioneer' ) ?></a>
|
||||
</div>
|
||||
<hr>
|
||||
<p class="description row"><?php _e( '<strong>Upgrade or reset contributor role.</strong> The default contributor role lacks the permissions to work with Fictioneer’s custom post types, which require page editing capabilities. You can amend this here to allow story and chapter submissions, or reset the permissions.', 'fictioneer' ) ?></p>
|
||||
<div class="row flex wrap gap-6">
|
||||
<a class="button button--secondary" id="upgrade-contributor-role" href="<?php echo fictioneer_tool_action( 'fictioneer_upgrade_contributor_role' ); ?>"><?php _e( 'Upgrade Contributor Role', 'fictioneer' ) ?></a>
|
||||
<a class="button button--secondary" id="reset-contributor-role" href="<?php echo fictioneer_tool_action( 'fictioneer_reset_contributor_role' ); ?>"><?php _e( 'Reset Contributor Role', 'fictioneer' ) ?></a>
|
||||
</div>
|
||||
<hr>
|
||||
<p class="description row"><?php _e( '<strong>Limit or reset editor role.</strong> The default editor role has an unreasonable level of permissions considering what its supposed to do. You can limit that to actual <em>editing</em> here, without publishing or moderation capabilities, or reset the permissions.', 'fictioneer' ) ?></p>
|
||||
<div class="row flex wrap gap-6">
|
||||
<a class="button button--secondary" id="limit-editor-role" href="<?php echo fictioneer_tool_action( 'fictioneer_limit_editor_role' ); ?>"><?php _e( 'Limit Editor Role', 'fictioneer' ) ?></a>
|
||||
<a class="button button--secondary" id="reset-editor-role" href="<?php echo fictioneer_tool_action( 'fictioneer_reset_editor_role' ); ?>"><?php _e( 'Reset Editor Role', 'fictioneer' ) ?></a>
|
||||
<p class="description row"><?php _e( '<strong>Initialize theme roles and capabilities.</strong> Fictioneer comes with extended capabilities and roles that need to be initialized in order to work correctly. This should happen once when you first activate the theme, but you can do it manually here. Note that this will only reset theme-related capabilities, not undo anything else done by other plugins.', 'fictioneer' ) ?></p>
|
||||
<div class="row flex flex-wrap gap-6">
|
||||
<a class="button button--secondary" id="button-initialize-roles" href="<?php echo fictioneer_tool_action( 'fictioneer_initialize_roles' ); ?>"><?php _e( 'Initialize Roles', 'fictioneer' ) ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -52,13 +38,13 @@
|
||||
<h3 class="card-header"><?php _e( 'Story Tools', 'fictioneer' ) ?></h3>
|
||||
<div class="card-content">
|
||||
<p class="description row"><?php _e( '<strong>Convert or duplicate story tags to genres.</strong> If you want to change your previous tagging choices in bulk, you can start here. Converting will turn all tags into genres, duplicating will copy and append them as genres but also keep the originals. No taxonomies are ever deleted with either operation.', 'fictioneer' ) ?></p>
|
||||
<div class="row flex wrap gap-6">
|
||||
<div class="row flex flex-wrap gap-6">
|
||||
<a class="button button--secondary" id="button-move-tags-to-genres" href="<?php echo fictioneer_tool_action( 'fictioneer_move_story_tags_to_genres' ); ?>"><?php _e( 'Tags → Genres', 'fictioneer' ) ?></a>
|
||||
<a class="button button--secondary" id="button-duplicate-tags-to-genres" href="<?php echo fictioneer_tool_action( 'fictioneer_duplicate_story_tags_to_genres' ); ?>"><?php _e( 'Duplicate Tags → Genres', 'fictioneer' ) ?></a>
|
||||
</div>
|
||||
<hr>
|
||||
<p class="description row"><?php _e( '<strong>Purge story data caches.</strong> In order to accelerate story and chapter pages, certain information is collected once and then cached. These caches should get purged whenever you make a relevant update. If that should fail for whatever reason, you can purge them manually here.', 'fictioneer' ) ?></p>
|
||||
<div class="row flex wrap gap-6">
|
||||
<div class="row flex flex-wrap gap-6">
|
||||
<a class="button button--secondary" id="purge-story-data-caches" href="<?php echo fictioneer_tool_action( 'fictioneer_purge_story_data_caches' ); ?>"><?php _e( 'Purge Story Data Caches', 'fictioneer' ) ?></a>
|
||||
</div>
|
||||
</div>
|
||||
@ -70,7 +56,7 @@
|
||||
<h3 class="card-header"><?php _e( 'Chapter Tools', 'fictioneer' ) ?></h3>
|
||||
<div class="card-content">
|
||||
<p class="description row"><?php _e( '<strong>Convert or duplicate chapter tags to genres.</strong> If you want to change your previous tagging choices in bulk, you can start here. Converting will turn all tags into genres, duplicating will copy and append them as genres but also keep the originals. No taxonomies are ever deleted with either operation.', 'fictioneer' ) ?></p>
|
||||
<div class="row flex wrap gap-6">
|
||||
<div class="row flex flex-wrap gap-6">
|
||||
<a class="button button--secondary" id="button-move-tags-to-genres" href="<?php echo fictioneer_tool_action( 'fictioneer_move_chapter_tags_to_genres' ); ?>"><?php _e( 'Tags → Genres', 'fictioneer' ) ?></a>
|
||||
<a class="button button--secondary" id="button-duplicate-tags-to-genres" href="<?php echo fictioneer_tool_action( 'fictioneer_duplicate_chapter_tags_to_genres' ); ?>"><?php _e( 'Duplicate Tags → Genres', 'fictioneer' ) ?></a>
|
||||
</div>
|
||||
@ -108,7 +94,7 @@
|
||||
?>
|
||||
</div>
|
||||
</details>
|
||||
<div class="row flex wrap gap-6">
|
||||
<div class="row flex flex-wrap gap-6">
|
||||
<a class="button button--secondary" id="button-append-default-genres" href="<?php echo fictioneer_tool_action( 'fictioneer_append_default_genres' ); ?>"><?php _e( 'Add Genres', 'fictioneer' ) ?></a>
|
||||
</div>
|
||||
</div>
|
||||
@ -145,7 +131,7 @@
|
||||
?>
|
||||
</div>
|
||||
</details>
|
||||
<div class="row flex wrap gap-6">
|
||||
<div class="row flex flex-wrap gap-6">
|
||||
<a class="button button--secondary" id="button-append-default-tags" href="<?php echo fictioneer_tool_action( 'fictioneer_append_default_tags' ); ?>"><?php _e( 'Add Tags', 'fictioneer' ) ?></a>
|
||||
<a class="button button--secondary" id="button-remove-unused-tags" href="<?php echo fictioneer_tool_action( 'fictioneer_remove_unused_tags' ); ?>"><?php _e( 'Remove Unused Tags', 'fictioneer' ) ?></a>
|
||||
</div>
|
||||
@ -158,7 +144,7 @@
|
||||
<h3 class="card-header"><?php _e( 'Repair Tools', 'fictioneer' ) ?></h3>
|
||||
<div class="card-content">
|
||||
<p class="description row"><?php _e( '<strong>Repair or migrate legacy data.</strong> Regardless of planning and efforts, there can always be updates with changes so drastic that it may cause older databases to become invalid or outright broken. These actions attempt to fix such issues.', 'fictioneer' ) ?></p>
|
||||
<div class="row flex wrap gap-6">
|
||||
<div class="row flex flex-wrap gap-6">
|
||||
<a class="button button--secondary disabled" href="<?php echo fictioneer_tool_action( 'fictioneer_fix_users' ); ?>"><?php _e( 'Fix Users', 'fictioneer' ) ?></a>
|
||||
<a class="button button--secondary disabled" href="<?php echo fictioneer_tool_action( 'fictioneer_fix_stories' ); ?>"><?php _e( 'Fix Stories', 'fictioneer' ) ?></a>
|
||||
<a class="button button--secondary disabled" href="<?php echo fictioneer_tool_action( 'fictioneer_fix_chapters' ); ?>"><?php _e( 'Fix Chapters', 'fictioneer' ) ?></a>
|
||||
@ -176,7 +162,7 @@
|
||||
<pre><?php print_r( fictioneer_get_relationship_registry() ); ?></pre>
|
||||
</code>
|
||||
</details>
|
||||
<div class="row flex wrap gap-6">
|
||||
<div class="row flex flex-wrap gap-6">
|
||||
<a class="button button--secondary" id="reset-post-relationship-registry" data-click="reset-post-relationship-registry" data-prompt="<?php esc_attr_e( 'Are you sure? Repopulating the registry requires re-saving every single post or page you want to be covered. Manually.', 'fictioneer' ) ?>" href="<?php echo fictioneer_tool_action( 'fictioneer_reset_post_relationship_registry' ); ?>"><?php _e( 'Reset Registry', 'fictioneer' ) ?></a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
@ -144,6 +144,37 @@ function fictioneer_admin_profile_clear_data_node() {
|
||||
// Not conditional since clearing your data nodes should always be allowed
|
||||
add_action( 'admin_post_fictioneer_admin_profile_clear_data_node', 'fictioneer_admin_profile_clear_data_node' );
|
||||
|
||||
/**
|
||||
* Self-delete account
|
||||
*
|
||||
* @since Fictioneer 5.6.0
|
||||
*/
|
||||
|
||||
function fictioneer_admin_profile_self_delete() {
|
||||
// Verify request
|
||||
fictioneer_verify_admin_profile_action( 'fictioneer_admin_profile_self_delete' );
|
||||
|
||||
// Setup
|
||||
$sender = absint( $_GET['profile_user_id'] ?? 0 );
|
||||
|
||||
// Guard
|
||||
if ( $sender != get_current_user_id() ) {
|
||||
wp_die( __( 'Access Denied', 'fictioneer' ) );
|
||||
}
|
||||
|
||||
// Delete
|
||||
if ( fictioneer_delete_my_account() ) {
|
||||
wp_redirect( home_url() );
|
||||
exit;
|
||||
} {
|
||||
fictioneer_finish_admin_profile_action( 'admin-profile-not-deleted', 'failure' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( current_user_can( 'fcn_allow_self_delete' ) ) {
|
||||
add_action( 'admin_post_fictioneer_admin_profile_self_delete', 'fictioneer_admin_profile_self_delete' );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// OUTPUT ADMIN PROFILE NOTICES
|
||||
// =============================================================================
|
||||
@ -173,6 +204,7 @@ if ( ! defined( 'FICTIONEER_ADMIN_PROFILE_NOTICES' ) ) {
|
||||
'oauth_merged_google' => __( 'Google account successfully linked.', 'fictioneer' ),
|
||||
'oauth_merged_twitch' => __( 'Twitch account successfully linked.', 'fictioneer' ),
|
||||
'oauth_merged_patreon' => __( 'Patreon account successfully linked.', 'fictioneer' ),
|
||||
'admin-profile-not-deleted' => __( 'Database error. Account could not be deleted.', 'fictioneer' )
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -748,30 +780,32 @@ function fictioneer_admin_profile_author( $profile_user ) {
|
||||
);
|
||||
|
||||
// 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>
|
||||
<?php if ( current_user_can( 'edit_pages' ) ) : ?>
|
||||
<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>
|
||||
<?php endif; ?>
|
||||
<tr class="user-support-message-wrap">
|
||||
<th><label for="fictioneer_support_message"><?php _e( 'Support Message', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
@ -914,4 +948,64 @@ function fictioneer_admin_profile_external_avatar( $profile_user ) {
|
||||
}
|
||||
add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_profile_external_avatar', 50 );
|
||||
|
||||
// =============================================================================
|
||||
// DANGER ZONE SECTION
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Adds HTML for the danger zone section to the wp-admin user profile
|
||||
*
|
||||
* @since Fictioneer 5.6.0
|
||||
*
|
||||
* @param WP_User $profile_user The profile user object. Not necessarily the one
|
||||
* currently editing the profile!
|
||||
*/
|
||||
|
||||
function fictioneer_admin_danger_zone( $profile_user ) {
|
||||
// Setup
|
||||
$is_owner = $profile_user->ID === get_current_user_id();
|
||||
|
||||
// Only for the profile user
|
||||
if ( ! $is_owner ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Action
|
||||
$action = 'fictioneer_admin_profile_self_delete';
|
||||
$confirmation_string = _x( 'delete', 'Prompt confirm deletion string.', 'fictioneer' );
|
||||
$confirmation_message = sprintf(
|
||||
__( 'Are you sure? Your account will be irrevocably deleted, although this will not remove your comments. Enter %s to confirm.', 'fictioneer' ),
|
||||
strtoupper( $confirmation_string )
|
||||
);
|
||||
|
||||
$deletion_url = add_query_arg(
|
||||
array( 'profile_user_id' => $profile_user->ID ),
|
||||
wp_nonce_url( admin_url( "admin-post.php?action={$action}" ), $action, 'fictioneer_nonce' )
|
||||
);
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-danger-zone-wrap">
|
||||
<th><label for=""><?php _e( 'Delete Account', 'fictioneer' ) ?></label></th>
|
||||
<td>
|
||||
<p style="margin: 0.35em 0 1em !important;"><?php _e( 'You can delete your account and associated data with it. Submitted <em>content</em> such as comments will remain under the “Deleted User” name unless you clear that <em>prior</em>. Be aware that once you delete your account, there is no going back.', 'fictioneer' ); ?></p>
|
||||
<fieldset>
|
||||
<div>
|
||||
<a
|
||||
href="<?php echo $deletion_url; ?>"
|
||||
id="delete-my-account"
|
||||
class="button button-danger confirm-dialog"
|
||||
data-dialog-message="<?php echo esc_attr( $confirmation_message ); ?>"
|
||||
data-dialog-confirm="<?php echo esc_attr( $confirmation_string ); ?>"
|
||||
><?php _e( 'Delete Account', 'fictioneer' ); ?></a>
|
||||
</div>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
|
||||
if ( current_user_can( 'fcn_allow_self_delete' ) ) {
|
||||
add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_danger_zone', 9999 );
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -110,8 +110,8 @@ if ( ! function_exists( 'fictioneer_get_custom_avatar_url' ) ) {
|
||||
|
||||
function fictioneer_get_avatar_url( $url, $id_or_email, $args ) {
|
||||
// Abort conditions...
|
||||
if ( $args['force_default'] ?? false ) {
|
||||
return fictioneer_get_default_avatar_url();
|
||||
if ( $args['force_default'] ?? false || empty( $id_or_email ) ) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
// Setup
|
||||
@ -127,7 +127,7 @@ function fictioneer_get_avatar_url( $url, $id_or_email, $args ) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return fictioneer_get_default_avatar_url();
|
||||
return $url;
|
||||
}
|
||||
|
||||
// Return custom avatar if set
|
||||
@ -136,7 +136,7 @@ function fictioneer_get_avatar_url( $url, $id_or_email, $args ) {
|
||||
}
|
||||
|
||||
// Return default avatar
|
||||
return fictioneer_get_default_avatar_url();
|
||||
return $url;
|
||||
};
|
||||
add_filter( 'get_avatar_url', 'fictioneer_get_avatar_url', 10, 3 );
|
||||
|
||||
|
@ -1,250 +0,0 @@
|
||||
<?php
|
||||
|
||||
// =============================================================================
|
||||
// HIDE PRIVACY SENSITIVE DATA FROM NON-ADMINISTRATORS
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Remove email and name columns from user table
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
*
|
||||
* @param array $column_headers Columns to show in the user table.
|
||||
*
|
||||
* @return array Reduced columns to show in the user table.
|
||||
*/
|
||||
|
||||
function fictioneer_hide_users_columns( $column_headers ) {
|
||||
unset( $column_headers['email'] );
|
||||
unset( $column_headers['name'] );
|
||||
return $column_headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove quick edit from comments table
|
||||
*
|
||||
* The quick edit form for comments shows unfortunately private data that
|
||||
* we want to hide if that setting is enabled.
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
*
|
||||
* @param array $actions Actions per row in the comments table.
|
||||
*
|
||||
* @return array Restricted actions per row in the comments table.
|
||||
*/
|
||||
|
||||
function fictioneer_remove_quick_edit( $actions ) {
|
||||
unset( $actions['quickedit'] );
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove URL and email fields from comment edit page
|
||||
*
|
||||
* Since these are not normally accessible, we need to quickly hide them
|
||||
* with JavaScript. This is not a great solution but better than nothing.
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
*/
|
||||
|
||||
function fictioneer_hide_private_data() {
|
||||
wp_add_inline_script(
|
||||
'fictioneer-admin-script',
|
||||
"jQuery(function($) {
|
||||
$('.editcomment tr:nth-child(3)').remove();
|
||||
$('.editcomment tr:nth-child(2)').remove();
|
||||
});"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add filters and action depending on security settings
|
||||
*/
|
||||
|
||||
if ( get_option( 'fictioneer_admin_restrict_private_data' ) && ! current_user_can( 'administrator' ) ) {
|
||||
add_filter( 'manage_users_columns', 'fictioneer_hide_users_columns', 99 );
|
||||
add_filter( 'comment_email', '__return_false', 99 );
|
||||
add_filter( 'get_comment_author_IP', '__return_empty_string', 99 );
|
||||
add_filter( 'comment_row_actions', 'fictioneer_remove_quick_edit', 99 );
|
||||
add_action( 'admin_enqueue_scripts', 'fictioneer_hide_private_data', 99 );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// RESTRICT ADMIN PANEL FOR NON-ADMINISTRATORS
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Remove menu pages from admin panel
|
||||
*
|
||||
* WordPress does remove most menus for users without the required capabilities,
|
||||
* but not all. The same goes for plugins.
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
*/
|
||||
|
||||
function fictioneer_remove_menu_pages() {
|
||||
// Default menus
|
||||
remove_menu_page( 'tools.php' );
|
||||
remove_menu_page( 'plugins.php' );
|
||||
remove_menu_page( 'themes.php' );
|
||||
remove_meta_box( 'dashboard_plugins', 'dashboard', 'normal' );
|
||||
|
||||
// Known plugins
|
||||
remove_menu_page( 'stc-subscribe-settings' );
|
||||
|
||||
// Is not moderator...
|
||||
if ( ! current_user_can( 'moderate_comments' ) ) {
|
||||
remove_menu_page( 'edit-comments.php' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restrict menu access for non-administrators
|
||||
*
|
||||
* This may be somewhat overzealous but ensures that users without the required
|
||||
* capabilities have no way to access these admin pages, regardless whether or not
|
||||
* they could do anything there.
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
*/
|
||||
|
||||
function fictioneer_restrict_menu_access() {
|
||||
// Setup
|
||||
$screen = get_current_screen();
|
||||
$base = $screen->id;
|
||||
|
||||
// No access for non-administrators...
|
||||
if (
|
||||
in_array(
|
||||
$base,
|
||||
['tools', 'export', 'import', 'site-health', 'export-personal-data', 'erase-personal-data', 'themes', 'customize', 'nav-menus', 'theme-editor', 'users', 'user-new', 'options-general']
|
||||
)
|
||||
) {
|
||||
wp_die( __( 'Access denied.', 'fictioneer' ) );
|
||||
}
|
||||
|
||||
// Is not moderator...
|
||||
if ( ! current_user_can( 'moderate_comments' ) ) {
|
||||
if ( $base === 'edit-comments' ) {
|
||||
wp_die( __( 'Access denied.', 'fictioneer' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add filters and action depending on security settings
|
||||
*/
|
||||
|
||||
if ( get_option( 'fictioneer_admin_restrict_menus' ) && ! fictioneer_is_admin( get_current_user_id() ) ) {
|
||||
add_action( 'admin_menu', 'fictioneer_remove_menu_pages' );
|
||||
add_action( 'current_screen', 'fictioneer_restrict_menu_access' );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// RESTRICT COMMENTS (ALSO SEE _ROLES)
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Remove comments column for non-administrators
|
||||
*
|
||||
* @since Fictioneer 5.5.3
|
||||
*
|
||||
* @param array $columns The table columns.
|
||||
*
|
||||
* @return array Modified table column.
|
||||
*/
|
||||
|
||||
function fictioneer_restrict_comments_column( $columns ) {
|
||||
// Administrators and moderators
|
||||
if ( current_user_can( 'moderate_comments' ) ) {
|
||||
return $columns;
|
||||
}
|
||||
|
||||
// Everyone else
|
||||
if ( isset( $columns['comments'] ) ) {
|
||||
unset( $columns['comments'] );
|
||||
}
|
||||
|
||||
// Return modified array
|
||||
return $columns;
|
||||
}
|
||||
add_filter( 'manage_posts_columns', 'fictioneer_restrict_comments_column' );
|
||||
add_filter( 'manage_pages_columns', 'fictioneer_restrict_comments_column' );
|
||||
|
||||
// =============================================================================
|
||||
// RESTRICT MEDIA MANAGER
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Scope media files visibility to the uploader
|
||||
*
|
||||
* @since Fictioneer 5.5.3
|
||||
*
|
||||
* @param WP_Query $query The queried attachments.
|
||||
*/
|
||||
|
||||
function fictioneer_scope_media_to_uploader( $query ) {
|
||||
global $current_user, $pagenow;
|
||||
|
||||
if ( empty( $current_user ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only affect media library on admin side
|
||||
if( 'admin-ajax.php' != $pagenow || $_REQUEST['action'] != 'query-attachments' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Those who can edit posts of others, can also see their files
|
||||
if ( ! current_user_can( 'edit_others_posts' ) ) {
|
||||
$query->set( 'author', $current_user->ID );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restrict edit and delete capabilities of media files
|
||||
*
|
||||
* @since Fictioneer 5.5.3
|
||||
*
|
||||
* @param array $caps Primitive capabilities required of the user.
|
||||
* @param string $cap Capability being checked.
|
||||
* @param int $user_id The user ID.
|
||||
* @param array $args Adds context to the capability check, typically
|
||||
* starting with an object ID.
|
||||
*
|
||||
* @return array The still allowed primitive capabilities of the user.
|
||||
*/
|
||||
|
||||
function fictioneer_restrict_media_edit_delete( $caps, $cap, $user_id, $args ) {
|
||||
// Skip unrelated capabilities
|
||||
if ( 'edit_post' != $cap && 'delete_post' != $cap ) {
|
||||
return $caps;
|
||||
}
|
||||
|
||||
// Those who can edit posts of others, can also edit their files
|
||||
if ( user_can( $user_id, 'edit_others_posts' ) ) {
|
||||
return $caps;
|
||||
}
|
||||
|
||||
// Get the post in question.
|
||||
$post = get_post( $args[0] );
|
||||
|
||||
// Check if an attachment and whether the user is the owner (author)
|
||||
if (
|
||||
empty( $post ) ||
|
||||
$post->post_type != 'attachment' ||
|
||||
$post->post_author == $user_id
|
||||
) {
|
||||
return $caps;
|
||||
}
|
||||
|
||||
// Disallow
|
||||
return ['do_not_allow'];
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_restrict_media_access' ) ) {
|
||||
add_filter( 'map_meta_cap', 'fictioneer_restrict_media_edit_delete', 10, 4 );
|
||||
add_action( 'pre_get_posts', 'fictioneer_scope_media_to_uploader' );
|
||||
}
|
||||
|
||||
?>
|
@ -435,6 +435,105 @@ function fictioneer_cancel_frontend_email_change() {
|
||||
}
|
||||
add_action( 'admin_post_fictioneer_cancel_frontend_email_change', 'fictioneer_cancel_frontend_email_change' );
|
||||
|
||||
// =============================================================================
|
||||
// GET COMMENT BADGE
|
||||
// =============================================================================
|
||||
|
||||
if ( ! function_exists( 'fictioneer_get_comment_badge' ) ) {
|
||||
/**
|
||||
* Get HTML for comment badge
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User|null $user The comment user.
|
||||
* @param WP_Comment|null $comment Optional. The comment object.
|
||||
* @param int $post_author_id Optional. ID of the author of the post
|
||||
* the comment is for.
|
||||
*
|
||||
* @return string Badge HTML or empty string.
|
||||
*/
|
||||
|
||||
function fictioneer_get_comment_badge( $user, $comment = null, $post_author_id = 0 ) {
|
||||
// Pre-setup
|
||||
$user_id = $user ? $user->ID : 0;
|
||||
$filter_args = array(
|
||||
'comment' => $comment,
|
||||
'post_author_id' => $post_author_id
|
||||
);
|
||||
|
||||
// Abort conditions...
|
||||
if ( empty( $user_id ) || get_the_author_meta( 'fictioneer_hide_badge', $user_id ) ) {
|
||||
$filter_args['class'] = 'is-guest';
|
||||
$filter_args['badge'] = '';
|
||||
|
||||
return apply_filters( 'fictioneer_filter_comment_badge', '', $user, $filter_args );
|
||||
}
|
||||
|
||||
// Setup
|
||||
$is_post_author = empty( $comment ) ? false : $comment->user_id == $post_author_id;
|
||||
$is_moderator = fictioneer_is_moderator( $user_id );
|
||||
$is_admin = fictioneer_is_admin( $user_id );
|
||||
$badge_body = '<div class="fictioneer-comment__badge %1$s">%2$s</div>';
|
||||
$badge_class = '';
|
||||
$badge = '';
|
||||
$role_has_badge = user_can( $user_id, 'fcn_show_badge' );
|
||||
|
||||
// Role badge
|
||||
if ( $role_has_badge ) {
|
||||
if ( $is_post_author ) {
|
||||
$badge = fcntr( 'author' );
|
||||
$badge_class = 'is-author';
|
||||
} elseif ( $is_admin ) {
|
||||
$badge = fcntr( 'admin' );
|
||||
$badge_class = 'is-admin';
|
||||
} elseif ( $is_moderator ) {
|
||||
$badge = fcntr( 'moderator' );
|
||||
$badge_class = 'is-moderator';
|
||||
} elseif ( ! empty( $user->roles ) ) {
|
||||
global $wp_roles;
|
||||
|
||||
$role_slug = $user->roles[0] ?? '';
|
||||
$role = $wp_roles->roles[ $role_slug ];
|
||||
|
||||
if ( ! empty( $role_slug ) ) {
|
||||
$badge = $role['name'];
|
||||
$badge_class = "is-{$role_slug}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Patreon badge (if no higher badge set yet)
|
||||
if ( empty( $badge ) ) {
|
||||
$badge = fictioneer_get_patreon_badge( $user );
|
||||
$badge_class = 'is-supporter';
|
||||
}
|
||||
|
||||
// Custom badge (can override all)
|
||||
if (
|
||||
get_option( 'fictioneer_enable_custom_badges' ) &&
|
||||
! get_the_author_meta( 'fictioneer_disable_badge_override', $user_id )
|
||||
) {
|
||||
$custom_badge = fictioneer_get_override_badge( $user );
|
||||
|
||||
if ( $custom_badge ) {
|
||||
$badge = $custom_badge;
|
||||
$badge_class = 'badge-override';
|
||||
}
|
||||
}
|
||||
|
||||
// Apply filters
|
||||
$output = empty( $badge ) ? '' : sprintf( $badge_body, $badge_class, $badge );
|
||||
|
||||
$filter_args['class'] = $badge_class;
|
||||
$filter_args['badge'] = $badge;
|
||||
|
||||
$output = apply_filters( 'fictioneer_filter_comment_badge', $output, $user, $filter_args );
|
||||
|
||||
// Return badge or empty sting
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// GET CUSTOM BADGE
|
||||
// =============================================================================
|
||||
@ -445,16 +544,20 @@ if ( ! function_exists( 'fictioneer_get_override_badge' ) ) {
|
||||
*
|
||||
* @since Fictioneer 4.0
|
||||
*
|
||||
* @param WP_User $user The user.
|
||||
* @param string|boolean $default Default value or false.
|
||||
* @param WP_User $user The user.
|
||||
* @param string|boolean $default Default value or false.
|
||||
*
|
||||
* @return string|boolean The badge label, default, or false.
|
||||
*/
|
||||
|
||||
function fictioneer_get_override_badge( $user, $default = false ) {
|
||||
// Abort conditions...
|
||||
if ( ! $user ) return $default;
|
||||
if ( get_the_author_meta( 'fictioneer_hide_badge', $user->ID ) ) return false;
|
||||
if (
|
||||
! $user ||
|
||||
get_the_author_meta( 'fictioneer_hide_badge', $user->ID )
|
||||
) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
// Setup
|
||||
$badge = get_the_author_meta( 'fictioneer_badge_override', $user->ID );
|
||||
@ -479,21 +582,24 @@ if ( ! function_exists( 'fictioneer_get_patreon_badge' ) ) {
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param WP_User $user The user.
|
||||
* @param string|boolean $default Default value or false.
|
||||
* @param WP_User $user The user.
|
||||
* @param string|boolean $default Default value or false.
|
||||
*
|
||||
* @return string|boolean The badge label, default, or false.
|
||||
*/
|
||||
|
||||
function fictioneer_get_patreon_badge( $user, $default = false ) {
|
||||
// Abort conditions...
|
||||
if ( ! $user ) return $default;
|
||||
if ( ! $user ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
// Setup
|
||||
$patreon_tiers = get_user_meta( $user->ID, 'fictioneer_patreon_tiers', true );
|
||||
$last_updated = is_array( $patreon_tiers ) ? ( $patreon_tiers[0]['timestamp'] ?? 0 ) : 0;
|
||||
|
||||
// Check if still valid (two weeks since last login) if not empty
|
||||
if ( ! empty( $patreon_tiers ) && $patreon_tiers[0]['timestamp'] <= $patreon_tiers[0]['timestamp'] + 1209600 ) {
|
||||
if ( time() <= $last_updated + WEEK_IN_SECONDS * 2 ) {
|
||||
$label = get_option( 'fictioneer_patreon_label' );
|
||||
return empty( $label ) ? _x( 'Patron', 'Default Patreon supporter badge label.', 'fictioneer' ) : $label;
|
||||
}
|
||||
@ -516,7 +622,7 @@ if ( ! function_exists( 'fictioneer_get_user_fingerprint' ) ) {
|
||||
*
|
||||
* @since Fictioneer 4.7
|
||||
*
|
||||
* @param int $user_id User ID to get the hash for.
|
||||
* @param int $user_id User ID to get the hash for.
|
||||
*
|
||||
* @return string The unique fingerprint hash or empty string if not found.
|
||||
*/
|
||||
@ -524,7 +630,11 @@ if ( ! function_exists( 'fictioneer_get_user_fingerprint' ) ) {
|
||||
function fictioneer_get_user_fingerprint( $user_id ) {
|
||||
// Setup
|
||||
$user = get_user_by( 'ID', $user_id );
|
||||
if ( ! $user ) return '';
|
||||
|
||||
if ( ! $user ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$fingerprint = get_user_meta( $user_id, 'fictioneer_user_fingerprint', true );
|
||||
|
||||
// If hash does not yet exist, create one
|
||||
@ -605,7 +715,7 @@ if ( ! function_exists( 'fictioneer_soft_delete_user_comments' ) ) {
|
||||
*
|
||||
* @since Fictioneer 5.0
|
||||
*
|
||||
* @param int $user_id User ID to soft delete the comments for.
|
||||
* @param int $user_id User ID to soft delete the comments for.
|
||||
*
|
||||
* @return array|false Detailed results about the database update. Accounts
|
||||
* for completeness, partial success, and errors. Includes
|
||||
@ -786,11 +896,9 @@ function fictioneer_ajax_delete_my_account() {
|
||||
! $sender_id ||
|
||||
! $current_user ||
|
||||
$sender_id !== $current_user->ID ||
|
||||
$current_user == 1 ||
|
||||
$current_user->ID === 1 ||
|
||||
in_array( 'administrator', $current_user->roles ) ||
|
||||
current_user_can( 'edit_posts' ) ||
|
||||
current_user_can( 'publish_posts' ) ||
|
||||
current_user_can( 'moderate_comments' )
|
||||
! current_user_can( 'fcn_allow_self_delete' )
|
||||
) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
@ -801,33 +909,8 @@ function fictioneer_ajax_delete_my_account() {
|
||||
die(); // Just to be sure
|
||||
}
|
||||
|
||||
// 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' => ''
|
||||
)
|
||||
);
|
||||
|
||||
// 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 ) );
|
||||
}
|
||||
|
||||
// Delete user
|
||||
if ( wp_delete_user( $current_user->ID ) ) {
|
||||
if ( fictioneer_delete_my_account() ) {
|
||||
wp_send_json_success();
|
||||
} else {
|
||||
wp_send_json_error(
|
||||
@ -839,7 +922,7 @@ function fictioneer_ajax_delete_my_account() {
|
||||
}
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_subscriber_self_delete' ) ) {
|
||||
if ( current_user_can( 'fcn_allow_self_delete' ) ) {
|
||||
add_action( 'wp_ajax_fictioneer_ajax_delete_my_account', 'fictioneer_ajax_delete_my_account' );
|
||||
}
|
||||
|
||||
|
2
js/admin.min.js
vendored
2
js/admin.min.js
vendored
@ -1 +1 @@
|
||||
function fcn_getWindowPosition(e){const t=e.getBoundingClientRect();return{top:t.top+window.scrollY,left:t.left+window.scrollX}}var fcn_lastPopupMenu;function fcn_togglePopupMenu(e){const t=_$$$(`popup-${e}`);if(t.classList.contains("hidden")){t.classList.remove("hidden"),fcn_lastPopupMenu&&fcn_togglePopupMenu(fcn_lastPopupMenu.dataset.id);const e=t.closest(".fictioneer-settings"),n=fcn_getWindowPosition(t),o=fcn_getWindowPosition(e),a=window.innerWidth<600?0:o.top;t.style.top=n.top-a+"px",t.style.left=n.left-o.left+"px",t.style.transform="translate(-100%, -50%)",e.append(t),fcn_lastPopupMenu=t}else{t.classList.add("hidden");const n=_$$$(`popup-container-${e}`);t.style.top="50%",t.style.left="0",t.style.transform="",n.append(t),fcn_lastPopupMenu=null}}function fcn_purgeSchema(e){jQuery.ajax({url:fictioneer_ajax.ajax_url,type:"post",data:{action:"fictioneer_ajax_purge_schema",nonce:document.getElementById("fictioneer_admin_nonce").value,id:e},dataType:"json",success:function(t){if(t.success){const t=_$$$(`schema-${e}`);t.querySelector(".text-blob").innerHTML=t.querySelector("summary").innerHTML,t.querySelector(".delete").remove(),t.querySelector(".no-schema-note").classList.remove("hidden")}}})}function fcn_delete_epub(e,t){jQuery.ajax({url:fictioneer_ajax.ajax_url,type:"post",data:{action:"fictioneer_ajax_delete_epub",nonce:document.getElementById("fictioneer_admin_nonce").value,name:e},dataType:"json",success:function(e){e.success&&document.getElementById(`epub-id-${t}`).remove()}})}function fcn_checkInputValidity(e){e.classList.toggle("invalid",e.hasAttribute("required")&&""==e.value||!e.checkValidity())}function fcn_ogMediaUpload(e){e.preventDefault();var t=wp.media({multiple:!1,library:{type:"image"}}).open().on("select",(function(){const e=t.state().get("selection").first().toJSON();_$$$("fictioneer-seo-og-image").value=e.id,_$$$("fictioneer-seo-og-display").setAttribute("src",e.url),_$$$("fictioneer-button-seo-og-image-remove").classList.remove("hidden"),_$(".og-source").classList.add("hidden")}))}function fcn_update_seo_title_chars(){const e=_$$$("fictioneer-seo-title");"{{title}} – {{site}}"!=e.value?_$$$("fictioneer-seo-title-chars").innerHTML=`(${e.value.length}/70)`:_$$$("fictioneer-seo-title-chars").innerHTML=""}function fcn_remove_seo_og_image(e){e.preventDefault();const t=_$$$("fictioneer-seo-og-display").dataset.placeholder;_$$$("fictioneer-seo-og-image").value="",_$$$("fictioneer-seo-og-display").setAttribute("src",t),_$$$("fictioneer-button-seo-og-image-remove").classList.add("hidden")}function fcn_confirmIt(e){const t=e.currentTarget.dataset.dialogMessage,n=e.currentTarget.dataset.dialogConfirm;if(!t||!n)return;const o=prompt(t);o?o.toLowerCase()!=n.toLowerCase()&&e.preventDefault():e.preventDefault()}_$$(".popup-menu-toggle").forEach((e=>{e.addEventListener("click",(e=>{fcn_togglePopupMenu(e.currentTarget.dataset.id),e.stopPropagation()}))})),_$("body").addEventListener("click",(()=>{fcn_lastPopupMenu&&fcn_togglePopupMenu(fcn_lastPopupMenu.dataset.id)})),window.addEventListener("resize",(()=>{fcn_lastPopupMenu&&fcn_togglePopupMenu(fcn_lastPopupMenu.dataset.id)})),_$$(".button-purge-schema").forEach((e=>{e.addEventListener("click",(e=>{fcn_purgeSchema(e.currentTarget.dataset.id)}))})),_$$(".button-delete-epub").forEach((e=>{e.addEventListener("click",(e=>{fcn_delete_epub(e.target.dataset.filename,e.target.dataset.id)}))})),_$$(".fictioneer-ui input[type=email]").forEach((e=>{e.addEventListener("blur",(()=>{fcn_checkInputValidity(e)}))})),(button=_$$$("fictioneer-button-og-upload"))&&button.addEventListener("click",fcn_ogMediaUpload),(button=_$$$("fictioneer-seo-title"))&&(fcn_update_seo_title_chars(),button.addEventListener("keyup",fcn_update_seo_title_chars)),(button=_$$$("fictioneer-button-seo-og-image-remove"))&&button.addEventListener("click",fcn_remove_seo_og_image),_$$(".confirm-dialog").forEach((e=>{e.addEventListener("click",(e=>{fcn_confirmIt(e)}))})),_$("#wp-admin-bar-logout a")?.addEventListener("click",(()=>{localStorage.removeItem("fcnProfileAvatar"),localStorage.removeItem("fcnStoryFollows"),localStorage.removeItem("fcnStoryReminders"),localStorage.removeItem("fcnCheckmarks"),localStorage.removeItem("fcnFingerprint"),localStorage.removeItem("fcnLoginState"),localStorage.removeItem("fcnNonce"),localStorage.removeItem("fcnBookshelfContent"),localStorage.removeItem("fcnChapterBookmarks")})),_$(".fictioneer-settings")?.addEventListener("click",(e=>{const t=e.target.closest("[data-click]"),n=t?.dataset.click;if(n)switch(n){case"purge-all-epubs":case"purge-all-schemas":case"purge-all-meta":case"reset-post-relationship-registry":confirm(t.dataset.prompt)||e.preventDefault();break;case"dismiss-popup-note":t.closest(".popup-note").remove()}}));
|
||||
function fcn_purgeSchema(e){jQuery.ajax({url:fictioneer_ajax.ajax_url,type:"post",data:{action:"fictioneer_ajax_purge_schema",nonce:document.getElementById("fictioneer_admin_nonce").value,id:e},dataType:"json",success:function(t){if(t.success){const t=_$$$(`schema-${e}`);t.querySelector(".text-blob").innerHTML=t.querySelector("summary").innerHTML,t.querySelector(".delete").remove(),t.querySelector(".no-schema-note").classList.remove("hidden")}}})}function fcn_delete_epub(e,t){jQuery.ajax({url:fictioneer_ajax.ajax_url,type:"post",data:{action:"fictioneer_ajax_delete_epub",nonce:document.getElementById("fictioneer_admin_nonce").value,name:e},dataType:"json",success:function(e){e.success&&document.getElementById(`epub-id-${t}`).remove()}})}function fcn_ogMediaUpload(e){e.preventDefault();var t=wp.media({multiple:!1,library:{type:"image"}}).open().on("select",(function(){const e=t.state().get("selection").first().toJSON();_$$$("fictioneer-seo-og-image").value=e.id,_$$$("fictioneer-seo-og-display").setAttribute("src",e.url),_$$$("fictioneer-button-seo-og-image-remove").classList.remove("hidden"),_$(".og-source").classList.add("hidden")}))}function fcn_update_seo_title_chars(){const e=_$$$("fictioneer-seo-title");"{{title}} – {{site}}"!=e.value?_$$$("fictioneer-seo-title-chars").innerHTML=`(${e.value.length}/70)`:_$$$("fictioneer-seo-title-chars").innerHTML=""}function fcn_remove_seo_og_image(e){e.preventDefault();const t=_$$$("fictioneer-seo-og-display").dataset.placeholder;_$$$("fictioneer-seo-og-image").value="",_$$$("fictioneer-seo-og-display").setAttribute("src",t),_$$$("fictioneer-button-seo-og-image-remove").classList.add("hidden")}function fcn_confirmIt(e){const t=e.currentTarget.dataset.dialogMessage,o=e.currentTarget.dataset.dialogConfirm;if(!t||!o)return;const a=prompt(t);a?a.toLowerCase()!=o.toLowerCase()&&e.preventDefault():e.preventDefault()}_$$(".button-purge-schema").forEach((e=>{e.addEventListener("click",(e=>{fcn_purgeSchema(e.currentTarget.dataset.id)}))})),_$$(".button-delete-epub").forEach((e=>{e.addEventListener("click",(e=>{fcn_delete_epub(e.target.dataset.filename,e.target.dataset.id)}))})),(button=_$$$("fictioneer-button-og-upload"))&&button.addEventListener("click",fcn_ogMediaUpload),(button=_$$$("fictioneer-seo-title"))&&(fcn_update_seo_title_chars(),button.addEventListener("keyup",fcn_update_seo_title_chars)),(button=_$$$("fictioneer-button-seo-og-image-remove"))&&button.addEventListener("click",fcn_remove_seo_og_image),_$$(".confirm-dialog").forEach((e=>{e.addEventListener("click",(e=>{fcn_confirmIt(e)}))})),_$("#wp-admin-bar-logout a")?.addEventListener("click",(()=>{localStorage.removeItem("fcnProfileAvatar"),localStorage.removeItem("fcnStoryFollows"),localStorage.removeItem("fcnStoryReminders"),localStorage.removeItem("fcnCheckmarks"),localStorage.removeItem("fcnFingerprint"),localStorage.removeItem("fcnLoginState"),localStorage.removeItem("fcnNonce"),localStorage.removeItem("fcnBookshelfContent"),localStorage.removeItem("fcnChapterBookmarks")})),_$(".fictioneer-settings")?.addEventListener("click",(e=>{const t=e.target.closest("[data-click]"),o=t?.dataset.click;if(o)switch(o){case"purge-all-epubs":case"purge-all-schemas":case"purge-all-meta":case"reset-post-relationship-registry":confirm(t.dataset.prompt)||e.preventDefault()}})),_$$("button[data-dialog-target]").forEach((e=>{e.addEventListener("click",(e=>{_$$$(e.currentTarget.dataset.dialogTarget)?.showModal()}))})),_$$('button[formmethod="dialog"][value="cancel"]').forEach((e=>{e.addEventListener("click",(e=>{e.preventDefault(),e.currentTarget.closest("dialog").close()}))}));
|
1
js/block-editor.min.js
vendored
Normal file
1
js/block-editor.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
wp.domReady((function(){setTimeout((()=>{document.querySelectorAll("label").forEach((e=>{"Stick to the top of the blog"===e.textContent&&(fictioneerData.userCapabilities?.fcn_make_sticky||e.closest(".components-panel__row").remove())}))}),100)}));
|
@ -6,11 +6,11 @@
|
||||
* @subpackage Fictioneer
|
||||
* @since 5.0
|
||||
*
|
||||
* @internal $args['user'] Current user.
|
||||
* @internal $args['is_admin'] True if the user is an administrator.
|
||||
* @internal $args['is_author'] True if the user is an author (by capabilities).
|
||||
* @internal $args['is_editor'] True if the user is an editor.
|
||||
* @internal $args['is_moderator'] True if the user is a moderator (by capabilities).
|
||||
* @internal $args['user'] Current user.
|
||||
* @internal $args['is_admin'] True if the user is an administrator.
|
||||
* @internal $args['is_author'] True if the user is an author (by capabilities).
|
||||
* @internal $args['is_editor'] True if the user is an editor.
|
||||
* @internal $args['is_moderator'] True if the user is a moderator (by capabilities).
|
||||
*/
|
||||
?>
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
$current_user = $args['user'];
|
||||
|
||||
// Do not show for roles above subscriber
|
||||
if ( ! in_array( 'subscriber', $current_user->roles ) ) return;
|
||||
if ( ! current_user_can( 'fcn_allow_self_delete' ) ) return;
|
||||
|
||||
?>
|
||||
|
||||
@ -29,5 +29,5 @@ if ( ! in_array( 'subscriber', $current_user->roles ) ) return;
|
||||
<p class="profile__description"><?php _e( 'You can delete your account and associated data with it. Submitted <em>content</em> such as comments will remain under the “Deleted User” name unless you clear that <em>prior</em>. Be aware that once you delete your account, there is no going back.', 'fictioneer' ); ?></p>
|
||||
|
||||
<div class="profile__actions">
|
||||
<button id="button-delete-my-account" type="button" data-nonce="<?php echo wp_create_nonce( 'fictioneer_delete_account' ); ?>" data-warning="<?php esc_attr_e( 'Are you sure? Your profile will be irrevocably deleted, although this will not remove your comments. Enter %s to confirm.', 'fictioneer' ); ?>" class="button _danger" data-id="<?php echo $current_user->ID; ?>"><?php _e( 'Delete Account', 'fictioneer' ); ?></button>
|
||||
<button id="button-delete-my-account" type="button" data-nonce="<?php echo wp_create_nonce( 'fictioneer_delete_account' ); ?>" data-warning="<?php esc_attr_e( 'Are you sure? Your account will be irrevocably deleted, although this will not remove your comments. Enter %s to confirm.', 'fictioneer' ); ?>" class="button _danger" data-id="<?php echo $current_user->ID; ?>"><?php _e( 'Delete Account', 'fictioneer' ); ?></button>
|
||||
</div>
|
||||
|
@ -19,8 +19,7 @@
|
||||
// Setup
|
||||
$current_user = $args['user'];
|
||||
$avatar = get_avatar( $current_user->ID, 32 );
|
||||
$badge = fictioneer_get_patreon_badge( $current_user );
|
||||
$badge = empty( $badge ) ? fictioneer_get_override_badge( $current_user, 'Badge' ) : $badge;
|
||||
$badge = fictioneer_get_comment_badge( $current_user, null );
|
||||
|
||||
?>
|
||||
|
||||
@ -99,9 +98,7 @@ $badge = empty( $badge ) ? fictioneer_get_override_badge( $current_user, 'Badge'
|
||||
<div class="comment__meta">
|
||||
<div class="comment__author">
|
||||
<span><?php echo $current_user->display_name; ?></span>
|
||||
<?php if ( $badge ) : ?>
|
||||
<div class="comment__badge"><?php echo $badge; ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ( $badge ) echo $badge; ?>
|
||||
</div>
|
||||
<div class="comment__date-and-link"><?php
|
||||
echo date_format(
|
||||
|
@ -22,6 +22,8 @@ if ( ! get_option( 'fictioneer_enable_oauth' ) ) return;
|
||||
// Setup
|
||||
$current_user = $args['user'];
|
||||
$patreon_tiers = get_user_meta( $current_user->ID, 'fictioneer_patreon_tiers', true );
|
||||
$patreon_timestamp = is_array( $patreon_tiers ) ? ( $patreon_tiers[0]['timestamp'] ?? 0 ) : 0;
|
||||
$patreon_expired = $patreon_timestamp + WEEK_IN_SECONDS * 2 < time();
|
||||
$oauth_providers = [
|
||||
['discord', 'Discord'],
|
||||
['twitch', 'Twitch'],
|
||||
@ -36,23 +38,36 @@ $unset_notification = __( '%s connection successfully unset.', 'fictioneer' )
|
||||
|
||||
<p class="profile__description"><?php _e( 'Your profile can be linked to one or more external accounts, such as Discord or Google. You may add or remove these accounts at your own volition, but be aware that removing all accounts will lock you out with no means of access.', 'fictioneer' ) ?></p>
|
||||
|
||||
<ul class="profile__admin-notes">
|
||||
<?php if ( ! empty( $patreon_tiers ) ) : ?>
|
||||
<?php foreach ( $patreon_tiers as $tier ) : ?>
|
||||
<?php if ( is_array( $patreon_tiers ) && ! empty( $patreon_tiers ) ) : ?>
|
||||
|
||||
<?php if ( $patreon_expired ) : ?>
|
||||
<ul class="profile__admin-notes">
|
||||
<li>
|
||||
<i class="fa-solid fa-ribbon"></i>
|
||||
<span>
|
||||
<?php
|
||||
printf(
|
||||
_x( '<b>Patreon:</b> %1$s', 'Pattern form "Patreon: {Tier}"', 'fictioneer' ),
|
||||
$tier['tier']
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<i class="fa-solid fa-hourglass-end"></i>
|
||||
<span><?php _e( '<b>Patreon:</b> Data expires after two weeks. Log in with Patreon again to refresh.', 'fictioneer' ) ?></span>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
|
||||
<?php if ( ! $patreon_expired ) : ?>
|
||||
<ul class="profile__admin-notes">
|
||||
<?php foreach ( $patreon_tiers as $tier ) : ?>
|
||||
<li>
|
||||
<i class="fa-solid fa-ribbon"></i>
|
||||
<span>
|
||||
<?php
|
||||
printf(
|
||||
_x( '<b>Patreon:</b> %1$s', 'Pattern form "Patreon: {Tier}"', 'fictioneer' ),
|
||||
$tier['tier']
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="profile__oauth profile__segment">
|
||||
<?php
|
||||
|
BIN
repo/assets/settings_connections_preview.jpg
Normal file
BIN
repo/assets/settings_connections_preview.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
BIN
repo/assets/settings_epubs_preview.jpg
Normal file
BIN
repo/assets/settings_epubs_preview.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
Binary file not shown.
Before Width: | Height: | Size: 227 KiB After Width: | Height: | Size: 137 KiB |
BIN
repo/assets/settings_phrases_preview.png
Normal file
BIN
repo/assets/settings_phrases_preview.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 95 KiB |
BIN
repo/assets/settings_roles_preview.jpg
Normal file
BIN
repo/assets/settings_roles_preview.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
228
src/js/admin.js
228
src/js/admin.js
@ -1,143 +1,3 @@
|
||||
// =============================================================================
|
||||
// GET POSITION OF ELEMENT RELATIVE TO WINDOW
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @typedef {Object} TopLeftPosition
|
||||
* @property {number} left - The X Coordinate.
|
||||
* @property {number} top - The Y Coordinate.
|
||||
* @inner
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the top-left position of an element relative to the window.
|
||||
*
|
||||
* @since 4.7
|
||||
* @param {HTMLElement} element - Element to get the position for.
|
||||
* @return {TopLeftPosition} Top-left position of the element.
|
||||
*/
|
||||
|
||||
function fcn_getWindowPosition(element) {
|
||||
const rect = element.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
top: rect.top + window.scrollY,
|
||||
left: rect.left + window.scrollX
|
||||
};
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// POPUP MENU
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* The last opened popup menu.
|
||||
*
|
||||
* @type {HTMLElement}
|
||||
*/
|
||||
|
||||
var fcn_lastPopupMenu;
|
||||
|
||||
/**
|
||||
* Toggles a popup menu.
|
||||
*
|
||||
* @description Gets the targeted menu by ID and checks whether it is currently
|
||||
* open or not. If closed, the menu is made visible and immediately relocated to the
|
||||
* closest parent with ".fictioneer-settings" class to escape overflow clippings,
|
||||
* the position set absolute to the new direct parent to remain in place. If open,
|
||||
* this whole process is reversed to restore the original conditions.
|
||||
*
|
||||
* @since 4.7
|
||||
* @param {Number} id - ID of the menu element
|
||||
*/
|
||||
|
||||
function fcn_togglePopupMenu(id) {
|
||||
const menu = _$$$(`popup-${id}`);
|
||||
|
||||
if (menu.classList.contains('hidden')) {
|
||||
// Is closed...
|
||||
menu.classList.remove('hidden');
|
||||
|
||||
if (fcn_lastPopupMenu) {
|
||||
// Close other open menu
|
||||
fcn_togglePopupMenu(fcn_lastPopupMenu.dataset.id);
|
||||
}
|
||||
|
||||
const dest = menu.closest('.fictioneer-settings'),
|
||||
pos_menu = fcn_getWindowPosition(menu),
|
||||
pos_dest = fcn_getWindowPosition(dest),
|
||||
offset = window.innerWidth < 600 ? 0 : pos_dest.top; // Adminbar
|
||||
|
||||
// Position based on new parent and window offset
|
||||
menu.style.top = `${pos_menu.top - offset}px`;
|
||||
menu.style.left = `${pos_menu.left - pos_dest.left}px`;
|
||||
menu.style.transform = 'translate(-100%, -50%)';
|
||||
|
||||
// Move to parent and remember
|
||||
dest.append(menu);
|
||||
fcn_lastPopupMenu = menu;
|
||||
} else {
|
||||
// Is open...
|
||||
menu.classList.add('hidden');
|
||||
|
||||
const dest = _$$$(`popup-container-${id}`);
|
||||
|
||||
// Reverse positioning
|
||||
menu.style.top = '50%';
|
||||
menu.style.left = '0';
|
||||
menu.style.transform = '';
|
||||
|
||||
// Move back to origin and unset reference
|
||||
dest.append(menu);
|
||||
fcn_lastPopupMenu = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clicking on any element with the .popup-menu-toggle class
|
||||
* toggles the associated popup menu via the data-id attribute.
|
||||
*/
|
||||
|
||||
_$$('.popup-menu-toggle').forEach(element => {
|
||||
element.addEventListener(
|
||||
'click',
|
||||
(e) => {
|
||||
fcn_togglePopupMenu(e.currentTarget.dataset.id);
|
||||
e.stopPropagation(); // Prevent close click from firing
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Clicking anywhere except the menu toggle will close the last opened
|
||||
* popup menu, including the popup menu itself. This does not matter
|
||||
* since a click into the menu will also bubble up to the menu action,
|
||||
* dismissing the menu as expected.
|
||||
*/
|
||||
|
||||
_$('body').addEventListener(
|
||||
'click',
|
||||
() => {
|
||||
if (fcn_lastPopupMenu) {
|
||||
fcn_togglePopupMenu(fcn_lastPopupMenu.dataset.id);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Resizing the window would cause an open popup menu to become misplaced,
|
||||
* so better close it and reset the location.
|
||||
*/
|
||||
|
||||
window.addEventListener(
|
||||
'resize',
|
||||
() => {
|
||||
if (fcn_lastPopupMenu) {
|
||||
fcn_togglePopupMenu(fcn_lastPopupMenu.dataset.id);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/* =============================================================================
|
||||
** SCHEMAS
|
||||
** ========================================================================== */
|
||||
@ -229,38 +89,6 @@ _$$('.button-delete-epub').forEach(element => {
|
||||
);
|
||||
});
|
||||
|
||||
// =============================================================================
|
||||
// INPUT VALIDATIONS
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Adds .invalid class to an :invalid input.
|
||||
*
|
||||
* @description If the element is :invalid by HTML5 validation, the .invalid class
|
||||
* is added. Otherwise, the class is removed.
|
||||
*
|
||||
* @since 4.7
|
||||
* @param {HTMLElement} element - The element to check for validity.
|
||||
*/
|
||||
|
||||
function fcn_checkInputValidity(element) {
|
||||
element.classList.toggle(
|
||||
'invalid',
|
||||
(element.hasAttribute('required') && element.value == '') ||
|
||||
!element.checkValidity()
|
||||
);
|
||||
}
|
||||
|
||||
// Listen for blur on email inputs
|
||||
_$$('.fictioneer-ui input[type=email]').forEach(element => {
|
||||
element.addEventListener(
|
||||
'blur',
|
||||
() => {
|
||||
fcn_checkInputValidity(element)
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// =============================================================================
|
||||
// SEO METABOX
|
||||
// =============================================================================
|
||||
@ -427,8 +255,58 @@ _$('.fictioneer-settings')?.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
}
|
||||
break;
|
||||
case 'dismiss-popup-note':
|
||||
clickTarget.closest('.popup-note').remove();
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// =============================================================================
|
||||
// SUBNAV TABS
|
||||
// =============================================================================
|
||||
|
||||
// _$('.fictioneer-settings__subnav')?.addEventListener('click', event => {
|
||||
// const clickTarget = event.target.closest('[data-subnav-click]');
|
||||
|
||||
// if (!clickTarget) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// const navTarget = _$(`[data-subnav-target="${clickTarget.dataset.subnavClick}"]`);
|
||||
|
||||
// if (!navTarget) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// _$$('[data-subnav-target]').forEach(element => {
|
||||
// element.classList.add('hidden');
|
||||
// });
|
||||
|
||||
// _$$('[data-subnav-click]').forEach(element => {
|
||||
// element.classList.remove('active');
|
||||
// });
|
||||
|
||||
// navTarget.classList.remove('hidden');
|
||||
// clickTarget.classList.add('active');
|
||||
|
||||
// window.history.pushState(
|
||||
// {},
|
||||
// '',
|
||||
// window.location.href += `&fictioneer-subnav=${clickTarget.dataset.subnavClick}`
|
||||
// );
|
||||
// });
|
||||
|
||||
// =============================================================================
|
||||
// DIALOGS
|
||||
// =============================================================================
|
||||
|
||||
_$$('button[data-dialog-target]').forEach(element => {
|
||||
element.addEventListener('click', event => {
|
||||
_$$$(event.currentTarget.dataset.dialogTarget)?.showModal();
|
||||
});
|
||||
});
|
||||
|
||||
// Close regardless of required fields
|
||||
_$$('button[formmethod="dialog"][value="cancel"]').forEach(element => {
|
||||
element.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
event.currentTarget.closest('dialog').close();
|
||||
});
|
||||
});
|
||||
|
18
src/js/block-editor.js
Normal file
18
src/js/block-editor.js
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
// =============================================================================
|
||||
// RESTRICT STICKY CHECKBOX
|
||||
// =============================================================================
|
||||
|
||||
wp.domReady(function() {
|
||||
|
||||
setTimeout(() => {
|
||||
document.querySelectorAll('label').forEach(element => {
|
||||
if (element.textContent === 'Stick to the top of the blog') {
|
||||
if (!fictioneerData.userCapabilities?.fcn_make_sticky) {
|
||||
element.closest('.components-panel__row').remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 100);
|
||||
|
||||
});
|
@ -217,7 +217,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__badge {
|
||||
.fictioneer-comment__badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: var(--badge-generic-background);
|
||||
@ -231,30 +231,30 @@
|
||||
height: 16px;
|
||||
transform: translateY(-1px);
|
||||
|
||||
&--override {
|
||||
&.badge-override {
|
||||
background: var(--badge-override-background);
|
||||
color: var(--badge-override-text);
|
||||
}
|
||||
|
||||
&--moderator {
|
||||
&.is-moderator {
|
||||
background: var(--badge-moderator-background);
|
||||
color: var(--badge-moderator-text);
|
||||
}
|
||||
|
||||
&--admin {
|
||||
&.is-admin {
|
||||
background: var(--badge-admin-background);
|
||||
color: var(--badge-admin-text);
|
||||
}
|
||||
|
||||
&--author {
|
||||
&.is-author {
|
||||
background: var(--badge-author-background);
|
||||
color: var(--badge-author-text);
|
||||
}
|
||||
|
||||
&--supporter {
|
||||
background: var(--badge-supporter-background);
|
||||
color: var(--badge-supporter-text);
|
||||
}
|
||||
&.is-supporter {
|
||||
background: var(--badge-supporter-background);
|
||||
color: var(--badge-supporter-text);
|
||||
}
|
||||
}
|
||||
|
||||
&__date-and-link {
|
||||
|
@ -14,7 +14,7 @@
|
||||
}
|
||||
|
||||
hr {
|
||||
border-top: 1px solid var(--bg-200);
|
||||
border-top: 1px solid var(--hr-color);
|
||||
border-bottom: 0;
|
||||
margin: var(--16bp) 0;
|
||||
}
|
||||
@ -36,13 +36,13 @@
|
||||
|
||||
code {
|
||||
display: block;
|
||||
background: var(--bg-800);
|
||||
color: var(--text-400);
|
||||
background: var(--code-background-color);
|
||||
color: var(--code-color);
|
||||
font-family: Consolas, Monaco, monospace;
|
||||
font-size: var(--fs-xxs);
|
||||
line-height: 1.7;
|
||||
padding: var(--12bp);
|
||||
border-radius: var(--large-border-radius);
|
||||
border-radius: 2px;
|
||||
overflow: scroll;
|
||||
|
||||
pre {
|
||||
@ -66,12 +66,12 @@
|
||||
}
|
||||
|
||||
:is(input, select, textarea) {
|
||||
background: var(--bg-200);
|
||||
background: var(--input-background-color);
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
|
||||
&::placeholder {
|
||||
color: var(--text-400);
|
||||
color: var(--input-color-placeholder);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
@ -79,7 +79,7 @@
|
||||
}
|
||||
|
||||
&:not([type=checkbox], [type=radio], [readonly], .button):focus {
|
||||
box-shadow: inset 0 0 0 2px var(--primary-500);
|
||||
box-shadow: inset 0 0 0 2px var(--input-border-color-active);
|
||||
}
|
||||
|
||||
&[readonly]:focus {
|
||||
@ -87,13 +87,7 @@
|
||||
}
|
||||
|
||||
&:is([type=checkbox], [type=radio]):focus-visible {
|
||||
box-shadow: 0 0 0 1px white, 0 0 0 3px var(--primary-500);
|
||||
}
|
||||
|
||||
&:not(.invalid) {
|
||||
+ .popup-note.invalid {
|
||||
display: none;
|
||||
}
|
||||
box-shadow: 0 0 0 1px white, 0 0 0 3px var(--input-border-color-active);
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,7 +97,7 @@
|
||||
width: 16px;
|
||||
|
||||
&:checked {
|
||||
background: var(--bg-700);
|
||||
background: var(--input-checkbox-background-color-checked);
|
||||
|
||||
&::before {
|
||||
// https://icon-sets.iconify.design/?query=checkmark
|
||||
@ -128,14 +122,10 @@
|
||||
select {
|
||||
padding: 0 8px;
|
||||
height: 32px;
|
||||
|
||||
&:focus {
|
||||
background-color: var(--bg-50);
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
background: var(--bg-200) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' preserveAspectRatio='xMidYMid meet' width='20' height='20' viewBox='0 0 20 20' class='iconify iconify--bx'%3E%3Cpath fill='currentColor' d='M16.293 9.293L12 13.586L7.707 9.293l-1.414 1.414L12 16.414l5.707-5.707z'%3E%3C/path%3E%3C/svg%3E") no-repeat right 8px top 40%;
|
||||
background: var(--input-background-color) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' preserveAspectRatio='xMidYMid meet' width='20' height='20' viewBox='0 0 20 20' class='iconify iconify--bx'%3E%3Cpath fill='currentColor' d='M16.293 9.293L12 13.586L7.707 9.293l-1.414 1.414L12 16.414l5.707-5.707z'%3E%3C/path%3E%3C/svg%3E") no-repeat right 8px top 40%;
|
||||
line-height: 32px;
|
||||
padding: 0 32px 0 8px;
|
||||
height: 32px;
|
||||
|
@ -1,7 +1,7 @@
|
||||
& {
|
||||
.sub-label {
|
||||
display: block;
|
||||
color: var(--text-500);
|
||||
color: var(--sublabel-text-color);
|
||||
font-size: var(--fs-xxs);
|
||||
line-height: 1.5;
|
||||
margin: var(--2bp) 2px 0;
|
||||
@ -22,7 +22,7 @@
|
||||
&:not(:checked) {
|
||||
~ * {
|
||||
input {
|
||||
color: var(--text-400);
|
||||
color: var(--input-color-disabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -52,6 +52,7 @@
|
||||
padding-bottom: 1px;
|
||||
height: 20px;
|
||||
width: auto;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
&.row:not(:first-child) {
|
||||
@ -73,8 +74,8 @@
|
||||
}
|
||||
|
||||
thead {
|
||||
background: var(--bg-50);
|
||||
border: 1px solid rgb(0 0 0 / 5%);
|
||||
background: var(--table-row-background-color-head);
|
||||
border: 1px solid var(--table-border-color);
|
||||
border-width: 1px 0;
|
||||
}
|
||||
|
||||
@ -93,7 +94,6 @@
|
||||
}
|
||||
|
||||
th {
|
||||
color: var(--text-500);
|
||||
font-size: var(--fs-xxs);
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
@ -142,7 +142,7 @@
|
||||
}
|
||||
|
||||
.description {
|
||||
color: var(--text-500);
|
||||
color: var(--description-text-color);
|
||||
|
||||
&:not(.row, :first-child) {
|
||||
margin-top: var(--4bp);
|
||||
@ -151,10 +151,6 @@
|
||||
&:not(.row, :last-child) {
|
||||
margin-bottom: var(--4bp);
|
||||
}
|
||||
|
||||
strong {
|
||||
color: var(--text-600);
|
||||
}
|
||||
}
|
||||
|
||||
.inline-row-actions {
|
||||
@ -172,196 +168,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
.popup-note {
|
||||
--this-background: var(--bg-600);
|
||||
--this-text-color: var(--text-white);
|
||||
|
||||
&.floating {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
&.dismissable {
|
||||
pointer-events: all;
|
||||
|
||||
> * {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.dismiss {
|
||||
cursor: pointer;
|
||||
line-height: 1;
|
||||
padding-right: 1px;
|
||||
transform: translateY(2px);
|
||||
|
||||
&:not(:hover) {
|
||||
opacity: .9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:is(.warning, .invalid) {
|
||||
--this-background: var(--invalid-note-background);
|
||||
--this-text-color: var(--invalid-note-text-color);
|
||||
}
|
||||
|
||||
> * {
|
||||
position: relative;
|
||||
display: block;
|
||||
background: var(--this-background);
|
||||
color: var(--this-text-color);
|
||||
font-size: var(--fs-xxs);
|
||||
line-height: 1.3;
|
||||
padding: 4px 6px;
|
||||
margin: 0 4px;
|
||||
border-radius: var(--large-border-radius);
|
||||
transform: translateY(-3px);
|
||||
width: fit-content;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 12px;
|
||||
display: block;
|
||||
border-style: solid;
|
||||
border-width: 0 6px 4px 6px;
|
||||
border-color: transparent transparent var(--this-background) transparent;
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.spacer {
|
||||
display: block;
|
||||
height: var(--24bp);
|
||||
}
|
||||
|
||||
.popup-menu-toggle {
|
||||
display: block;
|
||||
text-align: center;
|
||||
min-width: 32px;
|
||||
}
|
||||
|
||||
.popup-menu {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
z-index: 100;
|
||||
background: var(--bg-800);
|
||||
border-radius: var(--large-border-radius);
|
||||
min-width: 64px;
|
||||
overflow: hidden;
|
||||
box-shadow: var(--popup-shadow);
|
||||
|
||||
> * {
|
||||
display: block;
|
||||
color: var(--text-white);
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
padding: 8px 16px;
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-700);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
display: grid;
|
||||
place-content: center;
|
||||
background: var(--bg-700);
|
||||
color: var(--text-white);
|
||||
font-size: var(--fs-xxs);
|
||||
line-height: 1;
|
||||
padding: 0 16px;
|
||||
border: none;
|
||||
border-radius: var(--large-border-radius);
|
||||
min-height: 32px;
|
||||
|
||||
&.disabled {
|
||||
pointer-events: none;
|
||||
background: var(--bg-200) !important; // WP
|
||||
color: var(--text-400) !important; // WP
|
||||
border: none !important; // WP
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
background: var(--bg-600);
|
||||
color: var(--text-white);
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
background: transparent;
|
||||
color: var(--bg-600);
|
||||
font-weight: 500;
|
||||
border: 1px solid var(--bg-600);
|
||||
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
background: var(--bg-50);
|
||||
color: var(--bg-700);
|
||||
border: 1px solid var(--bg-700);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pill-nav {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--8bp);
|
||||
|
||||
.tab {
|
||||
display: grid;
|
||||
place-content: center;
|
||||
color: var(--text-50);
|
||||
font-size: var(--fs-xs);
|
||||
line-height: 1;
|
||||
text-decoration: none;
|
||||
padding: 0 16px;
|
||||
border-radius: var(--large-border-radius);
|
||||
height: 32px;
|
||||
opacity: .7;
|
||||
transition: opacity .1s;
|
||||
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
opacity: 1;
|
||||
background: var(--bg-800);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: var(--bg-50);
|
||||
color: var(--text-700);
|
||||
opacity: 1;
|
||||
|
||||
&:focus {
|
||||
background: var(--bg-300);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.action-row {
|
||||
--gap-offset: var(--8bp);
|
||||
display: flex;
|
||||
@ -399,14 +210,13 @@
|
||||
}
|
||||
|
||||
.button {
|
||||
display: grid;
|
||||
place-content: center;
|
||||
padding: 0;
|
||||
width: 32px;
|
||||
|
||||
&:not(.disabled, :hover) {
|
||||
background: var(--bg-500);
|
||||
}
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
line-height: 1.625;
|
||||
text-align: center;
|
||||
padding: 0 4px;
|
||||
min-height: 30px;
|
||||
min-width: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -421,7 +231,36 @@
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: var(--primary-600);
|
||||
color: var(--highlight-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.capability-checkbox {
|
||||
&__input {
|
||||
display: none;
|
||||
|
||||
&:checked + .capability-checkbox__name {
|
||||
color: var(--checkbox-toggle-color-active);
|
||||
background: var(--checkbox-toggle-background-color-active);
|
||||
|
||||
&:hover {
|
||||
filter: brightness(0.9);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__name {
|
||||
background: var(--checkbox-toggle-background-color);
|
||||
font-size: var(--fs-xxs);
|
||||
line-height: 1.4;
|
||||
padding: 4px 6px;
|
||||
border-radius: 2px;
|
||||
width: fit-content;
|
||||
transition: color .1s;
|
||||
|
||||
&:hover {
|
||||
background: var(--checkbox-toggle-background-color-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
& {
|
||||
.columns-layout {
|
||||
--max-width-offset: var(--32bp);
|
||||
column-gap: var(--32bp);
|
||||
|
||||
@include bp(768px) {
|
||||
@ -29,70 +28,50 @@
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
background: var(--card-background);
|
||||
border-radius: var(--large-border-radius);
|
||||
box-shadow: var(--card-shadow);
|
||||
background: var(--card-background-color);
|
||||
border: 1px solid var(--card-border-color);
|
||||
|
||||
&-header {
|
||||
padding: var(--16bp) var(--16bp) 0;
|
||||
padding: var(--8bp) var(--12bp);
|
||||
border-bottom: 1px solid #c3c4c7;
|
||||
}
|
||||
|
||||
&-header,
|
||||
&-header :is(h1, h2, h3, h4, h5, h6) {
|
||||
font-size: var(--fs-m);
|
||||
color: #1d2327;
|
||||
font-size: var(--fs-xs);
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
&-content {
|
||||
font-size: var(--fs-xs);
|
||||
padding: var(--16bp) 0;
|
||||
padding: var(--12bp) 0;
|
||||
}
|
||||
|
||||
&-footer {
|
||||
padding: var(--16bp);
|
||||
}
|
||||
}
|
||||
|
||||
.modal {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
background: var(--modal-background);
|
||||
border-radius: var(--large-border-radius);
|
||||
box-shadow: var(--modal-shadow);
|
||||
|
||||
&.hidden {
|
||||
pointer-events: none;
|
||||
z-index: -1000;
|
||||
padding: var(--12bp);
|
||||
}
|
||||
|
||||
&:not(.hidden) {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
&__header {
|
||||
font-size: var(--fs-m);
|
||||
font-weight: 600;
|
||||
padding: var(--16bp) var(--16bp) 0;
|
||||
}
|
||||
|
||||
&__content {
|
||||
font-size: var(--fs-xs);
|
||||
padding: var(--16bp) 0;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
padding: var(--16bp);
|
||||
&-capabilities {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
gap: var(--8bp);
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
padding: 0 var(--16bp);
|
||||
padding: 0 var(--12bp);
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-bottom: var(--16bp);
|
||||
margin-bottom: var(--12bp);
|
||||
}
|
||||
}
|
||||
|
||||
.toggle-checkboxes {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
@ -30,12 +30,12 @@
|
||||
|
||||
&::before {
|
||||
left: 0;
|
||||
background: linear-gradient(to right, var(--card-background), var(--card-background) 50%, transparent);
|
||||
background: linear-gradient(to right, var(--card-background-color), var(--card-background-color) 50%, transparent);
|
||||
}
|
||||
|
||||
&::after {
|
||||
right: 0;
|
||||
background: linear-gradient(to left, var(--card-background), var(--card-background) 50%, transparent);
|
||||
background: linear-gradient(to left, var(--card-background-color), var(--card-background-color) 50%, transparent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -64,7 +64,7 @@
|
||||
}
|
||||
|
||||
.subtext {
|
||||
color: var(--text-500);
|
||||
color: var(--subtext-color);
|
||||
}
|
||||
|
||||
.code {
|
||||
@ -95,7 +95,7 @@
|
||||
|
||||
.alternate-rows {
|
||||
> *:nth-child(even) {
|
||||
background-color: rgb(0 0 0 / 2%);
|
||||
background-color: var(--table-row-background-color-even);
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
&.wrap {
|
||||
&.flex-wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@ -188,7 +188,7 @@
|
||||
}
|
||||
|
||||
// Margin-top 2 to 16
|
||||
@for $i from 1 through 16 {
|
||||
@for $i from 1 through 32 {
|
||||
$n: 2 * $i;
|
||||
.mt-#{$n} {
|
||||
margin-top: var(--#{$n}bp);
|
||||
@ -196,7 +196,7 @@
|
||||
}
|
||||
|
||||
// Margin-bottom 2 to 16
|
||||
@for $i from 1 through 16 {
|
||||
@for $i from 1 through 32 {
|
||||
$n: 2 * $i;
|
||||
.mb-#{$n} {
|
||||
margin-bottom: var(--#{$n}bp);
|
||||
|
@ -22,57 +22,4 @@
|
||||
--fs-xs: #{get_clamp(13, 14, 320, 768)};
|
||||
--fs-s: #{get_clamp(15, 16, 320, 768)};
|
||||
--fs-m: #{get_clamp(17, 18, 320, 768)};
|
||||
|
||||
// Primary colors
|
||||
--primary-50: #f0f9ff;
|
||||
--primary-100: #e0f2fe;
|
||||
--primary-200: #bae6fd;
|
||||
--primary-300: #7dd3fc;
|
||||
--primary-400: #38bdf8;
|
||||
--primary-500: #0ea5e9;
|
||||
--primary-600: #0284c7;
|
||||
--primary-700: #0369a1;
|
||||
--primary-800: #075985;
|
||||
--primary-900: #0c4a6e;
|
||||
|
||||
// Background colors
|
||||
--bg-50: rgb(249 250 251);
|
||||
--bg-100: rgb(243 244 246);
|
||||
--bg-200: rgb(229 231 235);
|
||||
--bg-300: rgb(209 213 219);
|
||||
--bg-400: rgb(156 163 175);
|
||||
--bg-500: rgb(107 114 128);
|
||||
--bg-600: rgb(75 85 99);
|
||||
--bg-700: rgb(55 65 81);
|
||||
--bg-800: rgb(31 41 55);
|
||||
--bg-900: rgb(17 24 39);
|
||||
|
||||
// Text colors
|
||||
--text-50: rgb(249 250 251);
|
||||
--text-100: rgb(243 244 246);
|
||||
--text-200: rgb(229 231 235);
|
||||
--text-300: rgb(209 213 219);
|
||||
--text-400: rgb(156 163 175);
|
||||
--text-500: rgb(107 114 128);
|
||||
--text-600: rgb(75 85 99);
|
||||
--text-700: rgb(55 65 81);
|
||||
--text-800: rgb(31 41 55);
|
||||
--text-900: rgb(17 24 39);
|
||||
|
||||
--text-white: white;
|
||||
|
||||
// Shadows
|
||||
--card-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
--popup-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
--modal-shadow: 0 0 24px -4px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
|
||||
|
||||
// Layout
|
||||
--large-border-radius: 4px;
|
||||
--card-background: white;
|
||||
--modal-background: white;
|
||||
--max-width-offset: 0;
|
||||
|
||||
// Popup notes
|
||||
--invalid-note-background: rgb(248 113 113 / 90%);
|
||||
--invalid-note-text-color: var(--text-white);
|
||||
}
|
||||
|
@ -31,7 +31,6 @@
|
||||
}
|
||||
|
||||
:is(h1, h2, h3, h4, h5, h6) {
|
||||
color: var(--text-700);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
@ -6,20 +6,6 @@
|
||||
// GENERAL ADMIN STYLES
|
||||
// =============================================================================
|
||||
|
||||
.is-subscriber {
|
||||
#wpcontent {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
:is(#adminmenuwrap, #adminmenuback, #wpfooter, #wp-admin-bar-menu-toggle) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#wpbody-content {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
details {
|
||||
summary {
|
||||
cursor: pointer;
|
||||
@ -39,6 +25,24 @@ td.comment {
|
||||
}
|
||||
}
|
||||
|
||||
.edit-term-notes {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.button.button-danger {
|
||||
background: #dc3232;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
border-color: #dc3232;
|
||||
}
|
||||
|
||||
.button.button-danger:hover,
|
||||
.button.button-danger:focus {
|
||||
background: #c00;
|
||||
color: #fff;
|
||||
border-color: #c00;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// CUSTOMIZER
|
||||
// =============================================================================
|
||||
@ -87,7 +91,6 @@ body[class*=fictioneer] {
|
||||
// =============================================================================
|
||||
|
||||
.fictioneer-ui {
|
||||
color: var(--text-700);
|
||||
font-size: var(--fs-xs);
|
||||
line-height: 1.5;
|
||||
|
||||
@ -103,18 +106,220 @@ body[class*=fictioneer] {
|
||||
// FICTIONEER SETTING PAGES
|
||||
// =============================================================================
|
||||
|
||||
.fictioneer-settings {
|
||||
margin-left: -10px;
|
||||
body[class*="page_fictioneer"] #wpcontent {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
@include bp(783px) {
|
||||
margin-left: -20px;
|
||||
body[class*="page_fictioneer"] {
|
||||
--focus-color: #ef4d4d;
|
||||
--focus-box-shadow: 0 0 0 1px #4f94d4, 0 0 2px 1px rgba(79, 148, 212, .8);
|
||||
--highlight-color: #72aee6;
|
||||
|
||||
--header-heading-color: #fff;
|
||||
--header-background-color: #1d2327;
|
||||
--header-note-color: rgba(240, 246, 252, .7);
|
||||
--header-note-color-active: #fff;
|
||||
--header-nav-item-color: #fff;
|
||||
--header-nav-item-color-hover: #fff;
|
||||
--header-nav-item-color-active: #fff;
|
||||
--header-nav-item-background-active: #2271b1;
|
||||
--header-nav-item-background-hover: #2c3337;
|
||||
|
||||
--subnav-background-color: #2c3337;
|
||||
--subnav-item-color: rgba(240, 246, 252, .7);
|
||||
--subnav-item-color-hover: #fff;
|
||||
--subnav-item-color-active: #fff;
|
||||
--subnav-item-border-color: transparent;
|
||||
--subnav-item-border-color-hover: currentColor;
|
||||
--subnav-item-border-color-active: #fff;
|
||||
|
||||
--card-background-color: #fff;
|
||||
--card-border-color: #c3c4c7;
|
||||
|
||||
--checkbox-toggle-background-color: #ddd;
|
||||
--checkbox-toggle-background-color-hover: #d6d6d6;
|
||||
--checkbox-toggle-background-color-active: #646970;
|
||||
--checkbox-toggle-color-active: #fff;
|
||||
|
||||
--input-background-color: #e9ecec;
|
||||
--input-checkbox-background-color-checked: #2271b1;
|
||||
--input-color-placeholder: #646970;
|
||||
--input-color-disabled: #858a93;
|
||||
--input-border-color-active: #2271b1;
|
||||
|
||||
--description-text-color: inherit;
|
||||
--sublabel-text-color: #646970;
|
||||
--subtext-color: #646970;
|
||||
|
||||
--hr-color: #c3c4c7;
|
||||
--code-background-color: #2c3337;
|
||||
--code-color: #fff;
|
||||
|
||||
--table-border-color: #c3c4c7;
|
||||
--table-row-background-color-head: #f6f7f7;
|
||||
--table-row-background-color-even: #f6f7f7;
|
||||
|
||||
&.admin-color-coffee {
|
||||
--header-background-color: #59524c;
|
||||
--header-note-color: #cdcbc9;
|
||||
--header-nav-item-color: #fff;
|
||||
--header-nav-item-color-hover: #fff;
|
||||
--header-nav-item-background-active: #c7a589;
|
||||
--header-nav-item-background-hover: #c7a589;
|
||||
|
||||
--subnav-background-color: #46403b;
|
||||
--subnav-item-color: #cdcbc9;
|
||||
|
||||
--checkbox-toggle-background-color-active: #615851;
|
||||
|
||||
--input-checkbox-background-color-checked: #59524c;
|
||||
--input-border-color-active: #c7a589;
|
||||
}
|
||||
|
||||
&.admin-color-light {
|
||||
--header-heading-color: #333;
|
||||
--header-background-color: #e5e5e5;
|
||||
--header-note-color: #686868;
|
||||
--header-note-color-active: #d64e07;
|
||||
--header-nav-item-color: #333;
|
||||
--header-nav-item-color-hover: #333;
|
||||
--header-nav-item-background-active: #888;
|
||||
--header-nav-item-background-hover: #f9f9f9;
|
||||
|
||||
--subnav-background-color: #fff;
|
||||
--subnav-item-color: #686868;
|
||||
--subnav-item-color-hover: #333;
|
||||
--subnav-item-color-active: #333;
|
||||
--subnav-item-border-color-active: #888;
|
||||
|
||||
--checkbox-toggle-background-color: #e5e5e5;
|
||||
--checkbox-toggle-background-color-hover: #ddd;
|
||||
--checkbox-toggle-background-color-active: #888;
|
||||
|
||||
--code-background-color: #222;
|
||||
|
||||
--input-checkbox-background-color-checked: #888;
|
||||
--input-border-color-active: #04a4cc;
|
||||
}
|
||||
|
||||
&.admin-color-modern {
|
||||
--header-background-color: #1e1e1e;
|
||||
--header-note-color: #bcbcbc;
|
||||
--header-note-color-active: #33f078;
|
||||
--header-nav-item-color: #fff;
|
||||
--header-nav-item-color-hover: #fff;
|
||||
--header-nav-item-background-hover: #0c0c0c;
|
||||
--header-nav-item-background-active: #3858e9;
|
||||
|
||||
--subnav-background-color: #0c0c0c;
|
||||
--subnav-item-color: #bcbcbc;
|
||||
|
||||
--checkbox-toggle-background-color-active: #2e2e2e;
|
||||
|
||||
--code-background-color: #0c0c0c;
|
||||
|
||||
--input-checkbox-background-color-checked: #3858e9;
|
||||
--input-border-color-active: #3858e9;
|
||||
}
|
||||
|
||||
&.admin-color-blue {
|
||||
--header-background-color: #53accc;
|
||||
--header-note-color: #e2ecf1;
|
||||
--header-nav-item-color: #fff;
|
||||
--header-nav-item-color-hover: #fff;
|
||||
--header-nav-item-background-hover: #4896b3;
|
||||
--header-nav-item-background-active: #0b6484;
|
||||
|
||||
--subnav-background-color: #4896b3;
|
||||
--subnav-item-color: #e2ecf1;
|
||||
|
||||
--checkbox-toggle-background-color-active: #4896b3;
|
||||
|
||||
--code-background-color: #04242f;
|
||||
|
||||
--input-checkbox-background-color-checked: #0b6484;
|
||||
--input-border-color-active: #0b6484;
|
||||
}
|
||||
|
||||
&.admin-color-ectoplasm {
|
||||
--header-background-color: #523f6d;
|
||||
--header-note-color: #cbc5d3;
|
||||
--header-nav-item-color: #fff;
|
||||
--header-nav-item-background-hover: #413256;
|
||||
--header-nav-item-background-active: #a3b745;
|
||||
|
||||
--subnav-background-color: #413256;
|
||||
--subnav-item-color: #cbc5d3;
|
||||
|
||||
--checkbox-toggle-background-color-active: #413256;
|
||||
|
||||
--code-background-color: #181320;
|
||||
|
||||
--input-checkbox-background-color-checked: #413256;
|
||||
--input-border-color-active: #a3b745;
|
||||
}
|
||||
|
||||
&.admin-color-midnight {
|
||||
--header-background-color: #363b3f;
|
||||
--header-note-color: #c3c4c5;
|
||||
--header-nav-item-color: #fff;
|
||||
--header-nav-item-background-hover: #25282b;
|
||||
--header-nav-item-background-active: #e14d43;
|
||||
|
||||
--subnav-background-color: #25282b;
|
||||
--subnav-item-color: #c3c4c5;
|
||||
|
||||
--checkbox-toggle-background-color-active: #363b3f;
|
||||
|
||||
--code-background-color: #25282b;
|
||||
|
||||
--input-checkbox-background-color-checked: #25282b;
|
||||
--input-border-color-active: #e14d43;
|
||||
}
|
||||
|
||||
&.admin-color-ocean {
|
||||
--header-background-color: #738e96;
|
||||
--header-note-color: #d5dde0;
|
||||
--header-nav-item-color: #fff;
|
||||
--header-nav-item-background-hover: #627c83;
|
||||
--header-nav-item-background-active: #9ebaa0;
|
||||
|
||||
--subnav-background-color: #627c83;
|
||||
--subnav-item-color: #d5dde0;
|
||||
|
||||
--checkbox-toggle-background-color-active: #627c83;
|
||||
|
||||
--code-background-color: #2c373a;
|
||||
|
||||
--input-checkbox-background-color-checked: #627c83;
|
||||
--input-border-color-active: #9ebaa0;
|
||||
}
|
||||
|
||||
&.admin-color-sunrise {
|
||||
--header-background-color: #cf4944;
|
||||
--header-note-color: #f1c8c7;
|
||||
--header-nav-item-color: #fff;
|
||||
--header-nav-item-background-hover: #b43c38;
|
||||
--header-nav-item-background-active: #dd823b;
|
||||
|
||||
--subnav-background-color: #b43c38;
|
||||
--subnav-item-color: #f1c8c7;
|
||||
|
||||
--checkbox-toggle-background-color-active: #b43c38;
|
||||
|
||||
--code-background-color: #1f0a0a;
|
||||
|
||||
--input-checkbox-background-color-checked: #b43c38;
|
||||
--input-border-color-active: #dd823b;
|
||||
}
|
||||
}
|
||||
|
||||
.fictioneer-settings {
|
||||
&__header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
background: var(--bg-900);
|
||||
background: var(--header-background-color);
|
||||
padding: var(--20bp) 4px;
|
||||
height: 256px;
|
||||
|
||||
@ -131,20 +336,20 @@ body[class*=fictioneer] {
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: var(--text-200);
|
||||
color: var(--header-heading-color);
|
||||
font-size: 64px;
|
||||
}
|
||||
|
||||
&-links {
|
||||
color: var(--text-600);
|
||||
color: var(--header-note-color);
|
||||
font-variant-numeric: tabular-nums;
|
||||
|
||||
a {
|
||||
color: var(--text-400);
|
||||
color: var(--header-note-color);
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: var(--text-200);
|
||||
color: var(--header-note-color-active);
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,6 +357,137 @@ body[class*=fictioneer] {
|
||||
font-size: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.pill-nav {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--8bp);
|
||||
|
||||
.tab {
|
||||
cursor: pointer;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
color: var(--header-nav-item-color);
|
||||
font-size: 13px;
|
||||
line-height: 1;
|
||||
text-decoration: none;
|
||||
padding: 0 16px;
|
||||
margin: 0;
|
||||
border-radius: 2px;
|
||||
height: 32px;
|
||||
transition: color .1s;
|
||||
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
box-shadow: var(--focus-box-shadow);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: var(--header-nav-item-background-hover);
|
||||
color: var(--header-nav-item-color-hover);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: var(--header-nav-item-background-active);
|
||||
color: var(--header-nav-item-color-active);
|
||||
|
||||
&:focus-visible {
|
||||
box-shadow: var(--focus-box-shadow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__subnav {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--8bp) var(--20bp);
|
||||
background: var(--subnav-background-color);
|
||||
padding: var(--8bp) 20px 0;
|
||||
margin: 0;
|
||||
|
||||
@include bp(375px) {
|
||||
padding: var(--8bp) calc(16px + var(--10bp)) 0;
|
||||
}
|
||||
|
||||
@include bp(480px) {
|
||||
padding: var(--8bp) calc(16px + var(--14bp)) 0;
|
||||
}
|
||||
|
||||
@include bp(768px) {
|
||||
padding: var(--8bp) calc(16px + var(--20bp)) 0;
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
color: var(--subnav-item-color);
|
||||
padding: 8px 0 calc(5px + var(--8bp));
|
||||
border: none;
|
||||
|
||||
&:hover {
|
||||
color: var(--subnav-item-color-hover);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
box-shadow: var(--focus-box-shadow);
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.dashicons-plus {
|
||||
font-size: 16px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.tab {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
color: var(--subnav-item-color);
|
||||
font-size: 13px;
|
||||
line-height: 1;
|
||||
text-decoration: none;
|
||||
padding: 8px 0 calc(5px + var(--8bp));
|
||||
border-bottom: 3px solid var(--subnav-item-border-color);
|
||||
margin: 0;
|
||||
transition: color .1s, border .1s;
|
||||
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
box-shadow: var(--focus-box-shadow);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: var(--subnav-item-color-hover);
|
||||
border-bottom-color: var(--subnav-item-border-color-hover);
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: var(--subnav-item-color-active);
|
||||
font-weight: 600;
|
||||
border-bottom-color: var(--subnav-item-border-color-active);
|
||||
|
||||
&:focus-visible {
|
||||
box-shadow: var(--focus-box-shadow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__content {
|
||||
@ -171,6 +507,50 @@ body[class*=fictioneer] {
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// FICTIONEER DIALOG MODAL
|
||||
// =============================================================================
|
||||
|
||||
.fictioneer-dialog {
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
background: #fff;
|
||||
padding: 0;
|
||||
margin: 20px;
|
||||
border: none;
|
||||
width: min(480px, calc(100vw - 40px));
|
||||
max-width: 480px;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
&::backdrop {
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
color: #1d2327;
|
||||
font-size: var(--fs-m);
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
padding: 0 var(--16bp);
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
&__content {
|
||||
font-size: var(--fs-xs);
|
||||
padding: 0 var(--16bp) var(--16bp);
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
padding-top: var(--16bp);
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// FICTIONEER METABOXES
|
||||
// =============================================================================
|
||||
|
@ -75,7 +75,7 @@ body {
|
||||
}
|
||||
|
||||
p {
|
||||
img {
|
||||
img:not(.wp-more-tag) {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
height: 1em;
|
||||
|
Loading…
x
Reference in New Issue
Block a user