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

equalizedigital / accessibility-checker / 14914072596

08 May 2025 07:03PM UTC coverage: 28.872%. First build
14914072596

Pull #966

github

web-flow
Merge f62f5bbff into f6dc26e5a
Pull Request #966: Release v1.23.0

55 of 158 new or added lines in 10 files covered. (34.81%)

1495 of 5178 relevant lines covered (28.87%)

1.49 hits per line

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

16.1
/includes/helper-functions.php
1
<?php
2
/**
3
 * Accessibility Checker pluign file.
4
 *
5
 * @package Accessibility_Checker
6
 */
7

8
/**
9
 * Compare strings
10
 *
11
 * @param string $string1 String to compare.
12
 * @param string $string2 String to compare.
13
 * @return boolean
14
 */
15
function edac_compare_strings( $string1, $string2 ) {
16
        /**
17
         * Prepare strings for our comparison.
18
         *
19
         * @param string $content String to prepare.
20
         * @return string
21
         */
22
        $prepare_strings = function ( $content ) {
12✔
23
                // Text to remove.
24
                $remove_text = [
12✔
25
                        __( 'permalink of ', 'accessibility-checker' ),
12✔
26
                        __( 'permalink to ', 'accessibility-checker' ),
12✔
27
                        __( '&nbsp;', 'accessibility-checker' ),
12✔
28
                ];
12✔
29

30
                $content = strtolower( $content );
12✔
31
                $content = str_ireplace( $remove_text, '', $content );
12✔
32
                $content = wp_strip_all_tags( $content );
12✔
33
                $content = trim( $content, " \t\n\r\0\x0B\xC2\xA0" );
12✔
34

35
                return html_entity_decode( $content );
12✔
36
        };
12✔
37

38
        return $prepare_strings( $string1 ) === $prepare_strings( $string2 );
12✔
39
}
40

41
/**
42
 * Check if plugin is installed by getting all plugins from the plugins dir
43
 *
44
 * @param string $plugin_slug Slug of the plugin.
45
 * @return bool
46
 */
47
function edac_check_plugin_installed( $plugin_slug ) {
48
        $installed_plugins = get_plugins();
×
49

50
        return array_key_exists( $plugin_slug, $installed_plugins ) || in_array( $plugin_slug, $installed_plugins, true );
×
51
}
52

53
/**
54
 * Convert cardinal number into ordinal number
55
 *
56
 * @param int|string $number Number to make ordinal.
57
 * @return string
58
 */
59
function edac_ordinal( $number ) {
60

61
        $number = (int) $number;
32✔
62

63
        if ( class_exists( 'NumberFormatter' ) ) {
32✔
64
                return (
32✔
65
                        new NumberFormatter(
32✔
66
                                get_locale(),
32✔
67
                                NumberFormatter::ORDINAL
32✔
68
                        )
32✔
69
                )->format( $number );
32✔
70

71
        } else {
72
                if ( $number % 100 >= 11 && $number % 100 <= 13 ) {
×
73
                        $ordinal = $number . 'th';
×
74
                } else {
75
                        switch ( $number % 10 ) {
×
76
                                case 1:
×
77
                                        $ordinal = $number . 'st';
×
78
                                        break;
×
79
                                case 2:
×
80
                                        $ordinal = $number . 'nd';
×
81
                                        break;
×
82
                                case 3:
×
83
                                        $ordinal = $number . 'rd';
×
84
                                        break;
×
85
                                default:
86
                                        $ordinal = $number . 'th';
×
87
                                        break;
×
88
                        }
89
                }
90
                return $ordinal;
×
91

92
        }
93
}
94

95
/**
96
 * Remove element from multidimensional array
97
 *
98
 * @param array  $items The multidimensional array.
99
 * @param string $key The key of the element.
100
 * @param string $value The value of the element.
101
 * @return array
102
 */
103
function edac_remove_element_with_value( $items, $key, $value ) {
104
        foreach ( $items as $sub_key => $sub_array ) {
×
105
                if ( $sub_array[ $key ] === $value ) {
×
106
                        unset( $items[ $sub_key ] );
×
107
                }
108
        }
109
        return $items;
×
110
}
111

112
/**
113
 * Filter a multi-demensional array
114
 *
115
 * @param array  $items The multi-dimensional array.
116
 * @param string $index The index of the element.
117
 * @param string $value of the array.
118
 * @return array
119
 */
120
function edac_filter_by_value( $items, $index, $value ) {
121
        if ( is_array( $items ) && count( $items ) > 0 ) {
×
122
                foreach ( array_keys( $items ) as $key ) {
×
123
                        $temp[ $key ] = $items[ $key ][ $index ];
×
124

125
                        if ( $temp[ $key ] === $value ) {
×
126
                                $newarray[ $key ] = $items[ $key ];
×
127
                        }
128
                }
129
        }
130

131
        if ( isset( $newarray ) && is_array( $newarray ) && count( $newarray ) ) {
×
132
                return array_values( $newarray );
×
133
        }
134
        return [];
×
135
}
136

137
/**
138
 * Get days plugin has been active
139
 *
140
 * @return int
141
 */
142
function edac_days_active() {
143
        $activation_date = get_option( 'edac_activation_date' );
×
144
        if ( $activation_date ) {
×
145
                $diff = strtotime( $activation_date ) - strtotime( gmdate( 'Y-m-d H:i:s' ) );
×
146
                return abs( round( $diff / 86400 ) );
×
147
        }
148
        return 0;
×
149
}
150

151
/**
152
 * Documentation Link.
153
 *
154
 * @param array $rule to get link from.
155
 * @return string markup for link.
156
 */
157
function edac_documentation_link( $rule ) {
158
        global $wp_version;
×
159
        $days_active = edac_days_active();
×
160

161
        if ( ! $rule['info_url'] || ! isset( $rule['slug'] ) ) {
×
162
                return '';
×
163
        }
164

165
        return add_query_arg(
×
166
                [
×
167
                        'utm_source'       => 'accessibility-checker',
×
168
                        'utm_medium'       => 'software',
×
169
                        'utm_term'         => esc_attr( $rule['slug'] ),
×
170
                        'utm_content'      => 'content-analysis',
×
171
                        'utm_campaign'     => 'wordpress-general',
×
172
                        'php_version'      => PHP_VERSION,
×
173
                        'platform'         => 'wordpress',
×
174
                        'platform_version' => $wp_version,
×
175
                        'software'         => 'free',
×
176
                        'software_version' => EDAC_VERSION,
×
177
                        'days_active'      => $days_active,
×
178
                ],
×
179
                $rule['info_url']
×
180
        );
×
181
}
182

183
/**
184
 * Custom Post Types
185
 *
186
 * @return array
187
 */
188
function edac_custom_post_types() {
189
        $args = [
×
190
                'public'   => true,
×
191
                '_builtin' => false,
×
192
        ];
×
193

194
        $output   = 'names'; // names or objects, note names is the default.
×
195
        $operator = 'and'; // Options 'and' or 'or'.
×
196

197
        return get_post_types( $args, $output, $operator );
×
198
}
199

200
/**
201
 * Available Post Types
202
 *
203
 * @return array
204
 */
205
function edac_post_types() {
206
        /**
207
         * Filter the post types that the plugin will check.
208
         *
209
         * @since 1.4.0
210
         *
211
         * @param array $post_types post types.
212
         */
213
        $post_types = apply_filters( 'edac_filter_post_types', [ 'post', 'page' ] );
×
214

215
        // remove duplicates.
216
        $post_types = array_unique( $post_types );
×
217

218
        // validate post types.
219
        foreach ( $post_types as $key => $post_type ) {
×
220
                if ( ! post_type_exists( $post_type ) ) {
×
221
                        unset( $post_types[ $key ] );
×
222
                }
223
        }
224

225
        return $post_types;
×
226
}
227

228
/**
229
 * This function validates a table name against WordPress naming conventions and checks its existence in the database.
230
 *
231
 * The function first checks if the provided table name only contains alphanumeric characters, underscores, or hyphens.
232
 * If not, it returns null.
233
 *
234
 * After that, it checks if a table with that name actually exists in the database using the SHOW TABLES LIKE query.
235
 * If the table doesn't exist, it also returns null.
236
 *
237
 * If both checks are passed, it returns the valid table name.
238
 *
239
 * @param string $table_name The name of the table to be validated.
240
 *
241
 * @return string|null The validated table name, or null if the table name is invalid or the table does not exist.
242
 */
243
function edac_get_valid_table_name( $table_name ) {
244
        global $wpdb;
24✔
245

246
        // Check if table name only contains alphanumeric characters, underscores, or hyphens.
247
        if ( ! preg_match( '/^[a-zA-Z0-9_\-]+$/', $table_name ) ) {
24✔
248
                // Invalid table name.
249
                return null;
×
250
        }
251

252
        // Verify that the table actually exists in the database.
253
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
254
        if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) !== $table_name ) {
24✔
255
                // Table does not exist.
256
                return null;
×
257
        }
258

259
        return $table_name;
24✔
260
}
261

262
/**
263
 * Upcoming meetups in json format
264
 *
265
 * @param string  $meetup meetup name.
266
 * @param integer $count number of meetups to return.
267
 * @return json
268
 */
269
function edac_get_upcoming_meetups_json( $meetup, $count = 5 ) {
270

271
        if ( empty( $meetup ) || ! is_string( $meetup ) ) {
×
272
                return;
×
273
        }
274

275
        // Min of 1 and max of 25.
276
        $count = absint( max( 1, min( 25, $count ) ) );
×
277

278
        $key    = '_upcoming_meetups__' . sanitize_title( $meetup ) . '__' . (int) $count;
×
279
        $output = get_transient( $key );
×
280

281
        if ( false === $output ) {
×
282
                $request_uri = 'https://api.meetup.com/gql-ext';
×
283
                $query       = '
×
284
                query Group {
285
                        groupByUrlname(urlname: "' . (string) $meetup . '") {
×
286
                                events(first: ' . (int) $count . ') {
×
287
                                        totalCount
288
                                        edges {
289
                                                node {
290
                                                        dateTime
291
                                                        eventUrl
292
                                                        id
293
                                                        title
294
                                                }
295
                                        }
296
                                }
297
                        }
298
                }';
×
299

300
                // Make POST request with the GraphQL query.
301
                $request = wp_remote_post(
×
302
                        $request_uri,
×
303
                        [
×
304
                                'headers' => [
×
305
                                        'Content-Type' => 'application/json',
×
306
                                ],
×
307
                                'body'    => wp_json_encode(
×
308
                                        [
×
309
                                                'query' => $query,
×
310
                                        ]
×
311
                                ),
×
312
                        ]
×
313
                );
×
314

315
                if ( is_wp_error( $request ) || 200 !== (int) wp_remote_retrieve_response_code( $request ) ) {
×
316
                        return;
×
317
                }
318

319
                $response_body = json_decode( wp_remote_retrieve_body( $request ) );
×
320

321
                // Return early if we don't have the expected data.
322
                if ( empty( $response_body ) || ! isset( $response_body->data->groupByUrlname->events->edges ) ) {
×
323
                        return;
×
324
                }
325

326
                // Transform the GraphQL response to match the format expected from old rest response.
327
                $output = [];
×
328
                foreach ( $response_body->data->groupByUrlname->events->edges as $edge ) {
×
329
                        $event = $edge->node;
×
330

331
                        // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- GraphQL response uses camelCase.
332
                        $event_data       = new stdClass();
×
333
                        $event_data->name = $event->title;
×
334
                        $event_data->time = strtotime( $event->dateTime ) * 1000; // Convert to milliseconds to match old format.
×
335
                        $event_data->link = $event->eventUrl;
×
336
                        $event_data->id   = $event->id;
×
337
                        // phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase.
338

339
                        $output[] = $event_data;
×
340
                }
341

342
                if ( empty( $output ) ) {
×
343
                        return;
×
344
                }
345

346
                set_transient( $key, $output, DAY_IN_SECONDS );
×
347
        }
348

349
        return $output;
×
350
}
351

352
/**
353
 * Upcoming meetups in html
354
 *
355
 * @param  string  $meetup meetup name.
356
 * @param  integer $count number of meetups to return.
357
 * @param  string  $heading heading level.
358
 * @return json
359
 */
360
function edac_get_upcoming_meetups_html( $meetup, $count = 5, $heading = '3' ) {
361

362
        $json = edac_get_upcoming_meetups_json( $meetup, $count );
×
363

364
        if ( empty( $json ) ) {
×
365
                return;
×
366
        }
367

368
        $html = '<ul class="edac-upcoming-meetup-list">';
×
369

370
        foreach ( $json as $event ) {
×
371
                $link_text = esc_html__( 'Attend Free', 'accessibility-checker' );
×
372

373
                $html .= '
×
374
                <li class="edac-upcoming-meetup-item edac-mb-3">
375
                        <h' . esc_html( $heading ) . ' class="edac-upcoming-meetup-item-name">' . esc_html( $event->name ) . '</h' . esc_html( $heading ) . '>
×
376
                        <div class="edac-upcoming-meetup-item-time edac-timestamp-to-local">' . ( (int) $event->time / 1000 ) . '</div>
×
377
                        <a aria-label="' . esc_attr( $link_text . ': ' . $event->name ) . '" class="edac-upcoming-meetup-item-link" href="' . esc_url( $event->link ) . '">' . $link_text . '</a>
×
378
                </li>';
×
379
        }
380

381
        $html .= '</ul>';
×
382

383
        return $html;
×
384
}
385

386
/**
387
 * Calculate the issue density
388
 *
389
 * @param  int $issue_count number of issues.
390
 * @param  int $element_count number of elements.
391
 * @param  int $content_length length of content.
392
 * @return int
393
 */
394
function edac_get_issue_density( $issue_count, $element_count, $content_length ) {
395

396
        if ( $element_count < 1 || $content_length < 1 ) {
×
397
                return 0;
×
398
        }
399

400
        $element_weight = .8;
×
401
        $content_weight = .2;
×
402

403
        $error_elements_percentage = $issue_count / $element_count;
×
404
        $error_content_percentage  = $issue_count / $content_length;
×
405

406
        $score = (
×
407
                ( $error_elements_percentage * $element_weight ) +
×
408
                ( $error_content_percentage * $content_weight )
×
409
        );
×
410

411
        return round( $score * 100, 2 );
×
412
}
413

414
/**
415
 * Get simplified summary
416
 *
417
 * @param integer $post Post ID.
418
 * @return void
419
 */
420
function edac_get_simplified_summary( $post = null ) {
421
        if ( null === $post ) {
×
422
                $post = get_the_ID();
×
423
        }
424

425
        if ( null === $post ) {
×
426
                return;
×
427
        }
428

429
        echo wp_kses_post(
×
430
                ( new \EDAC\Inc\Simplified_Summary() )->simplified_summary_markup( $post )
×
431
        );
×
432
}
433

434
/**
435
 * Get Post Count by available custom post types
436
 *
437
 * @return mixed
438
 */
439
function edac_get_posts_count() {
440

441
        $output = [];
×
442

443
        $post_types = get_option( 'edac_post_types' );
×
444
        if ( $post_types ) {
×
445
                foreach ( $post_types as $post_type ) {
×
446

447
                        $counts = wp_count_posts( $post_type );
×
448

449
                        if ( $counts ) {
×
450
                                foreach ( $counts as $key => $value ) {
×
451
                                        // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual
452
                                        if ( 0 == $value ) {
×
453
                                                unset( $counts->{$key} );
×
454
                                        }
455
                                }
456
                        }
457

458
                        if ( $counts ) {
×
459
                                $array = [];
×
460
                                foreach ( $counts as $key => $value ) {
×
461
                                        $array[] = $key . ' = ' . $value;
×
462
                                }
463
                                if ( $array ) {
×
464
                                        $output[] = $post_type . ': ' . implode( ', ', $array );
×
465
                                }
466
                        }
467
                }
468
        }
469

470
        if ( $output ) {
×
471
                return implode( ', ', $output );
×
472
        }
473
        return false;
×
474
}
475

476
/**
477
 * Get Raw Global Error Count
478
 *
479
 * @return array
480
 */
481
function edac_get_error_count() {
482
        global $wpdb;
×
483

484
        // Define a unique cache key for our data.
485
        $cache_key     = 'edac_errors_' . get_current_blog_id();
×
486
        $stored_errors = wp_cache_get( $cache_key );
×
487

488
        // Check if the result exists in the cache.
489
        if ( false === $stored_errors ) {
×
490
                // If not, perform the database query.
491
                $table_name = $wpdb->prefix . 'accessibility_checker';
×
492

493
                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
494
                $stored_errors = (int) $wpdb->get_var( $wpdb->prepare( 'SELECT count(*) FROM %i WHERE siteid = %d AND ruletype = %s', $table_name, get_current_blog_id(), 'error' ) );
×
495

496
                // Save the result in the cache for future use.
497
                wp_cache_set( $cache_key, $stored_errors );
×
498
        }
499

500
        return $stored_errors;
×
501
}
502

503
/**
504
 * Get Raw Global Warning Count
505
 *
506
 * @return array Array of.
507
 */
508
function edac_get_warning_count() {
509
        global $wpdb;
×
510

511
        // Define a unique cache key for our data.
512
        $cache_key       = 'edac_warnings_' . get_current_blog_id();
×
513
        $stored_warnings = wp_cache_get( $cache_key );
×
514

515
        // Check if the result exists in the cache.
516
        if ( false === $stored_warnings ) {
×
517
                // If not, perform the database query.
518
                $table_name = $wpdb->prefix . 'accessibility_checker';
×
519

520
                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
521
                $stored_warnings = (int) $wpdb->get_var( $wpdb->prepare( 'SELECT count(*) FROM %i WHERE siteid = %d AND ruletype = %s', $table_name, get_current_blog_id(), 'warning' ) );
×
522

523
                // Save the result in the cache for future use.
524
                wp_cache_set( $cache_key, $stored_warnings );
×
525
        }
526

527
        return $stored_warnings;
×
528
}
529

530
/**
531
 * Get Database Table Count
532
 *
533
 * @param string $table Database table.
534
 * @return int
535
 */
536
function edac_database_table_count( $table ) {
537
        global $wpdb;
×
538

539
        // Create a unique cache key based on the table's name.
540
        $cache_key = 'edac_table_count_' . $table;
×
541

542
        // Try to get the count from the cache first.
543
        $count = wp_cache_get( $cache_key );
×
544

545
        if ( false === $count ) {
×
546
                // If the count is not in the cache, perform the database query.
547
                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
548
                $count = $wpdb->get_var( $wpdb->prepare( 'SELECT count(*) FROM %i', $wpdb->prefix . $table ) );
×
549

550
                // Save the count to the cache for future use.
551
                wp_cache_set( $cache_key, $count );
×
552
        }
553

554
        return $count;
×
555
}
556

557
/**
558
 * Generate a summary statistic list item.
559
 *
560
 * @since 1.14.0
561
 *
562
 * @param string $item_class     The base CSS class for the list item.
563
 * @param int    $count     The count of items to display.
564
 * @param string $label      The translated label with count included.
565
 *
566
 * @return string The generated HTML list item.
567
 */
568
function edac_generate_summary_stat( string $item_class, int $count, string $label ): string {
569
        $has_error_class = ( $count > 0 ) ? ' has-errors' : '';
×
570

571
        return '
×
572
        <li class="edac-summary-stat ' . $item_class . $has_error_class . '" aria-label="' . $label . '">
×
573
            <div class="edac-panel-number">
574
                ' . $count . '
×
575
            </div>
576
            <div class="edac-panel-number-label">' . $label . '</div>
×
577
        </li>';
×
578
}
579

580
/**
581
 * Generate links to pro page with some params.
582
 *
583
 * @param array  $query_args A list of key value pairs to add as query vars to the link.
584
 * @param string $type The type of link to generate. Default is 'pro'.
585
 * @param array  $args Additional arguments to pass on the link.
586
 * @return string
587
 */
588
function edac_generate_link_type( $query_args = [], $type = 'pro', $args = [] ): string {
589

590
        $date_now        = new DateTime( gmdate( 'Y-m-d H:i:s' ) );
6✔
591
        $activation_date = new DateTime( get_option( 'edac_activation_date', gmdate( 'Y-m-d H:i:s' ) ) );
6✔
592
        $interval        = $date_now->diff( $activation_date );
6✔
593
        $days_active     = $interval->days;
6✔
594
        $query_defaults  = [
6✔
595
                'utm_source'       => 'accessibility-checker',
6✔
596
                'utm_medium'       => 'software',
6✔
597
                'utm_campaign'     => 'wordpress-general',
6✔
598
                'php_version'      => PHP_VERSION,
6✔
599
                'platform'         => 'wordpress',
6✔
600
                'platform_version' => $GLOBALS['wp_version'],
6✔
601
                'software'         => defined( 'EDACP_KEY_VALID' ) && EDACP_KEY_VALID ? 'pro' : 'free',
6✔
602
                'software_version' => defined( 'EDACP_VERSION' ) ? EDACP_VERSION : EDAC_VERSION,
6✔
603
                'days_active'      => $days_active,
6✔
604
        ];
6✔
605

606
        $query_args = array_merge( $query_defaults, $query_args );
6✔
607

608
        switch ( $type ) {
609
                case 'help':
6✔
610
                        $base_link = trailingslashit( 'https://a11ychecker.com/help' . $args['help_id'] ?? '' );
×
611
                        break;
×
612
                case 'custom': // phpcs:ignore -- intentially only breaking inside the condition because if it's not set we want to hit default.
6✔
613
                        if ( $args['base_link'] ) {
×
614
                                $base_link = $args['base_link'];
×
615
                                break;
×
616
                        }
617
                case 'pro':
6✔
618
                default:
619
                        $base_link = 'https://equalizedigital.com/accessibility-checker/pricing/';
6✔
620
                        break;
6✔
621
        }
622
        return add_query_arg( $query_args, $base_link );
6✔
623
}
624

625
/**
626
 * Check if WooCommerce is enabled.
627
 *
628
 * This just checks for existence of the main WooCommerce function and class.
629
 *
630
 * @return bool
631
 */
632
function edac_is_woocommerce_enabled() {
633
        return function_exists( 'WC' ) && class_exists( 'WooCommerce' );
×
634
}
635

636
/**
637
 * Check if a given post id is the WooCommerce checkout page.
638
 *
639
 * @param int $post_id The post ID to check.
640
 * @return bool
641
 */
642
function edac_check_if_post_id_is_woocommerce_checkout_page( $post_id ) {
643
        if ( ! edac_is_woocommerce_enabled() ) {
×
644
                return false;
×
645
        }
646

647
        return wc_get_page_id( 'checkout' ) === $post_id;
×
648
}
649

650
/**
651
 * Create a DOMDocument from HTML string
652
 * 
653
 * @since 1.23.0
654
 * @param string  $html The HTML content to parse.
655
 * @param boolean $wrap Whether to wrap the result in a compatibility wrapper.
656
 * @return \DOMDocument|\EDAC\Inc\DOM_Wrapper|false Returns DOMDocument or wrapper on success, false on failure
657
 */
658
function edac_get_dom_from_html( $html, $wrap = false ) {
NEW
659
        libxml_use_internal_errors( true );
×
NEW
660
        $dom     = new \DOMDocument();
×
NEW
661
        $success = $dom->loadHTML(
×
NEW
662
                htmlspecialchars_decode( $html, ENT_QUOTES ),
×
NEW
663
                LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
×
NEW
664
        );
×
NEW
665
        libxml_clear_errors();
×
666

NEW
667
        if ( ! $success ) {
×
NEW
668
                return false;
×
669
        }
670
        
NEW
671
        if ( $wrap ) {
×
NEW
672
                return new \EDAC\Inc\DOM_Wrapper( $dom );
×
673
        }
NEW
674
        return $dom;
×
675
}
676

677
/**
678
 * Parse HTML content to extract image or SVG elements
679
 * 
680
 * @since 1.23.0
681
 * @param string $html The HTML content to parse.
682
 * @return array Array containing 'img' (string) and 'svg' (string) keys
683
 */
684
function edac_parse_html_for_media( $html ) {
NEW
685
        $result = [
×
NEW
686
                'img' => null,
×
NEW
687
                'svg' => null,
×
NEW
688
        ];
×
689

NEW
690
        $dom = edac_get_dom_from_html( $html );
×
NEW
691
        if ( ! $dom ) {
×
NEW
692
                return $result;
×
693
        }
694
        
NEW
695
        $xpath = new \DOMXPath( $dom );
×
696
        
697
        // Check for img elements first.
NEW
698
        $img_elements = $xpath->query( '//img' );
×
NEW
699
        if ( $img_elements->length > 0 ) {
×
NEW
700
                foreach ( $img_elements as $element ) {
×
NEW
701
                        $src = $element->getAttribute( 'src' );
×
NEW
702
                        if ( $src ) {
×
NEW
703
                                $result['img'] = $src;
×
NEW
704
                                break;
×
705
                        }
706
                }
707
        } else {
708
                // If no images found, check for SVG.
NEW
709
                $svg_elements = $xpath->query( '//svg' );
×
NEW
710
                if ( $svg_elements->length > 0 ) {
×
NEW
711
                        $result['svg'] = $dom->saveHTML( $svg_elements->item( 0 ) );
×
712
                }
713
        }
714
        
NEW
715
        return $result;
×
716
}
717

718
/**
719
 * Remove corrected posts
720
 *
721
 * @param int    $post_ID The ID of the post.
722
 * @param string $type    The type of the post.
723
 * @param int    $pre     The flag indicating the removal stage (1 for before validation php based rules, 2 for after validation).
724
 * @param string $ruleset    The type of the ruleset to correct (php or js). For backwards compatibility, defaults to 'php'.
725
 *
726
 * @return void
727
 */
728
function edac_remove_corrected_posts( $post_ID, $type, $pre = 1, $ruleset = 'php' ) {  // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed, VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- $ruleset is for backwards compatibility.
NEW
729
        global $wpdb;
×
730

NEW
731
        $rules = edac_register_rules();
×
732

NEW
733
        if ( 0 === count( $rules ) ) {
×
NEW
734
                return;
×
735
        }
736

NEW
737
        $sql = 1 === $pre
×
NEW
738
                ? "UPDATE {$wpdb->prefix}accessibility_checker SET recordcheck = %d WHERE siteid = %d AND postid = %d AND type = %s"
×
NEW
739
                : "DELETE FROM {$wpdb->prefix}accessibility_checker WHERE recordcheck = %d AND siteid = %d AND postid = %d AND type = %s";
×
740

741
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Using direct query for adding data to database, caching not required for one time operation.
NEW
742
        $wpdb->query(
×
NEW
743
                $wpdb->prepare(
×
NEW
744
                        $sql, // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared
×
NEW
745
                        0,
×
NEW
746
                        get_current_blog_id(),
×
NEW
747
                        $post_ID,
×
NEW
748
                        $type
×
NEW
749
                )
×
NEW
750
        );
×
751
}
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