From 0d6a21506f2aef1170348a654477095872418739 Mon Sep 17 00:00:00 2001 From: Christian Fasching Date: Mon, 18 Nov 2024 08:32:49 +0100 Subject: [PATCH] Added support for PDFreactor 11 (#89) * added support for PDFreactor 11 * Apply php-cs-fixer changes * fixed tests * Apply php-cs-fixer changes * restore license of pdfreactor client * Apply php-cs-fixer changes * fix version constant for PDFreactor 10 compatibility * Apply php-cs-fixer changes * restore PDFreactor.class.php * Apply php-cs-fixer changes * restore PDFreactor.class.php * Apply php-cs-fixer changes * restore PDFreactor.class.php * Apply php-cs-fixer changes * restore PDFreactor.class.php * Apply php-cs-fixer changes * restore PDFreactor.class.php * Apply php-cs-fixer changes * restore PDFreactor.class.php * Apply php-cs-fixer changes * restore PDFreactor.class.php * restore PDFreactor.class.php --- .php-cs-fixer.dist.php | 4 + doc/01_Doc_Types_and_Available_Processors.md | 10 +- src/Controller/SettingsController.php | 8 +- src/Processor/Api/PDFreactor.class.php | 4017 +++++++++++------- src/Processor/PdfReactor.php | 35 +- tests/Model/Processor/ProcessorTest.php | 8 +- 6 files changed, 2632 insertions(+), 1450 deletions(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index d6bb1ca..f332d0b 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -12,6 +12,10 @@ __DIR__ . '/tests/Support/_generated', __DIR__ . '/src/Processor/Api/PDFreactor.class.php', ]) + + ->notPath([ + 'Processor/Api/PDFreactor.class.php' + ]) ; // do not enable self_accessor as it breaks pimcore models relying on get_called_class() diff --git a/doc/01_Doc_Types_and_Available_Processors.md b/doc/01_Doc_Types_and_Available_Processors.md index acfcb70..951bb42 100644 --- a/doc/01_Doc_Types_and_Available_Processors.md +++ b/doc/01_Doc_Types_and_Available_Processors.md @@ -9,11 +9,11 @@ This bundle introduces 2 new document types: ## Available PDF Processors -| Name | Description | -|----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Chromium](https://www.chromium.org/Home/) | Convert to PDF by installing the Chromium binary or by using a dockerized chromium (via websocket) | -| [Gotenberg](https://gotenberg.dev/) | A Docker service with Chromium and LibreOffice support | -| [PDF Reactor](https://www.pdfreactor.com/) | A REST/SOAP solution, please visit the official website for further information | +| Name | Description | +|----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [Chromium](https://www.chromium.org/Home/) | Convert to PDF by installing the Chromium binary or by using a dockerized chromium (via websocket) | +| [Gotenberg](https://gotenberg.dev/) | A Docker service with Chromium and LibreOffice support | +| [PDF Reactor](https://www.pdfreactor.com/) | A REST solution for rendering complex catalogs, please visit the official website for further information. Currently Pimcore supports PDFreactor 10, 11, 12 | > For details on how to install and configure these processors, please see [Additional Tools Installation](https://pimcore.com/docs/platform/Pimcore/Installation_and_Upgrade/System_Setup_and_Hosting/Additional_Tools_Installation) page in the Core. diff --git a/src/Controller/SettingsController.php b/src/Controller/SettingsController.php index 5a685a7..9bfc26d 100644 --- a/src/Controller/SettingsController.php +++ b/src/Controller/SettingsController.php @@ -95,10 +95,14 @@ public function testWeb2printAction(Request $request): Response if ($adapter instanceof PdfReactor) { $params['adapterConfig'] = [ - 'javaScriptMode' => 0, + 'javaScriptSettings' => [ + 'enabled' => false, + ], 'addLinks' => true, 'appendLog' => true, - 'enableDebugMode' => true, + 'debugSettings' => [ + 'all' => true, + ], ]; } elseif ($adapter instanceof Gotenberg) { $params = Config::getWeb2PrintConfig(); diff --git a/src/Processor/Api/PDFreactor.class.php b/src/Processor/Api/PDFreactor.class.php index 88a34ba..9ee6428 100644 --- a/src/Processor/Api/PDFreactor.class.php +++ b/src/Processor/Api/PDFreactor.class.php @@ -1,1641 +1,2794 @@ url = $url; if ($url == null) { - $this->url = 'http://localhost:9423/service/rest'; + $this->url = "http://localhost:9423/service/rest"; } - if (substr($this->url, -1) == '/') { + if (substr($this->url, -1) == "/") { $this->url = substr($this->url, 0, -1); } $this->apiKey = null; } - public function convert($config, & $connectionSettings = null) - { - $url = $this->url .'/convert.json'; - if (!is_null($this->apiKey)) { - $url .= '?apiKey=' . $this->apiKey; - } - if (!is_null($config)) { - $config['clientName'] = 'PHP'; - $config['clientVersion'] = PDFreactor::VERSION; - } - $headerStr = ''; - $cookieStr = ''; - if (!empty($connectionSettings) && !empty($connectionSettings['headers'])) { - foreach ($connectionSettings['headers'] as $name => $value) { - $lcName = strtolower($name); - if ($lcName !== 'user-agent' && $lcName !== 'content-type' && $lcName !== 'range') { - $headerStr .= $name . ': ' . $value . "\r\n"; - } - } - } - if (!empty($connectionSettings) && !empty($connectionSettings['cookies'])) { - foreach ($connectionSettings['cookies'] as $name => $value) { - $cookieStr .= $name . '=' . $value . '; '; + /** + * Converts the specified configuration into PDF or image and returns the generated PDF or image. + * @param Configuration $configuration The configuration object. + * @param array $connectionSettings The connection settings object. + * @return Result The result object containing the converted document and metadata. + * @throws PDFreactorWebserviceException If an issue occurred while attempting to connect to the service. + */ + public function convert($config, &$connectionSettings = null) { + $this->prepareConfiguration($config); + try { + $responseData = $this->createConnectionWithData('convert.json', $connectionSettings, false, false, false, false, $config); + $status = $responseData["status"]; + if ($status == null || $status <= 0) { + throw $this->createAnonymousClientException($responseData["error"]); } - } - $headerStr .= "Content-Type: application/json\r\n"; - $headerStr .= "User-Agent: PDFreactor PHP API v8\r\n"; - $headerStr .= "X-RO-User-Agent: PDFreactor PHP API v8\r\n"; - if (!empty($connectionSettings) || !empty($cookieStr)) { - $headerStr .= 'Cookie: ' . substr($cookieStr, 0, -2); - } - $options = [ - 'http' => [ - 'header' => $headerStr, - 'follow_location' => false, - 'max_redirects' => 0, - 'method' => 'POST', - 'content' => json_encode($config), - 'ignore_errors' => true, - ], - ]; - $context = stream_context_create($options); - $result = null; - $errorMode = true; - $rh = fopen($url, 'r', false, $context); - if (!isset($http_response_header)) { - $lastError = error_get_last(); - - throw new UnreachableServiceException('Error connecting to PDFreactor Web Service at ' . $this->url . '. Please make sure the PDFreactor Web Service is installed and running (Error: ' . $lastError['message'] . ')'); - } - $status = intval(substr($http_response_header[0], 9, 3)); - if ($status >= 200 && $status <= 204) { - $errorMode = false; - } - if (!$errorMode) { - $result = json_decode(stream_get_contents($rh)); - } - fclose($rh); - $errorId = null; - if ($errorMode) { - foreach ($http_response_header as $header) { - $t = explode(':', $header, 2); - if (isset($t[1])) { - $headerName = trim($t[0]); - if ($headerName == 'X-RO-Error-ID') { - $errorId = trim($t[1]); - } + if ($responseData["errorMode"]) { + switch ($status) { + case 422: + throw $this->createServerException($responseData); + case 400: + throw $this->createServerException($responseData, PDFreactor::ERROR_400); + case 401: + throw $this->createServerException($responseData, PDFreactor::ERROR_401); + case 413: + throw $this->createServerException($responseData, PDFreactor::ERROR_413); + case 429: + throw $this->createServerException($responseData, PDFreactor::ERROR_429); + case 500: + throw $this->createServerException($responseData); + case 503: + throw $this->createServerException($responseData, PDFreactor::ERROR_503); + default: + throw $this->createAnonymousServerException($status); } } + return json_decode($responseData["data"]); + } catch (Exception $e) { + if ($e instanceof PDFreactorWebserviceException) { + throw $e; + } + throw $this->createAnonymousClientException($e->message, $e); } - if ($status == 422) { - throw $this->_createServerException($errorId, $result->error, $result); - } elseif ($status == 400) { - throw $this->_createServerException($errorId, 'Invalid client data. '.$result->error, $result); - } elseif ($status == 401) { - throw $this->_createServerException($errorId, 'Unauthorized. '.$result->error, $result); - } elseif ($status == 413) { - throw $this->_createServerException($errorId, 'The configuration is too large to process.', $result); - } elseif ($status == 500) { - throw $this->_createServerException($errorId, $result->error, $result); - } elseif ($status == 503) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service is unavailable.', $result); - } elseif ($status > 400) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service error (status: ' . $status . ').', $result); - } - - return $result; } - - public function convertAsBinary($config, & $wh = null, & $connectionSettings = null): bool|string|null - { - $url = $this->url .'/convert.bin'; - if (!is_null($this->apiKey)) { - $url .= '?apiKey=' . $this->apiKey; - } - if (!is_null($config)) { - $config['clientName'] = 'PHP'; - $config['clientVersion'] = PDFreactor::VERSION; - } + /** + * Converts the specified configuration into PDF or image. Writes the result in the specified stream. If no stream is specified, returns the result instead. + * @param Configuration $configuration The configuration object. + * @param resource $wh The stream to write into. + * @param array $connectionSettings The connection settings object. + * @return byte[]|void The converted document as binary data. No data is returned if a stream parameter was specified. + * @throws PDFreactorWebserviceException If an issue occurred while attempting to connect to the service. + */ + public function convertAsBinary($config, &$writeHandle = null, &$connectionSettings = null) { + $this->prepareConfiguration($config); $useStream = true; - if (is_array($wh)) { - $connectionSettings = $wh; + if ($writeHandle == NULL || is_array ($writeHandle)) { + $connectionSettings = $writeHandle; + $writeHandle = null; $useStream = false; } - $headerStr = ''; - $cookieStr = ''; - if (!empty($connectionSettings) && !empty($connectionSettings['headers'])) { - foreach ($connectionSettings['headers'] as $name => $value) { - $lcName = strtolower($name); - if ($lcName !== 'user-agent' && $lcName !== 'content-type' && $lcName !== 'range') { - $headerStr .= $name . ': ' . $value . "\r\n"; + try { + $responseData = $this->createConnectionWithData('convert.bin', $connectionSettings, true, false, false, false, $config, $writeHandle); + $status = $responseData["status"]; + if ($status == null || $status <= 0) { + throw $this->createAnonymousClientException($responseData["error"]); + } + if ($responseData["errorMode"]) { + switch ($status) { + case 422: + throw $this->createServerException($responseData); + case 400: + throw $this->createServerException($responseData, PDFreactor::ERROR_400); + case 401: + throw $this->createServerException($responseData, PDFreactor::ERROR_401); + case 413: + throw $this->createServerException($responseData, PDFreactor::ERROR_413); + case 429: + throw $this->createServerException($responseData, PDFreactor::ERROR_429); + case 500: + throw $this->createServerException($responseData); + case 503: + throw $this->createServerException($responseData, PDFreactor::ERROR_503); + default: + throw $this->createAnonymousServerException($status); } } - } - if (!empty($connectionSettings) && !empty($connectionSettings['cookies'])) { - foreach ($connectionSettings['cookies'] as $name => $value) { - $cookieStr .= $name . '=' . $value . '; '; + if (!$useStream) { + return $responseData["data"]; } + } catch (Exception $e) { + if ($e instanceof PDFreactorWebserviceException) { + throw $e; + } + throw $this->createAnonymousClientException($e->message, $e); } - $headerStr .= "Content-Type: application/json\r\n"; - $headerStr .= "User-Agent: PDFreactor PHP API v8\r\n"; - $headerStr .= "X-RO-User-Agent: PDFreactor PHP API v8\r\n"; - if (!empty($connectionSettings) || !empty($cookieStr)) { - $headerStr .= 'Cookie: ' . substr($cookieStr, 0, -2); - } - $options = [ - 'http' => [ - 'header' => $headerStr, - 'follow_location' => false, - 'max_redirects' => 0, - 'method' => 'POST', - 'content' => json_encode($config), - 'ignore_errors' => true, - ], - ]; - $context = stream_context_create($options); - $result = null; - $errorMode = true; - $rh = fopen($url, 'r', false, $context); - if (!isset($http_response_header)) { - $lastError = error_get_last(); - - throw new UnreachableServiceException('Error connecting to PDFreactor Web Service at ' . $this->url . '. Please make sure the PDFreactor Web Service is installed and running (Error: ' . $lastError['message'] . ')'); - } - $status = intval(substr($http_response_header[0], 9, 3)); - if ($status >= 200 && $status <= 204) { - $errorMode = false; - } - if (!$errorMode && ($wh == null || !$useStream)) { - $result = stream_get_contents($rh); - fclose($rh); - } - $errorId = null; - if ($errorMode) { - foreach ($http_response_header as $header) { - $t = explode(':', $header, 2); - if (isset($t[1])) { - $headerName = trim($t[0]); - if ($headerName == 'X-RO-Error-ID') { - $errorId = trim($t[1]); - } + } + /** + * Converts the specified configuration into PDF or image. This operation responds immediately and does not wait for the conversion to finish. This is especially useful for very large or complex documents where the conversion will take some time. + * @param Configuration $configuration The configuration object. + * @param array $connectionSettings The connection settings object. + * @return Result A URL to determine the progress of the conversion is contained in the 'Location' response header. + * @throws PDFreactorWebserviceException If an issue occurred while attempting to connect to the service. + */ + public function convertAsync($config, &$connectionSettings = null) { + $this->prepareConfiguration($config); + try { + $responseData = $this->createConnectionWithData('convert/async.json', $connectionSettings, false, false, false, true, $config); + $status = $responseData["status"]; + if ($status == null || $status <= 0) { + throw $this->createAnonymousClientException($responseData["error"]); + } + if ($responseData["errorMode"]) { + switch ($status) { + case 422: + throw $this->createServerException($responseData); + case 400: + throw $this->createServerException($responseData, PDFreactor::ERROR_400); + case 401: + throw $this->createServerException($responseData, PDFreactor::ERROR_401); + case 413: + throw $this->createServerException($responseData, PDFreactor::ERROR_413); + case 429: + throw $this->createServerException($responseData, PDFreactor::ERROR_429); + case 500: + throw $this->createServerException($responseData); + case 503: + throw $this->createServerException($responseData, PDFreactor::ASYNC_503); + default: + throw $this->createAnonymousServerException($status); } } + return $responseData["documentId"]; + } catch (Exception $e) { + if ($e instanceof PDFreactorWebserviceException) { + throw $e; + } + throw $this->createAnonymousClientException($e->message, $e); } - if ($status == 422) { - throw $this->_createServerException($errorId, $result); - } elseif ($status == 400) { - throw $this->_createServerException($errorId, 'Invalid client data. '.$result); - } elseif ($status == 401) { - throw $this->_createServerException($errorId, 'Unauthorized. '.$result); - } elseif ($status == 413) { - throw $this->_createServerException($errorId, 'The configuration is too large to process.'); - } elseif ($status == 500) { - throw $this->_createServerException($errorId, $result); - } elseif ($status == 503) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service is unavailable.'); - } elseif ($status > 400) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service error (status: ' . $status . ').'); + } + /** + * Converts the specified configuration into PDF or image. Writes the result in the specified stream. If no stream is specified, returns the result instead. + * @param string $documentId The document ID. + * @param array $connectionSettings The connection settings object. + * @return Progress The progress object containing information about the progress of the document conversion. When the conversion is finished, a URL to download the conversion result is contained in the 'Location' response header. + * @throws PDFreactorWebserviceException If an issue occurred while attempting to connect to the service. + */ + public function getProgress($documentId, &$connectionSettings = null) { + if (is_null($documentId)) { + throw new ClientException("No conversion was triggered."); } - if (!$errorMode && $wh != null && $useStream) { - while (!feof($rh)) { - if (fwrite($wh, fread($rh, 1024)) === false) { - return null; + try { + $responseData = $this->createConnection("progress/{$documentId}.json", $connectionSettings, false, false, false, false); + $status = $responseData["status"]; + if ($status == null || $status <= 0) { + throw $this->createAnonymousClientException($responseData["error"]); + } + if ($responseData["errorMode"]) { + switch ($status) { + case 422: + throw $this->createServerException($responseData); + case 404: + throw $this->createServerException($responseData, PDFreactor::ERROR_404); + case 401: + throw $this->createServerException($responseData, PDFreactor::ERROR_401); + case 429: + throw $this->createServerException($responseData, PDFreactor::ERROR_429); + case 503: + throw $this->createServerException($responseData, PDFreactor::ERROR_503); + default: + throw $this->createAnonymousServerException($status); } } - fclose($rh); - fclose($wh); + return json_decode($responseData["data"]); + } catch (Exception $e) { + if ($e instanceof PDFreactorWebserviceException) { + throw $e; + } + throw $this->createAnonymousClientException($e->message, $e); } - - return $result; } - - public function convertAsync($config, & $connectionSettings = null): ?string - { - $documentId = null; - $url = $this->url .'/convert/async.json'; - if (!is_null($this->apiKey)) { - $url .= '?apiKey=' . $this->apiKey; - } - if (!is_null($config)) { - $config['clientName'] = 'PHP'; - $config['clientVersion'] = PDFreactor::VERSION; + /** + * Retrieves the asynchronously converted document with the given ID. + * @param string $documentId The document ID. + * @param array $connectionSettings The connection settings object. + * @return Result The result object containing the converted document and metadata. + * @throws PDFreactorWebserviceException If an issue occurred while attempting to connect to the service. + */ + public function getDocument($documentId, &$connectionSettings = null) { + if (is_null($documentId)) { + throw new ClientException("No conversion was triggered."); } - $headerStr = ''; - $cookieStr = ''; - if (!empty($connectionSettings) && !empty($connectionSettings['headers'])) { - foreach ($connectionSettings['headers'] as $name => $value) { - $lcName = strtolower($name); - if ($lcName !== 'user-agent' && $lcName !== 'content-type' && $lcName !== 'range') { - $headerStr .= $name . ': ' . $value . "\r\n"; + try { + $responseData = $this->createConnection("document/{$documentId}.json", $connectionSettings, false, false, false, false); + $status = $responseData["status"]; + if ($status == null || $status <= 0) { + throw $this->createAnonymousClientException($responseData["error"]); + } + if ($responseData["errorMode"]) { + switch ($status) { + case 422: + throw $this->createServerException($responseData); + case 404: + throw $this->createServerException($responseData, PDFreactor::ERROR_404); + case 401: + throw $this->createServerException($responseData, PDFreactor::ERROR_401); + case 429: + throw $this->createServerException($responseData, PDFreactor::ERROR_429); + case 503: + throw $this->createServerException($responseData, PDFreactor::ERROR_503); + default: + throw $this->createAnonymousServerException($status); } } - } - if (!empty($connectionSettings) && !empty($connectionSettings['cookies'])) { - foreach ($connectionSettings['cookies'] as $name => $value) { - $cookieStr .= $name . '=' . $value . '; '; + return json_decode($responseData["data"]); + } catch (Exception $e) { + if ($e instanceof PDFreactorWebserviceException) { + throw $e; } + throw $this->createAnonymousClientException($e->message, $e); } - $headerStr .= "Content-Type: application/json\r\n"; - $headerStr .= "User-Agent: PDFreactor PHP API v8\r\n"; - $headerStr .= "X-RO-User-Agent: PDFreactor PHP API v8\r\n"; - if (!empty($connectionSettings) || !empty($cookieStr)) { - $headerStr .= 'Cookie: ' . substr($cookieStr, 0, -2); - } - $options = [ - 'http' => [ - 'header' => $headerStr, - 'follow_location' => false, - 'max_redirects' => 0, - 'method' => 'POST', - 'content' => json_encode($config), - 'ignore_errors' => true, - ], - ]; - $context = stream_context_create($options); - $result = null; - $errorMode = true; - $rh = fopen($url, 'r', false, $context); - if (!isset($http_response_header)) { - $lastError = error_get_last(); - - throw new UnreachableServiceException('Error connecting to PDFreactor Web Service at ' . $this->url . '. Please make sure the PDFreactor Web Service is installed and running (Error: ' . $lastError['message'] . ')'); - } - $status = intval(substr($http_response_header[0], 9, 3)); - if ($status >= 200 && $status <= 204) { - $errorMode = false; + } + /** + * Retrieves the asynchronously converted document with the given ID. Writes the result in the specified stream. If no stream is specified, returns the result instead. + * @param Configuration $configuration The configuration object. + * @param resource $wh The stream to write into. + * @param array $connectionSettings The connection settings object. + * @return byte[]|void The converted document as binary data. No data is returned if a stream parameter was specified. + * @throws PDFreactorWebserviceException If an issue occurred while attempting to connect to the service. + */ + public function getDocumentAsBinary($documentId, &$writeHandle = null, &$connectionSettings = null) { + if (is_null($documentId)) { + throw new ClientException("No conversion was triggered."); } - if (!$errorMode) { - $result = json_decode(stream_get_contents($rh)); + $useStream = true; + if ($writeHandle == NULL || is_array ($writeHandle)) { + $connectionSettings = $writeHandle; + $writeHandle = null; + $useStream = false; } - fclose($rh); - $errorId = null; - if ($errorMode) { - foreach ($http_response_header as $header) { - $t = explode(':', $header, 2); - if (isset($t[1])) { - $headerName = trim($t[0]); - if ($headerName == 'X-RO-Error-ID') { - $errorId = trim($t[1]); - } - } + try { + $responseData = $this->createConnection("document/{$documentId}.bin", $connectionSettings, true, false, false, false, $writeHandle); + $status = $responseData["status"]; + if ($status == null || $status <= 0) { + throw $this->createAnonymousClientException($responseData["error"]); } - } - if ($status == 422) { - throw $this->_createServerException($errorId, $result->error, $result); - } elseif ($status == 400) { - throw $this->_createServerException($errorId, 'Invalid client data. '.$result->error, $result); - } elseif ($status == 401) { - throw $this->_createServerException($errorId, 'Unauthorized. '.$result->error, $result); - } elseif ($status == 413) { - throw $this->_createServerException($errorId, 'The configuration is too large to process.', $result); - } elseif ($status == 500) { - throw $this->_createServerException($errorId, $result->error, $result); - } elseif ($status == 503) { - throw $this->_createServerException($errorId, 'Asynchronous conversions are unavailable.', $result); - } elseif ($status > 400) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service error (status: ' . $status . ').', $result); - } - foreach ($http_response_header as $header) { - $t = explode(':', $header, 2); - if (isset($t[1])) { - $headerName = trim($t[0]); - if ($headerName == 'Location') { - $documentId = trim(substr($t[1], strrpos($t[1], '/') + 1)); + if ($responseData["errorMode"]) { + switch ($status) { + case 422: + throw $this->createServerException($responseData); + case 404: + throw $this->createServerException($responseData, PDFreactor::ERROR_404); + case 401: + throw $this->createServerException($responseData, PDFreactor::ERROR_401); + case 429: + throw $this->createServerException($responseData, PDFreactor::ERROR_429); + case 503: + throw $this->createServerException($responseData, PDFreactor::ERROR_503); + default: + throw $this->createAnonymousServerException($status); } } - if (preg_match('/^Set-Cookie:\s*([^;]+)/', $header, $matches)) { - parse_str($matches[1], $tmp); - $keepDocument = false; - if (isset($config->{'keepDocument'})) { - $keepDocument = $config->{'keepDocument'}; - } - if (isset($connectionSettings)) { - if (empty($connectionSettings['cookies'])) { - $connectionSettings['cookies'] = []; - } - foreach ($tmp as $name => $value) { - $connectionSettings['cookies'][$name] = $value; - } - } + if (!$useStream) { + return $responseData["data"]; + } + } catch (Exception $e) { + if ($e instanceof PDFreactorWebserviceException) { + throw $e; } + throw $this->createAnonymousClientException($e->message, $e); } - - return $documentId; } - - public function getProgress($documentId, & $connectionSettings = null) - { + /** + * Retrieves the metadata of the asynchronously converted document with the given ID. + * @param string $documentId The document ID. + * @param array $connectionSettings The connection settings object. + * @return Result The result object containing the converted document and metadata. + * @throws PDFreactorWebserviceException If an issue occurred while attempting to connect to the service. + */ + public function getDocumentMetadata($documentId, &$connectionSettings = null) { if (is_null($documentId)) { - throw new ClientException('No conversion was triggered.'); - } - $url = $this->url .'/progress/' . $documentId . '.json'; - if (!is_null($this->apiKey)) { - $url .= '?apiKey=' . $this->apiKey; + throw new ClientException("No conversion was triggered."); } - $headerStr = ''; - $cookieStr = ''; - if (!empty($connectionSettings) && !empty($connectionSettings['headers'])) { - foreach ($connectionSettings['headers'] as $name => $value) { - $lcName = strtolower($name); - if ($lcName !== 'user-agent' && $lcName !== 'content-type' && $lcName !== 'range') { - $headerStr .= $name . ': ' . $value . "\r\n"; + try { + $responseData = $this->createConnection("document/metadata/{$documentId}.json", $connectionSettings, false, false, false, false); + $status = $responseData["status"]; + if ($status == null || $status <= 0) { + throw $this->createAnonymousClientException($responseData["error"]); + } + if ($responseData["errorMode"]) { + switch ($status) { + case 422: + throw $this->createServerException($responseData); + case 404: + throw $this->createServerException($responseData, PDFreactor::ERROR_404); + case 401: + throw $this->createServerException($responseData, PDFreactor::ERROR_401); + case 429: + throw $this->createServerException($responseData, PDFreactor::ERROR_429); + case 503: + throw $this->createServerException($responseData, PDFreactor::ERROR_503); + default: + throw $this->createAnonymousServerException($status); } } - } - if (!empty($connectionSettings) && !empty($connectionSettings['cookies'])) { - foreach ($connectionSettings['cookies'] as $name => $value) { - $cookieStr .= $name . '=' . $value . '; '; + return json_decode($responseData["data"]); + } catch (Exception $e) { + if ($e instanceof PDFreactorWebserviceException) { + throw $e; } + throw $this->createAnonymousClientException($e->message, $e); } - $headerStr .= "Content-Type: application/json\r\n"; - $headerStr .= "User-Agent: PDFreactor PHP API v8\r\n"; - $headerStr .= "X-RO-User-Agent: PDFreactor PHP API v8\r\n"; - if (!empty($connectionSettings) || !empty($cookieStr)) { - $headerStr .= 'Cookie: ' . substr($cookieStr, 0, -2); - } - $options = [ - 'http' => [ - 'header' => $headerStr, - 'follow_location' => false, - 'max_redirects' => 0, - 'method' => 'GET', - 'ignore_errors' => true, - ], - ]; - $context = stream_context_create($options); - $result = null; - $errorMode = true; - $rh = fopen($url, 'r', false, $context); - if (!isset($http_response_header)) { - $lastError = error_get_last(); - - throw new UnreachableServiceException('Error connecting to PDFreactor Web Service at ' . $this->url . '. Please make sure the PDFreactor Web Service is installed and running (Error: ' . $lastError['message'] . ')'); - } - $status = intval(substr($http_response_header[0], 9, 3)); - if ($status >= 200 && $status <= 204) { - $errorMode = false; - } - if (!$errorMode) { - $result = json_decode(stream_get_contents($rh)); - } - fclose($rh); - $errorId = null; - if ($errorMode) { - foreach ($http_response_header as $header) { - $t = explode(':', $header, 2); - if (isset($t[1])) { - $headerName = trim($t[0]); - if ($headerName == 'X-RO-Error-ID') { - $errorId = trim($t[1]); - } + } + /** + * Converts the specified asset package into PDF or image and returns the generated PDF or image. + * @param resource $assetPackage The input stream for the Asset Package. + * @param array $connectionSettings The connection settings object. + * @return Result The result object containing the converted document and metadata. + * @throws PDFreactorWebserviceException If an issue occurred while attempting to connect to the service. + */ + public function convertAssetPackage(&$assetPackage, &$connectionSettings = null) { + try { + $responseData = $this->createConnectionWithData('convert.json', $connectionSettings, false, true, false, false, $assetPackage); + $status = $responseData["status"]; + if ($status == null || $status <= 0) { + throw $this->createAnonymousClientException($responseData["error"]); + } + if ($responseData["errorMode"]) { + switch ($status) { + case 422: + throw $this->createServerException($responseData); + case 400: + throw $this->createServerException($responseData, PDFreactor::ERROR_400); + case 401: + throw $this->createServerException($responseData, PDFreactor::ERROR_401); + case 413: + throw $this->createServerException($responseData, PDFreactor::ERROR_413); + case 429: + throw $this->createServerException($responseData, PDFreactor::ERROR_429); + case 500: + throw $this->createServerException($responseData); + case 503: + throw $this->createServerException($responseData, PDFreactor::ERROR_503); + default: + throw $this->createAnonymousServerException($status); } } + return json_decode($responseData["data"]); + } catch (Exception $e) { + if ($e instanceof PDFreactorWebserviceException) { + throw $e; + } + throw $this->createAnonymousClientException($e->message, $e); } - if ($status == 422) { - throw $this->_createServerException($errorId, $result->error, $result); - } elseif ($status == 404) { - throw $this->_createServerException($errorId, 'Document with the given ID was not found. '.$result->error, $result); - } elseif ($status == 401) { - throw $this->_createServerException($errorId, 'Unauthorized. '.$result->error, $result); - } elseif ($status == 503) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service is unavailable.', $result); - } elseif ($status > 400) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service error (status: ' . $status . ').', $result); - } - - return $result; } - - public function getDocument($documentId, & $connectionSettings = null) - { - if (is_null($documentId)) { - throw new ClientException('No conversion was triggered.'); - } - $url = $this->url .'/document/' . $documentId . '.json'; - if (!is_null($this->apiKey)) { - $url .= '?apiKey=' . $this->apiKey; + /** + * Converts the specified asset package into PDF or image. Writes the result in the specified stream. If no stream is specified, returns the result instead. + * @param resource $assetPackage The input stream for the Asset Package. + * @param resource $wh The stream to write into. + * @param array $connectionSettings The connection settings object. + * @return byte[]|void The converted document as binary data. No data is returned if a stream parameter was specified. + * @throws PDFreactorWebserviceException If an issue occurred while attempting to connect to the service. + */ + public function convertAssetPackageAsBinary(&$assetPackage, &$writeHandle = null, &$connectionSettings = null) { + $useStream = true; + if ($writeHandle == NULL || is_array ($writeHandle)) { + $connectionSettings = $writeHandle; + $writeHandle = null; + $useStream = false; } - $headerStr = ''; - $cookieStr = ''; - if (!empty($connectionSettings) && !empty($connectionSettings['headers'])) { - foreach ($connectionSettings['headers'] as $name => $value) { - $lcName = strtolower($name); - if ($lcName !== 'user-agent' && $lcName !== 'content-type' && $lcName !== 'range') { - $headerStr .= $name . ': ' . $value . "\r\n"; + try { + $responseData = $this->createConnectionWithData('convert.bin', $connectionSettings, true, true, false, false, $assetPackage, $writeHandle); + $status = $responseData["status"]; + if ($status == null || $status <= 0) { + throw $this->createAnonymousClientException($responseData["error"]); + } + if ($responseData["errorMode"]) { + switch ($status) { + case 422: + throw $this->createServerException($responseData); + case 400: + throw $this->createServerException($responseData, PDFreactor::ERROR_400); + case 401: + throw $this->createServerException($responseData, PDFreactor::ERROR_401); + case 413: + throw $this->createServerException($responseData, PDFreactor::ERROR_413); + case 429: + throw $this->createServerException($responseData, PDFreactor::ERROR_429); + case 500: + throw $this->createServerException($responseData); + case 503: + throw $this->createServerException($responseData, PDFreactor::ERROR_503); + default: + throw $this->createAnonymousServerException($status); } } - } - if (!empty($connectionSettings) && !empty($connectionSettings['cookies'])) { - foreach ($connectionSettings['cookies'] as $name => $value) { - $cookieStr .= $name . '=' . $value . '; '; + if (!$useStream) { + return $responseData["data"]; } + } catch (Exception $e) { + if ($e instanceof PDFreactorWebserviceException) { + throw $e; + } + throw $this->createAnonymousClientException($e->message, $e); } - $headerStr .= "Content-Type: application/json\r\n"; - $headerStr .= "User-Agent: PDFreactor PHP API v8\r\n"; - $headerStr .= "X-RO-User-Agent: PDFreactor PHP API v8\r\n"; - if (!empty($connectionSettings) || !empty($cookieStr)) { - $headerStr .= 'Cookie: ' . substr($cookieStr, 0, -2); - } - $options = [ - 'http' => [ - 'header' => $headerStr, - 'follow_location' => false, - 'max_redirects' => 0, - 'method' => 'GET', - 'ignore_errors' => true, - ], - ]; - $context = stream_context_create($options); - $result = null; - $errorMode = true; - $rh = fopen($url, 'r', false, $context); - if (!isset($http_response_header)) { - $lastError = error_get_last(); - - throw new UnreachableServiceException('Error connecting to PDFreactor Web Service at ' . $this->url . '. Please make sure the PDFreactor Web Service is installed and running (Error: ' . $lastError['message'] . ')'); - } - $status = intval(substr($http_response_header[0], 9, 3)); - if ($status >= 200 && $status <= 204) { - $errorMode = false; - } - if (!$errorMode) { - $result = json_decode(stream_get_contents($rh)); - } - fclose($rh); - $errorId = null; - if ($errorMode) { - foreach ($http_response_header as $header) { - $t = explode(':', $header, 2); - if (isset($t[1])) { - $headerName = trim($t[0]); - if ($headerName == 'X-RO-Error-ID') { - $errorId = trim($t[1]); - } + } + /** + * Converts the specified asset package into PDF or image. This operation responds immediately and does not wait for the conversion to finish. This is especially useful for very large or complex documents where the conversion will take some time. + * @param resource $assetPackage The input stream for the Asset Package. + * @param resource $wh The stream to write into. + * @param array $connectionSettings The connection settings object. + * @return documentId A URL to determine the progress of the conversion is contained in the 'Location' response header. + * @throws PDFreactorWebserviceException If an issue occurred while attempting to connect to the service. + */ + public function convertAssetPackageAsync(&$assetPackage, &$connectionSettings = null) { + try { + $responseData = $this->createConnectionWithData('convert/async.json', $connectionSettings, false, true, false, true, $assetPackage); + $status = $responseData["status"]; + if ($status == null || $status <= 0) { + throw $this->createAnonymousClientException($responseData["error"]); + } + if ($responseData["errorMode"]) { + switch ($status) { + case 422: + throw $this->createServerException($responseData); + case 400: + throw $this->createServerException($responseData, PDFreactor::ERROR_400); + case 401: + throw $this->createServerException($responseData, PDFreactor::ERROR_401); + case 413: + throw $this->createServerException($responseData, PDFreactor::ERROR_413); + case 429: + throw $this->createServerException($responseData, PDFreactor::ERROR_429); + case 500: + throw $this->createServerException($responseData); + case 503: + throw $this->createServerException($responseData, PDFreactor::ASYNC_503); + default: + throw $this->createAnonymousServerException($status); } } + return $responseData["documentId"]; + } catch (Exception $e) { + if ($e instanceof PDFreactorWebserviceException) { + throw $e; + } + throw $this->createAnonymousClientException($e->message, $e); } - if ($status == 422) { - throw $this->_createServerException($errorId, $result->error, $result); - } elseif ($status == 404) { - throw $this->_createServerException($errorId, 'Document with the given ID was not found. '.$result->error, $result); - } elseif ($status == 401) { - throw $this->_createServerException($errorId, 'Unauthorized. '.$result->error, $result); - } elseif ($status == 503) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service is unavailable.', $result); - } elseif ($status > 400) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service error (status: ' . $status . ').', $result); - } - - return $result; } - - public function getDocumentAsBinary($documentId, & $wh = null, & $connectionSettings = null): bool|string|null - { + /** + * Retrieves the asynchronously converted page of a multi-image with the given ID and page number. Writes the result in the specified stream. If no stream is specified, returns the result instead. + * @param string $documentId The document ID. + * @param int $pageNumber The page number. + * @param resource $wh The stream to write into. + * @param array $connectionSettings The connection settings object. + * @return byte[]|void The converted document as binary data. No data is returned if a stream parameter was specified. + * @throws PDFreactorWebserviceException If an issue occurred while attempting to connect to the service. + */ + public function getDocumentPageAsBinary($documentId, $pageNumber, &$writeHandle = null, &$connectionSettings = null) { if (is_null($documentId)) { - throw new ClientException('No conversion was triggered.'); - } - $url = $this->url .'/document/' . $documentId . '.bin'; - if (!is_null($this->apiKey)) { - $url .= '?apiKey=' . $this->apiKey; + throw new ClientException("No conversion was triggered."); } $useStream = true; - if (is_array($wh)) { - $connectionSettings = $wh; + if ($writeHandle == NULL || is_array ($writeHandle)) { + $connectionSettings = $writeHandle; + $writeHandle = null; $useStream = false; } - $headerStr = ''; - $cookieStr = ''; - if (!empty($connectionSettings) && !empty($connectionSettings['headers'])) { - foreach ($connectionSettings['headers'] as $name => $value) { - $lcName = strtolower($name); - if ($lcName !== 'user-agent' && $lcName !== 'content-type' && $lcName !== 'range') { - $headerStr .= $name . ': ' . $value . "\r\n"; + try { + $responseData = $this->createConnection("document/{$documentId}/{$pageNumber}.bin", $connectionSettings, true, false, false, false, $writeHandle); + $status = $responseData["status"]; + if ($status == null || $status <= 0) { + throw $this->createAnonymousClientException($responseData["error"]); + } + if ($responseData["errorMode"]) { + switch ($status) { + case 422: + throw $this->createServerException($responseData); + case 400: + throw $this->createServerException($responseData, PDFreactor::ERROR_400); + case 404: + throw $this->createServerException($responseData, PDFreactor::ERROR_404); + case 401: + throw $this->createServerException($responseData, PDFreactor::ERROR_401); + case 429: + throw $this->createServerException($responseData, PDFreactor::ERROR_429); + case 503: + throw $this->createServerException($responseData, PDFreactor::ERROR_503); + default: + throw $this->createAnonymousServerException($status); } } - } - if (!empty($connectionSettings) && !empty($connectionSettings['cookies'])) { - foreach ($connectionSettings['cookies'] as $name => $value) { - $cookieStr .= $name . '=' . $value . '; '; + if (!$useStream) { + return $responseData["data"]; } + } catch (Exception $e) { + if ($e instanceof PDFreactorWebserviceException) { + throw $e; + } + throw $this->createAnonymousClientException($e->message, $e); } - $headerStr .= "Content-Type: application/json\r\n"; - $headerStr .= "User-Agent: PDFreactor PHP API v8\r\n"; - $headerStr .= "X-RO-User-Agent: PDFreactor PHP API v8\r\n"; - if (!empty($connectionSettings) || !empty($cookieStr)) { - $headerStr .= 'Cookie: ' . substr($cookieStr, 0, -2); - } - $options = [ - 'http' => [ - 'header' => $headerStr, - 'follow_location' => false, - 'max_redirects' => 0, - 'method' => 'GET', - 'ignore_errors' => true, - ], - ]; - $context = stream_context_create($options); - $result = null; - $errorMode = true; - $rh = fopen($url, 'r', false, $context); - if (!isset($http_response_header)) { - $lastError = error_get_last(); - - throw new UnreachableServiceException('Error connecting to PDFreactor Web Service at ' . $this->url . '. Please make sure the PDFreactor Web Service is installed and running (Error: ' . $lastError['message'] . ')'); - } - $status = intval(substr($http_response_header[0], 9, 3)); - if ($status >= 200 && $status <= 204) { - $errorMode = false; - } - if (!$errorMode && ($wh == null || !$useStream)) { - $result = stream_get_contents($rh); - fclose($rh); + } + /** + * Deletes the asynchronously converted document with the given ID. If the conversion is still running, it gets terminated. + * @param string $documentId The document ID. + * @param array $connectionSettings The connection settings object. + * @throws PDFreactorWebserviceException If an issue occurred while attempting to connect to the service. + */ + public function deleteDocument($documentId, &$connectionSettings = null) { + if (is_null($documentId)) { + throw new ClientException("No conversion was triggered."); } - $errorId = null; - if ($errorMode) { - foreach ($http_response_header as $header) { - $t = explode(':', $header, 2); - if (isset($t[1])) { - $headerName = trim($t[0]); - if ($headerName == 'X-RO-Error-ID') { - $errorId = trim($t[1]); - } + try { + $responseData = $this->createConnection("document/{$documentId}.json", $connectionSettings, false, false, true, false); + $status = $responseData["status"]; + if ($status == null || $status <= 0) { + throw $this->createAnonymousClientException($responseData["error"]); + } + if ($responseData["errorMode"]) { + switch ($status) { + case 404: + throw $this->createServerException($responseData, PDFreactor::ERROR_404); + case 401: + throw $this->createServerException($responseData, PDFreactor::ERROR_401); + case 429: + throw $this->createServerException($responseData, PDFreactor::ERROR_429); + case 503: + throw $this->createServerException($responseData, PDFreactor::ERROR_503); + default: + throw $this->createAnonymousServerException($status); } } + } catch (Exception $e) { + if ($e instanceof PDFreactorWebserviceException) { + throw $e; + } + throw $this->createAnonymousClientException($e->message, $e); } - if ($status == 422) { - throw $this->_createServerException($errorId, $result); - } elseif ($status == 404) { - throw $this->_createServerException($errorId, 'Document with the given ID was not found. '.$result); - } elseif ($status == 401) { - throw $this->_createServerException($errorId, 'Unauthorized. '.$result); - } elseif ($status == 503) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service is unavailable.'); - } elseif ($status > 400) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service error (status: ' . $status . ').'); + } + /** + * Returns the version of the PDFreactor Web Service that is currently running. + * @param array $connectionSettings The connection settings object. + * @return Version The version object. + * @throws PDFreactorWebserviceException If an issue occurred while attempting to connect to the service. + */ + public function getVersion(&$connectionSettings = null) { + try { + $responseData = $this->createConnection('version.json', $connectionSettings, false, false, false, false); + $status = $responseData["status"]; + if ($status == null || $status <= 0) { + throw $this->createAnonymousClientException($responseData["error"]); + } + if ($responseData["errorMode"]) { + switch ($status) { + case 401: + throw $this->createServerException($responseData, PDFreactor::ERROR_401); + case 429: + throw $this->createServerException($responseData, PDFreactor::ERROR_429); + case 503: + throw $this->createServerException($responseData, PDFreactor::ERROR_503); + default: + throw $this->createAnonymousServerException($status); + } + } + return json_decode($responseData["data"]); + } catch (Exception $e) { + if ($e instanceof PDFreactorWebserviceException) { + throw $e; + } + throw $this->createAnonymousClientException($e->message, $e); } - if (!$errorMode && $wh != null && $useStream) { - while (!feof($rh)) { - if (fwrite($wh, fread($rh, 1024)) === false) { - return null; + } + /** + * Checks if the PDFreactor Web Service is available and functional. + * @param array $connectionSettings The connection settings object. + * @throws PDFreactorWebserviceException If an issue occurred while attempting to connect to the service. + */ + public function getStatus(&$connectionSettings = null) { + try { + $responseData = $this->createConnection('status.json', $connectionSettings, false, false, false, false); + $status = $responseData["status"]; + if ($status == null || $status <= 0) { + throw $this->createAnonymousClientException($responseData["error"]); + } + if ($responseData["errorMode"]) { + switch ($status) { + case 401: + throw $this->createServerException($responseData, PDFreactor::ERROR_401); + case 429: + throw $this->createServerException($responseData, PDFreactor::ERROR_429); + case 503: + throw $this->createServerException($responseData, PDFreactor::ERROR_503); + default: + throw $this->createAnonymousServerException($status); } } - fclose($rh); - fclose($wh); + } catch (Exception $e) { + if ($e instanceof PDFreactorWebserviceException) { + throw $e; + } + throw $this->createAnonymousClientException($e->message, $e); + } + } + /** + * Returns the URL where the document with the given ID can be accessed. + * @param string $documentId The document ID. + * @param int $pageNumber The page number. + * @return string The document URL. + */ + function getDocumentUrl($documentId, $pageNumber = null) { + if (!is_null($documentId)) { + if (!is_null($pageNumber)) { + return "{$this->url}/document/{$documentId}/{$pageNumber}"; + } + return "{$this->url}/document/{$documentId}"; + } + return null; + } + /** + * Returns the URL where the progress of the document with the given ID can be accessed. + * @param string $documentId The document ID. + * @return string The progress URL. + */ + function getProgressUrl($documentId) { + if (!is_null($documentId)) { + return "{$this->url}/progress/{$documentId}"; + } + return null; + } + public const VERSION = 12; //"12.0.0"; + /** + * The API key. Only required if the PDFreactor Web Service is so configured that only clients with a valid API key can access it. + */ + public function __get($name) { + if ($name == "apiKey") { + return $this->apiKey; } - - return $result; } - public function getDocumentMetadata($documentId, & $connectionSettings = null) - { - if (is_null($documentId)) { - throw new ClientException('No conversion was triggered.'); + private function prepareConfiguration(&$config) { + if (!is_null($config)) { + $config['clientName'] = "PHP"; + $config['clientVersion'] = PDFreactor::VERSION; } - $url = $this->url .'/document/metadata/' . $documentId . '.json'; + } + private function createConnection($path, &$connectionSettings = null, $textError = false, $zip = false, $delete = false, $async = false, &$wh = null) { + $emptyPayload = []; + return $this->createConnectionWithData($path, $connectionSettings, $textError, $zip, $delete, $async, $emptyPayload, $wh); + } + private function createConnectionWithData($path, &$connectionSettings = null, $textError = false, $zip = false, $delete = false, $async = false, &$payload = null, &$wh = null) { + $url = $this->url . "/" . $path; + $input = !!$payload; + $useStream = $wh != null; + if (!is_null($this->apiKey)) { - $url .= '?apiKey=' . $this->apiKey; + $url .= "?apiKey=" . $this->apiKey; } - $headerStr = ''; + $headers = []; + $headers[] = "User-Agent: PDFreactor PHP API v" . PDFreactor::VERSION; + $headers[] = "X-RO-User-Agent: PDFreactor PHP API v" . PDFreactor::VERSION; $cookieStr = ''; if (!empty($connectionSettings) && !empty($connectionSettings['headers'])) { foreach ($connectionSettings['headers'] as $name => $value) { $lcName = strtolower($name); - if ($lcName !== 'user-agent' && $lcName !== 'content-type' && $lcName !== 'range') { - $headerStr .= $name . ': ' . $value . "\r\n"; + if ($lcName !== "content-type" && $lcName !== "content-length" && $lcName !== "range") { + $headers[] = $name . ": " . $value; } } } if (!empty($connectionSettings) && !empty($connectionSettings['cookies'])) { foreach ($connectionSettings['cookies'] as $name => $value) { - $cookieStr .= $name . '=' . $value . '; '; + $cookieStr .= $name . "=" . $value . "; "; } } - $headerStr .= "Content-Type: application/json\r\n"; - $headerStr .= "User-Agent: PDFreactor PHP API v8\r\n"; - $headerStr .= "X-RO-User-Agent: PDFreactor PHP API v8\r\n"; + if ($input) { + $headers[] = "Content-Type: " . ($zip ? "application/zip" : "application/json"); + } if (!empty($connectionSettings) || !empty($cookieStr)) { - $headerStr .= 'Cookie: ' . substr($cookieStr, 0, -2); + $headers[] = "Cookie: " . substr($cookieStr, 0, -2); } - $options = [ - 'http' => [ - 'header' => $headerStr, - 'follow_location' => false, - 'max_redirects' => 0, - 'method' => 'GET', - 'ignore_errors' => true, - ], - ]; - $context = stream_context_create($options); - $result = null; - $errorMode = true; - $rh = fopen($url, 'r', false, $context); - if (!isset($http_response_header)) { - $lastError = error_get_last(); + $curl = curl_init($url); + $responseHeaders = []; - throw new UnreachableServiceException('Error connecting to PDFreactor Web Service at ' . $this->url . '. Please make sure the PDFreactor Web Service is installed and running (Error: ' . $lastError['message'] . ')'); + if ($input) { + if ($zip) { + curl_setopt($curl, CURLOPT_PUT, 1); + curl_setopt($curl, CURLOPT_INFILE, $payload); + } else { + curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($payload)); + } } - $status = intval(substr($http_response_header[0], 9, 3)); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $delete ? "DELETE" : ($input ? "POST" : "GET")); + curl_setopt($curl, CURLOPT_TIMEOUT, 300); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curl, CURLINFO_HEADER_OUT, true); + curl_setopt($curl, CURLOPT_HEADERFUNCTION, function($curl, $header) use (&$responseHeaders) { + $len = strlen($header); + $header = explode(':', $header, 2); + if (count($header) < 2) { // ignore invalid headers + return $len; + } + $responseHeaders[] = [ trim($header[0]), trim($header[1]) ]; + return $len; + }); + $error = null; + $result = null; + $errorMode = true; + curl_setopt($curl, CURLOPT_WRITEFUNCTION, function($curl, $data) use(&$wh, &$useStream, &$result) { + if ($wh != null && $useStream) { + fwrite($wh, $data); + } else { + $result .= $data; + } + return strlen($data); + }); + $response = curl_exec($curl); + $info = curl_getinfo($curl); + $error = curl_error($curl); + $status = $info["http_code"]; if ($status >= 200 && $status <= 204) { $errorMode = false; } - if (!$errorMode) { - $result = json_decode(stream_get_contents($rh)); - } - fclose($rh); $errorId = null; + $documentId = null; if ($errorMode) { - foreach ($http_response_header as $header) { - $t = explode(':', $header, 2); - if (isset($t[1])) { - $headerName = trim($t[0]); - if ($headerName == 'X-RO-Error-ID') { - $errorId = trim($t[1]); + foreach ($responseHeaders as $header) { + $headerName = $header[0]; + if ($headerName == "X-RO-Error-ID") { + $errorId = $header[1]; + } + } + } + if ($async) { + foreach ($responseHeaders as $header) { + $headerName = $header[0]; + if (strtolower($headerName) == "location") { + $documentId = trim(substr($header[1], strrpos($header[1], "/") + 1)); + } + if (strtolower($headerName) == "set-cookie") { + $keepDocument = false; + if (isset($config->{'keepDocument'})) { + $keepDocument = $config->{'keepDocument'}; + } + if (isset($connectionSettings)) { + if (empty($connectionSettings['cookies'])) { + $connectionSettings['cookies'] = []; + } + $pos = stripos($header[1], ';', 0); + $headerValue = $header[1]; + if ($pos > 0) { + $headerValue = substr($headerValue, 0, $pos); + } + $cookie = explode('=', $headerValue); + $cookieName = trim($cookie[0]); + $cookieValue = trim($cookie[1]); + $connectionSettings['cookies'][$cookieName] = $cookieValue; } } } } - if ($status == 422) { - throw $this->_createServerException($errorId, $result->error, $result); - } elseif ($status == 404) { - throw $this->_createServerException($errorId, 'Document with the given ID was not found. '.$result->error, $result); - } elseif ($status == 401) { - throw $this->_createServerException($errorId, 'Unauthorized. '.$result->error, $result); - } elseif ($status == 503) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service is unavailable.', $result); - } elseif ($status > 400) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service error (status: ' . $status . ').', $result); + curl_close($curl); + if ($errorMode && empty($error)) { + if ($status == NULL || $status <= 0) { + $error = "Could not connect to server."; + } else if ($textError && !empty($result)) { + $error = $result; + } } - - return $result; + return [ + "errorMode" => $errorMode, + "error" => $error, + "errorId" => $errorId, + "data" => $error == NULL || !$textError ? $result : NULL, + "status" => $status, + "documentId" => $documentId, + "info" => $info + ]; } + private function createServerException(&$responseData, $clientMessage = NULL) { + $serverMessage = NULL; + $result = NULL; + $errorId = ""; - public function deleteDocument($documentId, & $connectionSettings = null): void - { - if (is_null($documentId)) { - throw new ClientException('No conversion was triggered.'); - } - $url = $this->url .'/document/' . $documentId . '.json'; - if (!is_null($this->apiKey)) { - $url .= '?apiKey=' . $this->apiKey; - } - $headerStr = ''; - $cookieStr = ''; - if (!empty($connectionSettings) && !empty($connectionSettings['headers'])) { - foreach ($connectionSettings['headers'] as $name => $value) { - $lcName = strtolower($name); - if ($lcName !== 'user-agent' && $lcName !== 'content-type' && $lcName !== 'range') { - $headerStr .= $name . ': ' . $value . "\r\n"; - } - } - } - if (!empty($connectionSettings) && !empty($connectionSettings['cookies'])) { - foreach ($connectionSettings['cookies'] as $name => $value) { - $cookieStr .= $name . '=' . $value . '; '; - } - } - $headerStr .= "Content-Type: application/json\r\n"; - $headerStr .= "User-Agent: PDFreactor PHP API v8\r\n"; - $headerStr .= "X-RO-User-Agent: PDFreactor PHP API v8\r\n"; - if (!empty($connectionSettings) || !empty($cookieStr)) { - $headerStr .= 'Cookie: ' . substr($cookieStr, 0, -2); - } - $options = [ - 'http' => [ - 'header' => $headerStr, - 'follow_location' => false, - 'max_redirects' => 0, - 'method' => 'DELETE', - 'ignore_errors' => true, - ], - ]; - $context = stream_context_create($options); - $result = null; - $errorMode = true; - $rh = fopen($url, 'r', false, $context); - if (!isset($http_response_header)) { - $lastError = error_get_last(); - - throw new UnreachableServiceException('Error connecting to PDFreactor Web Service at ' . $this->url . '. Please make sure the PDFreactor Web Service is installed and running (Error: ' . $lastError['message'] . ')'); - } - $status = intval(substr($http_response_header[0], 9, 3)); - if ($status >= 200 && $status <= 204) { - $errorMode = false; - } - if (!$errorMode) { - $result = json_decode(stream_get_contents($rh)); - } - fclose($rh); - $errorId = null; - if ($errorMode) { - foreach ($http_response_header as $header) { - $t = explode(':', $header, 2); - if (isset($t[1])) { - $headerName = trim($t[0]); - if ($headerName == 'X-RO-Error-ID') { - $errorId = trim($t[1]); - } - } - } - } - if ($status == 404) { - throw $this->_createServerException($errorId, 'Document with the given ID was not found. '.$result->error, $result); - } elseif ($status == 401) { - throw $this->_createServerException($errorId, 'Unauthorized. '.$result->error, $result); - } elseif ($status == 503) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service is unavailable.', $result); - } elseif ($status > 400) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service error (status: ' . $status . ').', $result); - } - } - - public function getVersion(& $connectionSettings = null) - { - $url = $this->url .'/version.json'; - if (!is_null($this->apiKey)) { - $url .= '?apiKey=' . $this->apiKey; - } - $headerStr = ''; - $cookieStr = ''; - if (!empty($connectionSettings) && !empty($connectionSettings['headers'])) { - foreach ($connectionSettings['headers'] as $name => $value) { - $lcName = strtolower($name); - if ($lcName !== 'user-agent' && $lcName !== 'content-type' && $lcName !== 'range') { - $headerStr .= $name . ': ' . $value . "\r\n"; - } - } - } - if (!empty($connectionSettings) && !empty($connectionSettings['cookies'])) { - foreach ($connectionSettings['cookies'] as $name => $value) { - $cookieStr .= $name . '=' . $value . '; '; - } - } - $headerStr .= "Content-Type: application/json\r\n"; - $headerStr .= "User-Agent: PDFreactor PHP API v8\r\n"; - $headerStr .= "X-RO-User-Agent: PDFreactor PHP API v8\r\n"; - if (!empty($connectionSettings) || !empty($cookieStr)) { - $headerStr .= 'Cookie: ' . substr($cookieStr, 0, -2); - } - $options = [ - 'http' => [ - 'header' => $headerStr, - 'follow_location' => false, - 'max_redirects' => 0, - 'method' => 'GET', - 'ignore_errors' => true, - ], - ]; - $context = stream_context_create($options); - $result = null; - $errorMode = true; - $rh = fopen($url, 'r', false, $context); - if (!isset($http_response_header)) { - $lastError = error_get_last(); - - throw new UnreachableServiceException('Error connecting to PDFreactor Web Service at ' . $this->url . '. Please make sure the PDFreactor Web Service is installed and running (Error: ' . $lastError['message'] . ')'); - } - $status = intval(substr($http_response_header[0], 9, 3)); - if ($status >= 200 && $status <= 204) { - $errorMode = false; - } - if (!$errorMode) { - $result = json_decode(stream_get_contents($rh)); - } - fclose($rh); - $errorId = null; - if ($errorMode) { - foreach ($http_response_header as $header) { - $t = explode(':', $header, 2); - if (isset($t[1])) { - $headerName = trim($t[0]); - if ($headerName == 'X-RO-Error-ID') { - $errorId = trim($t[1]); - } - } - } - } - if ($status == 401) { - throw $this->_createServerException($errorId, 'Unauthorized. '.$result->error, $result); - } elseif ($status == 503) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service is unavailable.', $result); - } elseif ($status > 400) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service error (status: ' . $status . ').', $result); + if ($responseData != NULL) { + $serverMessage = $responseData["error"]; + $result = $responseData["data"] != null ? json_decode($responseData["data"]) : NULL; + $errorId = $responseData["errorId"]; } - return $result; - } - - public function getStatus(& $connectionSettings = null): void - { - $url = $this->url .'/status.json'; - if (!is_null($this->apiKey)) { - $url .= '?apiKey=' . $this->apiKey; - } - $headerStr = ''; - $cookieStr = ''; - if (!empty($connectionSettings) && !empty($connectionSettings['headers'])) { - foreach ($connectionSettings['headers'] as $name => $value) { - $lcName = strtolower($name); - if ($lcName !== 'user-agent' && $lcName !== 'content-type' && $lcName !== 'range') { - $headerStr .= $name . ': ' . $value . "\r\n"; - } - } - } - if (!empty($connectionSettings) && !empty($connectionSettings['cookies'])) { - foreach ($connectionSettings['cookies'] as $name => $value) { - $cookieStr .= $name . '=' . $value . '; '; - } - } - $headerStr .= "Content-Type: application/json\r\n"; - $headerStr .= "User-Agent: PDFreactor PHP API v8\r\n"; - $headerStr .= "X-RO-User-Agent: PDFreactor PHP API v8\r\n"; - if (!empty($connectionSettings) || !empty($cookieStr)) { - $headerStr .= 'Cookie: ' . substr($cookieStr, 0, -2); - } - $options = [ - 'http' => [ - 'header' => $headerStr, - 'follow_location' => false, - 'max_redirects' => 0, - 'method' => 'GET', - 'ignore_errors' => true, - ], - ]; - $context = stream_context_create($options); - $result = null; - $errorMode = true; - $rh = fopen($url, 'r', false, $context); - if (!isset($http_response_header)) { - $lastError = error_get_last(); - - throw new UnreachableServiceException('Error connecting to PDFreactor Web Service at ' . $this->url . '. Please make sure the PDFreactor Web Service is installed and running (Error: ' . $lastError['message'] . ')'); - } - $status = intval(substr($http_response_header[0], 9, 3)); - if ($status >= 200 && $status <= 204) { - $errorMode = false; - } - if (!$errorMode) { - $result = json_decode(stream_get_contents($rh)); - } - fclose($rh); - $errorId = null; - if ($errorMode) { - foreach ($http_response_header as $header) { - $t = explode(':', $header, 2); - if (isset($t[1])) { - $headerName = trim($t[0]); - if ($headerName == 'X-RO-Error-ID') { - $errorId = trim($t[1]); - } - } - } - } - if ($status == 401) { - throw $this->_createServerException($errorId, 'Unauthorized. '.$result->error, $result); - } elseif ($status == 503) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service is unavailable.', $result); - } elseif ($status > 400) { - throw $this->_createServerException($errorId, 'PDFreactor Web Service error (status: ' . $status . ').', $result); - } - } - - public function getDocumentUrl($documentId): ?string - { - if (!is_null($documentId)) { - return $this->url . '/document/' . $documentId; + switch ($errorId) { + case "asyncUnavailable": + return new AsyncUnavailableException($errorId, $clientMessage, $serverMessage, $result); + case "badRequest": + return new BadRequestException($errorId, $clientMessage, $serverMessage, $result); + case "conversionAborted": + return new ConversionAbortedException($errorId, $clientMessage, $serverMessage, $result); + case "conversionFailure": + return new ConversionFailureException($errorId, $clientMessage, $serverMessage, $result); + case "documentNotFound": + return new DocumentNotFoundException($errorId, $clientMessage, $serverMessage, $result); + case "invalidClient": + return new InvalidClientException($errorId, $clientMessage, $serverMessage, $result); + case "invalidConfiguration": + return new InvalidConfigurationException($errorId, $clientMessage, $serverMessage, $result); + case "noConfiguration": + return new NoConfigurationException($errorId, $clientMessage, $serverMessage, $result); + case "noInputDocument": + return new NoInputDocumentException($errorId, $clientMessage, $serverMessage, $result); + case "notAcceptable": + return new NotAcceptableException($errorId, $clientMessage, $serverMessage, $result); + case "serviceUnavailable": + return new ServiceUnavailableException($errorId, $clientMessage, $serverMessage, $result); + case "unauthorized": + return new UnauthorizedException($errorId, $clientMessage, $serverMessage, $result); + case "unprocessableConfiguration": + return new UnprocessableConfigurationException($errorId, $clientMessage, $serverMessage, $result); + case "unprocessableInput": + return new UnprocessableInputException($errorId, $clientMessage, $serverMessage, $result); + default: + return new ServerException($errorId, $serverMessage, $result); } - - return null; } - - public function getProgressUrl($documentId): ?string - { - if (!is_null($documentId)) { - return $this->url . '/progress/' . $documentId; - } - - return null; + private function createAnonymousServerException($status) { + return new ServerException(NULL, "PDFreactor Web Service error (status {$status})."); } - - const VERSION = 8; - - public function __get($name) - { - if ($name == 'apiKey') { - return isset($this->$name) ? $this->$name : null; - } + private function createAnonymousClientException($message, $exception = null) { + return new UnreachableServiceException("Error connecting to PDFreactor Web Service at {$this->url}. Please make sure the PDFreactor Web Service is installed and running (Error: {$message})", $exception); } - - public function _createServerException($errorId = null, $message = null, $result = null): ServerException|NotAcceptableException|CommandRejectedException|NoInputDocumentException|UnprocessableConfigurationException|ResourceNotFoundException|BadRequestException|NoConfigurationException|InvalidClientException|DocumentNotFoundException|RequestRejectedException|ConversionFailureException|AsyncUnavailableException|UnprocessableInputException|ConversionAbortedException|UnauthorizedException - { - switch ($errorId) { - case 'asyncUnavailable': - return new AsyncUnavailableException($errorId, $message, $result); - case 'badRequest': - return new BadRequestException($errorId, $message, $result); - case 'commandRejected': - return new CommandRejectedException($errorId, $message, $result); - case 'conversionAborted': - return new ConversionAbortedException($errorId, $message, $result); - case 'conversionFailure': - return new ConversionFailureException($errorId, $message, $result); - case 'documentNotFound': - return new DocumentNotFoundException($errorId, $message, $result); - case 'resourceNotFound': - return new ResourceNotFoundException($errorId, $message, $result); - case 'invalidClient': - return new InvalidClientException($errorId, $message, $result); - case 'invalidConfiguration': - return new InvalidConfigurationException($errorId, $message, $result); - case 'noConfiguration': - return new NoConfigurationException($errorId, $message, $result); - case 'noInputDocument': - return new NoInputDocumentException($errorId, $message, $result); - case 'requestRejected': - return new RequestRejectedException($errorId, $message, $result); - case 'serviceUnavailable': - return new ServiceUnavailableException($errorId, $message, $result); - case 'unauthorized': - return new UnauthorizedException($errorId, $message, $result); - case 'unprocessableConfiguration': - return new UnprocessableConfigurationException($errorId, $message, $result); - case 'unprocessableInput': - return new UnprocessableInputException($errorId, $message, $result); - case 'notAcceptable': - return new NotAcceptableException($errorId, $message, $result); - default: - return new ServerException($errorId, $message, $result); - } + private function createUnknownException($exception) { + return new PDFreactorWebserviceException("Unknown PDFreactor Web Service error (Error: {$exception->message})", $exception); } } -class PDFreactorWebserviceException extends \Exception -{ - public mixed $result = null; - public function __construct($message) - { - parent::__construct($message == null ? 'Unknown PDFreactor Web Service error' : $message); +/** + * This type of exception is thrown by the PDFreactor Web Service client. It has several sub classes, all indicating different issues. To react to specific problems, it is recommended to catch appropriate sub class exceptions. + * @see ClientException + * @see ServerException + */ +class PDFreactorWebserviceException extends \Exception { + var $result; + function __construct($message) { + parent::__construct($message == null ? "Unknown PDFreactor Web Service error" : $message); } - - public function __get($property) - { + public function __get($property) { if (property_exists($this, $property)) { return $this->$property; } } } -class ServerException extends PDFreactorWebserviceException -{ - public function __construct($errorId = null, $message = null, $result = null) - { +/** + * This type of exception is produced by the PDFreactor Web Service and indicates that the conversion could not be processed for some reason. Exceptions of this class mean that the PDFreactor Web Service is running. Please note that the client requires the 'X-RO-Error-ID' HTTP header to be present to convert the exception in the appropriate type. If that header is missing, exceptions will have this generic type instead. + * @see AsyncUnavailableException + * @see BadRequestException + * @see ConversionAbortedException + * @see ConversionFailureException + * @see DocumentNotFoundException + * @see InvalidClientException + * @see InvalidConfigurationException + * @see NoConfigurationException + * @see NoInputDocumentException + * @see NotAcceptableException + * @see ServiceUnavailableException + * @see UnauthorizedException + * @see UnprocessableConfigurationException + * @see UnprocessableInputException + */ +class ServerException extends PDFreactorWebserviceException { + var $result; + var $errorId; + function __construct($errorId = null, $clientMessage = null, $serverMessage = null, $result = null) { $this->result = $result; $this->errorId = $errorId; - parent::__construct($message == null ? 'Unknown PDFreactor Web Service error' : $message); + $messages = []; + if ($serverMessage == NULL && $result != NULL) { + $serverMessage = $result->error; + } + if ($clientMessage != NULL) { + array_push($messages, $clientMessage); + } + if ($serverMessage != NULL) { + array_push($messages, $serverMessage); + } + $message = implode(" ", $messages); + parent::__construct($message == null ? "Unknown PDFreactor Web Service error" : $message); } - - public function getResult() - { + public function getResult() { return $this->result; } } -class ClientException extends PDFreactorWebserviceException -{ - public function __construct($message) - { +/** + * This type of exception is produced by the client and indicates that a connection to the PDFreactor Web Service could not be established. Exceptions of this class do not necessarily indicate a problem with the PDFreactor Web Service, only that it could not be reached. This could have various reasons, including a non-functioning PDFreactor Web Service, a blocking firewall or an incorrectly configured service URL. + * @see ClientTimeoutException + * @see InvalidServiceException + * @see UnreachableServiceException + */ +class ClientException extends PDFreactorWebserviceException { + var $cause; + function __construct($message, $cause = null) { + $this->cause = $cause; parent::__construct($message); } } -class AsyncUnavailableException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * Asynchronous conversions are not available in this PDFreactor Web Service. + */ +class AsyncUnavailableException extends ServerException { + function __construct($errorId, $clientMessage, $serverMessage, $result) { + parent::__construct($errorId, $clientMessage, $serverMessage, $result); } } -class BadRequestException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * The page number you specified is either below 0 or exceeds the document's total number of pages. + */ +class BadRequestException extends ServerException { + function __construct($errorId, $clientMessage, $serverMessage, $result) { + parent::__construct($errorId, $clientMessage, $serverMessage, $result); } } -class CommandRejectedException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * The supplied configuration is valid, however the conversion could not be completed for some reason. See the error message for details. + */ +class ConversionAbortedException extends ServerException { + function __construct($errorId, $clientMessage, $serverMessage, $result) { + parent::__construct($errorId, $clientMessage, $serverMessage, $result); } } -class ConversionAbortedException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * The configuration could not be processed and should be re-checked. + */ +class ConversionFailureException extends ServerException { + function __construct($errorId, $clientMessage, $serverMessage, $result) { + parent::__construct($errorId, $clientMessage, $serverMessage, $result); } } -class ConversionFailureException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * Conversion does not exist. + */ +class DocumentNotFoundException extends ServerException { + function __construct($errorId, $clientMessage, $serverMessage, $result) { + parent::__construct($errorId, $clientMessage, $serverMessage, $result); } } -class DocumentNotFoundException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * The version of the client that was used is outdated and no longer supported. This is only available for the PDFreactor REST clients. + */ +class InvalidClientException extends ServerException { + function __construct($errorId, $clientMessage, $serverMessage, $result) { + parent::__construct($errorId, $clientMessage, $serverMessage, $result); } } -class ResourceNotFoundException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * The supplied configuration was not valid for some reason. See the error message for details. + */ +class InvalidConfigurationException extends ServerException { + function __construct($errorId, $clientMessage, $serverMessage, $result) { + parent::__construct($errorId, $clientMessage, $serverMessage, $result); } } -class InvalidClientException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * No configuration was supplied to the operation. + */ +class NoConfigurationException extends ServerException { + function __construct($errorId, $clientMessage, $serverMessage, $result) { + parent::__construct($errorId, $clientMessage, $serverMessage, $result); } } -class InvalidConfigurationException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * No input document was specified in the configuration. + */ +class NoInputDocumentException extends ServerException { + function __construct($errorId, $clientMessage, $serverMessage, $result) { + parent::__construct($errorId, $clientMessage, $serverMessage, $result); } } -class NoConfigurationException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * The server could not produce a result with a media type that matches the client's request. The configuration or Accept header should be adjusted accordingly. + */ +class NotAcceptableException extends ServerException { + function __construct($errorId, $clientMessage, $serverMessage, $result) { + parent::__construct($errorId, $clientMessage, $serverMessage, $result); } } -class NoInputDocumentException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * The PDFreactor Web Service is running and reachable, but not in a state to perform the requested operation. + */ +class ServiceUnavailableException extends ServerException { + function __construct($errorId, $clientMessage, $serverMessage, $result) { + parent::__construct($errorId, $clientMessage, $serverMessage, $result); } } -class RequestRejectedException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * The client failed an authorization check, e.g. because a supplied API key was invalid. + */ +class UnauthorizedException extends ServerException { + function __construct($errorId, $clientMessage, $serverMessage, $result) { + parent::__construct($errorId, $clientMessage, $serverMessage, $result); } } -class ServiceUnavailableException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * The supplied configuration was accepted by PDFreactor but could not be converted for some reason. See the error message for details. + */ +class UnprocessableConfigurationException extends ServerException { + function __construct($errorId, $clientMessage, $serverMessage, $result) { + parent::__construct($errorId, $clientMessage, $serverMessage, $result); } } -class UnauthorizedException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * The supplied input data was accepted by PDFreactur but could not be processed for some reason. See the error message for details. + */ +class UnprocessableInputException extends ServerException { + function __construct($errorId, $clientMessage, $serverMessage, $result) { + parent::__construct($errorId, $clientMessage, $serverMessage, $result); } } -class UnprocessableConfigurationException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * The PDFreactor Web Service could not be reached. + */ +class UnreachableServiceException extends ClientException { + function __construct($message, $cause = null) { + parent::__construct($message, $cause); } } -class UnprocessableInputException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * A response was received but it could not be identified as a response from the PDFreactor Web Service. + */ +class InvalidServiceException extends ClientException { + function __construct($message, $cause = null) { + parent::__construct($message, $cause); } } -class NotAcceptableException extends ServerException -{ - public function __construct($errorId, $message, $result) - { - parent::__construct($errorId, $message, $result); +/** + * This exception is thrown under the following circumstances: + * The request to the PDFreactor Web Service timed out. This usually occurs during synchronous conversions. Increasing the timeout or switching to asynchronous conversions might resolve this. + */ +class ClientTimeoutException extends ClientException { + function __construct($message, $cause = null) { + parent::__construct($message, $cause); } } -class UnreachableServiceException extends ClientException -{ - public function __construct($message) - { - parent::__construct($message); - } + +/** + *

An enum containing callback type constants.

+ */ +abstract class CallbackType { + /** + *

This callback is called when the conversion is finished.

+ *
    + *
  • Allowed content types: + * {@see ContentType::JSON} + * , + * {@see ContentType::XML} + * , + * {@see ContentType::TEXT} + * .
  • + *
  • Payload model: + * Result. The object returned will only contain the metadata, not the document data. + * The document has to be retrieved actively from the server. If the content type is + * {@see ContentType::TEXT} + * , only the document ID will be posted.
  • + *
+ * @var string + */ + public const FINISH = "FINISH"; + /** + *

This callback is called regularly to inform on the progress of the conversion.

+ *
    + *
  • Allowed content types: + * {@see ContentType::JSON} + * , + * {@see ContentType::XML} + * , + * {@see ContentType::TEXT} + * .
  • + *
  • Payload model: + * Progress. If the content type is + * {@see ContentType::TEXT} + * , only the progress percentage will be posted.
  • + *
  • Interval property applies.
  • + *
+ * @var string + */ + public const PROGRESS = "PROGRESS"; + /** + *

This callback is called when the conversion is started.

+ *
    + *
  • Allowed content types: + * {@see ContentType::JSON} + * , + * {@see ContentType::XML} + * , + * {@see ContentType::TEXT} + * .
  • + *
  • Payload model: + * Info. If the content type is + * {@see ContentType::TEXT} + * , only the document ID will be posted.
  • + *
+ * @var string + */ + public const START = "START"; } -class InvalidServiceException extends ClientException -{ - public function __construct($message) - { - parent::__construct($message); - } +/** + *

An enum containing cleanup constants.

+ */ +abstract class Cleanup { + /** + *

Indicates that the CyberNeko HTML parser will be used to perform a + * cleanup when loading a non-well-formed document.

+ * @var string + */ + public const CYBERNEKO = "CYBERNEKO"; + /** + *

Indicates that JTidy will be used to perform a cleanup when loading a + * non-well-formed document.

+ * @var string + */ + public const JTIDY = "JTIDY"; + /** + *

Indicates that no cleanup will be performed when loading a document. If the + * loaded document is not well-formed, an exception will be thrown.

+ * @var string + */ + public const NONE = "NONE"; + /** + *

Indicates that tagsoup will be used to perform a + * cleanup when loading a non-well-formed document.

+ * @var string + */ + public const TAGSOUP = "TAGSOUP"; } -abstract class CallbackType -{ - const FINISH = 'FINISH'; - - const PROGRESS = 'PROGRESS'; - - const START = 'START'; +/** + *

An enum containing color space constants.

+ */ +abstract class ColorSpace { + /** + *

The color space CMYK.

+ * @var string + */ + public const CMYK = "CMYK"; + /** + *

The color space RGB.

+ * @var string + */ + public const RGB = "RGB"; } -abstract class Cleanup -{ - const CYBERNEKO = 'CYBERNEKO'; - - const JTIDY = 'JTIDY'; - - const NONE = 'NONE'; - - const TAGSOUP = 'TAGSOUP'; +/** + *

An enum containing conformance constants.

+ */ +abstract class Conformance { + /** + *

PDF with no additional restrictions (default)

+ * @var string + */ + public const PDF = "PDF"; + /** + *

PDF/A-1a (ISO 19005-1:2005 Level A)

+ * @var string + */ + public const PDFA1A = "PDFA1A"; + /** + *

PDF/A-1a + PDF/UA-1 (ISO 19005-1:2005 Level A + ISO 14289-1:2014)

+ * @var string + */ + public const PDFA1A_PDFUA1 = "PDFA1A_PDFUA1"; + /** + *

PDF/A-1b (ISO 19005-1:2005 Level B)

+ * @var string + */ + public const PDFA1B = "PDFA1B"; + /** + *

PDF/A-2a (ISO 19005-2:2011 Level A)

+ * @var string + */ + public const PDFA2A = "PDFA2A"; + /** + *

PDF/A-2a + PDF/UA-1 (ISO 19005-2:2011 Level A + ISO 14289-1:2014)

+ * @var string + */ + public const PDFA2A_PDFUA1 = "PDFA2A_PDFUA1"; + /** + *

PDF/A-2b (ISO 19005-2:2011 Level B)

+ * @var string + */ + public const PDFA2B = "PDFA2B"; + /** + *

PDF/A-2u (ISO 19005-2:2011 Level U)

+ * @var string + */ + public const PDFA2U = "PDFA2U"; + /** + *

PDF/A-3a (ISO 19005-3:2012 Level A)

+ * @var string + */ + public const PDFA3A = "PDFA3A"; + /** + *

PDF/A-3a + PDF/UA-1 (ISO 19005-3:2012 Level A + ISO 14289-1:2014)

+ * @var string + */ + public const PDFA3A_PDFUA1 = "PDFA3A_PDFUA1"; + /** + *

PDF/A-3b (ISO 19005-3:2012 Level B)

+ * @var string + */ + public const PDFA3B = "PDFA3B"; + /** + *

PDF/A-3u (ISO 19005-3:2012 Level U)

+ * @var string + */ + public const PDFA3U = "PDFA3U"; + /** + *

PDF/UA-1 (ISO 14289-1:2014)

+ * @var string + */ + public const PDFUA1 = "PDFUA1"; + /** + *

PDF/X-1a:2001 (ISO 15930-1:2001)

+ * @var string + */ + public const PDFX1A_2001 = "PDFX1A_2001"; + /** + *

PDF/X-1a:2003 (ISO 15930-4:2003)

+ * @var string + */ + public const PDFX1A_2003 = "PDFX1A_2003"; + /** + *

PDF/X-3:2002 (ISO 15930-3:2002)

+ * @var string + */ + public const PDFX3_2002 = "PDFX3_2002"; + /** + *

PDF/X-3:2003 (ISO 15930-6:2003)

+ * @var string + */ + public const PDFX3_2003 = "PDFX3_2003"; + /** + *

PDF/X-4 (ISO 15930-7:2008)

+ * @var string + */ + public const PDFX4 = "PDFX4"; + /** + *

PDF/X-4p (ISO 15930-7:2008)

+ * @var string + */ + public const PDFX4P = "PDFX4P"; } -abstract class ColorSpace -{ - const CMYK = 'CMYK'; - - const RGB = 'RGB'; +/** + *

An enum containing content type constants.

+ */ +abstract class ContentType { + /** + *

Content type BINARY, corresponds with "application/octet-stream" MIME type.

+ * @var string + */ + public const BINARY = "BINARY"; + /** + *

Content type BMP, corresponds with "image/bmp" MIME type.

+ * @var string + */ + public const BMP = "BMP"; + /** + *

Content type GIF, corresponds with "image/gif" MIME type.

+ * @var string + */ + public const GIF = "GIF"; + /** + *

Content type HTML, corresponds with "text/html" MIME type.

+ * @var string + */ + public const HTML = "HTML"; + /** + *

Content type JPEG, corresponds with "image/jpeg" MIME type.

+ * @var string + */ + public const JPEG = "JPEG"; + /** + *

Content type JSON, corresponds with "application/json" MIME type.

+ * @var string + */ + public const JSON = "JSON"; + /** + *

Content type NONE, i.e. no content.

+ * @var string + */ + public const NONE = "NONE"; + /** + *

Content type PDF, corresponds with "application/pdf" MIME type.

+ * @var string + */ + public const PDF = "PDF"; + /** + *

Content type PNG, corresponds with "image/png" MIME type.

+ * @var string + */ + public const PNG = "PNG"; + /** + *

Content type TEXT, corresponds with "text/plain" MIME type.

+ * @var string + */ + public const TEXT = "TEXT"; + /** + *

Content type TIFF, corresponds with "image/tiff" MIME type.

+ * @var string + */ + public const TIFF = "TIFF"; + /** + *

Content type XML, corresponds with "application/xml" MIME type.

+ * @var string + */ + public const XML = "XML"; } -abstract class Conformance -{ - const PDF = 'PDF'; - - const PDFA1A = 'PDFA1A'; - - const PDFA1A_PDFUA1 = 'PDFA1A_PDFUA1'; - - const PDFA1B = 'PDFA1B'; - - const PDFA2A = 'PDFA2A'; - - const PDFA2A_PDFUA1 = 'PDFA2A_PDFUA1'; - - const PDFA2B = 'PDFA2B'; - - const PDFA2U = 'PDFA2U'; - - const PDFA3A = 'PDFA3A'; - - const PDFA3A_PDFUA1 = 'PDFA3A_PDFUA1'; - - const PDFA3B = 'PDFA3B'; - - const PDFA3U = 'PDFA3U'; - - const PDFUA1 = 'PDFUA1'; - - const PDFX1A_2001 = 'PDFX1A_2001'; - - const PDFX1A_2003 = 'PDFX1A_2003'; - - const PDFX3_2002 = 'PDFX3_2002'; - - const PDFX3_2003 = 'PDFX3_2003'; - - const PDFX4 = 'PDFX4'; - - const PDFX4P = 'PDFX4P'; +/** + *

An enum containing cookie policy constants.

+ */ +abstract class CookiePolicy { + /** + *

Disables cookie handling entirely. Cookies specified in the API are still sent, but server cookies are rejected.

+ * @var string + */ + public const DISABLED = "DISABLED"; + /** + *

A standard-compliant cookie policy that ignores date issues. This is the default value.

+ * @var string + */ + public const RELAXED = "RELAXED"; + /** + *

A strict standard-compliant cookie policy.

+ * @var string + */ + public const STRICT = "STRICT"; } -abstract class ContentType -{ - const BINARY = 'BINARY'; - - const BMP = 'BMP'; - - const GIF = 'GIF'; - - const HTML = 'HTML'; - - const JPEG = 'JPEG'; - - const JSON = 'JSON'; - - const NONE = 'NONE'; - - const PDF = 'PDF'; - - const PNG = 'PNG'; - - const TEXT = 'TEXT'; - - const TIFF = 'TIFF'; - - const XML = 'XML'; +/** + *

An enum containing CSS property support mode constants.

+ */ +abstract class CssPropertySupport { + /** + *

Indicates that all style declarations are considered valid + * disregarding the possibility of improper rendering.

+ *

Valid values may be overwritten by invalid style declarations.

+ * @var string + */ + public const ALL = "ALL"; + /** + *

Indicates that all values set in style declarations will be + * validated as long as PDFreactor supports the corresponding + * property.

+ *

Style declarations for properties not supported + * by PDFreactor are taken as invalid.

+ * @var string + */ + public const HTML = "HTML"; + /** + *

Indicates that all values set in style declarations will be + * validated as long as PDFreactor supports the corresponding + * property.

+ *

Style declarations for properties not supported + * by PDFreactor but by third party products are taken as valid.

+ * @var string + */ + public const HTML_THIRD_PARTY = "HTML_THIRD_PARTY"; + /** + *

Indicates that all values set in style declarations will be + * taken as valid if a third party product supports the corresponding + * property.

+ *

Style declarations for properties not supported by + * any third party product but supported by PDFreactor will be validated.

+ * @var string + */ + public const HTML_THIRD_PARTY_LENIENT = "HTML_THIRD_PARTY_LENIENT"; } -abstract class CssPropertySupport -{ - const ALL = 'ALL'; - - const HTML = 'HTML'; - - const HTML_THIRD_PARTY = 'HTML_THIRD_PARTY'; - - const HTML_THIRD_PARTY_LENIENT = 'HTML_THIRD_PARTY_LENIENT'; +/** + *

An enum containing document type constants.

+ */ +abstract class Doctype { + /** + *

Indicates that the document type will be detected automatically. + * When the document has a file extension, it is used to determine whether the document is + * {@see Doctype::HTML5} + * or + * {@see Doctype::XHTML} + * . If there is no file extension or it is unknown, then the document content itself is searched + * for an XML declaration, a doctype preamble and the root element.

+ * @var string + */ + public const AUTODETECT = "AUTODETECT"; + /** + *

Indicates that the document type will be set to HTML5. + * The HTML default style sheet is used and the document is loaded regarding style + * elements, style attributes and link stylesheets.

+ * @var string + */ + public const HTML5 = "HTML5"; + /** + *

Indicates that the document type will be set to XHTML. The HTML default + * style sheet is used and the document is loaded regarding style + * elements, style attributes and link stylesheets.

+ * @var string + */ + public const XHTML = "XHTML"; + /** + *

Indicates that the document type will be set to generic XML. No default + * style sheet is used and the document is loaded as is without regards + * to style elements or attributes.

+ * @var string + */ + public const XML = "XML"; } -abstract class Doctype -{ - const AUTODETECT = 'AUTODETECT'; - - const HTML5 = 'HTML5'; - - const XHTML = 'XHTML'; - - const XML = 'XML'; +/** + *

An enum containing encryption constants.

+ */ +abstract class Encryption { + /** + *

Indicates that the document will be encrypted using AES 128 bit encryption. + * @var string + */ + public const AES_128 = "AES_128"; + /** + *

Indicates that the document will be encrypted using AES 256 bit encryption. + * @var string + */ + public const AES_256 = "AES_256"; + /** + *

Indicates that the document will not be encrypted. If encryption is disabled + * then no user password and no owner password can be used.

+ * @var string + */ + public const NONE = "NONE"; + /** + *

Indicates that the document will be encrypted using RC4 128 bit encryption. + * @var string + */ + public const RC4_128 = "RC4_128"; + /** + *

Indicates that the document will be encrypted using RC4 40 bit encryption.

+ * @var string + */ + public const RC4_40 = "RC4_40"; + /** + *

Deprecated as of PDFreactor 12. Use + * {@see Encryption::RC4_128} + * instead.

+ * @var string + */ + public const TYPE_128 = "TYPE_128"; + /** + *

Deprecated as of PDFreactor 12. Use + * {@see Encryption::RC4_40} + * instead.

+ * @var string + */ + public const TYPE_40 = "TYPE_40"; } -abstract class Encryption -{ - const NONE = 'NONE'; - - const TYPE_128 = 'TYPE_128'; - - const TYPE_40 = 'TYPE_40'; +/** + *

An enum containing error policies.

+ */ +abstract class ErrorPolicy { + /** + *

Whether an exception should be thrown when the PDF's conformance was not validated + * even though + * {@see Configuration::setValidateConformance(Boolean)} + * was enabled. + * Now exceptions will be thrown if the validation module is not available or the conformance format is + * not fully supported for validation.

+ *

Use this policy only if you exclusively convert documents where validation is supported + * and strictly required.

+ * @var string + */ + public const CONFORMANCE_VALIDATION_UNAVAILABLE = "CONFORMANCE_VALIDATION_UNAVAILABLE"; + /** + *

Whether exceptions occurring when trying to merge invalid documents (e.g. + * encrypted documents for which no owner password or an invalid password was + * supplied) should be ignored.

+ *

Use this policy if the conversion should proceed even if one or more + * documents that should be merged are invalid. They will be omitted from + * the final PDF.

+ * @var string + */ + public const IGNORE_INVALID_MERGE_DOCUMENTS_EXCEPTION = "IGNORE_INVALID_MERGE_DOCUMENTS_EXCEPTION"; + /** + *

Whether an exception should be thrown when no legal full license key is set. + * This allows to programmatically ensure that documents are not altered due to license issues.

+ * @var string + */ + public const LICENSE = "LICENSE"; + /** + *

Whether an exception should be thrown when resources could not be loaded.

+ * @var string + */ + public const MISSING_RESOURCE = "MISSING_RESOURCE"; + /** + *

Whether an exception should be thrown when there are uncaught exceptions + * in the input document JavaScript, including syntax error.

+ * @var string + */ + public const UNCAUGHT_JAVASCRIPT_EXCEPTION = "UNCAUGHT_JAVASCRIPT_EXCEPTION"; + /** + *

Whether an exception should be thrown when an event of level + * {@see LogLevel::WARN} + * is logged.

+ * @var string + */ + public const WARN_EVENT = "WARN_EVENT"; } -abstract class ErrorPolicy -{ - const CONFORMANCE_VALIDATION_UNAVAILABLE = 'CONFORMANCE_VALIDATION_UNAVAILABLE'; - - const LICENSE = 'LICENSE'; - - const MISSING_RESOURCE = 'MISSING_RESOURCE'; - - const UNCAUGHT_JAVASCRIPT_EXCEPTION = 'UNCAUGHT_JAVASCRIPT_EXCEPTION'; +/** + *

An enum containing constants for logging exceeding content against.

+ */ +abstract class ExceedingContentAgainst { + /** + *

Do not log exceeding content.

+ * @var string + */ + public const NONE = "NONE"; + /** + *

Log content exceeding the edges of its page.

+ * @var string + */ + public const PAGE_BORDERS = "PAGE_BORDERS"; + /** + *

Log content exceeding its page content area (overlaps the page margin).

+ * @var string + */ + public const PAGE_CONTENT = "PAGE_CONTENT"; + /** + *

Log content exceeding its container.

+ * @var string + */ + public const PARENT = "PARENT"; } -abstract class ExceedingContentAgainst -{ - const NONE = 'NONE'; - - const PAGE_BORDERS = 'PAGE_BORDERS'; - - const PAGE_CONTENT = 'PAGE_CONTENT'; - - const PARENT = 'PARENT'; +/** + *

An enum containing constants for analyzing exceeding content.

+ */ +abstract class ExceedingContentAnalyze { + /** + *

Log exceeding content.

+ * @var string + */ + public const CONTENT = "CONTENT"; + /** + *

Log exceeding content and all boxes.

+ * @var string + */ + public const CONTENT_AND_BOXES = "CONTENT_AND_BOXES"; + /** + *

Log exceeding content and boxes without absolute positioning.

+ * @var string + */ + public const CONTENT_AND_STATIC_BOXES = "CONTENT_AND_STATIC_BOXES"; + /** + *

Do not log exceeding content.

+ * @var string + */ + public const NONE = "NONE"; } -abstract class ExceedingContentAnalyze -{ - const CONTENT = 'CONTENT'; - - const CONTENT_AND_BOXES = 'CONTENT_AND_BOXES'; - - const CONTENT_AND_STATIC_BOXES = 'CONTENT_AND_STATIC_BOXES'; - - const NONE = 'NONE'; +/** + *

An enum containing HTTP authentication scheme constants.

+ */ +abstract class HttpAuthScheme { + /** + *

This constant indicates that the credentials are to be used for any authentication scheme. This is the default value.

+ * @var string + */ + public const ANY = "ANY"; + /** + *

BASIC authentication.

+ * @var string + */ + public const BASIC = "BASIC"; + /** + *

DIGEST authentication.

+ * @var string + */ + public const DIGEST = "DIGEST"; + /** + *

Kerberos authentication.

+ * @var string + */ + public const KERBEROS = "KERBEROS"; + /** + *

Windows NTLM authentication.

+ * @var string + */ + public const NTLM = "NTLM"; + /** + *

Simple and Protected GSSAPI Negotiation Mechanism.

+ * @var string + */ + public const SPNEGO = "SPNEGO"; } -abstract class HttpsMode -{ - const LENIENT = 'LENIENT'; - - const STRICT = 'STRICT'; +/** + *

An enum containing HTTP protocol constants.

+ */ +abstract class HttpProtocol { + /** + *

This constant indicates that the credentials are to be used for any HTTP protocol.

+ * @var string + */ + public const ANY = "ANY"; + /** + *

HTTP only.

+ * @var string + */ + public const HTTP = "HTTP"; + /** + *

HTTPS only.

+ * @var string + */ + public const HTTPS = "HTTPS"; } -abstract class JavaScriptDebugMode -{ - const EXCEPTIONS = 'EXCEPTIONS'; - - const FUNCTIONS = 'FUNCTIONS'; - - const LINES = 'LINES'; - - const NONE = 'NONE'; - - const POSITIONS = 'POSITIONS'; +/** + *

Deprecated as of PDFreactor 12. Use + * {@see SecuritySettings::setTrustAllConnectionCertificates(Boolean)} + * instead.

+ */ +abstract class HttpsMode { + /** + *

Indicates lenient HTTPS behavior. This means that many certificate issues are ignored.

+ * @var string + */ + public const LENIENT = "LENIENT"; + /** + *

Indicates strict HTTPS behavior. This matches the default behavior of Java.

+ * @var string + */ + public const STRICT = "STRICT"; } -abstract class JavaScriptMode -{ - const DISABLED = 'DISABLED'; - - const ENABLED = 'ENABLED'; - - const ENABLED_NO_LAYOUT = 'ENABLED_NO_LAYOUT'; - - const ENABLED_REAL_TIME = 'ENABLED_REAL_TIME'; - - const ENABLED_TIME_LAPSE = 'ENABLED_TIME_LAPSE'; +/** + *

An enum containing JavaScript debug mode constants.

+ */ +abstract class JavaScriptDebugMode { + /** + *

Indicates that all exceptions thrown during JavaScript processing are logged + * in addition to the effects of POSITIONS.

+ * @var string + */ + public const EXCEPTIONS = "EXCEPTIONS"; + /** + *

Indicates that all JavaScript functions entered or exited are logged + * in addition to the effects of POSITIONS and EXCEPTIONS.

+ * @var string + */ + public const FUNCTIONS = "FUNCTIONS"; + /** + *

Indicates that every line of executed JavaScript is logged + * in addition to the effects of POSITIONS, EXCEPTIONS and FUNCTIONS.

+ * @var string + */ + public const LINES = "LINES"; + /** + *

Indicates that debugging is disabled.

+ * @var string + */ + public const NONE = "NONE"; + /** + *

Indicates that the filenames and line numbers that caused output + * (e.g. via console.log) are logged.

+ * @var string + */ + public const POSITIONS = "POSITIONS"; } -abstract class KeystoreType -{ - const JKS = 'JKS'; - - const PKCS12 = 'PKCS12'; +/** + *

An enum containing JavaScript engines.

+ */ +abstract class JavaScriptEngine { + /** + *

GraalVM JavaScript engine

+ * @var string + */ + public const GRAALJS = "GRAALJS"; + /** + *

Rhino JavaScript engine

+ * @var string + */ + public const RHINO = "RHINO"; } -abstract class LogLevel -{ - const DEBUG = 'DEBUG'; - - const FATAL = 'FATAL'; - - const INFO = 'INFO'; - - const NONE = 'NONE'; - - const PERFORMANCE = 'PERFORMANCE'; - - const WARN = 'WARN'; +/** + *

An enum containing keystore type constants.

+ */ +abstract class KeystoreType { + /** + *

Keystore type "jks".

+ * @var string + */ + public const JKS = "JKS"; + /** + *

Keystore type "pkcs12".

+ * @var string + */ + public const PKCS12 = "PKCS12"; } -abstract class MediaFeature -{ - const ASPECT_RATIO = 'ASPECT_RATIO'; - - const COLOR = 'COLOR'; - - const COLOR_INDEX = 'COLOR_INDEX'; - - const DEVICE_ASPECT_RATIO = 'DEVICE_ASPECT_RATIO'; - - const DEVICE_HEIGHT = 'DEVICE_HEIGHT'; - - const DEVICE_WIDTH = 'DEVICE_WIDTH'; - - const GRID = 'GRID'; - - const HEIGHT = 'HEIGHT'; - - const MONOCHROME = 'MONOCHROME'; - - const ORIENTATION = 'ORIENTATION'; - - const RESOLUTION = 'RESOLUTION'; - - const WIDTH = 'WIDTH'; +/** + *

An enum containing log level constants.

+ */ +abstract class LogLevel { + /** + *

Indicates that debug, info, warn and fatal log events will be logged.

+ * @var string + */ + public const DEBUG = "DEBUG"; + /** + *

Indicates that only error log events will be logged.

+ * @var string + */ + public const ERROR = "ERROR"; + /** + *

Deprecated as of PDFreactor 12. Use + * {@see LogLevel::ERROR} + * instead.

+ * @var string + */ + public const FATAL = "FATAL"; + /** + *

Indicates that info, warn and fatal log events will be logged.

+ * @var string + */ + public const INFO = "INFO"; + /** + *

Indicates that no log events will be logged.

+ * @var string + */ + public const NONE = "NONE"; + /** + *

Deprecated as of PDFreactor 12. Use + * {@see LogLevel::TRACE} + * instead.

+ * @var string + */ + public const PERFORMANCE = "PERFORMANCE"; + /** + *

Indicates that all log events will be logged.

+ * @var string + */ + public const TRACE = "TRACE"; + /** + *

Indicates that warn and fatal log events will be logged.

+ * @var string + */ + public const WARN = "WARN"; } -abstract class MergeMode -{ - const APPEND = 'APPEND'; - - const ARRANGE = 'ARRANGE'; - - const OVERLAY = 'OVERLAY'; - - const OVERLAY_BELOW = 'OVERLAY_BELOW'; - - const PREPEND = 'PREPEND'; +/** + *

An enum containing media feature constants.

+ */ +abstract class MediaFeature { + /** + *

CSS Media Feature (Media Queries Level 4) describing whether any available input mechanism allows the user to hover over elements.

+ *

The default value is "none".

+ * @var string + */ + public const ANY_HOVER = "ANY_HOVER"; + /** + *

CSS Media Feature (Media Queries Level 4) describing whether any available input mechanism is a pointing device, and if so, how accurate is it.

+ *

The default value is "none".

+ * @var string + */ + public const ANY_POINTER = "ANY_POINTER"; + /** + *

CSS 3 Media Feature describing the aspect ratio of the page content.

+ *

By default, this value is computed using the values of + * {@see MediaFeature::WIDTH} + * and + * {@see MediaFeature::HEIGHT} + * . Setting a specific value does override the computed + * value.

+ * @var string + */ + public const ASPECT_RATIO = "ASPECT_RATIO"; + /** + *

CSS 3 Media Feature describing the number of bits per color component.

+ *

Default value is 8, except if the output is forced to be grayscale, in which case it is 0.

+ * @var string + */ + public const COLOR = "COLOR"; + /** + *

CSS Media Feature (Media Queries Level 4) describing the approximate range of colors that are supported by the UA and output device.

+ *

The default value is "srgb".

+ * @var string + */ + public const COLOR_GAMUT = "COLOR_GAMUT"; + /** + *

CSS 3 Media Feature describing the number of entries in the color lookup table.

+ *

Default value is 0, except if the output format is "gif" in which case it is 256.

+ * @var string + */ + public const COLOR_INDEX = "COLOR_INDEX"; + /** + *

CSS 3 Media Feature describing the aspect ratio of the page.

+ *

By default, this value is computed using the values of + * {@see MediaFeature::DEVICE_WIDTH} + * and + * {@see MediaFeature::DEVICE_HEIGHT} + * . Setting a specific value does override + * the computed value.

+ * @var string + */ + public const DEVICE_ASPECT_RATIO = "DEVICE_ASPECT_RATIO"; + /** + *

CSS 3 Media Feature describing the height of the page.

+ *

The default height is that of a DIN A4 page (297mm).

+ * @var string + */ + public const DEVICE_HEIGHT = "DEVICE_HEIGHT"; + /** + *

CSS 3 Media Feature describing the width of the page.

+ *

The default width is that of a DIN A4 page (210mm).

+ * @var string + */ + public const DEVICE_WIDTH = "DEVICE_WIDTH"; + /** + *

CSS Media Feature (Media Queries Level 5) representing how a web application is being presented within the context of an OS.

+ *

The default value is "fullscreen".

+ * @var string + */ + public const DISPLAY_MODE = "DISPLAY_MODE"; + /** + *

CSS Media Feature (Media Queries Level 5) representing the combination of max brightness, color depth, and contrast ratio that are supported by the user agent and output device.

+ *

The default value is "standard".

+ * @var string + */ + public const DYNAMIC_RANGE = "DYNAMIC_RANGE"; + /** + *

CSS Media Feature (Media Queries Level 5) that is used to query the characteristics of the user's display so the author can adjust the style of the document.

+ *

The default value is "opaque".

+ * @var string + */ + public const ENVIRONMENT_BLENDING = "ENVIRONMENT_BLENDING"; + /** + *

CSS Media Feature (Media Queries Level 5) indicates whether the user-agent enforces a limited color palette.

+ *

The default value is "none".

+ * @var string + */ + public const FORCED_COLORS = "FORCED_COLORS"; + /** + *

CSS 3 Media Feature defining whether the output is grid-based.

+ *

Default value 0, as PDFs are not grid-based.

+ * @var string + */ + public const GRID = "GRID"; + /** + *

CSS 3 Media Feature height of page content.

+ *

The default height is that of a DIN A4 page with 2cm margin (257mm).

+ * @var string + */ + public const HEIGHT = "HEIGHT"; + /** + *

CSS Media Feature (Media Queries Level 5) that describes the number of logical segments of the viewport in the horizontal direction.

+ *

The default value is "1".

+ * @var string + */ + public const HORIZONTAL_VIEWPORT_SEGMENTS = "HORIZONTAL_VIEWPORT_SEGMENTS"; + /** + *

CSS Media Feature (Media Queries Level 4) describing whether the primary input mechanism allows the user to hover over elements.

+ *

The default value is "none".

+ * @var string + */ + public const HOVER = "HOVER"; + /** + *

CSS Media Feature (Media Queries Level 5) indicating whether the content is displayed normally, or whether colors have been inverted.

+ *

The default value is "none".

+ * @var string + */ + public const INVERTED_COLORS = "INVERTED_COLORS"; + /** + *

CSS 3 Media Feature describing the number of bits per pixel in a monochrome frame buffer.

+ *

Default value is 0, if the output format is not monochrome.

+ * @var string + */ + public const MONOCHROME = "MONOCHROME"; + /** + *

CSS Media Feature (Media Queries Level 5) allowing authors to know whether the user agent is providing obviously discoverable navigation controls as part of its user interface.

+ *

The default value is "none".

+ * @var string + */ + public const NAV_CONTROLS = "NAV_CONTROLS"; + /** + *

CSS 3 Media Feature describing the page orientation.

+ *

By default, this value is computed using the values of + * {@see MediaFeature::WIDTH} + * and + * {@see MediaFeature::HEIGHT} + * . + * Setting a specific value does override the computed value.

+ *

Valid values are "portrait" or "landscape".

+ * @var string + */ + public const ORIENTATION = "ORIENTATION"; + /** + *

CSS Media Feature (Media Queries Level 4) describing the behavior of the device when content overflows the initial containing block in the block axis.

+ *

The default value is "page", except if an image output was set to continuous, in which case it is "none".

+ * @var string + */ + public const OVERFLOW_BLOCK = "OVERFLOW_BLOCK"; + /** + *

CSS Media Feature (Media Queries Level 4) describing the behavior of the device when content overflows the initial containing block in the inline axis.

+ *

The default value is "none".

+ * @var string + */ + public const OVERFLOW_INLINE = "OVERFLOW_INLINE"; + /** + *

CSS Media Feature (Media Queries Level 4) describing whether the primary input mechanism is a pointing device, and if so, how accurate is it.

+ *

The default value is "none".

+ * @var string + */ + public const POINTER = "POINTER"; + /** + *

CSS Media Feature (Media Queries Level 5) reflecting the user's desire that the page use a light or dark color theme.

+ *

The default value is "light".

+ * @var string + */ + public const PREFERS_COLOR_SCHEME = "PREFERS_COLOR_SCHEME"; + /** + *

CSS Media Feature (Media Queries Level 5) used to detect if the user has requested more or less contrast in the page.

+ *

The default value is "no-preference".

+ * @var string + */ + public const PREFERS_CONSTRAST = "PREFERS_CONSTRAST"; + /** + *

CSS Media Feature (Media Queries Level 5) used to detect if the user has a preference for being served alternate content that uses less data for the page to be rendered.

+ *

The default value is "no-preference".

+ * @var string + */ + public const PREFERS_REDUCED_DATA = "PREFERS_REDUCED_DATA"; + /** + *

CSS Media Feature (Media Queries Level 5) used to detect if the user has requested the system minimize the amount of animation or motion it uses.

+ *

The default value is "reduce".

+ * @var string + */ + public const PREFERS_REDUCED_MOTION = "PREFERS_REDUCED_MOTION"; + /** + *

CSS Media Feature (Media Queries Level 5) used to detect if the user has requested the system minimize the amount of transparent or translucent layer effects it uses.

+ *

The default value is "no-preference".

+ * @var string + */ + public const PREFERS_REDUCED_TRANSPARENCY = "PREFERS_REDUCED_TRANSPARENCY"; + /** + *

CSS 3 Media Feature describing the resolution of the output device.

+ *

This also defines the value of the window.devicePixelRatio property available from JavaScript.

+ *

Default value is 300dpi.

+ * @var string + */ + public const RESOLUTION = "RESOLUTION"; + /** + *

CSS Media Feature (Media Queries Level 4) describing the scanning process of some output devices.

+ *

The default value is "progressive".

+ * @var string + */ + public const SCAN = "SCAN"; + /** + *

CSS Media Feature (Media Queries Level 5) used to query whether scripting languages, such as JavaScript, are supported on the current document.

+ *

The default value is "initial-only" if JavaScript has been enabled or "none" otherwise.

+ * @var string + */ + public const SCRIPTING = "SCRIPTING"; + /** + *

CSS Media Feature (Media Queries Level 5) used to query the ability of the output device to modify the appearance of content once it has been rendered.

+ *

The default value is "none".

+ * @var string + */ + public const UPDATE = "UPDATE"; + /** + *

CSS Media Feature (Media Queries Level 5) that describes the number of logical segments of the viewport in the vertical direction.

+ *

The default value is "1".

+ * @var string + */ + public const VERTICAL_VIEWPORT_SEGMENTS = "VERTICAL_VIEWPORT_SEGMENTS"; + /** + *

CSS Media Feature (Media Queries Level 5) describing the approximate range of colors that are supported by the UA and output device's video plane.

+ *

The default value is "srgb".

+ * @var string + */ + public const VIDEO_COLOR_GAMUT = "VIDEO_COLOR_GAMUT"; + /** + *

CSS Media Feature (Media Queries Level 5) representing the combination of max brightness, color depth, and contrast ratio that are supported by the UA and output device's video plane.

+ *

The default value is "standard".

+ * @var string + */ + public const VIDEO_DYNAMIC_RANGE = "VIDEO_DYNAMIC_RANGE"; + /** + *

CSS 3 Media Feature width of page content.

+ *

The default width is that of a DIN A4 page with 2cm margin (170mm).

+ * @var string + */ + public const WIDTH = "WIDTH"; } -abstract class OutputIntentDefaultProfile -{ - const FOGRA39 = 'Coated FOGRA39'; - - const GRACOL = 'Coated GRACoL 2006'; - - const IFRA = 'ISO News print 26% (IFRA)'; - - const JAPAN = 'Japan Color 2001 Coated'; - - const JAPAN_NEWSPAPER = 'Japan Color 2001 Newspaper'; - - const JAPAN_UNCOATED = 'Japan Color 2001 Uncoated'; - - const JAPAN_WEB = 'Japan Web Coated (Ad)'; - - const SWOP = 'US Web Coated (SWOP) v2'; - - const SWOP_3 = 'Web Coated SWOP 2006 Grade 3 Paper'; +/** + *

An enum containing merge mode constants.

+ */ +abstract class MergeMode { + /** + *

Default merge mode: Append converted document to existing PDF.

+ * @var string + */ + public const APPEND = "APPEND"; + /** + *

Advanced merge mode: Allows to insert specific pages from existing PDFs into + * the converted document.

+ *

This is done via a special syntax of + * {@see Configuration::setPageOrder(String)} + * .

+ * @var string + */ + public const ARRANGE = "ARRANGE"; + /** + *

Alternate merge mode (overlay): Adding converted document above the existing PDF.

+ * @var string + */ + public const OVERLAY = "OVERLAY"; + /** + *

Alternate merge mode (overlay): Adding converted document below the existing PDF.

+ * @var string + */ + public const OVERLAY_BELOW = "OVERLAY_BELOW"; + /** + *

Alternate merge mode: Prepend converted document to existing PDF.

+ * @var string + */ + public const PREPEND = "PREPEND"; } -abstract class OutputType -{ - const BMP = 'BMP'; - - const GIF = 'GIF'; - - const GIF_DITHERED = 'GIF_DITHERED'; - - const JPEG = 'JPEG'; - - const PDF = 'PDF'; - - const PNG = 'PNG'; - - const PNG_AI = 'PNG_AI'; - - const PNG_TRANSPARENT = 'PNG_TRANSPARENT'; - - const PNG_TRANSPARENT_AI = 'PNG_TRANSPARENT_AI'; - - const TIFF_CCITT_1D = 'TIFF_CCITT_1D'; - - const TIFF_CCITT_1D_DITHERED = 'TIFF_CCITT_1D_DITHERED'; - - const TIFF_CCITT_GROUP_3 = 'TIFF_CCITT_GROUP_3'; - - const TIFF_CCITT_GROUP_3_DITHERED = 'TIFF_CCITT_GROUP_3_DITHERED'; - - const TIFF_CCITT_GROUP_4 = 'TIFF_CCITT_GROUP_4'; - - const TIFF_CCITT_GROUP_4_DITHERED = 'TIFF_CCITT_GROUP_4_DITHERED'; - - const TIFF_LZW = 'TIFF_LZW'; - - const TIFF_PACKBITS = 'TIFF_PACKBITS'; - - const TIFF_UNCOMPRESSED = 'TIFF_UNCOMPRESSED'; +/** + *

An enum containing default profiles for output intents.

+ */ +abstract class OutputIntentDefaultProfile { + /** + *

"Coated FOGRA39" output intent default profile.

+ * @var string + */ + public const FOGRA39 = "Coated FOGRA39"; + /** + *

"Coated GRACoL 2006" output intent default profile.

+ * @var string + */ + public const GRACOL = "Coated GRACoL 2006"; + /** + *

"ISO News print 26% (IFRA)" output intent default profile.

+ * @var string + */ + public const IFRA = "ISO News print 26% (IFRA)"; + /** + *

"Japan Color 2001 Coated" output intent default profile.

+ * @var string + */ + public const JAPAN = "Japan Color 2001 Coated"; + /** + *

"Japan Color 2001 Newspaper" output intent default profile.

+ * @var string + */ + public const JAPAN_NEWSPAPER = "Japan Color 2001 Newspaper"; + /** + *

"Japan Color 2001 Uncoated" output intent default profile.

+ * @var string + */ + public const JAPAN_UNCOATED = "Japan Color 2001 Uncoated"; + /** + *

"Japan Web Coated (Ad)" output intent default profile.

+ * @var string + */ + public const JAPAN_WEB = "Japan Web Coated (Ad)"; + /** + *

"US Web Coated (SWOP) v2" output intent default profile.

+ * @var string + */ + public const SWOP = "US Web Coated (SWOP) v2"; + /** + *

"Web Coated SWOP 2006 Grade 3 Paper" output intent default profile.

+ * @var string + */ + public const SWOP_3 = "Web Coated SWOP 2006 Grade 3 Paper"; } -abstract class OverlayRepeat -{ - const ALL_PAGES = 'ALL_PAGES'; - - const LAST_PAGE = 'LAST_PAGE'; - - const NONE = 'NONE'; - - const TRIM = 'TRIM'; +/** + *

An enum containing output format constants.

+ */ +abstract class OutputType { + /** + *

BMP output format.

+ * @var string + */ + public const BMP = "BMP"; + /** + *

GIF output format.

+ * @var string + */ + public const GIF = "GIF"; + /** + *

JPEG output format, with dithering applied.

+ * @var string + */ + public const GIF_DITHERED = "GIF_DITHERED"; + /** + *

JPEG output format.

+ * @var string + */ + public const JPEG = "JPEG"; + /** + *

PDF output format.

+ * @var string + */ + public const PDF = "PDF"; + /** + *

PNG output format.

+ * @var string + */ + public const PNG = "PNG"; + /** + *

Deprecated as of PDFreactor 11. Use + * {@see OutputType::PNG} + * instead.

+ * @var string + */ + public const PNG_AI = "PNG_AI"; + /** + *

Transparent PNG output format.

+ * @var string + */ + public const PNG_TRANSPARENT = "PNG_TRANSPARENT"; + /** + *

Deprecated as of PDFreactor 11. Use + * {@see OutputType::PNG_TRANSPARENT} + * instead.

+ * @var string + */ + public const PNG_TRANSPARENT_AI = "PNG_TRANSPARENT_AI"; + /** + *

Monochrome CCITT 1D/RLE compressed TIFF output format.

+ * @var string + */ + public const TIFF_CCITT_1D = "TIFF_CCITT_1D"; + /** + *

Monochrome CCITT 1D/RLE compressed TIFF output format, with dithering applied.

+ * @var string + */ + public const TIFF_CCITT_1D_DITHERED = "TIFF_CCITT_1D_DITHERED"; + /** + *

Monochrome CCITT Group 3/T.4 compressed TIFF output format.

+ * @var string + */ + public const TIFF_CCITT_GROUP_3 = "TIFF_CCITT_GROUP_3"; + /** + *

Monochrome CCITT Group 3/T.4 compressed TIFF output format, with dithering applied.

+ * @var string + */ + public const TIFF_CCITT_GROUP_3_DITHERED = "TIFF_CCITT_GROUP_3_DITHERED"; + /** + *

Monochrome CCITT Group 4/T.6 compressed TIFF output format.

+ * @var string + */ + public const TIFF_CCITT_GROUP_4 = "TIFF_CCITT_GROUP_4"; + /** + *

Monochrome CCITT Group 4/T.6 compressed TIFF output format, with dithering applied.

+ * @var string + */ + public const TIFF_CCITT_GROUP_4_DITHERED = "TIFF_CCITT_GROUP_4_DITHERED"; + /** + *

LZW compressed TIFF output format.

+ * @var string + */ + public const TIFF_LZW = "TIFF_LZW"; + /** + *

PackBits compressed TIFF output format.

+ * @var string + */ + public const TIFF_PACKBITS = "TIFF_PACKBITS"; + /** + *

Uncompressed TIFF output format.

+ * @var string + */ + public const TIFF_UNCOMPRESSED = "TIFF_UNCOMPRESSED"; } -abstract class PageOrder -{ - const BOOKLET = 'BOOKLET'; - - const BOOKLET_RTL = 'BOOKLET_RTL'; - - const EVEN = 'EVEN'; - - const ODD = 'ODD'; - - const REVERSE = 'REVERSE'; +/** + *

An enum containing constants that determines whether the converted document + * or the specified PDF document(s) is the content document for overlaying.

+ */ +abstract class OverlayContentDocument { + /** + *

The converted HTML document will be the content document.

+ * @var string + */ + public const CONVERTED = "CONVERTED"; + /** + *

The PDF document(s) indicated in the MergeSettings "documents", + * appended to each other if there are multiple ones, will be the content document.

+ * @var string + */ + public const PDF = "PDF"; } -abstract class PagesPerSheetDirection -{ - const DOWN_LEFT = 'DOWN_LEFT'; - - const DOWN_RIGHT = 'DOWN_RIGHT'; - - const LEFT_DOWN = 'LEFT_DOWN'; - - const LEFT_UP = 'LEFT_UP'; - - const RIGHT_DOWN = 'RIGHT_DOWN'; - - const RIGHT_UP = 'RIGHT_UP'; - - const UP_LEFT = 'UP_LEFT'; - - const UP_RIGHT = 'UP_RIGHT'; +/** + *

An enum containing data to configure how overlay pages that have + * different dimensions from the pages they are overlaying should be resized.

+ */ +abstract class OverlayFit { + /** + *

The page keeps its aspect ratio, but is resized to fit within the given dimension.

+ * @var string + */ + public const CONTAIN = "CONTAIN"; + /** + *

The page keeps its aspect ratio and fills the given dimension. It will be clipped to fit.

+ * @var string + */ + public const COVER = "COVER"; + /** + *

The default. The page is resized to fill the given dimension. + * If necessary, the page will be stretched or squished to fit.

+ * @var string + */ + public const FILL = "FILL"; + /** + *

The page is not resized. If necessary it will be clipped to fit.

+ * @var string + */ + public const NONE = "NONE"; } -abstract class PdfScriptTriggerEvent -{ - const AFTER_PRINT = 'AFTER_PRINT'; - - const AFTER_SAVE = 'AFTER_SAVE'; - - const BEFORE_PRINT = 'BEFORE_PRINT'; - - const BEFORE_SAVE = 'BEFORE_SAVE'; - - const CLOSE = 'CLOSE'; - - const OPEN = 'OPEN'; +/** + *

An enum containing data for repeating overlays.

+ */ +abstract class OverlayRepeat { + /** + *

All pages of the shorter document are repeated, to overlay all pages of the longer document.

+ * @var string + */ + public const ALL_PAGES = "ALL_PAGES"; + /** + *

Last page of the shorter document is repeated, to overlay all pages of the longer document.

+ * @var string + */ + public const LAST_PAGE = "LAST_PAGE"; + /** + *

No pages of the shorter document are repeated, leaving some pages of the longer document without overlay.

+ * @var string + */ + public const NONE = "NONE"; + /** + *

The resulting PDF is trimmed to the number of pages of the shorter document.

+ * @var string + */ + public const TRIM = "TRIM"; } -abstract class ProcessingPreferences -{ - const SAVE_MEMORY_IMAGES = 'SAVE_MEMORY_IMAGES'; +/** + *

An enum containing pre-defined page orders.

+ */ +abstract class PageOrder { + /** + *

Page order mode to arrange all pages in booklet order. To be used with + * {@see PagesPerSheetDirection::RIGHT_DOWN} + * . + * @var string + */ + public const BOOKLET = "BOOKLET"; + /** + *

Page order mode to arrange all pages in right-to-left booklet order. To be used with + * {@see PagesPerSheetDirection::RIGHT_DOWN} + * .

+ * @var string + */ + public const BOOKLET_RTL = "BOOKLET_RTL"; + /** + *

Page order mode to keep even pages only.

+ * @var string + */ + public const EVEN = "EVEN"; + /** + *

Page order mode to keep odd pages only.

+ * @var string + */ + public const ODD = "ODD"; + /** + *

Page order mode to reverse the page order.

+ * @var string + */ + public const REVERSE = "REVERSE"; } -abstract class QuirksMode -{ - const DETECT = 'DETECT'; - - const QUIRKS = 'QUIRKS'; - - const STANDARDS = 'STANDARDS'; +/** + *

An enum containing constants for pages per sheet directions.

+ */ +abstract class PagesPerSheetDirection { + /** + *

Arranges the pages on a sheet from top to bottom and right to left.

+ * @var string + */ + public const DOWN_LEFT = "DOWN_LEFT"; + /** + *

Arranges the pages on a sheet from top to bottom and left to right.

+ * @var string + */ + public const DOWN_RIGHT = "DOWN_RIGHT"; + /** + *

Arranges the pages on a sheet from right to left and top to bottom.

+ * @var string + */ + public const LEFT_DOWN = "LEFT_DOWN"; + /** + *

Arranges the pages on a sheet from right to left and bottom to top.

+ * @var string + */ + public const LEFT_UP = "LEFT_UP"; + /** + *

Arranges the pages on a sheet from left to right and top to bottom.

+ * @var string + */ + public const RIGHT_DOWN = "RIGHT_DOWN"; + /** + *

Arranges the pages on a sheet from left to right and bottom to top.

+ * @var string + */ + public const RIGHT_UP = "RIGHT_UP"; + /** + *

Arranges the pages on a sheet from bottom to top and right to left.

+ * @var string + */ + public const UP_LEFT = "UP_LEFT"; + /** + *

Arranges the pages on a sheet from bottom to top and left to right.

+ * @var string + */ + public const UP_RIGHT = "UP_RIGHT"; } -abstract class ResolutionUnit -{ - const DPCM = 'DPCM'; - - const DPI = 'DPI'; - - const DPPX = 'DPPX'; - - const TDPCM = 'TDPCM'; - - const TDPI = 'TDPI'; - - const TDPPX = 'TDPPX'; +/** + *

An enum containing trigger events for PDF scripts.

+ */ +abstract class PdfScriptTriggerEvent { + /** + *

This event is triggered after the PDF has been printed by the viewer application.

+ * @var string + */ + public const AFTER_PRINT = "AFTER_PRINT"; + /** + *

This event is triggered after the PDF has been saved by the viewer application.

+ * @var string + */ + public const AFTER_SAVE = "AFTER_SAVE"; + /** + *

This event is triggered before the PDF is printed by the viewer application.

+ * @var string + */ + public const BEFORE_PRINT = "BEFORE_PRINT"; + /** + *

This event is triggered before the PDF is saved by the viewer application.

+ * @var string + */ + public const BEFORE_SAVE = "BEFORE_SAVE"; + /** + *

This event is triggered when the PDF is closed by the viewer application.

+ * @var string + */ + public const CLOSE = "CLOSE"; + /** + *

This event is triggered when the PDF is opened in the viewer application.

+ * @var string + */ + public const OPEN = "OPEN"; } -abstract class ResourceType -{ - const ATTACHMENT = 'ATTACHMENT'; - - const DOCUMENT = 'DOCUMENT'; - - const FONT = 'FONT'; - - const ICC_PROFILE = 'ICC_PROFILE'; - - const IFRAME = 'IFRAME'; - - const IMAGE = 'IMAGE'; - - const LICENSEKEY = 'LICENSEKEY'; - - const MERGE_DOCUMENT = 'MERGE_DOCUMENT'; - - const OBJECT = 'OBJECT'; - - const RUNNING_DOCUMENT = 'RUNNING_DOCUMENT'; - - const SCRIPT = 'SCRIPT'; - - const STYLESHEET = 'STYLESHEET'; - - const UNKNOWN = 'UNKNOWN'; - - const XHR = 'XHR'; +/** + *

An enum containing constants for processing preferences.

+ */ +abstract class ProcessingPreferences { + /** + *

Processing preferences flag for the memory saving mode for images.

+ * @var string + */ + public const SAVE_MEMORY_IMAGES = "SAVE_MEMORY_IMAGES"; } -abstract class SigningMode -{ - const SELF_SIGNED = 'SELF_SIGNED'; - - const VERISIGN_SIGNED = 'VERISIGN_SIGNED'; - - const WINCER_SIGNED = 'WINCER_SIGNED'; +/** + *

An enum containing modes for Quirks.

+ */ +abstract class QuirksMode { + /** + *

Doctype dependent behavior.

+ * @var string + */ + public const DETECT = "DETECT"; + /** + *

Forced quirks behavior.

+ * @var string + */ + public const QUIRKS = "QUIRKS"; + /** + *

Forced no-quirks behavior.

+ * @var string + */ + public const STANDARDS = "STANDARDS"; } -abstract class ViewerPreferences -{ - const CENTER_WINDOW = 'CENTER_WINDOW'; - - const DIRECTION_L2R = 'DIRECTION_L2R'; - - const DIRECTION_R2L = 'DIRECTION_R2L'; - - const DISPLAY_DOC_TITLE = 'DISPLAY_DOC_TITLE'; - - const DUPLEX_FLIP_LONG_EDGE = 'DUPLEX_FLIP_LONG_EDGE'; - - const DUPLEX_FLIP_SHORT_EDGE = 'DUPLEX_FLIP_SHORT_EDGE'; - - const DUPLEX_SIMPLEX = 'DUPLEX_SIMPLEX'; - - const FIT_WINDOW = 'FIT_WINDOW'; - - const HIDE_MENUBAR = 'HIDE_MENUBAR'; - - const HIDE_TOOLBAR = 'HIDE_TOOLBAR'; - - const HIDE_WINDOW_UI = 'HIDE_WINDOW_UI'; - - const NON_FULLSCREEN_PAGE_MODE_USE_NONE = 'NON_FULLSCREEN_PAGE_MODE_USE_NONE'; - - const NON_FULLSCREEN_PAGE_MODE_USE_OC = 'NON_FULLSCREEN_PAGE_MODE_USE_OC'; - - const NON_FULLSCREEN_PAGE_MODE_USE_OUTLINES = 'NON_FULLSCREEN_PAGE_MODE_USE_OUTLINES'; - - const NON_FULLSCREEN_PAGE_MODE_USE_THUMBS = 'NON_FULLSCREEN_PAGE_MODE_USE_THUMBS'; - - const PAGE_LAYOUT_ONE_COLUMN = 'PAGE_LAYOUT_ONE_COLUMN'; - - const PAGE_LAYOUT_SINGLE_PAGE = 'PAGE_LAYOUT_SINGLE_PAGE'; - - const PAGE_LAYOUT_TWO_COLUMN_LEFT = 'PAGE_LAYOUT_TWO_COLUMN_LEFT'; - - const PAGE_LAYOUT_TWO_COLUMN_RIGHT = 'PAGE_LAYOUT_TWO_COLUMN_RIGHT'; - - const PAGE_LAYOUT_TWO_PAGE_LEFT = 'PAGE_LAYOUT_TWO_PAGE_LEFT'; - - const PAGE_LAYOUT_TWO_PAGE_RIGHT = 'PAGE_LAYOUT_TWO_PAGE_RIGHT'; - - const PAGE_MODE_FULLSCREEN = 'PAGE_MODE_FULLSCREEN'; - - const PAGE_MODE_USE_ATTACHMENTS = 'PAGE_MODE_USE_ATTACHMENTS'; - - const PAGE_MODE_USE_NONE = 'PAGE_MODE_USE_NONE'; - - const PAGE_MODE_USE_OC = 'PAGE_MODE_USE_OC'; - - const PAGE_MODE_USE_OUTLINES = 'PAGE_MODE_USE_OUTLINES'; - - const PAGE_MODE_USE_THUMBS = 'PAGE_MODE_USE_THUMBS'; - - const PICKTRAYBYPDFSIZE_FALSE = 'PICKTRAYBYPDFSIZE_FALSE'; - - const PICKTRAYBYPDFSIZE_TRUE = 'PICKTRAYBYPDFSIZE_TRUE'; - - const PRINTSCALING_APPDEFAULT = 'PRINTSCALING_APPDEFAULT'; - - const PRINTSCALING_NONE = 'PRINTSCALING_NONE'; +/** + *

An enum containing resolution units.

+ */ +abstract class ResolutionUnit { + /** + *

Dots per inch. The default 1dppx/96dpi in this unit is about 38.

+ * @var string + */ + public const DPCM = "DPCM"; + /** + *

Dots per Inch. The default 1dppx/96dpi in this unit is 96.

+ * @var string + */ + public const DPI = "DPI"; + /** + *

Dots per 'px' unit. The default 1dppx/96dpi in this unit is 1.

+ * @var string + */ + public const DPPX = "DPPX"; + /** + *

Thousand dots per centimeter. The default 1dppx/96dpi in this unit is about 37795.

+ * @var string + */ + public const TDPCM = "TDPCM"; + /** + *

Thousand dots per inch. The default 1dppx/96dpi in this unit is 96000.

+ * @var string + */ + public const TDPI = "TDPI"; + /** + *

Thousand dots per 'px' unit. The default 1dppx/96dpi in this unit is 1000.

+ * @var string + */ + public const TDPPX = "TDPPX"; } -abstract class XmpPriority -{ - const HIGH = 'HIGH'; - - const LOW = 'LOW'; - - const NONE = 'NONE'; +/** + *

An enum containing resource sub type constants.

+ */ +abstract class ResourceSubtype { + /** + *

Indicates a "classic" (non-module) JavaScript. Used for resources of type + * {@see ResourceType::SCRIPT} + * .

+ * @var string + */ + public const JAVASCRIPT_CLASSIC = "JAVASCRIPT_CLASSIC"; + /** + *

Indicates a JavaScript import map. Used for resources of type + * {@see ResourceType::SCRIPT} + * .

+ * @var string + */ + public const JAVASCRIPT_IMPORTMAP = "JAVASCRIPT_IMPORTMAP"; + /** + *

Indicates a JavaScript module. Used for resources of type + * {@see ResourceType::SCRIPT} + * .

+ * @var string + */ + public const JAVASCRIPT_MODULE = "JAVASCRIPT_MODULE"; +} +/** + *

Indicates the type of resource.

+ */ +abstract class ResourceType { + /** + *

An attachment.

+ * @var string + */ + public const ATTACHMENT = "ATTACHMENT"; + /** + * The main HTML or XML document. + * @var string + */ + public const DOCUMENT = "DOCUMENT"; + /** + *

A font.

+ * @var string + */ + public const FONT = "FONT"; + /** + *

An ICC profile.

+ * @var string + */ + public const ICC_PROFILE = "ICC_PROFILE"; + /** + *

An iframe.

+ * @var string + */ + public const IFRAME = "IFRAME"; + /** + *

An image.

+ * @var string + */ + public const IMAGE = "IMAGE"; + /** + *

The license key.

+ * @var string + */ + public const LICENSEKEY = "LICENSEKEY"; + /** + *

A merge document.

+ * @var string + */ + public const MERGE_DOCUMENT = "MERGE_DOCUMENT"; + /** + *

An embedded object.

+ * @var string + */ + public const OBJECT = "OBJECT"; + /** + *

A running document.

+ * @var string + */ + public const RUNNING_DOCUMENT = "RUNNING_DOCUMENT"; + /** + *

A script.

+ * @var string + */ + public const SCRIPT = "SCRIPT"; + /** + *

A style sheet.

+ * @var string + */ + public const STYLESHEET = "STYLESHEET"; + /** + *

An unknown resource type.

+ * @var string + */ + public const UNKNOWN = "UNKNOWN"; + /** + * An XMLHttpRequest. + * @var string + */ + public const XHR = "XHR"; +} +/** + *

An enum containing the cryptographic filter type that is used for signing.

+ */ +abstract class SigningMode { + /** + *

The self signed filter: PDFreactor creates a signature with the adbe.x509.rsa_sha1 (PKCS#1) filter type.

+ * @var string + */ + public const SELF_SIGNED = "SELF_SIGNED"; + /** + *

The VeriSign filter. PDFreactor creates a signature with VeriSign filter type.

+ * @var string + */ + public const VERISIGN_SIGNED = "VERISIGN_SIGNED"; + /** + *

The Windows Certificate Security: PDFreactor creates a signature with the adbe.pkcs7.sha1 (PKCS#7) filter type.

+ * @var string + */ + public const WINCER_SIGNED = "WINCER_SIGNED"; +} +/** + *

An enum containing constants for viewer preferences.

+ */ +abstract class ViewerPreferences { + /** + *

Position the document's window in the center of the screen.

+ * @var string + */ + public const CENTER_WINDOW = "CENTER_WINDOW"; + /** + *

Position pages in ascending order from left to right.

+ * @var string + */ + public const DIRECTION_L2R = "DIRECTION_L2R"; + /** + *

Position pages in ascending order from right to left.

+ * @var string + */ + public const DIRECTION_R2L = "DIRECTION_R2L"; + /** + *

Display the document's title in the top bar.

+ * @var string + */ + public const DISPLAY_DOC_TITLE = "DISPLAY_DOC_TITLE"; + /** + *

Print dialog default setting: duplex (long edge).

+ * @var string + */ + public const DUPLEX_FLIP_LONG_EDGE = "DUPLEX_FLIP_LONG_EDGE"; + /** + *

Print dialog default setting: duplex (short edge).

+ * @var string + */ + public const DUPLEX_FLIP_SHORT_EDGE = "DUPLEX_FLIP_SHORT_EDGE"; + /** + *

Print dialog default setting: simplex.

+ * @var string + */ + public const DUPLEX_SIMPLEX = "DUPLEX_SIMPLEX"; + /** + *

Resize the document's window to fit the size of the first displayed page.

+ * @var string + */ + public const FIT_WINDOW = "FIT_WINDOW"; + /** + *

Hide the viewer application's menu bar when the document is active.

+ * @var string + */ + public const HIDE_MENUBAR = "HIDE_MENUBAR"; + /** + *

Hide the viewer application's tool bars when the document is active.

+ * @var string + */ + public const HIDE_TOOLBAR = "HIDE_TOOLBAR"; + /** + *

Hide user interface elements in the document's window.

+ * @var string + */ + public const HIDE_WINDOW_UI = "HIDE_WINDOW_UI"; + /** + *

Show no panel on exiting full-screen mode. Has to be combined with + * {@see ViewerPreferences::PAGE_MODE_FULLSCREEN} + * .

+ * @var string + */ + public const NON_FULLSCREEN_PAGE_MODE_USE_NONE = "NON_FULLSCREEN_PAGE_MODE_USE_NONE"; + /** + *

Show optional content group panel on exiting full-screen mode. Has to be combined with + * {@see ViewerPreferences::PAGE_MODE_FULLSCREEN} + * .

+ * @var string + */ + public const NON_FULLSCREEN_PAGE_MODE_USE_OC = "NON_FULLSCREEN_PAGE_MODE_USE_OC"; + /** + *

Show bookmarks panel on exiting full-screen mode. Has to be combined with + * {@see ViewerPreferences::PAGE_MODE_FULLSCREEN} + * .

+ * @var string + */ + public const NON_FULLSCREEN_PAGE_MODE_USE_OUTLINES = "NON_FULLSCREEN_PAGE_MODE_USE_OUTLINES"; + /** + *

Show thumbnail images panel on exiting full-screen mode. Has to be combined with + * {@see ViewerPreferences::PAGE_MODE_FULLSCREEN} + * .

+ * @var string + */ + public const NON_FULLSCREEN_PAGE_MODE_USE_THUMBS = "NON_FULLSCREEN_PAGE_MODE_USE_THUMBS"; + /** + *

Display the pages in one column.

+ * @var string + */ + public const PAGE_LAYOUT_ONE_COLUMN = "PAGE_LAYOUT_ONE_COLUMN"; + /** + *

Display one page at a time (default).

+ * @var string + */ + public const PAGE_LAYOUT_SINGLE_PAGE = "PAGE_LAYOUT_SINGLE_PAGE"; + /** + *

Display the pages in two columns, with odd numbered pages on the left.

+ * @var string + */ + public const PAGE_LAYOUT_TWO_COLUMN_LEFT = "PAGE_LAYOUT_TWO_COLUMN_LEFT"; + /** + *

Display the pages in two columns, with odd numbered pages on the right.

+ * @var string + */ + public const PAGE_LAYOUT_TWO_COLUMN_RIGHT = "PAGE_LAYOUT_TWO_COLUMN_RIGHT"; + /** + *

Display two pages at a time, with odd numbered pages on the left.

+ * @var string + */ + public const PAGE_LAYOUT_TWO_PAGE_LEFT = "PAGE_LAYOUT_TWO_PAGE_LEFT"; + /** + *

Display two pages at a time, with odd numbered pages on the right.

+ * @var string + */ + public const PAGE_LAYOUT_TWO_PAGE_RIGHT = "PAGE_LAYOUT_TWO_PAGE_RIGHT"; + /** + *

Switch to fullscreen mode on startup.

+ * @var string + */ + public const PAGE_MODE_FULLSCREEN = "PAGE_MODE_FULLSCREEN"; + /** + *

Show attachments panel on startup.

+ * @var string + */ + public const PAGE_MODE_USE_ATTACHMENTS = "PAGE_MODE_USE_ATTACHMENTS"; + /** + *

Show no panel on startup.

+ * @var string + */ + public const PAGE_MODE_USE_NONE = "PAGE_MODE_USE_NONE"; + /** + *

Show optional content group panel on startup.

+ * @var string + */ + public const PAGE_MODE_USE_OC = "PAGE_MODE_USE_OC"; + /** + *

Show bookmarks panel on startup.

+ * @var string + */ + public const PAGE_MODE_USE_OUTLINES = "PAGE_MODE_USE_OUTLINES"; + /** + *

Show thumbnail images panel on startup.

+ * @var string + */ + public const PAGE_MODE_USE_THUMBS = "PAGE_MODE_USE_THUMBS"; + /** + *

Print dialog default setting: do not pick tray by PDF size.

+ * @var string + */ + public const PICKTRAYBYPDFSIZE_FALSE = "PICKTRAYBYPDFSIZE_FALSE"; + /** + *

Print dialog default setting: pick tray by PDF size.

+ * @var string + */ + public const PICKTRAYBYPDFSIZE_TRUE = "PICKTRAYBYPDFSIZE_TRUE"; + /** + *

Print dialog default setting: set scaling to application default value.

+ * @var string + */ + public const PRINTSCALING_APPDEFAULT = "PRINTSCALING_APPDEFAULT"; + /** + *

Print dialog default setting: disabled scaling.

+ * @var string + */ + public const PRINTSCALING_NONE = "PRINTSCALING_NONE"; +} +/** + *

An enum containing the priority for XMP.

+ */ +abstract class XmpPriority { + /** + *

Embed XMP ignoring requirements of the output format.

+ *

This may cause output PDFs to not achieve a specified conformance.

+ * @var string + */ + public const HIGH = "HIGH"; + /** + *

Embed XMP if the output format does not have XMP requirements.

+ * @var string + */ + public const LOW = "LOW"; + /** + *

Do not embed XMP.

+ * @var string + */ + public const NONE = "NONE"; } +?> diff --git a/src/Processor/PdfReactor.php b/src/Processor/PdfReactor.php index a0927b6..c5216d9 100644 --- a/src/Processor/PdfReactor.php +++ b/src/Processor/PdfReactor.php @@ -19,7 +19,6 @@ use com\realobjects\pdfreactor\webservice\client\ColorSpace; use com\realobjects\pdfreactor\webservice\client\Encryption; use com\realobjects\pdfreactor\webservice\client\HttpsMode; -use com\realobjects\pdfreactor\webservice\client\JavaScriptMode; use com\realobjects\pdfreactor\webservice\client\LogLevel; use com\realobjects\pdfreactor\webservice\client\ViewerPreferences; use Pimcore\Bundle\WebToPrintBundle\Config; @@ -31,6 +30,13 @@ class PdfReactor extends Processor { + //Legacy constants, needed for compatibility reasons + private const JAVA_SCRIPT_MODE_DISABLED = 'DISABLED'; + + private const JAVA_SCRIPT_MODE_ENABLED = 'ENABLED'; + + private const JAVA_SCRIPT_MODE_ENABLED_NO_LAYOUT = 'ENABLED_NO_LAYOUT'; + /** * returns the default web2print config * @@ -38,6 +44,13 @@ class PdfReactor extends Processor */ protected function getConfig(object $config): array { + + $javaScriptMode = $config->javaScriptMode ?? self::JAVA_SCRIPT_MODE_ENABLED; + $javaScriptSettings = [ + 'enabled' => $javaScriptMode === self::JAVA_SCRIPT_MODE_ENABLED || $javaScriptMode === self::JAVA_SCRIPT_MODE_ENABLED_NO_LAYOUT, + 'noLayout' => $javaScriptMode === self::JAVA_SCRIPT_MODE_ENABLED_NO_LAYOUT, + ]; + $web2PrintConfig = Config::getWeb2PrintConfig(); $reactorConfig = [ 'document' => '', @@ -46,12 +59,16 @@ protected function getConfig(object $config): array 'title' => $config->title ?? '', 'addLinks' => isset($config->links) && $config->links === true, 'addBookmarks' => isset($config->bookmarks) && $config->bookmarks === true, - 'javaScriptMode' => $config->javaScriptMode ?? JavaScriptMode::ENABLED, - 'defaultColorSpace' => $config->colorspace ?? ColorSpace::CMYK, + 'javaScriptSettings' => $javaScriptSettings, + 'colorSpaceSettings' => [ + 'targetColorSpace' => $config->colorspace ?? ColorSpace::CMYK, + ], 'encryption' => $config->encryption ?? Encryption::NONE, 'addTags' => isset($config->tags) && $config->tags === true, 'logLevel' => $config->loglevel ?? LogLevel::FATAL, - 'enableDebugMode' => $web2PrintConfig['pdfreactorEnableDebugMode'] || (isset($config->enableDebugMode) && $config->enableDebugMode === true), + 'debugSettings' => [ + 'all' => $web2PrintConfig['pdfreactorEnableDebugMode'] || (isset($config->enableDebugMode) && $config->enableDebugMode === true), + ], 'addOverprint' => isset($config->addOverprint) && $config->addOverprint === true, 'httpsMode' => $web2PrintConfig['pdfreactorEnableLenientHttpsMode'] ? HttpsMode::LENIENT : HttpsMode::STRICT, ]; @@ -75,9 +92,9 @@ protected function getClient(): \com\realobjects\pdfreactor\webservice\client\PD $pdfreactor = new \com\realobjects\pdfreactor\webservice\client\PDFreactor($protocol . '://' . $web2PrintConfig['pdfreactorServer'] . ':' . $port . '/service/rest'); - if (trim($web2PrintConfig['pdfreactorApiKey'])) { - $pdfreactor->apiKey = trim($web2PrintConfig['pdfreactorApiKey']); - } + //if (trim($web2PrintConfig['pdfreactorApiKey'])) { + $pdfreactor->apiKey = trim($web2PrintConfig['pdfreactorApiKey']); + //} return $pdfreactor; } @@ -179,8 +196,8 @@ public function getProcessingOptions(): array $options[] = [ 'name' => 'javaScriptMode', 'type' => 'select', - 'values' => [JavaScriptMode::ENABLED, JavaScriptMode::DISABLED, JavaScriptMode::ENABLED_NO_LAYOUT], - 'default' => JavaScriptMode::ENABLED, + 'values' => [self::JAVA_SCRIPT_MODE_ENABLED, self::JAVA_SCRIPT_MODE_DISABLED, self::JAVA_SCRIPT_MODE_ENABLED_NO_LAYOUT], + 'default' => self::JAVA_SCRIPT_MODE_ENABLED, ]; $options[] = [ diff --git a/tests/Model/Processor/ProcessorTest.php b/tests/Model/Processor/ProcessorTest.php index 7ee4f97..19016b5 100644 --- a/tests/Model/Processor/ProcessorTest.php +++ b/tests/Model/Processor/ProcessorTest.php @@ -54,10 +54,14 @@ public function testPdfReactor() $pdfReactorConfig = [ 'adapterConfig' => [ - 'javaScriptMode' => 0, + 'javaScriptSettings' => [ + 'enabled' => false, + ], 'addLinks' => true, 'appendLog' => true, - 'enableDebugMode' => true, + 'debugSettings' => [ + 'all' => true, + ], ], ]; $this->checkProcessors('PdfReactor', $pdfReactorConfig);