pdftract/sdk/php/src/Pdftract/Models/Attachment.php
jedarden 246befd8d1 feat(pdftract-2m3gl): implement PHP SDK with Packagist publishing
- Add jedarden/pdftract Composer package (sdk/php/)
- Implement Client.php with proc_open subprocess execution
- Add PSR-3 LoggerInterface integration (defaults to NullLogger)
- Add 9 contract methods: extract, extractText, extractMarkdown, extractStream, search, getMetadata, hash, classify, verifyReceipt
- Add readonly model classes: Document, Page, Metadata, Fingerprint, Classification, Match, Receipt
- Add exception classes: PdftractException base + 8 subclasses
- Add PHPUnit conformance test suite
- Add phpunit.xml configuration
- Add composer.json with jedarden/pdftract package name
- Add .ci/argo-workflows/pdftract-php-publish.yaml (Packagist auto-discovery from git tags)

Also includes Ruby SDK scaffold from parallel workflow.

Closes pdftract-2m3gl
2026-06-01 10:27:03 -04:00

134 lines
3.6 KiB
PHP

<?php
declare(strict_types=1);
namespace Jedarden\Pdftract\Models;
/**
* JSON representation of an embedded file attachment
*
* Represents a single embedded file extracted from the PDF's
* `/EmbeddedFiles` name tree or `/AF` (Associated Files) array.
*/
class Attachment
{
/**
* Attachment filename from /UF (Unicode, preferred) or /F (system-independent)
*/
public string $name;
/**
* Description from /Desc (null if absent, not empty string)
*/
public ?string $description = null;
/**
* MIME type from stream /Subtype (null if absent, no guessing from extension)
*/
public ?string $mime_type = null;
/**
* Original decoded size in bytes (always populated, even when truncated)
*
* This is the size of the attachment content before base64 encoding.
* When `truncated: true`, this represents the full original size that
* was not included in the output.
*/
public int $size;
/**
* Creation date from /Params /CreationDate as ISO 8601 string (null if absent)
*/
public ?string $created = null;
/**
* Modification date from /Params /ModDate as ISO 8601 string (null if absent)
*/
public ?string $modified = null;
/**
* MD5 checksum from /Params /CheckSum as hex string (null if absent)
*
* Per PDF spec, /CheckSum is a 16-byte binary string (MD5), hex-encoded
* as 32 lowercase hex characters.
*/
public ?string $checksum_md5 = null;
/**
* Base64-encoded attachment content (null if truncated or empty)
*
* - Some(base64_string) when content <= 50 MB
* - None when `truncated: true` (content too large)
*/
public ?string $data = null;
/**
* Whether the attachment content was truncated due to the 50 MB size limit
*
* When true, the `data` field is null and only metadata is included.
* The `size` field still reflects the original full size.
*/
public bool $truncated;
/**
* Create Attachment from JSON array
*
* @param array<string,mixed> $data JSON data
* @return self
*/
public static function fromArray(array $data): self
{
$attachment = new self();
$attachment->name = $data['name'];
$attachment->description = $data['description'] ?? null;
$attachment->mime_type = $data['mime_type'] ?? null;
$attachment->size = $data['size'];
$attachment->created = $data['created'] ?? null;
$attachment->modified = $data['modified'] ?? null;
$attachment->checksum_md5 = $data['checksum_md5'] ?? null;
$attachment->data = $data['data'] ?? null;
$attachment->truncated = $data['truncated'] ?? false;
return $attachment;
}
/**
* Convert to JSON array
*
* @return array<string,mixed>
*/
public function toArray(): array
{
$data = [
'name' => $this->name,
'size' => $this->size,
'truncated' => $this->truncated,
];
if ($this->description !== null) {
$data['description'] = $this->description;
}
if ($this->mime_type !== null) {
$data['mime_type'] = $this->mime_type;
}
if ($this->created !== null) {
$data['created'] = $this->created;
}
if ($this->modified !== null) {
$data['modified'] = $this->modified;
}
if ($this->checksum_md5 !== null) {
$data['checksum_md5'] = $this->checksum_md5;
}
if ($this->data !== null) {
$data['data'] = $this->data;
}
return $data;
}
}