=== Accessibility Statement and EN 301 549 Self Check by TheSEO ===
Contributors: theseo
Tags: accessibility, wcag, a11y, accessibility statement, audit
Requires at least: 6.0
Tested up to: 6.8
Requires PHP: 7.4
Stable tag: 1.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Checks your pages against the machine testable points of EN 301 549 and writes an accessibility statement that matches what was measured.

== Description ==

Two things that belong together and are almost never done together: a check of
what a machine can actually test, and a statement built out of that measurement
instead of out of good intentions.

**No overlay.** This plugin adds nothing to the front end of your site except,
if you switch it on, one link to your statement page. It never repairs anything
on top of a page. It points at the problem and you fix it in the place where it
sits. An overlay hides the problem from the tool and leaves it in place for the
person who ran into it.

**No outgoing request in the default setting.** Everything the plugin knows it
worked out on your own server. There is no account, no dashboard elsewhere, no
service behind it and no key to enter. The one exception is described under
"the only request that ever leaves your server" below, it is your site calling
itself, and it is off unless you choose it.

= What it checks =

Eighteen rules, ten of which block somebody and eight of which deserve
attention. Together they touch twelve WCAG 2.2 success criteria. Chapter 9 of
EN 301 549 adopts the WCAG criteria one to one, so criterion 1.1.1 is clause
9.1.1.1 of the standard. The plugin prints both numbers next to every finding.

The whole list, and there is nothing outside it:

* image without a text alternative, and a text alternative that is really a
  file name
* clickable area of an image map without a text alternative
* embedded object or embed without anything to fall back on
* empty heading, and a heading level skipped
* table with data cells and not a single header cell
* audio or video that starts by itself, is not muted and has no controls
* zooming switched off or capped below twice the size
* page without a title element
* positive tabindex
* link without a name, link text that says nothing, and a link that opens in a
  new window without saying so
* page language not set on the html element
* form field without a label, an aria-label or a title
* the same id used twice
* frame without a name

= What it cannot check, and says so on every screen =

A machine test covers part of accessibility and no more. It sees a missing text
alternative. It cannot judge whether an alternative describes the picture,
whether your site can be used with a keyboard alone, whether the contrast holds
up, whether an error message actually explains itself, or whether a custom
widget behaves the way it announces itself. A statement that leans on this
measurement alone is incomplete, the plugin writes that sentence into the
statement itself, and both the overview and the settings screen repeat it.

Testing with people who use assistive technology, and a review by somebody who
does this for a living, are the parts that are missing. This plugin does not
replace either of them and does not declare anybody compliant.

= The statement =

The statement tab asks for what a statement needs: the name of the
organisation, where somebody reports a problem, what happens when you do not
answer, the date of the assessment and who carried it out. Then, for every rule
that was actually broken somewhere on the site, you pick one of three answers:
fixed, known and being worked on, or a disproportionate burden with your
reasons in your own words.

The statement is written out of those answers and out of the measurement, and
out of nothing else. You see the whole text on screen before you write it
anywhere. The button then saves it as a **draft page**. A new page is never
published for you. When a statement page already exists it is rewritten and
keeps whatever status it had.

It comes in Dutch or in English.

= A Dutch government body needs a different document =

Public bodies in the Netherlands have to publish their statement in the
national register, in the prescribed model, and that model asks for things this
plugin does not measure. This is a statement for a business under the European
Accessibility Act. It is not that model and it does not replace it. The
statement screen says so before you fill anything in.

= What it stores =

Two tables in your own database.

One row per finding: the post id, the rule code, the weight, a short pointer to
the element, the offending html cut to 300 characters, and the moment of
measuring. One row per check: the moment, how it read the site, and the totals.
Your statement fields sit in a single option.

No personal data. No visitor data. No IP address, no cookie, nothing in
localStorage or sessionStorage, no user agent. The plugin never looks at your
visitors at all; it reads your own content.

= The only request that ever leaves your server =

The check reads either the content of an item, which is what the editor
produces, or the whole page including the header, the menu and the footer of
your theme. Three of the eighteen rules can only be judged on a whole page: the
page language, the page title and the viewport.

Whole page mode is the only way to see those three, and the only way to see
them is to ask your own site for the page over http. That request goes to your
own domain and nowhere else. **Content mode is the default, and in content mode
there is no outgoing request at all.** Some hosts block a site from calling
itself; the overview then reports how many items could not be read instead of
quietly counting them as clean.

= Retention =

Findings are replaced per item on every check, so what you see is the state of
the last measurement and not a pile of history. Deactivating the plugin keeps
the findings and stops the scheduled check. Deleting the plugin drops both
tables, the option and the schedule. Your statement page is left alone, because
that page is yours.

== Installation ==

1. Upload the plugin folder to `/wp-content/plugins/theseo-toegankelijkheidsverklaring`,
   or upload the zip through Plugins, Add new, Upload plugin.
2. Activate the plugin. Nothing is checked and nothing changes on the front end
   until you press a button.
3. Open Settings, Accessibility, Settings and pick which post types are read,
   how much is read, and whether the check should repeat by itself.
4. Go to the Overview tab and press "Check the site now". The check runs in
   steps so a big site does not walk into the time limit of the server.
5. Work through the findings. Click any row to see what is wrong, which clause
   it belongs to and what to do about it.
6. Open the Statement tab, fill in your details, answer for every finding, and
   write the statement into a page. It arrives as a draft. Read it, change what
   you want, and publish it yourself.

== Frequently Asked Questions ==

= Does this make my site accessible? =

No, and be careful with anything that says it does. This tells you what a
machine can see, in plain language, with the clause it belongs to. Fixing it is
work in your content, your theme and your plugins. There is no button here that
makes a site accessible, because there is no such button.

= Why is there no accessibility widget? =

Because an overlay does not fix the underlying page. It sits on top of it, and
many people who use assistive technology every day ask for it to be switched
off again. This plugin takes the other road: point at the problem, in the
markup, where it can actually be fixed.

= Does it change anything on the front end of my site? =

Only one thing, and only if you tick it: a link to your statement page in the
footer. That link appears only when the statement page is actually published; a
draft is never linked to. Nothing else is added, no script is loaded and no
style is enqueued for visitors.

= How is the EN 301 549 clause number worked out? =

Chapter 9 of EN 301 549 adopts the WCAG success criteria one to one, so the
clause is 9 followed by the criterion number. That is how the standard is
built, not a guess by this plugin.

= One rule is marked as withdrawn, why is it still in there? =

Criterion 4.1.1, the same id used twice, was withdrawn in WCAG 2.2. EN 301 549
still points at WCAG 2.1, where it counts. It is therefore in the list as
something to note rather than as something blocking, and the reason is printed
next to the finding.

= The check says an item could not be read =

That happens in whole page mode when your server cannot call itself, or when
the page answers with something other than 200. The screen counts those items
separately instead of pretending they were fine. Switching to content mode
avoids it entirely, at the cost of the three rules that need a whole page.

= Does it work on multisite? =

Yes. Each site in the network gets its own tables, its own settings and its own
statement. Deleting the plugin cleans up every site.

= Is anything sent to TheSEO? =

No. Nothing is sent anywhere. There is no tracking, no phone home, no usage
statistic and no licence check.

== Changelog ==

= 1.0.0 =
* First version.
* Eighteen machine testable rules over twelve WCAG 2.2 success criteria, each
  with the matching EN 301 549 clause, in plain language, with what to do about
  it.
* Overview with three counters, a filter on blocking findings only, and a
  per item screen with the pointer and the offending html.
* Check in steps over ajax, with a nonce and a capability check on every step,
  so a large site does not run into the time limit of the server.
* Optional automatic check, weekly or every thirty days, off by default.
* Statement builder in Dutch or English, with three answers per finding and a
  place for the reasons behind a disproportionate burden.
* The statement is saved as a draft page, never published for you, and an
  existing page keeps its status when it is rewritten.
* States on every screen and inside the statement itself what a machine test
  cannot cover.
* No overlay, no personal data, no visitor data, and no outgoing request except
  your own site calling itself in whole page mode.

== Upgrade Notice ==

= 1.0.0 =
First version.
