Plugin Directory

source: wp-accessibility/trunk/wp-accessibility.php

Last change on this file was 3491383, checked in by joedolson, 2 days ago

Remove 2.3.1, add 2.3.3, change stable.

https://github.com/joedolson/wp-accessibility/releases/tag/v2.3.3

File size: 36.0 KB
Line 
 . __( 'Accessibility Settings', 'wp-accessibility' ) . '</a>';
159        }
160
161        return $links;
162}
163
164add_action( 'wp_enqueue_scripts', 'wpa_stylesheet' );
165/**
166 * Enqueue stylesheets for WP Accessibility.
167 */
168function wpa_stylesheet() {
169        $version = ( SCRIPT_DEBUG ) ? wp_rand( 10000, 100000 ) : wpa_check_version();
170        wp_register_style( 'wpa-style', plugins_url( 'css/wpa-style.css', __FILE__ ), array(), $version );
171        $ld = get_option( 'wpa_longdesc' );
172        if ( 'link' === $ld || 'jquery' === $ld || 'button' === $ld || 'on' === get_option( 'asl_enable' ) || ! empty( get_option( 'wpa_post_types', array() ) ) ) {
173                wp_enqueue_style( 'wpa-style' );
174                // these styles are derived from the WordPress skip link defaults.
175                $top = '7px';
176                if ( is_admin_bar_showing() ) {
177                        $top = '37px';
178                }
179                $add_css    = ( ! wpa_accessible_theme() ) ? wpa_css() : '';
180                $custom_css = ':root { --admin-bar-top : ' . $top . '; }';
181                wp_add_inline_style( 'wpa-style', wp_filter_nohtml_kses( wp_unslash( $add_css . $custom_css ) ) );
182        }
183        if ( current_user_can( 'edit_files' ) && 'on' === get_option( 'wpa_diagnostics' ) ) {
184                wp_register_style( 'diagnostic', plugins_url( 'css/diagnostic.css', __FILE__ ) );
185                wp_register_style( 'diagnostic-head', plugins_url( 'css/diagnostic-head.css', __FILE__ ) );
186                wp_enqueue_style( 'diagnostic' );
187                wp_enqueue_style( 'diagnostic-head' );
188        }
189}
190
191add_action( 'admin_head', 'wpa_admin_stylesheet' );
192/**
193 * Enqueue admin stylesheets if enabled
194 */
195function wpa_admin_stylesheet() {
196        // Used to provide an admin CSS from plug-in, now only enqueue if custom provided in theme.
197        if ( file_exists( get_stylesheet_directory() . '/wp-admin.css' ) ) {
198                $file = get_stylesheet_directory_uri() . '/wp-admin.css';
199                wp_register_style( 'wp-a11y-css', $file );
200                wp_enqueue_style( 'wp-a11y-css' );
201        }
202}
203
204/**
205 * Generate skiplink CSS.
206 *
207 * @param bool $defaults 'true' to return defaults regardless of settings.
208 *
209 * @return string
210 */
211function wpa_skiplink_css( $defaults = false ) {
212        $use_defaults = get_option( 'asl_default_styles', '' );
213        $styles       = '';
214        $focus        = '';
215        $passive      = '';
216        $visibility   = ( 'on' === get_option( 'asl_visible' ) ) ? 'wpa-visible' : 'wpa-hide';
217        $is_rtl       = ( is_rtl() ) ? '-rtl' : '-ltr';
218        $off_vis      = ( 'on' === get_option( 'asl_visible' ) ) ? 'wpa-hide' : 'wpa-visible';
219        $off_rtl      = ( is_rtl() ) ? '-ltr' : '-rtl';
220        // If not using default styles.
221        if ( 'true' !== $use_defaults && ! $defaults ) {
222                $default_focus   = '';
223                $default_passive = '';
224                if ( '' !== get_option( 'asl_styles' ) ) {
225                        $styles = wp_filter_nohtml_kses( get_option( 'asl_styles' ) );
226                        // Ensure custom styles match settings.
227                        $styles = str_replace( array( $off_vis, $off_rtl ), array( $visibility, $is_rtl ), $styles );
228                        // If custom styles contain #skiplinks, we can just return this; it's probably a fully realized selector.
229                        if ( false !== stripos( $styles, '#skiplinks' ) ) {
230                                return $styles;
231                        }
232                } else {
233                        $focus   = wp_filter_nohtml_kses( get_option( 'asl_styles_focus' ) );
234                        $passive = wp_filter_nohtml_kses( get_option( 'asl_styles_passive' ) );
235                }
236        } else {
237                // these styles are derived from the WordPress skip link defaults.
238                $default_focus = 'background-color: #f1f1f1;
239        box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6);
240        color: #0073aa;
241        display: block;
242        font-weight: 600;
243        height: auto;
244        line-height: normal;
245        padding: 15px 23px 14px;
246        position: absolute;
247        left: 6px;
248        top: var(--admin-bar-top);
249        text-decoration: none;
250        text-transform: none;
251        width: auto;
252        z-index: 100000;';
253
254                // Passive default styles derived from WordPress default focus styles.
255                $default_passive = 'background-color: #fff;
256        box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.2);
257        color: #333;
258        display: block;
259        font-weight: 600;
260        height: auto;
261        line-height: normal;
262        padding: 15px 23px 14px;
263        position: absolute;
264        left: 6px;
265        top: var(--admin-bar-top);
266        text-decoration: none;
267        text-transform: none;
268        width: auto;
269        z-index: 100000;';
270        }
271        if ( is_admin() && '' !== $styles ) {
272                return $styles;
273        }
274
275        if ( ! $focus ) {
276                $focus = $default_focus;
277        } else {
278                $focus = $default_focus . $focus;
279        }
280
281        $vis   = '';
282        $invis = '';
283        $class = '.' . $visibility . $is_rtl;
284        // If links are visible, "hover" is a focus style, otherwise, it's a passive style.
285        if ( 'on' === get_option( 'asl_visible' ) ) {
286                $vis     = $class . '#skiplinks a:hover,';
287                $passive = $default_passive . $passive;
288        } else {
289                $invis   = $class . '#skiplinks a:hover,';
290                $passive = '';
291        }
292        $styles .= "
293$class#skiplinks a, $invis $class#skiplinks a:visited {
294        $passive
295}
296$class#skiplinks a:active, $vis $class#skiplinks a:focus {
297        $focus
298}
299        ";
300        /**
301         * Filter CSS styles output on front-end for skip links.
302         *
303         * @hook wpa_skiplink_styles
304         *
305         * @param {string} $styles Styles configured by settings.
306         *
307         * @return {string}
308         */
309        $styles = apply_filters( 'wpa_skiplink_styles', $styles );
310
311        return $styles;
312}
313
314/**
315 * Generate styles needed for WP Accessibility options.
316 */
317function wpa_css() {
318        $styles = '';
319        if ( get_option( 'asl_enable' ) === 'on' ) {
320                $styles .= wpa_skiplink_css();
321        }
322        if ( 'on' === get_option( 'wpa_focus' ) ) {
323                $color   = ( false !== (bool) get_option( 'wpa_focus_color' ) ) ? ' #' . get_option( 'wpa_focus_color' ) : '#233c7f';
324                $styles .= "
325                :focus { outline: 2px solid$color!important; outline-offset: 2px !important; }
326                ";
327        }
328
329        return $styles;
330}
331
332/**
333 * Test whether a URL is validly structured.
334 *
335 * @param string $url A purported URL.
336 *
337 * @return mixed URL if valid, false if not.
338 */
339function wpa_is_url( $url ) {
340        return preg_match( '|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $url );
341}
342
343add_action( 'wp_enqueue_scripts', 'wpa_enqueue_js', 100 );
344/**
345 * Enqueue JS needed for WP Accessibility options.
346 */
347function wpa_enqueue_js() {
348        $version    = ( SCRIPT_DEBUG ) ? wp_rand( 10000, 100000 ) : wpa_check_version();
349        $visibility = ( 'on' === get_option( 'asl_visible' ) ) ? 'wpa-visible' : 'wpa-hide';
350        $output     = '';
351        if ( 'on' === get_option( 'asl_enable' ) && ! wpa_accessible_theme() ) {
352                $html = '';
353                /**
354                 * Customize the default value for extra skiplink. Turns on extra skiplink options in WP Accessibility versions > 1.9.0.
355                 *
356                 * @hook asl_extra_target
357                 * @param {string} Value to use as a default for the extra skiplink.
358                 *
359                 * @return {string}
360                 */
361                $default_extra = apply_filters( 'asl_extra_target', '' );
362                $extra         = get_option( 'asl_extra_target', $default_extra );
363                $extra         = ( wpa_is_url( $extra ) ) ? esc_url( $extra ) : str_replace( '#', '', esc_attr( $extra ) );
364                if ( '' !== $extra && ! wpa_is_url( $extra ) ) {
365                        $extra = "#$extra";
366                }
367                $extra_text = (string) stripslashes( get_option( 'asl_extra_text' ) );
368                $content    = str_replace( '#', '', esc_attr( get_option( 'asl_content' ) ) );
369                $nav        = str_replace( '#', '', esc_attr( get_option( 'asl_navigation' ) ) );
370                /**
371                 * Customize the default value for sitemap skiplink. Turns on sitemap skiplink options in WP Accessibility versions > 1.9.0.
372                 *
373                 * @hook asl_sitemap
374                 * @param {string} Value to use as a default for the sitemap.
375                 *
376                 * @return {string}
377                 */
378                $default_sitemap = apply_filters( 'asl_sitemap', '' );
379                $sitemap         = esc_url( get_option( 'asl_sitemap', $default_sitemap ) );
380                $html           .= ( '' !== $content ) ? "<a href=\"#$content\" class='no-scroll et_smooth_scroll_disabled'>" . __( 'Skip to Content', 'wp-accessibility' ) . '</a> ' : '';
381                $html           .= ( '' !== $nav ) ? "<a href=\"#$nav\" class='no-scroll et_smooth_scroll_disabled'>" . __( 'Skip to navigation', 'wp-accessibility' ) . '</a> ' : '';
382                $html           .= ( '' !== $sitemap ) ? "<a href=\"$sitemap\" class='no-scroll et_smooth_scroll_disabled'>" . __( 'Site map', 'wp-accessibility' ) . '</a> ' : '';
383                $html           .= ( '' !== $extra && '' !== $extra_text ) ? "<a href=\"$extra\" class='no-scroll et_smooth_scroll_disabled'>$extra_text</a> " : '';
384                $is_rtl          = ( is_rtl() ) ? '-rtl' : '-ltr';
385                $skiplinks       = __( 'Skip links', 'wp-accessibility' );
386                $output          = ( '' !== $html ) ? "<div class=\"$visibility$is_rtl\" id=\"skiplinks\" role=\"navigation\" aria-label=\"" . esc_attr( $skiplinks ) . "\">$html</div>" : '';
387        }
388
389        $labels = array(
390                's'       => _x( 'Search', 'Search field label', 'wp-accessibility' ),
391                'author'  => _x( 'Name', 'Commenter name label', 'wp-accessibility' ),
392                'email'   => _x( 'Email', 'Commenter email label', 'wp-accessibility' ),
393                'url'     => _x( 'Website', 'Commenter website label', 'wp-accessibility' ),
394                'comment' => _x( 'Comment', 'Commenter message label', 'wp-accessibility' ),
395        );
396        /**
397         * Customize labels passed to automatically label core WordPress fields.
398         *
399         * @hook wpa_labels
400         * @param {array} $labels Array of labels for search and comment fields.
401         *
402         * @return {array}
403         */
404        $labels = apply_filters( 'wpa_labels', $labels );
405        $dir    = '';
406        $lang   = '';
407        if ( 'off' !== get_option( 'wpa_lang_attributes' ) && ! wpa_accessible_theme() ) {
408                $dir  = ( is_rtl() ) ? 'rtl' : 'ltr';
409                $lang = get_bloginfo( 'language' );
410        }
411
412        if ( SCRIPT_DEBUG ) {
413                $wpajs = plugins_url( 'js/wp-accessibility.js', __FILE__ );
414        } else {
415                $wpajs = plugins_url( 'js/wp-accessibility.min.js', __FILE__ );
416        }
417        wp_enqueue_script(
418                'wp-accessibility',
419                $wpajs,
420                array(),
421                $version,
422                array(
423                        'in_footer' => true,
424                        'strategy'  => 'defer',
425                )
426        );
427
428        $longdesc_type = false;
429        if ( 'link' === get_option( 'wpa_longdesc' ) ) {
430                $longdesc_type = 'link';
431        } elseif ( 'jquery' === get_option( 'wpa_longdesc' ) || 'button' === get_option( 'wpa_longdesc' ) ) {
432                $longdesc_type = 'button';
433        }
434        /**
435         * Modify the selector used to attach the alt attribute toggle button on images. Default `.hentry img[alt!=""], .comment-content img[alt!=""]`.
436         *
437         * @hook wpa_show_alt_selector
438         *
439         * @since 2.0.0
440         *
441         * @param {string} $selector Valid CSS selector string.
442         *
443         * @return {string}
444         */
445        $selector = apply_filters( 'wpa_show_alt_selector', '.hentry img[alt]:not([alt=""]), .comment-content img[alt]:not([alt=""]), #content img[alt]:not([alt=""]),.entry-content img[alt]:not([alt=""])' );
446        $alttext  = ( 'on' === get_option( 'wpa_show_alt' ) ) ? true : false;
447
448        /**
449         * Filter target element selector for underlines. Default `a`.
450         *
451         * @hook wpa_underline_target
452         *
453         * @param {string} $el Target element selector.
454         *
455         * @return string
456         */
457        $target = apply_filters( 'wpa_underline_target', 'a' );
458        /**
459         * Filter whether console log messages about remediation actions will be sent.
460         *
461         * @hook wpa_view_remediation_logs
462         *
463         * @param {bool} $visible Default `true` if user is logged in and has capabilities to manage options.
464         *
465         * @return {bool}
466         */
467        $errors_enabled = apply_filters( 'wpa_view_remediation_logs', current_user_can( 'manage_options' ) );
468        $track          = ( '' === get_option( 'wpa_track_stats', '' ) ) ? current_user_can( 'manage_options' ) : true;
469        $track          = ( 'off' === get_option( 'wpa_track_stats' ) ) ? false : $track;
470        /**
471         * Filter whether data from views will be tracked.
472         *
473         * @hook wpa_track_view_statistics
474         *
475         * @param {bool} $visible Default `true` if user is logged in and has capabilities to manage options or if enabled in settings.
476         *
477         * @return {bool}
478         */
479        $tracking_enabled = apply_filters( 'wpa_track_view_statistics', $track );
480        $apply_labels     = ( 'off' === get_option( 'wpa_labels' ) ) ? false : true;
481        /**
482         * Filter whether automatic labeling is enabled.
483         *
484         * @hook wpa_disable_labels
485         *
486         * @param {bool} $enabled True if labels are automatically added.
487         *
488         * @return {bool}
489         */
490        $apply_labels  = apply_filters( 'wpa_disable_labels', $apply_labels );
491        $remove_titles = ( 'off' === get_option( 'wpa_remove_titles' ) ) ? false : true;
492        /**
493         * Filter whether title attributes are removed. Used to be image titles only, now applies buttons and links, as well.
494         *
495         * @hook wpa_remove_titles
496         *
497         * @param {bool} $enabled True if title attributes are removed.
498         *
499         * @return {bool}
500         */
501        $remove_titles = apply_filters( 'wpa_remove_titles', $remove_titles );
502        $set_viewport  = ( 'off' === get_option( 'wpa_viewport' ) ) ? false : true;
503        /**
504         * Filter whether WP Accessibility manipulates the viewport.
505         *
506         * @hook wpa_viewport
507         *
508         * @param {bool} $enabled True viewport can be modified.
509         *
510         * @return {bool}
511         */
512        $viewport = apply_filters( 'wpa_viewport', $set_viewport );
513        wp_localize_script(
514                'wp-accessibility',
515                'wpa',
516                array(
517                        'skiplinks'   => array(
518                                'enabled' => ( 'on' === get_option( 'asl_enable' ) ) ? true : false,
519                                'output'  => $output,
520                        ),
521                        'target'      => ( 'on' === get_option( 'wpa_target' ) ) ? true : false,
522                        'tabindex'    => ( 'on' === get_option( 'wpa_tabindex' ) ) ? true : false,
523                        'underline'   => array(
524                                'enabled' => ( 'on' === get_option( 'wpa_underline' ) ) ? true : false,
525                                'target'  => $target,
526                        ),
527                        'videos'      => ( 'on' === get_option( 'wpa_videos' ) ) ? true : false,
528                        'dir'         => $dir,
529                        'viewport'    => $viewport,
530                        'lang'        => $lang,
531                        'titles'      => $remove_titles,
532                        'labels'      => $apply_labels,
533                        'wpalabels'   => $labels,
534                        'alt'         => $alttext,
535                        'altSelector' => $selector,
536                        'current'     => ( version_compare( $GLOBALS['wp_version'], '5.3', '<' ) ) ? true : false,
537                        'errors'      => ( $errors_enabled ) ? true : false,
538                        'tracking'    => ( $tracking_enabled ) ? true : false,
539                        'ajaxurl'     => admin_url( 'admin-ajax.php' ),
540                        'security'    => wp_create_nonce( 'wpa-stats-action' ),
541                        'action'      => 'wpa_stats_action',
542                        'url'         => ( function_exists( 'wpa_get_current_url' ) ) ? wpa_get_current_url() : 'disabled',
543                        'post_id'     => ( is_singular() ) ? get_the_ID() : '',
544                        'continue'    => ( wp_is_block_theme() ) ? true : false,
545                        'pause'       => __( 'Pause video', 'wp-accessibility' ),
546                        'play'        => __( 'Play video', 'wp-accessibility' ),
547                        'restUrl'     => get_rest_url( null, 'wp/v2/media' ),
548                        'ldType'      => $longdesc_type,
549                        'ldHome'      => home_url(),
550                        'ldText'      => '<span class="dashicons dashicons-media-text" aria-hidden="true"></span><span class="screen-reader">' . __( 'Long Description', 'wp-accessibility' ) . '</span>',
551                )
552        );
553}
554
555// courtesy of Graham Armfield (modified).
556add_action( 'admin_bar_menu', 'wpa_logout_item', 11 );
557/**
558 * Add adminbar menu logout.
559 *
560 * @link http://www.coolfields.co.uk/2013/02/wordpress-permanently-visible-log-out-link-plugin-version-0-1/
561 * @param object $admin_bar Admin bar object.
562 */
563function wpa_logout_item( $admin_bar ) {
564        if ( ! is_user_logged_in() || 'on' === get_option( 'wpa_disable_logout', 'true' ) ) {
565                return;
566        }
567
568        $args = array(
569                'id'    => 'wpa-logout',
570                'title' => __( 'Log Out', 'wp-accessibility' ),
571                'href'  => wp_logout_url(),
572        );
573        $admin_bar->add_node( $args );
574}
575
576add_filter( 'posts_clauses', 'wpa_search_attachment_alt', 20, 2 );
577/**
578 * Allow users to search alt attributes in the media library.
579 *
580 * @param array  $clauses WordPress post query clauses.
581 * @param object $query WordPress query object.
582 *
583 * @return array
584 */
585function wpa_search_attachment_alt( $clauses, $query ) {
586        if ( is_admin() && 'on' === get_option( 'wpa_search_alt' ) ) {
587                global $wpdb;
588                if ( isset( $query->query['post_type'] ) && 'attachment' === $query->query['post_type'] && '' !== $query->query_vars['s'] ) {
589                        $clauses['join'] = " LEFT JOIN {$wpdb->postmeta} AS sq1 ON ( {$wpdb->posts}.ID = sq1.post_id AND ( sq1.meta_key = '_wp_attached_file' OR sq1.meta_key = '_wp_attachment_image_alt' ) )";
590                }
591        }
592
593        return $clauses;
594}
595
596add_filter( 'mce_css', 'wpa_diagnostic_css' );
597/**
598 * Add diagnostic CSS.
599 *
600 * @param string $mce_css Existing CSS.
601 *
602 * @return full string css.
603 */
604function wpa_diagnostic_css( $mce_css ) {
605        if ( get_option( 'wpa_diagnostics' ) === 'on' ) {
606                $mce_css .= ', ' . plugins_url( 'css/diagnostic.css', __FILE__ );
607        }
608
609        return $mce_css;
610}
611
612if ( 'on' === get_option( 'wpa_search' ) ) {
613        add_filter( 'pre_get_posts', 'wpa_filter' );
614}
615
616/**
617 * Filter search queries to ensure that an error page is returned if no results.
618 *
619 * @param object $query Main WP_Query object.
620 *
621 * @return $query.
622 */
623function wpa_filter( $query ) {
624        if ( ! is_admin() ) {
625                if ( isset( $_GET['s'] ) && '' === trim( $_GET['s'] ) && ( $query->is_main_query() ) ) {
626                        $query->query_vars['s'] = '&#32;';
627                        $query->set( 'is_search', 1 );
628                        add_action( 'template_include', 'wpa_search_error' );
629                        add_filter(
630                                'get_search_query',
631                                function ( $search_query ) {
632                                        if ( '&#32;' === $search_query ) {
633                                                return '';
634                                        }
635                                        return $search_query;
636                                }
637                        );
638                }
639        }
640
641        return $query;
642}
643
644/**
645 * Locate template for the search error page.
646 *
647 * @param string $template Current template name.
648 *
649 * @return string New template name if changed.
650 */
651function wpa_search_error( $template ) {
652        $search = locate_template( 'search.php' );
653        if ( $search ) {
654                return $search;
655        }
656
657        return $template;
658}
659
660if ( 'on' === get_option( 'wpa_more' ) && ! wpa_accessible_theme() ) {
661        add_filter(
662                'body_class',
663                function ( $classes ) {
664                        return array_merge( $classes, array( 'wpa-excerpt' ) );
665                }
666        );
667        add_filter( 'get_the_excerpt', 'wpa_custom_excerpt_more', 100 );
668        add_filter( 'excerpt_more', 'wpa_excerpt_more', 100 );
669        add_filter( 'the_content_more_link', 'wpa_content_more', 100 );
670}
671
672/**
673 * Custom "Continue Reading" with post title context.
674 *
675 * @param int $id Post ID.
676 *
677 * @return string HTML link & text.
678 */
679function wpa_continue_reading( $id ) {
680        return '<a class="continue" href="' . esc_url( get_permalink( $id ) ) . '">' . get_option( 'wpa_continue' ) . '<span> ' . get_the_title( $id ) . '</span></a>';
681}
682
683/**
684 * Add custom continue reading text to excerpts.
685 *
686 * @return string Ellipsis + continue reading text.
687 */
688function wpa_excerpt_more() {
689        global $id;
690
691        return '&hellip; ' . wpa_continue_reading( $id );
692}
693
694/**
695 * Add custom continue reading text to content.
696 *
697 * @return continue reading text.
698 */
699function wpa_content_more() {
700        global $id;
701
702        return wpa_continue_reading( $id );
703}
704
705/**
706 * Add custom continue reading text to custom excerpts.
707 *
708 * @param string $output Existing content.
709 *
710 * @return continue reading text.
711 */
712function wpa_custom_excerpt_more( $output ) {
713        if ( has_excerpt() && ! is_attachment() ) {
714                global $id;
715                $output .= ' ' . wpa_continue_reading( $id ); // insert a blank space.
716        }
717
718        return $output;
719}
720
721/**
722 * Create support form.
723 */
724function wpa_get_support_form() {
725        global $current_user;
726        $current_user = wp_get_current_user();
727        $request      = '';
728        $version      = wpa_check_version();
729        // send fields for all plugins.
730        $wp_version = get_bloginfo( 'version' );
731        $home_url   = home_url();
732        $wp_url     = site_url();
733        $language   = get_bloginfo( 'language' );
734        $charset    = get_bloginfo( 'charset' );
735        // server.
736        $php_version = phpversion();
737
738        // theme data.
739        $theme         = wp_get_theme();
740        $theme_name    = $theme->get( 'Name' );
741        $theme_uri     = $theme->get( 'ThemeURI' );
742        $theme_parent  = $theme->get( 'Template' );
743        $theme_parent  = ( $theme_parent ) ? $theme_parent : __( 'None', 'wp-accessibility' );
744        $theme_version = $theme->get( 'Version' );
745
746        // plugin data.
747        $plugins        = get_plugins();
748        $plugins_string = '';
749        foreach ( array_keys( $plugins ) as $key ) {
750                if ( is_plugin_active( $key ) ) {
751                        $plugin          =& $plugins[ $key ];
752                        $plugin_name     = $plugin['Name'];
753                        $plugin_uri      = $plugin['PluginURI'];
754                        $plugin_version  = $plugin['Version'];
755                        $plugins_string .= "$plugin_name: $plugin_version; $plugin_uri\n";
756                }
757        }
758        $data = "
759================ Installation Data ====================
760==WP Accessibility==
761Version: $version
762
763==WordPress:==
764Version: $wp_version
765URL: $home_url
766Install: $wp_url
767Language: $language
768Charset: $charset
769Admin Email: $current_user->user_email
770
771==Extra info:==
772PHP Version: $php_version
773Server Software: $_SERVER[SERVER_SOFTWARE]
774User Agent: $_SERVER[HTTP_USER_AGENT]
775
776==Theme:==
777Name: $theme_name
778URI: $theme_uri
779Parent: $theme_parent
780Version: $theme_version
781
782==Active Plugins:==
783$plugins_string
784";
785        if ( isset( $_POST['wpa_support'] ) ) {
786                $nonce = $_REQUEST['_wpnonce'];
787                if ( ! wp_verify_nonce( $nonce, 'wpa-nonce' ) ) {
788                        wp_die( 'WP Accessibility: Security check failed' );
789                }
790                $request     = ( ! empty( $_POST['support_request'] ) ) ? sanitize_textarea_field( wp_unslash( $_POST['support_request'] ) ) : false;
791                $has_donated = ( 'on' === $_POST['has_donated'] ) ? 'Donor' : 'No donation';
792                $subject     = "WP Accessibility support request. $has_donated";
793                $message     = $request . "\n\n" . $data;
794                // Get the site domain and get rid of www. from pluggable.php.
795                $sitename = sanitize_text_field( strtolower( $_SERVER['SERVER_NAME'] ) );
796                if ( 'www.' === substr( $sitename, 0, 4 ) ) {
797                        $sitename = substr( $sitename, 4 );
798                }
799                $from_email = 'wordpress@' . $sitename;
800                $from       = "From: $current_user->display_name <$from_email>\r\nReply-to: $current_user->display_name <$current_user->user_email>\r\n";
801
802                if ( ! $request ) {
803                        echo "<div class='message error'><p>" . esc_html__( 'Please describe your problem.', 'wp-accessibility' ) . '</p></div>';
804                } else {
805                        wp_mail( 'plugins@joedolson.com', $subject, $message, $from );
806                        if ( 'Donor' === $has_donated ) {
807                                echo "<div class='message updated'><p>" . esc_html__( 'Thank you for supporting the continuing development of this plug-in! I\'ll get back to you as soon as I can.', 'wp-accessibility' ) . '</p></div>';
808                        } else {
809                                echo "<div class='message updated'><p>" . esc_html__( 'I cannot provide support, but will treat your request as a bug report, and will incorporate any permanent solutions I discover into the plug-in.', 'wp-accessibility' ) . '</p></div>';
810                        }
811                }
812        }
813        $admin_url = admin_url( 'admin.php?page=wp-accessibility' );
814
815        echo "
816        <form method='post' action='" . esc_url( $admin_url ) . "'>
817                <div><input type='hidden' name='_wpnonce' value='" . wp_create_nonce( 'wpa-nonce' ) . "' /></div>
818                <div>";
819        echo '
820                <p>
821                <code>' . __( 'From:', 'wp-accessibility' ) . " \"$current_user->display_name\" &lt;$current_user->user_email&gt;</code>
822                </p>
823                <p>
824                <input type='checkbox' name='has_donated' id='has_donated' value='on' /> <label for='has_donated'>";
825                // Translators: Donation URL.
826        echo sprintf( __( 'I <a href="%s">made a donation</a> to help support this plugin', 'wp-accessibility' ), 'https://www.joedolson.com/donate/' ) . "</label>
827                </p>
828                <p>
829                <label for='support_request'>" . __( 'Support Request:', 'wp-accessibility' ) . "</label><br /><textarea name='support_request' required id='support_request' cols='80' rows='10' class='widefat'>" . esc_textarea( stripslashes( $request ) ) . "</textarea>
830                </p>
831                <p>
832                <input type='submit' value='" . __( 'Send Support Request', 'wp-accessibility' ) . "' name='wpa_support' class='button-primary' />
833                </p>
834                <p>" . __( 'The following additional information will be sent with your support request:', 'wp-accessibility' ) . "</p>
835                <div class='wpa_support'>
836                " . wpautop( $data ) . '
837                </div>
838                </div>
839        </form>';
840}
841
842/**
843 * Tests whether the current theme is labeled accessibility-ready
844 *
845 * @return boolean True if this theme has the tag 'accessibility-ready'.
846 */
847function wpa_accessible_theme() {
848        // This is Oxygen Builder, and the active theme test is invalid.
849        if ( defined( 'CT_VERSION' ) ) {
850                return false;
851        }
852        $theme = wp_get_theme();
853        $tags  = $theme->get( 'Tags' );
854        if ( is_array( $tags ) && in_array( 'accessibility-ready', $tags, true ) ) {
855                return true;
856        }
857        return false;
858}
859
860/**
861 * Disable full screen block editor by default.
862 */
863function wpa_disable_editor_fullscreen_by_default() {
864        if ( 'on' === get_option( 'wpa_disable_fullscreen' ) ) {
865                $script = "window.onload = function() { const isFullscreenMode = wp.data.select( 'core/edit-post' ).isFeatureActive( 'fullscreenMode' ); if ( isFullscreenMode ) { wp.data.dispatch( 'core/edit-post' ).toggleFeature( 'fullscreenMode' ); } }";
866                wp_add_inline_script( 'wp-blocks', $script );
867        }
868}
869add_action( 'enqueue_block_editor_assets', 'wpa_disable_editor_fullscreen_by_default' );
870
871/**
872 * Disable file embeds by default.
873 *
874 * @param array $blockdata Array of block configuration meta data.
875 *
876 * @return array
877 */
878function wpa_disable_file_embed_by_default( $blockdata ) {
879        if ( 'core/file' === $blockdata['name'] && 'on' === get_option( 'wpa_disable_file_embed' ) ) {
880                if ( isset( $blockdata['attributes']['displayPreview'] ) ) {
881                        $blockdata['attributes']['displayPreview']['default'] = false;
882                }
883        }
884
885        return $blockdata;
886}
887add_filter( 'block_type_metadata', 'wpa_disable_file_embed_by_default' );
888
889/**
890 * Remove the H1 heading from the headings block.
891 *
892 * @param array  $args Block type arguments array.
893 * @param string $block_type Block type declaration.
894 *
895 * @return array
896 */
897function wpa_remove_h1( $args, $block_type ) {
898        // The H1 is not allowed by default.
899        $allowed = get_option( 'wpa_allow_h1', '' );
900        if ( 'on' !== $allowed ) {
901                // Only proceed if the current block is a Heading.
902                if ( 'core/heading' !== $block_type ) {
903                        return $args;
904                }
905
906                // Declare valid heading levels.
907                $args['attributes']['levelOptions']['default'] = array( 2, 3, 4, 5, 6 );
908        }
909        return $args;
910}
911add_filter( 'register_block_type_args', 'wpa_remove_h1', 10, 2 );
912
913/**
914 * Insert content summary at top of article content.
915 *
916 * @param string $content Post content.
917 *
918 * @return string
919 */
920function wpa_content_summary( $content ) {
921        if ( is_singular() && wpa_in_post_type( get_queried_object_id() ) ) {
922                $post_id = get_the_ID();
923                $summary = wpa_get_content_summary( $post_id );
924                if ( ! $summary ) {
925                        return $content;
926                }
927                $content = $summary . $content;
928        }
929
930        return $content;
931}
932add_filter( 'the_content', 'wpa_content_summary' );
933
934/**
935 * Get a simplified summary for content.
936 *
937 * @param int $post_id Post ID.
938 *
939 * @return string
940 */
941function wpa_get_content_summary( $post_id ) {
942        $summary = trim( get_post_meta( $post_id, '_wpa_content_summary', true ) );
943        if ( ! $summary ) {
944                return '';
945        }
946        /**
947         * Filter the heading text for content summaries. Default `Summary`.
948         *
949         * @hook wpa_summary_heading
950         *
951         * @param {string} $heading Heading text.
952         * @param {int}    $post_id Post ID.
953         *
954         * @return {string}
955         */
956        $heading = apply_filters( 'wpa_summary_heading', __( 'Summary', 'wp-accessibility' ), $post_id );
957        /**
958         * Filter the heading level for content summaries. Default `h2`.
959         *
960         * @hook wpa_summary_heading_level
961         *
962         * @param {string} $heading Element selector.
963         * @param {int}    $post_id Post ID.
964         *
965         * @return {string}
966         */
967        $level = apply_filters( 'wpa_summary_heading_level', 'h2', $post_id );
968
969        $heading = "<$level>" . $heading . "</$level>";
970        $content = '<section class="wpa-content-summary" id="summary-' . absint( $post_id ) . '"><div class="wpa-content-summary-inner">' . $heading . wpautop( wp_kses_post( stripslashes( $summary ) ) ) . '</div></section>';
971
972        return $content;
973}
974
975/**
976 * Check whether a given post is in an allowed post type for content summaries.
977 *
978 * @param integer $post_id Post ID.
979 *
980 * @return boolean True if post is allowed, false otherwise.
981 */
982function wpa_in_post_type( $post_id ) {
983        $settings = get_option( 'wpa_post_types', array() );
984        if ( is_array( $settings ) && ! empty( $settings ) ) {
985                $type = get_post_type( $post_id );
986                if ( in_array( $type, $settings, true ) ) {
987                        return true;
988                }
989        }
990
991        return false;
992}
993
994add_action( 'admin_menu', 'wpa_add_outer_box' );
995/**
996 * Add metabox for content summaries.
997 */
998function wpa_add_outer_box() {
999        $allowed = get_option( 'wpa_post_types', array() );
1000        if ( is_array( $allowed ) ) {
1001                foreach ( $allowed as $post_type ) {
1002                        add_meta_box( 'wpa_content_summary_container', __( 'Content Summary', 'wp-accessibility' ), 'wpa_add_inner_box', $post_type, 'normal', 'high' );
1003                }
1004        }
1005}
1006
1007/**
1008 * Render content summary form.
1009 */
1010function wpa_add_inner_box() {
1011        global $post;
1012        $summary = get_post_meta( $post->ID, '_wpa_content_summary', true );
1013        $nonce   = wp_nonce_field( 'wpa-nonce-field', 'wpa_nonce_name', true, false );
1014        echo $nonce;
1015        ?>
1016        <p class='wpa-content-summary-field'>
1017                <label for="wpa_content_summary"><?php _e( 'Simple Content Summary', 'wp-accessibility' ); ?></label><br/>
1018                <textarea class="wpa-content-summary widefat" name="wpa_content_summary" id="wpa_content_summary" rows="4" cols="60" aria-describedy="content-summary-description"><?php echo esc_textarea( $summary ); ?></textarea>
1019                <span id="content-summary-description"><?php _e( 'Provide a simplified summary to aid comprehension of complex content.', 'wp-accessibility' ); ?></span>
1020        </p>
1021        <?php
1022}
1023
1024/**
1025 * Save content summary from post meta box.
1026 *
1027 * @param int    $id Post ID.
1028 * @param object $post Post.
1029 *
1030 * @return int
1031 */
1032function wpa_save_content_summary( $id, $post ) {
1033        if ( empty( $_POST ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || wp_is_post_revision( $id ) || isset( $_POST['_inline_edit'] ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || ! wpa_in_post_type( $id ) ) {
1034                return $id;
1035        }
1036
1037        // verify this came from our screen and with proper authorization.
1038        // because save_post can be triggered at other times.
1039        if ( isset( $_POST['wpa_nonce_name'] ) ) {
1040                if ( ! wp_verify_nonce( $_POST['wpa_nonce_name'], 'wpa-nonce-field' ) ) {
1041                        return $id;
1042                }
1043                $summary = isset( $_POST['wpa_content_summary'] ) ? wp_kses_post( $_POST['wpa_content_summary'] ) : '';
1044                update_post_meta( $id, '_wpa_content_summary', $summary );
1045        }
1046
1047        return $id;
1048}
1049add_action( 'save_post', 'wpa_save_content_summary', 10, 2 );
Note: See TracBrowser for help on using the repository browser.