diff --git a/admin/class-ajax.php b/admin/class-ajax.php index bb24eb0c7..b1ab06748 100644 --- a/admin/class-ajax.php +++ b/admin/class-ajax.php @@ -118,6 +118,9 @@ public function summary() { $html['content'] .= ''; + // if this is a virtual page, we don't show the readability section. + $is_virtual_page = edac_is_virtual_page( $post_id ); + $html['content'] .= ' ' . edac_generate_summary_stat( 'edac-summary-errors', @@ -145,7 +148,7 @@ public function summary() { ) . ' -
+
@@ -479,7 +482,7 @@ function ( $a, $b ) { $landmark = isset( $row['landmark'] ) ? $row['landmark'] : ''; $landmark_selector = isset( $row['landmark_selector'] ) ? $row['landmark_selector'] : ''; - + $html .= edac_generate_landmark_link( $landmark, $landmark_selector, $postid ); $html .= '
'; @@ -488,12 +491,18 @@ function ( $a, $b ) { if ( ! isset( $rule['viewable'] ) || $rule['viewable'] ) { + $post_view_link = apply_filters( + 'edac_get_origin_url_for_virtual_page', + get_the_permalink( $postid ), + $postid + ); + $url = add_query_arg( [ 'edac' => $id, 'edac_nonce' => wp_create_nonce( 'edac_highlight' ), ], - get_the_permalink( $postid ) + $post_view_link ); // Translators: %d is the issue ID. diff --git a/admin/class-enqueue-admin.php b/admin/class-enqueue-admin.php index 821e867fc..32197dd00 100644 --- a/admin/class-enqueue-admin.php +++ b/admin/class-enqueue-admin.php @@ -48,7 +48,7 @@ public static function enqueue_styles() { public static function maybe_enqueue_admin_and_editor_app_scripts() { global $pagenow; - $post_types = get_option( 'edac_post_types' ); + $post_types = Settings::get_scannable_post_types(); $current_post_type = get_post_type(); $page = self::get_current_page_slug(); $enabled_pages = apply_filters( @@ -82,18 +82,18 @@ public static function maybe_enqueue_admin_and_editor_app_scripts() { 'edac', 'edac_script_vars', [ - 'postID' => $post_id, - 'nonce' => wp_create_nonce( 'ajax-nonce' ), - 'edacApiUrl' => esc_url_raw( rest_url() . 'accessibility-checker/v1' ), - 'restNonce' => wp_create_nonce( 'wp_rest' ), - 'fixesProUrl' => esc_url_raw( edac_generate_link_type( [ 'utm-content', '__fix__' ] ) ), + 'postID' => $post_id, + 'nonce' => wp_create_nonce( 'ajax-nonce' ), + 'edacApiUrl' => esc_url_raw( rest_url() . 'accessibility-checker/v1' ), + 'restNonce' => wp_create_nonce( 'wp_rest' ), + 'proUrl' => esc_url_raw( edac_generate_link_type( [ 'utm-content' => '__name__' ] ) ), ] ); if ( 'post.php' === $pagenow || 'post-new.php' === $pagenow ) { // Is this posttype setup to be checked? - $post_types = get_option( 'edac_post_types' ); + $post_types = Settings::get_scannable_post_types(); $current_post_type = get_post_type(); $active = ( is_array( $post_types ) && in_array( $current_post_type, $post_types, true ) ); @@ -112,9 +112,17 @@ public static function maybe_enqueue_admin_and_editor_app_scripts() { if ( (int) get_option( 'page_on_front' ) === $post_id || (int) get_option( 'page_for_posts' ) === $post_id ) { $scan_url = add_query_arg( 'edac_pageScanner', 1, get_permalink( $post_id ) ); } else { - $scan_url = get_preview_post_link( - $post_id, - [ 'edac_pageScanner' => 1 ] + $post_view_link = apply_filters( + 'edac_get_origin_url_for_virtual_page', + get_preview_post_link( $post_id ), + $post_id + ); + + $scan_url = add_query_arg( + [ + 'edac_pageScanner' => 1, + ], + $post_view_link ); } diff --git a/admin/class-meta-boxes.php b/admin/class-meta-boxes.php index 727ef1925..c1e0be41c 100644 --- a/admin/class-meta-boxes.php +++ b/admin/class-meta-boxes.php @@ -31,7 +31,7 @@ public function init_hooks(): void { * @return void */ public function register_meta_boxes(): void { - $post_types = get_option( 'edac_post_types' ); + $post_types = Settings::get_scannable_post_types(); if ( $post_types ) { foreach ( $post_types as $post_type ) { add_meta_box( diff --git a/admin/class-post-save.php b/admin/class-post-save.php index 36cf268ca..71d872d6b 100644 --- a/admin/class-post-save.php +++ b/admin/class-post-save.php @@ -35,7 +35,7 @@ class Post_Save { */ public static function delete_issue_data_on_post_trashing( $post_ID, $post, $update ) { // check post type. - $post_types = get_option( 'edac_post_types' ); + $post_types = Settings::get_scannable_post_types(); if ( is_array( $post_types ) && ! in_array( $post->post_type, $post_types, true ) ) { return; } diff --git a/admin/class-purge-post-data.php b/admin/class-purge-post-data.php index 4c48f5f4c..8569316c3 100755 --- a/admin/class-purge-post-data.php +++ b/admin/class-purge-post-data.php @@ -82,6 +82,15 @@ public static function delete_cpt_posts( string $post_type ) { global $wpdb; + /** + * Fires before deleting posts of a specific post type. + * + * @since 1.31.0 + * + * @param string $post_type Post Type. + */ + do_action( 'edac_before_delete_cpt_posts', $post_type ); + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Safe variable used for table name, caching not required for one time operation. return $wpdb->query( $wpdb->prepare( diff --git a/admin/class-scans-stats.php b/admin/class-scans-stats.php index 02ca7f26a..d2bd08182 100644 --- a/admin/class-scans-stats.php +++ b/admin/class-scans-stats.php @@ -143,7 +143,7 @@ public function summary( $skip_cache = false ) { $data['scannable_posts_count'] = (int) $scannable_posts_count; $data['rule_count'] = (int) $this->rule_count; $data['tests_count'] = (int) $tests_count; - $data['scannable_post_types_count'] = (int) count( Settings::get_scannable_post_types() ); + $data['scannable_post_types_count'] = (int) count( Settings::get_scannable_post_types( true ) ); $post_types = get_post_types( [ diff --git a/admin/class-settings.php b/admin/class-settings.php index 14291abfa..2e5385c74 100644 --- a/admin/class-settings.php +++ b/admin/class-settings.php @@ -35,40 +35,39 @@ public static function get_scannable_post_statuses() { /** * Gets a list of post types that are scannable. * + * @param bool $skip_filtering Whether to skip filtering when passing through alternative settings class. + * * @return array */ - public static function get_scannable_post_types() { + public static function get_scannable_post_types( $skip_filtering = false ) { - // Check if the new settings class exists. This is added to allow for backwards compatibility - // with the old settings class. The old settings class check should be removed after a few releases. - $new_settings_class_exists = class_exists( 'EqualizeDigital\AccessibilityCheckerPro\Admin\Settings' ); - if ( ! class_exists( '\EDACP\Settings' ) && ! $new_settings_class_exists ) { + if ( + class_exists( 'EqualizeDigital\AccessibilityCheckerPro\Admin\Settings' ) && + method_exists( 'EqualizeDigital\AccessibilityCheckerPro\Admin\Settings', 'get_scannable_post_types' ) + ) { + return \EqualizeDigital\AccessibilityCheckerPro\Admin\Settings::get_scannable_post_types( $skip_filtering ); + } - $post_types = Helpers::get_option_as_array( 'edac_post_types' ); + $post_types = Helpers::get_option_as_array( 'edac_post_types' ); - // remove duplicates. - $post_types = array_unique( $post_types ); + // remove duplicates. + $post_types = array_unique( $post_types ); - // validate post types. - $args = [ - 'public' => true, - '_builtin' => true, - ]; - $valid_post_types = get_post_types( $args, 'names', 'and' ); - unset( $valid_post_types['attachment'] ); + // validate post types. + $args = [ + 'public' => true, + '_builtin' => true, + ]; + $valid_post_types = get_post_types( $args, 'names', 'and' ); + unset( $valid_post_types['attachment'] ); - foreach ( $post_types as $key => $post_type ) { + foreach ( $post_types as $key => $post_type ) { - if ( ! post_type_exists( $post_type ) || ! array_key_exists( $post_type, $valid_post_types ) ) { - unset( $post_types[ $key ] ); - } + if ( ! post_type_exists( $post_type ) || ! array_key_exists( $post_type, $valid_post_types ) ) { + unset( $post_types[ $key ] ); } - return $post_types; } - - return $new_settings_class_exists - ? \EqualizeDigital\AccessibilityCheckerPro\Admin\Settings::get_scannable_post_types() - : \EDACP\Settings::get_scannable_post_types(); + return $post_types; } diff --git a/includes/activation.php b/includes/activation.php index 3b0609783..f24ecc716 100644 --- a/includes/activation.php +++ b/includes/activation.php @@ -19,4 +19,7 @@ function edac_activation() { update_option( 'edac_simplified_summary_position', 'after' ); Accessibility_Statement::add_page(); + + // This is an add_option on purpose to not overwrite user settings on update. + add_option( 'edacp_ignore_user_roles', [ 'administrator' ] ); } diff --git a/includes/classes/class-enqueue-frontend.php b/includes/classes/class-enqueue-frontend.php index ce56415de..78862b1fd 100644 --- a/includes/classes/class-enqueue-frontend.php +++ b/includes/classes/class-enqueue-frontend.php @@ -7,6 +7,8 @@ namespace EDAC\Inc; +use EDAC\Admin\Settings; + /** * Class that initializes and handles enqueueing styles and scripts for the frontend. */ @@ -50,7 +52,7 @@ public static function maybe_enqueue_frontend_highlighter() { // Don't load on the frontend if we don't have a post to work with. global $post; - $post_id = is_object( $post ) ? $post->ID : null; + $post_id = apply_filters( 'edac_filter_frontend_highlight_post_id', is_object( $post ) ? $post->ID : null ); if ( null === $post_id ) { return; @@ -82,7 +84,7 @@ public static function maybe_enqueue_frontend_highlighter() { // Don't load if this pagetype is not setup to be scanned. - $post_types = get_option( 'edac_post_types' ); + $post_types = Settings::get_scannable_post_types(); $current_post_type = get_post_type(); $active = ( is_array( $post_types ) && in_array( $current_post_type, $post_types, true ) ); diff --git a/includes/classes/class-rest-api.php b/includes/classes/class-rest-api.php index d1f1a0c4d..e47a7b3e7 100644 --- a/includes/classes/class-rest-api.php +++ b/includes/classes/class-rest-api.php @@ -7,7 +7,6 @@ namespace EDAC\Inc; -use EDAC\Admin\Helpers; use EDAC\Admin\Insert_Rule_Data; use EDAC\Admin\Scans_Stats; use EDAC\Admin\Settings; @@ -248,7 +247,7 @@ public function clear_issues_for_post( $request ) { } $post_type = get_post_type( $post ); - $post_types = Helpers::get_option_as_array( 'edac_post_types' ); + $post_types = Settings::get_scannable_post_types(); if ( empty( $post_types ) || ! in_array( $post_type, $post_types, true ) ) { return new \WP_REST_Response( [ 'message' => 'The post type is not set to be scanned.' ], 400 ); } @@ -320,7 +319,7 @@ public function set_post_scan_results( $request ) { } $post_type = get_post_type( $post ); - $post_types = Helpers::get_option_as_array( 'edac_post_types' ); + $post_types = Settings::get_scannable_post_types(); if ( empty( $post_types ) || ! in_array( $post_type, $post_types, true ) ) { return new \WP_REST_Response( [ 'message' => 'The post type is not set to be scanned.' ], 400 ); diff --git a/includes/helper-functions.php b/includes/helper-functions.php index e547fabf1..85237460e 100644 --- a/includes/helper-functions.php +++ b/includes/helper-functions.php @@ -5,6 +5,8 @@ * @package Accessibility_Checker */ +use EDAC\Admin\Settings; + /** * Compare strings * @@ -408,7 +410,7 @@ function edac_get_posts_count() { $output = []; - $post_types = get_option( 'edac_post_types' ); + $post_types = Settings::get_scannable_post_types(); if ( $post_types ) { foreach ( $post_types as $post_type ) { @@ -767,22 +769,28 @@ function edac_generate_landmark_link( $landmark, $landmark_selector, $post_id, $ } $landmark = ucwords( $landmark ); $landmark = esc_html( $landmark ); - + // If we have both landmark and selector, create a link. if ( ! empty( $landmark_selector ) ) { + $link = apply_filters( + 'edac_get_origin_url_for_virtual_page', + get_the_permalink( $post_id ), + $post_id + ); + $landmark_url = add_query_arg( [ 'edac_landmark' => base64_encode( $landmark_selector ), 'edac_nonce' => wp_create_nonce( 'edac_highlight' ), ], - get_the_permalink( $post_id ) + $link ); - + // translators: %s is the landmark type (e.g., "Header", "Navigation", "Main"). $landmark_aria_label = sprintf( __( 'View %s landmark on website, opens a new window', 'accessibility-checker' ), $landmark ); - + $target_attr = $target_blank ? ' target="_blank"' : ''; - + return sprintf( '%s', esc_url( $landmark_url ), @@ -792,7 +800,35 @@ function edac_generate_landmark_link( $landmark, $landmark_selector, $post_id, $ $landmark ); } - + // If we only have landmark text, return it formatted. return $landmark; } + +/** + * Check if a post is a virtual page. + * + * This function checks if a post is a virtual page using the pro plugin's + * VirtualItemType:POST_TYPE constant. + * + * @param int $post_id The post ID to check. + * @return bool True if the post is a virtual page, false otherwise. + */ +function edac_is_virtual_page( $post_id ) { + if ( class_exists( '\EqualizeDigital\AccessibilityCheckerPro\VirtualContent\PostType\VirtualItemType' ) ) { + $post_type = get_post_type( $post_id ); + $pro_post_type = \EqualizeDigital\AccessibilityCheckerPro\VirtualContent\PostType\VirtualItemType::POST_TYPE; + return $pro_post_type === $post_type; + } + + return false; +} + +/** + * Check if the Pro version of the plugin is active. + * + * @return bool True if Pro version is active, false otherwise. + */ +function edac_is_pro() { + return defined( 'EDACP_VERSION' ) && defined( 'EDAC_KEY_VALID' ) && EDAC_KEY_VALID; +} diff --git a/includes/options-page.php b/includes/options-page.php index 98a04e07f..a4f511308 100644 --- a/includes/options-page.php +++ b/includes/options-page.php @@ -6,6 +6,8 @@ */ use EDAC\Admin\Purge_Post_Data; +use EDAC\Admin\Scans_Stats; +use EDAC\Admin\Settings; use EDAC\Inc\Accessibility_Statement; use EqualizeDigital\AccessibilityChecker\Admin\AdminPage\FixesPage; @@ -72,6 +74,16 @@ function edac_add_options_page() { $fixes_page = new FixesPage( $settings_capability ); $fixes_page->add_page(); + + // Deregister the pro setting registration - this is added for backwards compatibility for users + // that don't update pro. Added here in 1.31.0 and released with pro 1.16.0. + add_action( + 'admin_init', + function () { + // Remove the pro plugin's settings registration entirely. + remove_action( 'admin_init', 'edacp_register_setting', 11 ); + } + ); } /** @@ -96,11 +108,18 @@ function edac_register_setting() { // Add sections. add_settings_section( 'edac_general', - __( 'General Settings', 'accessibility-checker' ), + __( 'Scan Settings', 'accessibility-checker' ), 'edac_general_cb', 'edac_settings' ); + add_settings_section( + 'edac_permissions', + __( 'Permissions', 'accessibility-checker' ), + 'edac_permissions_section_cb', + 'edac_settings' + ); + add_settings_section( 'edac_simplified_summary', __( 'Simplified Summary Settings', 'accessibility-checker' ), @@ -122,6 +141,13 @@ function edac_register_setting() { 'edac_settings' ); + add_settings_section( + 'edac_system', + __( 'System Settings', 'accessibility-checker' ), + 'edac_system_cb', + 'edac_settings' + ); + // Add fields. add_settings_field( 'edac_post_types', @@ -132,12 +158,48 @@ function edac_register_setting() { [ 'label_for' => 'edac_post_types' ] ); + add_settings_field( + 'edacp_full_site_scan_speed', + __( 'Scan Speed', 'accessibility-checker' ), + 'edac_full_site_scan_speed_cb', + 'edac_settings', + 'edac_general', + [ 'label_for' => 'edacp_full_site_scan_speed' ] + ); + + add_settings_field( + 'edacp_enable_archive_scanning', + __( 'Enable Archive Scanning', 'accessibility-checker' ), + 'edac_enable_archive_scanning_cb', + 'edac_settings', + 'edac_general', + [ 'label_for' => 'edacp_enable_archive_scanning' ] + ); + + add_settings_field( + 'edacp_scan_all_taxonomy_terms', + __( 'Scan All Taxonomy Terms', 'accessibility-checker' ), + 'edac_scan_all_taxonomy_terms_cb', + 'edac_settings', + 'edac_general', + [ 'label_for' => 'edacp_scan_all_taxonomy_terms' ] + ); + + add_settings_field( + 'edacp_ignore_user_roles', + __( 'Ignore Permissions', 'accessibility-checker' ), + 'edac_ignore_user_roles_cb', + 'edac_settings', + 'edac_permissions', + [ 'label_for' => 'edac_ignore_user_roles' ] + ); + add_settings_field( 'edac_delete_data', __( 'Delete Data', 'accessibility-checker' ), 'edac_delete_data_cb', 'edac_settings', - 'edac_general', + 'edac_system', [ 'label_for' => 'edac_delete_data' ] ); @@ -159,6 +221,15 @@ function edac_register_setting() { [ 'label_for' => 'edac_simplified_summary_position' ] ); + add_settings_field( + 'edacp_simplified_summary_heading', + __( 'Simplified Summary Heading', 'accessibility-checker' ), + 'edac_simplified_summary_heading_cb', + 'edac_settings', + 'edac_simplified_summary', + [ 'label_for' => 'edacp_simplified_summary_heading' ] + ); + add_settings_field( 'edac_add_footer_accessibility_statement', __( 'Add Footer Accessibility Statement', 'accessibility-checker' ), @@ -204,9 +275,9 @@ function edac_register_setting() { [ 'label_for' => 'edac_frontend_highlighter_position' ] ); - // Register settings. register_setting( 'edac_settings', 'edac_post_types', 'edac_sanitize_post_types' ); + register_setting( 'edac_settings', 'edac_delete_data', 'edac_sanitize_checkbox' ); register_setting( 'edac_settings', @@ -231,6 +302,13 @@ function edac_register_setting() { register_setting( 'edac_settings', 'edac_accessibility_policy_page', 'edac_sanitize_accessibility_policy_page' ); register_setting( 'edac_settings', 'edac_frontend_highlighter_position', 'edac_sanitize_frontend_highlighter_position' ); + + // Upsell settings - these are using edacp prefix for backwards compatibility. + register_setting( 'edac_settings', 'edacp_full_site_scan_speed', 'edac_sanitize_pro_scan_speed' ); + register_setting( 'edac_settings', 'edacp_enable_archive_scanning', 'edac_sanitize_pro_archive_scanning' ); + register_setting( 'edac_settings', 'edacp_scan_all_taxonomy_terms', 'edac_sanitize_pro_taxonomy_terms' ); + register_setting( 'edac_settings', 'edacp_ignore_user_roles', 'edac_sanitize_pro_ignore_roles' ); + register_setting( 'edac_settings', 'edacp_simplified_summary_heading', 'edac_sanitize_pro_summary_heading' ); } /** @@ -239,13 +317,9 @@ function edac_register_setting() { function edac_general_cb() { echo '

'; - printf( - /* translators: %1$s: link to the plugin documentation website. */ - esc_html__( 'Use the settings below to configure Accessibility Checker. Additional information about each setting can be found in the %1$s.', 'accessibility-checker' ), - '' . esc_html__( 'plugin documentation', 'accessibility-checker' ) . '' - ); + esc_html_e( 'Configure the types of content that should be checked for accessibility issues.', 'accessibility-checker' ); - if ( EDAC_KEY_VALID === false ) { + if ( ! edac_is_pro() ) { printf( /* translators: %1$s: link to the "Accessibility Checker Pro" website. */ ' ' . esc_html__( 'More features and email support is available with %1$s.', 'accessibility-checker' ), @@ -303,6 +377,130 @@ function edac_footer_accessibility_statement_cb() { echo '

'; } +/** + * Render the text for the system settings section + */ +function edac_system_cb() { + echo '

'; + esc_html_e( 'Configure system-level settings for the Accessibility Checker plugin.', 'accessibility-checker' ); + echo '

'; +} + +/** + * Render the dropdown input field for scan speed option. + * + * Note: this setting is purposefully using edacp as prefix for back compat reasons. + */ +function edac_full_site_scan_speed_cb() { + + $full_site_scan_speed = (int) get_option( 'edacp_full_site_scan_speed', 1000 ); + + $speed_values = [ + '250' => __( 'Fast', 'accessibility-checker' ), + '1000' => __( 'Normal', 'accessibility-checker' ), + '5000' => __( 'Slow', 'accessibility-checker' ), + '30000' => __( 'Slowest', 'accessibility-checker' ), + ]; + + ?> +
> + +
+

+ +

+ +
> + +
+

+ +

+ +
> + +
+

+ +

+ clear_cache(); // EDACP\Scans is the old namespace, kept for back compat but should be removed after a few releases. @@ -611,6 +813,90 @@ function edac_delete_data_cb() { + + type="text" + name="edacp_simplified_summary_heading" + id="edacp_simplified_summary_heading" + value="" + + > + roles; + + ?> +
> + + $role ) : ?> + +
+ + +
+

+ +

+ roles ); + + if ( $selected_roles ) { + foreach ( $selected_roles as $key => $selected_role ) { + if ( ! in_array( $selected_role, (array) $roles, true ) ) { + unset( $selected_roles[ $key ] ); + } + } + } + + return $selected_roles; +} + +/** + * Render the text for the permissions section + */ +function edac_permissions_section_cb() { + ?> +

+ +

+

@@ -31,7 +34,7 @@ class="active" -
  • +
  • >