Pro редакция
Compliance — глубокий справочник
Модуль Compliance объединяет три независимые поверхности в пространстве NextPDF\Pro\Compliance:
- Отчётность по языковым тегам — строгий фасад политики
/Langдля PDF/UA-2 плюс структурированный репортёр событий соответствия в форме PSR-3. - Обработка электронных счетов — проверка Factur-X 1.08 / ZUGFeRD 2.4 на соответствие семантической модели EN 16931 и создание гибридного PDF/A-3.
- Происхождение — встраивание и извлечение переданных вызывающей стороной хранилищ манифестов C2PA через устойчивый к атакам парсер JUMBF; синтез утверждений остаётся в предварительной версии.
Модуль сообщает то, что проверяет. Он не сертифицирует документы и не выполняет криптографического подписания.
Доступность и лицензирование
Заголовок раздела «Доступность и лицензирование»Эта возможность поставляется в составе NextPDF Pro (nextpdf/pro) и активируется лицензионным конвертом уровня Pro. Развёртывание без этого права доступа не загружает классы возможности. Сравнить редакции и получить лицензию.
Пофункционального лицензионного флага нет. Это возможность редакции Pro. Экспериментальный конструктор утверждений C2PA дополнительно требует явного включения через переменную окружения (см. «Граничные случаи и режимы отказа»).
Публичная поверхность API
Заголовок раздела «Публичная поверхность API»composer require nextpdf/pro:^3| Символ | Параметры | Поведение по умолчанию | Возвращает | Выбрасывает или завершается с | Примечания |
|---|---|---|---|---|---|
LangComplianceReporter::warn() / ::error() | string $tag, string $reason, ?string $clauseReference = null | Выдаёт одну структурированную запись JSON на каждое событие языкового тега через логгер PSR-3 | void | JsonException, если запись не удаётся закодировать в JSON | warn = отклонение в нестрогом режиме; error = отклонение в строгом режиме |
LangComplianceReporter::reportException() | InvalidBcp47TagException $exception, string $severity = 'error' | Извлекает тег и причину из исключения; делегирует warn() или error() | void | Как выше | Удобный путь |
LangComplianceReporter::buildRecord() | string $severity, string $tag, string $reason, ?string $clauseReference = null | Строит массив записи без логирования | array | Не выбрасывает | Для пользовательских приёмников, например пофайловых сводок JSON |
ConformancePolicy::default() | ?LoggerInterface $logger = null | Строгая политика UA-2: некорректные или незарегистрированные теги /Lang отклоняются | self | Не выбрасывает | Значение по умолчанию в v5.0 — строгое |
ConformancePolicy::fromCore() | CoreConformancePolicy $core, ?LoggerInterface $logger = null | Оборачивает существующую политику Core как есть; ни одна ось не переключается | self | Не выбрасывает | Для строгой позиции предпочитайте default() |
ConformancePolicy::withStrictUa2() | bool $enabled | Возвращает копию с установленной строгой осью; отключение выдаёт notice PSR-3 | self | Не выбрасывает | Устаревший отказ; целевое удаление 6.0.0 |
ConformancePolicy::isStrictUa2() / ::mode() | — | Читает лежащую в основе политику Core | bool / ConformanceMode | Не выбрасывает | — |
EInvoiceValidator::validate() | string $pdfPath | Полный конвейер: проверка обёртки PDF/A-3, извлечение вложений, определение профиля, правила EN 16931, Schematron | EInvoiceValidationResult | Подкласс EInvoiceException при сбое ввода-вывода, некорректной структуре PDF или сбое инструментария | Замороженный интерфейс SPI; корректно сформированный PDF, не являющийся электронным счётом, возвращает результат и никогда не выбрасывает |
EInvoiceXmlValidator::validate() | string $xmlPayload, ValidatorContext $context | Структурная предпроверка плюс корпус глубоко-семантических правил EN 16931 над полезной нагрузкой CII | контракт ValidationResult | Не выбрасывает при некорректном вводе; отклонение проявляется как неуспешный результат с находками | Конкретный межуровневый валидатор; ввод фильтруется через XmlGuard |
EInvoiceValidationResult::isValid() | — | True только когда верны обёртка, спецификация вложения, профиль, синтаксис и нет нарушения уровня FATAL | bool | Не выбрасывает | Один лишь пустой список нарушений не означает валидность |
EInvoiceValidationResult::notAnEInvoice() | — | Детерминированный результат: все значения null и false | self | Не выбрасывает | Фабрика для случая «не гибридный счёт» |
EInvoiceProfile | перечисление на строках | Варианты MINIMUM, BASIC_WL, BASIC, EN16931, EXTENDED, опирающиеся на URN BT-24 | — | — | isEn16931Conformant() равно false для MINIMUM и BASIC_WL |
EInvoiceSyntax | перечисление на строках | Варианты UN_CEFACT_CII, UBL_INVOICE, UBL_CREDIT_NOTE | — | — | Только CII является isFacturXEligible(); UBL только для валидации |
BusinessRuleViolation | string $ruleId, BusinessRuleSeverity $severity, string $message, ?string $xpath = null, ?string $ramPath = null | Неизменяемый DTO нарушения | — | — | Семейства идентификаторов правил BR-, BR-CO-, BR-CL-, BR-DEC-, BR-FXEXT- |
BusinessRuleSeverity | перечисление на строках | FATAL делает счёт недействительным; WARNING отмечает вопрос качества | — | — | Отражает уровни Schematron из EN 16931 |
FacturXEmbedder::embed() | см. блок сигнатуры | Добавляет поток встроенного файла, filespec и XMP к источнику PDF/A; перезаписывает xref | void | EInvoiceException при некорректном XML, нечитаемом источнике, отсутствующем каталоге, источнике с потоком объектов или потоком xref, либо сбое записи вывода | Исходный файл остаётся нетронутым |
FacturXEmbedderOptions::default() | — | /AFRelationship /Alternative, имя файла factur-x.xml, тип INVOICE, версия 1.0 | self | Не выбрасывает | Значения по умолчанию удовлетворяют немецкому мандату и принимаются во Франции |
FacturXEmbedderOptions::withRelationship() / ::withFilename() | string | Возвращает копию с применённым переопределением | self | InvalidArgumentException вне множеств допустимых значений | Отношения: Source, Data, Alternative; имена файлов включают zugferd-invoice.xml и xrechnung.xml |
FacturXEmbedderOptions::withDocumentType() | string $documentType | Возвращает копию с переопределением типа документа XMP | self | Не выбрасывает | Значения не проверяются по перечислению |
FacturXContractEmbedder::embed() | string $pdfBytes, string $xmlPayload, EmbedderOptions $options | Адаптер «байты на входе, байты на выходе» над FacturXEmbedder через недолговечные временные файлы | string | EInvoiceException; профиль XRECHNUNG отклоняется как доступный только в Enterprise | Межуровневая реализация EmbedderInterface |
C2paManifestEmbedder::embed() | string $pdfBytes, ManifestStore $store | Встраивает байтовую сериализацию хранилища в место, заданное профилем | string | C2paException при любом сбое встраивания | Замороженный интерфейс SPI; только байты, без ввода-вывода |
C2paManifestEmbedder::extract() | string $pdfBytes | Разбирает встроенное хранилище через усиленный парсер JUMBF | ManifestStore|null | Подкласс C2paException, когда хранилище присутствует, но нарушает лимит усиления | Null означает отсутствие; отсутствие никогда не выбрасывает |
ManifestStore::fromBoxes() / ::empty() | list<JumbfBox> / — | Строит неизменяемый объект-значение хранилища | self | Не выбрасывает | Порядок боксов значим для равенства при round-trip |
ManifestStore::toBytes() / ::isEmpty() / ::size() | — | Сериализует корневые боксы; пустое хранилище сериализуется в пустую строку | string / bool / int | Не выбрасывает | — |
JumbfBoxParser::parse() | string $bytes | Разбирает боксы JUMBF корневого уровня под жёсткими лимитами | list<JumbfBox> | MalformedJumbfException, JumbfBombException, JumbfCycleDetectedException, JumbfDepthExceededException | Лимиты: глубина 8, 64 MiB на бокс, 128 MiB всего, MAX_CHILDREN_PER_SUPERBOX 4096 |
JumbfBox::superbox() / ::leaf() | string $tbox, … | Строит проверенный бокс; toBytes() совершает round-trip через парсер | self | MalformedJumbfException, когда TBox не ровно 4 байта | — |
C2paCapabilityStatus::current() / ::summary() | — | Сообщает зрелость возможности C2PA, сейчас preview-draft | self / string | Не выбрасывает | Машиночитаемый маркер предварительной версии |
Feature::PREVIEW_C2PA_DRAFT->isEnabled() | — | Читает окружение процесса при каждом вызове; включает только литерал '1' | bool | Не выбрасывает | Переменная окружения NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT |
ExperimentalC2paEmbedder::buildManifestStore() | string $sourceBytes, string $producer | Строит закреплённое за черновиком хранилище манифестов с одним утверждением привязки хеша SHA-256 | ManifestStore | Конструктор выбрасывает LogicException, когда флаг предварительной версии выключен | Предварительная версия; формат представления закреплён за снимком черновика; подпись утверждения не создаётся |
Сигнатуры точек входа, дословно:
public static function default(?LoggerInterface $logger = null): selfpublic function withStrictUa2(bool $enabled): selfpublic function isStrictUa2(): boolpublic function validate(string $pdfPath): EInvoiceValidationResultpublic function embed( string $sourcePdfPath, string $xml, EInvoiceProfile $profile, string $outputPdfPath, ?FacturXEmbedderOptions $options = null,): voidpublic function embed(string $pdfBytes, ManifestStore $store): stringpublic function extract(string $pdfBytes): ?ManifestStoreКонтракт поведения
Заголовок раздела «Контракт поведения»Отчётность по языковым тегам. LangComplianceReporter выдаёт одну структурированную запись JSON на каждое событие языкового тега PDF/UA-2. Каждая запись несёт фиксированный дискриминатор события, серьёзность (warn для отклонения в нестрогом режиме, error для отклонения в строгом режиме), нарушающий тег дословно, машиночитаемую причину, разобранные компоненты тега (или null, когда тег не проходит грамматику формы RFC 5646), ссылку на пункт ISO 14289-2 §8.4.4 и метку времени UTC с микросекундами. JSON передаётся как тело сообщения PSR-3; нижестоящие приёмники разбирают поле сообщения напрямую. ConformancePolicy — фасад Premium над политикой соответствия Core. Его значение по умолчанию применяет строгую обработку языка UA-2 и отклоняет некорректный или незарегистрированный тег, попадающий в /Lang. Помощник отказа withStrictUa2(false) возвращает к прежнему нестрогому поведению и записывает уведомление PSR-3, когда эффективное значение действительно меняется. NextPDF помечает этот помощник как устаревший с версии v5.0 с целевым удалением в 6.0.0. Чтобы выполнить миграцию: проверьте корпус на некорректные значения /Lang командой composer pdfua2:audit-lang-tags <pdf-or-dir>, исправьте их, затем уберите вызов отказа.
Обработка электронных счетов. EInvoiceValidator — замороженный контракт SPI для проверки гибридных PDF: проверка обёртки PDF/A-3, извлечение вложения /AF, определение профиля по идентификатору спецификации BT-24, движок бизнес-правил EN 16931 и проход Schematron. Корректно сформированный PDF, не являющийся Factur-X, возвращает EInvoiceValidationResult::notAnEInvoice(), а не выбрасывает исключение; только сбои ввода-вывода, некорректная структура PDF или сбои инструментария поднимают подкласс EInvoiceException. EInvoiceXmlValidator — конкретный межуровневый валидатор XML: он фильтрует ввод через Core XmlGuard, выполняет структурную предпроверку и глубокий корпус семантических правил EN 16931 и завершается закрыто — ошибки движка проявляются как ошибочные находки, а не как молчаливые проходы. FacturXEmbedder преобразует источник PDF/A в гибридный PDF/A-3: он добавляет поток встроенного файла, filespec с настраиваемым /AFRelationship и пакет расширения XMP Factur-X, затем перезаписывает классическую таблицу перекрёстных ссылок. И массив /AF каталога, и дерево имён /Names /EmbeddedFiles ссылаются на вложение, поэтому его находят прежние читатели ZUGFeRD.
Происхождение. C2paManifestEmbedder встраивает переданное вызывающей стороной хранилище манифестов C2PA в байтовую строку PDF или извлекает его. ManifestStore — неизменяемый объект-значение, пересекающий границу. Этот стык работает только с байтами и нейтрален к поставщику: он не синтезирует утверждения, не принимает ссылки URI и не разрешает привязки хешей, а также не выполняет сетевого или файлового ввода-вывода. extract() возвращает null при промахе и дёшев на PDF без хранилища. Каждое ненулевое извлечение уже прошло лимиты усиления JumbfBoxParser.
Этот модуль сообщает то, что проверяет. Он не сертифицирует документ, не делает его юридически обязывающим и не гарантирует, что какой-либо вывод удовлетворяет регламенту. Валидатор электронных счетов не является валидатором налогового органа и исключает национальные расширения (например итальянский SDI, французский Chorus Pro, немецкий XRechnung). Как указано в EN 16931-1, эмитент счёта остаётся ответственным за выполнение правил соответствующего законодательства. Поддержка стандарта — это не соответствие ему. По нормативной достаточности обращайтесь к своей команде по соответствию требованиям.
Граничные случаи и режимы отказа
Заголовок раздела «Граничные случаи и режимы отказа»- Корректно сформированный PDF, не являющийся Factur-X, возвращает результат «не электронный счёт»; он не выбрасывает исключение.
- Пустой список нарушений бизнес-правил сам по себе не означает, что документ действителен; применяются также проверки обёртки и вложений.
FacturXEmbedderзавершается закрыто на источниках, использующих сжатые потоки объектов (/Type /ObjStm) или потоки перекрёстных ссылок (/Type /XRef, гибридный/XRefStm). Сначала пересохраните такие источники с классической таблицей перекрёстных ссылок.- Полезные нагрузки XML фильтруются через Core
XmlGuard: объявления DOCTYPE или сущностей, чрезмерно большой ввод и некорректный UTF-8 отклоняются сEInvoiceExceptionна пути встраивания или неуспешным результатом на пути валидатора. FacturXContractEmbedderотклоняет профильXRECHNUNGявно, а не молча понижает его; создание XRechnung — возможность Enterprise.C2paManifestEmbedder::extract()различает отсутствие (null) и некорректность (подклассC2paException, называющий нарушенный инвариант: некорректная структура, бомба по размеру или количеству, цикл смещений, глубина вложенности).- Создание
ExperimentalC2paEmbedderвыбрасываетLogicException, если флаг предварительной версии в окружении не равен'1'. Его формат представления закреплён за снимком черновика C2PA и может измениться без уведомления; он не создаёт подписи утверждения. Эта возможность остаётся предварительной, пока не будет заморожен профиль C2PA для PDF. - Нестрогий отказ от строгого UA-2 устарел; переходите на строгое значение по умолчанию (см. «Контракт поведения»).
- Этот модуль не выполняет криптографического подписания. Подписание утверждений C2PA и хранение ключей вне области рассмотрения; о поведении подписания в режиме FIPS см. модуль Security.
Соответствие
Заголовок раздела «Соответствие»| Поведение | Ссылка | Статус |
|---|---|---|
Объявление естественного языка (/Lang) | ISO 14289-2:2024 §8.4.4 | Проверяется / сообщается |
| Семантическая модель основного счёта | EN 16931-1:2026 | Проверяется (эмитент остаётся ответственным) |
| Ассоциированные файлы / потоки встроенных файлов | ISO 32000-2:2020 §14.13.2 | Создаётся (/AF, /EF, /Params) |
| Отношение вложения и правила контейнера | Factur-X 1.08 §3.1, §6.2 | Создаётся / проверяется (по умолчанию /AFRelationship /Alternative) |
| Хранилище манифестов C2PA / JUMBF | C2PA 2.1 §11.1 | Встраивание / извлечение поддерживается; синтез утверждений — предварительно |
Это фиксирует спецификации, на которые опирается модуль, и то, что он проверяет или создаёт. Это не заявление о сертификации или нормативной достаточности. NextPDF не имеет сертификации по этим стандартам.
Замечания по разработке
Заголовок раздела «Замечания по разработке»- Форма записи репортёра — стабильный контракт; нижестоящие правила оповещения могут закрепляться за фиксированным дискриминатором события.
- Отключение строгого UA-2 выдаёт видимое в телеметрии уведомление об устаревании только когда эффективное значение меняется; повторное подтверждение текущего значения проходит молча.
- Встраиватель Factur-X сохраняет байты источника дословно и добавляет новые объекты; он стремится сохранить соответствие PDF/A-3, но не выполняет повторную проверку. Для строгого подтверждения пропустите вывод через внешний валидатор PDF/A.
- Стык C2PA замораживает пять инвариантов: отсутствие сторонних импортов, контракт только на байтах, отсутствие ввода-вывода, извлечение с null при промахе и отсутствие синтеза утверждений в стабильном слое.
- Лимиты
JumbfBoxParser— публичные константы; соизмеряйте принимаемый ввод с ними, а не выводите лимиты заново.
Граница публикации
Заголовок раздела «Граница публикации»Эта страница документирует только внешне наблюдаемое поведение и поддерживаемую публичную поверхность API. Внутренние пути пространств имён, вспомогательные классы, таблицы механизмов, имена файлов runbook и префиксы тикетов вне области рассмотрения.