Skip to content

[WIP] Sign usign only PHP#2595

Draft
vitormattos wants to merge 26 commits intomainfrom
feature/sign-usign-only-php
Draft

[WIP] Sign usign only PHP#2595
vitormattos wants to merge 26 commits intomainfrom
feature/sign-usign-only-php

Conversation

@vitormattos
Copy link
Member

@vitormattos vitormattos commented Mar 26, 2024

Target: Make possible sign using only PHP

Start to implement jeidison/pdf-signer

ref: jeidison/signer-php#3

Administration setting: change the signature engine
image

Performance test: Results for 10 documents with clickToSign:

Engine Start End Duration
PhpNative 18:32:49 18:33:08 19s
JSignPdf 18:33:55 18:34:32 37s

PhpNative is ~2× faster than JSignPdf (1.9s vs 3.7s per document). The native PHP implementation cuts signing time roughly in half by eliminating the Java/JVM overhead.

@vitormattos vitormattos added this to the Next Major (29) milestone Mar 26, 2024
@vitormattos vitormattos self-assigned this Mar 26, 2024
@vitormattos vitormattos force-pushed the feature/sign-usign-only-php branch 2 times, most recently from 4b1b252 to 424f9f4 Compare March 26, 2024 13:29
@vitormattos vitormattos changed the title Start to implement jeidison/pdf-signe [WIP] Start to implement jeidison/pdf-signe Mar 26, 2024
@vitormattos vitormattos changed the title [WIP] Start to implement jeidison/pdf-signe [WIP] Sign usign only PHP Mar 26, 2024
@vitormattos vitormattos force-pushed the feature/sign-usign-only-php branch from 424f9f4 to 581e196 Compare April 11, 2024 04:45
@vitormattos vitormattos force-pushed the feature/sign-usign-only-php branch 3 times, most recently from d7414c1 to c78d966 Compare April 23, 2024 23:44
@vitormattos vitormattos force-pushed the feature/sign-usign-only-php branch from c78d966 to e71f53a Compare May 17, 2024 17:30
@vitormattos vitormattos force-pushed the main branch 9 times, most recently from 7c7ad4e to cae8ce7 Compare June 25, 2024 02:20
@vitormattos vitormattos force-pushed the feature/sign-usign-only-php branch 2 times, most recently from df6ade7 to 24f7ca9 Compare March 4, 2026 17:20
vitormattos and others added 5 commits March 4, 2026 14:25
Signed-off-by: Vitor Mattos <vitor@php.rio>
Signed-off-by: Vitor Mattos <vitor@php.rio>
Signed-off-by: Vitor Mattos <vitor@php.rio>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Reduce line height from 1.2× to 1.15× font size for tighter spacing
- Set top padding to 0.35× line height to match JSignPdf output
- Ensures visual parity with JSignPdf's iText-based text rendering

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Replace string literal 'GRAPHIC_ONLY' with SignerElementsService::RENDER_MODE_GRAPHIC_ONLY
- Improves code consistency and maintainability

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Use date_default_timezone_get() instead of hardcoded UTC
- Ensures ServerSignatureDate reflects actual server timezone configuration
- Captures date at rendering time, not during params preparation

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- ServerSignatureDate is now injected at rendering time by each handler
- PhpNativeHandler uses server timezone
- JSignPdfHandler uses ${timestamp} placeholder
- Ensures proper timezone handling for each implementation

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- LocalSignerSignatureDateTime now uses user's timezone, not UTC
- Correctly reflects 'Local' in variable name
- Use date_default_timezone_get() for user's configured timezone
- LocalSignerTimezone parameter indicates which timezone was used

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…ervice

- Replace string literal 'GRAPHIC_ONLY' with SignerElementsService::RENDER_MODE_GRAPHIC_ONLY
- Add SignerElementsService import
- Improves code consistency across codebase

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- New render mode for PhpNativeHandler to show signature without description text
- Full canvas displays signature drawing with watermark background
- Extends existing JSignPdf render modes for PHP-only signing

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…bject text operators

Remove Imagick/ITempManager dependencies from PhpNativeHandler. All render modes now produce a SignatureAppearanceXObjectDto carrying PDF text stream operators instead of compositing raster images. The paradoxical-condition psalm issue is also resolved here - the max(0.0,...) guard was removed so the inner overflow check can fire.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…pearance branch

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Covers: wrapTextForPdf (4 cases), escapePdfText (5 cases), hasExistingSignatures (5 cases), buildTimestampOptions (4 cases), resolveCertificationLevel (4 cases), buildAppearanceForElement signature image placement (2 cases), buildXObject layout per render mode (4 cases).
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…signature params

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…x-start

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces an alternative PDF signing path that can run using PHP-only signing (via jeidison/signer-php), adds an admin setting to choose the signature engine, and adjusts installation/configure-check behavior to avoid Java/JSignPdf requirements when not selected.

Changes:

  • Add a new PhpNativeHandler sign engine implementation and unit tests.
  • Add an admin UI setting to switch between JSignPdf and PHP native engines, and trigger configure-check refresh on change.
  • Add page-dimensions metadata (PageDimensions) into signature params for use by the PHP-native engine.

Reviewed changes

Copilot reviewed 15 out of 18 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
vendor-bin/rector/composer.lock Composer plugin-api-version lock update.
vendor-bin/phpunit/composer.lock Composer plugin-api-version lock update.
composer.json Adds VCS repository and requires jeidison/signer-php dev branch.
composer.lock Locks jeidison/signer-php dependency and updates content hash/stability flags.
lib/Handler/SignEngine/PhpNativeHandler.php Implements PHP-native PDF signing using signer-php, including appearance/timestamp/DocMDP handling.
lib/Handler/SignEngine/Pkcs12Handler.php Adds support for delegating to PhpNativeHandler based on signature_engine.
lib/Handler/SignEngine/JSignPdfHandler.php Uses SignerElementsService::RENDER_MODE_GRAPHIC_ONLY constant instead of raw string.
lib/Service/SignFileService.php Adds PageDimensions into signature params from file metadata.
lib/Service/Install/InstallService.php Skips Java/JSignPdf install steps depending on selected signature engine.
lib/Service/Install/ConfigureCheckService.php Skips JSignPdf checks when not selected signature engine.
lib/Service/SignerElementsService.php Adds RENDER_MODE_GRAPHIC_ONLY constant.
lib/Service/SignatureTextService.php Uses new render-mode constant when computing signature width.
lib/Settings/Admin.php Exposes signature_engine via initial-state for the admin UI.
src/views/Settings/SignatureEngine.vue New settings section to choose signature engine and persist to AppConfig.
src/views/Settings/Settings.vue Adds SignatureEngine to settings page (but currently breaks CollectMetadata registration).
src/store/configureCheck.js Subscribes to engine-changed events to rerun configure-check.
tests/php/Unit/Handler/SignEngine/PhpNativeHandlerTest.php New unit tests covering appearance/text wrapping/timestamp options/DocMDP behaviors.
tests/php/Unit/Service/SignFileServiceTest.php New unit test coverage for PageDimensions propagation into signature params.
Comments suppressed due to low confidence (1)

lib/Service/Install/ConfigureCheckService.php:392

  • When signature_engine is not JSignPdf, checkJSignPdf() now returns [], but checkSign() still always includes checkJava(). This can keep the configure-check in a permanent "need download" state due to Java errors even though Java/JSignPdf are intentionally disabled. Consider skipping checkJava() (or returning [] from it) when the configured signature engine is not JSignPdf, mirroring the logic added to checkJSignPdf().
	private function checkJava(): array {
		if (!empty($this->result['java'])) {
			return $this->result['java'];
		}

		$javaPath = $this->javaHelper->getJavaPath();
		if ($javaPath) {
			$resultOfVerify = $this->verify('java');
			if (count($resultOfVerify)) {

Comment on lines +963 to +966
$pageDimensions = $this->libreSignFile?->getMetadata()['d'] ?? [];
if (!empty($pageDimensions)) {
$signatureParams['PageDimensions'] = $pageDimensions;
}
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$this->libreSignFile?->getMetadata()['d'] can throw a TypeError when getMetadata() returns null (File::getMetadata() is nullable). This breaks signature param generation (and the new unit test case where metadata is unset). Consider fetching metadata into a variable first (defaulting to []) and then reading ['d'], or otherwise guarding with is_array() before offset access.

Copilot uses AI. Check for mistakes.
Comment on lines 38 to 68
@@ -63,7 +64,7 @@ export default {
components: {
AllowedGroups,
CertificateEngine,
CollectMetadata,
SignatureEngine,
ConfigureCheck,
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<CollectMetadata /> is still used in the template, but the CollectMetadata component is no longer imported/registered in this file. This will cause an unknown custom element/runtime error in the Settings page. Re-add the CollectMetadata import and include it in the components map (or remove it from the template if intentionally dropped).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 0. Needs triage

Development

Successfully merging this pull request may close these issues.

2 participants