$meta ) { if ( empty( $counts[ $key ] ) ) { continue; } $total = (int) $counts[ $key ]['total']; if ( $total < 1 ) { continue; } $line = $meta['label'] . ' (' . sprintf( /* translators: %d: number of findings. */ _n( '%d instance', '%d instances', $total, 'siftra' ), $total ) . ')'; if ( '' !== $meta['wcag'] ) { $line .= ' — WCAG ' . $meta['wcag']; } $lines[] = $line; } return $lines; } /** * Whether an address can actually receive a complaint. * * admin_email is not always a real inbox. A fresh install on a test host * hands back admin@localhost.com or admin@example.com, and a statement * that sends visitors to a dead address is worse than one that sends them * nowhere: the visitor believes there is a feedback route and there is not. * * @param string $email Email address. * @return bool */ public static function is_usable_email( $email ) { $email = trim( (string) $email ); if ( '' === $email || ! is_email( $email ) ) { return false; } $parts = explode( '@', $email ); $host = strtolower( (string) end( $parts ) ); /* * Playground and several one-click installers ship admin@localhost.com, * admin@localhost.localdomain and friends. They all start with * "localhost": matching the bare word only was not enough, because * localhost.com slipped straight through. */ if ( 0 === strpos( $host, 'localhost' ) || false !== strpos( $host, '.localhost' ) ) { return false; } $placeholders = array( 'example.com', 'example.org', 'example.net', 'example.edu' ); if ( in_array( $host, $placeholders, true ) ) { return false; } foreach ( array( '.local', '.test', '.invalid', '.example', '.localhost', '.localdomain' ) as $suffix ) { if ( substr( $host, -strlen( $suffix ) ) === $suffix ) { return false; } } return true; } /** * Build the statement text. * * @param array $args Inputs from the form. * @return string */ public static function build( $args ) { $defaults = array( 'org' => get_bloginfo( 'name' ), 'site' => home_url( '/' ), 'email' => get_option( 'admin_email' ), 'phone' => '', 'standard' => 'WCAG 2.1 level AA', 'conformance' => 'partially conformant', 'date' => date_i18n( get_option( 'date_format' ) ), 'response_days' => 5, 'known_issues' => array(), 'manual' => '', 'scan_date' => '', 'pages_checked' => 0, 'pages_attempted' => 0, ); $a = array_merge( $defaults, is_array( $args ) ? $args : array() ); $org = trim( (string) $a['org'] ); $site = trim( (string) $a['site'] ); $email = trim( (string) $a['email'] ); $email_ok = self::is_usable_email( $email ); $phone = trim( (string) $a['phone'] ); $date = trim( (string) $a['date'] ); $days = max( 1, (int) $a['response_days'] ); $issues = is_array( $a['known_issues'] ) ? $a['known_issues'] : array(); $manual = trim( (string) $a['manual'] ); $checked = max( 0, (int) $a['pages_checked'] ); $attempted = max( $checked, (int) $a['pages_attempted'] ); if ( '' === $org ) { $org = get_bloginfo( 'name' ); } // An empty field would otherwise leave a blank in the middle of a sentence. if ( '' === $site ) { $site = home_url( '/' ); } if ( '' === $date ) { $date = date_i18n( get_option( 'date_format' ) ); } $conformance = (string) $a['conformance']; if ( ! in_array( $conformance, array( 'fully conformant', 'partially conformant', 'not conformant' ), true ) ) { $conformance = 'partially conformant'; } $lines = array(); $lines[] = 'Accessibility Statement for ' . $org; $lines[] = ''; $lines[] = sprintf( 'This statement applies to %1$s and was last reviewed on %2$s.', $site, $date ); $lines[] = ''; $lines[] = sprintf( '%1$s wants this website to be usable by as many people as possible, including people who use screen readers, keyboard navigation, screen magnification, or speech input.', $org ); $lines[] = ''; $lines[] = 'Conformance status'; $lines[] = sprintf( 'This website is %1$s with %2$s.', $conformance, $a['standard'] ); if ( 'partially conformant' === $conformance ) { $lines[] = '"Partially conformant" means that some parts of the content do not fully meet the standard. The known gaps are listed below.'; } elseif ( 'not conformant' === $conformance ) { $lines[] = '"Not conformant" means that the content does not meet the standard yet. The known gaps are listed below.'; } $lines[] = ''; $lines[] = 'Known limitations'; if ( empty( $issues ) ) { if ( $checked > 0 ) { $lines[] = 'We are not aware of any known limitations at this time.'; } else { $lines[] = 'This site has not been assessed yet, so no limitations can be listed here.'; } } else { foreach ( $issues as $issue ) { $issue = trim( (string) $issue ); if ( '' !== $issue ) { $lines[] = '- ' . $issue; } } } $lines[] = ''; $lines[] = 'These findings come from automated testing, which can detect only a share of accessibility problems. This list is therefore not a complete picture of the site.'; if ( $checked > 0 ) { if ( $attempted > $checked ) { $lines[] = sprintf( 'The scan read %1$d of %2$d pages; the remaining %3$d could not be fetched and were not checked.', $checked, $attempted, $attempted - $checked ); } else { $lines[] = sprintf( 'The scan read %d pages.', $checked ); } } $lines[] = ''; $lines[] = 'Feedback'; if ( $email_ok ) { $contact = 'If you meet a barrier on this site, please tell us at ' . $email . '.'; if ( '' !== $phone ) { $contact .= ' You can also call ' . $phone . '.'; } $lines[] = $contact; } elseif ( '' !== $phone ) { $lines[] = 'If you meet a barrier on this site, please call ' . $phone . '.'; } else { $lines[] = 'If you meet a barrier on this site, please use the contact details on our contact page so that we can fix it.'; } $lines[] = sprintf( 'We aim to reply within %d business days.', $days ); $lines[] = ''; $lines[] = 'Assessment approach'; if ( '' !== $manual ) { $lines[] = $org . ' assessed this website with automated scanning plus manual checks: ' . $manual; } else { $lines[] = $org . ' assessed this website with automated scanning. Manual testing has not been carried out yet.'; } $lines[] = ''; $lines[] = 'Enforcement procedure'; $lines[] = 'If you are not satisfied with our response, you can contact the authority responsible for accessibility in your country.'; $lines[] = ''; $lines[] = 'Date of this statement: ' . $date; $lines[] = 'Created with Siftra, the free accessibility statement generator.'; return implode( "\n", $lines ); } }