• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

equalizedigital / accessibility-checker / 13822285232

12 Mar 2025 09:55PM UTC coverage: 30.881%. First build
13822285232

Pull #863

github

web-flow
Merge 296556ac2 into e55df1ca7
Pull Request #863: Release v1.22.0

6 of 8 new or added lines in 2 files covered. (75.0%)

2208 of 7150 relevant lines covered (30.88%)

5.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

27.12
/includes/classes/Fixes/FixesManager.php
1
<?php
2
/**
3
 * Manager class for fixes.
4
 *
5
 * @package Accessibility_Checker
6
 */
7

8
namespace EqualizeDigital\AccessibilityChecker\Fixes;
9

10
use EqualizeDigital\AccessibilityChecker\Fixes\Fix\AddFileSizeAndTypeToLinkedFilesFix;
11
use EqualizeDigital\AccessibilityChecker\Fixes\Fix\AddLabelToUnlabelledFormFieldsFix;
12
use EqualizeDigital\AccessibilityChecker\Fixes\Fix\AddMissingOrEmptyPageTitleFix;
13
use EqualizeDigital\AccessibilityChecker\Fixes\Fix\AddNewWindowWarningFix;
14
use EqualizeDigital\AccessibilityChecker\Fixes\Fix\BlockPDFUploadsFix;
15
use EqualizeDigital\AccessibilityChecker\Fixes\Fix\CommentSearchLabelFix;
16
use EqualizeDigital\AccessibilityChecker\Fixes\Fix\HTMLLangAndDirFix;
17
use EqualizeDigital\AccessibilityChecker\Fixes\Fix\RemoveTitleIfPrefferedAccessibleNameFix;
18
use EqualizeDigital\AccessibilityChecker\Fixes\Fix\PreventLinksOpeningNewWindowFix;
19
use EqualizeDigital\AccessibilityChecker\Fixes\Fix\SkipLinkFix;
20
use EqualizeDigital\AccessibilityChecker\Fixes\Fix\TabindexFix;
21
use EqualizeDigital\AccessibilityChecker\Fixes\Fix\LinkUnderline;
22
use EqualizeDigital\AccessibilityChecker\Fixes\Fix\MetaViewportScalableFix;
23
use EqualizeDigital\AccessibilityChecker\Fixes\Fix\FocusOutlineFix;
24
use EqualizeDigital\AccessibilityChecker\Fixes\Fix\ReadMoreAddTitleFix;
25
use EqualizeDigital\AccessibilityChecker\Admin\AdminPage\FixesPage;
26

27
/**
28
 * Manager class for fixes.
29
 *
30
 * @since 1.16.0
31
 */
32
class FixesManager {
33

34
        /**
35
         * The single instance of the class.
36
         *
37
         * @var FixesManager|null
38
         */
39
        private static $instance = null;
40

41
        /**
42
         * Whether the theme has the accessibility-ready tag.
43
         *
44
         * @var bool|null
45
         */
46
        private static $theme_is_accessibility_ready = null;
47

48
        /**
49
         * The fixes.
50
         *
51
         * @var array
52
         */
53
        private $fixes = [];
54

55
        /**
56
         * Private constructor to prevent direct instantiation.
57
         */
58
        private function __construct() {
59
                $this->maybe_enqueue_frontend_scripts();
6✔
60
                $this->maybe_enqueue_thickbox();
6✔
61

62
                self::$theme_is_accessibility_ready = self::is_theme_accessibility_ready();
6✔
63
        }
64

65
        /**
66
         * Maybe enqueue the thickbox script.
67
         *
68
         * This powers the modal that is used to display fix settings in the editor.
69
         */
70
        public function maybe_enqueue_thickbox() {
71
                add_action(
6✔
72
                        'admin_enqueue_scripts',
6✔
73
                        function () {
6✔
74
                                add_thickbox();
×
75
                        }
6✔
76
                );
6✔
77
        }
78

79
        /**
80
         * Get the single instance of the class.
81
         *
82
         * @return FixesManager
83
         */
84
        public static function get_instance() {
85
                if ( null === self::$instance ) {
6✔
86
                        self::$instance = new self();
6✔
87
                }
88
                return self::$instance;
6✔
89
        }
90

91
        /**
92
         * Maybe enqueue the frontend scripts.
93
         */
94
        private function maybe_enqueue_frontend_scripts() {
95

96
                if (
97
                        ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ||
6✔
98
                        ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ||
6✔
99
                        ( defined( 'DOING_CRON' ) && DOING_CRON ) ||
6✔
100
                        ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
6✔
101
                ) {
102
                        return;
×
103
                }
104

105
                // Consider adding this only if we can determine at least 1 of the fixes are enabled.
106
                add_action(
6✔
107
                        'wp_enqueue_scripts',
6✔
108
                        function () {
6✔
109
                                wp_enqueue_script( 'edac-frontend-fixes', EDAC_PLUGIN_URL . 'build/frontendFixes.bundle.js', [], EDAC_VERSION, true );
×
110
                                wp_localize_script(
×
111
                                        'edac-frontend-fixes',
×
112
                                        'edac_frontend_fixes',
×
113
                                        apply_filters( 'edac_filter_frontend_fixes_data', [] )
×
114
                                );
×
115
                                do_action( 'edac_action_enqueue_frontend_fixes' );
×
116
                        }
6✔
117
                );
6✔
118
        }
119

120
        /**
121
         * Load the fixes.
122
         */
123
        private function load_fixes() {
124
                $fixes = apply_filters(
×
125
                        'edac_filter_fixes',
×
126
                        [
×
127
                                SkipLinkFix::class,
×
128
                                CommentSearchLabelFix::class,
×
129
                                HTMLLangAndDirFix::class,
×
130
                                TabindexFix::class,
×
131
                                RemoveTitleIfPrefferedAccessibleNameFix::class,
×
132
                                LinkUnderline::class,
×
133
                                MetaViewportScalableFix::class,
×
134
                                PreventLinksOpeningNewWindowFix::class,
×
135
                                FocusOutlineFix::class,
×
136
                                BlockPDFUploadsFix::class,
×
137
                                AddFileSizeAndTypeToLinkedFilesFix::class,
×
138
                                AddMissingOrEmptyPageTitleFix::class,
×
139
                                AddLabelToUnlabelledFormFieldsFix::class,
×
140
                                AddNewWindowWarningFix::class,
×
141
                        ]
×
142
                );
×
143
                foreach ( $fixes as $fix ) {
×
144
                        if ( is_subclass_of( $fix, '\EqualizeDigital\AccessibilityChecker\Fixes\FixInterface' ) ) {
×
145
                                if ( ! isset( $this->fixes[ $fix::get_slug() ] ) ) {
×
146
                                        $this->fixes[ $fix::get_slug() ] = ( new $fix() );
×
147
                                }
148
                        }
149
                }
150
        }
151

152
        /**
153
         * Get a fix by its slug.
154
         *
155
         * @param string $slug The fix slug.
156
         *
157
         * @return FixInterface|null
158
         */
159
        public function get_fix( $slug ) {
160
                return isset( $this->fixes[ $slug ] ) ? $this->fixes[ $slug ] : null;
×
161
        }
162

163
        /**
164
         * Get the fixes settings.
165
         *
166
         * Returns an array of all the fix settings and their values along with a pro or not flag.
167
         *
168
         * @return array
169
         */
170
        public function get_fixes_settings() {
171
                $fixes_array = [];
6✔
172
                foreach ( $this->fixes as $fix ) {
6✔
173

174
                        $fields = [];
4✔
175
                        foreach ( $fix->get_fields_array() as $field_slug => $field ) {
4✔
176
                                $fields[ $field_slug ] = get_option( $field_slug, $field['default'] ?? 0 );
4✔
177
                        }
178

179
                        $fixes_array[ $fix::get_slug() ] = [
4✔
180
                                'fields' => $fields,
4✔
181
                                'is_pro' => isset( $fix->is_pro ) ? $fix->is_pro : false,
4✔
182
                        ];
4✔
183
                }
184
                return $fixes_array;
6✔
185
        }
186

187
        /**
188
         * Register the fixes.
189
         */
190
        public function register_fixes() {
191
                $this->load_fixes();
×
192

193
                foreach ( $this->fixes as $fix ) {
×
194
                        $fix->register();
×
195
                        $this->maybe_run_fix( $fix );
×
196
                }
197
        }
198

199
        /**
200
         * Maybe run a fix depending on current context.
201
         *
202
         * @param FixInterface $fix The fix to maybe run.
203
         */
204
        public function maybe_run_fix( $fix ) {
205
                if ( 'backend' === $fix::get_type() && is_admin() ) {
×
206
                        $fix->run();
×
207
                } elseif ( 'frontend' === $fix::get_type() && ! is_admin() ) {
×
208
                        $fix->run();
×
209
                } elseif ( 'everywhere' === $fix::get_type() ) {
×
210
                        $fix->run();
×
211
                }
212
        }
213

214
        /**
215
         * Check if the theme is accessibility ready.
216
         *
217
         * True if the theme has the tag, false otherwise.
218
         *
219
         * @return bool
220
         */
221
        public static function is_theme_accessibility_ready() {
222
                if ( null !== self::$theme_is_accessibility_ready ) {
6✔
223
                        return self::$theme_is_accessibility_ready;
6✔
224
                }
225

226
                $theme = wp_get_theme();
×
227
                $tags  = $theme->get( 'Tags' );
×
228

NEW
229
                self::$theme_is_accessibility_ready = is_array( $tags ) && in_array( 'accessibility-ready', $tags, true );
×
230
                return self::$theme_is_accessibility_ready;
×
231
        }
232

233
        /**
234
         * Maybe show a notice if the theme is accessibility-ready.
235
         */
236
        public static function maybe_show_accessibility_ready_conflict_notice() {
237
                if ( self::is_theme_accessibility_ready() ) {
×
238
                        ?>
239
                        <span class="edac-notice--accessibility-ready-conflict">
×
240
                                <?php esc_html_e( 'Note: This setting is not recommended for themes that are already accessibility-ready.', 'accessibility-checker' ); ?>
×
241
                        </span>
×
242
                        <?php
×
243
                }
244
        }
245

246
        /**
247
         * Register the rest routes.
248
         *
249
         * @return void
250
         */
251
        public function register_rest_routes() {
252
                register_rest_route(
×
253
                        'edac/v1',
×
254
                        '/fixes',
×
255
                        [
×
256
                                'methods'             => 'GET',
×
257
                                'callback'            => [ $this, 'get_fixes' ],
×
258
                                'permission_callback' => function () {
×
259
                                        return current_user_can( apply_filters( 'edac_filter_settings_capability', 'manage_options' ) );
×
260
                                },
×
261
                        ]
×
262
                );
×
263

264
                register_rest_route(
×
265
                        'edac/v1',
×
266
                        '/fixes/update',
×
267
                        [
×
268
                                'methods'             => 'POST',
×
269
                                'callback'            => [ $this, 'update_fix_settings' ],
×
270
                                'permission_callback' => function () {
×
271
                                        return current_user_can( apply_filters( 'edac_filter_settings_capability', 'manage_options' ) );
×
272
                                },
×
273
                        ]
×
274
                );
×
275
        }
276

277
        /**
278
         * Handle the request to set a fix.
279
         *
280
         * @param \WP_REST_Request $request The request recieved through a rest call.
281
         *
282
         * @return \WP_Error|\WP_HTTP_Response|\WP_REST_Response
283
         */
284
        public function update_fix_settings( $request ) {
285
                // get body of the request.
286
                $body = $request->get_json_params();
×
287

288
                // loop through body and find fixes for those items.
289
                foreach ( $body as $rule_slug => $settings ) {
×
290
                        $fix        = $this->get_fix( $rule_slug );
×
291
                        $fix_fields = $fix->get_fields_array();
×
292
                        if ( ! $fix ) {
×
293
                                return new \WP_Error( 'edac_fix_not_found', esc_html__( 'Fix not found', 'accessibility-checker' ), [ 'status' => 404 ] );
×
294
                        }
295

296
                        foreach ( $settings as $setting => $value ) {
×
297
                                $sanitizer = isset( $fix_fields[ $setting ]['sanitize_callback'] ) ? $fix_fields[ $setting ]['sanitize_callback'] : [ FixesPage::class, 'sanitize_' . $fix_fields[ $setting ]['type'] ];
×
298
                                if ( ! $sanitizer || ! is_callable( $sanitizer ) ) {
×
299
                                        // no sanitizer, do not save.
300
                                        continue;
×
301
                                }
302
                                update_option( $setting, $sanitizer( $value ) );
×
303
                        }
304
                }
305

306
                return rest_ensure_response( [ 'enabled' => $enabled ] );
×
307
        }
308
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc