EpubReader
in package
Minimal in-tree EPUB reader.
Replaces kiwilan/php-ebook for LWT's single use case: pulling metadata and
readable chapter text out of an EPUB. It deliberately implements only EPUB,
where the dependency also covered MOBI, CBZ and PDF, none of which LWT
imports.
Structure read, per the OCF and OPF specifications:
META-INF/container.xmlnames the OPF package document.- The OPF carries Dublin Core metadata, a manifest of every resource, and a spine giving reading order.
- The table of contents is either an EPUB 2 NCX (
navMap/navPoint) or an EPUB 3 navigation document (<nav epub:type="toc">). Both are read; NCX wins when a book ships both, matching reader behaviour.
Every XPath query matches on local-name() because EPUBs in the wild are
inconsistent about namespace prefixes and default namespaces.
Tags
Table of Contents
Constants
- LIBXML_OPTIONS : mixed = LIBXML_NONET | LIBXML_NOERROR | LIBXML_NOWARNING
- libxml options: never fetch external resources, and keep entity substitution off, so a hostile EPUB cannot mount an XXE or billion-laughs attack through any of the XML documents we parse.
Methods
- read() : EpubBook
- Read an EPUB from disk.
- directoryOf() : string
- The directory part of an archive path, with a trailing slash, or '' at the root.
- firstMetadataValue() : string|null
- The first Dublin Core value for an element name, or null when absent.
- locatePackageDocument() : string
- Resolve the OPF package document path from `META-INF/container.xml`.
- metadataValues() : array<int, string>
- Every non-empty Dublin Core value for an element name, in document order.
- parseHtml() : DOMDocument|null
- Parse a navigation document, which may be XHTML or plain HTML.
- parseXml() : DOMDocument|null
- Parse XML, returning null instead of raising on malformed input.
- readArchive() : EpubBook
- Parse an already-open archive.
- readManifest() : array<string, array{href: string, mediaType: string, properties: string}>
- Read the manifest into a map of item id => item details.
- readNavEntries() : array<int, array{0: string, 1: string}>
- Read EPUB 3 navigation-document TOC links, in document order.
- readNcxEntries() : array<int, array{0: string, 1: string}>
- Read EPUB 2 NCX navigation points, in document order.
- readSpine() : array<int, EpubDocument>
- Read the spine into content documents, in reading order.
- readTableOfContents() : array<int, EpubChapter>
- Build the chapter list from whichever table of contents the EPUB ships.
- resolveHref() : string
- Resolve a TOC href, dropping any fragment, against its document's directory.
Constants
LIBXML_OPTIONS
libxml options: never fetch external resources, and keep entity substitution off, so a hostile EPUB cannot mount an XXE or billion-laughs attack through any of the XML documents we parse.
private
mixed
LIBXML_OPTIONS
= LIBXML_NONET | LIBXML_NOERROR | LIBXML_NOWARNING
Methods
read()
Read an EPUB from disk.
public
static read(string $filePath) : EpubBook
Parameters
- $filePath : string
-
Absolute path to the EPUB
Tags
Return values
EpubBookdirectoryOf()
The directory part of an archive path, with a trailing slash, or '' at the root.
private
static directoryOf(string $path) : string
Parameters
- $path : string
Return values
stringfirstMetadataValue()
The first Dublin Core value for an element name, or null when absent.
private
static firstMetadataValue(DOMXPath $xpath, string $name) : string|null
Parameters
- $xpath : DOMXPath
- $name : string
Return values
string|nulllocatePackageDocument()
Resolve the OPF package document path from `META-INF/container.xml`.
private
static locatePackageDocument(EpubArchive $archive) : string
Falls back to scanning for a lone .opf entry when the container is
absent or malformed, which keeps slightly broken EPUBs importable.
Parameters
- $archive : EpubArchive
Tags
Return values
stringmetadataValues()
Every non-empty Dublin Core value for an element name, in document order.
private
static metadataValues(DOMXPath $xpath, string $name) : array<int, string>
Parameters
- $xpath : DOMXPath
- $name : string
Return values
array<int, string>parseHtml()
Parse a navigation document, which may be XHTML or plain HTML.
private
static parseHtml(string $source) : DOMDocument|null
Parameters
- $source : string
Return values
DOMDocument|nullparseXml()
Parse XML, returning null instead of raising on malformed input.
private
static parseXml(string $source) : DOMDocument|null
Parameters
- $source : string
Return values
DOMDocument|nullreadArchive()
Parse an already-open archive.
private
static readArchive(EpubArchive $archive) : EpubBook
Parameters
- $archive : EpubArchive
Tags
Return values
EpubBookreadManifest()
Read the manifest into a map of item id => item details.
private
static readManifest(DOMXPath $xpath, string $baseDir, EpubArchive $archive) : array<string, array{href: string, mediaType: string, properties: string}>
Parameters
- $xpath : DOMXPath
- $baseDir : string
- $archive : EpubArchive
Return values
array<string, array{href: string, mediaType: string, properties: string}>readNavEntries()
Read EPUB 3 navigation-document TOC links, in document order.
private
static readNavEntries(array<string, array{href: string, mediaType: string, properties: string}> $manifest, EpubArchive $archive) : array<int, array{0: string, 1: string}>
Parameters
- $manifest : array<string, array{href: string, mediaType: string, properties: string}>
- $archive : EpubArchive
Return values
array<int, array{0: string, 1: string}> —Label / resolved-href pairs
readNcxEntries()
Read EPUB 2 NCX navigation points, in document order.
private
static readNcxEntries(array<string, array{href: string, mediaType: string, properties: string}> $manifest, EpubArchive $archive) : array<int, array{0: string, 1: string}>
Parameters
- $manifest : array<string, array{href: string, mediaType: string, properties: string}>
- $archive : EpubArchive
Return values
array<int, array{0: string, 1: string}> —Label / resolved-href pairs
readSpine()
Read the spine into content documents, in reading order.
private
static readSpine(DOMXPath $xpath, array<string, array{href: string, mediaType: string, properties: string}> $manifest, EpubArchive $archive) : array<int, EpubDocument>
Parameters
- $xpath : DOMXPath
- $manifest : array<string, array{href: string, mediaType: string, properties: string}>
- $archive : EpubArchive
Return values
array<int, EpubDocument>readTableOfContents()
Build the chapter list from whichever table of contents the EPUB ships.
private
static readTableOfContents(DOMXPath $xpath, array<string, array{href: string, mediaType: string, properties: string}> $manifest, EpubArchive $archive, array<int, EpubDocument> $documents) : array<int, EpubChapter>
Parameters
- $xpath : DOMXPath
- $manifest : array<string, array{href: string, mediaType: string, properties: string}>
- $archive : EpubArchive
- $documents : array<int, EpubDocument>
Return values
array<int, EpubChapter>resolveHref()
Resolve a TOC href, dropping any fragment, against its document's directory.
private
static resolveHref(EpubArchive $archive, string $baseDir, string $href) : string
Parameters
- $archive : EpubArchive
- $baseDir : string
- $href : string