diff --git a/.gitignore b/.gitignore
index b2932df..6089c48 100644
--- a/.gitignore
+++ b/.gitignore
@@ -83,4 +83,6 @@ legacy/vendor
legacy/vendor/*
testData
-testData/*
\ No newline at end of file
+testData/*
+
+/ExampleBook*.epub
\ No newline at end of file
diff --git a/rector.php b/rector.php
index c2fe993..85fc8a6 100644
--- a/rector.php
+++ b/rector.php
@@ -5,13 +5,18 @@
use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
+use Rector\Set\ValueObject\SetList;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
__DIR__ . '/src',
]);
$rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
- $rectorConfig->sets([
- LevelSetList::UP_TO_PHP_82
+ $rectorConfig->sets([SetList::CODE_QUALITY,
+ SetList::DEAD_CODE,
+ SetList::EARLY_RETURN,
+ SetList::TYPE_DECLARATION,
+ LevelSetList::UP_TO_PHP_81,
+ SetList::CODING_STYLE
]);
};
diff --git a/src/PHPePub/Core/EPub.php b/src/PHPePub/Core/EPub.php
index bf50f81..15c6e4d 100644
--- a/src/PHPePub/Core/EPub.php
+++ b/src/PHPePub/Core/EPub.php
@@ -2,7 +2,6 @@
namespace PHPePub\Core;
-use com\grandt\BinStringStatic;
use Masterminds\HTML5;
use DOMDocument;
use DOMXPath;
@@ -42,25 +41,33 @@ class EPub
final public const VERSION = '4.0.6';
final public const IDENTIFIER_UUID = 'UUID';
+
final public const IDENTIFIER_URI = 'URI';
+
final public const IDENTIFIER_ISBN = 'ISBN';
/** Ignore all external references, and do not process the file for these */
final public const EXTERNAL_REF_IGNORE = 0;
+
/** Process the file for external references and add them to the book */
final public const EXTERNAL_REF_ADD = 1;
+
/** Process the file for external references and add them to the book, but remove images, and img tags */
final public const EXTERNAL_REF_REMOVE_IMAGES = 2;
+
/** Process the file for external references and add them to the book, but replace images, and img tags with [image] */
final public const EXTERNAL_REF_REPLACE_IMAGES = 3;
final public const DIRECTION_LEFT_TO_RIGHT = 'ltr';
+
final public const DIRECTION_RIGHT_TO_LEFT = 'rtl';
final public const BOOK_VERSION_EPUB2 = '2.0';
+
final public const BOOK_VERSION_EPUB3 = '3.0';
final public const FORMAT_XHTML = 'xhtml';
+
final public const FORMAT_HTML5 = 'html5';
public $viewportMap = ["small" => ['width' => 600, 'height' => 800], "medium" => ['width' => 720, 'height' => 1280], "720p" => ['width' => 720, 'height' => 1280], "ipad" => ['width' => 768, 'height' => 1024], "large" => ['width' => 1080, 'height' => 1920], "2k" => ['width' => 1080, 'height' => 1920], "1080p" => ['width' => 1080, 'height' => 1920], "ipad3" => ['width' => 1536, 'height' => 2048], "4k" => ['width' => 2160, 'height' => 3840]];
@@ -68,7 +75,9 @@ class EPub
public $splitDefaultSize = 250000;
public $maxImageWidth = 768;
+
public $maxImageHeight = 1024;
+
/**
* Gifs can crash some early ADE based readers, and are disabled by default.
* getImage will convert these if it can, unless this is set to TRUE.
@@ -76,63 +85,105 @@ class EPub
public $isGifImagesEnabled = false;
public $isReferencesAddedToToc = true;
+
/**
* Used for building the TOC.
* If this list is overwritten it MUST contain at least "text" as an element.
*/
- public $referencesOrder = null;
+ public $referencesOrder;
public $pluginDir = 'extLib';
public $isLogging = true;
+
public $encodeHTML = false;
+
/** @var $Zip Zip */
- private $zip;
- private $title = '';
- private $language = 'en';
- private $identifier = '';
- private $identifierType = '';
- private $description = '';
- private $author = '';
- private $authorSortKey = '';
- private $publisherName = '';
- private $publisherURL = '';
- private $date = 0;
- private $rights = '';
- private $coverage = '';
- private $relation = '';
- private $sourceURL = '';
- private $chapterCount = 0;
+ private \PHPZip\Zip\File\Zip $zip;
+
+ private string $title = '';
+
+ private string $language = 'en';
+
+ private string $identifier = '';
+
+ private string $identifierType = '';
+
+ private string $description = '';
+
+ private string $author = '';
+
+ private string $authorSortKey = '';
+
+ private string $publisherName = '';
+
+ private string $publisherURL = '';
+
+ private int $date = 0;
+
+ private string $rights = '';
+
+ private string $coverage = '';
+
+ private string $relation = '';
+
+ private string $sourceURL = '';
+
+ private int $chapterCount = 0;
+
/** @var $opf Opf */
- private $opf = null;
+ private ?\PHPePub\Core\Structure\Opf $opf = null;
+
/** @var $ncx Ncx */
- private $ncx = null;
- private $isFinalized = false;
- private $isInitialized = false;
- private $isCoverImageSet = false;
- private $buildTOC = false; // ISO 8601 long
- private $tocTitle = null; // short date format to placate ePubChecker.
- private $tocFileName = null;
- private $tocNavAdded = false;
- private $tocCSSClass = null;
- private $tocAddReferences = false;
- private $tocCssFileName = null;
- private $fileList = [];
- private $dateformat = 'Y-m-d\TH:i:s.000000P';
- private $dateformatShort = 'Y-m-d';
- private $headerDateFormat = "D, d M Y H:i:s T";
- private $docRoot = null;
- private $bookRoot = 'OEBPS/';
- private $EPubMark = true;
- private $generator = '';
- private $log = null;
- private $htmlContentHeader = "\n\n\n
\n\n\n\n";
- private $htmlContentFooter = "\n\n";
-
- /** @var array $viewport */
- private $viewport = null;
-
- private $dangermode = false;
+ private ?\PHPePub\Core\Structure\Ncx $ncx = null;
+
+ private bool $isFinalized = false;
+
+ private bool $isInitialized = false;
+
+ private bool $isCoverImageSet = false;
+
+ private bool $buildTOC = false;
+
+ // ISO 8601 long
+ private $tocTitle;
+
+ // short date format to placate ePubChecker.
+ private ?string $tocFileName = null;
+
+ private bool $tocNavAdded = false;
+
+ private $tocCSSClass;
+
+ private bool $tocAddReferences = false;
+
+ private ?string $tocCssFileName = null;
+
+ private array $fileList = [];
+
+ private string $dateformat = 'Y-m-d\TH:i:s.000000P';
+
+ private string $dateformatShort = 'Y-m-d';
+
+ private string $headerDateFormat = "D, d M Y H:i:s T";
+
+ private ?string $docRoot = null;
+
+ private string $bookRoot = 'OEBPS/';
+
+ private bool $EPubMark = true;
+
+ private string $generator = '';
+
+ private ?\PHPePub\Core\Logger $log = null;
+
+ private string $htmlContentHeader = "\n\n\n\n\n\n\n";
+
+ private string $htmlContentFooter = "\n\n";
+
+ private ?array $viewport = null;
+
+ private bool $dangermode = false;
/**
* Class constructor.
@@ -155,10 +206,11 @@ public function __construct(
$this->log->logLine('EPub class version....: ' . self::VERSION);
$this->log->dumpInstalledModules();
}
+
$this->setUp();
}
- private function setUp()
+ private function setUp(): void
{
$this->referencesOrder = [Reference::COVER => 'Cover Page', Reference::TITLE_PAGE => 'Title Page', Reference::ACKNOWLEDGEMENTS => 'Acknowledgements', Reference::BIBLIOGRAPHY => 'Bibliography', Reference::COLOPHON => 'Colophon', Reference::COPYRIGHT_PAGE => 'Copyright', Reference::DEDICATION => 'Dedication', Reference::EPIGRAPH => 'Epigraph', Reference::FOREWORD => 'Foreword', Reference::TABLE_OF_CONTENTS => 'Table of Contents', Reference::NOTES => 'Notes', Reference::PREFACE => 'Preface', Reference::TEXT => 'First Page', Reference::LIST_OF_ILLUSTRATIONS => 'List of Illustrations', Reference::LIST_OF_TABLES => 'List of Tables', Reference::GLOSSARY => 'Glossary', Reference::INDEX => 'Index'];
@@ -213,13 +265,15 @@ public function __destruct()
*
* @return mixed $success FALSE if the addition failed, else the new NavPoint.
*/
- public function addChapter($chapterName, $fileName, $chapterData = null, $autoSplit = false, $externalReferences = EPub::EXTERNAL_REF_IGNORE, $baseDir = "")
+ public function addChapter($chapterName, $fileName, $chapterData = null, $autoSplit = false, $externalReferences = EPub::EXTERNAL_REF_IGNORE, string $baseDir = ""): bool|\PHPePub\Core\Structure\NCX\NavPoint
{
if ($this->isFinalized) {
return false;
}
+
$fileName = RelativePath::getRelativePath($fileName);
$fileName = preg_replace('#^[/\.]+#i', "", $fileName);
+
$navPoint = false;
$chapter = $chapterData;
@@ -244,7 +298,7 @@ public function addChapter($chapterName, $fileName, $chapterData = null, $autoSp
$chapter = StringHelper::encodeHtml($chapter);
}
- $this->chapterCount++;
+ ++$this->chapterCount;
$this->addFile($fileName, "chapter" . $this->chapterCount, $chapter, "application/xhtml+xml");
$this->extractIdAttributes("chapter" . $this->chapterCount, $chapter);
@@ -254,13 +308,13 @@ public function addChapter($chapterName, $fileName, $chapterData = null, $autoSp
$this->ncx->addNavPoint($navPoint);
$this->ncx->chapterList[$chapterName] = $navPoint;
} elseif (is_array($chapter)) {
- $this->log->logLine("addChapter: \$chapterName: $chapterName ; \$fileName: $fileName ; ");
+ $this->log->logLine(sprintf('addChapter: $chapterName: %s ; $fileName: %s ; ', $chapterName, $fileName));
$fileNameParts = pathinfo($fileName);
$extension = $fileNameParts['extension'];
$name = $fileNameParts['filename'];
$partCount = 0;
- $this->chapterCount++;
+ ++$this->chapterCount;
foreach ($chapter as $oneChapter) {
if ($this->encodeHTML === true) {
@@ -270,13 +324,15 @@ public function addChapter($chapterName, $fileName, $chapterData = null, $autoSp
if ($externalReferences !== EPub::EXTERNAL_REF_IGNORE) {
$this->processChapterExternalReferences($oneChapter, $externalReferences, $baseDir);
}
- $partCount++;
+
+ ++$partCount;
$partName = $name . "_" . $partCount;
$this->addFile($partName . "." . $extension, $partName, $oneChapter, "application/xhtml+xml");
$this->extractIdAttributes($partName, $oneChapter);
$this->opf->addItemRef($partName);
}
+
$partName = $name . "_1." . $extension;
$navPoint = new NavPoint(StringHelper::decodeHtmlEntities($chapterName), $partName, $partName);
@@ -284,7 +340,7 @@ public function addChapter($chapterName, $fileName, $chapterData = null, $autoSp
$this->ncx->chapterList[$chapterName] = $navPoint;
} elseif (!isset($chapterData) && strpos($fileName, "#") > 0) {
- $this->chapterCount++;
+ ++$this->chapterCount;
//$this->opf->addItemRef("chapter" . $this->chapterCount);
$id = preg_split("/[#]/", $fileName);
@@ -312,7 +368,7 @@ public function addChapter($chapterName, $fileName, $chapterData = null, $autoSp
$this->ncx->addNavPoint($navPoint);
$this->ncx->chapterList[$chapterName] = $navPoint;
} elseif (!isset($chapterData) && $fileName == "TOC.xhtml") {
- $this->chapterCount++;
+ ++$this->chapterCount;
$this->opf->addItemRef("toc");
$navPoint = new NavPoint(StringHelper::decodeHtmlEntities($chapterName), $fileName, "chapter" . $this->chapterCount);
@@ -328,9 +384,8 @@ public function addChapter($chapterName, $fileName, $chapterData = null, $autoSp
* find all id attributes in the html document.
*
* @param string $chapterData
- * @return array
*/
- public function findIdAttributes($chapterData)
+ public function findIdAttributes($chapterData): array
{
switch ($this->htmlFormat) {
case EPub::FORMAT_HTML5:
@@ -359,7 +414,7 @@ public function findIdAttributes($chapterData)
* @param string $partName
* @param string $chapterData
*/
- public function extractIdAttributes($partName, $chapterData)
+ public function extractIdAttributes($partName, $chapterData): void
{
$item = $this->opf->getItemById($partName);
$ids = $this->findIdAttributes($chapterData);
@@ -392,7 +447,7 @@ public function extractIdAttributes($partName, $chapterData)
*
* @return bool false if unsuccessful (book is finalized or $externalReferences == EXTERNAL_REF_IGNORE).
*/
- protected function processChapterExternalReferences(mixed &$doc, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $htmlDir = "")
+ protected function processChapterExternalReferences(mixed &$doc, $externalReferences = EPub::EXTERNAL_REF_ADD, string $baseDir = "", $htmlDir = ""): bool
{
if ($this->isFinalized || $externalReferences === EPub::EXTERNAL_REF_IGNORE) {
return false;
@@ -433,12 +488,12 @@ protected function processChapterExternalReferences(mixed &$doc, $externalRefere
$bodyNode = $xmlDoc->getElementsByTagName("body");
$htmlNS = "";
- for ($index = 0; $index < $htmlNode->item(0)->attributes->length; $index++) {
+ for ($index = 0; $index < $htmlNode->item(0)->attributes->length; ++$index) {
$nodeName = $htmlNode->item(0)->attributes->item($index)->nodeName;
$nodeValue = $htmlNode->item(0)->attributes->item($index)->nodeValue;
if ($nodeName != "xmlns") {
- $htmlNS .= " $nodeName=\"$nodeValue\"";
+ $htmlNS .= sprintf(' %s="%s"', $nodeName, $nodeValue);
}
}
@@ -451,7 +506,7 @@ protected function processChapterExternalReferences(mixed &$doc, $externalRefere
$xml2Doc->lookupPrefix("http://www.w3.org/1999/xhtml");
$xml2Doc->loadXML("\n\n"
- . "\n\n");
+ . '\n\n");
$html = $xml2Doc->getElementsByTagName("html")->item(0);
$html->appendChild($xml2Doc->importNode($headNode->item(0), true));
$html->appendChild($xml2Doc->importNode($bodyNode->item(0), true));
@@ -478,15 +533,16 @@ protected function processChapterExternalReferences(mixed &$doc, $externalRefere
*
* @return bool FALSE if uncuccessful (book is finalized or $externalReferences == EXTERNAL_REF_IGNORE).
*/
- protected function processChapterStyles(&$xmlDoc, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $htmlDir = "")
+ protected function processChapterStyles(&$xmlDoc, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $htmlDir = ""): bool
{
if ($this->isFinalized || $externalReferences === EPub::EXTERNAL_REF_IGNORE) {
return false;
}
+
// process inlined CSS styles in style tags.
$styles = $xmlDoc->getElementsByTagName("style");
$styleCount = $styles->length;
- for ($styleIdx = 0; $styleIdx < $styleCount; $styleIdx++) {
+ for ($styleIdx = 0; $styleIdx < $styleCount; ++$styleIdx) {
$style = $styles->item($styleIdx);
$styleData = preg_replace('#[/\*\s]*\<\!\[CDATA\[[\s\*/]*#im', "", $style->nodeValue);
@@ -511,7 +567,7 @@ protected function processChapterStyles(&$xmlDoc, $externalReferences = EPub::EX
*
* @return bool FALSE if unsuccessful (book is finalized or $externalReferences == EXTERNAL_REF_IGNORE).
*/
- protected function processCSSExternalReferences(&$cssFile, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $cssDir = "")
+ protected function processCSSExternalReferences(&$cssFile, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $cssDir = ""): bool
{
if ($this->isFinalized || $externalReferences === EPub::EXTERNAL_REF_IGNORE) {
return false;
@@ -522,7 +578,7 @@ protected function processCSSExternalReferences(&$cssFile, $externalReferences =
preg_match_all('#url\s*\([\'\"\s]*(.+?)[\'\"\s]*\)#im', $cssFile, $imgs, PREG_SET_ORDER);
$itemCount = count($imgs);
- for ($idx = 0; $idx < $itemCount; $idx++) {
+ for ($idx = 0; $idx < $itemCount; ++$idx) {
$img = $imgs[$idx];
if ($externalReferences === EPub::EXTERNAL_REF_REMOVE_IMAGES || $externalReferences === EPub::EXTERNAL_REF_REPLACE_IMAGES) {
$cssFile = str_replace($img[0], "", $cssFile);
@@ -554,52 +610,50 @@ protected function processCSSExternalReferences(&$cssFile, $externalReferences =
* @param string &$isSourceExternal (referenced) Return value, will be set to TRUE if the image originated from a full URL.
* @param string $baseDir Default is "", meaning it is pointing to the document root.
* @param string $htmlDir The path to the parent HTML file's directory from the root of the archive.
- *
- * @return bool
*/
- protected function resolveImage($source, &$internalPath, &$internalSrc, &$isSourceExternal, $baseDir = "", $htmlDir = "")
+ protected function resolveImage(string $source, &$internalPath, &$internalSrc, &$isSourceExternal, string $baseDir = "", string $htmlDir = ""): bool
{
if ($this->isFinalized) {
return false;
}
+
$imageData = null;
if (preg_match('#^(http|ftp)s?://#i', $source) == 1) {
$urlinfo = parse_url($source);
-
if (str_contains($urlinfo['path'], $baseDir . "/")) {
$internalSrc = FileHelper::sanitizeFileName(urldecode(substr($urlinfo['path'], strpos($urlinfo['path'], $baseDir . "/") + strlen($baseDir) + 1)));
}
+
$internalPath = $urlinfo["scheme"] . "/" . $urlinfo["host"] . "/" . pathinfo($urlinfo["path"], PATHINFO_DIRNAME);
$isSourceExternal = true;
$imageData = ImageHelper::getImage($this, $source);
- } else {
- if (str_starts_with($source, "/")) {
- $internalPath = pathinfo($source, PATHINFO_DIRNAME);
-
- $path = $source;
- if (!file_exists($path)) {
- $path = $this->docRoot . $path;
- }
-
- $imageData = ImageHelper::getImage($this, $path);
- } else {
- $internalPath = $htmlDir . "/" . preg_replace('#^[/\.]+#', '', pathinfo($source, PATHINFO_DIRNAME));
+ } elseif (str_starts_with($source, "/")) {
+ $internalPath = pathinfo($source, PATHINFO_DIRNAME);
+ $path = $source;
+ if (!file_exists($path)) {
+ $path = $this->docRoot . $path;
+ }
- $path = $baseDir . "/" . $source;
- if (!file_exists($path)) {
- $path = $this->docRoot . $path;
- }
+ $imageData = ImageHelper::getImage($this, $path);
+ } else {
+ $internalPath = $htmlDir . "/" . preg_replace('#^[/\.]+#', '', pathinfo($source, PATHINFO_DIRNAME));
- $imageData = ImageHelper::getImage($this, $path);
+ $path = $baseDir . "/" . $source;
+ if (!file_exists($path)) {
+ $path = $this->docRoot . $path;
}
+
+ $imageData = ImageHelper::getImage($this, $path);
}
+
if ($imageData !== false) {
$iSrcInfo = pathinfo((string) $internalSrc);
if (!empty($imageData['ext']) && (!isset($iSrcInfo['extension']) || $imageData['ext'] != $iSrcInfo['extension'])) {
$internalSrc = $iSrcInfo['filename'] . "." . $imageData['ext'];
}
+
$internalPath = RelativePath::getRelativePath("images/" . $internalPath . "/" . $internalSrc);
if (!array_key_exists($internalPath, $this->fileList)) {
$this->addFile($internalPath, "i_" . $internalSrc, $imageData['image'], $imageData['mime']);
@@ -621,14 +675,16 @@ protected function resolveImage($source, &$internalPath, &$internalSrc, &$isSour
*
* @return bool $success
*/
- public function addFileToMETAINF($fileName, $fileData)
+ public function addFileToMETAINF($fileName, $fileData): bool
{
if ($this->isFinalized) {
return false;
}
+
if (!$this->isInitialized) {
$this->initialize();
}
+
$fileName = FileHelper::normalizeFileName($fileName);
$this->zip->addFile($fileData, "META-INF/" . $fileName);
@@ -646,14 +702,16 @@ public function addFileToMETAINF($fileName, $fileData)
*
* @return bool $success
*/
- public function addFile($fileName, $fileId, $fileData, $mimetype)
+ public function addFile($fileName, $fileId, $fileData, $mimetype): bool
{
if ($this->isFinalized || array_key_exists($fileName, $this->fileList)) {
return false;
}
+
if (!$this->isInitialized) {
$this->initialize();
}
+
$fileName = FileHelper::normalizeFileName($fileName);
$compress = (!str_starts_with($mimetype, "image/"));
@@ -677,15 +735,16 @@ public function addFile($fileName, $fileId, $fileData, $mimetype)
*
* @return bool FALSE if uncuccessful (book is finalized or $externalReferences == EXTERNAL_REF_IGNORE).
*/
- protected function processChapterLinks(&$xmlDoc, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $htmlDir = "", $backPath = "")
+ protected function processChapterLinks(&$xmlDoc, $externalReferences = EPub::EXTERNAL_REF_ADD, string $baseDir = "", $htmlDir = "", string $backPath = ""): bool
{
if ($this->isFinalized || $externalReferences === EPub::EXTERNAL_REF_IGNORE) {
return false;
}
+
// process link tags.
$links = $xmlDoc->getElementsByTagName("link");
$linkCount = $links->length;
- for ($linkIdx = 0; $linkIdx < $linkCount; $linkIdx++) {
+ for ($linkIdx = 0; $linkIdx < $linkCount; ++$linkIdx) {
/** @var $link \DOMElement */
$link = $links->item($linkIdx);
$source = $link->attributes->getNamedItem("href")->nodeValue;
@@ -696,18 +755,15 @@ protected function processChapterLinks(&$xmlDoc, $externalReferences = EPub::EXT
if (preg_match('#^(http|ftp)s?://#i', $source) == 1) {
$urlinfo = parse_url($source);
-
if (str_contains($urlinfo['path'], $baseDir . "/")) {
$internalSrc = substr($urlinfo['path'], strpos($urlinfo['path'], $baseDir . "/") + strlen($baseDir) + 1);
}
@$sourceData = FileHelper::getFileContents($source);
+ } elseif (str_starts_with($source, "/")) {
+ @$sourceData = file_get_contents($this->docRoot . $source);
} else {
- if (str_starts_with($source, "/")) {
- @$sourceData = file_get_contents($this->docRoot . $source);
- } else {
- @$sourceData = file_get_contents($this->docRoot . $baseDir . "/" . $source);
- }
+ @$sourceData = file_get_contents($this->docRoot . $baseDir . "/" . $source);
}
if (!empty($sourceData)) {
@@ -716,6 +772,7 @@ protected function processChapterLinks(&$xmlDoc, $externalReferences = EPub::EXT
if (empty($mime)) {
$mime = "text/plain";
}
+
if ($mime == "text/css") {
$this->processCSSExternalReferences($sourceData, $externalReferences, $baseDir, $htmlDir);
$this->addCSSFile($internalSrc, $internalSrc, $sourceData, EPub::EXTERNAL_REF_IGNORE, $baseDir);
@@ -723,6 +780,7 @@ protected function processChapterLinks(&$xmlDoc, $externalReferences = EPub::EXT
} else {
$this->addFile($internalSrc, $internalSrc, $sourceData, $mime);
}
+
$this->fileList[$internalSrc] = $source;
} else {
$link->setAttribute("href", $backPath . $internalSrc);
@@ -744,11 +802,12 @@ protected function processChapterLinks(&$xmlDoc, $externalReferences = EPub::EXT
*
* @return bool $success
*/
- public function addCSSFile($fileName, $fileId, $fileData, $externalReferences = EPub::EXTERNAL_REF_IGNORE, $baseDir = "")
+ public function addCSSFile($fileName, string $fileId, $fileData, $externalReferences = EPub::EXTERNAL_REF_IGNORE, $baseDir = ""): bool
{
if ($this->isFinalized || array_key_exists($fileName, $this->fileList)) {
return false;
}
+
$fileName = RelativePath::getRelativePath($fileName);
$fileName = preg_replace('#^[/\.]+#i', "", $fileName);
@@ -779,46 +838,45 @@ public function addCSSFile($fileName, $fileId, $fileData, $externalReferences =
*
* @return bool FALSE if uncuccessful (book is finalized or $externalReferences == EXTERNAL_REF_IGNORE).
*/
- protected function processChapterImages(&$xmlDoc, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $htmlDir = "", $backPath = "")
+ protected function processChapterImages(&$xmlDoc, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $htmlDir = "", string $backPath = ""): bool
{
if ($this->isFinalized || $externalReferences === EPub::EXTERNAL_REF_IGNORE) {
return false;
}
+
// process img tags.
$postProcDomElememts = [];
$images = $xmlDoc->getElementsByTagName("img");
$itemCount = $images->length;
- for ($idx = 0; $idx < $itemCount; $idx++) {
+ for ($idx = 0; $idx < $itemCount; ++$idx) {
/** @var $img \DOMElement */
$img = $images->item($idx);
if ($externalReferences === EPub::EXTERNAL_REF_REMOVE_IMAGES) {
$postProcDomElememts[] = $img;
+ } elseif ($externalReferences === EPub::EXTERNAL_REF_REPLACE_IMAGES) {
+ $altNode = $img->attributes->getNamedItem("alt");
+ $alt = "image";
+ if ($altNode !== null && strlen($altNode->nodeValue) > 0) {
+ $alt = $altNode->nodeValue;
+ }
+
+ $postProcDomElememts[] = [$img, StringHelper::createDomFragment($xmlDoc, "[" . $alt . "]")];
} else {
- if ($externalReferences === EPub::EXTERNAL_REF_REPLACE_IMAGES) {
- $altNode = $img->attributes->getNamedItem("alt");
- $alt = "image";
- if ($altNode !== null && strlen($altNode->nodeValue) > 0) {
- $alt = $altNode->nodeValue;
- }
- $postProcDomElememts[] = [$img, StringHelper::createDomFragment($xmlDoc, "[" . $alt . "]")];
- } else {
- $source = $img->attributes->getNamedItem("src")->nodeValue;
+ $source = $img->attributes->getNamedItem("src")->nodeValue;
- $parsedSource = parse_url($source);
- $internalSrc = FileHelper::sanitizeFileName(urldecode(pathinfo($parsedSource['path'], PATHINFO_BASENAME)));
- $internalPath = "";
- $isSourceExternal = false;
+ $parsedSource = parse_url($source);
+ $internalSrc = FileHelper::sanitizeFileName(urldecode(pathinfo($parsedSource['path'], PATHINFO_BASENAME)));
+ $internalPath = "";
+ $isSourceExternal = false;
- if ($this->resolveImage($source, $internalPath, $internalSrc, $isSourceExternal, $baseDir, $htmlDir)) {
- $img->setAttribute("src", $backPath . $internalPath);
- } else {
- if ($isSourceExternal) {
- $postProcDomElememts[] = $img; // External image is missing
- }
- } // else do nothing, if the image is local, and missing, assume it's been generated.
- }
+ if ($this->resolveImage($source, $internalPath, $internalSrc, $isSourceExternal, $baseDir, $htmlDir)) {
+ $img->setAttribute("src", $backPath . $internalPath);
+ } elseif ($isSourceExternal) {
+ $postProcDomElememts[] = $img;
+ // External image is missing
+ } // else do nothing, if the image is local, and missing, assume it's been generated.
}
}
@@ -845,7 +903,7 @@ protected function processChapterImages(&$xmlDoc, $externalReferences = EPub::EX
*
* @return bool FALSE if uncuccessful (book is finalized or $externalReferences == EXTERNAL_REF_IGNORE).
*/
- protected function processChapterSources(&$xmlDoc, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $htmlDir = "", $backPath = "")
+ protected function processChapterSources(&$xmlDoc, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $htmlDir = "", string $backPath = ""): bool
{
if ($this->isFinalized || $externalReferences === EPub::EXTERNAL_REF_IGNORE) {
return false;
@@ -859,35 +917,33 @@ protected function processChapterSources(&$xmlDoc, $externalReferences = EPub::E
$postProcDomElememts = [];
$images = $xmlDoc->getElementsByTagName("source");
$itemCount = $images->length;
- for ($idx = 0; $idx < $itemCount; $idx++) {
+ for ($idx = 0; $idx < $itemCount; ++$idx) {
/** @var $img \DOMElement */
$img = $images->item($idx);
if ($externalReferences === EPub::EXTERNAL_REF_REMOVE_IMAGES) {
$postProcDomElememts[] = $img;
+ } elseif ($externalReferences === EPub::EXTERNAL_REF_REPLACE_IMAGES) {
+ $altNode = $img->attributes->getNamedItem("alt");
+ $alt = "image";
+ if ($altNode !== null && strlen($altNode->nodeValue) > 0) {
+ $alt = $altNode->nodeValue;
+ }
+
+ $postProcDomElememts[] = [$img, StringHelper::createDomFragment($xmlDoc, "[" . $alt . "]")];
} else {
- if ($externalReferences === EPub::EXTERNAL_REF_REPLACE_IMAGES) {
- $altNode = $img->attributes->getNamedItem("alt");
- $alt = "image";
- if ($altNode !== null && strlen($altNode->nodeValue) > 0) {
- $alt = $altNode->nodeValue;
- }
- $postProcDomElememts[] = [$img, StringHelper::createDomFragment($xmlDoc, "[" . $alt . "]")];
- } else {
- $source = $img->attributes->getNamedItem("src")->nodeValue;
+ $source = $img->attributes->getNamedItem("src")->nodeValue;
- $parsedSource = parse_url($source);
- $internalSrc = FileHelper::sanitizeFileName(urldecode(pathinfo($parsedSource['path'], PATHINFO_BASENAME)));
- $internalPath = "";
- $isSourceExternal = false;
+ $parsedSource = parse_url($source);
+ $internalSrc = FileHelper::sanitizeFileName(urldecode(pathinfo($parsedSource['path'], PATHINFO_BASENAME)));
+ $internalPath = "";
+ $isSourceExternal = false;
- if ($this->resolveMedia($source, $internalPath, $internalSrc, $isSourceExternal, $baseDir, $htmlDir)) {
- $img->setAttribute("src", $backPath . $internalPath);
- } else {
- if ($isSourceExternal) {
- $postProcDomElememts[] = $img; // External image is missing
- }
- } // else do nothing, if the image is local, and missing, assume it's been generated.
- }
+ if ($this->resolveMedia($source, $internalPath, $internalSrc, $isSourceExternal, $baseDir, $htmlDir)) {
+ $img->setAttribute("src", $backPath . $internalPath);
+ } elseif ($isSourceExternal) {
+ $postProcDomElememts[] = $img;
+ // External image is missing
+ } // else do nothing, if the image is local, and missing, assume it's been generated.
}
}
@@ -903,42 +959,38 @@ protected function processChapterSources(&$xmlDoc, $externalReferences = EPub::E
* @param string $isSourceExternal (referenced) Return value, will be set to TRUE if the image originated from a full URL.
* @param string $baseDir Default is "", meaning it is pointing to the document root.
* @param string $htmlDir The path to the parent HTML file's directory from the root of the archive.
- *
- * @return bool
*/
- protected function resolveMedia($source, &$internalPath, &$internalSrc, &$isSourceExternal, $baseDir = "", $htmlDir = "")
+ protected function resolveMedia(string $source, &$internalPath, &$internalSrc, &$isSourceExternal, string $baseDir = "", string $htmlDir = ""): bool
{
if ($this->isFinalized) {
return false;
}
+
$mediaPath = null;
$tmpFile = null;
if (preg_match('#^(http|ftp)s?://#i', $source) == 1) {
$urlInfo = parse_url($source);
-
if (str_contains($urlInfo['path'], $baseDir . "/")) {
$internalSrc = substr($urlInfo['path'], strpos($urlInfo['path'], $baseDir . "/") + strlen($baseDir) + 1);
}
+
$internalPath = $urlInfo["scheme"] . "/" . $urlInfo["host"] . "/" . pathinfo($urlInfo["path"], PATHINFO_DIRNAME);
$isSourceExternal = true;
$mediaPath = FileHelper::getFileContents($source, true);
$tmpFile = $mediaPath;
+ } elseif (str_starts_with($source, "/")) {
+ $internalPath = pathinfo($source, PATHINFO_DIRNAME);
+ $mediaPath = $source;
+ if (!file_exists($mediaPath)) {
+ $mediaPath = $this->docRoot . $mediaPath;
+ }
} else {
- if (str_starts_with($source, "/")) {
- $internalPath = pathinfo($source, PATHINFO_DIRNAME);
-
- $mediaPath = $source;
- if (!file_exists($mediaPath)) {
- $mediaPath = $this->docRoot . $mediaPath;
- }
- } else {
- $internalPath = $htmlDir . "/" . preg_replace('#^[/\.]+#', '', pathinfo($source, PATHINFO_DIRNAME));
+ $internalPath = $htmlDir . "/" . preg_replace('#^[/\.]+#', '', pathinfo($source, PATHINFO_DIRNAME));
- $mediaPath = $baseDir . "/" . $source;
- if (!file_exists($mediaPath)) {
- $mediaPath = $this->docRoot . $mediaPath;
- }
+ $mediaPath = $baseDir . "/" . $source;
+ if (!file_exists($mediaPath)) {
+ $mediaPath = $this->docRoot . $mediaPath;
}
}
@@ -951,6 +1003,7 @@ protected function resolveMedia($source, &$internalPath, &$internalSrc, &$isSour
) {
$this->fileList[$internalPath] = $source;
}
+
if (isset($tmpFile)) {
unlink($tmpFile);
}
@@ -971,14 +1024,16 @@ protected function resolveMedia($source, &$internalPath, &$internalSrc, &$isSour
*
* @return bool $success
*/
- public function addLargeFile($fileName, $fileId, $filePath, $mimetype)
+ public function addLargeFile($fileName, $fileId, $filePath, $mimetype): bool
{
if ($this->isFinalized || array_key_exists($fileName, $this->fileList)) {
return false;
}
+
if (!$this->isInitialized) {
$this->initialize();
}
+
$fileName = FileHelper::normalizeFileName($fileName);
if ($this->zip->addLargeFile($filePath, $this->bookRoot . $fileName)) {
@@ -994,12 +1049,13 @@ public function addLargeFile($fileName, $fileId, $filePath, $mimetype)
/**
* initialize defaults.
*/
- private function initialize()
+ private function initialize(): void
{
if ($this->isInitialized) {
return;
}
- if (strlen((string) $this->bookRoot) != 0 && $this->bookRoot != 'OEBPS/') {
+
+ if (strlen($this->bookRoot) != 0 && $this->bookRoot != 'OEBPS/') {
$this->setBookRoot($this->bookRoot);
}
@@ -1032,26 +1088,23 @@ private function initialize()
*
* @param string $bookRoot
*/
- public function setBookRoot($bookRoot)
+ public function setBookRoot($bookRoot): void
{
if ($this->isInitialized) {
die("bookRoot can't be set after book initialization (first file added).");
}
+
$bookRoot = trim($bookRoot);
if (strlen($bookRoot) <= 1 || $bookRoot == '/') {
$bookRoot = '';
- } else {
- if (!BinStringStatic::endsWith($bookRoot, '/')) {
- $bookRoot .= '/';
- }
+ } elseif (!str_ends_with($bookRoot, '/')) {
+ $bookRoot .= '/';
}
+
$this->bookRoot = $bookRoot;
}
- /**
- * @return bool
- */
- public function isEPubVersion2()
+ public function isEPubVersion2(): bool
{
return $this->bookVersion === EPub::BOOK_VERSION_EPUB2;
}
@@ -1069,7 +1122,7 @@ public function isEPubVersion2()
*
* @return bool|NavPoint The new NavPoint for that level.
*/
- public function subLevel($navTitle = null, $navId = null, $navClass = null, $isNavHidden = false, $writingDirection = null)
+ public function subLevel($navTitle = null, $navId = null, $navClass = null, $isNavHidden = false, $writingDirection = null): \PHPePub\Core\Structure\NCX\NavPoint|bool
{
return $this->ncx->subLevel(StringHelper::decodeHtmlEntities($navTitle), $navId, $navClass, $isNavHidden, $writingDirection);
}
@@ -1079,7 +1132,7 @@ public function subLevel($navTitle = null, $navId = null, $navClass = null, $isN
*
* Subsequent chapters will be added to this chapters parent level.
*/
- public function backLevel()
+ public function backLevel(): void
{
$this->ncx->backLevel();
}
@@ -1089,7 +1142,7 @@ public function backLevel()
*
* Subsequent chapters will be added to the rooot NavMap.
*/
- public function rootLevel()
+ public function rootLevel(): void
{
$this->ncx->rootLevel();
}
@@ -1101,7 +1154,7 @@ public function rootLevel()
*
* @param int $newLevel
*/
- public function setCurrentLevel($newLevel)
+ public function setCurrentLevel($newLevel): void
{
$this->ncx->setCurrentLevel($newLevel);
}
@@ -1121,7 +1174,7 @@ public function getCurrentLevel()
* @param string $nsName
* @param string $nsURI
*/
- public function addCustomNamespace($nsName, $nsURI)
+ public function addCustomNamespace($nsName, $nsURI): void
{
if ($this->isFinalized) {
return;
@@ -1138,7 +1191,7 @@ public function addCustomNamespace($nsName, $nsURI)
* @param string $name
* @param string $URI
*/
- public function addCustomPrefix($name, $URI)
+ public function addCustomPrefix($name, $URI): void
{
if ($this->isFinalized) {
return;
@@ -1157,7 +1210,7 @@ public function addCustomPrefix($name, $URI)
*
* @param MetaValue $value
*/
- public function addCustomMetaValue($value)
+ public function addCustomMetaValue($value): void
{
if ($this->isFinalized) {
return;
@@ -1177,7 +1230,7 @@ public function addCustomMetaValue($value)
* @param string $name property name, including the namespace declaration, ie. "dcterms:modified"
* @param string $content
*/
- public function addCustomMetaProperty($name, $content)
+ public function addCustomMetaProperty($name, $content): void
{
if ($this->isFinalized) {
return;
@@ -1185,6 +1238,7 @@ public function addCustomMetaProperty($name, $content)
$this->opf->addMetaProperty($name, $content);
}
+
/**
* Add custom metadata to the book.
*
@@ -1193,7 +1247,7 @@ public function addCustomMetaProperty($name, $content)
* @param string $name
* @param string $content
*/
- public function addCustomMetadata($name, $content)
+ public function addCustomMetadata($name, $content): void
{
if ($this->isFinalized) {
return;
@@ -1210,7 +1264,7 @@ public function addCustomMetadata($name, $content)
* @param string $dublinCoreConstant name
* @param string $value
*/
- public function addDublinCoreMetadata($dublinCoreConstant, $value)
+ public function addDublinCoreMetadata($dublinCoreConstant, $value): void
{
if ($this->isFinalized) {
return;
@@ -1231,7 +1285,7 @@ public function addDublinCoreMetadata($dublinCoreConstant, $value)
*
* @return bool $success
*/
- public function setCoverImage($fileName, $imageData = null, $mimetype = null)
+ public function setCoverImage($fileName, $imageData = null, $mimetype = null): bool
{
if ($this->isFinalized || $this->isCoverImageSet || array_key_exists("CoverPage.xhtml", $this->fileList)) {
return false;
@@ -1248,10 +1302,12 @@ public function setCoverImage($fileName, $imageData = null, $mimetype = null)
$fileName = $rp;
}
}
+
$image = ImageHelper::getImage($this, $fileName);
if (false === $image) {
return false;
}
+
$imageData = $image['image'];
$mimetype = $image['mime'];
$fileName = preg_replace('#\.[^\.]+$#', "." . $image['ext'], $fileName);
@@ -1265,17 +1321,20 @@ public function setCoverImage($fileName, $imageData = null, $mimetype = null)
[$width, $height, $type, $attr] = getimagesize($fileName);
$mimetype = image_type_to_mime_type($type);
}
+
if (empty($mimetype)) {
$ext = strtolower($path['extension']);
if ($ext == "jpg") {
$ext = "jpeg";
}
+
$mimetype = "image/" . $ext;
}
if ($this->isEPubVersion2()) {
- $coverPage = "\n"
- . "
+\n"
. "\n"
. "\t\n"
@@ -1305,12 +1364,16 @@ public function setCoverImage($fileName, $imageData = null, $mimetype = null)
. "\t\n"
. "\n";
}
- $coverPageCss = "@page, body, div, img {\n"
- . "\tpadding: 0pt;\n"
- . "\tmargin:0pt;\n"
- . "}\n\nbody {\n"
- . "\ttext-align: center;\n"
- . "}\n";
+
+ $coverPageCss = '@page, body, div, img {
+ padding: 0pt;
+ margin:0pt;
+}
+
+body {
+ text-align: center;
+}
+';
$this->addCSSFile("Styles/CoverPage.css", "CoverPageCss", $coverPageCss);
$this->addFile($imgPath, "CoverImage", $imageData, $mimetype);
@@ -1335,11 +1398,12 @@ public function setCoverImage($fileName, $imageData = null, $mimetype = null)
*
* @return bool $success
*/
- public function addReferencePage($pageName, $fileName, $pageData, $reference, $externalReferences = EPub::EXTERNAL_REF_IGNORE, $baseDir = "")
+ public function addReferencePage($pageName, $fileName, $pageData, string $reference, $externalReferences = EPub::EXTERNAL_REF_IGNORE, string $baseDir = ""): bool
{
if ($this->isFinalized) {
return false;
}
+
$fileName = RelativePath::getRelativePath($fileName);
$fileName = preg_replace('#^[/\.]+#i', "", $fileName);
@@ -1380,7 +1444,7 @@ public function addReferencePage($pageName, $fileName, $pageData, $reference, $e
*
* @return string $content
*/
- private function wrapChapter($content)
+ private function wrapChapter(string $content): string
{
return $this->htmlContentHeader . "\n" . $content . "\n" . $this->htmlContentFooter;
}
@@ -1391,7 +1455,7 @@ private function wrapChapter($content)
* @access public
* @return number of chapters
*/
- public function getChapterCount()
+ public function getChapterCount(): int
{
return $this->chapterCount;
}
@@ -1402,7 +1466,7 @@ public function getChapterCount()
* @access public
* @return string $title
*/
- public function getTitle()
+ public function getTitle(): string
{
return $this->title;
}
@@ -1412,16 +1476,16 @@ public function getTitle()
*
* Used for the dc:title metadata parameter in the OPF file as well as the DocTitle attribute in the NCX file.
*
- * @param string $title
*
* @access public
* @return bool $success
*/
- public function setTitle($title)
+ public function setTitle(string $title): bool
{
if ($this->isFinalized) {
return false;
}
+
$this->title = $title;
return true;
@@ -1433,7 +1497,7 @@ public function setTitle($title)
* @access public
* @return string $language
*/
- public function getLanguage()
+ public function getLanguage(): string
{
return $this->language;
}
@@ -1451,11 +1515,12 @@ public function getLanguage()
* @access public
* @return bool $success
*/
- public function setLanguage($language)
+ public function setLanguage($language): bool
{
- if ($this->isFinalized || 0 === preg_match('/^((?([A-Za-z]{2,3}(-(?[A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-(?[A-Za-z]{2}|[0-9]{3}))?)$/', $language)) {
+ if ($this->isFinalized || 0 === preg_match('/^((?([A-Za-z]{2,3}(-(?[A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-(?[A-Za-z]{2}|\d{3}))?)$/', $language)) {
return false;
}
+
$this->language = $language;
return true;
@@ -1467,7 +1532,7 @@ public function setLanguage($language)
* @access public
* @return string $identifier
*/
- public function getIdentifier()
+ public function getIdentifier(): string
{
return $this->identifier;
}
@@ -1489,17 +1554,17 @@ public function getIdentifier()
* EPub::IDENTIFIER_ISBN
* EPub::IDENTIFIER_UUID
*
- * @param string $identifier
* @param string $identifierType
*
* @access public
* @return bool $success
*/
- public function setIdentifier($identifier, $identifierType)
+ public function setIdentifier(string $identifier, $identifierType): bool
{
if ($this->isFinalized || ($identifierType !== EPub::IDENTIFIER_URI && $identifierType !== EPub::IDENTIFIER_ISBN && $identifierType !== EPub::IDENTIFIER_UUID)) {
return false;
}
+
$this->identifier = $identifier;
$this->identifierType = $identifierType;
@@ -1512,7 +1577,7 @@ public function setIdentifier($identifier, $identifierType)
* @access public
* @return string $identifierType
*/
- public function getIdentifierType()
+ public function getIdentifierType(): string
{
return $this->identifierType;
}
@@ -1523,7 +1588,7 @@ public function getIdentifierType()
* @access public
* @return string $description
*/
- public function getDescription()
+ public function getDescription(): string
{
return $this->description;
}
@@ -1539,16 +1604,16 @@ public function getDescription()
*
* Used for the dc:source metadata parameter in the OPF file
*
- * @param string $description
*
* @access public
* @return bool $success
*/
- public function setDescription($description)
+ public function setDescription(string $description): bool
{
if ($this->isFinalized) {
return false;
}
+
$this->description = $description;
return true;
@@ -1560,7 +1625,7 @@ public function setDescription($description)
* @access public
* @return string $author
*/
- public function getAuthor()
+ public function getAuthor(): string
{
return $this->author;
}
@@ -1580,17 +1645,16 @@ public function getAuthor()
* docAuthor attribure in the NCX file.
* The sort key is used for the opf:file-as attribute in dc:creator.
*
- * @param string $author
- * @param string $authorSortKey
*
* @access public
* @return bool $success
*/
- public function setAuthor($author, $authorSortKey)
+ public function setAuthor(string $author, string $authorSortKey): bool
{
if ($this->isFinalized) {
return false;
}
+
$this->author = $author;
$this->authorSortKey = $authorSortKey;
@@ -1607,17 +1671,16 @@ public function setAuthor($author, $authorSortKey)
*
* Used for the dc:publisher and dc:relation metadata parameters in the OPF file.
*
- * @param string $publisherName
- * @param string $publisherURL
*
* @access public
* @return bool $success
*/
- public function setPublisher($publisherName, $publisherURL)
+ public function setPublisher(string $publisherName, string $publisherURL): bool
{
if ($this->isFinalized) {
return false;
}
+
$this->publisherName = $publisherName;
$this->publisherURL = $publisherURL;
@@ -1630,7 +1693,7 @@ public function setPublisher($publisherName, $publisherURL)
* @access public
* @return string $publisherName
*/
- public function getPublisherName()
+ public function getPublisherName(): string
{
return $this->publisherName;
}
@@ -1641,7 +1704,7 @@ public function getPublisherName()
* @access public
* @return string $publisherURL
*/
- public function getPublisherURL()
+ public function getPublisherURL(): string
{
return $this->publisherURL;
}
@@ -1652,7 +1715,7 @@ public function getPublisherURL()
* @access public
* @return string $date
*/
- public function getDate()
+ public function getDate(): int
{
return $this->date;
}
@@ -1670,16 +1733,16 @@ public function getDate()
*
* Used for the dc:date metadata parameter in the OPF file
*
- * @param int $timestamp
*
* @access public
* @return bool $success
*/
- public function setDate($timestamp)
+ public function setDate(int $timestamp): bool
{
if ($this->isFinalized) {
return false;
}
+
$this->date = $timestamp;
$this->opf->date = $timestamp;
@@ -1692,7 +1755,7 @@ public function setDate($timestamp)
* @access public
* @return string $rights
*/
- public function getRights()
+ public function getRights(): string
{
return $this->rights;
}
@@ -1708,16 +1771,16 @@ public function getRights()
*
* Used for the dc:rights metadata parameter in the OPF file
*
- * @param string $rightsText
*
* @access public
* @return bool $success
*/
- public function setRights($rightsText)
+ public function setRights(string $rightsText): bool
{
if ($this->isFinalized) {
return false;
}
+
$this->rights = $rightsText;
return true;
@@ -1735,11 +1798,12 @@ public function setRights($rightsText)
*
* @param string $subject
*/
- public function setSubject($subject)
+ public function setSubject($subject): void
{
if ($this->isFinalized) {
return;
}
+
$this->opf->addDCMeta(DublinCore::SUBJECT, StringHelper::decodeHtmlEntities($subject));
}
@@ -1749,7 +1813,7 @@ public function setSubject($subject)
* @access public
* @return string $sourceURL
*/
- public function getSourceURL()
+ public function getSourceURL(): string
{
return $this->sourceURL;
}
@@ -1765,16 +1829,16 @@ public function getSourceURL()
*
* Used for the dc:source metadata parameter in the OPF file
*
- * @param string $sourceURL
*
* @access public
* @return bool $success
*/
- public function setSourceURL($sourceURL)
+ public function setSourceURL(string $sourceURL): bool
{
if ($this->isFinalized) {
return false;
}
+
$this->sourceURL = $sourceURL;
return true;
@@ -1786,7 +1850,7 @@ public function setSourceURL($sourceURL)
* @access public
* @return string $coverage
*/
- public function getCoverage()
+ public function getCoverage(): string
{
return $this->coverage;
}
@@ -1810,16 +1874,16 @@ public function getCoverage()
*
* Same as ->addDublinCoreMetadata(DublinCore::COVERAGE, $coverage);
*
- * @param string $coverage
*
* @access public
* @return bool $success
*/
- public function setCoverage($coverage)
+ public function setCoverage(string $coverage): bool
{
if ($this->isFinalized) {
return false;
}
+
$this->coverage = $coverage;
return true;
@@ -1830,7 +1894,7 @@ public function setCoverage($coverage)
*
* @return string The relation.
*/
- public function getRelation()
+ public function getRelation(): string
{
return $this->relation;
}
@@ -1842,14 +1906,13 @@ public function getRelation()
*
* Recommended best practice is to identify the related resource by means
* of a string conforming to a formal identification system.
- *
- * @param string $relation
*/
- public function setRelation($relation)
+ public function setRelation(string $relation): void
{
if ($this->isFinalized) {
return;
}
+
$this->relation = $relation;
}
@@ -1858,7 +1921,7 @@ public function setRelation($relation)
*
* @return string The generator identity string.
*/
- public function getGenerator()
+ public function getGenerator(): string
{
return $this->generator;
}
@@ -1868,14 +1931,13 @@ public function getGenerator()
*
* The generator is a meta tag added to the ncx file, it is not visible
* from within the book, but is a kind of electronic watermark.
- *
- * @param string $generator
*/
- public function setGenerator($generator)
+ public function setGenerator(string $generator): void
{
if ($this->isFinalized) {
return;
}
+
$this->generator = $generator;
}
@@ -1889,11 +1951,12 @@ public function setGenerator($generator)
* @access public
* @return bool $success
*/
- public function setShortDateFormat()
+ public function setShortDateFormat(): bool
{
if ($this->isFinalized) {
return false;
}
+
$this->dateformat = $this->dateformatShort;
return true;
@@ -1905,14 +1968,13 @@ public function setShortDateFormat()
* @param string $referencesTitle
* @param string $referencesId
* @param string $referencesClass
- *
- * @return bool
*/
- public function setReferencesTitle($referencesTitle = "Guide", $referencesId = "", $referencesClass = "references")
+ public function setReferencesTitle($referencesTitle = "Guide", $referencesId = "", $referencesClass = "references"): bool
{
if ($this->isFinalized) {
return false;
}
+
$this->ncx->referencesTitle = is_string($referencesTitle) ? trim($referencesTitle) : "Guide";
$this->ncx->referencesId = is_string($referencesId) ? trim($referencesId) : "references";
$this->ncx->referencesClass = is_string($referencesClass) ? trim($referencesClass) : "references";
@@ -1924,14 +1986,13 @@ public function setReferencesTitle($referencesTitle = "Guide", $referencesId = "
* Set the references title for the ePub 3 landmarks section
*
* @param bool $isReferencesAddedToToc
- *
- * @return bool
*/
- public function setisReferencesAddedToToc($isReferencesAddedToToc = true)
+ public function setisReferencesAddedToToc($isReferencesAddedToToc = true): bool
{
if ($this->isFinalized) {
return false;
}
+
$this->isReferencesAddedToToc = $isReferencesAddedToToc === true;
return true;
@@ -1941,9 +2002,8 @@ public function setisReferencesAddedToToc($isReferencesAddedToToc = true)
* Get Book status.
*
* @access public
- * @return bool
*/
- public function isFinalized()
+ public function isFinalized(): bool
{
return $this->isFinalized;
}
@@ -1957,20 +2017,20 @@ public function isFinalized()
* @param bool $addReferences include reference pages in the TOC, using the $referencesOrder array to determine the order of the pages in the TOC. Default is TRUE.
* @param bool $addToIndex Add the TOC to the NCX index at the current leve/position. Default is FALSE
* @param string $tocFileName Change the default name of the TOC file. The default is "TOC.xhtml"
- *
- * @return bool
*/
- public function buildTOC($cssFileName = null, $tocCSSClass = "toc", $title = "Table of Contents", $addReferences = true, $addToIndex = false, $tocFileName = "TOC.xhtml")
+ public function buildTOC($cssFileName = null, $tocCSSClass = "toc", $title = "Table of Contents", bool $addReferences = true, $addToIndex = false, $tocFileName = "TOC.xhtml"): bool
{
if ($this->isFinalized) {
return false;
}
+
$this->buildTOC = true;
$this->tocTitle = $title;
$this->tocFileName = FileHelper::normalizeFileName($tocFileName);
if (!empty($cssFileName)) {
$this->tocCssFileName = FileHelper::normalizeFileName($cssFileName);
}
+
$this->tocCSSClass = $tocCSSClass;
$this->tocAddReferences = $addReferences;
@@ -1986,18 +2046,17 @@ public function buildTOC($cssFileName = null, $tocCSSClass = "toc", $title = "Ta
$this->ncx->referencesName[Reference::TABLE_OF_CONTENTS] = $title;
}
}
+
return true;
}
/**
* Save the ePub file to local disk.
*
- * @param string $fileName
* @param string $baseDir If empty baseDir is absolute to server path, if omitted it's relative to script path
- *
* @return string The sent file name if successful, FALSE if it failed.
*/
- public function saveBook($fileName, $baseDir = '.')
+ public function saveBook(string $fileName, string $baseDir = '.'): string|bool
{
// Make fileName safe
@@ -2008,7 +2067,7 @@ public function saveBook($fileName, $baseDir = '.')
$this->finalize();
}
- if (!BinStringStatic::endsWith($fileName, ".epub")) {
+ if (!str_ends_with($fileName, ".epub")) {
$fileName .= ".epub";
}
@@ -2016,7 +2075,7 @@ public function saveBook($fileName, $baseDir = '.')
$fh = fopen($baseDir . '/' . $fileName, "w");
if ($fh) {
- fputs($fh, $this->getBook());
+ fwrite($fh, $this->getBook());
fclose($fh);
// if file is written return TRUE
@@ -2033,13 +2092,13 @@ public function saveBook($fileName, $baseDir = '.')
*
* @return bool $success
*/
- public function finalize()
+ public function finalize(): bool
{
- if ($this->isFinalized || $this->chapterCount == 0 || empty($this->title) || empty($this->language)) {
+ if ($this->isFinalized || $this->chapterCount == 0 || ($this->title === '' || $this->title === '0') || ($this->language === '' || $this->language === '0')) {
return false;
}
- if (empty($this->identifier) || empty($this->identifierType)) {
+ if ($this->identifier === '' || $this->identifier === '0' || ($this->identifierType === '' || $this->identifierType === '0')) {
$this->setIdentifier(StringHelper::createUUID(4), EPub::IDENTIFIER_UUID);
}
@@ -2047,11 +2106,11 @@ public function finalize()
$this->date = time();
}
- if (empty($this->sourceURL)) {
+ if ($this->sourceURL === '' || $this->sourceURL === '0') {
$this->sourceURL = URLHelper::getCurrentPageURL();
}
- if (empty($this->publisherURL)) {
+ if ($this->publisherURL === '' || $this->publisherURL === '0') {
$this->sourceURL = URLHelper::getCurrentServerURL();
}
@@ -2061,39 +2120,40 @@ public function finalize()
$DCdate = new DublinCore(DublinCore::DATE, gmdate($this->dateformat, $this->date));
$DCdate->addOpfAttr("event", "publication");
+
$this->opf->metadata->addDublinCore($DCdate);
- if (!empty($this->description)) {
+ if ($this->description !== '' && $this->description !== '0') {
$this->opf->addDCMeta(DublinCore::DESCRIPTION, StringHelper::decodeHtmlEntities($this->description));
}
- if (!empty($this->publisherName)) {
+ if ($this->publisherName !== '' && $this->publisherName !== '0') {
$this->opf->addDCMeta(DublinCore::PUBLISHER, StringHelper::decodeHtmlEntities($this->publisherName));
}
- if (!empty($this->publisherURL)) {
+ if ($this->publisherURL !== '' && $this->publisherURL !== '0') {
$this->opf->addDCMeta(DublinCore::RELATION, StringHelper::decodeHtmlEntities($this->publisherURL));
}
- if (!empty($this->author)) {
+ if ($this->author !== '' && $this->author !== '0') {
$author = StringHelper::decodeHtmlEntities($this->author);
$this->opf->addCreator($author, StringHelper::decodeHtmlEntities($this->authorSortKey), MarcCode::AUTHOR);
$this->ncx->setDocAuthor($author);
}
- if (!empty($this->rights)) {
+ if ($this->rights !== '' && $this->rights !== '0') {
$this->opf->addDCMeta(DublinCore::RIGHTS, StringHelper::decodeHtmlEntities($this->rights));
}
- if (!empty($this->coverage)) {
+ if ($this->coverage !== '' && $this->coverage !== '0') {
$this->opf->addDCMeta(DublinCore::COVERAGE, StringHelper::decodeHtmlEntities($this->coverage));
}
- if (!empty($this->sourceURL)) {
+ if ($this->sourceURL !== '' && $this->sourceURL !== '0') {
$this->opf->addDCMeta(DublinCore::SOURCE, $this->sourceURL);
}
- if (!empty($this->relation)) {
+ if ($this->relation !== '' && $this->relation !== '0') {
$this->opf->addDCMeta(DublinCore::RELATION, StringHelper::decodeHtmlEntities($this->relation));
}
@@ -2101,7 +2161,7 @@ public function finalize()
$this->opf->addMeta("cover", "CoverImage");
}
- if (!empty($this->generator)) {
+ if ($this->generator !== '' && $this->generator !== '0') {
$gen = StringHelper::decodeHtmlEntities($this->generator);
$this->opf->addMeta("generator", $gen);
$this->ncx->addMetaEntry("dtb:generator", $gen);
@@ -2158,10 +2218,8 @@ public function finalize()
/**
* Finalize and build final ePub structures.
- *
- * @return bool
*/
- private function finalizeTOC()
+ private function finalizeTOC(): bool
{
if (!$this->buildTOC) {
return false;
@@ -2187,6 +2245,7 @@ private function finalizeTOC()
$tocData .= "\n"
. "\n\n";
}
+
$tocData .= $this->getViewportMetaLine();
$tocData .= "\n";
- if (!empty($this->tocCssFileName)) {
- $tocData .= "tocCssFileName . "\" />\n";
+ if ($this->tocCssFileName !== null && $this->tocCssFileName !== '' && $this->tocCssFileName !== '0') {
+ $tocData .= '\n";
}
$tocData .= "" . $this->tocTitle . "\n"
@@ -2208,8 +2267,9 @@ private function finalizeTOC()
. "" . $this->tocTitle . "
\ntocCSSClass)) {
- $tocData .= " class=\"" . $this->tocCSSClass . "\"";
+ $tocData .= ' class="' . $this->tocCSSClass . '"';
}
+
$tocData .= ">\n";
foreach ($this->referencesOrder as $item => $descriptive) {
@@ -2220,24 +2280,19 @@ private function finalizeTOC()
$level = $navPoint->getLevel() - 2;
$tocData .= "\t
"
/* . str_repeat(" ", $level) . */
- . "" . $chapterName . "
\n";
+ . '
' . $chapterName . "\n";
}
- } else {
- if ($this->tocAddReferences === true) {
- if (array_key_exists($item, $this->ncx->referencesList)) {
- $tocData .= "\t
ncx->referencesList[$item] . "\">" . $descriptive . "
\n";
- } else {
- if ($item === "toc") {
- $tocData .= "\t
" . $this->tocTitle . "
\n";
- } else {
- if ($item === "cover" && $this->isCoverImageSet) {
- $tocData .= "\t
" . $descriptive . "
\n";
- }
- }
- }
+ } elseif ($this->tocAddReferences) {
+ if (array_key_exists($item, $this->ncx->referencesList)) {
+ $tocData .= "\t
ncx->referencesList[$item] . '">' . $descriptive . "
\n";
+ } elseif ($item === "toc") {
+ $tocData .= "\t
" . $this->tocTitle . "
\n";
+ } elseif ($item === "cover" && $this->isCoverImageSet) {
+ $tocData .= "\t
" . $descriptive . "
\n";
}
}
}
+
$tocData .= "
\n\n\n";
$this->addReferencePage($this->tocTitle, $this->tocFileName, $tocData, Reference::TABLE_OF_CONTENTS);
@@ -2248,14 +2303,13 @@ private function finalizeTOC()
/**
* @param string $fileName
* @param string $tocData
- *
- * @return bool
*/
- public function addEPub3TOC($fileName, $tocData)
+ public function addEPub3TOC($fileName, $tocData): bool
{
if ($this->isEPubVersion2() || $this->isFinalized || array_key_exists($fileName, $this->fileList)) {
return false;
}
+
if (!$this->isInitialized) {
$this->initialize();
}
@@ -2274,10 +2328,8 @@ public function addEPub3TOC($fileName, $tocData)
/**
* @param string $cssFileName
* @param string $title
- *
- * @return string
*/
- public function buildEPub3TOC($cssFileName = null, $title = "Table of Contents")
+ public function buildEPub3TOC($cssFileName = null, $title = "Table of Contents"): string
{
$this->ncx->referencesOrder = $this->referencesOrder;
$this->ncx->setDocTitle(StringHelper::decodeHtmlEntities($this->title));
@@ -2324,13 +2376,13 @@ public function getBookSize()
*
* @return string|bool The sent file name if successful, FALSE if it failed.
*/
- public function sendBook($fileName)
+ public function sendBook(string $fileName): string|bool
{
if (!$this->isFinalized) {
$this->finalize();
}
- if (!BinStringStatic::endsWith($fileName, ".epub")) {
+ if (!str_ends_with($fileName, ".epub")) {
$fileName .= ".epub";
}
@@ -2348,7 +2400,7 @@ public function sendBook($fileName)
*
* @return array file list
*/
- public function getFileList()
+ public function getFileList(): array
{
return $this->fileList;
}
@@ -2358,10 +2410,8 @@ public function getFileList()
* Default is 250000 bytes, and minimum is 10240 bytes.
*
* @param int $size segment size in bytes
- *
- * @return void
*/
- public function setSplitSize($size)
+ public function setSplitSize($size): void
{
$this->splitDefaultSize = (int)$size;
if ($size < 10240) {
@@ -2379,10 +2429,7 @@ public function getSplitSize()
return $this->splitDefaultSize;
}
- /**
- * @return string
- */
- public function getLog()
+ public function getLog(): string
{
return $this->log->getLog();
}
@@ -2396,16 +2443,18 @@ public function getLog()
* @param int|string $width integer for the width, or a string referencing an entry in the $viewportMap.
* @param int $height
*/
- public function setViewport($width = null, $height = null)
+ public function setViewport($width = null, $height = null): void
{
if ($width == null) {
unset($this->viewport);
}
+
if (is_string($width) && in_array($width, $this->viewportMap)) {
$vp = $this->viewportMap[$width];
$width = $vp['width'];
$height = $vp['height'];
}
+
$this->viewport = ['width' => $width, 'height' => $height];
}
@@ -2414,9 +2463,21 @@ public function setViewport($width = null, $height = null)
*
* @return string the meta data line, or an empty string if no viewport is defined.
*/
- public function getViewportMetaLine()
+ public function getViewportMetaLine(): string
{
- if (empty($this->viewport)) {
+ if (is_null($this->viewport)) {
+ return "";
+ }
+
+ if ($this->viewport === []) {
+ return "";
+ }
+
+ if (!array_key_exists("width", $this->viewport)) {
+ return "";
+ }
+
+ if (!array_key_exists("height", $this->viewport)) {
return "";
}
@@ -2431,7 +2492,7 @@ public function getViewportMetaLine()
*
* @param bool $dangermode
*/
- public function setDangermode($dangermode)
+ public function setDangermode($dangermode): void
{
$this->dangermode = $dangermode === true;
}
@@ -2441,7 +2502,7 @@ public function setDangermode($dangermode)
*
* @return null|Opf the Opf structure class.
*/
- public function DANGER_getOpf()
+ public function DANGER_getOpf(): ?\PHPePub\Core\Structure\Opf
{
return $this->dangermode ? $this->opf : null;
}
@@ -2451,7 +2512,7 @@ public function DANGER_getOpf()
*
* @return null|Ncx The Ncx Navigation class
*/
- public function DANGER_getNcx()
+ public function DANGER_getNcx(): ?\PHPePub\Core\Structure\Ncx
{
return $this->dangermode ? $this->ncx : null;
}
@@ -2465,7 +2526,7 @@ public function DANGER_getNcx()
*
* @return null|Zip The actual zip file.
*/
- public function DANGER_getZip()
+ public function DANGER_getZip(): ?\PHPZip\Zip\File\Zip
{
return $this->dangermode ? $this->zip : null;
}
diff --git a/src/PHPePub/Core/EPubChapterSplitter.php b/src/PHPePub/Core/EPubChapterSplitter.php
index 6d6164b..23f1065 100644
--- a/src/PHPePub/Core/EPubChapterSplitter.php
+++ b/src/PHPePub/Core/EPubChapterSplitter.php
@@ -18,8 +18,10 @@
*/
class EPubChapterSplitter
{
- private $splitDefaultSize = 250000;
- private $bookVersion = EPub::BOOK_VERSION_EPUB2;
+ private int $splitDefaultSize = 250000;
+
+ private string $bookVersion = EPub::BOOK_VERSION_EPUB2;
+
private $htmlFormat = EPub::FORMAT_XHTML;
/**
@@ -38,7 +40,7 @@ public function __construct($htmlFormat = EPub::FORMAT_XHTML)
*
* @param string $bookVersion
*/
- public function setVersion($bookVersion)
+ public function setVersion($bookVersion): void
{
$this->bookVersion = is_string($bookVersion) ? trim($bookVersion) : EPub::BOOK_VERSION_EPUB2;
}
@@ -48,7 +50,7 @@ public function setVersion($bookVersion)
*
* @param string $htmlFormat
*/
- public function setHtmlFormat($htmlFormat)
+ public function setHtmlFormat($htmlFormat): void
{
$this->htmlFormat = in_array($htmlFormat, [EPub::FORMAT_XHTML, EPub::FORMAT_HTML5])
? $htmlFormat
@@ -60,10 +62,8 @@ public function setHtmlFormat($htmlFormat)
* Default is 250000 bytes, and minimum is 10240 bytes.
*
* @param int $size segment size in bytes
- *
- * @return void
*/
- public function setSplitSize($size)
+ public function setSplitSize($size): void
{
$this->splitDefaultSize = (int)$size;
if ($size < 10240) {
@@ -76,7 +76,7 @@ public function setSplitSize($size)
*
* @return int $size
*/
- public function getSplitSize()
+ public function getSplitSize(): int
{
return $this->splitDefaultSize;
}
@@ -93,7 +93,7 @@ public function getSplitSize()
*
* @return array with 1 or more parts
*/
- public function splitChapter($chapter, $splitOnSearchString = false, $searchString = '/^Chapter\\ /i')
+ public function splitChapter($chapter, $splitOnSearchString = false, $searchString = '/^Chapter\\ /i'): array
{
$chapterData = [];
$isSearchRegexp = $splitOnSearchString && (preg_match('#^(\D|\S|\W).+\1[imsxeADSUXJu]*$#m', $searchString) == 1);
@@ -126,6 +126,7 @@ public function splitChapter($chapter, $splitOnSearchString = false, $searchStri
if (!str_contains(trim($newXML), "\n" . $newXML;
}
+
$headerLength = strlen($newXML);
$files = [];
@@ -158,7 +159,7 @@ public function splitChapter($chapter, $splitOnSearchString = false, $searchStri
if ($nodeLen > $partSize && $node->hasChildNodes()) {
$domPath[] = $node;
$domClonedPath[] = $node->cloneNode(false);
- $domDepth++;
+ ++$domDepth;
$node = $node->firstChild;
}
@@ -185,15 +186,17 @@ public function splitChapter($chapter, $splitOnSearchString = false, $searchStri
$curParent = $newParent;
}
}
+
$curSize = strlen($xmlDoc->saveXML($curFile));
}
+
$curParent->appendChild($node->cloneNode(true));
$curSize += $nodeLen;
}
$node = $node2;
while ($node == null && $domDepth > 0) {
- $domDepth--;
+ --$domDepth;
$node = end($domPath)->nextSibling;
array_pop($domPath);
array_pop($domClonedPath);
@@ -201,14 +204,14 @@ public function splitChapter($chapter, $splitOnSearchString = false, $searchStri
}
} while ($node != null);
- $curFile = null;
-
$xml = new DOMDocument('1.0', $xmlDoc->xmlEncoding);
$xml->lookupPrefix("http://www.w3.org/1999/xhtml");
+
$xml->preserveWhiteSpace = false;
$xml->formatOutput = true;
+ $counter = count($files);
- for ($idx = 0; $idx < count($files); $idx++) {
+ for ($idx = 0; $idx < $counter; ++$idx) {
$xml2Doc = new DOMDocument('1.0', $xmlDoc->xmlEncoding);
$xml2Doc->lookupPrefix("http://www.w3.org/1999/xhtml");
$xml2Doc->loadXML($newXML);
diff --git a/src/PHPePub/Core/Logger.php b/src/PHPePub/Core/Logger.php
index 57d660d..4989c69 100644
--- a/src/PHPePub/Core/Logger.php
+++ b/src/PHPePub/Core/Logger.php
@@ -11,11 +11,15 @@
*/
class Logger
{
- private $log = "";
- private $tStart;
+ private string $log = "";
+
+ private array|float|null $tStart = null;
+
private $tLast;
- private $name = null;
- private $isDebugging = false;
+
+ private ?string $name = null;
+
+ private bool $isDebugging = false;
/**
* Class constructor.
@@ -25,15 +29,11 @@ class Logger
*/
public function __construct($name = null, private $isLogging = false)
{
- if ($name === null) {
- $this->name = "";
- } else {
- $this->name = $name . " : ";
- }
+ $this->name = $name === null ? "" : $name . " : ";
$this->start();
}
- public function start()
+ public function start(): void
{
/* Prepare Logging. Just in case it's used. later */
if ($this->isLogging) {
@@ -44,7 +44,7 @@ public function start()
}
}
- public function logLine($line)
+ public function logLine(string $line): void
{
if ($this->isLogging) {
$tTemp = gettimeofday();
@@ -73,7 +73,7 @@ public function __destruct()
unset($this->log);
}
- public function dumpInstalledModules()
+ public function dumpInstalledModules(): void
{
if ($this->isLogging) {
$isCurlInstalled = extension_loaded('curl') && function_exists('curl_version');
@@ -90,17 +90,15 @@ public function dumpInstalledModules()
}
}
- public function getLog()
+ public function getLog(): string
{
return $this->log;
}
/**
* @param $isCurlInstalled
- *
- * @return string
*/
- public function boolYN($isCurlInstalled)
+ public function boolYN($isCurlInstalled): string
{
return ($isCurlInstalled ? "Yes" : "No");
}
diff --git a/src/PHPePub/Core/StaticData.php b/src/PHPePub/Core/StaticData.php
index 49b793e..c1d4844 100644
--- a/src/PHPePub/Core/StaticData.php
+++ b/src/PHPePub/Core/StaticData.php
@@ -12,7 +12,7 @@
class StaticData
{
public static $htmlEntities = [
- """ => "\x22",
+ """ => '"',
// " ((double) quotation mark)
"&" => "\x26",
// & (ampersand)
@@ -526,7 +526,7 @@ class StaticData
public static $opsContentTypes = ["application/xhtml+xml", "application/x-dtbook+xml", "application/xml", "application/x-dtbncx+xml", "text/x-oeb1-document"];
- public static $forbiddenCharacters = ["?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", "%"];
+ public static $forbiddenCharacters = ["?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", '"', "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", "%"];
public static $namespaces = ["xsi" => "http://www.w3.org/2001/XMLSchema-instance", "opf" => "http://www.idpf.org/2007/opf", "dcterms" => "http://purl.org/dc/terms/", "dc" => "http://purl.org/dc/elements/1.1/"];
}
diff --git a/src/PHPePub/Core/Structure/NCX/NavMap.php b/src/PHPePub/Core/Structure/NCX/NavMap.php
index eecbe2d..43dd294 100644
--- a/src/PHPePub/Core/Structure/NCX/NavMap.php
+++ b/src/PHPePub/Core/Structure/NCX/NavMap.php
@@ -13,9 +13,11 @@ class NavMap extends AbstractNavEntry
{
final public const _VERSION = 3.30;
- private $navPoints = [];
- private $navLevels = 0;
- private $writingDirection = null;
+ private array $navPoints = [];
+
+ private int $navLevels = 0;
+
+ private ?string $writingDirection = null;
/**
* Class constructor.
@@ -37,7 +39,7 @@ public function __destruct()
unset($this->navPoints, $this->navLevels, $this->writingDirection);
}
- public function getWritingDirection()
+ public function getWritingDirection(): ?string
{
return $this->writingDirection;
}
@@ -47,7 +49,7 @@ public function getWritingDirection()
*
* @param string $writingDirection
*/
- public function setWritingDirection($writingDirection)
+ public function setWritingDirection($writingDirection): void
{
$this->writingDirection = isset($writingDirection) && is_string($writingDirection) ? trim($writingDirection) : null;
}
@@ -59,13 +61,14 @@ public function setWritingDirection($writingDirection)
*
* @return NavMap
*/
- public function addNavPoint($navPoint)
+ public function addNavPoint($navPoint): \PHPePub\Core\Structure\NCX\NavPoint|static
{
if ($navPoint != null && is_object($navPoint) && $navPoint instanceof NavPoint) {
$navPoint->setParent($this);
if ($navPoint->getWritingDirection() == null) {
$navPoint->setWritingDirection($this->writingDirection);
}
+
$this->navPoints[] = $navPoint;
return $navPoint;
@@ -80,12 +83,12 @@ public function addNavPoint($navPoint)
*
* @return number
*/
- public function getNavLevels()
+ public function getNavLevels(): int|float
{
return $this->navLevels + 1;
}
- public function getLevel()
+ public function getLevel(): int
{
return 1;
}
@@ -93,7 +96,7 @@ public function getLevel()
/**
* @return AbstractNavEntry this
*/
- public function getParent()
+ public function getParent(): static
{
return $this;
}
@@ -102,14 +105,14 @@ public function getParent()
* Finalize the navMap, the final max depth for the "dtb:depth" meta attribute can be retrieved with getNavLevels after finalization
*
*/
- public function finalize()
+ public function finalize(): string
{
$playOrder = 0;
$this->navLevels = 0;
$nav = "\t\n";
- if (count($this->navPoints) > 0) {
- $this->navLevels++;
+ if ($this->navPoints !== []) {
+ ++$this->navLevels;
foreach ($this->navPoints as $navPoint) {
/** @var $navPoint NavPoint */
$retLevel = $navPoint->finalize($nav, $playOrder, 0);
@@ -126,7 +129,7 @@ public function finalize()
* Finalize the navMap, the final max depth for the "dtb:depth" meta attribute can be retrieved with getNavLevels after finalization
*
*/
- public function finalizeEPub3()
+ public function finalizeEPub3(): string
{
$playOrder = 0;
$level = 0;
@@ -134,8 +137,8 @@ public function finalizeEPub3()
$nav = "\t\t