diff --git a/10up-experience.php b/10up-experience.php index 0681978..84a818a 100644 --- a/10up-experience.php +++ b/10up-experience.php @@ -3,7 +3,7 @@ * Plugin Name: 10up Experience * Plugin URI: https://github.com/10up/10up-experience * Description: The 10up Experience plugin configures WordPress to better protect and inform clients, aligned to 10up’s best practices. - * Version: 1.11.2 + * Version: 1.12.0 * Author: 10up * Author URI: https://10up.com * License: GPLv2 or later @@ -19,7 +19,7 @@ use YahnisElsts\PluginUpdateChecker\v5\PucFactory; -define( 'TENUP_EXPERIENCE_VERSION', '1.11.2' ); +define( 'TENUP_EXPERIENCE_VERSION', '1.12.0' ); define( 'TENUP_EXPERIENCE_DIR', __DIR__ ); define( 'TENUP_EXPERIENCE_FILE', __FILE__ ); @@ -73,6 +73,7 @@ function ( $class_name ) { API\API::instance(); Authentication\Usernames::instance(); Authors\Authors::instance(); +Comments\Comments::instance(); Gutenberg\Gutenberg::instance(); Headers\Headers::instance(); Plugins\Plugins::instance(); diff --git a/README.md b/README.md index 3a24151..4ea33bd 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,52 @@ Filters how many log items to store. Items are stored in array saved to the opti Define `TENUP_DISABLE_ACTIVITYLOG` as `true` to disable Activity Log. +### Comments + +10up Experience includes a feature to disable comments across the site. This feature can be enabled or disabled in `Settings > General`. It is disabled by default. + +On top of disabling the comment form, this feature removes the following: + +- Comments from the admin menu. +- Comment blocks from the post editor. +- Comments from the admin bar. + +#### Constants + +- `TENUP_DISABLE_COMMENTS` + +Define this as `true` to force disable comments or `false` to enable comments from a config file. +Setting this constant will disable the UI for enabling/disabling comments in the admin. + +#### Filters + +- `tenup_experience_disable_comments` + +Filters whether to disable comments. Default is `false`. +Defining this filter will disable the UI for enabling/disabling comments in the admin. + +- `tenup_experience_disable_comments_disallowed_blocks` + +Filters the list of blocks that should be disallowed when comments are disabled. This is useful when core adds new blocks that aren't covered by the default list. + +The default list of disallowed blocks is: + +- `core/comment-author-name` +- `core/comment-content` +- `core/comment-date` +- `core/comment-edit-link` +- `core/comment-reply-link` +- `core/comment-template` +- `core/comments` +- `core/comments-pagination` +- `core/comments-pagination-next` +- `core/comments-pagination-numbers` +- `core/comments-pagination-previous` +- `core/comments-title` +- `core/post-comments` +- `core/post-comments-form` +- `core/latest-comments` + ## Support Level **Active:** 10up is actively working on this, and we expect to continue work for the foreseeable future including keeping tested up to the most recent version of WordPress. Bug reports, feature requests, questions, and pull requests are welcome. diff --git a/includes/classes/AdminCustomizations/Customizations.php b/includes/classes/AdminCustomizations/Customizations.php index 3f3e67e..1606e3e 100644 --- a/includes/classes/AdminCustomizations/Customizations.php +++ b/includes/classes/AdminCustomizations/Customizations.php @@ -84,7 +84,7 @@ public function main_screen() { ?> - 10up.com + 10up.com

@@ -191,7 +191,7 @@ public function enqueue_scripts() { * @return string */ public function filter_admin_footer_text() { - $new_text = sprintf( __( 'Thank you for creating with WordPress and 10up.', 'tenup' ) ); + $new_text = sprintf( __( 'Thank you for creating with WordPress and 10up.', 'tenup' ) ); return $new_text; } } diff --git a/includes/classes/Comments/Comments.php b/includes/classes/Comments/Comments.php new file mode 100644 index 0000000..b1d7749 --- /dev/null +++ b/includes/classes/Comments/Comments.php @@ -0,0 +1,360 @@ +comments_are_disabled() ) { + return; + } + + // Remove comments support from posts and pages + add_action( 'init', [ $this, 'disable_comments_post_types_support' ] ); + + // Remove comments-related UI elements + add_action( 'admin_menu', [ $this, 'remove_comments_admin_menus' ] ); + add_action( 'wp_before_admin_bar_render', [ $this, 'remove_comments_admin_bar_links' ] ); + + // Hide any existing comments on front end + add_filter( 'comments_array', [ $this, 'disable_comments_hide_existing_comments' ], 10, 2 ); + add_filter( 'comments_open', [ $this, 'disable_comments_status' ], 20, 2 ); + add_filter( 'pings_open', [ $this, 'disable_comments_status' ], 20, 2 ); + + // Short-circuit WP_Comment_Query. + add_filter( 'comments_pre_query', [ $this, 'filter_comments_pre_query' ], 10, 2 ); + + // Remove comment feeds. + add_filter( 'feed_links_show_comments_feed', '__return_false' ); + add_filter( 'feed_links_extra_show_post_comments_feed', '__return_false' ); + + // Remove the comment widget. + add_action( 'widgets_init', [ $this, 'remove_comment_widget' ], 1 ); + + // Remove the comment blocks. + add_action( 'allowed_block_types_all', [ $this, 'remove_comment_blocks' ], PHP_INT_MAX ); + } + + /** + * Get the setting + * + * @return boolean + */ + public function comments_are_disabled() { + // If the constant is defined, use it. + if ( defined( 'TENUP_DISABLE_COMMENTS' ) ) { + return boolval( TENUP_DISABLE_COMMENTS ); + } + + // If the filter is set, use it. + if ( has_filter( 'tenup_experience_disable_comments' ) ) { + return boolval( apply_filters( 'tenup_experience_disable_comments', false ) ); + } + + // Otherwise, check the setting. + $setting = ( TENUP_EXPERIENCE_IS_NETWORK ) ? get_site_option( 'tenup_disable_comments', 'no' ) : get_option( 'tenup_disable_comments', 'no' ); + + return 'yes' === $setting; + } + + /** + * Check if the UI is disabled + * + * @return boolean + */ + protected function is_ui_disabled() { + return defined( 'TENUP_DISABLE_COMMENTS' ) || has_filter( 'tenup_experience_disable_comments' ); + } + + /** + * Register restrict REST API setting. + * + * @return void + */ + public function single_site_setting() { + $settings_args = [ + 'type' => 'string', + 'sanitize_callback' => [ $this, 'validate_setting' ], + ]; + + register_setting( 'general', 'tenup_disable_comments', $settings_args ); + add_settings_field( 'tenup_disable_comments', esc_html__( 'Disable Comments', 'tenup' ), [ $this, 'diable_comments_setting_field_output' ], 'general' ); + } + + /** + * Display UI for restrict REST API setting. + * + * @return void + */ + public function diable_comments_setting_field_output() { + $disable_comments = $this->comments_are_disabled(); + ?> + + is_ui_disabled() ); + ?> + /> +
+ + is_ui_disabled() ); + ?> + /> + +

+ comments_are_disabled(); + ?> +

+

+ + + + + + + + + validate_setting( sanitize_text_field( $_POST['tenup_disable_comments'] ) ); + + update_site_option( 'tenup_disable_comments', $setting ); + } + + /** + * Validate the setting. + * + * @param string $value Current restriction. + * @return string + */ + public function validate_setting( $value ) { + if ( in_array( $value, [ 'yes', 'no' ], true ) ) { + return $value; + } + + return 'yes'; + } + + /** + * Remove comments support from posts and pages + * + * @return void + */ + public function disable_comments_post_types_support() { + $post_types = get_post_types(); + foreach ( $post_types as $post_type ) { + if ( post_type_supports( $post_type, 'comments' ) ) { + remove_post_type_support( $post_type, 'comments' ); + remove_post_type_support( $post_type, 'trackbacks' ); + } + } + } + + /** + * Remove comments admin menus + * + * @return void + */ + public function remove_comments_admin_menus() { + remove_menu_page( 'edit-comments.php' ); + } + + /** + * Remove comments admin bar links + * + * @return void + */ + public function remove_comments_admin_bar_links() { + global $wp_admin_bar; + $wp_admin_bar->remove_menu( 'comments' ); + } + + /** + * Hide any existing comments on front end + * + * @return array + */ + public function disable_comments_hide_existing_comments() { + return []; + } + + /** + * Disable commenting + * + * @return boolean + */ + public function disable_comments_status() { + return false; + } + + /** + * Short-circuit WP_Comment_Query + * + * @param array $comment_data Comment data. + * @param array $query Query data. + * + * @return array|int|null + */ + public function filter_comments_pre_query( $comment_data, $query ) { + + if ( is_a( $query, '\WP_Comment_Query' ) && $query->query_vars['count'] ) { + return 0; + } + + return array(); + } + + /** + * Remove the comment widget + * + * @return void + */ + public function remove_comment_widget() { + unregister_widget( 'WP_Widget_Recent_Comments' ); + } + + /** + * Remove the comment blocks + * + * @param array $allowed_block_types Array of allowed block types. + * + * @return array + */ + public function remove_comment_blocks( $allowed_block_types ) { + // A list of disallowed comment blocks. + $disallowed_blocks = [ + 'core/comment-author-name', + 'core/comment-content', + 'core/comment-date', + 'core/comment-edit-link', + 'core/comment-reply-link', + 'core/comment-template', + 'core/comments', + 'core/comments-pagination', + 'core/comments-pagination-next', + 'core/comments-pagination-numbers', + 'core/comments-pagination-previous', + 'core/comments-title', + 'core/post-comments', + 'core/post-comments-form', + 'core/latest-comments', + ]; + + /** + * Filter the list of disallowed comment blocks. + * + * @param array $disallowed_blocks Array of disallowed comment blocks. + */ + $disallowed_blocks = apply_filters( 'tenup_experience_disable_comments_disallowed_blocks', $disallowed_blocks ); + + // Get all registered blocks if $allowed_block_types is not already set. + if ( ! is_array( $allowed_block_types ) || empty( $allowed_block_types ) ) { + $registered_blocks = \WP_Block_Type_Registry::get_instance()->get_all_registered(); + $allowed_block_types = array_keys( $registered_blocks ); + + } + + // Create a new array for the allowed blocks. + $filtered_blocks = array(); + + // Loop through each block in the allowed blocks list. + foreach ( $allowed_block_types as $block ) { + + // Check if the block is not in the disallowed blocks list. + if ( ! in_array( $block, $disallowed_blocks, true ) ) { + + // If it's not disallowed, add it to the filtered list. + $filtered_blocks[] = $block; + } + } + + // Return the filtered list of allowed blocks + return $filtered_blocks; + } +} diff --git a/package-lock.json b/package-lock.json index 37a9f09..a33b6f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,9 +6,6 @@ "": { "name": "10up-experience", "license": "GPL-2.0-or-later", - "dependencies": { - "normalize.css": "^8.0.1" - }, "devDependencies": { "10up-toolkit": "^6.2.0", "husky": "^8.0.3", @@ -5404,9 +5401,9 @@ "dev": true }, "node_modules/10up-toolkit": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/10up-toolkit/-/10up-toolkit-6.2.0.tgz", - "integrity": "sha512-fNBTD6EAMTwskbsg90c2EKNZ48XyaA63sLDW5SnEfkiP4grblNHU1NObCIS+l5bAkUF3qFKgU4Q6gxgamvUZ6Q==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/10up-toolkit/-/10up-toolkit-6.2.2.tgz", + "integrity": "sha512-4dfiIWmWF0M+rHINV14+IZxmQLfonDPKuU3YmxCCAjAsRw79GQIW+YNzMeasaxI760N+zWxPGgizv+GwP2jKOA==", "dev": true, "dependencies": { "@babel/eslint-parser": "^7.23.3", @@ -14451,11 +14448,6 @@ "node": ">=0.10.0" } }, - "node_modules/normalize.css": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", - "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==" - }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -19887,9 +19879,9 @@ "dev": true }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", - "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, "engines": { "node": ">=10.0.0" @@ -20247,9 +20239,9 @@ } }, "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, "engines": { "node": ">=8.3.0" diff --git a/package.json b/package.json index 5cd23e8..1fc9b37 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,6 @@ "husky": "^8.0.3", "lint-staged": "^11.2.6" }, - "dependencies": { - "normalize.css": "^8.0.1" - }, "10up-toolkit": { "entry": { "notices": "./assets/js/notices.js",