QR-Zahlteil auf SIX 2.3 aktualisieren
Tests / test (push) Successful in 49s

This commit is contained in:
dh
2026-09-17 09:29:02 +00:00
parent d36bd29c31
commit b7c4b16987
37 changed files with 3959 additions and 3908 deletions
+18 -4
View File
@@ -19,6 +19,13 @@ Abmelden des WebHooks beim Löschen einer Instanz.
- erzeugt optional einen Schweizer QR-Zahlteil
- unterstützt den konfigurierbaren MWST-Ausweis
## QR-Zahlteil
Der QR-Zahlteil verwendet strukturierte Adressen (`S`) nach SIX SPS 2.3.
Er wird nur bei hinterlegter normaler CH/LI-IBAN und positivem Gesamtbetrag
erzeugt. QR-IBANs werden abgelehnt, da der Report keine QR-Referenz führt.
Benutzer- und Zahlungsempfängeradresse benötigen Name, PLZ, Ort und ISO-2-Land.
## Konfiguration
| Property | Beschreibung |
@@ -32,10 +39,17 @@ Abmelden des WebHooks beim Löschen einer Instanz.
| `FooterText` | PDF-Fusszeile |
| `EnableVAT` | aktiviert MWST |
| `VATPercentage` | MWST-Satz |
| `CreditorName` | Zahlungsempfänger |
| `CreditorAddress` | Adresse Zahlungsempfänger |
| `CreditorCity` | PLZ/Ort Zahlungsempfänger |
| `BankIBAN` | IBAN für QR-Zahlteil |
| `CreditorName` | Name des Zahlungsempfängers |
| `CreditorStreet` | Strasse des Zahlungsempfängers |
| `CreditorBuildingNumber` | Hausnummer des Zahlungsempfängers |
| `CreditorPostalCode` | PLZ des Zahlungsempfängers |
| `CreditorTown` | Ort des Zahlungsempfängers |
| `CreditorCountry` | ISO-2-Ländercode des Zahlungsempfängers |
| `BankIBAN` | normale CH/LI-IBAN für den QR-Zahlteil |
Bei einem Update müssen bisher kombinierte Benutzer- und Empfängeradressen einmalig
in die strukturierten Felder aufgeteilt und kontrolliert werden. Bei aktiver IBAN
verhindern fehlende QR-Pflichtfelder die Reporterzeugung.
## Bedienung
+26 -8
View File
@@ -47,13 +47,28 @@
},
{
"type": "ValidationTextBox",
"name": "CreditorAddress",
"caption": "Zahlungsempfänger Strasse/Nr."
"name": "CreditorStreet",
"caption": "Zahlungsempfänger Strasse"
},
{
"type": "ValidationTextBox",
"name": "CreditorCity",
"caption": "Zahlungsempfänger PLZ/Ort"
"name": "CreditorBuildingNumber",
"caption": "Zahlungsempfänger Hausnummer"
},
{
"type": "ValidationTextBox",
"name": "CreditorPostalCode",
"caption": "Zahlungsempfänger PLZ"
},
{
"type": "ValidationTextBox",
"name": "CreditorTown",
"caption": "Zahlungsempfänger Ort"
},
{
"type": "ValidationTextBox",
"name": "CreditorCountry",
"caption": "Zahlungsempfänger Land (ISO-2)"
},
{
"type": "ValidationTextBox",
@@ -68,10 +83,13 @@
"delete": true,
"sortable": true,
"columns": [
{ "caption": "ID", "name": "id", "width": "10%", "add": "", "edit": { "type": "ValidationTextBox" } },
{ "caption": "Name", "name": "name", "width": "20%", "add": "", "edit": { "type": "ValidationTextBox" } },
{ "caption": "Adresse", "name": "address", "width": "20%", "add": "", "edit": { "type": "ValidationTextBox" } },
{ "caption": "Ort", "name": "city", "width": "20%", "add": "", "edit": { "type": "ValidationTextBox" } }
{ "caption": "ID", "name": "id", "width": "8%", "add": "", "edit": { "type": "ValidationTextBox" } },
{ "caption": "Name", "name": "name", "width": "18%", "add": "", "edit": { "type": "ValidationTextBox" } },
{ "caption": "Strasse", "name": "street", "width": "18%", "add": "", "edit": { "type": "ValidationTextBox" } },
{ "caption": "Nr.", "name": "building_number", "width": "8%", "add": "", "edit": { "type": "ValidationTextBox" } },
{ "caption": "PLZ", "name": "postal_code", "width": "10%", "add": "", "edit": { "type": "ValidationTextBox" } },
{ "caption": "Ort", "name": "town", "width": "18%", "add": "", "edit": { "type": "ValidationTextBox" } },
{ "caption": "Land", "name": "country", "width": "8%", "add": "CH", "edit": { "type": "ValidationTextBox" } }
]
},
{
+1 -1
View File
@@ -1,5 +1,5 @@
{
"require": {
"tecnickcom/tcpdf": "6.3.5"
"tecnickcom/tcpdf": "6.11.3"
}
}
+28 -17
View File
@@ -4,24 +4,31 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "1d3d629fb7b7860f275198d08db11d75",
"content-hash": "61565f47f8edbe294fbfa2f4cd0ab261",
"packages": [
{
"name": "tecnickcom/tcpdf",
"version": "6.3.5",
"version": "6.11.3",
"source": {
"type": "git",
"url": "https://github.com/tecnickcom/TCPDF.git",
"reference": "19a535eaa7fb1c1cac499109deeb1a7a201b4549"
"reference": "b18f6119161019916c5bb07cb8da5205ae5c1b63"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/19a535eaa7fb1c1cac499109deeb1a7a201b4549",
"reference": "19a535eaa7fb1c1cac499109deeb1a7a201b4549",
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/b18f6119161019916c5bb07cb8da5205ae5c1b63",
"reference": "b18f6119161019916c5bb07cb8da5205ae5c1b63",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
"ext-curl": "*",
"php": ">=7.1.0"
},
"suggest": {
"ext-gd": "Enables additional image handling in some workflows.",
"ext-imagick": "Enables additional image format support when available.",
"ext-zlib": "Recommended for compressed streams and related features.",
"tecnickcom/tc-lib-pdf": "Modern replacement for TCPDF for new projects."
},
"type": "library",
"autoload": {
@@ -29,8 +36,6 @@
"config",
"include",
"tcpdf.php",
"tcpdf_parser.php",
"tcpdf_import.php",
"tcpdf_barcodes_1d.php",
"tcpdf_barcodes_2d.php",
"include/tcpdf_colors.php",
@@ -46,7 +51,7 @@
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0-only"
"LGPL-3.0-or-later"
],
"authors": [
{
@@ -55,8 +60,8 @@
"role": "lead"
}
],
"description": "TCPDF is a PHP class for generating PDF documents and barcodes.",
"homepage": "http://www.tcpdf.org/",
"description": "Deprecated legacy PDF engine for PHP. For new projects use tecnickcom/tc-lib-pdf.",
"homepage": "https://tcpdf.org",
"keywords": [
"PDFD32000-2008",
"TCPDF",
@@ -68,18 +73,24 @@
],
"support": {
"issues": "https://github.com/tecnickcom/TCPDF/issues",
"source": "https://github.com/tecnickcom/TCPDF/tree/6.3.5"
"source": "https://github.com/tecnickcom/TCPDF"
},
"time": "2020-02-14T14:20:12+00:00"
"funding": [
{
"url": "https://www.paypal.com/donate/?hosted_button_id=NZUEC5XS8MFBJ",
"type": "paypal"
}
],
"time": "2026-04-21T17:00:18+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"stability-flags": {},
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.0.0"
"platform": {},
"platform-dev": {},
"plugin-api-version": "2.9.0"
}
+15
View File
@@ -2,6 +2,21 @@
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
throw new RuntimeException($err);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit418d75d37a56e981b178936c5d087775::getLoader();
+166 -32
View File
@@ -42,21 +42,76 @@ namespace Composer\Autoload;
*/
class ClassLoader
{
/** @var \Closure(string):void */
private static $includeFile;
/** @var string|null */
private $vendorDir;
// PSR-4
/**
* @var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array<string, list<string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* List of PSR-0 prefixes
*
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
*
* @var array<string, array<string, list<string>>>
*/
private $prefixesPsr0 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var array<string, bool>
*/
private $missingClasses = array();
/** @var string|null */
private $apcuPrefix;
/**
* @var array<string, self>
*/
private static $registeredLoaders = array();
/**
* @param string|null $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
@@ -66,28 +121,42 @@ class ClassLoader
return array();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return list<string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return list<string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return array<string, string> Array of classname => path
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
* @param array<string, string> $classMap Class to filename map
*
* @return void
*/
public function addClassMap(array $classMap)
{
@@ -102,22 +171,25 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
$paths
);
}
@@ -126,19 +198,19 @@ class ClassLoader
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
$this->prefixesPsr0[$first][$prefix] = $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
$paths
);
}
}
@@ -147,25 +219,28 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
$paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
@@ -175,18 +250,18 @@ class ClassLoader
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
$this->prefixDirsPsr4[$prefix] = $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
$paths
);
}
}
@@ -195,8 +270,10 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
@@ -211,10 +288,12 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
@@ -234,6 +313,8 @@ class ClassLoader
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
@@ -256,6 +337,8 @@ class ClassLoader
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
@@ -276,6 +359,8 @@ class ClassLoader
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
@@ -296,33 +381,55 @@ class ClassLoader
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
* @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
$includeFile = self::$includeFile;
$includeFile($file);
return true;
}
return null;
}
/**
@@ -367,6 +474,21 @@ class ClassLoader
return $file;
}
/**
* Returns the currently registered loaders keyed by their corresponding vendor directories.
*
* @return array<string, self>
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
@@ -432,14 +554,26 @@ class ClassLoader
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
}
@@ -1,218 +1,396 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
/**
* This class is copied in every Composer installed project and available to all
*
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
private static $installed = array (
'root' =>
array (
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'aliases' =>
array (
),
'reference' => '5e48a63a2b0922cd9d1f1b239369d265719bf161',
'name' => '__root__',
),
'versions' =>
array (
'__root__' =>
array (
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'aliases' =>
array (
),
'reference' => '5e48a63a2b0922cd9d1f1b239369d265719bf161',
),
'tecnickcom/tcpdf' =>
array (
'pretty_version' => '6.3.5',
'version' => '6.3.5.0',
'aliases' =>
array (
),
'reference' => '19a535eaa7fb1c1cac499109deeb1a7a201b4549',
),
),
);
/**
* @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
* @internal
*/
private static $selfDir = null;
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool
*/
private static $installedIsLocalDir;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
* Returns a list of all package names which are present, either by being installed, replaced or provided
*
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
public static function getInstalledPackages()
{
return array_keys(self::$installed['versions']);
}
public static function isInstalled($packageName)
{
return isset(self::$installed['versions'][$packageName]);
}
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints($constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
public static function getVersionRanges($packageName)
{
if (!isset(self::$installed['versions'][$packageName])) {
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
$ranges = array();
if (isset(self::$installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = self::$installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', self::$installed['versions'][$packageName])) {
$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', self::$installed['versions'][$packageName])) {
$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', self::$installed['versions'][$packageName])) {
$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
public static function getVersion($packageName)
{
if (!isset(self::$installed['versions'][$packageName])) {
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
if (!isset(self::$installed['versions'][$packageName]['version'])) {
return null;
}
return self::$installed['versions'][$packageName]['version'];
}
public static function getPrettyVersion($packageName)
{
if (!isset(self::$installed['versions'][$packageName])) {
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return self::$installed['versions'][$packageName]['pretty_version'];
}
public static function getReference($packageName)
{
if (!isset(self::$installed['versions'][$packageName])) {
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
if (!isset(self::$installed['versions'][$packageName]['reference'])) {
return null;
}
return self::$installed['versions'][$packageName]['reference'];
}
public static function getRootPackage()
{
return self::$installed['root'];
}
public static function getRawData()
{
return self::$installed;
}
public static function reload($data)
{
self::$installed = $data;
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
/**
* Returns a list of all package names with a specific type e.g. 'library'
*
* @param string $type
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackagesByType($type)
{
$packagesByType = array();
foreach (self::getInstalled() as $installed) {
foreach ($installed['versions'] as $name => $package) {
if (isset($package['type']) && $package['type'] === $type) {
$packagesByType[] = $name;
}
}
}
return $packagesByType;
}
/**
* Checks whether the given package is installed
*
* This also returns true if the package name is provided or replaced by another package
*
* @param string $packageName
* @param bool $includeDevRequirements
* @return bool
*/
public static function isInstalled($packageName, $includeDevRequirements = true)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
}
}
return false;
}
/**
* Checks whether the given package satisfies a version constraint
*
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
*
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
*
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
* @param string $packageName
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
* @return bool
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
/**
* Returns a version constraint representing all the range(s) which are installed for a given package
*
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
* whether a given version of a package is installed, and not just whether it exists
*
* @param string $packageName
* @return string Version constraint usable with composer/semver
*/
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
*/
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
*/
public static function getInstallPath($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @return array
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
/**
* Returns the raw installed.php data for custom implementations
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = include __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
return self::$installed;
}
/**
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
return self::getInstalled();
}
/**
* Lets you reload the static array from another file
*
* This is only useful for complex integrations in which a project needs to use
* this class but then also needs to execute another project's autoloader in process,
* and wants to ensure both projects have access to their version of installed.php.
*
* A typical case would be PHPUnit, where it would need to make sure it reads all
* the data it needs from this class, then call reload() with
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
* the project in which it runs can then also use this class safely, without
* interference between PHPUnit's dependencies and the project's dependencies.
*
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
// when using reload, we disable the duplicate protection to ensure that self::$installed data is
// always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
// so we have to assume it does not, and that may result in duplicate data being returned when listing
// all installed packages for example
self::$installedIsLocalDir = false;
}
/**
* @return string
*/
private static function getSelfDir()
{
if (self::$selfDir === null) {
self::$selfDir = strtr(__DIR__, '\\', '/');
}
return self::$selfDir;
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
$copiedLocalDir = false;
if (self::$canGetVendors) {
$selfDir = self::getSelfDir();
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
$vendorDir = strtr($vendorDir, '\\', '/');
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
self::$installedByVendor[$vendorDir] = $required;
$installed[] = $required;
if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
self::$installed = $required;
self::$installedIsLocalDir = true;
}
}
if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
$copiedLocalDir = true;
}
}
}
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
} else {
self::$installed = array();
}
}
if (self::$installed !== array() && !$copiedLocalDir) {
$installed[] = self::$installed;
}
return $installed;
}
}
@@ -2,7 +2,7 @@
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
@@ -18,7 +18,5 @@ return array(
'TCPDF_FONTS' => $vendorDir . '/tecnickcom/tcpdf/include/tcpdf_fonts.php',
'TCPDF_FONT_DATA' => $vendorDir . '/tecnickcom/tcpdf/include/tcpdf_font_data.php',
'TCPDF_IMAGES' => $vendorDir . '/tecnickcom/tcpdf/include/tcpdf_images.php',
'TCPDF_IMPORT' => $vendorDir . '/tecnickcom/tcpdf/tcpdf_import.php',
'TCPDF_PARSER' => $vendorDir . '/tecnickcom/tcpdf/tcpdf_parser.php',
'TCPDF_STATIC' => $vendorDir . '/tecnickcom/tcpdf/include/tcpdf_static.php',
);
@@ -2,7 +2,7 @@
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
@@ -2,7 +2,7 @@
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
@@ -25,30 +25,11 @@ class ComposerAutoloaderInit418d75d37a56e981b178936c5d087775
require __DIR__ . '/platform_check.php';
spl_autoload_register(array('ComposerAutoloaderInit418d75d37a56e981b178936c5d087775', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit418d75d37a56e981b178936c5d087775', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit418d75d37a56e981b178936c5d087775::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit418d75d37a56e981b178936c5d087775::getInitializer($loader));
$loader->register(true);
@@ -19,8 +19,6 @@ class ComposerStaticInit418d75d37a56e981b178936c5d087775
'TCPDF_FONTS' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/tcpdf_fonts.php',
'TCPDF_FONT_DATA' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/tcpdf_font_data.php',
'TCPDF_IMAGES' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/tcpdf_images.php',
'TCPDF_IMPORT' => __DIR__ . '/..' . '/tecnickcom/tcpdf/tcpdf_import.php',
'TCPDF_PARSER' => __DIR__ . '/..' . '/tecnickcom/tcpdf/tcpdf_parser.php',
'TCPDF_STATIC' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/tcpdf_static.php',
);
+26 -14
View File
@@ -2,23 +2,30 @@
"packages": [
{
"name": "tecnickcom/tcpdf",
"version": "6.3.5",
"version_normalized": "6.3.5.0",
"version": "6.11.3",
"version_normalized": "6.11.3.0",
"source": {
"type": "git",
"url": "https://github.com/tecnickcom/TCPDF.git",
"reference": "19a535eaa7fb1c1cac499109deeb1a7a201b4549"
"reference": "b18f6119161019916c5bb07cb8da5205ae5c1b63"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/19a535eaa7fb1c1cac499109deeb1a7a201b4549",
"reference": "19a535eaa7fb1c1cac499109deeb1a7a201b4549",
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/b18f6119161019916c5bb07cb8da5205ae5c1b63",
"reference": "b18f6119161019916c5bb07cb8da5205ae5c1b63",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
"ext-curl": "*",
"php": ">=7.1.0"
},
"time": "2020-02-14T14:20:12+00:00",
"suggest": {
"ext-gd": "Enables additional image handling in some workflows.",
"ext-imagick": "Enables additional image format support when available.",
"ext-zlib": "Recommended for compressed streams and related features.",
"tecnickcom/tc-lib-pdf": "Modern replacement for TCPDF for new projects."
},
"time": "2026-04-21T17:00:18+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -26,8 +33,6 @@
"config",
"include",
"tcpdf.php",
"tcpdf_parser.php",
"tcpdf_import.php",
"tcpdf_barcodes_1d.php",
"tcpdf_barcodes_2d.php",
"include/tcpdf_colors.php",
@@ -43,7 +48,7 @@
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0-only"
"LGPL-3.0-or-later"
],
"authors": [
{
@@ -52,8 +57,8 @@
"role": "lead"
}
],
"description": "TCPDF is a PHP class for generating PDF documents and barcodes.",
"homepage": "http://www.tcpdf.org/",
"description": "Deprecated legacy PDF engine for PHP. For new projects use tecnickcom/tc-lib-pdf.",
"homepage": "https://tcpdf.org",
"keywords": [
"PDFD32000-2008",
"TCPDF",
@@ -65,10 +70,17 @@
],
"support": {
"issues": "https://github.com/tecnickcom/TCPDF/issues",
"source": "https://github.com/tecnickcom/TCPDF/tree/6.3.5"
"source": "https://github.com/tecnickcom/TCPDF"
},
"funding": [
{
"url": "https://www.paypal.com/donate/?hosted_button_id=NZUEC5XS8MFBJ",
"type": "paypal"
}
],
"install-path": "../tecnickcom/tcpdf"
}
],
"dev": true
"dev": true,
"dev-package-names": []
}
+29 -30
View File
@@ -1,33 +1,32 @@
<?php return array (
'root' =>
array (
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'aliases' =>
array (
<?php return array(
'root' => array(
'name' => '__root__',
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'reference' => null,
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev' => true,
),
'reference' => '5e48a63a2b0922cd9d1f1b239369d265719bf161',
'name' => '__root__',
),
'versions' =>
array (
'__root__' =>
array (
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'aliases' =>
array (
),
'reference' => '5e48a63a2b0922cd9d1f1b239369d265719bf161',
'versions' => array(
'__root__' => array(
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'reference' => null,
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev_requirement' => false,
),
'tecnickcom/tcpdf' => array(
'pretty_version' => '6.11.3',
'version' => '6.11.3.0',
'reference' => 'b18f6119161019916c5bb07cb8da5205ae5c1b63',
'type' => 'library',
'install_path' => __DIR__ . '/../tecnickcom/tcpdf',
'aliases' => array(),
'dev_requirement' => false,
),
),
'tecnickcom/tcpdf' =>
array (
'pretty_version' => '6.3.5',
'version' => '6.3.5.0',
'aliases' =>
array (
),
'reference' => '19a535eaa7fb1c1cac499109deeb1a7a201b4549',
),
),
);
@@ -4,11 +4,22 @@
$issues = array();
if (!(PHP_VERSION_ID >= 50300)) {
$issues[] = 'Your Composer dependencies require a PHP version ">= 5.3.0". You are running ' . PHP_VERSION . '.';
if (!(PHP_VERSION_ID >= 70100)) {
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.0". You are running ' . PHP_VERSION . '.';
}
if ($issues) {
echo 'Composer detected issues in your platform:' . "\n\n" . implode("\n", $issues);
exit(104);
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
} elseif (!headers_sent()) {
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
}
}
throw new \RuntimeException(
'Composer detected issues in your platform: ' . implode(' ', $issues)
);
}
@@ -7,7 +7,7 @@
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
2002-2019 Nicola Asuni - Tecnick.com LTD
2002-2026 Nicola Asuni - Tecnick.com LTD
**********************************************************************
**********************************************************************
@@ -15,7 +15,7 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://www.fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -184,7 +184,7 @@ Library.
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://www.fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -828,7 +828,7 @@ the "copyright" line and a pointer to where the full notice is found.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
@@ -847,14 +847,14 @@ might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
<https://www.gnu.org/philosophy/why-not-lgpl.html>.
**********************************************************************
**********************************************************************
@@ -1 +1 @@
6.3.5
6.11.3
@@ -1,47 +1,75 @@
{
"name": "tecnickcom/tcpdf",
"version": "6.3.5",
"homepage": "http://www.tcpdf.org/",
"type": "library",
"description": "TCPDF is a PHP class for generating PDF documents and barcodes.",
"keywords": [
"PDF",
"tcpdf",
"PDFD32000-2008",
"qrcode",
"datamatrix",
"pdf417",
"barcodes"
],
"license": "LGPL-3.0-only",
"authors": [
{
"name": "Nicola Asuni",
"email": "info@tecnick.com",
"role": "lead"
}
],
"require": {
"php": ">=5.3.0"
},
"autoload": {
"classmap": [
"config",
"include",
"tcpdf.php",
"tcpdf_parser.php",
"tcpdf_import.php",
"tcpdf_barcodes_1d.php",
"tcpdf_barcodes_2d.php",
"include/tcpdf_colors.php",
"include/tcpdf_filters.php",
"include/tcpdf_font_data.php",
"include/tcpdf_fonts.php",
"include/tcpdf_images.php",
"include/tcpdf_static.php",
"include/barcodes/datamatrix.php",
"include/barcodes/pdf417.php",
"include/barcodes/qrcode.php"
"name": "tecnickcom/tcpdf",
"type": "library",
"description": "Deprecated legacy PDF engine for PHP. For new projects use tecnickcom/tc-lib-pdf.",
"keywords": [
"PDF",
"tcpdf",
"PDFD32000-2008",
"qrcode",
"datamatrix",
"pdf417",
"barcodes"
],
"homepage": "https://tcpdf.org",
"license": "LGPL-3.0-or-later",
"authors": [
{
"name": "Nicola Asuni",
"email": "info@tecnick.com",
"role": "lead"
}
],
"require": {
"php": ">=7.1.0",
"ext-curl": "*"
},
"suggest": {
"tecnickcom/tc-lib-pdf": "Modern replacement for TCPDF for new projects.",
"ext-gd": "Enables additional image handling in some workflows.",
"ext-imagick": "Enables additional image format support when available.",
"ext-zlib": "Recommended for compressed streams and related features."
},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"sort-packages": true
},
"autoload": {
"classmap": [
"config",
"include",
"tcpdf.php",
"tcpdf_barcodes_1d.php",
"tcpdf_barcodes_2d.php",
"include/tcpdf_colors.php",
"include/tcpdf_filters.php",
"include/tcpdf_font_data.php",
"include/tcpdf_fonts.php",
"include/tcpdf_images.php",
"include/tcpdf_static.php",
"include/barcodes/datamatrix.php",
"include/barcodes/pdf417.php",
"include/barcodes/qrcode.php"
]
},
"archive": {
"exclude": [
"/.github",
"/.phpdoc",
"/examples",
"/scripts",
"/tests"
]
},
"support": {
"issues": "https://github.com/tecnickcom/TCPDF/issues",
"source": "https://github.com/tecnickcom/TCPDF"
},
"funding": [
{
"type": "paypal",
"url": "https://www.paypal.com/donate/?hosted_button_id=NZUEC5XS8MFBJ"
}
]
}
}
@@ -6,9 +6,9 @@
//
// Description : Configuration file for TCPDF.
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// License : GNU-LGPL v3 (https://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
// Copyright (C) 2004-2014 Nicola Asuni - Tecnick.com LTD
// Copyright (C) 2004-2014 2026 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
@@ -23,7 +23,7 @@
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with TCPDF. If not, see <http://www.gnu.org/licenses/>.
// along with TCPDF. If not, see <https://www.gnu.org/licenses/>.
//
// See LICENSE.TXT file for more information.
//============================================================+
@@ -114,7 +114,7 @@ define ('PDF_HEADER_TITLE', 'TCPDF Example');
/**
* Header description string.
*/
define ('PDF_HEADER_STRING', "by Nicola Asuni - Tecnick.com\nwww.tcpdf.org");
define ('PDF_HEADER_STRING', "by2026 Nicola Asuni - Tecnick.com\nwww.tcpdf.org");
/**
* Document unit of measure [pt=point, mm=millimeter, cm=centimeter, in=inch].
@@ -212,6 +212,14 @@ define('K_THAI_TOPCHARS', true);
*/
define('K_TCPDF_CALLS_IN_HTML', false);
/**
* List of TCPDF methods that are allowed to be called using HTML syntax.
* Note: each method name must end with surrounded with | (pipe) character.
* The constant K_TCPDF_CALLS_IN_HTML must be set to true.
* IMPORTANT: For security reason, disable this feature if you are allowing user HTML content.
*/
define('K_ALLOWED_TCPDF_TAGS', '');
/**
* If true and PHP version is greater than 5, then the Error() method throw new exception instead of terminating the execution.
*/
@@ -5,9 +5,9 @@
// Begin : 2010-06-07
// Last Update : 2014-05-06
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// License : GNU-LGPL v3 (https://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
// Copyright (C) 2010-2014 Nicola Asuni - Tecnick.com LTD
// Copyright (C) 2010-2014 2026 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
@@ -22,7 +22,7 @@
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with TCPDF. If not, see <http://www.gnu.org/licenses/>.
// along with TCPDF. If not, see <https://www.gnu.org/licenses/>.
//
// See LICENSE.TXT file for more information.
// -------------------------------------------------------------------
@@ -229,7 +229,7 @@ class Datamatrix {
/**
* This is the class constructor.
* Creates a datamatrix object
* @param $code (string) Code to represent using Datamatrix.
* @param string $code Code to represent using Datamatrix.
* @public
*/
public function __construct($code) {
@@ -355,11 +355,11 @@ class Datamatrix {
/**
* Product of two numbers in a Power-of-Two Galois Field
* @param $a (int) first number to multiply.
* @param $b (int) second number to multiply.
* @param $log (array) Log table.
* @param $alog (array) Anti-Log table.
* @param $gf (array) Number of Factors of the Reed-Solomon polynomial.
* @param int $a first number to multiply.
* @param int $b second number to multiply.
* @param array $log Log table.
* @param array $alog Anti-Log table.
* @param int $gf Number of Factors of the Reed-Solomon polynomial.
* @return int product
* @protected
*/
@@ -372,12 +372,12 @@ class Datamatrix {
/**
* Add error correction codewords to data codewords array (ANNEX E).
* @param $wd (array) Array of datacodewords.
* @param $nb (int) Number of blocks.
* @param $nd (int) Number of data codewords per block.
* @param $nc (int) Number of correction codewords per block.
* @param $gf (int) numner of fields on log/antilog table (power of 2).
* @param $pp (int) The value of its prime modulus polynomial (301 for ECC200).
* @param array $wd Array of datacodewords.
* @param int $nb Number of blocks.
* @param int $nd Number of data codewords per block.
* @param int $nc Number of correction codewords per block.
* @param int $gf numner of fields on log/antilog table (power of 2).
* @param int $pp The value of its prime modulus polynomial (301 for ECC200).
* @return array data codewords + error codewords
* @protected
*/
@@ -438,9 +438,9 @@ class Datamatrix {
/**
* Return the 253-state codeword
* @param $cwpad (int) Pad codeword.
* @param $cwpos (int) Number of data codewords from the beginning of encoded data.
* @return pad codeword
* @param int $cwpad Pad codeword.
* @param int $cwpos Number of data codewords from the beginning of encoded data.
* @return int pad codeword
* @protected
*/
protected function get253StateCodeword($cwpad, $cwpos) {
@@ -453,9 +453,9 @@ class Datamatrix {
/**
* Return the 255-state codeword
* @param $cwpad (int) Pad codeword.
* @param $cwpos (int) Number of data codewords from the beginning of encoded data.
* @return pad codeword
* @param int $cwpad Pad codeword.
* @param int $cwpos Number of data codewords from the beginning of encoded data.
* @return int pad codeword
* @protected
*/
protected function get255StateCodeword($cwpad, $cwpos) {
@@ -468,8 +468,8 @@ class Datamatrix {
/**
* Returns true if the char belongs to the selected mode
* @param $chr (int) Character (byte) to check.
* @param $mode (int) Current encoding mode.
* @param int $chr Character (byte) to check.
* @param int $mode Current encoding mode.
* @return boolean true if the char is of the selected mode.
* @protected
*/
@@ -514,9 +514,9 @@ class Datamatrix {
/**
* The look-ahead test scans the data to be encoded to find the best mode (Annex P - steps from J to S).
* @param $data (string) data to encode
* @param $pos (int) current position
* @param $mode (int) current encoding mode
* @param string $data data to encode
* @param int $pos current position
* @param int $mode current encoding mode
* @return int encoding mode
* @protected
*/
@@ -646,8 +646,8 @@ class Datamatrix {
/**
* Get the switching codeword to a new encoding mode (latch codeword)
* @param $mode (int) New encoding mode.
* @return (int) Switch codeword.
* @param int $mode New encoding mode.
* @return int Switch codeword.
* @protected
*/
protected function getSwitchEncodingCodeword($mode) {
@@ -685,8 +685,8 @@ class Datamatrix {
/**
* Choose the minimum matrix size and return the max number of data codewords.
* @param $numcw (int) Number of current codewords.
* @return number of data codewords in matrix
* @param int $numcw Number of current codewords.
* @return int number of data codewords in matrix
* @protected
*/
protected function getMaxDataCodewords($numcw) {
@@ -700,7 +700,7 @@ class Datamatrix {
/**
* Get high level encoding using the minimum symbol data characters for ECC 200
* @param $data (string) data to encode
* @param string $data data to encode
* @return array of codewords
* @protected
*/
@@ -778,7 +778,7 @@ class Datamatrix {
if (isset($this->chset['SH1'][$chr])) {
$temp_cw[] = 0; // shift 1
$shiftset = $this->chset['SH1'];
} elseif (isset($chr, $this->chset['SH2'][$chr])) {
} elseif (isset($this->chset['SH2'][$chr])) {
$temp_cw[] = 1; // shift 2
$shiftset = $this->chset['SH2'];
} elseif (($enc == ENC_C40) AND isset($this->chset['S3C'][$chr])) {
@@ -970,13 +970,13 @@ class Datamatrix {
/**
* Places "chr+bit" with appropriate wrapping within array[].
* (Annex F - ECC 200 symbol character placement)
* @param $marr (array) Array of symbols.
* @param $nrow (int) Number of rows.
* @param $ncol (int) Number of columns.
* @param $row (int) Row number.
* @param $col (int) Column number.
* @param $chr (int) Char byte.
* @param $bit (int) Bit.
* @param array $marr Array of symbols.
* @param int $nrow Number of rows.
* @param int $ncol Number of columns.
* @param int $row Row number.
* @param int $col Column number.
* @param int $chr Char byte.
* @param int $bit Bit.
* @return array
* @protected
*/
@@ -996,12 +996,12 @@ class Datamatrix {
/**
* Places the 8 bits of a utah-shaped symbol character.
* (Annex F - ECC 200 symbol character placement)
* @param $marr (array) Array of symbols.
* @param $nrow (int) Number of rows.
* @param $ncol (int) Number of columns.
* @param $row (int) Row number.
* @param $col (int) Column number.
* @param $chr (int) Char byte.
* @param array $marr Array of symbols.
* @param int $nrow Number of rows.
* @param int $ncol Number of columns.
* @param int $row Row number.
* @param int $col Column number.
* @param int $chr Char byte.
* @return array
* @protected
*/
@@ -1020,10 +1020,10 @@ class Datamatrix {
/**
* Places the 8 bits of the first special corner case.
* (Annex F - ECC 200 symbol character placement)
* @param $marr (array) Array of symbols.
* @param $nrow (int) Number of rows.
* @param $ncol (int) Number of columns.
* @param $chr (int) Char byte.
* @param array $marr Array of symbols.
* @param int $nrow Number of rows.
* @param int $ncol Number of columns.
* @param int $chr Char byte.
* @return array
* @protected
*/
@@ -1042,10 +1042,10 @@ class Datamatrix {
/**
* Places the 8 bits of the second special corner case.
* (Annex F - ECC 200 symbol character placement)
* @param $marr (array) Array of symbols.
* @param $nrow (int) Number of rows.
* @param $ncol (int) Number of columns.
* @param $chr (int) Char byte.
* @param array $marr Array of symbols.
* @param int $nrow Number of rows.
* @param int $ncol Number of columns.
* @param int $chr Char byte.
* @return array
* @protected
*/
@@ -1064,10 +1064,10 @@ class Datamatrix {
/**
* Places the 8 bits of the third special corner case.
* (Annex F - ECC 200 symbol character placement)
* @param $marr (array) Array of symbols.
* @param $nrow (int) Number of rows.
* @param $ncol (int) Number of columns.
* @param $chr (int) Char byte.
* @param array $marr Array of symbols.
* @param int $nrow Number of rows.
* @param int $ncol Number of columns.
* @param int $chr Char byte.
* @return array
* @protected
*/
@@ -1086,10 +1086,10 @@ class Datamatrix {
/**
* Places the 8 bits of the fourth special corner case.
* (Annex F - ECC 200 symbol character placement)
* @param $marr (array) Array of symbols.
* @param $nrow (int) Number of rows.
* @param $ncol (int) Number of columns.
* @param $chr (int) Char byte.
* @param array $marr Array of symbols.
* @param int $nrow Number of rows.
* @param int $ncol Number of columns.
* @param int $chr Char byte.
* @return array
* @protected
*/
@@ -1108,8 +1108,8 @@ class Datamatrix {
/**
* Build a placement map.
* (Annex F - ECC 200 symbol character placement)
* @param $nrow (int) Number of rows.
* @param $ncol (int) Number of columns.
* @param int $nrow Number of rows.
* @param int $ncol Number of columns.
* @return array
* @protected
*/
@@ -5,9 +5,9 @@
// Begin : 2010-06-03
// Last Update : 2014-04-25
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// License : GNU-LGPL v3 (https://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
// Copyright (C) 2010-2013 Nicola Asuni - Tecnick.com LTD
// Copyright (C) 2010-2013 2026 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
@@ -22,7 +22,7 @@
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with TCPDF. If not, see <http://www.gnu.org/licenses/>.
// along with TCPDF. If not, see <https://www.gnu.org/licenses/>.
//
// See LICENSE.TXT file for more information.
// -------------------------------------------------------------------
@@ -523,10 +523,10 @@ class PDF417 {
/**
* This is the class constructor.
* Creates a PDF417 object
* @param $code (string) code to represent using PDF417
* @param $ecl (int) error correction level (0-8); default -1 = automatic correction level
* @param $aspectratio (float) the width to height of the symbol (excluding quiet zones)
* @param $macro (array) information for macro block
* @param string $code code to represent using PDF417
* @param int $ecl error correction level (0-8); default -1 = automatic correction level
* @param float $aspectratio the width to height of the symbol (excluding quiet zones)
* @param array $macro information for macro block
* @public
*/
public function __construct($code, $ecl=-1, $aspectratio=2, $macro=array()) {
@@ -734,12 +734,13 @@ class PDF417 {
/**
* Returns the error correction level (0-8) to be used
* @param $ecl (int) error correction level
* @param $numcw (int) number of data codewords
* @param int $ecl error correction level
* @param int $numcw number of data codewords
* @return int error correction level
* @protected
*/
protected function getErrorCorrectionLevel($ecl, $numcw) {
$maxecl = 8; // starting error level
// check for automatic levels
if (($ecl < 0) OR ($ecl > 8)) {
if ($numcw < 41) {
@@ -755,7 +756,6 @@ class PDF417 {
}
}
// get maximum correction level
$maxecl = 8; // starting error level
$maxerrsize = (928 - $numcw); // available codewords for error
while ($maxecl > 0) {
$errsize = (2 << $ecl);
@@ -772,8 +772,8 @@ class PDF417 {
/**
* Returns the error correction codewords
* @param $cw (array) array of codewords including Symbol Length Descriptor and pad
* @param $ecl (int) error correction level 0-8
* @param array $cw array of codewords including Symbol Length Descriptor and pad
* @param int $ecl error correction level 0-8
* @return array of error correction codewords
* @protected
*/
@@ -809,8 +809,8 @@ class PDF417 {
/**
* Create array of sequences from input
* @param $code (string) code
* @return bidimensional array containing characters and classification
* @param string $code code
* @return array bi-dimensional array containing characters and classification
* @protected
*/
protected function getInputSequences($code) {
@@ -864,9 +864,9 @@ class PDF417 {
/**
* Compact data by mode.
* @param $mode (int) compaction mode number
* @param $code (string) data to compact
* @param $addmode (boolean) if true add the mode codeword at first position
* @param int $mode compaction mode number
* @param string $code data to compact
* @param boolean $addmode if true add the mode codeword at first position
* @return array of codewords
* @protected
*/
@@ -943,8 +943,8 @@ class PDF417 {
// tmp array for the 6 bytes block
$cw6 = array();
do {
$d = bcmod($t, '900');
$t = bcdiv($t, '900');
$d = bcmod($t, '900', 0);
$t = bcdiv($t, '900', 0);
// prepend the value to the beginning of the array
array_unshift($cw6, $d);
} while ($t != '0');
@@ -969,8 +969,8 @@ class PDF417 {
}
$t = '1'.$code;
do {
$d = bcmod($t, '900');
$t = bcdiv($t, '900');
$d = bcmod($t, '900', 0);
$t = bcdiv($t, '900', 0);
array_unshift($cw, $d);
} while ($t != '0');
$code = $rest;
File diff suppressed because it is too large Load Diff
@@ -5,9 +5,9 @@
// Begin : 2002-04-09
// Last Update : 2014-04-25
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// License : GNU-LGPL v3 (https://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
// Copyright (C) 2002-2013 Nicola Asuni - Tecnick.com LTD
// Copyright (C) 2002-2013 2026 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
@@ -22,7 +22,7 @@
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with TCPDF. If not, see <http://www.gnu.org/licenses/>.
// along with TCPDF. If not, see <https://www.gnu.org/licenses/>.
//
// See LICENSE.TXT file for more information.
// -------------------------------------------------------------------
@@ -240,9 +240,9 @@ class TCPDF_COLORS {
/**
* Return the Spot color array.
* @param $name (string) Name of the spot color.
* @param $spotc (array) Reference to an array of spot colors.
* @return (array) Spot color array or false if not defined.
* @param string $name Name of the spot color.
* @param array $spotc Reference to an array of spot colors.
* @return array|false Spot color array or false if not defined.
* @since 5.9.125 (2011-10-03)
* @public static
*/
@@ -264,10 +264,10 @@ class TCPDF_COLORS {
/**
* Returns an array (RGB or CMYK) from an html color name, or a six-digit (i.e. #3FE5AA), or three-digit (i.e. #7FF) hexadecimal color, or a javascript color array, or javascript color name.
* @param $hcolor (string) HTML color.
* @param $spotc (array) Reference to an array of spot colors.
* @param $defcol (array) Color to return in case of error.
* @return array RGB or CMYK color, or false in case of error.
* @param string $hcolor HTML color.
* @param array $spotc Reference to an array of spot colors.
* @param array $defcol Color to return in case of error.
* @return array|false RGB or CMYK color, or false in case of error.
* @public static
*/
public static function convertHTMLColorToDec($hcolor, &$spotc, $defcol=array('R'=>128,'G'=>128,'B'=>128)) {
@@ -275,7 +275,7 @@ class TCPDF_COLORS {
$color = strtolower($color);
// check for javascript color array syntax
if (strpos($color, '[') !== false) {
if (preg_match('/[\[][\"\'](t|g|rgb|cmyk)[\"\'][\,]?([0-9\.]*)[\,]?([0-9\.]*)[\,]?([0-9\.]*)[\,]?([0-9\.]*)[\]]/', $color, $m) > 0) {
if (preg_match('/[\[][\"\'](t|g|rgba|rgb|cmyk)[\"\'][\,]?([0-9\.]*+)[\,]?([0-9\.]*+)[\,]?([0-9\.]*+)[\,]?([0-9\.]*+)[\]]/', $color, $m) > 0) {
$returncolor = array();
switch ($m[1]) {
case 'cmyk': {
@@ -286,7 +286,8 @@ class TCPDF_COLORS {
$returncolor['K'] = max(0, min(100, (floatval($m[5]) * 100)));
break;
}
case 'rgb': {
case 'rgb':
case 'rgba': {
// RGB
$returncolor['R'] = max(0, min(255, (floatval($m[2]) * 255)));
$returncolor['G'] = max(0, min(255, (floatval($m[3]) * 255)));
@@ -317,6 +318,25 @@ class TCPDF_COLORS {
if (strlen($color) == 0) {
return $defcol;
}
// RGBA ARRAY
if (substr($color, 0, 4) == 'rgba') {
$codes = substr($color, 5);
$codes = str_replace(')', '', $codes);
$returncolor = explode(',', $codes);
// remove alpha component
array_pop($returncolor);
foreach ($returncolor as $key => $val) {
if (strpos($val, '%') > 0) {
// percentage
$returncolor[$key] = (255 * intval($val) / 100);
} else {
$returncolor[$key] = intval($val); /* floatize */
}
// normalize value
$returncolor[$key] = max(0, min(255, $returncolor[$key]));
}
return $returncolor;
}
// RGB ARRAY
if (substr($color, 0, 3) == 'rgb') {
$codes = substr($color, 4);
@@ -407,8 +427,8 @@ class TCPDF_COLORS {
/**
* Convert a color array into a string representation.
* @param $c (array) Array of colors.
* @return (string) The color array representation.
* @param array $c Array of colors.
* @return string The color array representation.
* @since 5.9.137 (2011-12-01)
* @public static
*/
@@ -438,7 +458,7 @@ class TCPDF_COLORS {
/**
* Convert color to javascript color.
* @param $color (string) color name or "#RRGGBB"
* @param string $color color name or "#RRGGBB"
* @protected
* @since 2.1.002 (2008-02-12)
* @public static
@@ -449,7 +469,7 @@ class TCPDF_COLORS {
}
if (!in_array($color, self::$jscolor)) {
// default transparent color
$color = $jscolor[0];
$color = self::$jscolor[0];
}
return 'color.'.$color;
}
@@ -5,9 +5,9 @@
// Begin : 2011-05-23
// Last Update : 2014-04-25
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// License : GNU-LGPL v3 (https://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
// Copyright (C) 2011-2013 Nicola Asuni - Tecnick.com LTD
// Copyright (C) 2011-2026 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
@@ -60,7 +60,7 @@ class TCPDF_FILTERS {
/**
* Get a list of available decoding filters.
* @return (array) Array of available filter decoders.
* @return array Array of available filter decoders.
* @since 1.0.000 (2011-05-23)
* @public static
*/
@@ -70,9 +70,9 @@ class TCPDF_FILTERS {
/**
* Decode data using the specified filter type.
* @param $filter (string) Filter name.
* @param $data (string) Data to decode.
* @return Decoded data string.
* @param string $filter Filter name.
* @param string $data Data to decode.
* @return string Decoded data string.
* @since 1.0.000 (2011-05-23)
* @public static
*/
@@ -130,8 +130,8 @@ class TCPDF_FILTERS {
/**
* Standard
* Default decoding filter (leaves data unchanged).
* @param $data (string) Data to decode.
* @return Decoded data string.
* @param string $data Data to decode.
* @return string Decoded data string.
* @since 1.0.000 (2011-05-23)
* @public static
*/
@@ -142,8 +142,8 @@ class TCPDF_FILTERS {
/**
* ASCIIHexDecode
* Decodes data encoded in an ASCII hexadecimal representation, reproducing the original binary data.
* @param $data (string) Data to decode.
* @return Decoded data string.
* @param string $data Data to decode.
* @return string Decoded data string.
* @since 1.0.000 (2011-05-23)
* @public static
*/
@@ -182,8 +182,8 @@ class TCPDF_FILTERS {
/**
* ASCII85Decode
* Decodes data encoded in an ASCII base-85 representation, reproducing the original binary data.
* @param $data (string) Data to decode.
* @return Decoded data string.
* @param string $data Data to decode.
* @return string Decoded data string.
* @since 1.0.000 (2011-05-23)
* @public static
*/
@@ -266,8 +266,8 @@ class TCPDF_FILTERS {
/**
* LZWDecode
* Decompresses data encoded using the LZW (Lempel-Ziv-Welch) adaptive compression method, reproducing the original text or binary data.
* @param $data (string) Data to decode.
* @return Decoded data string.
* @param string $data Data to decode.
* @return string Decoded data string.
* @since 1.0.000 (2011-05-23)
* @public static
*/
@@ -347,8 +347,8 @@ class TCPDF_FILTERS {
/**
* FlateDecode
* Decompresses data encoded using the zlib/deflate compression method, reproducing the original text or binary data.
* @param $data (string) Data to decode.
* @return Decoded data string.
* @param string $data Data to decode.
* @return string Decoded data string.
* @since 1.0.000 (2011-05-23)
* @public static
*/
@@ -364,7 +364,7 @@ class TCPDF_FILTERS {
/**
* RunLengthDecode
* Decompresses data encoded using a byte-oriented run-length encoding algorithm.
* @param $data (string) Data to decode.
* @param string $data Data to decode.
* @since 1.0.000 (2011-05-23)
* @public static
*/
@@ -400,8 +400,8 @@ class TCPDF_FILTERS {
/**
* CCITTFaxDecode (NOT IMPLEMETED - RETURN AN EXCEPTION)
* Decompresses data encoded using the CCITT facsimile standard, reproducing the original data (typically monochrome image data at 1 bit per pixel).
* @param $data (string) Data to decode.
* @return Decoded data string.
* @param string $data Data to decode.
* @return string Decoded data string.
* @since 1.0.000 (2011-05-23)
* @public static
*/
@@ -413,8 +413,8 @@ class TCPDF_FILTERS {
/**
* JBIG2Decode (NOT IMPLEMETED - RETURN AN EXCEPTION)
* Decompresses data encoded using the JBIG2 standard, reproducing the original monochrome (1 bit per pixel) image data (or an approximation of that data).
* @param $data (string) Data to decode.
* @return Decoded data string.
* @param string $data Data to decode.
* @return string Decoded data string.
* @since 1.0.000 (2011-05-23)
* @public static
*/
@@ -426,8 +426,8 @@ class TCPDF_FILTERS {
/**
* DCTDecode (NOT IMPLEMETED - RETURN AN EXCEPTION)
* Decompresses data encoded using a DCT (discrete cosine transform) technique based on the JPEG standard, reproducing image sample data that approximates the original data.
* @param $data (string) Data to decode.
* @return Decoded data string.
* @param string $data Data to decode.
* @return string Decoded data string.
* @since 1.0.000 (2011-05-23)
* @public static
*/
@@ -439,8 +439,8 @@ class TCPDF_FILTERS {
/**
* JPXDecode (NOT IMPLEMETED - RETURN AN EXCEPTION)
* Decompresses data encoded using the wavelet-based JPEG2000 standard, reproducing the original image data.
* @param $data (string) Data to decode.
* @return Decoded data string.
* @param string $data Data to decode.
* @return string Decoded data string.
* @since 1.0.000 (2011-05-23)
* @public static
*/
@@ -452,8 +452,8 @@ class TCPDF_FILTERS {
/**
* Crypt (NOT IMPLEMETED - RETURN AN EXCEPTION)
* Decrypts data encrypted by a security handler, reproducing the data as it was before encryption.
* @param $data (string) Data to decode.
* @return Decoded data string.
* @param string $data Data to decode.
* @return string Decoded data string.
* @since 1.0.000 (2011-05-23)
* @public static
*/
@@ -466,7 +466,7 @@ class TCPDF_FILTERS {
/**
* Throw an exception.
* @param $msg (string) The error message
* @param string $msg The error message
* @since 1.0.000 (2011-05-23)
* @public static
*/
@@ -5,9 +5,9 @@
// Begin : 2008-01-01
// Last Update : 2013-04-01
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// License : GNU-LGPL v3 (https://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
// Copyright (C) 2008-2013 Nicola Asuni - Tecnick.com LTD
// Copyright (C) 2008-2026 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
@@ -22,7 +22,7 @@
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with TCPDF. If not, see <http://www.gnu.org/licenses/>.
// along with TCPDF. If not, see <https://www.gnu.org/licenses/>.
//
// See LICENSE.TXT file for more information.
// -------------------------------------------------------------------
@@ -1,13 +1,13 @@
<?php
//============================================================+
// File name : tcpdf_fonts.php
// Version : 1.1.0
// Version : 1.1.1
// Begin : 2008-01-01
// Last Update : 2014-12-10
// Last Update : 2024-12-23
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// License : GNU-LGPL v3 (https://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
// Copyright (C) 2008-2014 Nicola Asuni - Tecnick.com LTD
// Copyright (C) 2008-2026 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
@@ -22,7 +22,7 @@
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with TCPDF. If not, see <http://www.gnu.org/licenses/>.
// along with TCPDF. If not, see <https://www.gnu.org/licenses/>.
//
// See LICENSE.TXT file for more information.
// -------------------------------------------------------------------
@@ -42,7 +42,7 @@
* @class TCPDF_FONTS
* Font methods for TCPDF library.
* @package com.tecnick.tcpdf
* @version 1.1.0
* @version 1.1.1
* @author Nicola Asuni - info@tecnick.com
*/
class TCPDF_FONTS {
@@ -55,16 +55,16 @@ class TCPDF_FONTS {
/**
* Convert and add the selected TrueType or Type1 font to the fonts folder (that must be writeable).
* @param $fontfile (string) Font file (full path).
* @param $fonttype (string) Font type. Leave empty for autodetect mode. Valid values are: TrueTypeUnicode, TrueType, Type1, CID0JP = CID-0 Japanese, CID0KR = CID-0 Korean, CID0CS = CID-0 Chinese Simplified, CID0CT = CID-0 Chinese Traditional.
* @param $enc (string) Name of the encoding table to use. Leave empty for default mode. Omit this parameter for TrueType Unicode and symbolic fonts like Symbol or ZapfDingBats.
* @param $flags (int) Unsigned 32-bit integer containing flags specifying various characteristics of the font (PDF32000:2008 - 9.8.2 Font Descriptor Flags): +1 for fixed font; +4 for symbol or +32 for non-symbol; +64 for italic. Fixed and Italic mode are generally autodetected so you have to set it to 32 = non-symbolic font (default) or 4 = symbolic font.
* @param $outpath (string) Output path for generated font files (must be writeable by the web server). Leave empty for default font folder.
* @param $platid (int) Platform ID for CMAP table to extract (when building a Unicode font for Windows this value should be 3, for Macintosh should be 1).
* @param $encid (int) Encoding ID for CMAP table to extract (when building a Unicode font for Windows this value should be 1, for Macintosh should be 0). When Platform ID is 3, legal values for Encoding ID are: 0=Symbol, 1=Unicode, 2=ShiftJIS, 3=PRC, 4=Big5, 5=Wansung, 6=Johab, 7=Reserved, 8=Reserved, 9=Reserved, 10=UCS-4.
* @param $addcbbox (boolean) If true includes the character bounding box information on the php font file.
* @param $link (boolean) If true link to system font instead of copying the font data (not transportable) - Note: do not work with Type1 fonts.
* @return (string) TCPDF font name or boolean false in case of error.
* @param string $fontfile Font file (full path).
* @param string $fonttype Font type. Leave empty for autodetect mode. Valid values are: TrueTypeUnicode, TrueType, Type1, CID0JP = CID-0 Japanese, CID0KR = CID-0 Korean, CID0CS = CID-0 Chinese Simplified, CID0CT = CID-0 Chinese Traditional.
* @param string $enc Name of the encoding table to use. Leave empty for default mode. Omit this parameter for TrueType Unicode and symbolic fonts like Symbol or ZapfDingBats.
* @param int $flags Unsigned 32-bit integer containing flags specifying various characteristics of the font (PDF32000:2008 - 9.8.2 Font Descriptor Flags): +1 for fixed font; +4 for symbol or +32 for non-symbol; +64 for italic. Fixed and Italic mode are generally autodetected so you have to set it to 32 = non-symbolic font (default) or 4 = symbolic font.
* @param string $outpath Output path for generated font files (must be writeable by the web server). Leave empty for default font folder.
* @param int $platid Platform ID for CMAP table to extract (when building a Unicode font for Windows this value should be 3, for Macintosh should be 1).
* @param int $encid Encoding ID for CMAP table to extract (when building a Unicode font for Windows this value should be 1, for Macintosh should be 0). When Platform ID is 3, legal values for Encoding ID are: 0=Symbol, 1=Unicode, 2=ShiftJIS, 3=PRC, 4=Big5, 5=Wansung, 6=Johab, 7=Reserved, 8=Reserved, 9=Reserved, 10=UCS-4.
* @param boolean $addcbbox If true includes the character bounding box information on the php font file.
* @param boolean $link If true link to system font instead of copying the font data (not transportable) - Note: do not work with Type1 fonts.
* @return string|false TCPDF font name or boolean false in case of error.
* @author Nicola Asuni
* @since 5.9.123 (2010-09-30)
* @public static
@@ -191,29 +191,30 @@ class TCPDF_FONTS {
fclose($fp);
// get font info
$fmetric['Flags'] = $flags;
preg_match ('#/FullName[\s]*\(([^\)]*)#', $font, $matches);
preg_match ('#/FullName[\s]*+\(([^\)]*+)#', $font, $matches);
$fmetric['name'] = preg_replace('/[^a-zA-Z0-9_\-]/', '', $matches[1]);
preg_match('#/FontBBox[\s]*{([^}]*)#', $font, $matches);
$fmetric['bbox'] = trim($matches[1]);
$bv = explode(' ', $fmetric['bbox']);
$fmetric['Ascent'] = intval($bv[3]);
$fmetric['Descent'] = intval($bv[1]);
preg_match('#/ItalicAngle[\s]*([0-9\+\-]*)#', $font, $matches);
preg_match('#/FontBBox[\s]*+{([^}]*+)#', $font, $matches);
$rawbvl = explode(' ', trim($matches[1]));
$bvl = [(int) $rawbvl[0], (int) $rawbvl[1], (int) $rawbvl[2], (int) $rawbvl[3]];
$fmetric['bbox'] = implode(' ', $bvl);
$fmetric['Ascent'] = $bvl[3];
$fmetric['Descent'] = $bvl[1];
preg_match('#/ItalicAngle[\s]*+([0-9\+\-]*+)#', $font, $matches);
$fmetric['italicAngle'] = intval($matches[1]);
if ($fmetric['italicAngle'] != 0) {
$fmetric['Flags'] |= 64;
}
preg_match('#/UnderlinePosition[\s]*([0-9\+\-]*)#', $font, $matches);
preg_match('#/UnderlinePosition[\s]*+([0-9\+\-]*+)#', $font, $matches);
$fmetric['underlinePosition'] = intval($matches[1]);
preg_match('#/UnderlineThickness[\s]*([0-9\+\-]*)#', $font, $matches);
preg_match('#/UnderlineThickness[\s]*+([0-9\+\-]*+)#', $font, $matches);
$fmetric['underlineThickness'] = intval($matches[1]);
preg_match('#/isFixedPitch[\s]*([^\s]*)#', $font, $matches);
preg_match('#/isFixedPitch[\s]*+([^\s]*+)#', $font, $matches);
if ($matches[1] == 'true') {
$fmetric['Flags'] |= 1;
}
// get internal map
$imap = array();
if (preg_match_all('#dup[\s]([0-9]+)[\s]*/([^\s]*)[\s]put#sU', $font, $fmap, PREG_SET_ORDER) > 0) {
if (preg_match_all('#dup[\s]([0-9]+)[\s]*+/([^\s]*+)[\s]put#sU', $font, $fmap, PREG_SET_ORDER) > 0) {
foreach ($fmap as $v) {
$imap[$v[2]] = $v[1];
}
@@ -229,22 +230,22 @@ class TCPDF_FONTS {
$eplain .= chr($chr ^ ($r >> 8));
$r = ((($chr + $r) * $c1 + $c2) % 65536);
}
if (preg_match('#/ForceBold[\s]*([^\s]*)#', $eplain, $matches) > 0) {
if (preg_match('#/ForceBold[\s]*+([^\s]*+)#', $eplain, $matches) > 0) {
if ($matches[1] == 'true') {
$fmetric['Flags'] |= 0x40000;
}
}
if (preg_match('#/StdVW[\s]*\[([^\]]*)#', $eplain, $matches) > 0) {
if (preg_match('#/StdVW[\s]*+\[([^\]]*+)#', $eplain, $matches) > 0) {
$fmetric['StemV'] = intval($matches[1]);
} else {
$fmetric['StemV'] = 70;
}
if (preg_match('#/StdHW[\s]*\[([^\]]*)#', $eplain, $matches) > 0) {
if (preg_match('#/StdHW[\s]*+\[([^\]]*+)#', $eplain, $matches) > 0) {
$fmetric['StemH'] = intval($matches[1]);
} else {
$fmetric['StemH'] = 30;
}
if (preg_match('#/BlueValues[\s]*\[([^\]]*)#', $eplain, $matches) > 0) {
if (preg_match('#/BlueValues[\s]*+\[([^\]]*+)#', $eplain, $matches) > 0) {
$bv = explode(' ', $matches[1]);
if (count($bv) >= 6) {
$v1 = intval($bv[2]);
@@ -265,7 +266,7 @@ class TCPDF_FONTS {
$fmetric['CapHeight'] = 700;
}
// get the number of random bytes at the beginning of charstrings
if (preg_match('#/lenIV[\s]*([0-9]*)#', $eplain, $matches) > 0) {
if (preg_match('#/lenIV[\s]*+([\d]*+)#', $eplain, $matches) > 0) {
$lenIV = intval($matches[1]);
} else {
$lenIV = 4;
@@ -273,7 +274,7 @@ class TCPDF_FONTS {
$fmetric['Leading'] = 0;
// get charstring data
$eplain = substr($eplain, (strpos($eplain, '/CharStrings') + 1));
preg_match_all('#/([A-Za-z0-9\.]*)[\s][0-9]+[\s]RD[\s](.*)[\s]ND#sU', $eplain, $matches, PREG_SET_ORDER);
preg_match_all('#/([A-Za-z0-9\.]*+)[\s][0-9]+[\s]RD[\s](.*)[\s]ND#sU', $eplain, $matches, PREG_SET_ORDER);
if (!empty($enc) AND isset(TCPDF_FONT_DATA::$encmap[$enc])) {
$enc_map = TCPDF_FONT_DATA::$encmap[$enc];
} else {
@@ -557,6 +558,7 @@ class TCPDF_FONTS {
$numGlyphs = TCPDF_STATIC::_getUSHORT($font, $offset);
// ---------- get CIDToGIDMap ----------
$ctg = array();
$c = 0;
foreach ($encodingTables as $enctable) {
// get only specified Platform ID and Encoding ID
if (($enctable['platformID'] == $platid) AND ($enctable['encodingID'] == $encid)) {
@@ -920,8 +922,8 @@ class TCPDF_FONTS {
/**
* Returs the checksum of a TTF table.
* @param $table (string) table to check
* @param $length (int) length of table in bytes
* @param string $table table to check
* @param int $length length of table in bytes
* @return int checksum
* @author Nicola Asuni
* @since 5.2.000 (2010-06-02)
@@ -942,9 +944,9 @@ class TCPDF_FONTS {
/**
* Returns a subset of the TrueType font data without the unused glyphs.
* @param $font (string) TrueType font data.
* @param $subsetchars (array) Array of used characters (the glyphs to keep).
* @return (string) A subset of TrueType font data without the unused glyphs.
* @param string $font TrueType font data.
* @param array $subsetchars Array of used characters (the glyphs to keep).
* @return string A subset of TrueType font data without the unused glyphs.
* @author Nicola Asuni
* @since 5.2.000 (2010-06-02)
* @public static
@@ -956,6 +958,7 @@ class TCPDF_FONTS {
// sfnt version must be 0x00010000 for TrueType version 1.0.
return $font;
}
$c = 0;
$offset += 4;
// get number of tables
$numTables = TCPDF_STATIC::_getUSHORT($font, $offset);
@@ -1149,7 +1152,7 @@ class TCPDF_FONTS {
$subsetglyphs[$g] = true;
}
}
}
}
break;
}
case 6: { // Format 6: Trimmed table mapping
@@ -1321,43 +1324,43 @@ class TCPDF_FONTS {
// set the checkSumAdjustment to 0
$table[$tag]['data'] = substr($table[$tag]['data'], 0, 8)."\x0\x0\x0\x0".substr($table[$tag]['data'], 12);
}
$pad = 4 - ($table[$tag]['length'] % 4);
if ($pad != 4) {
// the length of a table must be a multiple of four bytes
$table[$tag]['length'] += $pad;
$table[$tag]['data'] .= str_repeat("\x0", $pad);
}
$table[$tag]['offset'] = $offset;
$offset += $table[$tag]['length'];
$numPad = ($offset + 3 & ~3) - $offset;
if($numPad > 0) {
$table[$tag]['data'] .= str_repeat("\x0", $numPad);
$offset += $numPad;
}
// check sum is not changed (so keep the following line commented)
//$table[$tag]['checkSum'] = self::_getTTFtableChecksum($table[$tag]['data'], $table[$tag]['length']);
//$table[$tag]['checkSum'] = self::_getTTFtableChecksum($table[$tag]['data'], $table[$tag]['length'] + $numPad);
} else {
unset($table[$tag]);
}
}
// add loca
$table['loca'] = array();
$table['loca']['data'] = $loca;
$table['loca']['length'] = strlen($loca);
$pad = 4 - ($table['loca']['length'] % 4);
if ($pad != 4) {
// the length of a table must be a multiple of four bytes
$table['loca']['length'] += $pad;
$table['loca']['data'] .= str_repeat("\x0", $pad);
}
$table['loca']['offset'] = $offset;
$table['loca']['checkSum'] = self::_getTTFtableChecksum($table['loca']['data'], $table['loca']['length']);
$offset += $table['loca']['length'];
$numPad = ($offset + 3 & ~3) - $offset;
if($numPad > 0) {
$table['loca']['data'] .= str_repeat("\x0", $numPad);
$offset += $numPad;
}
$table['loca']['checkSum'] = self::_getTTFtableChecksum($table['loca']['data'], $table['loca']['length'] + $numPad);
// add glyf
$table['glyf'] = array();
$table['glyf']['data'] = $glyf;
$table['glyf']['length'] = strlen($glyf);
$pad = 4 - ($table['glyf']['length'] % 4);
if ($pad != 4) {
// the length of a table must be a multiple of four bytes
$table['glyf']['length'] += $pad;
$table['glyf']['data'] .= str_repeat("\x0", $pad);
}
$table['glyf']['offset'] = $offset;
$table['glyf']['checkSum'] = self::_getTTFtableChecksum($table['glyf']['data'], $table['glyf']['length']);
$offset += $table['glyf']['length'];
$numPad = ($offset + 3 & ~3) - $offset;
if($numPad > 0) {
$table['glyf']['data'] .= str_repeat("\x0", $numPad);
$offset += $numPad;
}
$table['glyf']['checkSum'] = self::_getTTFtableChecksum($table['glyf']['data'], $table['glyf']['length'] + $numPad);
// rebuild font
$font = '';
$font .= pack('N', 0x10000); // sfnt version
@@ -1381,15 +1384,15 @@ class TCPDF_FONTS {
}
// set checkSumAdjustment on head table
$checkSumAdjustment = 0xB1B0AFBA - self::_getTTFtableChecksum($font, strlen($font));
$font = substr($font, 0, $table['head']['offset'] + 8).pack('N', $checkSumAdjustment).substr($font, $table['head']['offset'] + 12);
$font = substr($font, 0, $table['head']['offset'] + $offset + 4).pack('N', $checkSumAdjustment).substr($font, $table['head']['offset'] + $offset + 8);
return $font;
}
/**
* Outputs font widths
* @param $font (array) font data
* @param $cidoffset (int) offset for CID values
* @return PDF command string for font widths
* @param array $font font data
* @param int $cidoffset offset for CID values
* @return string PDF command string for font widths
* @author Nicola Asuni
* @since 4.4.000 (2008-12-07)
* @public static
@@ -1495,10 +1498,10 @@ class TCPDF_FONTS {
/**
* Update the CIDToGIDMap string with a new value.
* @param $map (string) CIDToGIDMap.
* @param $cid (int) CID value.
* @param $gid (int) GID value.
* @return (string) CIDToGIDMap.
* @param string $map CIDToGIDMap.
* @param int $cid CID value.
* @param int $gid GID value.
* @return string CIDToGIDMap.
* @author Nicola Asuni
* @since 5.9.123 (2011-09-29)
* @public static
@@ -1533,8 +1536,8 @@ class TCPDF_FONTS {
/**
* Return font full path
* @param $file (string) Font file name.
* @param $fontdir (string) Font directory (set to false fto search on default directories)
* @param string $file Font file name.
* @param string $fontdir Font directory (set to false fto search on default directories)
* @return string Font full path or empty string
* @author Nicola Asuni
* @since 6.0.025
@@ -1558,8 +1561,8 @@ class TCPDF_FONTS {
/**
* Get a reference font size.
* @param $size (string) String containing font size value.
* @param $refsize (float) Reference font size in points.
* @param string $size String containing font size value.
* @param float $refsize Reference font size in points.
* @return float value in points
* @public static
*/
@@ -1657,9 +1660,9 @@ class TCPDF_FONTS {
/**
* Returns the unicode caracter specified by the value
* @param $c (int) UTF-8 value
* @param $unicode (boolean) True if we are in unicode mode, false otherwise.
* @return Returns the specified character.
* @param int $c UTF-8 value
* @param boolean $unicode True if we are in unicode mode, false otherwise.
* @return string Returns the specified character.
* @since 2.3.000 (2008-03-05)
* @public static
*/
@@ -1686,8 +1689,8 @@ class TCPDF_FONTS {
/**
* Returns the unicode caracter specified by UTF-8 value
* @param $c (int) UTF-8 value
* @return Returns the specified character.
* @param int $c UTF-8 value
* @return string Returns the specified character.
* @public static
*/
public static function unichrUnicode($c) {
@@ -1696,8 +1699,8 @@ class TCPDF_FONTS {
/**
* Returns the unicode caracter specified by ASCII value
* @param $c (int) UTF-8 value
* @return Returns the specified character.
* @param int $c UTF-8 value
* @return string Returns the specified character.
* @public static
*/
public static function unichrASCII($c) {
@@ -1734,8 +1737,8 @@ class TCPDF_FONTS {
* W1 = 110110yyyyyyyyyy
* W2 = 110111xxxxxxxxxx
* </pre>
* @param $unicode (array) array containing UTF-8 unicode values
* @param $setbom (boolean) if true set the Byte Order Mark (BOM = 0xFEFF)
* @param array $unicode array containing UTF-8 unicode values
* @param boolean $setbom if true set the Byte Order Mark (BOM = 0xFEFF)
* @return string
* @protected
* @author Nicola Asuni
@@ -1770,26 +1773,26 @@ class TCPDF_FONTS {
/**
* Convert an array of UTF8 values to array of unicode characters
* @param $ta (array) The input array of UTF8 values.
* @param $isunicode (boolean) True for Unicode mode, false otherwise.
* @return Return array of unicode characters
* @param array $ta The input array of UTF8 values.
* @param boolean $isunicode True for Unicode mode, false otherwise.
* @return array Return array of unicode characters
* @since 4.5.037 (2009-04-07)
* @public static
*/
public static function UTF8ArrayToUniArray($ta, $isunicode=true) {
if ($isunicode) {
return array_map(array('TCPDF_FONTS', 'unichrUnicode'), $ta);
return array_map(static::class.'::unichrUnicode', $ta);
}
return array_map(array('TCPDF_FONTS', 'unichrASCII'), $ta);
return array_map(static::class.'::unichrASCII', $ta);
}
/**
* Extract a slice of the $strarr array and return it as string.
* @param $strarr (string) The input array of characters.
* @param $start (int) the starting element of $strarr.
* @param $end (int) first element that will not be returned.
* @param $unicode (boolean) True if we are in unicode mode, false otherwise.
* @return Return part of a string
* @param string[] $strarr The input array of characters.
* @param int $start the starting element of $strarr.
* @param int $end first element that will not be returned.
* @param boolean $unicode True if we are in unicode mode, false otherwise.
* @return string Return part of a string
* @public static
*/
public static function UTF8ArrSubString($strarr, $start='', $end='', $unicode=true) {
@@ -1808,10 +1811,10 @@ class TCPDF_FONTS {
/**
* Extract a slice of the $uniarr array and return it as string.
* @param $uniarr (string) The input array of characters.
* @param $start (int) the starting element of $strarr.
* @param $end (int) first element that will not be returned.
* @return Return part of a string
* @param string[] $uniarr The input array of characters.
* @param int $start the starting element of $strarr.
* @param int $end first element that will not be returned.
* @return string Return part of a string
* @since 4.5.037 (2009-04-07)
* @public static
*/
@@ -1831,7 +1834,7 @@ class TCPDF_FONTS {
/**
* Converts UTF-8 characters array to array of Latin1 characters array<br>
* @param $unicode (array) array containing UTF-8 unicode values
* @param array $unicode array containing UTF-8 unicode values
* @return array
* @author Nicola Asuni
* @since 4.8.023 (2010-01-15)
@@ -1855,9 +1858,9 @@ class TCPDF_FONTS {
}
/**
* Converts UTF-8 characters array to array of Latin1 string<br>
* @param $unicode (array) array containing UTF-8 unicode values
* @return array
* Converts UTF-8 characters array to Latin1 string<br>
* @param array $unicode array containing UTF-8 unicode values
* @return string
* @author Nicola Asuni
* @since 4.8.023 (2010-01-15)
* @public static
@@ -1882,8 +1885,8 @@ class TCPDF_FONTS {
/**
* Converts UTF-8 character to integer value.<br>
* Uses the getUniord() method if the value is not cached.
* @param $uch (string) character string to process.
* @return integer Unicode value
* @param string $uch character string to process.
* @return int Unicode value
* @public static
*/
public static function uniord($uch) {
@@ -1921,8 +1924,8 @@ class TCPDF_FONTS {
* UTF8-tail = %x80-BF
* ---------------------------------------------------------------------
* </pre>
* @param $uch (string) character string to process.
* @return integer Unicode value
* @param string $uch character string to process.
* @return int Unicode value
* @author Nicola Asuni
* @public static
*/
@@ -1988,18 +1991,19 @@ class TCPDF_FONTS {
/**
* Converts UTF-8 strings to codepoints array.<br>
* Invalid byte sequences will be replaced with 0xFFFD (replacement character)<br>
* @param $str (string) string to process.
* @param $isunicode (boolean) True when the documetn is in Unicode mode, false otherwise.
* @param $currentfont (array) Reference to current font array.
* @param string $str string to process.
* @param boolean $isunicode True when the documetn is in Unicode mode, false otherwise.
* @param array $currentfont Reference to current font array.
* @return array containing codepoints (UTF-8 characters values)
* @author Nicola Asuni
* @public static
*/
public static function UTF8StringToArray($str, $isunicode=true, &$currentfont) {
public static function UTF8StringToArray($str, $isunicode, &$currentfont) {
$str = is_null($str) ? '' : $str;
if ($isunicode) {
// requires PCRE unicode support turned on
$chars = TCPDF_STATIC::pregSplit('//','u', $str, -1, PREG_SPLIT_NO_EMPTY);
$carr = array_map(array('TCPDF_FONTS', 'uniord'), $chars);
$carr = array_map(static::class.'::uniord', $chars);
} else {
$chars = str_split($str);
$carr = array_map('ord', $chars);
@@ -2014,30 +2018,30 @@ class TCPDF_FONTS {
/**
* Converts UTF-8 strings to Latin1 when using the standard 14 core fonts.<br>
* @param $str (string) string to process.
* @param $isunicode (boolean) True when the documetn is in Unicode mode, false otherwise.
* @param $currentfont (array) Reference to current font array.
* @param string $str string to process.
* @param boolean $isunicode True when the documetn is in Unicode mode, false otherwise.
* @param array $currentfont Reference to current font array.
* @return string
* @since 3.2.000 (2008-06-23)
* @public static
*/
public static function UTF8ToLatin1($str, $isunicode=true, &$currentfont) {
public static function UTF8ToLatin1($str, $isunicode, &$currentfont) {
$unicode = self::UTF8StringToArray($str, $isunicode, $currentfont); // array containing UTF-8 unicode values
return self::UTF8ArrToLatin1($unicode);
}
/**
* Converts UTF-8 strings to UTF16-BE.<br>
* @param $str (string) string to process.
* @param $setbom (boolean) if true set the Byte Order Mark (BOM = 0xFEFF)
* @param $isunicode (boolean) True when the documetn is in Unicode mode, false otherwise.
* @param $currentfont (array) Reference to current font array.
* @param string $str string to process.
* @param boolean $setbom if true set the Byte Order Mark (BOM = 0xFEFF)
* @param boolean $isunicode True when the documetn is in Unicode mode, false otherwise.
* @param array $currentfont Reference to current font array.
* @return string
* @author Nicola Asuni
* @since 1.53.0.TC005 (2005-01-05)
* @public static
*/
public static function UTF8ToUTF16BE($str, $setbom=false, $isunicode=true, &$currentfont) {
public static function UTF8ToUTF16BE($str, $setbom, $isunicode, &$currentfont) {
if (!$isunicode) {
return $str; // string is not in unicode
}
@@ -2047,50 +2051,50 @@ class TCPDF_FONTS {
/**
* Reverse the RLT substrings using the Bidirectional Algorithm (http://unicode.org/reports/tr9/).
* @param $str (string) string to manipulate.
* @param $setbom (bool) if true set the Byte Order Mark (BOM = 0xFEFF)
* @param $forcertl (bool) if true forces RTL text direction
* @param $isunicode (boolean) True if the document is in Unicode mode, false otherwise.
* @param $currentfont (array) Reference to current font array.
* @param string $str string to manipulate.
* @param bool $setbom if true set the Byte Order Mark (BOM = 0xFEFF)
* @param bool $forcertl if true forces RTL text direction
* @param boolean $isunicode True if the document is in Unicode mode, false otherwise.
* @param array $currentfont Reference to current font array.
* @return string
* @author Nicola Asuni
* @since 2.1.000 (2008-01-08)
* @public static
*/
public static function utf8StrRev($str, $setbom=false, $forcertl=false, $isunicode=true, &$currentfont) {
public static function utf8StrRev($str, $setbom, $forcertl, $isunicode, &$currentfont) {
return self::utf8StrArrRev(self::UTF8StringToArray($str, $isunicode, $currentfont), $str, $setbom, $forcertl, $isunicode, $currentfont);
}
/**
* Reverse the RLT substrings array using the Bidirectional Algorithm (http://unicode.org/reports/tr9/).
* @param $arr (array) array of unicode values.
* @param $str (string) string to manipulate (or empty value).
* @param $setbom (bool) if true set the Byte Order Mark (BOM = 0xFEFF)
* @param $forcertl (bool) if true forces RTL text direction
* @param $isunicode (boolean) True if the document is in Unicode mode, false otherwise.
* @param $currentfont (array) Reference to current font array.
* @param array $arr array of unicode values.
* @param string $str string to manipulate (or empty value).
* @param bool $setbom if true set the Byte Order Mark (BOM = 0xFEFF)
* @param bool $forcertl if true forces RTL text direction
* @param boolean $isunicode True if the document is in Unicode mode, false otherwise.
* @param array $currentfont Reference to current font array.
* @return string
* @author Nicola Asuni
* @since 4.9.000 (2010-03-27)
* @public static
*/
public static function utf8StrArrRev($arr, $str='', $setbom=false, $forcertl=false, $isunicode=true, &$currentfont) {
public static function utf8StrArrRev($arr, $str, $setbom, $forcertl, $isunicode, &$currentfont) {
return self::arrUTF8ToUTF16BE(self::utf8Bidi($arr, $str, $forcertl, $isunicode, $currentfont), $setbom);
}
/**
* Reverse the RLT substrings using the Bidirectional Algorithm (http://unicode.org/reports/tr9/).
* @param $ta (array) array of characters composing the string.
* @param $str (string) string to process
* @param $forcertl (bool) if 'R' forces RTL, if 'L' forces LTR
* @param $isunicode (boolean) True if the document is in Unicode mode, false otherwise.
* @param $currentfont (array) Reference to current font array.
* @param array $ta array of characters composing the string.
* @param string $str string to process
* @param bool $forcertl if 'R' forces RTL, if 'L' forces LTR
* @param boolean $isunicode True if the document is in Unicode mode, false otherwise.
* @param array $currentfont Reference to current font array.
* @return array of unicode chars
* @author Nicola Asuni
* @since 2.4.000 (2008-03-06)
* @public static
*/
public static function utf8Bidi($ta, $str='', $forcertl=false, $isunicode=true, &$currentfont) {
public static function utf8Bidi($ta, $str, $forcertl, $isunicode, &$currentfont) {
// paragraph embedding level
$pel = 0;
// max level
@@ -5,9 +5,9 @@
// Begin : 2002-08-03
// Last Update : 2014-11-15
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// License : GNU-LGPL v3 (https://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
// Copyright (C) 2002-2014 Nicola Asuni - Tecnick.com LTD
// Copyright (C) 2002-2026 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
@@ -55,6 +55,8 @@ class TCPDF_IMAGES {
* Array of hinheritable SVG properties.
* @since 5.0.000 (2010-05-02)
* @public static
*
* @var string[]
*/
public static $svginheritprop = array('clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cursor', 'direction', 'display', 'fill', 'fill-opacity', 'fill-rule', 'font', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'image-rendering', 'kerning', 'letter-spacing', 'marker', 'marker-end', 'marker-mid', 'marker-start', 'pointer-events', 'shape-rendering', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-rendering', 'visibility', 'word-spacing', 'writing-mode');
@@ -62,8 +64,8 @@ class TCPDF_IMAGES {
/**
* Return the image type given the file name or array returned by getimagesize() function.
* @param $imgfile (string) image file name
* @param $iminfo (array) array of image information returned by getimagesize() function.
* @param string $imgfile image file name
* @param array $iminfo array of image information returned by getimagesize() function.
* @return string image type
* @since 4.8.017 (2009-11-27)
* @public static
@@ -77,10 +79,7 @@ class TCPDF_IMAGES {
}
}
if (empty($type)) {
$fileinfo = pathinfo($imgfile);
if (isset($fileinfo['extension']) AND (!TCPDF_STATIC::empty_string($fileinfo['extension']))) {
$type = strtolower(trim($fileinfo['extension']));
}
$type = strtolower(trim(pathinfo(parse_url($imgfile, PHP_URL_PATH), PATHINFO_EXTENSION)));
}
if ($type == 'jpg') {
$type = 'jpeg';
@@ -90,9 +89,9 @@ class TCPDF_IMAGES {
/**
* Set the transparency for the given GD image.
* @param $new_image (image) GD image object
* @param $image (image) GD image object.
* return GD image object.
* @param resource $new_image GD image object
* @param resource $image GD image object.
* @return resource GD image object $new_image
* @since 4.9.016 (2010-04-20)
* @public static
*/
@@ -115,8 +114,8 @@ class TCPDF_IMAGES {
/**
* Convert the loaded image to a PNG and then return a structure for the PDF creator.
* This function requires GD library and write access to the directory defined on K_PATH_CACHE constant.
* @param $image (image) Image object.
* @param $tempfile (string) Temporary file name.
* @param resource $image Image object.
* @param string $tempfile Temporary file name.
* return image PNG image object.
* @since 4.9.016 (2010-04-20)
* @public static
@@ -127,7 +126,9 @@ class TCPDF_IMAGES {
// create temporary PNG image
imagepng($image, $tempfile);
// remove image from memory
imagedestroy($image);
if (PHP_VERSION_ID < 80000) {
imagedestroy($image);
}
// get PNG image data
$retvars = self::_parsepng($tempfile);
// tidy up by removing temporary image
@@ -138,15 +139,17 @@ class TCPDF_IMAGES {
/**
* Convert the loaded image to a JPEG and then return a structure for the PDF creator.
* This function requires GD library and write access to the directory defined on K_PATH_CACHE constant.
* @param $image (image) Image object.
* @param $quality (int) JPEG quality.
* @param $tempfile (string) Temporary file name.
* return image JPEG image object.
* @param resource $image Image object.
* @param int $quality JPEG quality.
* @param string $tempfile Temporary file name.
* return array|false image JPEG image object.
* @public static
*/
public static function _toJPEG($image, $quality, $tempfile) {
imagejpeg($image, $tempfile, $quality);
imagedestroy($image);
if (PHP_VERSION_ID < 80000) {
imagedestroy($image);
}
$retvars = self::_parsejpeg($tempfile);
// tidy up by removing temporary image
unlink($tempfile);
@@ -155,8 +158,8 @@ class TCPDF_IMAGES {
/**
* Extract info from a JPEG file without using the GD library.
* @param $file (string) image file to parse
* @return array structure containing the image data
* @param string $file image file to parse
* @return array|false structure containing the image data
* @public static
*/
public static function _parsejpeg($file) {
@@ -234,8 +237,8 @@ class TCPDF_IMAGES {
/**
* Extract info from a PNG file without using the GD library.
* @param $file (string) image file to parse
* @return array structure containing the image data
* @param string $file image file to parse
* @return array|false structure containing the image data
* @public static
*/
public static function _parsepng($file) {
@@ -271,12 +274,12 @@ class TCPDF_IMAGES {
return 'pngalpha';
}
if (ord(fread($f, 1)) != 0) {
// Unknown compression method
// Unknownn compression method
fclose($f);
return false;
}
if (ord(fread($f, 1)) != 0) {
// Unknown filter method
// Unknownn filter method
fclose($f);
return false;
}
@@ -328,7 +331,7 @@ class TCPDF_IMAGES {
}
// get compression method
if (ord(fread($f, 1)) != 0) {
// Unknown filter method
// Unknownn filter method
fclose($f);
return false;
}
@@ -1,13 +1,13 @@
<?php
//============================================================+
// File name : tcpdf_static.php
// Version : 1.1.4
// Version : 1.1.5
// Begin : 2002-08-03
// Last Update : 2019-11-01
// Last Update : 2024-12-23
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// License : GNU-LGPL v3 (https://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
// Copyright (C) 2002-2015 Nicola Asuni - Tecnick.com LTD
// Copyright (C) 2002-2026 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
@@ -38,7 +38,7 @@
* This is a PHP class that contains static methods for the TCPDF class.<br>
* @package com.tecnick.tcpdf
* @author Nicola Asuni
* @version 1.1.2
* @version 1.1.5
*/
/**
@@ -46,7 +46,7 @@
* Static methods used by the TCPDF class.
* @package com.tecnick.tcpdf
* @brief PHP class for generating PDF documents without requiring external extensions.
* @version 1.1.1
* @version 1.1.5
* @author Nicola Asuni - info@tecnick.com
*/
class TCPDF_STATIC {
@@ -55,7 +55,7 @@ class TCPDF_STATIC {
* Current TCPDF version.
* @private static
*/
private static $tcpdf_version = '6.3.5';
private static $tcpdf_version = '6.11.3';
/**
* String alias for total number of pages.
@@ -106,11 +106,36 @@ class TCPDF_STATIC {
*/
public static $pageboxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox');
/**
* Array of default cURL options for curl_setopt_array.
*
* @var array<int, bool|int|string> cURL options.
*/
protected const CURLOPT_DEFAULT = [
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_MAXREDIRS => 5,
CURLOPT_PROTOCOLS => CURLPROTO_HTTPS | CURLPROTO_HTTP | CURLPROTO_FTP | CURLPROTO_FTPS,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_USERAGENT => 'tcpdf',
];
/**
* Array of fixed cURL options for curl_setopt_array.
*
* @var array<int, bool|int|string> cURL options.
*/
protected const CURLOPT_FIXED = [
CURLOPT_FAILONERROR => true,
CURLOPT_RETURNTRANSFER => true,
];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/**
* Return the current TCPDF version.
* @return TCPDF version string
* @return string TCPDF version string
* @since 5.9.012 (2010-11-10)
* @public static
*/
@@ -120,7 +145,7 @@ class TCPDF_STATIC {
/**
* Return the current TCPDF producer.
* @return TCPDF producer string
* @return string TCPDF producer string
* @since 6.0.000 (2013-03-16)
* @public static
*/
@@ -128,48 +153,18 @@ class TCPDF_STATIC {
return "\x54\x43\x50\x44\x46\x20".self::getTCPDFVersion()."\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67\x29";
}
/**
* Sets the current active configuration setting of magic_quotes_runtime (if the set_magic_quotes_runtime function exist)
* @param $mqr (boolean) FALSE for off, TRUE for on.
* @since 4.6.025 (2009-08-17)
* @public static
*/
public static function set_mqr($mqr) {
if (!defined('PHP_VERSION_ID')) {
$version = PHP_VERSION;
define('PHP_VERSION_ID', (($version[0] * 10000) + ($version[2] * 100) + $version[4]));
}
if (PHP_VERSION_ID < 50300) {
@set_magic_quotes_runtime($mqr);
}
}
/**
* Gets the current active configuration setting of magic_quotes_runtime (if the get_magic_quotes_runtime function exist)
* @return Returns 0 if magic quotes runtime is off or get_magic_quotes_runtime doesn't exist, 1 otherwise.
* @since 4.6.025 (2009-08-17)
* @public static
*/
public static function get_mqr() {
if (!defined('PHP_VERSION_ID')) {
$version = PHP_VERSION;
define('PHP_VERSION_ID', (($version[0] * 10000) + ($version[2] * 100) + $version[4]));
}
if (PHP_VERSION_ID < 50300) {
return @get_magic_quotes_runtime();
}
return 0;
}
/**
* Check if the URL exist.
* @param $url (string) URL to check.
* @return Boolean true if the URl exist, false otherwise.
* @param string $url URL to check.
* @return boolean true if the URl exist, false otherwise.
* @since 5.9.204 (2013-01-28)
* @public static
*/
public static function isValidURL($url) {
$headers = @get_headers($url);
if ($headers === false) {
return false;
}
return (strpos($headers[0], '200') !== false);
}
@@ -184,8 +179,8 @@ class TCPDF_STATIC {
* <li>UTF-8 (hex): 0xC2 0xAD (c2ad)</li>
* <li>UTF-8 character: chr(194).chr(173)</li>
* </ul>
* @param $txt (string) input string
* @param $unicode (boolean) True if we are in unicode mode, false otherwise.
* @param string $txt input string
* @param boolean $unicode True if we are in unicode mode, false otherwise.
* @return string without SHY characters.
* @since (4.5.019) 2009-02-28
* @public static
@@ -201,10 +196,10 @@ class TCPDF_STATIC {
/**
* Get the border mode accounting for multicell position (opens bottom side of multicell crossing pages)
* @param $brd (mixed) Indicates if borders must be drawn around the cell block. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul>or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
* @param $position (string) multicell position: 'start', 'middle', 'end'
* @param $opencell (boolean) True when the cell is left open at the page bottom, false otherwise.
* @return border mode array
* @param string|array|int $brd Indicates if borders must be drawn around the cell block. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul>or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
* @param string $position multicell position: 'start', 'middle', 'end'
* @param boolean $opencell True when the cell is left open at the page bottom, false otherwise.
* @return array border mode array
* @since 4.4.002 (2008-12-09)
* @public static
*/
@@ -275,8 +270,8 @@ class TCPDF_STATIC {
/**
* Determine whether a string is empty.
* @param $str (string) string to be checked
* @return boolean true if string is empty
* @param string $str string to be checked
* @return bool true if string is empty
* @since 4.5.044 (2009-04-16)
* @public static
*/
@@ -286,8 +281,8 @@ class TCPDF_STATIC {
/**
* Returns a temporary filename for caching object on filesystem.
* @param $type (string) Type of file (name of the subdir on the tcpdf cache folder).
* @param $file_id (string) TCPDF file_id.
* @param string $type Type of file (name of the subdir on the tcpdf cache folder).
* @param string $file_id TCPDF file_id.
* @return string filename.
* @since 4.5.000 (2008-12-31)
* @public static
@@ -298,7 +293,7 @@ class TCPDF_STATIC {
/**
* Add "\" before "\", "(" and ")"
* @param $s (string) string to escape.
* @param string $s string to escape.
* @return string escaped string.
* @public static
*/
@@ -309,21 +304,21 @@ class TCPDF_STATIC {
/**
* Escape some special characters (&lt; &gt; &amp;) for XML output.
* @param $str (string) Input string to convert.
* @return converted string
* @param string $str Input string to convert.
* @return string converted string
* @since 5.9.121 (2011-09-28)
* @public static
*/
public static function _escapeXML($str) {
$replaceTable = array("\0" => '', '&' => '&amp;', '<' => '&lt;', '>' => '&gt;');
$str = strtr($str, $replaceTable);
$str = strtr($str === null ? '' : $str, $replaceTable);
return $str;
}
/**
* Creates a copy of a class object
* @param $object (object) class object to be cloned
* @return cloned object
* @param object $object class object to be cloned
* @return object cloned object
* @since 4.5.029 (2009-03-19)
* @public static
*/
@@ -337,8 +332,8 @@ class TCPDF_STATIC {
/**
* Output input data and compress it if possible.
* @param $data (string) Data to output.
* @param $length (int) Data length in bytes.
* @param string $data Data to output.
* @param int $length Data length in bytes.
* @since 5.9.086
* @public static
*/
@@ -352,10 +347,10 @@ class TCPDF_STATIC {
/**
* Replace page number aliases with number.
* @param $page (string) Page content.
* @param $replace (array) Array of replacements (array keys are replacement strings, values are alias arrays).
* @param $diff (int) If passed, this will be set to the total char number difference between alias and replacements.
* @return replaced page content and updated $diff parameter as array.
* @param string $page Page content.
* @param array $replace Array of replacements (array keys are replacement strings, values are alias arrays).
* @param int $diff If passed, this will be set to the total char number difference between alias and replacements.
* @return array replaced page content and updated $diff parameter as array.
* @public static
*/
public static function replacePageNumAliases($page, $replace, $diff=0) {
@@ -372,7 +367,7 @@ class TCPDF_STATIC {
/**
* Returns timestamp in seconds from formatted date-time.
* @param $date (string) Formatted date-time.
* @param string $date Formatted date-time.
* @return int seconds.
* @since 5.9.152 (2012-03-23)
* @public static
@@ -387,7 +382,7 @@ class TCPDF_STATIC {
/**
* Returns a formatted date-time.
* @param $time (int) Time in seconds.
* @param int $time Time in seconds.
* @return string escaped date string.
* @since 5.9.152 (2012-03-23)
* @public static
@@ -398,7 +393,7 @@ class TCPDF_STATIC {
/**
* Returns a string containing random data to be used as a seed for encryption methods.
* @param $seed (string) starting seed value
* @param string $seed starting seed value
* @return string containing random data
* @author Nicola Asuni
* @since 5.9.006 (2010-10-19)
@@ -409,7 +404,10 @@ class TCPDF_STATIC {
if (function_exists('posix_getpid')) {
$rnd .= posix_getpid();
}
if (function_exists('openssl_random_pseudo_bytes') AND (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) {
if (function_exists('random_bytes')) {
$rnd .= random_bytes(512);
} elseif (function_exists('openssl_random_pseudo_bytes') AND (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) {
// this is not used on windows systems because it is very slow for a know bug
$rnd .= openssl_random_pseudo_bytes(512);
} else {
@@ -417,13 +415,13 @@ class TCPDF_STATIC {
$rnd .= uniqid('', true);
}
}
return $rnd.$seed.__FILE__.serialize($_SERVER).microtime(true);
return $rnd.$seed.__FILE__.microtime(true);
}
/**
* Encrypts a string using MD5 and returns it's value as a binary string.
* @param $str (string) input string
* @return String MD5 encrypted binary string
* @param string $str input string
* @return string MD5 encrypted binary string
* @since 2.0.000 (2008-01-02)
* @public static
*/
@@ -432,11 +430,11 @@ class TCPDF_STATIC {
}
/**
* Returns the input text exrypted using AES algorithm and the specified key.
* Returns the input text encrypted using AES algorithm and the specified key.
* This method requires openssl or mcrypt. Text is padded to 16bytes blocks
* @param $key (string) encryption key
* @param $text (String) input text to be encrypted
* @return String encrypted text
* @param string $key encryption key
* @param string $text input text to be encrypted
* @return string encrypted text
* @author Nicola Asuni
* @since 5.0.005 (2010-05-11)
* @public static
@@ -446,8 +444,12 @@ class TCPDF_STATIC {
$padding = 16 - (strlen($text) % 16);
$text .= str_repeat(chr($padding), $padding);
if (extension_loaded('openssl')) {
$iv = openssl_random_pseudo_bytes (openssl_cipher_iv_length('aes-256-cbc'));
$text = openssl_encrypt($text, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
$algo = 'aes-256-cbc';
if (strlen($key) == 16) {
$algo = 'aes-128-cbc';
}
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($algo));
$text = openssl_encrypt($text, $algo, $key, OPENSSL_RAW_DATA, $iv);
return $iv.substr($text, 0, -16);
}
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND);
@@ -457,19 +459,23 @@ class TCPDF_STATIC {
}
/**
* Returns the input text exrypted using AES algorithm and the specified key.
* Returns the input text encrypted using AES algorithm and the specified key.
* This method requires openssl or mcrypt. Text is not padded
* @param $key (string) encryption key
* @param $text (String) input text to be encrypted
* @return String encrypted text
* @param string $key encryption key
* @param string $text input text to be encrypted
* @return string encrypted text
* @author Nicola Asuni
* @since TODO
* @public static
*/
public static function _AESnopad($key, $text) {
if (extension_loaded('openssl')) {
$iv = str_repeat("\x00", openssl_cipher_iv_length('aes-256-cbc'));
$text = openssl_encrypt($text, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
$algo = 'aes-256-cbc';
if (strlen($key) == 16) {
$algo = 'aes-128-cbc';
}
$iv = str_repeat("\x00", openssl_cipher_iv_length($algo));
$text = openssl_encrypt($text, $algo, $key, OPENSSL_RAW_DATA, $iv);
return substr($text, 0, -16);
}
$iv = str_repeat("\x00", mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));
@@ -480,13 +486,13 @@ class TCPDF_STATIC {
/**
* Returns the input text encrypted using RC4 algorithm and the specified key.
* RC4 is the standard encryption algorithm used in PDF format
* @param $key (string) Encryption key.
* @param $text (String) Input text to be encrypted.
* @param $last_enc_key (String) Reference to last RC4 key encrypted.
* @param $last_enc_key_c (String) Reference to last RC4 computed key.
* @return String encrypted text
* @param string $key Encryption key.
* @param string $text Input text to be encrypted.
* @param string $last_enc_key Reference to last RC4 key encrypted.
* @param string $last_enc_key_c Reference to last RC4 computed key.
* @return string encrypted text
* @since 2.0.000 (2008-01-02)
* @author Klemen Vodopivec, Nicola Asuni
* @author Klemen Vodopivec,2026 Nicola Asuni
* @public static
*/
public static function _RC4($key, $text, &$last_enc_key, &$last_enc_key_c) {
@@ -495,7 +501,7 @@ class TCPDF_STATIC {
return $out;
}
if ($last_enc_key != $key) {
$k = str_repeat($key, ((256 / strlen($key)) + 1));
$k = str_repeat($key, (int) ((256 / strlen($key)) + 1));
$rc4 = range(0, 255);
$j = 0;
for ($i = 0; $i < 256; ++$i) {
@@ -527,8 +533,8 @@ class TCPDF_STATIC {
/**
* Return the permission code used on encryption (P value).
* @param $permissions (Array) the set of permissions (specify the ones you want to block).
* @param $mode (int) encryption strength: 0 = RC4 40 bit; 1 = RC4 128 bit; 2 = AES 128 bit; 3 = AES 256 bit.
* @param array $permissions the set of permissions (specify the ones you want to block).
* @param int $mode encryption strength: 0 = RC4 40 bit; 1 = RC4 128 bit; 2 = AES 128 bit; 3 = AES 256 bit.
* @since 5.0.005 (2010-05-12)
* @author Nicola Asuni
* @public static
@@ -564,8 +570,8 @@ class TCPDF_STATIC {
/**
* Convert hexadecimal string to string
* @param $bs (string) byte-string to convert
* @return String
* @param string $bs byte-string to convert
* @return string
* @since 5.0.005 (2010-05-12)
* @author Nicola Asuni
* @public static
@@ -586,8 +592,8 @@ class TCPDF_STATIC {
/**
* Convert string to hexadecimal string (byte string)
* @param $s (string) string to convert
* @return byte string
* @param string $s string to convert
* @return string byte string
* @since 5.0.010 (2010-05-17)
* @author Nicola Asuni
* @public static
@@ -603,8 +609,8 @@ class TCPDF_STATIC {
/**
* Convert encryption P value to a string of bytes, low-order byte first.
* @param $protection (string) 32bit encryption permission value (P value)
* @return String
* @param string $protection 32bit encryption permission value (P value)
* @return string
* @since 5.0.005 (2010-05-12)
* @author Nicola Asuni
* @public static
@@ -620,8 +626,8 @@ class TCPDF_STATIC {
/**
* Encode a name object.
* @param $name (string) Name object to encode.
* @return (string) Encoded name object.
* @param string $name Name object to encode.
* @return string Encoded name object.
* @author Nicola Asuni
* @since 5.9.097 (2011-06-23)
* @public static
@@ -642,9 +648,9 @@ class TCPDF_STATIC {
/**
* Convert JavaScript form fields properties array to Annotation Properties array.
* @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference.
* @param $spot_colors (array) Reference to spot colors array.
* @param $rtl (boolean) True if in Right-To-Left text direction mode, false otherwise.
* @param array $prop javascript field properties. Possible values are described on official Javascript for Acrobat API reference.
* @param array $spot_colors Reference to spot colors array.
* @param boolean $rtl True if in Right-To-Left text direction mode, false otherwise.
* @return array of annotation properties
* @author Nicola Asuni
* @since 4.8.000 (2009-09-06)
@@ -652,7 +658,7 @@ class TCPDF_STATIC {
*/
public static function getAnnotOptFromJSProp($prop, &$spot_colors, $rtl=false) {
if (isset($prop['aopt']) AND is_array($prop['aopt'])) {
// the annotation options area lready defined
// the annotation options are already defined
return $prop['aopt'];
}
$opt = array(); // value to be returned
@@ -841,9 +847,7 @@ class TCPDF_STATIC {
if (isset($prop['charLimit'])) {
$opt['maxlen'] = intval($prop['charLimit']);
}
if (!isset($ff)) {
$ff = 0; // default value
}
$ff = 0;
// readonly: The read-only characteristic of a field. If a field is read-only, the user can see the field but cannot change it.
if (isset($prop['readonly']) AND ($prop['readonly'] == 'true')) {
$ff += 1 << 0;
@@ -1011,8 +1015,9 @@ class TCPDF_STATIC {
/**
* Format the page numbers.
* This method can be overriden for custom formats.
* @param $num (int) page number
* This method can be overridden for custom formats.
* @param int $num page number
* @return string
* @since 4.2.005 (2008-11-06)
* @public static
*/
@@ -1022,8 +1027,9 @@ class TCPDF_STATIC {
/**
* Format the page numbers on the Table Of Content.
* This method can be overriden for custom formats.
* @param $num (int) page number
* This method can be overridden for custom formats.
* @param int $num page number
* @return string
* @since 4.5.001 (2009-01-04)
* @see addTOC(), addHTMLTOC()
* @public static
@@ -1034,8 +1040,8 @@ class TCPDF_STATIC {
/**
* Extracts the CSS properties from a CSS string.
* @param $cssdata (string) string containing CSS definitions.
* @return An array where the keys are the CSS selectors and the values are the CSS properties.
* @param string $cssdata string containing CSS definitions.
* @return array An array where the keys are the CSS selectors and the values are the CSS properties.
* @author Nicola Asuni
* @since 5.1.000 (2010-05-25)
* @public static
@@ -1125,20 +1131,20 @@ class TCPDF_STATIC {
/**
* Cleanup HTML code (requires HTML Tidy library).
* @param $html (string) htmlcode to fix
* @param $default_css (string) CSS commands to add
* @param $tagvs (array) parameters for setHtmlVSpace method
* @param $tidy_options (array) options for tidy_parse_string function
* @param $tagvspaces (array) Array of vertical spaces for tags.
* @param string $html htmlcode to fix
* @param string $default_css CSS commands to add
* @param array|null $tagvs parameters for setHtmlVSpace method
* @param array|null $tidy_options options for tidy_parse_string function
* @param array $tagvspaces Array of vertical spaces for tags.
* @return string XHTML code cleaned up
* @author Nicola Asuni
* @since 5.9.017 (2010-11-16)
* @see setHtmlVSpace()
* @public static
*/
public static function fixHTMLCode($html, $default_css='', $tagvs='', $tidy_options='', &$tagvspaces) {
public static function fixHTMLCode($html, $default_css, $tagvs, $tidy_options, &$tagvspaces) {
// configure parameters for HTML Tidy
if ($tidy_options === '') {
if (TCPDF_STATIC::empty_string($tidy_options)) {
$tidy_options = array (
'clean' => 1,
'drop-empty-paras' => 0,
@@ -1185,7 +1191,7 @@ class TCPDF_STATIC {
// remove some empty tag blocks
$html = preg_replace('/<div([^\>]*)><\/div>/', '', $html);
$html = preg_replace('/<p([^\>]*)><\/p>/', '', $html);
if ($tagvs !== '') {
if (!TCPDF_STATIC::empty_string($tagvs)) {
// set vertical space for some XHTML tags
$tagvspaces = $tagvs;
}
@@ -1195,9 +1201,9 @@ class TCPDF_STATIC {
/**
* Returns true if the CSS selector is valid for the selected HTML tag
* @param $dom (array) array of HTML tags and properties
* @param $key (int) key of the current HTML tag
* @param $selector (string) CSS selector string
* @param array $dom array of HTML tags and properties
* @param int $key key of the current HTML tag
* @param string $selector CSS selector string
* @return true if the selector is valid, false otherwise
* @since 5.1.000 (2010-05-25)
* @public static
@@ -1355,9 +1361,9 @@ class TCPDF_STATIC {
/**
* Returns the styles array that apply for the selected HTML tag.
* @param $dom (array) array of HTML tags and properties
* @param $key (int) key of the current HTML tag
* @param $css (array) array of CSS properties
* @param array $dom array of HTML tags and properties
* @param int $key key of the current HTML tag
* @param array $css array of CSS properties
* @return array containing CSS properties
* @since 5.1.000 (2010-05-25)
* @public static
@@ -1402,7 +1408,7 @@ class TCPDF_STATIC {
/**
* Compact CSS data array into single string.
* @param $css (array) array of CSS properties
* @param array $css array of CSS properties
* @return string containing merged CSS properties
* @since 5.9.070 (2011-04-19)
* @public static
@@ -1433,13 +1439,17 @@ class TCPDF_STATIC {
/**
* Returns the Roman representation of an integer number
* @param $number (int) number to convert
* @param int $number number to convert
* @return string roman representation of the specified number
* @since 4.4.004 (2008-12-10)
* @public static
*/
public static function intToRoman($number) {
$roman = '';
if ($number >= 4000) {
// do not represent numbers above 4000 in Roman numerals
return strval($number);
}
while ($number >= 1000) {
$roman .= 'M';
$number -= 1000;
@@ -1497,10 +1507,10 @@ class TCPDF_STATIC {
/**
* Find position of last occurrence of a substring in a string
* @param $haystack (string) The string to search in.
* @param $needle (string) substring to search.
* @param $offset (int) May be specified to begin searching an arbitrary number of characters into the string.
* @return Returns the position where the needle exists. Returns FALSE if the needle was not found.
* @param string $haystack The string to search in.
* @param string $needle substring to search.
* @param int $offset May be specified to begin searching an arbitrary number of characters into the string.
* @return int|false Returns the position where the needle exists. Returns FALSE if the needle was not found.
* @since 4.8.038 (2010-03-13)
* @public static
*/
@@ -1513,7 +1523,7 @@ class TCPDF_STATIC {
/**
* Returns an array of hyphenation patterns.
* @param $file (string) TEX file containing hypenation patterns. TEX pattrns can be downloaded from http://www.ctan.org/tex-archive/language/hyph-utf8/tex/generic/hyph-utf8/patterns/
* @param string $file TEX file containing hypenation patterns. TEX patterns can be downloaded from http://www.ctan.org/tex-archive/language/hyph-utf8/tex/generic/hyph-utf8/patterns/
* @return array of hyphenation patterns
* @author Nicola Asuni
* @since 4.9.012 (2010-04-12)
@@ -1546,7 +1556,7 @@ class TCPDF_STATIC {
/**
* Get the Path-Painting Operators.
* @param $style (string) Style of rendering. Possible values are:
* @param string $style Style of rendering. Possible values are:
* <ul>
* <li>S or D: Stroke the path.</li>
* <li>s or d: Close and stroke the path.</li>
@@ -1560,7 +1570,8 @@ class TCPDF_STATIC {
* <li>CEO: Clipping mode using the nonzero winding number rule to determine which regions lie inside the clipping path</li>
* <li>n: End the path object without filling or stroking it.</li>
* </ul>
* @param $default (string) default style
* @param string $default default style
* @return string
* @author Nicola Asuni
* @since 5.0.000 (2010-04-30)
* @public static
@@ -1637,9 +1648,9 @@ class TCPDF_STATIC {
/**
* Get the product of two SVG tranformation matrices
* @param $ta (array) first SVG tranformation matrix
* @param $tb (array) second SVG tranformation matrix
* @return transformation array
* @param array $ta first SVG tranformation matrix
* @param array $tb second SVG tranformation matrix
* @return array transformation array
* @author Nicola Asuni
* @since 5.0.000 (2010-05-02)
* @public static
@@ -1657,7 +1668,7 @@ class TCPDF_STATIC {
/**
* Get the tranformation matrix from SVG transform attribute
* @param $attribute (string) transformation
* @param string $attribute transformation
* @return array of transformations
* @author Nicola Asuni
* @since 5.0.000 (2010-05-02)
@@ -1752,10 +1763,10 @@ class TCPDF_STATIC {
/**
* Returns the angle in radiants between two vectors
* @param $x1 (int) X coordinate of first vector point
* @param $y1 (int) Y coordinate of first vector point
* @param $x2 (int) X coordinate of second vector point
* @param $y2 (int) Y coordinate of second vector point
* @param int $x1 X coordinate of first vector point
* @param int $y1 Y coordinate of first vector point
* @param int $x2 X coordinate of second vector point
* @param int $y2 Y coordinate of second vector point
* @author Nicola Asuni
* @since 5.0.000 (2010-05-04)
* @public static
@@ -1777,20 +1788,27 @@ class TCPDF_STATIC {
/**
* Split string by a regular expression.
* This is a wrapper for the preg_split function to avoid the bug: https://bugs.php.net/bug.php?id=45850
* @param $pattern (string) The regular expression pattern to search for without the modifiers, as a string.
* @param $modifiers (string) The modifiers part of the pattern,
* @param $subject (string) The input string.
* @param $limit (int) If specified, then only substrings up to limit are returned with the rest of the string being placed in the last substring. A limit of -1, 0 or NULL means "no limit" and, as is standard across PHP, you can use NULL to skip to the flags parameter.
* @param $flags (int) The flags as specified on the preg_split PHP function.
* @return Returns an array containing substrings of subject split along boundaries matched by pattern.modifier
* @param string $pattern The regular expression pattern to search for without the modifiers, as a string.
* @param string $modifiers The modifiers part of the pattern,
* @param string $subject The input string.
* @param int $limit If specified, then only substrings up to limit are returned with the rest of the string being placed in the last substring. A limit of -1, 0 or NULL means "no limit" and, as is standard across PHP, you can use NULL to skip to the flags parameter.
* @param int $flags The flags as specified on the preg_split PHP function.
* @return array Returns an array containing substrings of subject split along boundaries matched by pattern.modifier
* @author Nicola Asuni
* @since 6.0.023
* @public static
*/
public static function pregSplit($pattern, $modifiers, $subject, $limit=NULL, $flags=NULL) {
// PHP 8.1 deprecates nulls for $limit and $flags
$limit = $limit === null ? -1 : $limit;
$flags = $flags === null ? 0 : $flags;
// the bug only happens on PHP 5.2 when using the u modifier
if ((strpos($modifiers, 'u') === FALSE) OR (count(preg_split('//u', "\n\t", -1, PREG_SPLIT_NO_EMPTY)) == 2)) {
return preg_split($pattern.$modifiers, $subject, $limit, $flags);
$ret = preg_split($pattern.$modifiers, $subject, $limit, $flags);
if ($ret === false) {
return array();
}
return is_array($ret) ? $ret : array();
}
// preg_split is bugged - try alternative solution
$ret = array();
@@ -1807,9 +1825,9 @@ class TCPDF_STATIC {
/**
* Wrapper to use fopen only with local files
* @param filename (string) Name of the file to open
* @param $mode (string)
* @return Returns a file pointer resource on success, or FALSE on error.
* @param string $filename Name of the file to open
* @param string $mode
* @return resource|false Returns a file pointer resource on success, or FALSE on error.
* @public static
*/
public static function fopenLocal($filename, $mode) {
@@ -1823,28 +1841,31 @@ class TCPDF_STATIC {
/**
* Check if the URL exist.
* @param url (string) URL to check.
* @return Returns TRUE if the URL exists; FALSE otherwise.
* @param string $url URL to check.
* @return bool Returns TRUE if the URL exists; FALSE otherwise.
* @public static
* @since 6.2.25
*/
public static function url_exists($url) {
$crs = curl_init();
// encode query params in URL to get right response form the server
$url = self::encodeUrlQuery($url);
curl_setopt($crs, CURLOPT_URL, $url);
curl_setopt($crs, CURLOPT_NOBODY, true);
curl_setopt($crs, CURLOPT_FAILONERROR, true);
if ((ini_get('open_basedir') == '') && (!ini_get('safe_mode'))) {
curl_setopt($crs, CURLOPT_FOLLOWLOCATION, true);
}
curl_setopt($crs, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($crs, CURLOPT_TIMEOUT, 30);
curl_setopt($crs, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($crs, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($crs, CURLOPT_USERAGENT, 'tc-lib-file');
$curlopts = [];
if (
(ini_get('open_basedir') == '')
&& (ini_get('safe_mode') === ''
|| ini_get('safe_mode') === false)
) {
$curlopts[CURLOPT_FOLLOWLOCATION] = true;
}
$curlopts = array_replace($curlopts, self::CURLOPT_DEFAULT);
$curlopts = array_replace($curlopts, K_CURLOPTS);
$curlopts = array_replace($curlopts, self::CURLOPT_FIXED);
$curlopts[CURLOPT_URL] = $url;
curl_setopt_array($crs, $curlopts);
curl_exec($crs);
$code = curl_getinfo($crs, CURLINFO_HTTP_CODE);
curl_close($crs);
if (PHP_VERSION_ID < 80000) {
curl_close($crs);
}
return ($code == 200);
}
@@ -1859,9 +1880,10 @@ class TCPDF_STATIC {
public static function encodeUrlQuery($url) {
$urlData = parse_url($url);
if (isset($urlData['query']) && $urlData['query']) {
$urlQueryData = [];
$urlQueryData = array();
parse_str(urldecode($urlData['query']), $urlQueryData);
$updatedUrl = $urlData['scheme'] . '://' . $urlData['host'] . $urlData['path'] . '?' . http_build_query($urlQueryData);
$port = isset($urlData['port']) ? ':'.$urlData['port'] : '';
$updatedUrl = $urlData['scheme'].'://'.$urlData['host'].$port.$urlData['path'].'?'.http_build_query($urlQueryData);
} else {
$updatedUrl = $url;
}
@@ -1872,8 +1894,8 @@ class TCPDF_STATIC {
* Wrapper for file_exists.
* Checks whether a file or directory exists.
* Only allows some protocols and local files.
* @param filename (string) Path to the file or directory.
* @return Returns TRUE if the file or directory specified by filename exists; FALSE otherwise.
* @param string $filename Path to the file or directory.
* @return bool Returns TRUE if the file or directory specified by filename exists; FALSE otherwise.
* @public static
*/
public static function file_exists($filename) {
@@ -1889,8 +1911,8 @@ class TCPDF_STATIC {
/**
* Reads entire file into a string.
* The file can be also an URL.
* @param $file (string) Name of the file or URL to read.
* @return The function returns the read data or FALSE on failure.
* @param string $file Name of the file or URL to read.
* @return string|false The function returns the read data or FALSE on failure.
* @author Nicola Asuni
* @since 6.0.025
* @public static
@@ -1961,20 +1983,23 @@ class TCPDF_STATIC {
) {
// try to get remote file data using cURL
$crs = curl_init();
curl_setopt($crs, CURLOPT_URL, $path);
curl_setopt($crs, CURLOPT_BINARYTRANSFER, true);
curl_setopt($crs, CURLOPT_FAILONERROR, true);
curl_setopt($crs, CURLOPT_RETURNTRANSFER, true);
if ((ini_get('open_basedir') == '') && (!ini_get('safe_mode'))) {
curl_setopt($crs, CURLOPT_FOLLOWLOCATION, true);
$curlopts = [];
if (
(ini_get('open_basedir') == '')
&& (ini_get('safe_mode') === ''
|| ini_get('safe_mode') === false)
) {
$curlopts[CURLOPT_FOLLOWLOCATION] = true;
}
curl_setopt($crs, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($crs, CURLOPT_TIMEOUT, 30);
curl_setopt($crs, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($crs, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($crs, CURLOPT_USERAGENT, 'tc-lib-file');
$curlopts = array_replace($curlopts, self::CURLOPT_DEFAULT);
$curlopts = array_replace($curlopts, K_CURLOPTS);
$curlopts = array_replace($curlopts, self::CURLOPT_FIXED);
$curlopts[CURLOPT_URL] = $url;
curl_setopt_array($crs, $curlopts);
$ret = curl_exec($crs);
curl_close($crs);
if (PHP_VERSION_ID < 80000) {
curl_close($crs);
}
if ($ret !== false) {
return $ret;
}
@@ -1985,8 +2010,8 @@ class TCPDF_STATIC {
/**
* Get ULONG from string (Big Endian 32-bit unsigned integer).
* @param $str (string) string from where to extract value
* @param $offset (int) point from where to read the data
* @param string $str string from where to extract value
* @param int $offset point from where to read the data
* @return int 32 bit value
* @author Nicola Asuni
* @since 5.2.000 (2010-06-02)
@@ -1999,8 +2024,8 @@ class TCPDF_STATIC {
/**
* Get USHORT from string (Big Endian 16-bit unsigned integer).
* @param $str (string) string from where to extract value
* @param $offset (int) point from where to read the data
* @param string $str string from where to extract value
* @param int $offset point from where to read the data
* @return int 16 bit value
* @author Nicola Asuni
* @since 5.2.000 (2010-06-02)
@@ -2013,8 +2038,8 @@ class TCPDF_STATIC {
/**
* Get SHORT from string (Big Endian 16-bit signed integer).
* @param $str (string) String from where to extract value.
* @param $offset (int) Point from where to read the data.
* @param string $str String from where to extract value.
* @param int $offset Point from where to read the data.
* @return int 16 bit value
* @author Nicola Asuni
* @since 5.2.000 (2010-06-02)
@@ -2027,8 +2052,8 @@ class TCPDF_STATIC {
/**
* Get FWORD from string (Big Endian 16-bit signed integer).
* @param $str (string) String from where to extract value.
* @param $offset (int) Point from where to read the data.
* @param string $str String from where to extract value.
* @param int $offset Point from where to read the data.
* @return int 16 bit value
* @author Nicola Asuni
* @since 5.9.123 (2011-09-30)
@@ -2044,8 +2069,8 @@ class TCPDF_STATIC {
/**
* Get UFWORD from string (Big Endian 16-bit unsigned integer).
* @param $str (string) string from where to extract value
* @param $offset (int) point from where to read the data
* @param string $str string from where to extract value
* @param int $offset point from where to read the data
* @return int 16 bit value
* @author Nicola Asuni
* @since 5.9.123 (2011-09-30)
@@ -2058,8 +2083,8 @@ class TCPDF_STATIC {
/**
* Get FIXED from string (32-bit signed fixed-point number (16.16).
* @param $str (string) string from where to extract value
* @param $offset (int) point from where to read the data
* @param string $str string from where to extract value
* @param int $offset point from where to read the data
* @return int 16 bit value
* @author Nicola Asuni
* @since 5.9.123 (2011-09-30)
@@ -2076,8 +2101,8 @@ class TCPDF_STATIC {
/**
* Get BYTE from string (8-bit unsigned integer).
* @param $str (string) String from where to extract value.
* @param $offset (int) Point from where to read the data.
* @param string $str String from where to extract value.
* @param int $offset Point from where to read the data.
* @return int 8 bit value
* @author Nicola Asuni
* @since 5.2.000 (2010-06-02)
@@ -2090,9 +2115,9 @@ class TCPDF_STATIC {
/**
* Binary-safe and URL-safe file read.
* Reads up to length bytes from the file pointer referenced by handle. Reading stops as soon as one of the following conditions is met: length bytes have been read; EOF (end of file) is reached.
* @param $handle (resource)
* @param $length (int)
* @return Returns the read string or FALSE in case of error.
* @param resource $handle
* @param int $length
* @return string|false Returns the read string or FALSE in case of error.
* @author Nicola Asuni
* @since 4.5.027 (2009-03-16)
* @public static
@@ -2111,8 +2136,8 @@ class TCPDF_STATIC {
/**
* Read a 4-byte (32 bit) integer from file.
* @param $f (string) file name.
* @return 4-byte integer
* @param resource $f file resource.
* @return int 4-byte integer
* @public static
*/
public static function _freadint($f) {
@@ -2120,11 +2145,12 @@ class TCPDF_STATIC {
return $a['i'];
}
/**
* Array of page formats
* measures are calculated in this way: (inches * 72) or (millimeters * 72 / 25.4)
* @public static
*
* @var array<string,float[]>
*/
public static $page_formats = array(
// ISO 216 A Series + 2 SIS 014711 extensions
@@ -2480,7 +2506,7 @@ class TCPDF_STATIC {
/**
* Get page dimensions from format name.
* @param $format (mixed) The format name @see self::$page_format<ul>
* @param mixed $format The format name @see self::$page_format<ul>
* @return array containing page width and height in points
* @since 5.0.010 (2010-05-17)
* @public static
@@ -2494,20 +2520,20 @@ class TCPDF_STATIC {
/**
* Set page boundaries.
* @param $page (int) page number
* @param $type (string) valid values are: <ul><li>'MediaBox' : the boundaries of the physical medium on which the page shall be displayed or printed;</li><li>'CropBox' : the visible region of default user space;</li><li>'BleedBox' : the region to which the contents of the page shall be clipped when output in a production environment;</li><li>'TrimBox' : the intended dimensions of the finished page after trimming;</li><li>'ArtBox' : the page's meaningful content (including potential white space).</li></ul>
* @param $llx (float) lower-left x coordinate in user units.
* @param $lly (float) lower-left y coordinate in user units.
* @param $urx (float) upper-right x coordinate in user units.
* @param $ury (float) upper-right y coordinate in user units.
* @param $points (boolean) If true uses user units as unit of measure, otherwise uses PDF points.
* @param $k (float) Scale factor (number of points in user unit).
* @param $pagedim (array) Array of page dimensions.
* @return pagedim array of page dimensions.
* @param int $page page number
* @param string $type valid values are: <ul><li>'MediaBox' : the boundaries of the physical medium on which the page shall be displayed or printed;</li><li>'CropBox' : the visible region of default user space;</li><li>'BleedBox' : the region to which the contents of the page shall be clipped when output in a production environment;</li><li>'TrimBox' : the intended dimensions of the finished page after trimming;</li><li>'ArtBox' : the page's meaningful content (including potential white space).</li></ul>
* @param float $llx lower-left x coordinate in user units.
* @param float $lly lower-left y coordinate in user units.
* @param float $urx upper-right x coordinate in user units.
* @param float $ury upper-right y coordinate in user units.
* @param boolean $points If true uses user units as unit of measure, otherwise uses PDF points.
* @param float $k Scale factor (number of points in user unit).
* @param array $pagedim Array of page dimensions.
* @return array pagedim array of page dimensions.
* @since 5.0.010 (2010-05-17)
* @public static
*/
public static function setPageBoxes($page, $type, $llx, $lly, $urx, $ury, $points=false, $k, $pagedim=array()) {
public static function setPageBoxes($page, $type, $llx, $lly, $urx, $ury, $points, $k, $pagedim=array()) {
if (!isset($pagedim[$page])) {
// initialize array
$pagedim[$page] = array();
@@ -2527,9 +2553,9 @@ class TCPDF_STATIC {
/**
* Swap X and Y coordinates of page boxes (change page boxes orientation).
* @param $page (int) page number
* @param $pagedim (array) Array of page dimensions.
* @return pagedim array of page dimensions.
* @param int $page page number
* @param array $pagedim Array of page dimensions.
* @return array pagedim array of page dimensions.
* @since 5.0.010 (2010-05-17)
* @public static
*/
@@ -2550,8 +2576,8 @@ class TCPDF_STATIC {
/**
* Get the canonical page layout mode.
* @param $layout (string) The page layout. Possible values are:<ul><li>SinglePage Display one page at a time</li><li>OneColumn Display the pages in one column</li><li>TwoColumnLeft Display the pages in two columns, with odd-numbered pages on the left</li><li>TwoColumnRight Display the pages in two columns, with odd-numbered pages on the right</li><li>TwoPageLeft (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the left</li><li>TwoPageRight (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the right</li></ul>
* @return (string) Canonical page layout name.
* @param string $layout The page layout. Possible values are:<ul><li>SinglePage Display one page at a time</li><li>OneColumn Display the pages in one column</li><li>TwoColumnLeft Display the pages in two columns, with odd-numbered pages on the left</li><li>TwoColumnRight Display the pages in two columns, with odd-numbered pages on the right</li><li>TwoPageLeft (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the left</li><li>TwoPageRight (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the right</li></ul>
* @return string Canonical page layout name.
* @public static
*/
public static function getPageLayoutMode($layout='SinglePage') {
@@ -2593,8 +2619,8 @@ class TCPDF_STATIC {
/**
* Get the canonical page layout mode.
* @param $mode (string) A name object specifying how the document should be displayed when opened:<ul><li>UseNone Neither document outline nor thumbnail images visible</li><li>UseOutlines Document outline visible</li><li>UseThumbs Thumbnail images visible</li><li>FullScreen Full-screen mode, with no menu bar, window controls, or any other window visible</li><li>UseOC (PDF 1.5) Optional content group panel visible</li><li>UseAttachments (PDF 1.6) Attachments panel visible</li></ul>
* @return (string) Canonical page mode name.
* @param string $mode A name object specifying how the document should be displayed when opened:<ul><li>UseNone Neither document outline nor thumbnail images visible</li><li>UseOutlines Document outline visible</li><li>UseThumbs Thumbnail images visible</li><li>FullScreen Full-screen mode, with no menu bar, window controls, or any other window visible</li><li>UseOC (PDF 1.5) Optional content group panel visible</li><li>UseAttachments (PDF 1.6) Attachments panel visible</li></ul>
* @return string Canonical page mode name.
* @public static
*/
public static function getPageMode($mode='UseNone') {
@@ -2630,7 +2656,6 @@ class TCPDF_STATIC {
return $page_mode;
}
} // END OF TCPDF_STATIC CLASS
//============================================================+
File diff suppressed because one or more lines are too long
@@ -3,11 +3,11 @@
// File name : tcpdf_autoconfig.php
// Version : 1.1.1
// Begin : 2013-05-16
// Last Update : 2014-12-18
// Last Update : 2025-04-18
// Authors : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// License : GNU-LGPL v3 (https://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
// Copyright (C) 2011-2014 Nicola Asuni - Tecnick.com LTD
// Copyright (C) 2011-2026 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
@@ -37,9 +37,14 @@
* @file
* Try to automatically configure some TCPDF constants if not defined.
* @package com.tecnick.tcpdf
* @version 1.1.1
* @version 1.2.1
*/
// Disable phar stream wrapper globally.
// if (in_array('phar', stream_get_wrappers(), true)) {
// stream_wrapper_unregister('phar');
// }
// DOCUMENT_ROOT fix for IIS Webserver
if ((!isset($_SERVER['DOCUMENT_ROOT'])) OR (empty($_SERVER['DOCUMENT_ROOT']))) {
if(isset($_SERVER['SCRIPT_FILENAME'])) {
@@ -149,7 +154,7 @@ if (!defined('PDF_HEADER_TITLE')) {
}
if (!defined('PDF_HEADER_STRING')) {
define ('PDF_HEADER_STRING', "by Nicola Asuni - Tecnick.com\nwww.tcpdf.org");
define ('PDF_HEADER_STRING', "by2026 Nicola Asuni - Tecnick.com\nwww.tcpdf.org");
}
if (!defined('PDF_UNIT')) {
@@ -201,7 +206,7 @@ if (!defined('PDF_FONT_MONOSPACED')) {
}
if (!defined('PDF_IMAGE_SCALE_RATIO')) {
define ('PDF_IMAGE_SCALE_RATIO', 1.25);
define ('PDF_IMAGE_SCALE_RATIO', 96/72);
}
if (!defined('HEAD_MAGNIFICATION')) {
@@ -228,6 +233,10 @@ if (!defined('K_TCPDF_CALLS_IN_HTML')) {
define('K_TCPDF_CALLS_IN_HTML', false);
}
if (!defined('K_ALLOWED_TCPDF_TAGS')) {
define('K_ALLOWED_TCPDF_TAGS', '');
}
if (!defined('K_TCPDF_THROW_EXCEPTION_ERROR')) {
define('K_TCPDF_THROW_EXCEPTION_ERROR', false);
}
@@ -236,6 +245,11 @@ if (!defined('K_TIMEZONE')) {
define('K_TIMEZONE', @date_default_timezone_get());
}
// Custom cURL options for curl_setopt_array.
if (!defined('K_CURLOPTS')) {
define('K_CURLOPTS', array());
}
//============================================================+
// END OF FILE
//============================================================+
@@ -5,9 +5,9 @@
// Begin : 2008-06-09
// Last Update : 2014-10-20
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// License : GNU-LGPL v3 (https://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
// Copyright (C) 2008-2014 Nicola Asuni - Tecnick.com LTD
// Copyright (C) 2008-2026 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
@@ -22,7 +22,7 @@
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with TCPDF. If not, see <http://www.gnu.org/licenses/>.
// along with TCPDF. If not, see <https://www.gnu.org/licenses/>.
//
// See LICENSE.TXT file for more information.
// -------------------------------------------------------------------
@@ -53,7 +53,7 @@ class TCPDFBarcode {
* Array representation of barcode.
* @protected
*/
protected $barcode_array;
protected $barcode_array = array();
/**
* This is the class constructor.
@@ -66,8 +66,8 @@ class TCPDFBarcode {
* <li>$arrcode['bcode'][$k]['w'] bar width in units.</li>
* <li>$arrcode['bcode'][$k]['h'] bar height in units.</li>
* <li>$arrcode['bcode'][$k]['p'] bar top position (0 = top, 1 = middle)</li></ul>
* @param $code (string) code to print
* @param $type (string) type of barcode: <ul><li>C39 : CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.</li><li>C39+ : CODE 39 with checksum</li><li>C39E : CODE 39 EXTENDED</li><li>C39E+ : CODE 39 EXTENDED + CHECKSUM</li><li>C93 : CODE 93 - USS-93</li><li>S25 : Standard 2 of 5</li><li>S25+ : Standard 2 of 5 + CHECKSUM</li><li>I25 : Interleaved 2 of 5</li><li>I25+ : Interleaved 2 of 5 + CHECKSUM</li><li>C128 : CODE 128</li><li>C128A : CODE 128 A</li><li>C128B : CODE 128 B</li><li>C128C : CODE 128 C</li><li>EAN2 : 2-Digits UPC-Based Extension</li><li>EAN5 : 5-Digits UPC-Based Extension</li><li>EAN8 : EAN 8</li><li>EAN13 : EAN 13</li><li>UPCA : UPC-A</li><li>UPCE : UPC-E</li><li>MSI : MSI (Variation of Plessey code)</li><li>MSI+ : MSI + CHECKSUM (modulo 11)</li><li>POSTNET : POSTNET</li><li>PLANET : PLANET</li><li>RMS4CC : RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)</li><li>KIX : KIX (Klant index - Customer index)</li><li>IMB: Intelligent Mail Barcode - Onecode - USPS-B-3200</li><li>CODABAR : CODABAR</li><li>CODE11 : CODE 11</li><li>PHARMA : PHARMACODE</li><li>PHARMA2T : PHARMACODE TWO-TRACKS</li></ul>
* @param string $code code to print
* @param string $type type of barcode: <ul><li>C39 : CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.</li><li>C39+ : CODE 39 with checksum</li><li>C39E : CODE 39 EXTENDED</li><li>C39E+ : CODE 39 EXTENDED + CHECKSUM</li><li>C93 : CODE 93 - USS-93</li><li>S25 : Standard 2 of 5</li><li>S25+ : Standard 2 of 5 + CHECKSUM</li><li>I25 : Interleaved 2 of 5</li><li>I25+ : Interleaved 2 of 5 + CHECKSUM</li><li>C128 : CODE 128</li><li>C128A : CODE 128 A</li><li>C128B : CODE 128 B</li><li>C128C : CODE 128 C</li><li>EAN2 : 2-Digits UPC-Based Extension</li><li>EAN5 : 5-Digits UPC-Based Extension</li><li>EAN8 : EAN 8</li><li>EAN13 : EAN 13</li><li>UPCA : UPC-A</li><li>UPCE : UPC-E</li><li>MSI : MSI (Variation of Plessey code)</li><li>MSI+ : MSI + CHECKSUM (modulo 11)</li><li>POSTNET : POSTNET</li><li>PLANET : PLANET</li><li>RMS4CC : RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)</li><li>KIX : KIX (Klant index - Customer index)</li><li>IMB: Intelligent Mail Barcode - Onecode - USPS-B-3200</li><li>CODABAR : CODABAR</li><li>CODE11 : CODE 11</li><li>PHARMA : PHARMACODE</li><li>PHARMA2T : PHARMACODE TWO-TRACKS</li></ul>
* @public
*/
public function __construct($code, $type) {
@@ -85,9 +85,9 @@ class TCPDFBarcode {
/**
* Send barcode as SVG image object to the standard output.
* @param $w (int) Minimum width of a single bar in user units.
* @param $h (int) Height of barcode in user units.
* @param $color (string) Foreground color (in SVG format) for bar elements (background is transparent).
* @param int $w Minimum width of a single bar in user units.
* @param int $h Height of barcode in user units.
* @param string $color Foreground color (in SVG format) for bar elements (background is transparent).
* @public
*/
public function getBarcodeSVG($w=2, $h=30, $color='black') {
@@ -105,9 +105,9 @@ class TCPDFBarcode {
/**
* Return a SVG string representation of barcode.
* @param $w (int) Minimum width of a single bar in user units.
* @param $h (int) Height of barcode in user units.
* @param $color (string) Foreground color (in SVG format) for bar elements (background is transparent).
* @param int $w Minimum width of a single bar in user units.
* @param int $h Height of barcode in user units.
* @param string $color Foreground color (in SVG format) for bar elements (background is transparent).
* @return string SVG code.
* @public
*/
@@ -138,9 +138,9 @@ class TCPDFBarcode {
/**
* Return an HTML representation of barcode.
* @param $w (int) Width of a single bar element in pixels.
* @param $h (int) Height of a single bar element in pixels.
* @param $color (string) Foreground color for bar elements (background is transparent).
* @param int $w Width of a single bar element in pixels.
* @param int $h Height of a single bar element in pixels.
* @param string $color Foreground color for bar elements (background is transparent).
* @return string HTML code.
* @public
*/
@@ -164,9 +164,9 @@ class TCPDFBarcode {
/**
* Send a PNG image representation of barcode (requires GD or Imagick library).
* @param $w (int) Width of a single bar element in pixels.
* @param $h (int) Height of a single bar element in pixels.
* @param $color (array) RGB (0-255) foreground color for bar elements (background is transparent).
* @param int $w Width of a single bar element in pixels.
* @param int $h Height of a single bar element in pixels.
* @param array $color RGB (0-255) foreground color for bar elements (background is transparent).
* @public
*/
public function getBarcodePNG($w=2, $h=30, $color=array(0,0,0)) {
@@ -183,10 +183,10 @@ class TCPDFBarcode {
/**
* Return a PNG image representation of barcode (requires GD or Imagick library).
* @param $w (int) Width of a single bar element in pixels.
* @param $h (int) Height of a single bar element in pixels.
* @param $color (array) RGB (0-255) foreground color for bar elements (background is transparent).
* @return image or false in case of error.
* @param int $w Width of a single bar element in pixels.
* @param int $h Height of a single bar element in pixels.
* @param array $color RGB (0-255) foreground color for bar elements (background is transparent).
* @return string|Imagick|false image or false in case of error.
* @public
*/
public function getBarcodePngData($w=2, $h=30, $color=array(0,0,0)) {
@@ -234,16 +234,18 @@ class TCPDFBarcode {
ob_start();
imagepng($png);
$imagedata = ob_get_clean();
imagedestroy($png);
if (PHP_VERSION_ID < 80000) {
imagedestroy($png);
}
return $imagedata;
}
}
/**
* Set the barcode.
* @param $code (string) code to print
* @param $type (string) type of barcode: <ul><li>C39 : CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.</li><li>C39+ : CODE 39 with checksum</li><li>C39E : CODE 39 EXTENDED</li><li>C39E+ : CODE 39 EXTENDED + CHECKSUM</li><li>C93 : CODE 93 - USS-93</li><li>S25 : Standard 2 of 5</li><li>S25+ : Standard 2 of 5 + CHECKSUM</li><li>I25 : Interleaved 2 of 5</li><li>I25+ : Interleaved 2 of 5 + CHECKSUM</li><li>C128 : CODE 128</li><li>C128A : CODE 128 A</li><li>C128B : CODE 128 B</li><li>C128C : CODE 128 C</li><li>EAN2 : 2-Digits UPC-Based Extension</li><li>EAN5 : 5-Digits UPC-Based Extension</li><li>EAN8 : EAN 8</li><li>EAN13 : EAN 13</li><li>UPCA : UPC-A</li><li>UPCE : UPC-E</li><li>MSI : MSI (Variation of Plessey code)</li><li>MSI+ : MSI + CHECKSUM (modulo 11)</li><li>POSTNET : POSTNET</li><li>PLANET : PLANET</li><li>RMS4CC : RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)</li><li>KIX : KIX (Klant index - Customer index)</li><li>IMB: Intelligent Mail Barcode - Onecode - USPS-B-3200</li><li>IMBPRE: Pre-processed Intelligent Mail Barcode - Onecode - USPS-B-3200, using only F,A,D,T letters</li><li>CODABAR : CODABAR</li><li>CODE11 : CODE 11</li><li>PHARMA : PHARMACODE</li><li>PHARMA2T : PHARMACODE TWO-TRACKS</li></ul>
* @return array barcode array
* @param string $code code to print
* @param string $type type of barcode: <ul><li>C39 : CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.</li><li>C39+ : CODE 39 with checksum</li><li>C39E : CODE 39 EXTENDED</li><li>C39E+ : CODE 39 EXTENDED + CHECKSUM</li><li>C93 : CODE 93 - USS-93</li><li>S25 : Standard 2 of 5</li><li>S25+ : Standard 2 of 5 + CHECKSUM</li><li>I25 : Interleaved 2 of 5</li><li>I25+ : Interleaved 2 of 5 + CHECKSUM</li><li>C128 : CODE 128</li><li>C128A : CODE 128 A</li><li>C128B : CODE 128 B</li><li>C128C : CODE 128 C</li><li>EAN2 : 2-Digits UPC-Based Extension</li><li>EAN5 : 5-Digits UPC-Based Extension</li><li>EAN8 : EAN 8</li><li>EAN13 : EAN 13</li><li>UPCA : UPC-A</li><li>UPCE : UPC-E</li><li>MSI : MSI (Variation of Plessey code)</li><li>MSI+ : MSI + CHECKSUM (modulo 11)</li><li>POSTNET : POSTNET</li><li>PLANET : PLANET</li><li>RMS4CC : RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)</li><li>KIX : KIX (Klant index - Customer index)</li><li>IMB: Intelligent Mail Barcode - Onecode - USPS-B-3200</li><li>IMBPRE: Pre-processed Intelligent Mail Barcode - Onecode - USPS-B-3200, using only F,A,D,T letters</li><li>CODABAR : CODABAR</li><li>CODE11 : CODE 11</li><li>PHARMA : PHARMACODE</li><li>PHARMA2T : PHARMACODE TWO-TRACKS</li></ul>
* @return void
* @public
*/
public function setBarcode($code, $type) {
@@ -373,7 +375,7 @@ class TCPDFBarcode {
break;
}
default: {
$this->barcode_array = false;
$this->barcode_array = array();
$arrcode = false;
break;
}
@@ -384,9 +386,9 @@ class TCPDFBarcode {
/**
* CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.
* General-purpose code in very wide use world-wide
* @param $code (string) code to represent.
* @param $extended (boolean) if true uses the extended mode.
* @param $checksum (boolean) if true add a checksum to the code.
* @param string $code code to represent.
* @param boolean $extended if true uses the extended mode.
* @param boolean $checksum if true add a checksum to the code.
* @return array barcode representation.
* @protected
*/
@@ -479,8 +481,8 @@ class TCPDFBarcode {
/**
* Encode a string to be used for CODE 39 Extended mode.
* @param $code (string) code to represent.
* @return encoded string.
* @param string $code code to represent.
* @return string encoded string.
* @protected
*/
protected function encode_code39_ext($code) {
@@ -530,8 +532,8 @@ class TCPDFBarcode {
/**
* Calculate CODE 39 checksum (modulo 43).
* @param $code (string) code to represent.
* @return char checksum.
* @param string $code code to represent.
* @return string char checksum.
* @protected
*/
protected function checksum_code39($code) {
@@ -553,7 +555,7 @@ class TCPDFBarcode {
/**
* CODE 93 - USS-93
* Compact code similar to Code 39
* @param $code (string) code to represent.
* @param string $code code to represent.
* @return array barcode representation.
* @protected
*/
@@ -681,7 +683,7 @@ class TCPDFBarcode {
/**
* Calculate CODE 93 checksum (modulo 47).
* @param $code (string) code to represent.
* @param string $code code to represent.
* @return string checksum code.
* @protected
*/
@@ -730,7 +732,7 @@ class TCPDFBarcode {
/**
* Checksum for standard 2 of 5 barcodes.
* @param $code (string) code to process.
* @param string $code code to process.
* @return int checksum.
* @protected
*/
@@ -755,8 +757,8 @@ class TCPDFBarcode {
* MSI.
* Variation of Plessey code, with similar applications
* Contains digits (0 to 9) and encodes the data only in the width of bars.
* @param $code (string) code to represent.
* @param $checksum (boolean) if true add a checksum to the code (modulo 11)
* @param string $code code to represent.
* @param boolean $checksum if true add a checksum to the code (modulo 11)
* @return array barcode representation.
* @protected
*/
@@ -814,8 +816,8 @@ class TCPDFBarcode {
* Standard 2 of 5 barcodes.
* Used in airline ticket marking, photofinishing
* Contains digits (0 to 9) and encodes the data only in the width of bars.
* @param $code (string) code to represent.
* @param $checksum (boolean) if true add a checksum to the code
* @param string $code code to represent.
* @param boolean $checksum if true add a checksum to the code
* @return array barcode representation.
* @protected
*/
@@ -828,7 +830,7 @@ class TCPDFBarcode {
$chr['5'] = '11101011101010';
$chr['6'] = '10111011101010';
$chr['7'] = '10101011101110';
$chr['8'] = '10101110111010';
$chr['8'] = '11101010111010';
$chr['9'] = '10111010111010';
if ($checksum) {
// add checksum
@@ -838,7 +840,7 @@ class TCPDFBarcode {
// add leading zero if code-length is odd
$code = '0'.$code;
}
$seq = '11011010';
$seq = '1110111010';
$clen = strlen($code);
for ($i = 0; $i < $clen; ++$i) {
$digit = $code[$i];
@@ -848,16 +850,15 @@ class TCPDFBarcode {
}
$seq .= $chr[$digit];
}
$seq .= '1101011';
$seq .= '111010111';
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
return $this->binseq_to_array($seq, $bararray);
}
/**
* Convert binary barcode sequence to TCPDF barcode array.
* @param $seq (string) barcode as binary sequence.
* @param $bararray (array) barcode array.
* òparam array $bararray TCPDF barcode array to fill up
* Convert binary barcode sequence to WarnockPDF barcode array.
* @param string $seq barcode as binary sequence.
* @param array $bararray barcode array to fill up
* @return array barcode representation.
* @protected
*/
@@ -886,8 +887,8 @@ class TCPDFBarcode {
* Interleaved 2 of 5 barcodes.
* Compact numeric code, widely used in industry, air cargo
* Contains digits (0 to 9) and encodes the data in the width of both bars and spaces.
* @param $code (string) code to represent.
* @param $checksum (boolean) if true add a checksum to the code
* @param string $code code to represent.
* @param boolean $checksum if true add a checksum to the code
* @return array barcode representation.
* @protected
*/
@@ -938,7 +939,7 @@ class TCPDFBarcode {
} else {
$t = false; // space
}
$w = $seq[$j];
$w = (float)$seq[$j];
$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
$bararray['maxw'] += $w;
++$k;
@@ -950,8 +951,8 @@ class TCPDFBarcode {
/**
* C128 barcodes.
* Very capable code, excellent density, high reliability; in very wide use world-wide
* @param $code (string) code to represent.
* @param $type (string) barcode type: A, B, C or empty for automatic switch (AUTO mode)
* @param string $code code to represent.
* @param string $type barcode type: A, B, C or empty for automatic switch (AUTO mode)
* @return array barcode representation.
* @protected
*/
@@ -1271,7 +1272,7 @@ class TCPDFBarcode {
} else {
$t = false; // space
}
$w = $seq[$j];
$w = (float)$seq[$j];
$bararray['bcode'][] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
$bararray['maxw'] += $w;
}
@@ -1281,7 +1282,7 @@ class TCPDFBarcode {
/**
* Split text code in A/B sequence for 128 code
* @param $code (string) code to split.
* @param string $code code to split.
* @return array sequence
* @protected
*/
@@ -1319,8 +1320,8 @@ class TCPDFBarcode {
* EAN13: European Article Numbering international retail product code
* UPC-A: Universal product code seen on almost all retail products in the USA and Canada
* UPC-E: Short version of UPC symbol
* @param $code (string) code to represent.
* @param $len (string) barcode type: 6 = UPC-E, 8 = EAN8, 13 = EAN13, 12 = UPC-A
* @param string $code code to represent.
* @param string $len barcode type: 6 = UPC-E, 8 = EAN8, 13 = EAN13, 12 = UPC-A
* @return array barcode representation.
* @protected
*/
@@ -1512,8 +1513,8 @@ class TCPDFBarcode {
* UPC-Based Extensions
* 2-Digit Ext.: Used to indicate magazines and newspaper issue numbers
* 5-Digit Ext.: Used to mark suggested retail price of books
* @param $code (string) code to represent.
* @param $len (string) barcode type: 2 = 2-Digit, 5 = 5-Digit
* @param string $code code to represent.
* @param string $len barcode type: 2 = 2-Digit, 5 = 5-Digit
* @return array barcode representation.
* @protected
*/
@@ -1587,8 +1588,8 @@ class TCPDFBarcode {
/**
* POSTNET and PLANET barcodes.
* Used by U.S. Postal Service for automated mail sorting
* @param $code (string) zip code to represent. Must be a string containing a zip code of the form DDDDD or DDDDD-DDDD.
* @param $planet (boolean) if true print the PLANET barcode, otherwise print POSTNET
* @param string $code zip code to represent. Must be a string containing a zip code of the form DDDDD or DDDDD-DDDD.
* @param boolean $planet if true print the PLANET barcode, otherwise print POSTNET
* @return array barcode representation.
* @protected
*/
@@ -1660,8 +1661,8 @@ class TCPDFBarcode {
* RMS4CC - CBC - KIX
* RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code) - KIX (Klant index - Customer index)
* RM4SCC is the name of the barcode symbology used by the Royal Mail for its Cleanmail service.
* @param $code (string) code to print
* @param $kix (boolean) if true prints the KIX variation (doesn't use the start and end symbols, and the checksum) - in this case the house number must be sufficed with an X and placed at the end of the code.
* @param string $code code to print
* @param boolean $kix if true prints the KIX variation (doesn't use the start and end symbols, and the checksum) - in this case the house number must be sufficed with an X and placed at the end of the code.
* @return array barcode representation.
* @protected
*/
@@ -1812,7 +1813,7 @@ class TCPDFBarcode {
/**
* CODABAR barcodes.
* Older code often used in library systems, sometimes in blood banks
* @param $code (string) code to represent.
* @param string $code code to represent.
* @return array barcode representation.
* @protected
*/
@@ -1856,7 +1857,7 @@ class TCPDFBarcode {
} else {
$t = false; // space
}
$w = $seq[$j];
$w = (float)$seq[$j];
$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
$bararray['maxw'] += $w;
++$k;
@@ -1868,7 +1869,7 @@ class TCPDFBarcode {
/**
* CODE11 barcodes.
* Used primarily for labeling telecommunications equipment
* @param $code (string) code to represent.
* @param string $code code to represent.
* @return array barcode representation.
* @protected
*/
@@ -1947,7 +1948,7 @@ class TCPDFBarcode {
} else {
$t = false; // space
}
$w = $seq[$j];
$w = (float)$seq[$j];
$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
$bararray['maxw'] += $w;
++$k;
@@ -1959,7 +1960,7 @@ class TCPDFBarcode {
/**
* Pharmacode
* Contains digits (0 to 9)
* @param $code (string) code to represent.
* @param string $code code to represent.
* @return array barcode representation.
* @protected
*/
@@ -1985,7 +1986,7 @@ class TCPDFBarcode {
/**
* Pharmacode two-track
* Contains digits (0 to 9)
* @param $code (string) code to represent.
* @param string $code code to represent.
* @return array barcode representation.
* @protected
*/
@@ -2047,7 +2048,7 @@ class TCPDFBarcode {
* (requires PHP bcmath extension)
* Intelligent Mail barcode is a 65-bar code for use on mail in the United States.
* The fields are described as follows:<ul><li>The Barcode Identifier shall be assigned by USPS to encode the presort identification that is currently printed in human readable form on the optional endorsement line (OEL) as well as for future USPS use. This shall be two digits, with the second digit in the range of 0–4. The allowable encoding ranges shall be 00–04, 10–14, 20–24, 30–34, 40–44, 50–54, 60–64, 70–74, 80–84, and 90–94.</li><li>The Service Type Identifier shall be assigned by USPS for any combination of services requested on the mailpiece. The allowable encoding range shall be 000http://it2.php.net/manual/en/function.dechex.php–999. Each 3-digit value shall correspond to a particular mail class with a particular combination of service(s). Each service program, such as OneCode Confirm and OneCode ACS, shall provide the list of Service Type Identifier values.</li><li>The Mailer or Customer Identifier shall be assigned by USPS as a unique, 6 or 9 digit number that identifies a business entity. The allowable encoding range for the 6 digit Mailer ID shall be 000000- 899999, while the allowable encoding range for the 9 digit Mailer ID shall be 900000000-999999999.</li><li>The Serial or Sequence Number shall be assigned by the mailer for uniquely identifying and tracking mailpieces. The allowable encoding range shall be 000000000–999999999 when used with a 6 digit Mailer ID and 000000-999999 when used with a 9 digit Mailer ID. e. The Delivery Point ZIP Code shall be assigned by the mailer for routing the mailpiece. This shall replace POSTNET for routing the mailpiece to its final delivery point. The length may be 0, 5, 9, or 11 digits. The allowable encoding ranges shall be no ZIP Code, 00000–99999, 000000000–999999999, and 00000000000–99999999999.</li></ul>
* @param $code (string) code to print, separate the ZIP (routing code) from the rest using a minus char '-' (BarcodeID_ServiceTypeID_MailerID_SerialNumber-RoutingCode)
* @param string $code code to print, separate the ZIP (routing code) from the rest using a minus char '-' (BarcodeID_ServiceTypeID_MailerID_SerialNumber-RoutingCode)
* @return array barcode representation.
* @protected
*/
@@ -2171,8 +2172,8 @@ class TCPDFBarcode {
/**
* IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200
*
* @param $code (string) pre-formatted IMB barcode (65 chars "FADT")
*
* @param string $code pre-formatted IMB barcode (65 chars "FADT")
* @return array barcode representation.
* @protected
*/
@@ -2223,7 +2224,7 @@ class TCPDFBarcode {
/**
* Convert large integer number to hexadecimal representation.
* (requires PHP bcmath extension)
* @param $number (string) number to convert specified as a string
* @param string $number number to convert specified as a string
* @return string hexadecimal representation
*/
public function dec_to_hex($number) {
@@ -2247,7 +2248,7 @@ class TCPDFBarcode {
/**
* Convert large hexadecimal number to decimal representation (string).
* (requires PHP bcmath extension)
* @param $hex (string) hexadecimal number to convert specified as a string
* @param string $hex hexadecimal number to convert specified as a string
* @return string hexadecimal representation
*/
public function hex_to_dec($hex) {
@@ -2263,7 +2264,7 @@ class TCPDFBarcode {
/**
* Intelligent Mail Barcode calculation of Frame Check Sequence
* @param $code_arr (string) array of hexadecimal values (13 bytes holding 102 bits right justified).
* @param string $code_arr array of hexadecimal values (13 bytes holding 102 bits right justified).
* @return int 11 bit Frame Check Sequence as integer (decimal base)
* @protected
*/
@@ -2299,7 +2300,7 @@ class TCPDFBarcode {
/**
* Reverse unsigned short value
* @param $num (int) value to reversr
* @param int $num value to reversr
* @return int reversed value
* @protected
*/
@@ -2315,8 +2316,8 @@ class TCPDFBarcode {
/**
* generate Nof13 tables used for Intelligent Mail Barcode
* @param $n (int) is the type of table: 2 for 2of13 table, 5 for 5of13table
* @param $size (int) size of table (78 for n=2 and 1287 for n=5)
* @param int $n is the type of table: 2 for 2of13 table, 5 for 5of13table
* @param int $size size of table (78 for n=2 and 1287 for n=5)
* @return array requested table
* @protected
*/
@@ -5,9 +5,9 @@
// Begin : 2009-04-07
// Last Update : 2014-05-20
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// License : GNU-LGPL v3 (https://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
// Copyright (C) 2009-2014 Nicola Asuni - Tecnick.com LTD
// Copyright (C) 2009-2026 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
@@ -22,7 +22,7 @@
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with TCPDF. If not, see <http://www.gnu.org/licenses/>.
// along with TCPDF. If not, see <https://www.gnu.org/licenses/>.
//
// See LICENSE.TXT file for more information.
// -------------------------------------------------------------------
@@ -53,7 +53,7 @@ class TCPDF2DBarcode {
* Array representation of barcode.
* @protected
*/
protected $barcode_array = false;
protected $barcode_array = array();
/**
* This is the class constructor.
@@ -62,8 +62,8 @@ class TCPDF2DBarcode {
* <li>$arrcode['num_rows'] required number of rows</li>
* <li>$arrcode['num_cols'] required number of columns</li>
* <li>$arrcode['bcode'][$r][$c] value of the cell is $r row and $c column (0 = transparent, 1 = black)</li></ul>
* @param $code (string) code to print
* @param $type (string) type of barcode: <ul><li>DATAMATRIX : Datamatrix (ISO/IEC 16022)</li><li>PDF417 : PDF417 (ISO/IEC 15438:2006)</li><li>PDF417,a,e,t,s,f,o0,o1,o2,o3,o4,o5,o6 : PDF417 with parameters: a = aspect ratio (width/height); e = error correction level (0-8); t = total number of macro segments; s = macro segment index (0-99998); f = file ID; o0 = File Name (text); o1 = Segment Count (numeric); o2 = Time Stamp (numeric); o3 = Sender (text); o4 = Addressee (text); o5 = File Size (numeric); o6 = Checksum (numeric). NOTES: Parameters t, s and f are required for a Macro Control Block, all other parametrs are optional. To use a comma character ',' on text options, replace it with the character 255: "\xff".</li><li>QRCODE : QRcode Low error correction</li><li>QRCODE,L : QRcode Low error correction</li><li>QRCODE,M : QRcode Medium error correction</li><li>QRCODE,Q : QRcode Better error correction</li><li>QRCODE,H : QR-CODE Best error correction</li><li>RAW: raw mode - comma-separad list of array rows</li><li>RAW2: raw mode - array rows are surrounded by square parenthesis.</li><li>TEST : Test matrix</li></ul>
* @param string $code code to print
* @param string $type type of barcode: <ul><li>DATAMATRIX : Datamatrix (ISO/IEC 16022)</li><li>PDF417 : PDF417 (ISO/IEC 15438:2006)</li><li>PDF417,a,e,t,s,f,o0,o1,o2,o3,o4,o5,o6 : PDF417 with parameters: a = aspect ratio (width/height); e = error correction level (0-8); t = total number of macro segments; s = macro segment index (0-99998); f = file ID; o0 = File Name (text); o1 = Segment Count (numeric); o2 = Time Stamp (numeric); o3 = Sender (text); o4 = Addressee (text); o5 = File Size (numeric); o6 = Checksum (numeric). NOTES: Parameters t, s and f are required for a Macro Control Block, all other parameters are optional. To use a comma character ',' on text options, replace it with the character 255: "\xff".</li><li>QRCODE : QRcode Low error correction</li><li>QRCODE,L : QRcode Low error correction</li><li>QRCODE,M : QRcode Medium error correction</li><li>QRCODE,Q : QRcode Better error correction</li><li>QRCODE,H : QR-CODE Best error correction</li><li>RAW: raw mode - comma-separad list of array rows</li><li>RAW2: raw mode - array rows are surrounded by square parenthesis.</li><li>TEST : Test matrix</li></ul>
*/
public function __construct($code, $type) {
$this->setBarcode($code, $type);
@@ -79,9 +79,9 @@ class TCPDF2DBarcode {
/**
* Send barcode as SVG image object to the standard output.
* @param $w (int) Width of a single rectangle element in user units.
* @param $h (int) Height of a single rectangle element in user units.
* @param $color (string) Foreground color (in SVG format) for bar elements (background is transparent).
* @param int $w Width of a single rectangle element in user units.
* @param int $h Height of a single rectangle element in user units.
* @param string $color Foreground color (in SVG format) for bar elements (background is transparent).
* @public
*/
public function getBarcodeSVG($w=3, $h=3, $color='black') {
@@ -99,9 +99,9 @@ class TCPDF2DBarcode {
/**
* Return a SVG string representation of barcode.
* @param $w (int) Width of a single rectangle element in user units.
* @param $h (int) Height of a single rectangle element in user units.
* @param $color (string) Foreground color (in SVG format) for bar elements (background is transparent).
* @param int $w Width of a single rectangle element in user units.
* @param int $h Height of a single rectangle element in user units.
* @param string $color Foreground color (in SVG format) for bar elements (background is transparent).
* @return string SVG code.
* @public
*/
@@ -135,9 +135,9 @@ class TCPDF2DBarcode {
/**
* Return an HTML representation of barcode.
* @param $w (int) Width of a single rectangle element in pixels.
* @param $h (int) Height of a single rectangle element in pixels.
* @param $color (string) Foreground color for bar elements (background is transparent).
* @param int $w Width of a single rectangle element in pixels.
* @param int $h Height of a single rectangle element in pixels.
* @param string $color Foreground color for bar elements (background is transparent).
* @return string HTML code.
* @public
*/
@@ -164,9 +164,9 @@ class TCPDF2DBarcode {
/**
* Send a PNG image representation of barcode (requires GD or Imagick library).
* @param $w (int) Width of a single rectangle element in pixels.
* @param $h (int) Height of a single rectangle element in pixels.
* @param $color (array) RGB (0-255) foreground color for bar elements (background is transparent).
* @param int $w Width of a single rectangle element in pixels.
* @param int $h Height of a single rectangle element in pixels.
* @param array $color RGB (0-255) foreground color for bar elements (background is transparent).
* @public
*/
public function getBarcodePNG($w=3, $h=3, $color=array(0,0,0)) {
@@ -184,10 +184,10 @@ class TCPDF2DBarcode {
/**
* Return a PNG image representation of barcode (requires GD or Imagick library).
* @param $w (int) Width of a single rectangle element in pixels.
* @param $h (int) Height of a single rectangle element in pixels.
* @param $color (array) RGB (0-255) foreground color for bar elements (background is transparent).
* @return image or false in case of error.
* @param int $w Width of a single rectangle element in pixels.
* @param int $h Height of a single rectangle element in pixels.
* @param array $color RGB (0-255) foreground color for bar elements (background is transparent).
* @return string|Imagick|false image or false in case of error.
* @public
*/
public function getBarcodePngData($w=3, $h=3, $color=array(0,0,0)) {
@@ -238,16 +238,18 @@ class TCPDF2DBarcode {
ob_start();
imagepng($png);
$imagedata = ob_get_clean();
imagedestroy($png);
if (PHP_VERSION_ID < 80000) {
imagedestroy($png);
}
return $imagedata;
}
}
/**
* Set the barcode.
* @param $code (string) code to print
* @param $type (string) type of barcode: <ul><li>DATAMATRIX : Datamatrix (ISO/IEC 16022)</li><li>PDF417 : PDF417 (ISO/IEC 15438:2006)</li><li>PDF417,a,e,t,s,f,o0,o1,o2,o3,o4,o5,o6 : PDF417 with parameters: a = aspect ratio (width/height); e = error correction level (0-8); t = total number of macro segments; s = macro segment index (0-99998); f = file ID; o0 = File Name (text); o1 = Segment Count (numeric); o2 = Time Stamp (numeric); o3 = Sender (text); o4 = Addressee (text); o5 = File Size (numeric); o6 = Checksum (numeric). NOTES: Parameters t, s and f are required for a Macro Control Block, all other parametrs are optional. To use a comma character ',' on text options, replace it with the character 255: "\xff".</li><li>QRCODE : QRcode Low error correction</li><li>QRCODE,L : QRcode Low error correction</li><li>QRCODE,M : QRcode Medium error correction</li><li>QRCODE,Q : QRcode Better error correction</li><li>QRCODE,H : QR-CODE Best error correction</li><li>RAW: raw mode - comma-separad list of array rows</li><li>RAW2: raw mode - array rows are surrounded by square parenthesis.</li><li>TEST : Test matrix</li></ul>
* @return array
* @param string $code code to print
* @param string $type type of barcode: <ul><li>DATAMATRIX : Datamatrix (ISO/IEC 16022)</li><li>PDF417 : PDF417 (ISO/IEC 15438:2006)</li><li>PDF417,a,e,t,s,f,o0,o1,o2,o3,o4,o5,o6 : PDF417 with parameters: a = aspect ratio (width/height); e = error correction level (0-8); t = total number of macro segments; s = macro segment index (0-99998); f = file ID; o0 = File Name (text); o1 = Segment Count (numeric); o2 = Time Stamp (numeric); o3 = Sender (text); o4 = Addressee (text); o5 = File Size (numeric); o6 = Checksum (numeric). NOTES: Parameters t, s and f are required for a Macro Control Block, all other parameters are optional. To use a comma character ',' on text options, replace it with the character 255: "\xff".</li><li>QRCODE : QRcode Low error correction</li><li>QRCODE,L : QRcode Low error correction</li><li>QRCODE,M : QRcode Medium error correction</li><li>QRCODE,Q : QRcode Better error correction</li><li>QRCODE,H : QR-CODE Best error correction</li><li>RAW: raw mode - comma-separad list of array rows</li><li>RAW2: raw mode - array rows are surrounded by square parenthesis.</li><li>TEST : Test matrix</li></ul>
* @return void
*/
public function setBarcode($code, $type) {
$mode = explode(',', $type);
@@ -338,7 +340,7 @@ class TCPDF2DBarcode {
break;
}
default: {
$this->barcode_array = false;
$this->barcode_array = array();
}
}
}
@@ -1,104 +0,0 @@
<?php
//============================================================+
// File name : tcpdf_import.php
// Version : 1.0.001
// Begin : 2011-05-23
// Last Update : 2013-09-17
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
// Copyright (C) 2011-2013 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
// TCPDF is free software: you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// TCPDF is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the License
// along with TCPDF. If not, see
// <http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT>.
//
// See LICENSE.TXT file for more information.
// -------------------------------------------------------------------
//
// Description : This is a PHP class extension of the TCPDF library to
// import existing PDF documents.
//
//============================================================+
/**
* @file
* !!! THIS CLASS IS UNDER DEVELOPMENT !!!
* This is a PHP class extension of the TCPDF (http://www.tcpdf.org) library to import existing PDF documents.<br>
* @package com.tecnick.tcpdf
* @author Nicola Asuni
* @version 1.0.001
*/
// include the TCPDF class
require_once(dirname(__FILE__).'/tcpdf.php');
// include PDF parser class
require_once(dirname(__FILE__).'/tcpdf_parser.php');
/**
* @class TCPDF_IMPORT
* !!! THIS CLASS IS UNDER DEVELOPMENT !!!
* PHP class extension of the TCPDF (http://www.tcpdf.org) library to import existing PDF documents.<br>
* @package com.tecnick.tcpdf
* @brief PHP class extension of the TCPDF library to import existing PDF documents.
* @version 1.0.001
* @author Nicola Asuni - info@tecnick.com
*/
class TCPDF_IMPORT extends TCPDF {
/**
* Import an existing PDF document
* @param $filename (string) Filename of the PDF document to import.
* @return true in case of success, false otherwise
* @public
* @since 1.0.000 (2011-05-24)
*/
public function importPDF($filename) {
// load document
$rawdata = file_get_contents($filename);
if ($rawdata === false) {
$this->Error('Unable to get the content of the file: '.$filename);
}
// configuration parameters for parser
$cfg = array(
'die_for_errors' => false,
'ignore_filter_decoding_errors' => true,
'ignore_missing_filter_decoders' => true,
);
try {
// parse PDF data
$pdf = new TCPDF_PARSER($rawdata, $cfg);
} catch (Exception $e) {
die($e->getMessage());
}
// get the parsed data
$data = $pdf->getParsedData();
// release some memory
unset($rawdata);
// ...
print_r($data); // DEBUG
unset($pdf);
}
} // END OF CLASS
//============================================================+
// END OF FILE
//============================================================+
@@ -1,815 +0,0 @@
<?php
//============================================================+
// File name : tcpdf_parser.php
// Version : 1.0.16
// Begin : 2011-05-23
// Last Update : 2015-04-28
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT GNU-LGPLv3
// -------------------------------------------------------------------
// Copyright (C) 2011-2015 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
// TCPDF is free software: you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// TCPDF is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the License
// along with TCPDF. If not, see
// <http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT>.
//
// See LICENSE.TXT file for more information.
// -------------------------------------------------------------------
//
// Description : This is a PHP class for parsing PDF documents.
//
//============================================================+
/**
* @file
* This is a PHP class for parsing PDF documents.<br>
* @package com.tecnick.tcpdf
* @author Nicola Asuni
* @version 1.0.15
*/
// include class for decoding filters
require_once(dirname(__FILE__).'/include/tcpdf_filters.php');
/**
* @class TCPDF_PARSER
* This is a PHP class for parsing PDF documents.<br>
* @package com.tecnick.tcpdf
* @brief This is a PHP class for parsing PDF documents..
* @version 1.0.15
* @author Nicola Asuni - info@tecnick.com
*/
class TCPDF_PARSER {
/**
* Raw content of the PDF document.
* @private
*/
private $pdfdata = '';
/**
* XREF data.
* @protected
*/
protected $xref = array();
/**
* Array of PDF objects.
* @protected
*/
protected $objects = array();
/**
* Class object for decoding filters.
* @private
*/
private $FilterDecoders;
/**
* Array of configuration parameters.
* @private
*/
private $cfg = array(
'die_for_errors' => false,
'ignore_filter_decoding_errors' => true,
'ignore_missing_filter_decoders' => true,
);
// -----------------------------------------------------------------------------
/**
* Parse a PDF document an return an array of objects.
* @param $data (string) PDF data to parse.
* @param $cfg (array) Array of configuration parameters:
* 'die_for_errors' : if true termitate the program execution in case of error, otherwise thows an exception;
* 'ignore_filter_decoding_errors' : if true ignore filter decoding errors;
* 'ignore_missing_filter_decoders' : if true ignore missing filter decoding errors.
* @public
* @since 1.0.000 (2011-05-24)
*/
public function __construct($data, $cfg=array()) {
if (empty($data)) {
$this->Error('Empty PDF data.');
}
// find the pdf header starting position
if (($trimpos = strpos($data, '%PDF-')) === FALSE) {
$this->Error('Invalid PDF data: missing %PDF header.');
}
// get PDF content string
$this->pdfdata = substr($data, $trimpos);
// get length
$pdflen = strlen($this->pdfdata);
// set configuration parameters
$this->setConfig($cfg);
// get xref and trailer data
$this->xref = $this->getXrefData();
// parse all document objects
$this->objects = array();
foreach ($this->xref['xref'] as $obj => $offset) {
if (!isset($this->objects[$obj]) AND ($offset > 0)) {
// decode objects with positive offset
$this->objects[$obj] = $this->getIndirectObject($obj, $offset, true);
}
}
// release some memory
unset($this->pdfdata);
$this->pdfdata = '';
}
/**
* Set the configuration parameters.
* @param $cfg (array) Array of configuration parameters:
* 'die_for_errors' : if true termitate the program execution in case of error, otherwise thows an exception;
* 'ignore_filter_decoding_errors' : if true ignore filter decoding errors;
* 'ignore_missing_filter_decoders' : if true ignore missing filter decoding errors.
* @public
*/
protected function setConfig($cfg) {
if (isset($cfg['die_for_errors'])) {
$this->cfg['die_for_errors'] = !!$cfg['die_for_errors'];
}
if (isset($cfg['ignore_filter_decoding_errors'])) {
$this->cfg['ignore_filter_decoding_errors'] = !!$cfg['ignore_filter_decoding_errors'];
}
if (isset($cfg['ignore_missing_filter_decoders'])) {
$this->cfg['ignore_missing_filter_decoders'] = !!$cfg['ignore_missing_filter_decoders'];
}
}
/**
* Return an array of parsed PDF document objects.
* @return (array) Array of parsed PDF document objects.
* @public
* @since 1.0.000 (2011-06-26)
*/
public function getParsedData() {
return array($this->xref, $this->objects);
}
/**
* Get Cross-Reference (xref) table and trailer data from PDF document data.
* @param $offset (int) xref offset (if know).
* @param $xref (array) previous xref array (if any).
* @return Array containing xref and trailer data.
* @protected
* @since 1.0.000 (2011-05-24)
*/
protected function getXrefData($offset=0, $xref=array()) {
if ($offset == 0) {
// find last startxref
if (preg_match_all('/[\r\n]startxref[\s]*[\r\n]+([0-9]+)[\s]*[\r\n]+%%EOF/i', $this->pdfdata, $matches, PREG_SET_ORDER, $offset) == 0) {
$this->Error('Unable to find startxref');
}
$matches = array_pop($matches);
$startxref = $matches[1];
} elseif (strpos($this->pdfdata, 'xref', $offset) == $offset) {
// Already pointing at the xref table
$startxref = $offset;
} elseif (preg_match('/([0-9]+[\s][0-9]+[\s]obj)/i', $this->pdfdata, $matches, PREG_OFFSET_CAPTURE, $offset)) {
// Cross-Reference Stream object
$startxref = $offset;
} elseif (preg_match('/[\r\n]startxref[\s]*[\r\n]+([0-9]+)[\s]*[\r\n]+%%EOF/i', $this->pdfdata, $matches, PREG_OFFSET_CAPTURE, $offset)) {
// startxref found
$startxref = $matches[1][0];
} else {
$this->Error('Unable to find startxref');
}
// check xref position
if (strpos($this->pdfdata, 'xref', $startxref) == $startxref) {
// Cross-Reference
$xref = $this->decodeXref($startxref, $xref);
} else {
// Cross-Reference Stream
$xref = $this->decodeXrefStream($startxref, $xref);
}
if (empty($xref)) {
$this->Error('Unable to find xref');
}
return $xref;
}
/**
* Decode the Cross-Reference section
* @param $startxref (int) Offset at which the xref section starts (position of the 'xref' keyword).
* @param $xref (array) Previous xref array (if any).
* @return Array containing xref and trailer data.
* @protected
* @since 1.0.000 (2011-06-20)
*/
protected function decodeXref($startxref, $xref=array()) {
$startxref += 4; // 4 is the length of the word 'xref'
// skip initial white space chars: \x00 null (NUL), \x09 horizontal tab (HT), \x0A line feed (LF), \x0C form feed (FF), \x0D carriage return (CR), \x20 space (SP)
$offset = $startxref + strspn($this->pdfdata, "\x00\x09\x0a\x0c\x0d\x20", $startxref);
// initialize object number
$obj_num = 0;
// search for cross-reference entries or subsection
while (preg_match('/([0-9]+)[\x20]([0-9]+)[\x20]?([nf]?)(\r\n|[\x20]?[\r\n])/', $this->pdfdata, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
if ($matches[0][1] != $offset) {
// we are on another section
break;
}
$offset += strlen($matches[0][0]);
if ($matches[3][0] == 'n') {
// create unique object index: [object number]_[generation number]
$index = $obj_num.'_'.intval($matches[2][0]);
// check if object already exist
if (!isset($xref['xref'][$index])) {
// store object offset position
$xref['xref'][$index] = intval($matches[1][0]);
}
++$obj_num;
} elseif ($matches[3][0] == 'f') {
++$obj_num;
} else {
// object number (index)
$obj_num = intval($matches[1][0]);
}
}
// get trailer data
if (preg_match('/trailer[\s]*<<(.*)>>/isU', $this->pdfdata, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
$trailer_data = $matches[1][0];
if (!isset($xref['trailer']) OR empty($xref['trailer'])) {
// get only the last updated version
$xref['trailer'] = array();
// parse trailer_data
if (preg_match('/Size[\s]+([0-9]+)/i', $trailer_data, $matches) > 0) {
$xref['trailer']['size'] = intval($matches[1]);
}
if (preg_match('/Root[\s]+([0-9]+)[\s]+([0-9]+)[\s]+R/i', $trailer_data, $matches) > 0) {
$xref['trailer']['root'] = intval($matches[1]).'_'.intval($matches[2]);
}
if (preg_match('/Encrypt[\s]+([0-9]+)[\s]+([0-9]+)[\s]+R/i', $trailer_data, $matches) > 0) {
$xref['trailer']['encrypt'] = intval($matches[1]).'_'.intval($matches[2]);
}
if (preg_match('/Info[\s]+([0-9]+)[\s]+([0-9]+)[\s]+R/i', $trailer_data, $matches) > 0) {
$xref['trailer']['info'] = intval($matches[1]).'_'.intval($matches[2]);
}
if (preg_match('/ID[\s]*[\[][\s]*[<]([^>]*)[>][\s]*[<]([^>]*)[>]/i', $trailer_data, $matches) > 0) {
$xref['trailer']['id'] = array();
$xref['trailer']['id'][0] = $matches[1];
$xref['trailer']['id'][1] = $matches[2];
}
}
if (preg_match('/Prev[\s]+([0-9]+)/i', $trailer_data, $matches) > 0) {
// get previous xref
$xref = $this->getXrefData(intval($matches[1]), $xref);
}
} else {
$this->Error('Unable to find trailer');
}
return $xref;
}
/**
* Decode the Cross-Reference Stream section
* @param $startxref (int) Offset at which the xref section starts.
* @param $xref (array) Previous xref array (if any).
* @return Array containing xref and trailer data.
* @protected
* @since 1.0.003 (2013-03-16)
*/
protected function decodeXrefStream($startxref, $xref=array()) {
// try to read Cross-Reference Stream
$xrefobj = $this->getRawObject($startxref);
$xrefcrs = $this->getIndirectObject($xrefobj[1], $startxref, true);
if (!isset($xref['trailer']) OR empty($xref['trailer'])) {
// get only the last updated version
$xref['trailer'] = array();
$filltrailer = true;
} else {
$filltrailer = false;
}
if (!isset($xref['xref'])) {
$xref['xref'] = array();
}
$valid_crs = false;
$columns = 0;
$sarr = $xrefcrs[0][1];
if (!is_array($sarr)) {
$sarr = array();
}
foreach ($sarr as $k => $v) {
if (($v[0] == '/') AND ($v[1] == 'Type') AND (isset($sarr[($k +1)]) AND ($sarr[($k +1)][0] == '/') AND ($sarr[($k +1)][1] == 'XRef'))) {
$valid_crs = true;
} elseif (($v[0] == '/') AND ($v[1] == 'Index') AND (isset($sarr[($k +1)]))) {
// first object number in the subsection
$index_first = intval($sarr[($k +1)][1][0][1]);
// number of entries in the subsection
$index_entries = intval($sarr[($k +1)][1][1][1]);
} elseif (($v[0] == '/') AND ($v[1] == 'Prev') AND (isset($sarr[($k +1)]) AND ($sarr[($k +1)][0] == 'numeric'))) {
// get previous xref offset
$prevxref = intval($sarr[($k +1)][1]);
} elseif (($v[0] == '/') AND ($v[1] == 'W') AND (isset($sarr[($k +1)]))) {
// number of bytes (in the decoded stream) of the corresponding field
$wb = array();
$wb[0] = intval($sarr[($k +1)][1][0][1]);
$wb[1] = intval($sarr[($k +1)][1][1][1]);
$wb[2] = intval($sarr[($k +1)][1][2][1]);
} elseif (($v[0] == '/') AND ($v[1] == 'DecodeParms') AND (isset($sarr[($k +1)][1]))) {
$decpar = $sarr[($k +1)][1];
foreach ($decpar as $kdc => $vdc) {
if (($vdc[0] == '/') AND ($vdc[1] == 'Columns') AND (isset($decpar[($kdc +1)]) AND ($decpar[($kdc +1)][0] == 'numeric'))) {
$columns = intval($decpar[($kdc +1)][1]);
} elseif (($vdc[0] == '/') AND ($vdc[1] == 'Predictor') AND (isset($decpar[($kdc +1)]) AND ($decpar[($kdc +1)][0] == 'numeric'))) {
$predictor = intval($decpar[($kdc +1)][1]);
}
}
} elseif ($filltrailer) {
if (($v[0] == '/') AND ($v[1] == 'Size') AND (isset($sarr[($k +1)]) AND ($sarr[($k +1)][0] == 'numeric'))) {
$xref['trailer']['size'] = $sarr[($k +1)][1];
} elseif (($v[0] == '/') AND ($v[1] == 'Root') AND (isset($sarr[($k +1)]) AND ($sarr[($k +1)][0] == 'objref'))) {
$xref['trailer']['root'] = $sarr[($k +1)][1];
} elseif (($v[0] == '/') AND ($v[1] == 'Info') AND (isset($sarr[($k +1)]) AND ($sarr[($k +1)][0] == 'objref'))) {
$xref['trailer']['info'] = $sarr[($k +1)][1];
} elseif (($v[0] == '/') AND ($v[1] == 'Encrypt') AND (isset($sarr[($k +1)]) AND ($sarr[($k +1)][0] == 'objref'))) {
$xref['trailer']['encrypt'] = $sarr[($k +1)][1];
} elseif (($v[0] == '/') AND ($v[1] == 'ID') AND (isset($sarr[($k +1)]))) {
$xref['trailer']['id'] = array();
$xref['trailer']['id'][0] = $sarr[($k +1)][1][0][1];
$xref['trailer']['id'][1] = $sarr[($k +1)][1][1][1];
}
}
}
// decode data
if ($valid_crs AND isset($xrefcrs[1][3][0])) {
// number of bytes in a row
$rowlen = ($columns + 1);
// convert the stream into an array of integers
$sdata = unpack('C*', $xrefcrs[1][3][0]);
// split the rows
$sdata = array_chunk($sdata, $rowlen);
// initialize decoded array
$ddata = array();
// initialize first row with zeros
$prev_row = array_fill (0, $rowlen, 0);
// for each row apply PNG unpredictor
foreach ($sdata as $k => $row) {
// initialize new row
$ddata[$k] = array();
// get PNG predictor value
$predictor = (10 + $row[0]);
// for each byte on the row
for ($i=1; $i<=$columns; ++$i) {
// new index
$j = ($i - 1);
$row_up = $prev_row[$j];
if ($i == 1) {
$row_left = 0;
$row_upleft = 0;
} else {
$row_left = $row[($i - 1)];
$row_upleft = $prev_row[($j - 1)];
}
switch ($predictor) {
case 10: { // PNG prediction (on encoding, PNG None on all rows)
$ddata[$k][$j] = $row[$i];
break;
}
case 11: { // PNG prediction (on encoding, PNG Sub on all rows)
$ddata[$k][$j] = (($row[$i] + $row_left) & 0xff);
break;
}
case 12: { // PNG prediction (on encoding, PNG Up on all rows)
$ddata[$k][$j] = (($row[$i] + $row_up) & 0xff);
break;
}
case 13: { // PNG prediction (on encoding, PNG Average on all rows)
$ddata[$k][$j] = (($row[$i] + (($row_left + $row_up) / 2)) & 0xff);
break;
}
case 14: { // PNG prediction (on encoding, PNG Paeth on all rows)
// initial estimate
$p = ($row_left + $row_up - $row_upleft);
// distances
$pa = abs($p - $row_left);
$pb = abs($p - $row_up);
$pc = abs($p - $row_upleft);
$pmin = min($pa, $pb, $pc);
// return minimum distance
switch ($pmin) {
case $pa: {
$ddata[$k][$j] = (($row[$i] + $row_left) & 0xff);
break;
}
case $pb: {
$ddata[$k][$j] = (($row[$i] + $row_up) & 0xff);
break;
}
case $pc: {
$ddata[$k][$j] = (($row[$i] + $row_upleft) & 0xff);
break;
}
}
break;
}
default: { // PNG prediction (on encoding, PNG optimum)
$this->Error('Unknown PNG predictor');
break;
}
}
}
$prev_row = $ddata[$k];
} // end for each row
// complete decoding
$sdata = array();
// for every row
foreach ($ddata as $k => $row) {
// initialize new row
$sdata[$k] = array(0, 0, 0);
if ($wb[0] == 0) {
// default type field
$sdata[$k][0] = 1;
}
$i = 0; // count bytes in the row
// for every column
for ($c = 0; $c < 3; ++$c) {
// for every byte on the column
for ($b = 0; $b < $wb[$c]; ++$b) {
if (isset($row[$i])) {
$sdata[$k][$c] += ($row[$i] << (($wb[$c] - 1 - $b) * 8));
}
++$i;
}
}
}
$ddata = array();
// fill xref
if (isset($index_first)) {
$obj_num = $index_first;
} else {
$obj_num = 0;
}
foreach ($sdata as $k => $row) {
switch ($row[0]) {
case 0: { // (f) linked list of free objects
break;
}
case 1: { // (n) objects that are in use but are not compressed
// create unique object index: [object number]_[generation number]
$index = $obj_num.'_'.$row[2];
// check if object already exist
if (!isset($xref['xref'][$index])) {
// store object offset position
$xref['xref'][$index] = $row[1];
}
break;
}
case 2: { // compressed objects
// $row[1] = object number of the object stream in which this object is stored
// $row[2] = index of this object within the object stream
$index = $row[1].'_0_'.$row[2];
$xref['xref'][$index] = -1;
break;
}
default: { // null objects
break;
}
}
++$obj_num;
}
} // end decoding data
if (isset($prevxref)) {
// get previous xref
$xref = $this->getXrefData($prevxref, $xref);
}
return $xref;
}
/**
* Get object type, raw value and offset to next object
* @param $offset (int) Object offset.
* @return array containing object type, raw value and offset to next object
* @protected
* @since 1.0.000 (2011-06-20)
*/
protected function getRawObject($offset=0) {
$objtype = ''; // object type to be returned
$objval = ''; // object value to be returned
// skip initial white space chars: \x00 null (NUL), \x09 horizontal tab (HT), \x0A line feed (LF), \x0C form feed (FF), \x0D carriage return (CR), \x20 space (SP)
$offset += strspn($this->pdfdata, "\x00\x09\x0a\x0c\x0d\x20", $offset);
// get first char
$char = $this->pdfdata[$offset];
// get object type
switch ($char) {
case '%': { // \x25 PERCENT SIGN
// skip comment and search for next token
$next = strcspn($this->pdfdata, "\r\n", $offset);
if ($next > 0) {
$offset += $next;
return $this->getRawObject($offset);
}
break;
}
case '/': { // \x2F SOLIDUS
// name object
$objtype = $char;
++$offset;
if (preg_match('/^([^\x00\x09\x0a\x0c\x0d\x20\s\x28\x29\x3c\x3e\x5b\x5d\x7b\x7d\x2f\x25]+)/', substr($this->pdfdata, $offset, 256), $matches) == 1) {
$objval = $matches[1]; // unescaped value
$offset += strlen($objval);
}
break;
}
case '(': // \x28 LEFT PARENTHESIS
case ')': { // \x29 RIGHT PARENTHESIS
// literal string object
$objtype = $char;
++$offset;
$strpos = $offset;
if ($char == '(') {
$open_bracket = 1;
while ($open_bracket > 0) {
if (!isset($this->pdfdata[$strpos])) {
break;
}
$ch = $this->pdfdata[$strpos];
switch ($ch) {
case '\\': { // REVERSE SOLIDUS (5Ch) (Backslash)
// skip next character
++$strpos;
break;
}
case '(': { // LEFT PARENHESIS (28h)
++$open_bracket;
break;
}
case ')': { // RIGHT PARENTHESIS (29h)
--$open_bracket;
break;
}
}
++$strpos;
}
$objval = substr($this->pdfdata, $offset, ($strpos - $offset - 1));
$offset = $strpos;
}
break;
}
case '[': // \x5B LEFT SQUARE BRACKET
case ']': { // \x5D RIGHT SQUARE BRACKET
// array object
$objtype = $char;
++$offset;
if ($char == '[') {
// get array content
$objval = array();
do {
// get element
$element = $this->getRawObject($offset);
$offset = $element[2];
$objval[] = $element;
} while ($element[0] != ']');
// remove closing delimiter
array_pop($objval);
}
break;
}
case '<': // \x3C LESS-THAN SIGN
case '>': { // \x3E GREATER-THAN SIGN
if (isset($this->pdfdata[($offset + 1)]) AND ($this->pdfdata[($offset + 1)] == $char)) {
// dictionary object
$objtype = $char.$char;
$offset += 2;
if ($char == '<') {
// get array content
$objval = array();
do {
// get element
$element = $this->getRawObject($offset);
$offset = $element[2];
$objval[] = $element;
} while ($element[0] != '>>');
// remove closing delimiter
array_pop($objval);
}
} else {
// hexadecimal string object
$objtype = $char;
++$offset;
if (($char == '<') AND (preg_match('/^([0-9A-Fa-f\x09\x0a\x0c\x0d\x20]+)>/iU', substr($this->pdfdata, $offset), $matches) == 1)) {
// remove white space characters
$objval = strtr($matches[1], "\x09\x0a\x0c\x0d\x20", '');
$offset += strlen($matches[0]);
} elseif (($endpos = strpos($this->pdfdata, '>', $offset)) !== FALSE) {
$offset = $endpos + 1;
}
}
break;
}
default: {
if (substr($this->pdfdata, $offset, 6) == 'endobj') {
// indirect object
$objtype = 'endobj';
$offset += 6;
} elseif (substr($this->pdfdata, $offset, 4) == 'null') {
// null object
$objtype = 'null';
$offset += 4;
$objval = 'null';
} elseif (substr($this->pdfdata, $offset, 4) == 'true') {
// boolean true object
$objtype = 'boolean';
$offset += 4;
$objval = 'true';
} elseif (substr($this->pdfdata, $offset, 5) == 'false') {
// boolean false object
$objtype = 'boolean';
$offset += 5;
$objval = 'false';
} elseif (substr($this->pdfdata, $offset, 6) == 'stream') {
// start stream object
$objtype = 'stream';
$offset += 6;
if (preg_match('/^([\r]?[\n])/isU', substr($this->pdfdata, $offset), $matches) == 1) {
$offset += strlen($matches[0]);
if (preg_match('/(endstream)[\x09\x0a\x0c\x0d\x20]/isU', substr($this->pdfdata, $offset), $matches, PREG_OFFSET_CAPTURE) == 1) {
$objval = substr($this->pdfdata, $offset, $matches[0][1]);
$offset += $matches[1][1];
}
}
} elseif (substr($this->pdfdata, $offset, 9) == 'endstream') {
// end stream object
$objtype = 'endstream';
$offset += 9;
} elseif (preg_match('/^([0-9]+)[\s]+([0-9]+)[\s]+R/iU', substr($this->pdfdata, $offset, 33), $matches) == 1) {
// indirect object reference
$objtype = 'objref';
$offset += strlen($matches[0]);
$objval = intval($matches[1]).'_'.intval($matches[2]);
} elseif (preg_match('/^([0-9]+)[\s]+([0-9]+)[\s]+obj/iU', substr($this->pdfdata, $offset, 33), $matches) == 1) {
// object start
$objtype = 'obj';
$objval = intval($matches[1]).'_'.intval($matches[2]);
$offset += strlen ($matches[0]);
} elseif (($numlen = strspn($this->pdfdata, '+-.0123456789', $offset)) > 0) {
// numeric object
$objtype = 'numeric';
$objval = substr($this->pdfdata, $offset, $numlen);
$offset += $numlen;
}
break;
}
}
return array($objtype, $objval, $offset);
}
/**
* Get content of indirect object.
* @param $obj_ref (string) Object number and generation number separated by underscore character.
* @param $offset (int) Object offset.
* @param $decoding (boolean) If true decode streams.
* @return array containing object data.
* @protected
* @since 1.0.000 (2011-05-24)
*/
protected function getIndirectObject($obj_ref, $offset=0, $decoding=true) {
$obj = explode('_', $obj_ref);
if (($obj === false) OR (count($obj) != 2)) {
$this->Error('Invalid object reference: '.$obj);
return;
}
$objref = $obj[0].' '.$obj[1].' obj';
// ignore leading zeros
$offset += strspn($this->pdfdata, '0', $offset);
if (strpos($this->pdfdata, $objref, $offset) != $offset) {
// an indirect reference to an undefined object shall be considered a reference to the null object
return array('null', 'null', $offset);
}
// starting position of object content
$offset += strlen($objref);
// get array of object content
$objdata = array();
$i = 0; // object main index
do {
$oldoffset = $offset;
// get element
$element = $this->getRawObject($offset);
$offset = $element[2];
// decode stream using stream's dictionary information
if ($decoding AND ($element[0] == 'stream') AND (isset($objdata[($i - 1)][0])) AND ($objdata[($i - 1)][0] == '<<')) {
$element[3] = $this->decodeStream($objdata[($i - 1)][1], $element[1]);
}
$objdata[$i] = $element;
++$i;
} while (($element[0] != 'endobj') AND ($offset != $oldoffset));
// remove closing delimiter
array_pop($objdata);
// return raw object content
return $objdata;
}
/**
* Get the content of object, resolving indect object reference if necessary.
* @param $obj (string) Object value.
* @return array containing object data.
* @protected
* @since 1.0.000 (2011-06-26)
*/
protected function getObjectVal($obj) {
if ($obj[0] == 'objref') {
// reference to indirect object
if (isset($this->objects[$obj[1]])) {
// this object has been already parsed
return $this->objects[$obj[1]];
} elseif (isset($this->xref[$obj[1]])) {
// parse new object
$this->objects[$obj[1]] = $this->getIndirectObject($obj[1], $this->xref[$obj[1]], false);
return $this->objects[$obj[1]];
}
}
return $obj;
}
/**
* Decode the specified stream.
* @param $sdic (array) Stream's dictionary array.
* @param $stream (string) Stream to decode.
* @return array containing decoded stream data and remaining filters.
* @protected
* @since 1.0.000 (2011-06-22)
*/
protected function decodeStream($sdic, $stream) {
// get stream length and filters
$slength = strlen($stream);
if ($slength <= 0) {
return array('', array());
}
$filters = array();
foreach ($sdic as $k => $v) {
if ($v[0] == '/') {
if (($v[1] == 'Length') AND (isset($sdic[($k + 1)])) AND ($sdic[($k + 1)][0] == 'numeric')) {
// get declared stream length
$declength = intval($sdic[($k + 1)][1]);
if ($declength < $slength) {
$stream = substr($stream, 0, $declength);
$slength = $declength;
}
} elseif (($v[1] == 'Filter') AND (isset($sdic[($k + 1)]))) {
// resolve indirect object
$objval = $this->getObjectVal($sdic[($k + 1)]);
if ($objval[0] == '/') {
// single filter
$filters[] = $objval[1];
} elseif ($objval[0] == '[') {
// array of filters
foreach ($objval[1] as $flt) {
if ($flt[0] == '/') {
$filters[] = $flt[1];
}
}
}
}
}
}
// decode the stream
$remaining_filters = array();
foreach ($filters as $filter) {
if (in_array($filter, TCPDF_FILTERS::getAvailableFilters())) {
try {
$stream = TCPDF_FILTERS::decodeFilter($filter, $stream);
} catch (Exception $e) {
$emsg = $e->getMessage();
if ((($emsg[0] == '~') AND !$this->cfg['ignore_missing_filter_decoders'])
OR (($emsg[0] != '~') AND !$this->cfg['ignore_filter_decoding_errors'])) {
$this->Error($e->getMessage());
}
}
} else {
// add missing filter to array
$remaining_filters[] = $filter;
}
}
return array($stream, $remaining_filters);
}
/**
* Throw an exception or print an error message and die if the K_TCPDF_PARSER_THROW_EXCEPTION_ERROR constant is set to true.
* @param $msg (string) The error message
* @public
* @since 1.0.000 (2011-05-23)
*/
public function Error($msg) {
if ($this->cfg['die_for_errors']) {
die('<strong>TCPDF_PARSER ERROR: </strong>'.$msg);
} else {
throw new Exception('TCPDF_PARSER ERROR: '.$msg);
}
}
} // END OF TCPDF_PARSER CLASS
//============================================================+
// END OF FILE
//============================================================+
+219 -51
View File
@@ -55,10 +55,13 @@ class Verbrauchskostenreport extends IPSModule
$this->RegisterPropertyBoolean('EnableVAT', false);
$this->RegisterPropertyFloat('VATPercentage', 8.1);
// Neue Felder für den QR-Schein
$this->RegisterPropertyString('CreditorName', 'Belevo AG');
$this->RegisterPropertyString('CreditorAddress', 'Musterstrasse 1');
$this->RegisterPropertyString('CreditorCity', '6122 Menznau');
// Strukturierte Adressfelder für den QR-Zahlteil nach SIX SPS 2.3
$this->RegisterPropertyString('CreditorName', '');
$this->RegisterPropertyString('CreditorStreet', '');
$this->RegisterPropertyString('CreditorBuildingNumber', '');
$this->RegisterPropertyString('CreditorPostalCode', '');
$this->RegisterPropertyString('CreditorTown', '');
$this->RegisterPropertyString('CreditorCountry', 'CH');
$this->RegisterPropertyString('BankIBAN', '');
$this->RegisterTariffVariableProfiles();
@@ -703,12 +706,15 @@ form.onsubmit=function(){
<table>
<thead>
<tr>
<th style='width:18%'>Name</th>
<th style='width:18%'>Adresse</th>
<th style='width:18%'>Ort</th>
<th style='width:19%'>Stromzaehler</th>
<th style='width:19%'>Nebenzaehler</th>
<th style='width:8%'>Aktion</th>
<th style='width:13%'>Name</th>
<th style='width:13%'>Strasse</th>
<th style='width:6%'>Nr.</th>
<th style='width:7%'>PLZ</th>
<th style='width:11%'>Ort</th>
<th style='width:6%'>Land</th>
<th style='width:17%'>Stromzaehler</th>
<th style='width:17%'>Nebenzaehler</th>
<th style='width:10%'>Aktion</th>
</tr>
</thead>
<tbody>" . $rows . "</tbody>
@@ -831,8 +837,11 @@ refreshPickers();
return '<tr>'
. '<td><input type="hidden" name="user_id[]" value="' . $this->h($userId) . '"><input type="hidden" name="row_key[]" value="' . $this->h($rowKey) . '"><input name="user_name[]" value="' . $this->h($user['name'] ?? '') . '"></td>'
. '<td><input name="user_address[]" value="' . $this->h($user['address'] ?? '') . '"></td>'
. '<td><input name="user_city[]" value="' . $this->h($user['city'] ?? '') . '"></td>'
. '<td><input name="user_street[]" value="' . $this->h($user['street'] ?? '') . '"></td>'
. '<td><input name="user_building_number[]" value="' . $this->h($user['building_number'] ?? '') . '"></td>'
. '<td><input name="user_postal_code[]" value="' . $this->h($user['postal_code'] ?? '') . '"></td>'
. '<td><input name="user_town[]" value="' . $this->h($user['town'] ?? '') . '"></td>'
. '<td><input name="user_country[]" value="' . $this->h($user['country'] ?? 'CH') . '"></td>'
. '<td>' . $this->BuildMeterPicker('power', 'power_assign', $rowKey, $powerMeters, $powerSelected) . '</td>'
. '<td>' . $this->BuildMeterPicker('water', 'water_assign', $rowKey, $waterMeters, $waterSelected) . '</td>'
. '<td><button type="button" class="danger" data-action="delete-user">Loeschen</button></td>'
@@ -923,13 +932,18 @@ refreshPickers();
{
$ids = $post['user_id'] ?? [];
$names = $post['user_name'] ?? [];
$addresses = $post['user_address'] ?? [];
$cities = $post['user_city'] ?? [];
$streets = $post['user_street'] ?? [];
$buildingNumbers = $post['user_building_number'] ?? [];
$postalCodes = $post['user_postal_code'] ?? [];
$towns = $post['user_town'] ?? [];
$countries = $post['user_country'] ?? [];
$rowKeys = $post['row_key'] ?? [];
$powerAssign = $post['power_assign'] ?? [];
$waterAssign = $post['water_assign'] ?? [];
if (!is_array($ids) || !is_array($names) || !is_array($addresses) || !is_array($cities) || !is_array($rowKeys)) {
if (!is_array($ids) || !is_array($names) || !is_array($streets)
|| !is_array($buildingNumbers) || !is_array($postalCodes)
|| !is_array($towns) || !is_array($countries) || !is_array($rowKeys)) {
throw new Exception('Ungueltige Benutzerwerte.');
}
if (!is_array($powerAssign)) {
@@ -968,18 +982,31 @@ refreshPickers();
}
$assignedPower = [];
$assignedWater = [];
$count = max(count($ids), count($names), count($addresses), count($cities), count($rowKeys));
$count = max(
count($ids),
count($names),
count($streets),
count($buildingNumbers),
count($postalCodes),
count($towns),
count($countries),
count($rowKeys)
);
for ($i = 0; $i < $count; $i++) {
$rowKey = (string)($rowKeys[$i] ?? $i);
$id = trim((string)($ids[$i] ?? ''));
$name = trim((string)($names[$i] ?? ''));
$address = trim((string)($addresses[$i] ?? ''));
$city = trim((string)($cities[$i] ?? ''));
$street = trim((string)($streets[$i] ?? ''));
$buildingNumber = trim((string)($buildingNumbers[$i] ?? ''));
$postalCode = trim((string)($postalCodes[$i] ?? ''));
$town = trim((string)($towns[$i] ?? ''));
$country = strtoupper(trim((string)($countries[$i] ?? 'CH')));
$selectedPower = $this->NormalizeMeterSelection($powerAssign[$rowKey] ?? []);
$selectedWater = $this->NormalizeMeterSelection($waterAssign[$rowKey] ?? []);
if ($id === '' && $name === '' && $address === '' && $city === '' && empty($selectedPower) && empty($selectedWater)) {
if ($id === '' && $name === '' && $street === '' && $buildingNumber === ''
&& $postalCode === '' && $town === '' && empty($selectedPower) && empty($selectedWater)) {
continue;
}
if ($id === '') {
@@ -993,8 +1020,12 @@ refreshPickers();
$user = $existingUsers[$id] ?? [];
$user['id'] = $id;
$user['name'] = $name;
$user['address'] = $address;
$user['city'] = $city;
$user['street'] = $street;
$user['building_number'] = $buildingNumber;
$user['postal_code'] = $postalCode;
$user['town'] = $town;
$user['country'] = $country;
unset($user['address'], $user['city']);
$users[] = $user;
foreach ($selectedPower as $meterIndex) {
@@ -1144,11 +1175,96 @@ refreshPickers();
}
}
if (trim($this->ReadPropertyString('BankIBAN')) !== '') {
$this->ValidateQRConfiguration($users, $errors);
}
if (!empty($errors)) {
throw new Exception(implode(' ', array_values(array_unique($errors))));
}
}
private function ValidateQRConfiguration(array $users, array &$errors)
{
$iban = strtoupper(str_replace(' ', '', $this->ReadPropertyString('BankIBAN')));
if (!preg_match('/^(CH|LI)[0-9]{19}$/', $iban) || !$this->IsValidIBAN($iban)) {
$errors[] = 'Die IBAN für den QR-Zahlteil ist ungültig.';
} elseif ($this->IsQRIBAN($iban)) {
$errors[] = 'Eine QR-IBAN erfordert eine QR-Referenz; für den Report ist eine normale CH/LI-IBAN zu verwenden.';
}
$this->ValidateStructuredQRAddress([
'name' => $this->ReadPropertyString('CreditorName'),
'street' => $this->ReadPropertyString('CreditorStreet'),
'building_number' => $this->ReadPropertyString('CreditorBuildingNumber'),
'postal_code' => $this->ReadPropertyString('CreditorPostalCode'),
'town' => $this->ReadPropertyString('CreditorTown'),
'country' => $this->ReadPropertyString('CreditorCountry')
], 'Zahlungsempfänger', $errors);
foreach ($users as $index => $user) {
if (!is_array($user)) {
continue;
}
$label = 'Benutzer ' . trim((string)($user['id'] ?? ($index + 1)));
$this->ValidateStructuredQRAddress($user, $label, $errors);
}
}
private function ValidateStructuredQRAddress(array $address, $label, array &$errors)
{
$name = trim((string)($address['name'] ?? ''));
$postalCode = trim((string)($address['postal_code'] ?? ''));
$town = trim((string)($address['town'] ?? ''));
$country = strtoupper(trim((string)($address['country'] ?? '')));
if ($name === '') {
$errors[] = $label . ': Name fehlt für den QR-Zahlteil.';
}
if ($postalCode === '') {
$errors[] = $label . ': PLZ fehlt für den QR-Zahlteil.';
}
if ($town === '') {
$errors[] = $label . ': Ort fehlt für den QR-Zahlteil.';
}
if (!preg_match('/^[A-Z]{2}$/', $country)) {
$errors[] = $label . ': Land muss als ISO-2-Code angegeben werden.';
}
$limits = [
'name' => 70,
'street' => 70,
'building_number' => 16,
'postal_code' => 16,
'town' => 35
];
foreach ($limits as $field => $limit) {
if (mb_strlen(trim((string)($address[$field] ?? ''))) > $limit) {
$errors[] = $label . ': Feld ' . $field . ' überschreitet ' . $limit . ' Zeichen.';
}
}
}
private function IsValidIBAN($iban)
{
$rearranged = substr($iban, 4) . substr($iban, 0, 4);
$remainder = 0;
for ($i = 0, $length = strlen($rearranged); $i < $length; $i++) {
$character = $rearranged[$i];
$numeric = ctype_alpha($character) ? (string)(ord($character) - 55) : $character;
for ($j = 0, $numericLength = strlen($numeric); $j < $numericLength; $j++) {
$remainder = (($remainder * 10) + (int)$numeric[$j]) % 97;
}
}
return $remainder === 1;
}
private function IsQRIBAN($iban)
{
$iid = (int)substr($iban, 4, 5);
return $iid >= 30000 && $iid <= 31999;
}
private function RequireTariffCoverage(array $tariffs, $type, $from, $to, array &$errors)
{
$gap = $this->GetTariffCoverageGap($tariffs, $type, (int)$from, (int)$to);
@@ -1419,7 +1535,14 @@ refreshPickers();
$periodText = date('d.m.Y', $from) . ' - ' . date('d.m.Y', $to);
$meterText = empty($meterNames) ? '-' : implode("\n", $meterNames);
$addressText = trim(($user['name'] ?? '') . "\n" . ($user['address'] ?? '') . "\n" . ($user['city'] ?? ''));
$addressText = implode("\n", array_filter([
trim((string)($user['name'] ?? '')),
trim((string)($user['street'] ?? '') . ' ' . (string)($user['building_number'] ?? '')),
trim((string)($user['postal_code'] ?? '') . ' ' . (string)($user['town'] ?? '')),
strtoupper(trim((string)($user['country'] ?? 'CH')))
], function ($value) {
return $value !== '';
}));
$meterLineCount = max(1, count(preg_split('/\r\n|\r|\n/', $meterText)));
$addressLineCount = max(1, count(preg_split('/\r\n|\r|\n/', $addressText)));
$meterBlockHeight = 22 + ($meterLineCount * 4.6);
@@ -1754,14 +1877,26 @@ refreshPickers();
$pdf->Line(62, $yStart, 62, 297);
$pdf->SetLineStyle(['dash' => 0, 'color' => [0, 0, 0]]);
if ($amount > 999999999.99) {
throw new Exception('Der Betrag überschreitet das Maximum für den QR-Zahlteil.');
}
$creditorName = $this->ReadPropertyString('CreditorName');
$creditorAddress = $this->ReadPropertyString('CreditorAddress');
$creditorCity = $this->ReadPropertyString('CreditorCity');
$creditorStreetLine = trim(
$this->ReadPropertyString('CreditorStreet') . ' '
. $this->ReadPropertyString('CreditorBuildingNumber')
);
$creditorTownLine = trim(
$this->ReadPropertyString('CreditorPostalCode') . ' '
. $this->ReadPropertyString('CreditorTown')
);
$creditorCountry = strtoupper($this->ReadPropertyString('CreditorCountry'));
$bankIBANFormatted = wordwrap($iban, 4, ' ', true);
$debtorLines = [
$user['name'] ?? '',
$user['address'] ?? '',
$user['city'] ?? ''
trim((string)($user['street'] ?? '') . ' ' . (string)($user['building_number'] ?? '')),
trim((string)($user['postal_code'] ?? '') . ' ' . (string)($user['town'] ?? '')),
strtoupper((string)($user['country'] ?? 'CH'))
];
// Linker Teil: Empfangsschein
@@ -1772,8 +1907,9 @@ refreshPickers();
$this->WriteQrTextBlock($pdf, 5, $yStart + 12, 52, 'Konto / Zahlbar an', [
$bankIBANFormatted,
$creditorName,
$creditorAddress,
$creditorCity
$creditorStreetLine,
$creditorTownLine,
$creditorCountry
], 6, 7, 3.2);
$this->WriteQrTextBlock($pdf, 5, $yStart + 39, 52, 'Zahlbar durch', $debtorLines, 6, 7, 3.2);
@@ -1823,8 +1959,9 @@ refreshPickers();
$this->WriteQrTextBlock($pdf, 118, $yStart + 5, 84, 'Konto / Zahlbar an', [
$bankIBANFormatted,
$creditorName,
$creditorAddress,
$creditorCity
$creditorStreetLine,
$creditorTownLine,
$creditorCountry
], 8, 9, 4);
$this->WriteQrTextBlock($pdf, 118, $yStart + 34, 84, 'Zusätzliche Informationen', [
@@ -1852,31 +1989,62 @@ refreshPickers();
$pdf->MultiCell($width, $lineHeight, $line, 0, 'L', false, 1);
}
}
private function GenerateQRString($iban, $amount, $user)
{
// Daten nach SIX Swiss Payment Standard beschneiden (max 70 Zeichen pro Zeile)
$creditorName = mb_substr($this->ReadPropertyString('CreditorName'), 0, 70);
$creditorStr = mb_substr($this->ReadPropertyString('CreditorAddress'), 0, 70);
$creditorCity = mb_substr($this->ReadPropertyString('CreditorCity'), 0, 70);
$sanitize = function ($value, $maxLength) {
$value = preg_replace('/[\r\n]+/', ' ', trim((string)$value));
return mb_substr((string)$value, 0, $maxLength);
};
// Fallback falls ein Mieter keinen Namen oder Ort hinterlegt hat (Banken verlangen das zwingend)
$debtorName = mb_substr(empty($user['name']) ? 'Unbekannt' : $user['name'], 0, 70);
$debtorStr = mb_substr($user['address'] ?? '', 0, 70);
$debtorCity = mb_substr(empty($user['city']) ? 'Unbekannt' : $user['city'], 0, 70);
$amountStr = number_format($amount, 2, '.', '');
// EPC / Swiss QR Code String Format (Exakte Reihenfolge ist kritisch!)
$lines = [
'SPC', '0200', '1', $iban, 'K',
$creditorName, $creditorStr, $creditorCity, '', '', 'CH',
'', '', '', '', '', '', '', // Ultimate Creditor (leer)
$amountStr, 'CHF', 'K',
$debtorName, $debtorStr, $debtorCity, '', '', 'CH',
'NON', '', // Reference Type (NON = Ohne Referenz)
'Verbrauchskostenreport Liegenschaft', // 30. Unstrukturierte Mitteilung
'EPD' // 31. Trailer (Zwingend exakt 'EPD' am Schluss!)
$creditor = [
'name' => $sanitize($this->ReadPropertyString('CreditorName'), 70),
'street' => $sanitize($this->ReadPropertyString('CreditorStreet'), 70),
'building_number' => $sanitize($this->ReadPropertyString('CreditorBuildingNumber'), 16),
'postal_code' => $sanitize($this->ReadPropertyString('CreditorPostalCode'), 16),
'town' => $sanitize($this->ReadPropertyString('CreditorTown'), 35),
'country' => strtoupper($sanitize($this->ReadPropertyString('CreditorCountry'), 2))
];
$debtor = [
'name' => $sanitize($user['name'] ?? '', 70),
'street' => $sanitize($user['street'] ?? '', 70),
'building_number' => $sanitize($user['building_number'] ?? '', 16),
'postal_code' => $sanitize($user['postal_code'] ?? '', 16),
'town' => $sanitize($user['town'] ?? '', 35),
'country' => strtoupper($sanitize($user['country'] ?? 'CH', 2))
];
$lines = [
'SPC',
'0200',
'1',
$iban,
'S',
$creditor['name'],
$creditor['street'],
$creditor['building_number'],
$creditor['postal_code'],
$creditor['town'],
$creditor['country'],
'', '', '', '', '', '', '', // Ultimate Creditor
number_format($amount, 2, '.', ''),
'CHF',
'S',
$debtor['name'],
$debtor['street'],
$debtor['building_number'],
$debtor['postal_code'],
$debtor['town'],
$debtor['country'],
'NON',
'',
$sanitize('Verbrauchskostenreport Liegenschaft', 140),
'EPD'
];
if (count($lines) !== 31) {
throw new LogicException('Swiss-QR-Payload muss genau 31 Basisfelder enthalten.');
}
return implode("\r\n", $lines);
}
+14 -4
View File
@@ -37,10 +37,20 @@ erstellt und im Medium `ReportPDF` bereitgestellt.
| `FooterText` / Fusstext | String | Bestehender editierbarer Text. |
| `EnableVAT` / MWST aktiv | Boolean | `false`. |
| `VATPercentage` / MWST-Satz | Float | Code-Default `8.1`; kein automatisch gültiger Steuersatz. |
| `CreditorName` / Zahlungsempfänger | String | `Belevo AG`. |
| `CreditorAddress` / Adresse | String | Konfigurierbarer Platzhalter. |
| `CreditorCity` / Ort | String | Konfigurierbare Vorgabe. |
| `BankIBAN` / IBAN | String | leer. |
| `CreditorName` / Zahlungsempfänger | String | leer; Pflichtfeld bei aktivem QR-Zahlteil. |
| `CreditorStreet` / Strasse | String | leer; strukturierter Adressbestandteil. |
| `CreditorBuildingNumber` / Hausnummer | String | leer; strukturierter Adressbestandteil. |
| `CreditorPostalCode` / PLZ | String | leer; Pflichtfeld bei aktivem QR-Zahlteil. |
| `CreditorTown` / Ort | String | leer; Pflichtfeld bei aktivem QR-Zahlteil. |
| `CreditorCountry` / Land | String | ISO-2-Code; Standard `CH`. |
| `BankIBAN` / IBAN | String | normale CH/LI-IBAN; leer deaktiviert den QR-Zahlteil. |
## Migration der QR-Adressen
Bestehende kombinierte Adresswerte werden nicht automatisch aufgeteilt. Vor dem
nächsten QR-Report müssen Strasse, Hausnummer, PLZ, Ort und Land kontrolliert und
strukturiert gespeichert werden. Bei aktiver IBAN verhindern fehlende Pflichtfelder
die Reporterzeugung mit einer verständlichen Fehlermeldung.
## Offene Punkte
+21
View File
@@ -54,6 +54,27 @@ final class LibraryMetadataTest extends TestCase
self::assertStringNotContainsString('echo ', substr($inhalt, $anfang, $ende - $anfang));
}
public function testQrZahlteilVerwendetStrukturierteAdressenUndAktuellesTcpdf(): void
{
$formular = file_get_contents(__DIR__ . '/../Verbrauchskostenreport/form.json');
$modul = file_get_contents(__DIR__ . '/../Verbrauchskostenreport/module.php');
$composer = json_decode(
file_get_contents(__DIR__ . '/../Verbrauchskostenreport/libs/composer.json'),
true,
512,
JSON_THROW_ON_ERROR
);
self::assertNotFalse($formular);
self::assertNotFalse($modul);
foreach (['CreditorStreet', 'CreditorBuildingNumber', 'CreditorPostalCode', 'CreditorTown', 'CreditorCountry'] as $feld) {
self::assertStringContainsString('"name": "' . $feld . '"', $formular);
}
self::assertStringContainsString("\$iban,\n 'S'", $modul);
self::assertStringNotContainsString("\$iban, 'K'", $modul);
self::assertSame('6.11.3', $composer['require']['tecnickcom/tcpdf']);
}
public function testVerbrauchskostenreportVerwendetNeutraleBegriffe(): void
{
$dateien = [