';
@@ -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;
+
+ ?>
+
+
+
+
+ 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() {
+ ?>
+