Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
CRAP
100.00% covered (success)
100.00%
1 / 1
AnnotationConstraint
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
7
100.00% covered (success)
100.00%
1 / 1
 check
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
7
1<?php
2
3declare(strict_types=1);
4
5namespace Phpdftk\Pdf\Conformance\Constraint;
6
7use Phpdftk\Pdf\Conformance\Inspection\DocumentInspector;
8use Phpdftk\Pdf\Conformance\Profile\ConformanceProfile;
9use Phpdftk\Pdf\Conformance\Result\ConformanceViolation;
10use Phpdftk\Pdf\Conformance\Result\ViolationSeverity;
11use Phpdftk\Pdf\Core\Annotation\Annotation;
12use Phpdftk\Pdf\Core\Annotation\WidgetAnnotation;
13use Phpdftk\Pdf\Core\Annotation\PopupAnnotation;
14use Phpdftk\Pdf\Core\Annotation\LinkAnnotation;
15
16/**
17 * PDF/UA-1 clause 7.18.1: Annotations must be accessible.
18 *
19 * All annotations (except Widget and Popup) must have /Contents set
20 * to provide an accessible text alternative. Link annotations must
21 * additionally have /Contents or be wrapped in a Link structure element.
22 */
23final class AnnotationConstraint implements ConformanceConstraint
24{
25    public function check(DocumentInspector $inspector, ConformanceProfile $profile): array
26    {
27        $violations = [];
28
29        foreach ($inspector->getRegisteredObjects() as $object) {
30            if (!$object instanceof Annotation) {
31                continue;
32            }
33
34            // Widget and Popup annotations are exempt from /Contents requirement
35            if ($object instanceof WidgetAnnotation || $object instanceof PopupAnnotation) {
36                continue;
37            }
38
39            if ($object->contents === null || trim($object->contents->value) === '') {
40                $subtype = $object->getSubtype();
41                $violations[] = new ConformanceViolation(
42                    clause: '7.18.1',
43                    message: sprintf(
44                        '%s annotation (object %d) must have /Contents for accessibility',
45                        $subtype,
46                        $object->objectNumber,
47                    ),
48                    severity: ViolationSeverity::Error,
49                    objectPath: "Annotation[{$subtype}][{$object->objectNumber}]",
50                );
51            }
52        }
53
54        return $violations;
55    }
56}