files

object

%CSV

/phlo/resources/files/CSV.phlo

CSV reader resource

Reads the first line as the header and picks its own separator by counting: more commas than semicolons and it is a comma, otherwise a semicolon. Every row comes back keyed by header name, so a file with duplicate or empty headers loses columns. It reads, it does not write.

filecsvreaderimport
static

CSV :: __handle

line 10
CSV::$__handle is een verwijzing naar de bestandshandle die wordt gebruikt voor het lezen of schrijven van CSV-gegevens op de opgegeven locatie en bestandsnaam.
"CSV/$path$filename"
method

%CSV -> __construct (string $filename, ?string $path = null)

line 11
Initialiseert een CSV-object door het pad van het bestand te construeren op basis van de gegeven bestandsnaam en optioneel pad, standaard ingesteld op 'data'. Als het geconstrueerde bestand leesbaar is, roept het de objRead-methode aan om de CSV-gegevens te lezen.
$path ??= data
$this->objFile = $path.strtr($filename, [slash => dot]).'.csv'
if (is_readable($this->objFile)) $this->objRead()
readonly

%CSV -> objFile:string

line 17
Converteert een CSV-bestand naar een obj-representatie voor eenvoudigere manipulatie binnen Phlo.
method

%CSV -> objRead:void

line 19
Leest een CSV-bestand en converteert de inhoud naar een associatieve array van objecten, waarbij de eerste rij als headers wordt gebruikt.
$fp = fopen($this->objFile, 'r+')
$headers = str_replace([dq, cr, lf], void, fgets($fp))
$delimiter = substr_count($headers, comma) > substr_count($headers, semi) ? comma : semi
$headers =  explode($delimiter, $headers)
while ($row = fgetcsv($fp, null, $delimiter, dq, void)) $this->objData[] = array_combine($headers, $row)
fclose($fp)
object

%DOCX

/phlo/resources/files/DOCX.phlo

DOCX reader resource

Pulls the plain text out of a .docx and nothing more: no styling, no tables as tables, no images. Paragraphs come out as a list, which is what makes it usable for search and for feeding a model, and DOCX::toText() is the one-liner for that.

filedocxwordreader
method

%DOCX -> __construct (string $file)

line 11
Initialiseert een DOCX-object door het opgegeven DOCX-bestand te openen, de tekst uit 'word/document.xml' te extraheren en deze te verwerken in alinea's.
$zip = new ZipArchive()
if ($zip->open($file) !== true) dx('error opening docx', $file)
$xml = $zip->getFromName('word/document.xml')
$zip->close()
if (!$xml) dx('error reading document.xml')
$text = preg_replace('/<\/w:p>/', lf, $xml)
$text = strip_tags($text)
$text = html_entity_decode($text, ENT_QUOTES | ENT_XML1, 'UTF-8')
$this->text = trim(preg_replace('/[ \t]+/', space, $text))
$this->paragraphs = array_values(array_filter(explode(lf, $this->text), fn($p) => trim($p) !== void))
static

DOCX :: toText (string $file):string

line 24
Converteert de inhoud van een DOCX-bestand naar platte tekst.
(new static($file))->text
object

%file

/phlo/resources/files/file.phlo

File resource

Wrap a path in %file and everything about it is one call away: contents, size, mime, hashes, human dates, and a token() derived from the file's sha1, so the same content always yields the same token. Watch the difference between file and name: file is where it sits, name is what it is called, and ext and mime read the name. An upload therefore keeps its extension while the temp path has none.

filefilesystemio
static

file :: __handle

line 10
Deze expressie bouwt een bestandspad door 'file/$file' te concatenateren met de optionele naam, indien opgegeven.
"file/$file".($name ? "/$name" : void)
method

%file -> __construct (public string $file, ?string $name = null, $contents = null, ...$args)

line 11
Initialiseert een bestandsobject met een opgegeven bestandsnaam, een optionele naam en optionele inhoud, en staat ook extra argumenten voor objectimport toe.
$name && $this->name = $name
is_string($contents) && $this->write($contents)
$args && $this->objImport(...$args)
method

%file -> append (string $data):int|false

line 17
Voegt de opgegeven stringgegevens toe aan het einde van het bestand, met exclusieve toegang tijdens de bewerking.
file_put_contents($this->file, $data, FILE_APPEND | LOCK_EX)
prop

%file -> basename:string

line 18
Geeft de basisnaam van het bestand terug vanuit het opgegeven bestandspad.
pathinfo($this->file, PATHINFO_BASENAME)
method

%file -> base64:string

line 19
Codet de inhoud van een bestand naar een Base64-string.
base64_encode($this->contents)
method

%file -> contents:string|false

line 20
Leest de volledige inhoud van een bestand in een string.
file_get_contents($this->file)
method

%file -> contentsINI (bool $parse = true):array|false

line 21
Leest de inhoud van een bestand en parseert het als een INI-string, waarbij een associatieve array wordt geretourneerd. De parameter $parse bepaalt of er getypeerde of ruwe scanning voor de INI-gegevens moet worden gebruikt.
parse_ini_string($this->contents, true, $parse ? INI_SCANNER_TYPED : INI_SCANNER_RAW)
method

%file -> contentsJSON ($assoc = null)

line 22
Decodeert de JSON-string die is opgeslagen in de inhouds-eigenschap naar een PHP-variabele, waarbij optioneel een associatieve array wordt geretourneerd als de $assoc-parameter op true is ingesteld.
json_decode($this->contents, $assoc)
method

%file -> copy ($to):bool

line 23
Kopieert het bestand dat door het huidige object wordt vertegenwoordigd naar het opgegeven bestemmingspad.
copy($this->file, $to)
method

%file -> created:int|false

line 24
Geeft de Unix-tijdstempel van de laatste keer dat het bestand is aangemaakt.
filectime($this->file)
method

%file -> createdAge:int

line 25
Geeft de leeftijd van het bestand op basis van de aanmaakdatum.
age($this->created)
method

%file -> createdHuman:string

line 26
Geeft een leesbare weergave van de creatietijd van het bestand.
time_human($this->created)
method

%file -> curl ($type = null, $filename = null):CURLFile

line 27
Maakt een nieuw CURLFile-object voor bestandsuploads in een cURL-verzoek, waarmee het bestandstype en de bestandsnaam kunnen worden opgegeven.
new CURLFile($this->file, $type, $filename)
method

%file -> delete:bool

line 28
Verwijdert het opgegeven bestand als het bestaat en retourneert een debugbericht dat het succes of falen van de bewerking aangeeft.
first($deleted = $this->exists && unlink($this->file), debug($deleted ? "Deleted $this->basename" : "Could not delete $this->basename"))
method

%file -> exists:bool

line 29
Controleert of het opgegeven bestand bestaat in het bestandssysteem.
file_exists($this->file)
prop

%file -> ext:string

line 30
Haal de bestandsextensie op uit de bestandsnaam die is opgeslagen in de 'name' eigenschap met behulp van de PHP-functie pathinfo.
pathinfo($this->name, PATHINFO_EXTENSION)
prop

%file -> filename:string

line 31
Haalt de bestandsnaam op uit het bestandspad dat is opgeslagen in de 'file' eigenschap.
pathinfo($this->file, PATHINFO_FILENAME)
method

%file -> getLine:string|false

line 32
Haalt een enkele regel op van een bestandspointer, retourneert false bij mislukking of de regel zonder afsluitende spaties bij succes.
($line = fgets($this->pointer)) === false ? false : rtrim($line)
method

%file -> getLength (int $length):string|false

line 33
Haal de lengte van het bestand op door een bepaald aantal bytes van de bestandspointer te lezen.
fread($this->pointer, $length)
method

%file -> is (string $file):bool

line 34
Controleert of het opgegeven bestand overeenkomt met de huidige bestandsinstantie.
$file === $this->file
method

%file -> md5:string|false

line 35
Berechnet de MD5-hash van het opgegeven bestand.
md5_file($this->file)
prop

%file -> mime:string

line 36
Geeft het MIME-type van het bestand op basis van de naam.
mime($this->name)
method

%file -> modified:int|false

line 37
Geeft de laatste wijzigingstijd van het opgegeven bestand terug als een Unix-tijdstempel.
filemtime($this->file)
method

%file -> modifiedAge:int

line 38
Geeft de leeftijd van het bestand op basis van de laatste wijzigingstijdstempel.
age($this->modified)
method

%file -> modifiedHuman:string

line 39
Geeft een leesbare weergave van de laatste wijzigingstijd van het bestand.
time_human($this->modified)
method

%file -> move ($to):bool

line 40
Verplaatst het huidige bestand naar een nieuwe locatie die is opgegeven door $to en werkt de bestandsverwijzing bij bij succes.
rename($this->file, $to) && $this->file = $to
prop

%file -> name:string

line 41
Dit haalt de basename van het bestand dat door het object wordt vertegenwoordigd, wat de naam van het bestand zonder pad is.
$this->basename
method

%file -> output ($download = false)

line 42
Geeft de inhoud van een bestand weer, met de optie om het te downloaden indien opgegeven.
output($this->contents, $this->name, $download)
prop

%file -> path:string

line 43
Dit haalt het pad van de map van het opgegeven bestand op en voegt er een schuine streep aan toe.
realpath(pathinfo($this->file, PATHINFO_DIRNAME)).slash
prop

%file -> pathRel:string

line 44
Deze expressie retourneert het relatieve pad van een bestand door te controleren of het bestandspad begint met 'app' en, indien dit het geval is, die prefix te verwijderen; anders retourneert het het oorspronkelijke bestandspad.
str_starts_with($this->file, app) ? substr($this->file, strlen(app)) : $this->file
prop

%file -> pointer

line 45
Opent het opgegeven bestand in lees- en schrijfmodes en retourneert een pointer naar de bestandsresource.
fopen($this->file, 'r+')
method

%file -> readable:bool

line 46
Controleert of het opgegeven bestand leesbaar is.
is_readable($this->file)
method

%file -> src:string

line 47
Deze expressie genereert een data-URI voor een bestand, waarbij het MIME-type en de base64-gecodeerde inhoud worden gecombineerd.
"data:$this->mime;base64,$this->base64"
method

%file -> size:int|false

line 48
Geeft de grootte van het opgegeven bestand in bytes terug.
filesize($this->file)
method

%file -> sizeHuman (int $precision = 0):string

line 49
Converteert een bestandsgrootte in bytes naar een leesbaar formaat, met een optionele precisie voor decimalen.
size_human($this->size, $precision)
method

%file -> sha1:string|false

line 50
Berechnet de SHA-1-hash van het opgegeven bestand.
sha1_file($this->file)
method

%file -> shortenTo (int $length):string

line 51
Verkort de bestandsnaam tot een opgegeven lengte terwijl de bestandsextensie behouden blijft, met toevoeging van een ellips als de naam wordt ingekort.
strlen($this->name) <= $length ? $this->name : substr($this->name, 0, $length - strlen($this->ext) - 3).dot.dot.dot.$this->ext
method

%file -> title:string

line 52
Haalt de titel uit de bestandsnaam door deze om te zetten naar een leesbaar formaat, waarbij underscores worden vervangen door spaties en de eerste letter wordt gecapitaliseerd.
ucfirst(strtr(pathinfo($this->name, PATHINFO_FILENAME), [us => space]))
method

%file -> token ($length = 20):string

line 53
Genereert een token van de opgegeven lengte met behulp van SHA-1 hashing.
token($length, $this->sha1)
method

%file -> type:string

line 54
Haalt het type van een bestand uit de MIME-type door de substring voor de eerste slash op te halen.
substr($this->mime, 0, strpos($this->mime, slash))
method

%file -> touch:bool

line 55
Maakt een nieuw bestand aan of werkt de tijdstempel van een bestaand bestand bij dat door het bestandspad is opgegeven.
touch($this->file)
method

%file -> writable:bool

line 56
Controleert of het opgegeven bestand schrijfbaar is.
is_writable($this->file)
method

%file -> writeINI ($data, bool $deleteEmpty = false):bool

line 57
Schrijft gegevens naar een INI-bestandsformaat. De optionele parameter staat het verwijderen van lege secties toe als deze op true is ingesteld.
$this->write(!$deleteEmpty || $data ? loop($data, fn($value, $key) => $key.' = '.dq.strtr($value, [dq => bs.dq, lf => '\n']).dq, lf).lf : void, $deleteEmpty)
method

%file -> writeJSON ($data, bool $deleteEmpty = false):bool

line 58
$this->write(!$deleteEmpty || $data ? json_encode($data, jsonPretty) : void, $deleteEmpty)
method

%file -> writeJSONplain ($data, bool $deleteEmpty = false):bool

line 59
Schrijft de opgegeven gegevens als een JSON-string naar een bestand, met de optie om lege vermeldingen te verwijderen op basis van de deleteEmpty-vlag.
$this->write(!$deleteEmpty || $data ? json_encode($data) : void, $deleteEmpty)
method

%file -> write (string $data, bool $deleteEmpty = false):bool

line 60
Schrijft de opgegeven stringgegevens naar een bestand, met de optie om het bestand te verwijderen als de gegevens leeg zijn.
if (!$data && $deleteEmpty) return $this->delete
if ($written = file_put_contents($this->file, $data, LOCK_EX) !== false) debug('Written '.$this->basename.' ('.$this->sizeHuman.')')
else error('Could not write '.$this->file)
return $written
method

%file -> objInfo:array

line 67
Maakt een object aan met informatie over een bestand, inclusief de naam, het bestaan, en optioneel de grootte, aanmaakdatum, wijzigingsdatum en MIME-type als het bestaat.
array_combine($keys = array_merge(['file', 'name', 'exists'], $this->exists ? ['sizeHuman', 'createdHuman', 'modifiedHuman', 'mime'] : []), loop($keys, fn($arg) => $this->$arg))
object

%img

/phlo/resources/files/img.phlo

GD image resource

Only scales down, never up: a request larger than the original returns the image untouched, so a thumbnail never looks stretched. The output format follows the extension you save to, so saving a .jpg writes JPEG at quality 85 whatever came in. Pass crop with a width and a height to fill the frame instead of fitting inside it, and top or bottom to choose which part survives.

imagegdfilegraphics
static

img :: detect ($data):?string

line 10
Detecteert het afbeeldingsformaat van gegeven binaire gegevens door de header te onderzoeken en retourneert het bijbehorende formaat als een string.
$header = substr($data, 0, 12)
if (substr($header, 0, 3) === "\xFF\xD8\xFF") return 'jpg'
if (substr($header, 0, 8) === "\x89PNG\x0D\x0A\x1A\x0A") return 'png'
if (substr($header, 0, 6) === 'GIF87a' || substr($header, 0, 6) === 'GIF89a') return 'gif'
if (substr($header, 0, 4) === 'RIFF' && substr($header, 8, 4) === 'WEBP') return 'webp'
if (substr($header, 0, 2) === "BM") return 'bmp'
if (substr($header, 0, 4) === "\x49\x49\x2A\x00" || substr($header, 0, 4) === "\x4D\x4D\x00\x2A") return 'tiff'
static

img :: __handle

line 20
Dit haalt de afbeeldingsbron op van het opgegeven bestandspad.
"img/$file"
method

%img -> __construct (public string $file)

line 21
Initialiseert een img-object met een openbare stringeigenschap $file die het bestandspad van de afbeelding vertegenwoordigt.
prop

%img -> src:GdImage

line 23
Deze functie maakt een afbeeldingsresource aan vanuit een string die afbeeldingsgegevens bevat, meestal geladen vanuit een bestand.
imagecreatefromstring(file_get_contents($this->file))
prop

%img -> width:int

line 24
Haal de breedte op van een afbeeldingsbron die is opgegeven door de `src`-eigenschap.
imagesx($this->src)
prop

%img -> height:int

line 25
Geeft de hoogte van de afbeelding die is opgegeven door de `src`-eigenschap.
imagesy($this->src)
method

%img -> scale ($width = null, $height = null, $crop = false):static

line 27
Schaalt de afbeelding naar de opgegeven breedte en hoogte, met de mogelijkheid om deze te croppen op basis van de opgegeven parameters.
if (!$width && !$height) return $this
$srcW = $this->width
$srcH = $this->height
$doCrop = ($crop && $width && $height)
if ($width && $height) $scale = $doCrop ? max($width / $srcW, $height / $srcH) : min($width / $srcW, $height / $srcH)
elseif ($width) $scale = $width / $srcW
else $scale = $height / $srcH
if ($scale >= 1) return $this
$scaledW = (int)round($srcW * $scale)
$scaledH = (int)round($srcH * $scale)
$destW = ($width && $height && $doCrop) ? (int)$width : $scaledW
$destH = ($width && $height && $doCrop) ? (int)$height : $scaledH
$offsetX = 0
$offsetY = 0
if ($width && $height && $doCrop){
	$offsetX = (int)-round(($scaledW - $destW) / 2)
	$offsetY = (int)-round(($scaledH - $destH) / 2)
	if ($crop === 'top') $offsetY = 0
	elseif ($crop === 'bottom') $offsetY = (int)-($scaledH - $destH)
}
$destImg = imagecreatetruecolor($destW, $destH)
imagealphablending($destImg, false)
imagesavealpha($destImg, true)
imagecopyresampled($destImg, $this->src, $offsetX, $offsetY, 0, 0, $scaledW, $scaledH, $srcW, $srcH)
$this->src = $destImg
$this->width = $destW
$this->height = $destH
return $this
method

%img -> ext ($file = null):string

line 58
Geeft de bestandsextensie van het opgegeven bestand in kleine letters terug. Als er geen bestand is opgegeven, wordt het standaardbestand van de instantie gebruikt.
strtolower(pathinfo($file ?? $this->file, PATHINFO_EXTENSION))
method

%img -> source ($format = null):string

line 60
Haal de bron van een afbeelding op in het opgegeven formaat, of het standaardformaat als er geen is opgegeven, door de uitvoer van de write-methode vast te leggen.
ob_start()
$this->write($format)
return ob_get_clean()
method

%img -> save ($file = null):bool

line 66
Slaat de afbeelding op de opgegeven bestandslocatie op als deze is opgegeven; anders schrijft het de afbeelding naar een standaardlocatie.
$file && $this->file = $file
return $this->write(null, $this->file)
method

%img -> write ($format = null, $file = null)

line 71
Schrijft de afbeelding naar een bestand in het opgegeven formaat, met JPEG als standaard als er geen formaat is opgegeven. Ondersteunde formaten zijn PNG, GIF, WebP en JPEG.
$format ??= $this->ext()
if ($format === 'png') return imagepng($this->src, $file, 8)
if ($format === 'gif') return imagegif($this->src, $file)
if ($format === 'webp'){
	imageistruecolor($this->src) || imagepalettetotruecolor($this->src)
	return imagewebp($this->src, $file)
}
return imagejpeg($this->src, $file, 85)
object

%INI

/phlo/resources/files/INI.phlo

Generic INI resource

The same shape as the JSON resource, saved when the object goes out of scope, but writing flattens the file: comments and section headers do not survive a round trip. Keep it to values a program owns; a file a person edits by hand deserves to be read rather than rewritten.

fileiniconfigparser
prop

%INI -> objFile:string

line 10
INI->$objFile wordt gebruikt om een INI-bestandobject te maken of te openen voor het lezen of schrijven van configuratie-instellingen.
static

INI :: __handle

line 12
INI::$__handle haalt de handle op voor het opgegeven INI-bestand, met de optie om het te parseren op basis van de opgegeven parameters.
"INI/$path$filename".(!$parse ? '/0' : void)
method

%INI -> __construct (string $filename, ?string $path = null, bool $parse = true)

line 13
Initialiseert een INI-object met een opgegeven bestandsnaam en optioneel pad, en leest het bestand als het toegankelijk is.
$path ??= data
$this->objFile = $path.strtr($filename, [slash => dot]).'.ini'
if (is_readable($this->objFile)) $this->objRead($parse)
method

%INI -> objRead ($parse = true)

line 19
Leest een INI-bestand en converteert het naar een obj, waarbij de waarden optioneel in hun respectieve types worden geparsed.
last($this->objData = parse_ini_file($this->objFile, true, $parse ? INI_SCANNER_TYPED : INI_SCANNER_RAW), $this->objChanged = false, $this)
method

%INI -> objWrite:int|false

line 20
Schrijft de huidige objectgegevens naar een INI-bestandsformaat, waarbij ervoor wordt gezorgd dat speciale tekens correct worden ontsnapt en het bestand tijdens de schrijfoperatie wordt vergrendeld.
file_put_contents($this->objFile, loop($this->objData, fn($value, $key) => $key.' = '.dq.strtr($value, [dq => bs.dq, lf => '\n']).dq, lf).lf, LOCK_EX)
method

%INI -> __destruct

line 22
De INI->__destruct-methode controleert of het object is gewijzigd en roept de objWrite-methode aan indien nodig om opruiming te verzorgen voordat het object wordt vernietigd.
$this->objChanged && $this->objWrite()
object

%JSON

/phlo/resources/files/JSON.phlo

Generic JSON resource

The file behaves as an object: read a key, write a key, and the file is saved when the object goes out of scope. That last part is the trap: nothing is written until then, so call objWrite() yourself when the request may end otherwise. Names are read against data/ and a slash in the name becomes a dot, so no name can escape the directory.

filejsonstorageparser
static

JSON :: __handle

line 11
Deze functie bouwt een JSON-bestandspad op basis van de opgegeven bestandsnaam en een associatieve boolean-vlag, die het formaat van het pad bepaalt.
"JSON/$path$filename".(is_bool($assoc) ? slash.(int)$assoc : void)
method

%JSON -> __construct (string $filename, ?string $path = null, $assoc = null)

line 12
Construeert een JSON-object vanuit een opgegeven bestandsnaam en optioneel pad, waarbij het volledige bestandspad wordt aangemaakt en de JSON-gegevens worden gelezen als het bestand toegankelijk is.
$path ??= data
$this->objFile = $path.strtr($filename, [slash => dot]).'.json'
if (is_readable($this->objFile)) $this->objRead($assoc)
readonly

%JSON -> objFile:string

line 18
Converteert een JSON-string naar een Phlo obj voor verdere manipulatie of verwerking.
method

%JSON -> objTouch:bool

line 20
Stelt de objChanged-eigenschap in op true, wat aangeeft dat het object is gewijzigd.
$this->objChanged = true
method

%JSON -> objRead ($assoc = null)

line 21
Leest een JSON-bestand en converteert het naar een object of een associatieve array op basis van de opgegeven parameter.
last($data = json_read($this->objFile, $assoc), $this->objData = $assoc || is_array($data) ? $data : get_object_vars($data), $this->objChanged = false, $this)
method

%JSON -> objWrite ($data, $flags = null)

line 22
Schrijft JSON-gegevens naar een objectbestand, eventueel met opgegeven vlaggen om het schrijfgedrag aan te passen.
first($written = json_write($this->objFile, $data, $flags), $written && $this->objChanged = false)
method

%JSON -> __destruct

line 24
Deze methode wordt aangeroepen wanneer een object wordt vernietigd, en zorgt ervoor dat eventuele wijzigingen aan de gegevens van het object worden geschreven voordat het uit het geheugen wordt verwijderd.
$this->objChanged && $this->objWrite($this->objData)
object

%PDF

/phlo/resources/files/PDF.phlo

PDF generator and reader

Two halves that share a name. Reading uses the pdftotext binary, so it needs poppler-utils on the machine and gives nothing on a scan without a text layer. Writing renders HTML through mPDF, and mode is the mPDF one: D sends a download, I shows it in the browser, S returns the bytes as a string, so leaving the default on an API route pushes a download at your caller.

filepdfreadergenerator
static

PDF :: toText (string $file):string

line 10
Converteert een PDF-bestand naar platte tekst met behulp van de `pdftotext` commandoregeltool en retourneert de geëxtraheerde tekst.
$process = proc_open('pdftotext '.escapeshellarg($file).' -', [['pipe', 'r'], ['pipe', 'w'], ['pipe', 'w']], $pipes)
if (!is_resource($process)) return null
fclose($pipes[0])
$text = stream_get_contents($pipes[1])
fclose($pipes[1])
$error = stream_get_contents($pipes[2])
fclose($pipes[2])
($code = proc_close($process)) && error("PDFToText Error: pdftotext command failed with code $code. Error: $error")
return rtrim($text, "\f")
prop

%PDF -> title:?string

line 22
Genereert een PDF-document met de opgegeven titel.
null
prop

%PDF -> author:?string

line 23
Haalt de auteur van het PDF-document op.
null
prop

%PDF -> subject:?string

line 24
Genereert een PDF-document op basis van het opgegeven onderwerp.
null
prop

%PDF -> keywords:?string

line 25
Genereert een lijst van trefwoorden die zijn geëxtraheerd uit een PDF-document.
null
prop

%PDF -> creator:string

line 26
De PDF->$creator eigenschap haalt de informatie over de maker van het PDF-document op.
'Phlo '.phlo.' (https://phlo.tech/)'
prop

%PDF -> filename:string

line 28
Dit item specificeert de bestandsnaam 'Download.pdf' voor een PDF-resource.
'Download.pdf'
prop

%PDF -> mode:string

line 29
Stelt de modus in voor PDF-verwerking, waarbij 'D' een specifieke werkwijze aangeeft.
'D'
method

%PDF -> fromHTML ($HTML):string

line 31
Genereert een PDF-document vanuit de opgegeven HTML-inhoud met behulp van de Mpdf-bibliotheek, waarbij verschillende metadata-eigenschappen zoals titel, auteur, onderwerp, trefwoorden en maker worden ingesteld voordat het bestand wordt geëxporteerd.
$mpdf = new \Mpdf\Mpdf
$this->title && $mpdf->SetTitle($this->title)
$this->author && $mpdf->SetAuthor($this->author)
$this->subject && $mpdf->SetSubject($this->subject)
$this->keywords && $mpdf->SetKeywords($this->keywords)
$this->creator && $mpdf->SetCreator($this->creator)
$mpdf->WriteHTML($HTML)
return $mpdf->Output($this->filename, $this->mode)
object

%UBL

/phlo/resources/files/UBL.phlo

UBL 2.1 invoice XML (PEPPOL BIS Billing 3.0) from a normalized invoice structure. Use UBL::invoice($data).

Builds the invoice XML that PEPPOL expects from a plain array with supplier, customer and lines. Tax is grouped by rate and each group gets its own subtotal, so lines at 21 and 9 percent land in the right boxes on their own. It formats and escapes the amounts you hand it but checks nothing: a total that does not match its lines is written out as given, and a receiver will reject it.

ublpeppolinvoicexmle-invoicingexport
static

UBL :: invoice (array $data):string

line 10
Genereert een UBL-factuur XML-structuur op basis van de verstrekte factuurgegevens, inclusief informatie over leverancier en klant, lijnitems, belastingberekeningen en totaalbedragen.
$currency = strtoupper((string)($data['currency'] ?? 'EUR'))
$issue = (string)($data['issue_date'] ?? void)
$due = (string)($data['due_date'] ?? void) ?: $issue
$lines = []
$linesSum = 0
$taxSubtotals = []
foreach ((array)($data['lines'] ?? []) AS $i => $line){
	$qty = (float)($line['quantity'] ?? 0)
	$net = round($qty * (float)($line['unit_price'] ?? 0), 2)
	$rate = (float)($line['tax_rate'] ?? 0)
	$lines[] = static::xmlLine($i + 1, $line, $qty, $net, $rate, $currency)
	$linesSum += $net
	$key = number_format($rate, 2, dot, void)
	$taxSubtotals[$key] = ($taxSubtotals[$key] ?? 0) + $net
}
$tax = (float)($data['tax_amount'] ?? 0)
$total = (float)($data['total_amount'] ?? 0)
$taxXml = void
foreach ($taxSubtotals AS $rate => $taxable){
	$amount = round($taxable * (float)$rate / 100, 2)
	$category = (float)$rate === 0.0 ? 'Z' : 'S'
	$taxXml .= implode(void, [
		'<cac:TaxSubtotal>',
		'<cbc:TaxableAmount currencyID="'.$currency.'">'.static::n($taxable).'</cbc:TaxableAmount>',
		'<cbc:TaxAmount currencyID="'.$currency.'">'.static::n($amount).'</cbc:TaxAmount>',
		'<cac:TaxCategory><cbc:ID>'.$category.'</cbc:ID><cbc:Percent>'.static::n((float)$rate).'</cbc:Percent>',
		'<cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme></cac:TaxCategory>',
		'</cac:TaxSubtotal>',
	])
}
$supplier = (array)($data['supplier'] ?? [])
$customer = (array)($data['customer'] ?? [])
return implode(void, [
	'<?xml version="1.0" encoding="UTF-8"?>',
	'<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">',
	'<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID>',
	'<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>',
	'<cbc:ID>'.static::esc((string)($data['number'] ?? void)).'</cbc:ID>',
	'<cbc:IssueDate>'.static::esc($issue).'</cbc:IssueDate>',
	'<cbc:DueDate>'.static::esc($due).'</cbc:DueDate>',
	'<cbc:InvoiceTypeCode>'.(!empty($data['credit_note']) ? '381' : '380').'</cbc:InvoiceTypeCode>',
	'<cbc:DocumentCurrencyCode>'.$currency.'</cbc:DocumentCurrencyCode>',
	static::partyXml('AccountingSupplierParty', (string)($supplier['name'] ?? void), $supplier, (string)($supplier['vat'] ?? void)),
	static::partyXml('AccountingCustomerParty', (string)($customer['name'] ?? void), $customer, (string)($customer['vat'] ?? void)),
	'<cac:TaxTotal><cbc:TaxAmount currencyID="'.$currency.'">'.static::n($tax).'</cbc:TaxAmount>'.$taxXml.'</cac:TaxTotal>',
	'<cac:LegalMonetaryTotal>',
	'<cbc:LineExtensionAmount currencyID="'.$currency.'">'.static::n($linesSum).'</cbc:LineExtensionAmount>',
	'<cbc:TaxExclusiveAmount currencyID="'.$currency.'">'.static::n($linesSum).'</cbc:TaxExclusiveAmount>',
	'<cbc:TaxInclusiveAmount currencyID="'.$currency.'">'.static::n($total).'</cbc:TaxInclusiveAmount>',
	'<cbc:PayableAmount currencyID="'.$currency.'">'.static::n($total).'</cbc:PayableAmount>',
	'</cac:LegalMonetaryTotal>',
	implode(void, $lines),
	'</Invoice>',
])
static

UBL :: xmlLine ($idx, $line, $qty, $net, $rate, $currency = 'EUR'):string

line 67
Genereert een XML-representatie van een factuurregel, inclusief details zoals hoeveelheid, bedrag, artikelbeschrijving, belastingcategorie en prijs.
$category = (float)$rate === 0.0 ? 'Z' : 'S'
return implode(void, [
	'<cac:InvoiceLine>',
	'<cbc:ID>'.$idx.'</cbc:ID>',
	'<cbc:InvoicedQuantity unitCode="EA">'.static::n($qty).'</cbc:InvoicedQuantity>',
	'<cbc:LineExtensionAmount currencyID="'.$currency.'">'.static::n($net).'</cbc:LineExtensionAmount>',
	'<cac:Item><cbc:Name>'.static::esc((string)($line['description'] ?? void)).'</cbc:Name>',
	'<cac:ClassifiedTaxCategory><cbc:ID>'.$category.'</cbc:ID><cbc:Percent>'.static::n((float)$rate).'</cbc:Percent>',
	'<cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme></cac:ClassifiedTaxCategory></cac:Item>',
	'<cac:Price><cbc:PriceAmount currencyID="'.$currency.'">'.static::n((float)($line['unit_price'] ?? 0)).'</cbc:PriceAmount></cac:Price>',
	'</cac:InvoiceLine>',
])
static

UBL :: partyXml ($wrapper, $name, $info, $vatNumber):string

line 82
Genereert een XML-representatie van een partij-element voor UBL, inclusief details zoals naam, adres, stad, postcode, land en belastinginformatie.
$address = (string)($info['address'] ?? void)
$postal = (string)($info['postal_code'] ?? void)
$city = (string)($info['city'] ?? void)
$country = (string)($info['country'] ?? void) ?: 'NL'
$tax = $vatNumber ? '<cac:PartyTaxScheme><cbc:CompanyID>'.static::esc($vatNumber).'</cbc:CompanyID><cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme></cac:PartyTaxScheme>' : void
return implode(void, [
	'<cac:'.$wrapper.'><cac:Party>',
	'<cac:PartyName><cbc:Name>'.static::esc($name).'</cbc:Name></cac:PartyName>',
	'<cac:PostalAddress>',
	'<cbc:StreetName>'.static::esc($address).'</cbc:StreetName>',
	'<cbc:CityName>'.static::esc($city).'</cbc:CityName>',
	'<cbc:PostalZone>'.static::esc($postal).'</cbc:PostalZone>',
	'<cac:Country><cbc:IdentificationCode>'.static::esc(strtoupper($country)).'</cbc:IdentificationCode></cac:Country>',
	'</cac:PostalAddress>',
	$tax,
	'<cac:PartyLegalEntity><cbc:RegistrationName>'.static::esc($name).'</cbc:RegistrationName></cac:PartyLegalEntity>',
	'</cac:Party></cac:'.$wrapper.'>',
])
static

UBL :: n ($v):string

line 103
Formatteert een getal naar twee decimalen met behulp van het opgegeven decimaalteken en duizendtallen scheidingsteken.
number_format((float)$v, 2, dot, void)
static

UBL :: esc ($v):string

line 104
Converteert speciale tekens naar HTML-entiteiten voor XML-uitvoer, en zorgt voor de juiste codering van UTF-8-strings.
htmlspecialchars((string)$v, ENT_XML1 | ENT_QUOTES, 'UTF-8')
object

%XLSX

/phlo/resources/files/XLSX.phlo

XLSX reader resource

Reads a workbook without a library by unpacking the zip itself, and gives every sheet by name with the first row as the header. Values arrive as the sheet stored them, so a date is the serial number Excel keeps and a percentage is a fraction; convert those yourself. Formulas give the last calculated value, so a sheet that was never opened after an edit hands you the old one.

filexlsxexcelreader
method

%XLSX -> __construct (string $file)

line 16
Reads the sheets straight out of the zip with regular expressions instead of an XML parser.
$sheets = []
$shared = []
$sheetNames = []
$zip = new ZipArchive()
if ($zip->open($file) !== true) dx('error opening zip', $file)
for ($i = 0; $i < $zip->numFiles; $i++){
	$name = $zip->getNameIndex($i)
	if ($name === false) continue
	if (dirname($name) === 'xl/worksheets') $sheets[filter_var($name, FILTER_SANITIZE_NUMBER_INT)] = $zip->getFromIndex($i)
	elseif ($name === 'xl/sharedStrings.xml'){
		$xml = $zip->getFromIndex($i)
		if (!preg_match_all('/<t[^>]*>(.*?)<\/t>/s', $xml, $m)) dx('error reading shared lib')
		$shared = array_map(fn($t) => html_entity_decode($t, ENT_QUOTES | ENT_XML1, 'UTF-8'), $m[1])
	}
	elseif ($name === 'xl/workbook.xml'){
		$xml = $zip->getFromIndex($i)
		if (!preg_match_all('/<sheet[^>]*name="([^"]+)"[^>]*sheetId="([0-9]+)"/', $xml, $m)) dx('error reading workbook')
		$sheetNames = $m[1]
	}
}
$zip->close()
$toIndex = fn($letters) => array_reduce(str_split(strtoupper($letters)), fn($n, $c) => $n * 26 + ord($c) - 64, 0) - 1
$isShared = fn($attrs) => preg_match('/\bt="s"\b/', $attrs) === 1
foreach ($sheets AS $sheetID => $sheet){
	$name = $sheetNames[$sheetID - 1] ?? 'Sheet '.$sheetID
	if (!preg_match('/<row[^>]*>(.+)<\/row>/s', $sheet, $m)) dx('error parsing sheet')
	$rowsXml = preg_split('/<\/row><row[^>]*>/', $m[1]) ?: []
	$headerMap = []
	$isHeader = true
	foreach ($rowsXml AS $rowXml){
		$rowXml = preg_replace('/<c([^>]*)\/>/', '<c$1></c>', $rowXml)
		if (!preg_match_all('/<c r="([A-Z]+)[0-9]+"([^>]*)>(?:<f\b[^>]*\/?>)?(?:(?:<v>([^<]*)<\/v>)|(?:<is>.*?<t[^>]*>(.*?)<\/t>.*?<\/is>))?<\/c>/s', $rowXml, $mm)) dx('error parsing row', $rowXml)
		if ($isHeader){
			foreach (array_keys($mm[0]) AS $i){
				$col = $toIndex($mm[1][$i])
				$attrs = $mm[2][$i]
				$valV = $mm[3][$i] ?? null
				$valIS = $mm[4][$i] ?? null
				$val = $valV !== null && $valV !== void ? $valV : ($valIS !== null && $valIS !== void ? html_entity_decode($valIS, ENT_QUOTES | ENT_XML1, 'UTF-8') : null)
				$txt = $isShared($attrs) ? ($shared[$val] ?? null) : $val
				$headerMap[$col] = $txt !== null && $txt !== void ? $txt : 'col'.$col
			}
			$isHeader = false
		}
		else {
			$rowArr = []
			foreach (array_keys($mm[0]) AS $i){
				$col = $toIndex($mm[1][$i])
				$attrs = $mm[2][$i]
				$valV = $mm[3][$i] ?? null
				$valIS = $mm[4][$i] ?? null
				$val = $valV !== null && $valV !== void ? $valV : ($valIS !== null && $valIS !== void ? html_entity_decode($valIS, ENT_QUOTES | ENT_XML1, 'UTF-8') : null)
				$key = $headerMap[$col] ?? 'col'.$col
				$rowArr[$key] = $isShared($attrs) ? ($shared[$val] ?? null) : $val
			}
			$this->objData[$name][] = $rowArr
		}
	}
}

Laatst bijgewerkt op 08-08-2026

We gebruiken essentiële cookies om deze site te laten werken. Met uw toestemming gebruiken we ook analytics om de site te verbeteren.