From 99410a21eb261f50234cc4148323a52b345e15e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Mon, 19 Jan 2015 13:00:33 +0100 Subject: phpepub via composer --- .../libraries/PHPePub/EPub.HtmlEntities.php | 266 --- inc/3rdparty/libraries/PHPePub/EPub.NCX.php | 782 ------- inc/3rdparty/libraries/PHPePub/EPub.OPF.php | 1226 ---------- inc/3rdparty/libraries/PHPePub/EPub.php | 2438 -------------------- .../libraries/PHPePub/EPubChapterSplitter.php | 201 -- inc/3rdparty/libraries/PHPePub/Logger.php | 92 - inc/3rdparty/libraries/PHPePub/Zip.php | 818 ------- .../libraries/PHPePub/lib.uuid.LICENCE.txt | 31 - inc/3rdparty/libraries/PHPePub/lib.uuid.php | 314 --- 9 files changed, 6168 deletions(-) delete mode 100644 inc/3rdparty/libraries/PHPePub/EPub.HtmlEntities.php delete mode 100644 inc/3rdparty/libraries/PHPePub/EPub.NCX.php delete mode 100644 inc/3rdparty/libraries/PHPePub/EPub.OPF.php delete mode 100644 inc/3rdparty/libraries/PHPePub/EPub.php delete mode 100644 inc/3rdparty/libraries/PHPePub/EPubChapterSplitter.php delete mode 100644 inc/3rdparty/libraries/PHPePub/Logger.php delete mode 100644 inc/3rdparty/libraries/PHPePub/Zip.php delete mode 100644 inc/3rdparty/libraries/PHPePub/lib.uuid.LICENCE.txt delete mode 100644 inc/3rdparty/libraries/PHPePub/lib.uuid.php (limited to 'inc/3rdparty') diff --git a/inc/3rdparty/libraries/PHPePub/EPub.HtmlEntities.php b/inc/3rdparty/libraries/PHPePub/EPub.HtmlEntities.php deleted file mode 100644 index 376b6133..00000000 --- a/inc/3rdparty/libraries/PHPePub/EPub.HtmlEntities.php +++ /dev/null @@ -1,266 +0,0 @@ - \ No newline at end of file diff --git a/inc/3rdparty/libraries/PHPePub/EPub.NCX.php b/inc/3rdparty/libraries/PHPePub/EPub.NCX.php deleted file mode 100644 index e5da05cd..00000000 --- a/inc/3rdparty/libraries/PHPePub/EPub.NCX.php +++ /dev/null @@ -1,782 +0,0 @@ - - * @copyright 2009-2014 A. Grandt - * @license GNU LGPL, Attribution required for commercial implementations, requested for everything else. - * @version 3.20 - */ -class Ncx { - const _VERSION = 3.20; - - const MIMETYPE = "application/x-dtbncx+xml"; - - private $bookVersion = EPub::BOOK_VERSION_EPUB2; - - private $navMap = NULL; - private $uid = NULL; - private $meta = array(); - private $docTitle = NULL; - private $docAuthor = NULL; - - private $currentLevel = NULL; - private $lastLevel = NULL; - - private $languageCode = "en"; - private $writingDirection = EPub::DIRECTION_LEFT_TO_RIGHT; - - public $chapterList = array(); - public $referencesTitle = "Guide"; - public $referencesClass = "references"; - public $referencesId = "references"; - public $referencesList = array(); - public $referencesName = array(); - public $referencesOrder = NULL; - - /** - * Class constructor. - * - * @param string $uid - * @param string $docTitle - * @param string $docAuthor - * @param string $languageCode - * @param string $writingDirection - */ - function __construct($uid = NULL, $docTitle = NULL, $docAuthor = NULL, $languageCode = "en", $writingDirection = EPub::DIRECTION_LEFT_TO_RIGHT) { - $this->navMap = new NavMap($writingDirection); - $this->currentLevel = $this->navMap; - $this->setUid($uid); - $this->setDocTitle($docTitle); - $this->setDocAuthor($docAuthor); - $this->setLanguageCode($languageCode); - $this->setWritingDirection($writingDirection); - } - - /** - * Class destructor - * - * @return void - */ - function __destruct() { - unset($this->bookVersion, $this->navMap, $this->uid, $this->meta); - unset($this->docTitle, $this->docAuthor, $this->currentLevel, $this->lastLevel); - unset($this->languageCode, $this->writingDirection, $this->chapterList, $this->referencesTitle); - unset($this->referencesClass, $this->referencesId, $this->referencesList, $this->referencesName); - unset($this->referencesOrder); - } - - /** - * - * Enter description here ... - * - * @param string $bookVersion - */ - function setVersion($bookVersion) { - $this->bookVersion = is_string($bookVersion) ? trim($bookVersion) : EPub::BOOK_VERSION_EPUB2; - } - - /** - * - * @return bool TRUE if the book is set to type ePub 2 - */ - function isEPubVersion2() { - return $this->bookVersion === EPub::BOOK_VERSION_EPUB2; - } - - /** - * - * Enter description here ... - * - * @param string $uid - */ - function setUid($uid) { - $this->uid = is_string($uid) ? trim($uid) : NULL; - } - - /** - * - * Enter description here ... - * - * @param string $docTitle - */ - function setDocTitle($docTitle) { - $this->docTitle = is_string($docTitle) ? trim($docTitle) : NULL; - } - - /** - * - * Enter description here ... - * - * @param string $docAuthor - */ - function setDocAuthor($docAuthor) { - $this->docAuthor = is_string($docAuthor) ? trim($docAuthor) : NULL; - } - - /** - * - * Enter description here ... - * - * @param string $languageCode - */ - function setLanguageCode($languageCode) { - $this->languageCode = is_string($languageCode) ? trim($languageCode) : "en"; - } - - /** - * - * Enter description here ... - * - * @param string $writingDirection - */ - function setWritingDirection($writingDirection) { - $this->writingDirection = is_string($writingDirection) ? trim($writingDirection) : EPub::DIRECTION_LEFT_TO_RIGHT; - } - - /** - * - * Enter description here ... - * - * @param NavMap $navMap - */ - function setNavMap($navMap) { - if ($navMap != NULL && is_object($navMap) && get_class($navMap) === "NavMap") { - $this->navMap = $navMap; - } - } - - /** - * Add one chapter level. - * - * Subsequent chapters will be added to this level. - * - * @param string $navTitle - * @param string $navId - * @param string $navClass - * @param string $isNavHidden - * @param string $writingDirection - * @return NavPoint - */ - function subLevel($navTitle = NULL, $navId = NULL, $navClass = NULL, $isNavHidden = FALSE, $writingDirection = NULL) { - $navPoint = FALSE; - if (isset($navTitle) && isset($navClass)) { - $navPoint = new NavPoint($navTitle, NULL, $navId, $navClass, $isNavHidden, $writingDirection); - $this->addNavPoint($navPoint); - } - if ($this->lastLevel !== NULL) { - $this->currentLevel = $this->lastLevel; - } - return $navPoint; - } - - /** - * Step back one chapter level. - * - * Subsequent chapters will be added to this chapters parent level. - */ - function backLevel() { - $this->lastLevel = $this->currentLevel; - $this->currentLevel = $this->currentLevel->getParent(); - } - - /** - * Step back to the root level. - * - * Subsequent chapters will be added to the rooot NavMap. - */ - function rootLevel() { - $this->lastLevel = $this->currentLevel; - $this->currentLevel = $this->navMap; - } - - /** - * Step back to the given level. - * Useful for returning to a previous level from deep within the structure. - * Values below 2 will have the same effect as rootLevel() - * - * @param int $newLevel - */ - function setCurrentLevel($newLevel) { - if ($newLevel <= 1) { - $this->rootLevel(); - } else { - while ($this->currentLevel->getLevel() > $newLevel) { - $this->backLevel(); - } - } - } - - /** - * Get current level count. - * The indentation of the current structure point. - * - * @return current level count; - */ - function getCurrentLevel() { - return $this->currentLevel->getLevel(); - } - - /** - * Add child NavPoints to current level. - * - * @param NavPoint $navPoint - */ - function addNavPoint($navPoint) { - $this->lastLevel = $this->currentLevel->addNavPoint($navPoint); - } - - /** - * - * Enter description here ... - * - * @return NavMap - */ - function getNavMap() { - return $this->navMap; - } - - /** - * - * Enter description here ... - * - * @param string $name - * @param string $content - */ - function addMetaEntry($name, $content) { - $name = is_string($name) ? trim($name) : NULL; - $content = is_string($content) ? trim($content) : NULL; - - if ($name != NULL && $content != NULL) { - $this->meta[] = array($name => $content); - } - } - - /** - * - * Enter description here ... - * - * @return string - */ - function finalize() { - $nav = $this->navMap->finalize(); - - $ncx = "\n"; - if ($this->isEPubVersion2()) { - $ncx .= "\n"; - } - $ncx .= "languageCode . "\" dir=\"" . $this->writingDirection . "\">\n" - . "\t\n" - . "\t\tuid . "\" />\n" - . "\t\tnavMap->getNavLevels() . "\" />\n" - . "\t\t\n" - . "\t\t\n"; - - if (sizeof($this->meta)) { - foreach ($this->meta as $metaEntry) { - list($name, $content) = each($metaEntry); - $ncx .= "\t\t\n"; - } - } - - $ncx .= "\t\n\n\t\n\t\t" - . $this->docTitle - . "\n\t\n\n\t\n\t\t" - . $this->docAuthor - . "\n\t\n\n" - . $nav; - - return $ncx . "\n"; - } - - /** - * - * @param string $title - * @param string $cssFileName - * @return string - */ - function finalizeEPub3($title = "Table of Contents", $cssFileName = NULL) { - $end = "\n" - . "languageCode . "\" lang=\"" . $this->languageCode . "\" dir=\"" . $this->writingDirection . "\">\n" - . "\t\n" - . "\t\t" . $this->docTitle . "\n" - . "\t\t\n"; - if ($cssFileName !== NULL) { - $end .= "\t\t\n"; - } - $end .= "\t\n" - . "\t\n" - . "\t\t
\n" - . "\t\t\t

" . $title . "

\n" - . "\t\t
\n" - . $this->navMap->finalizeEPub3() - . $this->finalizeEPub3Landmarks() - . "\t\n" - . "\n"; - - return $end; - } - - /** - * Build the references for the ePub 2 toc. - * These are merely reference pages added to the end of the navMap though. - * - * @return string - */ - function finalizeReferences() { - if (isset($this->referencesList) && sizeof($this->referencesList) > 0) { - $this->rootLevel(); - $this->subLevel($this->referencesTitle, $this->referencesId, $this->referencesClass); - $refId = 1; - while (list($item, $descriptive) = each($this->referencesOrder)) { - if (array_key_exists($item, $this->referencesList)) { - $name = (empty($this->referencesName[$item]) ? $descriptive : $this->referencesName[$item]); - $navPoint = new NavPoint($name, $this->referencesList[$item], "ref-" . $refId++); - $this->addNavPoint($navPoint); - } - } - } - } - - /** - * Build the landmarks for the ePub 3 toc. - * @return string - */ - function finalizeEPub3Landmarks() { - $lm = ""; - if (isset($this->referencesList) && sizeof($this->referencesList) > 0) { - $lm = "\t\t\t\n"; - } - return $lm; - } -} - -/** - * ePub NavMap class - */ -class NavMap { - const _VERSION = 3.00; - - private $navPoints = array(); - private $navLevels = 0; - private $writingDirection = NULL; - - /** - * Class constructor. - * - * @return void - */ - function __construct($writingDirection = NULL) { - $this->setWritingDirection($writingDirection); - } - - /** - * Class destructor - * - * @return void - */ - function __destruct() { - unset($this->navPoints, $this->navLevels, $this->writingDirection); - } - - /** - * Set the writing direction to be used for this NavPoint. - * - * @param string $writingDirection - */ - function setWritingDirection($writingDirection) { - $this->writingDirection = isset($writingDirection) && is_string($writingDirection) ? trim($writingDirection) : NULL; - } - - function getWritingDirection() { - return $this->writingDirection; - } - - /** - * Add a navPoint to the root of the NavMap. - * - * @param NavPoint $navPoint - * @return NavMap - */ - function addNavPoint($navPoint) { - if ($navPoint != NULL && is_object($navPoint) && get_class($navPoint) === "NavPoint") { - $navPoint->setParent($this); - if ($navPoint->getWritingDirection() == NULL) { - $navPoint->setWritingDirection($this->writingDirection); - } - $this->navPoints[] = $navPoint; - return $navPoint; - } - return $this; - } - - /** - * The final max depth for the "dtb:depth" meta attribute - * Only available after finalize have been called. - * - * @return number - */ - function getNavLevels() { - return $this->navLevels+1; - } - - function getLevel() { - return 1; - } - - function getParent() { - return $this; - } - - /** - * Finalize the navMap, the final max depth for the "dtb:depth" meta attribute can be retrieved with getNavLevels after finalization - * - */ - function finalize() { - $playOrder = 0; - $this->navLevels = 0; - - $nav = "\t\n"; - if (sizeof($this->navPoints) > 0) { - $this->navLevels++; - foreach ($this->navPoints as $navPoint) { - $retLevel = $navPoint->finalize($nav, $playOrder, 0); - if ($retLevel > $this->navLevels) { - $this->navLevels = $retLevel; - } - } - } - return $nav . "\t\n"; - } - - /** - * Finalize the navMap, the final max depth for the "dtb:depth" meta attribute can be retrieved with getNavLevels after finalization - * - */ - function finalizeEPub3() { - $playOrder = 0; - $level = 0; - $this->navLevels = 0; - - $nav = "\t\t\n"; - } -} - -/** - * ePub NavPoint class - */ -class NavPoint { - const _VERSION = 3.00; - - private $label = NULL; - private $contentSrc = NULL; - private $id = NULL; - private $navClass = NULL; - private $isNavHidden = FALSE; - private $navPoints = array(); - private $parent = NULL; - - /** - * Class constructor. - * - * All three attributes are mandatory, though if ID is set to null (default) the value will be generated. - * - * @param string $label - * @param string $contentSrc - * @param string $id - * @param string $navClass - * @param bool $isNavHidden - * @param string $writingDirection - */ - function __construct($label, $contentSrc = NULL, $id = NULL, $navClass = NULL, $isNavHidden = FALSE, $writingDirection = NULL) { - $this->setLabel($label); - $this->setContentSrc($contentSrc); - $this->setId($id); - $this->setNavClass($navClass); - $this->setNavHidden($isNavHidden); - $this->setWritingDirection($writingDirection); - } - - /** - * Class destructor - * - * @return void - */ - function __destruct() { - unset($this->label, $this->contentSrc, $this->id, $this->navClass); - unset($this->isNavHidden, $this->navPoints, $this->parent); - } - - /** - * Set the Text label for the NavPoint. - * - * The label is mandatory. - * - * @param string $label - */ - function setLabel($label) { - $this->label = is_string($label) ? trim($label) : NULL; - } - - /** - * Get the Text label for the NavPoint. - * - * @return string Label - */ - function getLabel() { - return $this->label; - } - - /** - * Set the src reference for the NavPoint. - * - * The src is mandatory for ePub 2. - * - * @param string $contentSrc - */ - function setContentSrc($contentSrc) { - $this->contentSrc = isset($contentSrc) && is_string($contentSrc) ? trim($contentSrc) : NULL; - } - - /** - * Get the src reference for the NavPoint. - * - * @return string content src url. - */ - function getContentSrc() { - return $this->contentSrc; - } - /** - * Set the parent for this NavPoint. - * - * @param NavPoint or NavMap $parent - */ - function setParent($parent) { - if ($parent != NULL && is_object($parent) && - (get_class($parent) === "NavPoint" || get_class($parent) === "NavMap") ) { - $this->parent = $parent; - } - } - - /** - * Get the parent to this NavPoint. - * - * @return NavPoint, or NavMap if the parent is the root. - */ - function getParent() { - return $this->parent; - } - - /** - * Get the current level. 1 = document root. - * - * @return int level - */ - function getLevel() { - return $this->parent === NULL ? 1 : $this->parent->getLevel()+1; - } - - /** - * Set the id for the NavPoint. - * - * The id must be unique, and is mandatory. - * - * @param string $id - */ - function setId($id) { - $this->id = is_string($id) ? trim($id) : NULL; - } - - /** - * Set the class to be used for this NavPoint. - * - * @param string $navClass - */ - function setNavClass($navClass) { - $this->navClass = isset($navClass) && is_string($navClass) ? trim($navClass) : NULL; - } - - /** - * Set the class to be used for this NavPoint. - * - * @param string $navClass - */ - function setNavHidden($isNavHidden) { - $this->isNavHidden = $isNavHidden === TRUE; - } - - /** - * Set the writing direction to be used for this NavPoint. - * - * @param string $writingDirection - */ - function setWritingDirection($writingDirection) { - $this->writingDirection = isset($writingDirection) && is_string($writingDirection) ? trim($writingDirection) : NULL; - } - - function getWritingDirection() { - return $this->writingDirection; - } - - /** - * Add child NavPoints for multi level NavMaps. - * - * @param NavPoint $navPoint - */ - function addNavPoint($navPoint) { - if ($navPoint != NULL && is_object($navPoint) && get_class($navPoint) === "NavPoint") { - $navPoint->setParent($this); - if ($navPoint->getWritingDirection() == NULL) { - $navPoint->setWritingDirection($this->writingDirection); - } - $this->navPoints[] = $navPoint; - return $navPoint; - } - return $this; - } - - /** - * - * Enter description here ... - * - * @param string $nav - * @param int $playOrder - * @param int $level - * @return int - */ - function finalize(&$nav = "", &$playOrder = 0, $level = 0) { - $maxLevel = $level; - $levelAdjust = 0; - - if ($this->isNavHidden) { - return $maxLevel; - } - - if (isset($this->contentSrc)) { - $playOrder++; - - if ($this->id == NULL) { - $this->id = "navpoint-" . $playOrder; - } - $nav .= str_repeat("\t", $level) . "\t\tid . "\" playOrder=\"" . $playOrder . "\">\n" - . str_repeat("\t", $level) . "\t\t\t\n" - . str_repeat("\t", $level) . "\t\t\t\t" . $this->label . "\n" - . str_repeat("\t", $level) . "\t\t\t\n" - . str_repeat("\t", $level) . "\t\t\tcontentSrc . "\" />\n"; - } else { - $levelAdjust++; - } - - if (sizeof($this->navPoints) > 0) { - $maxLevel++; - foreach ($this->navPoints as $navPoint) { - $retLevel = $navPoint->finalize($nav, $playOrder, ($level+1+$levelAdjust)); - if ($retLevel > $maxLevel) { - $maxLevel = $retLevel; - } - } - } - - if (isset($this->contentSrc)) { - $nav .= str_repeat("\t", $level) . "\t\t\n"; - } - - return $maxLevel; - } - - /** - * - * Enter description here ... - * - * @param string $nav - * @param int $playOrder - * @param int $level - * @return int - */ - function finalizeEPub3(&$nav = "", &$playOrder = 0, $level = 0, $subLevelClass = NULL, $subLevelHidden = FALSE) { - $maxLevel = $level; - - if ($this->id == NULL) { - $this->id = "navpoint-" . $playOrder; - } - $indent = str_repeat("\t", $level) . "\t\t\t\t"; - - $nav .= $indent . "
  • id . "\""; - if (isset($this->writingDirection)) { - $nav .= " dir=\"" . $this->writingDirection . "\""; - } - $nav .= ">\n"; - - if (isset($this->contentSrc)) { - $nav .= $indent . "\tcontentSrc . "\">" . $this->label . "\n"; - } else { - $nav .= $indent . "\t" . $this->label . "\n"; - } - - if (sizeof($this->navPoints) > 0) { - $maxLevel++; - - $nav .= $indent . "\t
      navPoints as $navPoint) { - $retLevel = $navPoint->finalizeEPub3($nav, $playOrder, ($level+2), $subLevelClass, $subLevelHidden); - if ($retLevel > $maxLevel) { - $maxLevel = $retLevel; - } - } - $nav .= $indent . "\t
    \n"; - } - - $nav .= $indent . "
  • \n"; - - return $maxLevel; - } -} -?> \ No newline at end of file diff --git a/inc/3rdparty/libraries/PHPePub/EPub.OPF.php b/inc/3rdparty/libraries/PHPePub/EPub.OPF.php deleted file mode 100644 index 803a2108..00000000 --- a/inc/3rdparty/libraries/PHPePub/EPub.OPF.php +++ /dev/null @@ -1,1226 +0,0 @@ - - * @copyright 2009-2014 A. Grandt - * @license GNU LGPL, Attribution required for commercial implementations, requested for everything else. - * @version 3.20 - */ -class Opf { - const _VERSION = 3.20; - - /* Core Media types. - * These types are the only guaranteed mime types any ePub reader must understand. - * Any other type muse define a fall back whose fallback chain will end in one of these. - */ - const TYPE_GIF = "image/gif"; - const TYPE_JPEG = "image/jpeg"; - const TYPE_PNG = "image/png"; - const TYPE_SVG = "image/svg+xml"; - const TYPE_XHTML = "application/xhtml+xml"; - const TYPE_DTBOOK = "application/x-dtbook+xml"; - const TYPE_CSS = "text/css"; - const TYPE_XML = "application/xml"; - const TYPE_OEB1_DOC = "text/x-oeb1-document"; // Deprecated - const TYPE_OEB1_CSS = "text/x-oeb1-css"; // Deprecated - const TYPE_NCX = "application/x-dtbncx+xml"; - - private $bookVersion = EPub::BOOK_VERSION_EPUB2; - private $ident = "BookId"; - - public $date = NULL; - public $metadata = NULL; - public $manifest = NULL; - public $spine = NULL; - public $guide = NULL; - - /** - * Class constructor. - * - * @return void - */ - function __construct($ident = "BookId", $bookVersion = EPub::BOOK_VERSION_EPUB2) { - $this->setIdent($ident); - $this->setVersion($bookVersion); - $this->metadata = new Metadata(); - $this->manifest = new Manifest(); - $this->spine = new Spine(); - $this->guide = new Guide(); - } - - /** - * Class destructor - * - * @return void - */ - function __destruct() { - unset ($this->bookVersion, $this->ident, $this->date, $this->metadata, $this->manifest, $this->spine, $this->guide); - } - - /** - * - * Enter description here ... - * - * @param string $ident - */ - function setVersion($bookVersion) { - $this->bookVersion = is_string($bookVersion) ? trim($bookVersion) : EPub::BOOK_VERSION_EPUB2; - } - - function isEPubVersion2() { - return $this->bookVersion === EPub::BOOK_VERSION_EPUB2; - } - - /** - * - * Enter description here ... - * - * @param string $ident - */ - function setIdent($ident = "BookId") { - $this->ident = is_string($ident) ? trim($ident) : "BookId"; - } - - /** - * - * Enter description here ... - * - * @return string - */ - function finalize() { - $opf = "\n" - . "ident . "\" version=\"" . $this->bookVersion . "\">\n"; - - $opf .= $this->metadata->finalize($this->bookVersion, $this->date); - $opf .= $this->manifest->finalize($this->bookVersion); - $opf .= $this->spine->finalize(); - - if ($this->guide->length() > 0) { - $opf .= $this->guide->finalize(); - } - - return $opf . "\n"; - } - - // Convenience functions: - - /** - * - * Enter description here ... - * - * @param string $title - * @param string $language - * @param string $identifier - * @param string $identifierScheme - */ - function initialize($title, $language, $identifier, $identifierScheme) { - $this->metadata->addDublinCore(new DublinCore("title", $title)); - $this->metadata->addDublinCore(new DublinCore("language", $language)); - - $dc = new DublinCore("identifier", $identifier); - $dc->addAttr("id", $this->ident); - $dc->addOpfAttr("scheme", $identifierScheme); - $this->metadata->addDublinCore($dc); - } - - /** - * - * Enter description here ... - * - * @param string $id - * @param string $href - * @param string $mediaType - */ - function addItem($id, $href, $mediaType, $properties = NULL) { - $this->manifest->addItem(new Item($id, $href, $mediaType, $properties)); - } - - /** - * - * Enter description here ... - * - * @param string $idref - * @param bool $linear - */ - function addItemRef($idref, $linear = TRUE) { - $this->spine->addItemref(new Itemref($idref, $linear)); - } - - /** - * - * Enter description here ... - * - * @param string $type - * @param string $title - * @param string $href - */ - function addReference($type, $title, $href) { - $this->guide->addReference(new Reference($type, $title, $href)); - } - - /** - * - * Enter description here ... - * - * @param string $name - * @param string $value - */ - function addDCMeta($name, $value) { - $this->metadata->addDublinCore(new DublinCore($name, $value)); - } - - /** - * - * Enter description here ... - * - * @param string $name - * @param string $content - */ - function addMeta($name, $content) { - $this->metadata->addMeta($name, $content); - } - - /** - * - * Enter description here ... - * - * @param string $name - * @param string $fileAs - * @param string $role Use the MarcCode constants - */ - function addCreator($name, $fileAs = NULL, $role = NULL) { - $dc = new DublinCore(DublinCore::CREATOR, trim($name)); - - if ($fileAs !== NULL) { - $dc->addOpfAttr("file-as", trim($fileAs)); - } - - if ($role !== NULL) { - $dc->addOpfAttr("role", trim($role)); - } - - $this->metadata->addDublinCore($dc); - } - - /** - * - * Enter description here ... - * - * @param string $name - * @param string $fileAs - * @param string $role Use the MarcCode constants - */ - function addColaborator($name, $fileAs = NULL, $role = NULL) { - $dc = new DublinCore(DublinCore::CONTRIBUTOR, trim($name)); - - if ($fileAs !== NULL) { - $dc->addOpfAttr("file-as", trim($fileAs)); - } - - if ($role !== NULL) { - $dc->addOpfAttr("role", trim($role)); - } - - $this->metadata->addDublinCore($dc); - } -} - -/** - * ePub OPF Metadata structures - */ -class Metadata { - const _VERSION = 3.00; - - private $dc = array(); - private $meta = array(); - - /** - * Class constructor. - * - * @return void - */ - function __construct() { - } - - /** - * Class destructor - * - * @return void - */ - function __destruct() { - unset ($this->dc, $this->meta); - } - - /** - * - * Enter description here ... - * - * @param DublinCore $dc - */ - function addDublinCore($dc) { - if ($dc != NULL && is_object($dc) && get_class($dc) === "DublinCore") { - $this->dc[] = $dc; - } - } - - /** - * - * Enter description here ... - * - * @param string $name - * @param string $content - */ - function addMeta($name, $content) { - $name = is_string($name) ? trim($name) : NULL; - if (isset($name)) { - $content = is_string($content) ? trim($content) : NULL; - } - if (isset($content)) { - $this->meta[] = array ($name => $content); - } - } - - /** - * - * @param string $bookVersion - * @param int $date - * @return string - */ - function finalize($bookVersion = EPub::BOOK_VERSION_EPUB2, $date = NULL) { - $metadata = "\t\n"; - } else { - $metadata .= "\t\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"; - if (!isset($date)) { - $date = time(); - } - $metadata .= "\t\t" . gmdate("Y-m-d\TH:i:s\Z", $date) . "\n"; - } - - foreach ($this->dc as $dc) { - $metadata .= $dc->finalize($bookVersion); - } - - foreach ($this->meta as $data) { - list($name, $content) = each($data); - $metadata .= "\t\t\n"; - } - - return $metadata . "\t\n"; - } -} - -/** - * ePub OPF Dublin Core (dc:) Metadata structures - */ -class DublinCore { - const _VERSION = 3.00; - - const CONTRIBUTOR = "contributor"; - const COVERAGE = "coverage"; - const CREATOR = "creator"; - const DATE = "date"; - const DESCRIPTION = "description"; - const FORMAT = "format"; - const IDENTIFIER = "identifier"; - const LANGUAGE = "language"; - const PUBLISHER = "publisher"; - const RELATION = "relation"; - const RIGHTS = "rights"; - const SOURCE = "source"; - const SUBJECT = "subject"; - const TITLE = "title"; - const TYPE = "type"; - - private $dcName = NULL; - private $dcValue = NULL; - private $attr = array(); - private $opfAttr = array(); - - /** - * Class constructor. - * - * @return void - */ - function __construct($name, $value) { - $this->setDc($name, $value); - } - - /** - * Class destructor - * - * @return void - */ - function __destruct() { - unset ($this->dcName, $this->dcValue, $this->attr, $this->opfAttr); - } - - /** - * - * Enter description here ... - * - * @param string $name - * @param string $value - */ - function setDc($name, $value) { - $this->dcName = is_string($name) ? trim($name) : NULL; - if (isset($this->dcName)) { - $this->dcValue = isset($value) ? (string)$value : NULL; - } - if (! isset($this->dcValue)) { - $this->dcName = NULL; - } - } - - /** - * - * Enter description here ... - * - * @param string $attrName - * @param string $attrValue - */ - function addAttr($attrName, $attrValue) { - $attrName = is_string($attrName) ? trim($attrName) : NULL; - if (isset($attrName)) { - $attrValue = is_string($attrValue) ? trim($attrValue) : NULL; - } - if (isset($attrValue)) { - $this->attr[$attrName] = $attrValue; - } - } - - /** - * - * Enter description here ... - * - * @param string $opfAttrName - * @param string $opfAttrValue - */ - function addOpfAttr($opfAttrName, $opfAttrValue) { - $opfAttrName = is_string($opfAttrName) ? trim($opfAttrName) : NULL; - if (isset($opfAttrName)) { - $opfAttrValue = is_string($opfAttrValue) ? trim($opfAttrValue) : NULL; - } - if (isset($opfAttrValue)) { - $this->opfAttr[$opfAttrName] = $opfAttrValue; - } - } - - - /** - * - * @param string $bookVersion - * @return string - */ - function finalize($bookVersion = EPub::BOOK_VERSION_EPUB2) { - $dc = "\t\tdcName; - - if (sizeof($this->attr) > 0) { - while (list($name, $content) = each($this->attr)) { - $dc .= " " . $name . "=\"" . $content . "\""; - } - } - - if ($bookVersion === EPub::BOOK_VERSION_EPUB2 && sizeof($this->opfAttr) > 0) { - while (list($name, $content) = each($this->opfAttr)) { - $dc .= " opf:" . $name . "=\"" . $content . "\""; - } - } - - return $dc . ">" . $this->dcValue . "dcName . ">\n"; - } -} - -/** - * ePub OPF Manifest structure - */ -class Manifest { - const _VERSION = 3.00; - - private $items = array(); - - /** - * Class constructor. - * - * @return void - */ - function __construct() { - } - - /** - * Class destructor - * - * @return void - */ - function __destruct() { - unset ($this->items); - } - - /** - * - * Enter description here ... - * - * @param Item $item - */ - function addItem($item) { - if ($item != NULL && is_object($item) && get_class($item) === "Item") { - $this->items[] = $item; - } - } - - /** - * - * @param string $bookVersion - * @return string - */ - function finalize($bookVersion = EPub::BOOK_VERSION_EPUB2) { - $manifest = "\n\t\n"; - foreach ($this->items as $item) { - $manifest .= $item->finalize($bookVersion); - } - return $manifest . "\t\n"; - } -} - -/** - * ePub OPF Item structure - */ -class Item { - const _VERSION = 3.00; - - private $id = NULL; - private $href = NULL; - private $mediaType = NULL; - private $properties = NULL; - private $requiredNamespace = NULL; - private $requiredModules = NULL; - private $fallback = NULL; - private $fallbackStyle = NULL; - - /** - * Class constructor. - * - * @return void - */ - function __construct($id, $href, $mediaType, $properties = NULL) { - $this->setId($id); - $this->setHref($href); - $this->setMediaType($mediaType); - $this->setProperties($properties); - } - - /** - * Class destructor - * - * @return void - */ - function __destruct() { - unset ($this->id, $this->href, $this->mediaType); - unset ($this->properties, $this->requiredNamespace, $this->requiredModules, $this->fallback, $this->fallbackStyle); - } - - /** - * - * Enter description here ... - * - * @param string $id - */ - function setId($id) { - $this->id = is_string($id) ? trim($id) : NULL; - } - - /** - * - * Enter description here ... - * - * @param string $href - */ - function setHref($href) { - $this->href = is_string($href) ? trim($href) : NULL; - } - - /** - * - * Enter description here ... - * - * @param string $mediaType - */ - function setMediaType($mediaType) { - $this->mediaType = is_string($mediaType) ? trim($mediaType) : NULL; - } - - /** - * - * Enter description here ... - * - * @param string $properties - */ - function setProperties($properties) { - $this->properties = is_string($properties) ? trim($properties) : NULL; - } - - /** - * - * Enter description here ... - * - * @param string $requiredNamespace - */ - function setRequiredNamespace($requiredNamespace) { - $this->requiredNamespace = is_string($requiredNamespace) ? trim($requiredNamespace) : NULL; - } - - /** - * - * Enter description here ... - * - * @param string $requiredModules - */ - function setRequiredModules($requiredModules) { - $this->requiredModules = is_string($requiredModules) ? trim($requiredModules) : NULL; - } - - /** - * - * Enter description here ... - * - * @param string $fallback - */ - function setfallback($fallback) { - $this->fallback = is_string($fallback) ? trim($fallback) : NULL; - } - - /** - * - * Enter description here ... - * - * @param string $fallbackStyle - */ - function setFallbackStyle($fallbackStyle) { - $this->fallbackStyle = is_string($fallbackStyle) ? trim($fallbackStyle) : NULL; - } - - /** - * - * @param string $bookVersion - * @return string - */ - function finalize($bookVersion = EPub::BOOK_VERSION_EPUB2) { - $item = "\t\tid . "\" href=\"" . $this->href . "\" media-type=\"" . $this->mediaType . "\" "; - if ($bookVersion === EPub::BOOK_VERSION_EPUB3 && isset($this->properties)) { - $item .= "properties=\"" . $this->properties . "\" "; - } - if (isset($this->requiredNamespace)) { - $item .= "\n\t\t\trequired-namespace=\"" . $this->requiredNamespace . "\" "; - if (isset($this->requiredModules)) { - $item .= "required-modules=\"" . $this->requiredModules . "\" "; - } - } - if (isset($this->fallback)) { - $item .= "\n\t\t\tfallback=\"" . $this->fallback . "\" "; - } - if (isset($this->fallbackStyle)) { - $item .= "\n\t\t\tfallback-style=\"" . $this->fallbackStyle . "\" "; - } - return $item . "/>\n"; - } -} - -/** - * ePub OPF Spine structure - */ -class Spine { - const _VERSION = 1.00; - - private $itemrefs = array(); - private $toc = NULL; - - /** - * Class constructor. - * - * @return void - */ - function __construct($toc = "ncx") { - $this->setToc($toc); - } - - /** - * Class destructor - * - * @return void - */ - function __destruct() { - unset ($this->itemrefs, $this->toc); - } - - /** - * - * Enter description here ... - * - * @param string $toc - */ - function setToc($toc) { - $this->toc = is_string($toc) ? trim($toc) : NULL; - } - - /** - * - * Enter description here ... - * - * @param Itemref $itemref - */ - function addItemref($itemref) { - if ($itemref != NULL - && is_object($itemref) - && get_class($itemref) === "Itemref" - && !isset($this->itemrefs[$itemref->getIdref()])) { - $this->itemrefs[$itemref->getIdref()] = $itemref; - } - } - - /** - * - * Enter description here ... - * - * @return string - */ - function finalize() { - $spine = "\n\ttoc . "\">\n"; - foreach ($this->itemrefs as $itemref) { - $spine .= $itemref->finalize(); - } - return $spine . "\t\n"; - } -} - -/** - * ePub OPF ItemRef structure - */ -class Itemref { - const _VERSION = 3.00; - - private $idref = NULL; - private $linear = TRUE; - - /** - * Class constructor. - * - * @return void - */ - function __construct($idref, $linear = TRUE) { - $this->setIdref($idref); - $this->setLinear($linear); - } - - /** - * Class destructor - * - * @return void - */ - function __destruct() { - unset ($this->idref, $this->linear); - } - - /** - * - * Enter description here ... - * - * @param string $idref - */ - function setIdref($idref) { - $this->idref = is_string($idref) ? trim($idref) : NULL; - } - - /** - * - * Enter description here ... - * - * @return string $idref - */ - function getIdref() { - return $this->idref; - } - - /** - * - * Enter description here ... - * - * @param bool $linear - */ - function setLinear($linear = TRUE) { - $this->linear = $linear === TRUE; - } - - /** - * - * Enter description here ... - * - * @return string - */ - function finalize() { - $itemref = "\t\tidref . "\""; - if ($this->linear == FALSE) { - return $itemref .= " linear=\"no\" />\n"; - } - return $itemref . " />\n"; - } -} - -/** - * ePub OPF Guide structure - */ -class Guide { - const _VERSION = 3.00; - - private $references = array(); - - /** - * Class constructor. - * - * @return void - */ - function __construct() { - } - - /** - * Class destructor - * - * @return void - */ - function __destruct() { - unset ($this->references); - } - - /** - * - * Enter description here ... - * - */ - function length() { - return sizeof($this->references); - } - - /** - * - * Enter description here ... - * - * @param Reference $reference - */ - function addReference($reference) { - if ($reference != NULL && is_object($reference) && get_class($reference) === "Reference") { - $this->references[] = $reference; - } - } - - /** - * - * Enter description here ... - * - * @return string - */ - function finalize() { - $ref = ""; - if (sizeof($this->references) > 0) { - $ref = "\n\t\n"; - foreach ($this->references as $reference) { - $ref .= $reference->finalize(); - } - $ref .= "\t\n"; - } - return $ref; - } -} - -/** - * Reference constants - */ -class Reference { - const _VERSION = 1.00; - - /* REFERENCE types are derived from the "Chicago Manual of Style" - */ - - /** Acknowledgements page */ - const ACKNOWLEDGEMENTS = "acknowledgements"; - - /** Bibliography page */ - const BIBLIOGRAPHY = "bibliography"; - - /** Colophon page */ - const COLOPHON = "colophon"; - - /** Copyright page */ - const COPYRIGHT_PAGE = "copyright-page"; - - /** Dedication */ - const DEDICATION = "dedication"; - - /** Epigraph */ - const EPIGRAPH = "epigraph"; - - /** Foreword */ - const FOREWORD = "foreword"; - - /** Glossary page */ - const GLOSSARY = "glossary"; - - /** back-of-book style index */ - const INDEX = "index"; - - /** List of illustrations */ - const LIST_OF_ILLUSTRATIONS = "loi"; - - /** List of tables */ - const LIST_OF_TABLES = "lot"; - - /** Notes page */ - const NOTES = "notes"; - - /** Preface page */ - const PREFACE = "preface"; - - /** Table of contents */ - const TABLE_OF_CONTENTS = "toc"; - - /** Page with possibly title, author, publisher, and other metadata */ - const TITLE_PAGE = "titlepage"; - - /** First page of the book, ie. first page of the first chapter */ - const TEXT = "text"; - - // ****************** - // ePub3 constants - // ****************** - - // Document partitions - /** The publications cover(s), jacket information, etc. This is officially in ePub3, but works for ePub 2 as well */ - const COVER = "cover"; - - /** Preliminary material to the content body, such as tables of contents, dedications, etc. */ - const FRONTMATTER = "frontmatter"; - - /** The main (body) content of a document. */ - const BODYMATTER = "bodymatter"; - - /** Ancillary material occurring after the document body, such as indices, appendices, etc. */ - const BACKMATTER = "backmatter"; - - - private $type = NULL; - private $title = NULL; - private $href = NULL; - - /** - * Class constructor. - * - * @param string $type - * @param string $title - * @param string $href - */ - function __construct($type, $title, $href) { - $this->setType($type); - $this->setTitle($title); - $this->setHref($href); - } - - /** - * Class destructor - * - * @return void - */ - function __destruct() { - unset ($this->type, $this->title, $this->href); - } - - /** - * - * Enter description here ... - * - * @param string $type - */ - function setType($type) { - $this->type = is_string($type) ? trim($type) : NULL; - } - - /** - * - * Enter description here ... - * - * @param string $title - */ - function setTitle($title) { - $this->title = is_string($title) ? trim($title) : NULL; - } - - /** - * - * Enter description here ... - * - * @param string $href - */ - function setHref($href) { - $this->href = is_string($href) ? trim($href) : NULL; - } - - /** - * - * Enter description here ... - * - * @return string - */ - function finalize() { - return "\t\ttype . "\" title=\"" . $this->title . "\" href=\"" . $this->href . "\" />\n"; - } -} - -/** - * Common Marc codes. - * Ref: http://www.loc.gov/marc/relators/ - */ -class MarcCode { - const _VERSION = 3.00; - - /** - * Adapter - * - * Use for a person who - * 1) reworks a musical composition, usually for a different medium, or - * 2) rewrites novels or stories for motion pictures or other audiovisual medium. - */ - const ADAPTER = "adp"; - - /** - * Annotator - * - * Use for a person who writes manuscript annotations on a printed item. - */ - const ANNOTATOR = "ann"; - - /** - * Arranger - * - * Use for a person who transcribes a musical composition, usually for a different - * medium from that of the original; in an arrangement the musical substance remains - * essentially unchanged. - */ - const ARRANGER = "arr"; - - /** - * Artist - * - * Use for a person (e.g., a painter) who conceives, and perhaps also implements, - * an original graphic design or work of art, if specific codes (e.g., [egr], - * [etr]) are not desired. For book illustrators, prefer Illustrator [ill]. - */ - const ARTIST = "art"; - - /** - * Associated name - * - * Use as a general relator for a name associated with or found in an item or - * collection, or which cannot be determined to be that of a Former owner [fmo] - * or other designated relator indicative of provenance. - */ - const ASSOCIATED_NAME = "asn"; - - /** - * Author - * - * Use for a person or corporate body chiefly responsible for the intellectual - * or artistic content of a work. This term may also be used when more than one - * person or body bears such responsibility. - */ - const AUTHOR = "aut"; - - /** - * Author in quotations or text extracts - * - * Use for a person whose work is largely quoted or extracted in a works to which - * he or she did not contribute directly. Such quotations are found particularly - * in exhibition catalogs, collections of photographs, etc. - */ - const AUTHOR_IN_QUOTES = "aqt"; - - /** - * Author of afterword, colophon, etc. - * - * Use for a person or corporate body responsible for an afterword, postface, - * colophon, etc. but who is not the chief author of a work. - */ - const AUTHOR_OF_AFTERWORD = "aft"; - - /** - * Author of introduction, etc. - * - * Use for a person or corporate body responsible for an introduction, preface, - * foreword, or other critical matter, but who is not the chief author. - */ - const AUTHOR_OF_INTRO = "aui"; - - /** - * Bibliographic antecedent - * - * Use for the author responsible for a work upon which the work represented by - * the catalog record is based. This can be appropriate for adaptations, sequels, - * continuations, indexes, etc. - */ - const BIB_ANTECEDENT = "ant"; - - /** - * Book producer - * - * Use for the person or firm responsible for the production of books and other - * print media, if specific codes (e.g., [bkd], [egr], [tyd], [prt]) are not desired. - */ - const BOOK_PRODUCER = "bkp"; - - /** - * Collaborator - * - * Use for a person or corporate body that takes a limited part in the elaboration - * of a work of another author or that brings complements (e.g., appendices, notes) - * to the work of another author. - */ - const COLABORATOR = "clb"; - - /** - * Commentator - * - * Use for a person who provides interpretation, analysis, or a discussion of the - * subject matter on a recording, motion picture, or other audiovisual medium. - * Compiler [com] Use for a person who produces a work or publication by selecting - * and putting together material from the works of various persons or bodies. - */ - const COMMENTATOR = "cmm"; - - /** - * Designer - * - * Use for a person or organization responsible for design if specific codes (e.g., - * [bkd], [tyd]) are not desired. - */ - const DESIGNER = "dsr"; - - /** - * Editor - * - * Use for a person who prepares for publication a work not primarily his/her own, - * such as by elucidating text, adding introductory or other critical matter, or - * technically directing an editorial staff. - */ - const EDITORT = "edt"; - - /** - * Illustrator - * - * Use for the person who conceives, and perhaps also implements, a design or - * illustration, usually to accompany a written text. - */ - const ILLUSTRATOR = "ill"; - - /** - * Lyricist - * - * Use for the writer of the text of a song. - */ - const LYRICIST = "lyr"; - - /** - * Metadata contact - * - * Use for the person or organization primarily responsible for compiling and - * maintaining the original description of a metadata set (e.g., geospatial - * metadata set). - */ - const METADATA_CONTACT = "mdc"; - - /** - * Musician - * - * Use for the person who performs music or contributes to the musical content - * of a work when it is not possible or desirable to identify the function more - * precisely. - */ - const MUSICIAN = "mus"; - - /** - * Narrator - * - * Use for the speaker who relates the particulars of an act, occurrence, or - * course of events. - */ - const NARRATOR = "nrt"; - - /** - * Other - * - * Use for relator codes from other lists which have no equivalent in the MARC - * list or for terms which have not been assigned a code. - */ - const OTHER = "oth"; - - /** - * Photographer - * - * Use for the person or organization responsible for taking photographs, whether - * they are used in their original form or as reproductions. - */ - const PHOTOGRAPHER = "pht"; - - /** - * Printer - * - * Use for the person or organization who prints texts, whether from type or plates. - */ - const PRINTER = "prt"; - - /** - * Redactor - * - * Use for a person who writes or develops the framework for an item without - * being intellectually responsible for its content. - */ - const REDACTOR = "red"; - - /** - * Reviewer - * - * Use for a person or corporate body responsible for the review of book, motion - * picture, performance, etc. - */ - const REVIEWER = "rev"; - - /** - * Sponsor - * - * Use for the person or agency that issued a contract, or under whose auspices - * a work has been written, printed, published, etc. - */ - const SPONSOR = "spn"; - - /** - * Thesis advisor - * - * Use for the person under whose supervision a degree candidate develops and - * presents a thesis, memoir, or text of a dissertation. - */ - const THESIS_ADVISOR = "ths"; - - /** - * Transcriber - * - * Use for a person who prepares a handwritten or typewritten copy from original - * material, including from dictated or orally recorded material. - */ - const TRANSCRIBER = "trc"; - - /** - * Translator - * - * Use for a person who renders a text from one language into another, or from - * an older form of a language into the modern form. - */ - const TRANSLATOR = "trl"; -} -?> diff --git a/inc/3rdparty/libraries/PHPePub/EPub.php b/inc/3rdparty/libraries/PHPePub/EPub.php deleted file mode 100644 index d9b990b7..00000000 --- a/inc/3rdparty/libraries/PHPePub/EPub.php +++ /dev/null @@ -1,2438 +0,0 @@ - - * @copyright 2009-2014 A. Grandt - * @license GNU LGPL 2.1 - * @version 3.20 - * @link http://www.phpclasses.org/package/6115 - * @link https://github.com/Grandt/PHPePub - * @uses Zip.php version 1.50; http://www.phpclasses.org/browse/package/6110.html or https://github.com/Grandt/PHPZip - */ -class EPub { - const VERSION = 3.20; - const REQ_ZIP_VERSION = 1.60; - - const IDENTIFIER_UUID = 'UUID'; - const IDENTIFIER_URI = 'URI'; - const IDENTIFIER_ISBN = 'ISBN'; - - /** Ignore all external references, and do not process the file for these */ - const EXTERNAL_REF_IGNORE = 0; - /** Process the file for external references and add them to the book */ - const EXTERNAL_REF_ADD = 1; - /** Process the file for external references and add them to the book, but remove images, and img tags */ - 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] */ - const EXTERNAL_REF_REPLACE_IMAGES = 3; - - const DIRECTION_LEFT_TO_RIGHT = "ltr"; - const DIRECTION_RIGHT_TO_LEFT = "rtl"; - - const BOOK_VERSION_EPUB2 = "2.0"; - const BOOK_VERSION_EPUB3 = "3.0"; - - private $bookVersion = EPub::BOOK_VERSION_EPUB2; - - private $debugInside = FALSE; - - public $maxImageWidth = 768; - public $maxImageHeight = 1024; - - public $splitDefaultSize = 250000; - /** 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. - */ - public $isGifImagesEnabled = FALSE; - public $isReferencesAddedToToc = TRUE; - - 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 $opf = NULL; - private $ncx = NULL; - private $isFinalized = FALSE; - private $isCoverImageSet = FALSE; - private $buildTOC = FALSE; - private $tocTitle = NULL; - private $tocFileName = NULL; - private $tocCSSClass = NULL; - private $tocAddReferences = FALSE; - private $tocCssFileName = NULL; - - private $fileList = array(); - private $writingDirection = EPub::DIRECTION_LEFT_TO_RIGHT; - private $languageCode = "en"; - - /** - * Used for building the TOC. - * If this list is overwritten it MUST contain at least "text" as an element. - */ - public $referencesOrder = NULL; - - private $dateformat = 'Y-m-d\TH:i:s.000000P'; // ISO 8601 long - private $dateformatShort = 'Y-m-d'; // short date format to placate ePubChecker. - private $headerDateFormat = "D, d M Y H:i:s T"; - - protected $isCurlInstalled; - protected $isGdInstalled; - protected $isExifInstalled; - protected $isFileGetContentsInstalled; - protected $isFileGetContentsExtInstalled; - - private $bookRoot = "OEBPS/"; - private $docRoot = NULL; - private $EPubMark = TRUE; - private $generator = ""; - - private $log = NULL; - public $isLogging = TRUE; - - public $encodeHTML = FALSE; - - private $mimetypes = array( - "js" => "application/x-javascript", "swf" => "application/x-shockwave-flash", "xht" => "application/xhtml+xml", "xhtml" => "application/xhtml+xml", "zip" => "application/zip", - "aif" => "audio/x-aiff", "aifc" => "audio/x-aiff", "aiff" => "audio/x-aiff", "au" => "audio/basic", "kar" => "audio/midi", "m3u" => "audio/x-mpegurl", "mid" => "audio/midi", "midi" => "audio/midi", "mp2" => "audio/mpeg", "mp3" => "audio/mpeg", "mpga" => "audio/mpeg", "oga" => "audio/ogg", "ogg" => "audio/ogg", "ra" => "audio/x-realaudio", "ram" => "audio/x-pn-realaudio", "rm" => "audio/x-pn-realaudio", "rpm" => "audio/x-pn-realaudio-plugin", "snd" => "audio/basic", "wav" => "audio/x-wav", - "bmp" => "image/bmp", "djv" => "image/vnd.djvu", "djvu" => "image/vnd.djvu", "gif" => "image/gif", "ief" => "image/ief", "jpe" => "image/jpeg", "jpeg" => "image/jpeg", "jpg" => "image/jpeg", "pbm" => "image/x-portable-bitmap", "pgm" => "image/x-portable-graymap", "png" => "image/png", "pnm" => "image/x-portable-anymap", "ppm" => "image/x-portable-pixmap", "ras" => "image/x-cmu-raster", "rgb" => "image/x-rgb", "tif" => "image/tif", "tiff" => "image/tiff", "wbmp" => "image/vnd.wap.wbmp", "xbm" => "image/x-xbitmap", "xpm" => "image/x-xpixmap", "xwd" => "image/x-windowdump", - "asc" => "text/plain", "css" => "text/css", "etx" => "text/x-setext", "htm" => "text/html", "html" => "text/html", "rtf" => "text/rtf", "rtx" => "text/richtext", "sgm" => "text/sgml", "sgml" => "text/sgml", "tsv" => "text/tab-seperated-values", "txt" => "text/plain", "wml" => "text/vnd.wap.wml", "wmls" => "text/vnd.wap.wmlscript", "xml" => "text/xml", "xsl" => "text/xml", - "avi" => "video/x-msvideo", "mov" => "video/quicktime", "movie" => "video/x-sgi-movie", "mp4" => "video/mp4", "mpe" => "video/mpeg", "mpeg" => "video/mpeg", "mpg" => "video/mpeg", "mxu" => "video/vnd.mpegurl", "ogv" => "video/ogg", "qt" => "video/quicktime", "webm" => "video/webm"); - - // These are the ONLY allowed types in that these are the ones ANY reader must support, any other MUST have the fallback attribute pointing to one of these. - private $coreMediaTypes = array("image/gif", "image/jpeg", "image/png", "image/svg+xml", "application/xhtml+xml", "application/x-dtbook+xml", "application/xml", "application/x-dtbncx+xml", "text/css", "text/x-oeb1-css", "text/x-oeb1-document"); - - private $opsContentTypes = array("application/xhtml+xml", "application/x-dtbook+xml", "application/xml", "application/x-dtbncx+xml", "text/x-oeb1-document"); - - private $forbiddenCharacters = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", "%"); - - private $htmlContentHeader = "\n\n\n\n\n\n\n"; - private $htmlContentFooter = "\n\n"; - - /** - * Class constructor. - * - * @return void - */ - function __construct($bookVersion = EPub::BOOK_VERSION_EPUB2, $debugInside = FALSE, $languageCode = "en", $writingDirection = EPub::DIRECTION_LEFT_TO_RIGHT) { - include_once("Zip.php"); - include_once("Logger.php"); - - if (!$debugInside) { - error_reporting(E_ERROR | E_PARSE); - } - - $this->bookVersion = $bookVersion; - $this->writingDirection = $writingDirection; - $this->languageCode = $languageCode; - - $this->log = new Logger("EPub", $this->isLogging); - - /* Prepare Logging. Just in case it's used. later */ - if ($this->isLogging) { - $this->log->logLine("EPub class version....: " . self::VERSION); - $this->log->logLine("EPub req. Zip version.: " . self::REQ_ZIP_VERSION); - $this->log->logLine("Zip version...........: " . Zip::VERSION); - $this->log->dumpInstalledModules(); - } - - if (!defined("Zip::VERSION") || Zip::VERSION < self::REQ_ZIP_VERSION) { - die("

    EPub version " . self::VERSION . " requires Zip.php at version " . self::REQ_ZIP_VERSION . " or higher.
    You can obtain the latest version from http://www.phpclasses.org/browse/package/6110.html.

    "); - } - - include_once("EPubChapterSplitter.php"); - include_once("EPub.HtmlEntities.php"); - include_once("EPub.NCX.php"); - include_once("EPub.OPF.php"); - - $this->initialize(); - } - - /** - * Class destructor - * - * @return void - * @TODO make sure elements in the destructor match the current class elements - */ - function __destruct() { - unset($this->bookVersion, $this->maxImageWidth, $this->maxImageHeight); - unset($this->splitDefaultSize, $this->isGifImagesEnabled, $this->isReferencesAddedToToc); - unset($this->zip, $this->title, $this->language, $this->identifier, $this->identifierType); - unset($this->description, $this->author, $this->authorSortKey, $this->publisherName); - unset($this->publisherURL, $this->date, $this->rights, $this->coverage, $this->relation); - unset($this->sourceURL, $this->chapterCount, $this->opf, $this->ncx, $this->isFinalized); - unset($this->isCoverImageSet, $this->fileList, $this->writingDirection, $this->languageCode); - unset($this->referencesOrder, $this->dateformat, $this->dateformatShort, $this->headerDateFormat); - unset($this->isCurlInstalled, $this->isGdInstalled, $this->isExifInstalled); - unset($this->isFileGetContentsInstalled, $this->isFileGetContentsExtInstalled, $this->bookRoot); - unset($this->docRoot, $this->EPubMark, $this->generator, $this->log, $this->isLogging); - unset($this->encodeHTML, $this->mimetypes, $this->coreMediaTypes, $this->opsContentTypes); - unset($this->forbiddenCharacters, $this->htmlContentHeader, $this->htmlContentFooter); - unset($this->buildTOC, $this->tocTitle, $this->tocCSSClass, $this->tocAddReferences); - unset($this->tocFileName, $this->tocCssFileName); - } - - /** - * initialize defaults. - */ - private function initialize() { - $this->referencesOrder = array( - 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"); - - $this->docRoot = filter_input(INPUT_SERVER, "DOCUMENT_ROOT") . "/"; - - $this->isCurlInstalled = extension_loaded('curl') && function_exists('curl_version'); - $this->isGdInstalled = extension_loaded('gd') && function_exists('gd_info'); - $this->isExifInstalled = extension_loaded('exif') && function_exists('exif_imagetype'); - $this->isFileGetContentsInstalled = function_exists('file_get_contents'); - $this->isFileGetContentsExtInstalled = $this->isFileGetContentsInstalled && ini_get('allow_url_fopen'); - - $this->zip = new Zip(); - $this->zip->setExtraField(FALSE); - $this->zip->addFile("application/epub+zip", "mimetype"); - $this->zip->setExtraField(TRUE); - $this->zip->addDirectory("META-INF"); - - $this->content = "\n\n\t\n\t\tbookRoot . "book.opf\" media-type=\"application/oebps-package+xml\" />\n\t\n\n"; - - if (!$this->isEPubVersion2()) { - $this->htmlContentHeader = "\n" - . "\n" - . "" - . "\n" - . "\n" - . "\n" - . "\n"; - } - - $this->zip->addFile($this->content, "META-INF/container.xml", 0, NULL, FALSE); - $this->content = NULL; - $this->ncx = new Ncx(NULL, NULL, NULL, $this->languageCode, $this->writingDirection); - $this->opf = new Opf(); - $this->ncx->setVersion($this->bookVersion); - $this->opf->setVersion($this->bookVersion); - $this->opf->addItem("ncx", "book.ncx", Ncx::MIMETYPE); - $this->chapterCount = 0; - } - - /** - * Add dynamically generated data as a file to the book. - * - * @param string $fileName Filename to use for the file, must be unique for the book. - * @param string $fileId Unique identifier for the file. - * @param string $fileData File data - * @param string $mimetype file mime type - * @return bool $success - */ - function addFile($fileName, $fileId, $fileData, $mimetype) { - if ($this->isFinalized || array_key_exists($fileName, $this->fileList)) { - return FALSE; - } - - $fileName = $this->normalizeFileName($fileName); - - $compress = (strpos($mimetype, "image/") !== 0); - - $this->zip->addFile($fileData, $this->bookRoot.$fileName, 0, NULL, $compress); - $this->fileList[$fileName] = $fileName; - $this->opf->addItem($fileId, $fileName, $mimetype); - return TRUE; - } - - /** - * Add a large file directly from the filestystem to the book. - * - * @param string $fileName Filename to use for the file, must be unique for the book. - * @param string $fileId Unique identifier for the file. - * @param string $filePath File path - * @param string $mimetype file mime type - * @return bool $success - */ - function addLargeFile($fileName, $fileId, $filePath, $mimetype) { - if ($this->isFinalized || array_key_exists($fileName, $this->fileList)) { - return FALSE; - } - $fileName = $this->normalizeFileName($fileName); - - if ($this->zip->addLargeFile($filePath, $this->bookRoot.$fileName)) { - $this->fileList[$fileName] = $fileName; - $this->opf->addItem($fileId, $fileName, $mimetype); - return TRUE; - } - return FALSE; - } - - /** - * Add a CSS file to the book. - * - * @param string $fileName Filename to use for the CSS file, must be unique for the book. - * @param string $fileId Unique identifier for the file. - * @param string $fileData CSS data - * @param int $externalReferences How to handle external references, EPub::EXTERNAL_REF_IGNORE, EPub::EXTERNAL_REF_ADD or EPub::EXTERNAL_REF_REMOVE_IMAGES? See documentation for processCSSExternalReferences for explanation. Default is EPub::EXTERNAL_REF_IGNORE. - * @param string $baseDir Default is "", meaning it is pointing to the document root. NOT used if $externalReferences is set to EPub::EXTERNAL_REF_IGNORE. - * - * @return bool $success - */ - function addCSSFile($fileName, $fileId, $fileData, $externalReferences = EPub::EXTERNAL_REF_IGNORE, $baseDir = "") { - if ($this->isFinalized || array_key_exists($fileName, $this->fileList)) { - return FALSE; - } - $fileName = Zip::getRelativePath($fileName); - $fileName = preg_replace('#^[/\.]+#i', "", $fileName); - - if ($externalReferences !== EPub::EXTERNAL_REF_IGNORE) { - $cssDir = pathinfo($fileName); - $cssDir = preg_replace('#^[/\.]+#i', "", $cssDir["dirname"] . "/"); - if (!empty($cssDir)) { - $cssDir = preg_replace('#[^/]+/#i', "../", $cssDir); - } - - $this->processCSSExternalReferences($fileData, $externalReferences, $baseDir, $cssDir); - } - - $this->addFile($fileName, "css_" . $fileId, $fileData, "text/css"); - - return TRUE; - } - - /** - * Add a chapter to the book, as a chapter should not exceed 250kB, you can parse an array with multiple parts as $chapterData. - * These will still only show up as a single chapter in the book TOC. - * - * @param string $chapterName Name of the chapter, will be use din the TOC - * @param string $fileName Filename to use for the chapter, must be unique for the book. - * @param string $chapter Chapter text in XHTML or array $chapterData valid XHTML data for the chapter. File should NOT exceed 250kB. - * @param bool $autoSplit Should the chapter be split if it exceeds the default split size? Default=FALSE, only used if $chapterData is a string. - * @param int $externalReferences How to handle external references, EPub::EXTERNAL_REF_IGNORE, EPub::EXTERNAL_REF_ADD or EPub::EXTERNAL_REF_REMOVE_IMAGES? See documentation for processChapterExternalReferences for explanation. Default is EPub::EXTERNAL_REF_IGNORE. - * @param string $baseDir Default is "", meaning it is pointing to the document root. NOT used if $externalReferences is set to EPub::EXTERNAL_REF_IGNORE. - * @return mixed $success FALSE if the addition failed, else the new NavPoint. - */ - function addChapter($chapterName, $fileName, $chapterData = NULL, $autoSplit = FALSE, $externalReferences = EPub::EXTERNAL_REF_IGNORE, $baseDir = "") { - if ($this->isFinalized) { - return FALSE; - } - $fileName = Zip::getRelativePath($fileName); - $fileName = preg_replace('#^[/\.]+#i', "", $fileName); - $fileName = $this->sanitizeFileName($fileName); - - $chapter = $chapterData; - if ($autoSplit && is_string($chapterData) && mb_strlen($chapterData) > $this->splitDefaultSize) { - $splitter = new EPubChapterSplitter(); - - $chapterArray = $splitter->splitChapter($chapterData); - if (count($chapterArray) > 1) { - $chapter = $chapterArray; - } - } - - if (!empty($chapter) && is_string($chapter)) { - if ($externalReferences !== EPub::EXTERNAL_REF_IGNORE) { - $htmlDirInfo = pathinfo($fileName); - $htmlDir = preg_replace('#^[/\.]+#i', "", $htmlDirInfo["dirname"] . "/"); - $this->processChapterExternalReferences($chapter, $externalReferences, $baseDir, $htmlDir); - } - - if ($this->encodeHTML === TRUE) { - $chapter = $this->encodeHtml($chapter); - } - - $this->chapterCount++; - $this->addFile($fileName, "chapter" . $this->chapterCount, $chapter, "application/xhtml+xml"); - $this->opf->addItemRef("chapter" . $this->chapterCount); - - $navPoint = new NavPoint($this->decodeHtmlEntities($chapterName), $fileName, "chapter" . $this->chapterCount); - $this->ncx->addNavPoint($navPoint); - $this->ncx->chapterList[$chapterName] = $navPoint; - } else if (is_array($chapter)) { - $fileNameParts = pathinfo($fileName); - $extension = $fileNameParts['extension']; - $name = $fileNameParts['filename']; - - $partCount = 0; - $this->chapterCount++; - - $oneChapter = each($chapter); - while ($oneChapter) { - list($k, $v) = $oneChapter; - if ($this->encodeHTML === TRUE) { - $v = $this->encodeHtml($v); - } - - if ($externalReferences !== EPub::EXTERNAL_REF_IGNORE) { - $this->processChapterExternalReferences($v, $externalReferences, $baseDir); - } - $partCount++; - $partName = $name . "_" . $partCount; - $this->addFile($partName . "." . $extension, $partName, $v, "application/xhtml+xml"); - $this->opf->addItemRef($partName); - - $oneChapter = each($chapter); - } - $partName = $name . "_1." . $extension; - $navPoint = new NavPoint($this->decodeHtmlEntities($chapterName), $partName, $partName); - $this->ncx->addNavPoint($navPoint); - - $this->ncx->chapterList[$chapterName] = $navPoint; - } else if (!isset($chapterData) && strpos($fileName, "#") > 0) { - $this->chapterCount++; - //$this->opf->addItemRef("chapter" . $this->chapterCount); - - $navPoint = new NavPoint($this->decodeHtmlEntities($chapterName), $fileName, "chapter" . $this->chapterCount); - $this->ncx->addNavPoint($navPoint); - $this->ncx->chapterList[$chapterName] = $navPoint; - } else if (!isset($chapterData) && $fileName=="TOC.xhtml") { - $this->chapterCount++; - $this->opf->addItemRef("toc"); - - $navPoint = new NavPoint($this->decodeHtmlEntities($chapterName), $fileName, "chapter" . $this->chapterCount); - $this->ncx->addNavPoint($navPoint); - $this->ncx->chapterList[$chapterName] = $navPoint; - } - return $navPoint; - } - - /** - * Add one chapter level. - * - * Subsequent chapters will be added to this level. - * - * @param string $navTitle - * @param string $navId - * @param string $navClass - * @param int $isNavHidden - * @param string $writingDirection - * @return NavPoint The new NavPoint for that level. - */ - function subLevel($navTitle = NULL, $navId = NULL, $navClass = NULL, $isNavHidden = FALSE, $writingDirection = NULL) { - return $this->ncx->subLevel($this->decodeHtmlEntities($navTitle), $navId, $navClass, $isNavHidden, $writingDirection); - } - - /** - * Step back one chapter level. - * - * Subsequent chapters will be added to this chapters parent level. - */ - function backLevel() { - $this->ncx->backLevel(); - } - - /** - * Step back to the root level. - * - * Subsequent chapters will be added to the rooot NavMap. - */ - function rootLevel() { - $this->ncx->rootLevel(); - } - - /** - * Step back to the given level. - * Useful for returning to a previous level from deep within the structure. - * Values below 2 will have the same effect as rootLevel() - * - * @param int $newLevel - */ - function setCurrentLevel($newLevel) { - $this->ncx->setCurrentLevel($newLevel); - } - - /** - * Get current level count. - * The indentation of the current structure point. - * - * @return current level count; - */ - function getCurrentLevel() { - return $this->ncx->getCurrentLevel(); - } - - /** - * Wrap ChapterContent with Head and Footer - * - * @param $content - * @return string $content - */ - private function wrapChapter($content) { - return $this->htmlContentHeader . "\n" . $content . "\n" . $this->htmlContentFooter; - } - - /** - * Reference pages is usually one or two pages for items such as Table of Contents, reference lists, Author notes or Acknowledgements. - * These do not show up in the regular navigation list. - * - * As they are supposed to be short. - * - * @param string $pageName Name of the chapter, will be use din the TOC - * @param string $fileName Filename to use for the chapter, must be unique for the book. - * @param string $pageData Page content in XHTML. File should NOT exceed 250kB. - * @param string $reference Reference key - * @param int $externalReferences How to handle external references. See documentation for processChapterExternalReferences for explanation. Default is EPub::EXTERNAL_REF_IGNORE. - * @param string $baseDir Default is "", meaning it is pointing to the document root. NOT used if $externalReferences is set to EPub::EXTERNAL_REF_IGNORE. - * @return bool $success - */ - function addReferencePage($pageName, $fileName, $pageData, $reference, $externalReferences = EPub::EXTERNAL_REF_IGNORE, $baseDir = "") { - if ($this->isFinalized) { - return FALSE; - } - $fileName = Zip::getRelativePath($fileName); - $fileName = preg_replace('#^[/\.]+#i', "", $fileName); - - - if (!empty($pageData) && is_string($pageData)) { - if ($this->encodeHTML === TRUE) { - $pageData = $this->encodeHtml($pageData); - } - - $this->wrapChapter($pageData); - - if ($externalReferences !== EPub::EXTERNAL_REF_IGNORE) { - $htmlDirInfo = pathinfo($fileName); - $htmlDir = preg_replace('#^[/\.]+#i', "", $htmlDirInfo["dirname"] . "/"); - $this->processChapterExternalReferences($pageData, $externalReferences, $baseDir, $htmlDir); - } - - $this->addFile($fileName, "ref_" . $reference, $pageData, "application/xhtml+xml"); - - if ($reference !== Reference::TABLE_OF_CONTENTS || !isset($this->ncx->referencesList[$reference])) { - $this->opf->addItemRef("ref_" . $reference, FALSE); - $this->opf->addReference($reference, $pageName, $fileName); - - $this->ncx->referencesList[$reference] = $fileName; - $this->ncx->referencesName[$reference] = $pageName; - } - return TRUE; - } - return TRUE; - } - - /** - * Add custom metadata to the book. - * - * It is up to the builder to make sure there are no collisions. Metadata are just key value pairs. - * - * @param string $name - * @param string $content - */ - function addCustomMetadata($name, $content) { - $this->opf->addMeta($name, $content); - } - - /** - * Add DublinCore metadata to the book - * - * Use the DublinCore constants included in EPub, ie DublinCore::DATE - * - * @param string $dublinCore name - * @param string $value - */ - function addDublinCoreMetadata($dublinCoreConstant, $value) { - if ($this->isFinalized) { - return; - } - - $this->opf->addDCMeta($dublinCoreConstant, $this->decodeHtmlEntities($value)); - } - - /** - * Add a cover image to the book. - * If the $imageData is not set, the function assumes the $fileName is the path to the image file. - * - * The styling and structure of the generated XHTML is heavily inspired by the XHTML generated by Calibre. - * - * @param string $fileName Filename to use for the image, must be unique for the book. - * @param string $imageData Binary image data - * @param string $mimetype Image mimetype, such as "image/jpeg" or "image/png". - * @return bool $success - */ - function setCoverImage($fileName, $imageData = NULL, $mimetype = NULL,$bookTitle) { - if ($this->isFinalized || $this->isCoverImageSet || array_key_exists("CoverPage.html", $this->fileList)) { - return FALSE; - } - - if ($imageData == NULL) { - // assume $fileName is the valid file path. - if (!file_exists($fileName)) { - // Attempt to locate the file using the doc root. - $rp = realpath($this->docRoot . "/" . $fileName); - - if ($rp !== FALSE) { - // only assign the docroot path if it actually exists there. - $fileName = $rp; - } - } - $image = $this->getImage($fileName); - $imageData = $image['image']; - $mimetype = $image['mime']; - $fileName = preg_replace("#\.[^\.]+$#", "." . $image['ext'], $fileName); - } - - - $path = pathinfo($fileName); - $imgPath = "images/" . $path["basename"]; - - if (empty($mimetype) && file_exists($fileName)) { - list($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; - } - - $coverPage = ""; - - if ($this->isEPubVersion2()) { - $coverPage = "\n" - . "\n" - . "\n" - . "\t\n" - . "\t\t\n" - . "\t\tCover Image\n" - . "\t\t\n" - . "\t\n" - . "\t\n" - . "\t" . $bookTitle . "\n" - . "\t\t
    \n" - . "\t\t\t\"Cover\n" - . "\t\t
    \n" - . "\t\n" - . "\n"; - } else { - $coverPage = "\n" - . "\n" - . "" - . "\t\n" - . "\t\tCover Image\n" - . "\t\t\n" - . "\t\n" - . "\t\n" - . "\t\t
    \n" - . "\t" . $bookTitle . "\n" - . "\t\t\t\"Cover\n" - . "\t\t
    \n" - . "\t\n" - . "\n"; - } - $coverPageCss = "@page, body, div, img {\n" - . "\tpadding: 0pt;\n" - . "\tmargin:0pt;\n" - . "}\n\nbody {\n" - . "\ttext-align: center;\n" - . "}\n"; - - $this->addCSSFile("Styles/CoverPage.css", "CoverPageCss", $coverPageCss); - $this->addFile($imgPath, "CoverImage", $imageData, $mimetype); - $this->addReferencePage("CoverPage", "CoverPage.xhtml", $coverPage, "cover"); - $this->isCoverImageSet = TRUE; - return TRUE; - } - - /** - * Process external references from a HTML to the book. The chapter itself is not stored. - * the HTML is scanned for <link..., <style..., and <img tags. - * Embedded CSS styles and links will also be processed. - * Script tags are not processed, as scripting should be avoided in e-books. - * - * EPub keeps track of added files, and duplicate files referenced across multiple - * chapters, are only added once. - * - * If the $doc is a string, it is assumed to be the content of an HTML file, - * else is it assumes to be a DOMDocument. - * - * Basedir is the root dir the HTML is supposed to "live" in, used to resolve - * relative references such as <img src="../images/image.png"/> - * - * $externalReferences determines how the function will handle external references. - * - * @param mixed &$doc (referenced) - * @param int $externalReferences How to handle external references, EPub::EXTERNAL_REF_IGNORE, EPub::EXTERNAL_REF_ADD or EPub::EXTERNAL_REF_REMOVE_IMAGES? Default is EPub::EXTERNAL_REF_ADD. - * @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 FALSE if uncuccessful (book is finalized or $externalReferences == EXTERNAL_REF_IGNORE). - */ - protected function processChapterExternalReferences(&$doc, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $htmlDir = "") { - if ($this->isFinalized || $externalReferences === EPub::EXTERNAL_REF_IGNORE) { - return FALSE; - } - - $backPath = preg_replace('#[^/]+/#i', "../", $htmlDir); - $isDocAString = is_string($doc); - $xmlDoc = NULL; - - if ($isDocAString) { - $xmlDoc = new DOMDocument(); - @$xmlDoc->loadHTML($doc); - } else { - $xmlDoc = $doc; - } - - $this->processChapterStyles($xmlDoc, $externalReferences, $baseDir, $htmlDir); - $this->processChapterLinks($xmlDoc, $externalReferences, $baseDir, $htmlDir, $backPath); - $this->processChapterImages($xmlDoc, $externalReferences, $baseDir, $htmlDir, $backPath); - $this->processChapterSources($xmlDoc, $externalReferences, $baseDir, $htmlDir, $backPath); - - if ($isDocAString) { - //$html = $xmlDoc->saveXML(); - - $htmlNode = $xmlDoc->getElementsByTagName("html"); - $headNode = $xmlDoc->getElementsByTagName("head"); - $bodyNode = $xmlDoc->getElementsByTagName("body"); - - $htmlNS = ""; - 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\""; - } - } - - $xml = new DOMDocument('1.0', "utf-8"); - $xml->lookupPrefix("http://www.w3.org/1999/xhtml"); - $xml->preserveWhiteSpace = FALSE; - $xml->formatOutput = TRUE; - - $xml2Doc = new DOMDocument('1.0', "utf-8"); - $xml2Doc->lookupPrefix("http://www.w3.org/1999/xhtml"); - $xml2Doc->loadXML("\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)); - - // force pretty printing and correct formatting, should not be needed, but it is. - $xml->loadXML($xml2Doc->saveXML()); - $doc = $xml->saveXML(); - - if (!$this->isEPubVersion2()) { - $doc = preg_replace('#^\s*\s*#im', '', $doc); - } - } - return TRUE; - } - - /** - * Process images referenced from an CSS file to the book. - * - * $externalReferences determins how the function will handle external references. - * - * @param string &$cssFile (referenced) - * @param int $externalReferences How to handle external references, EPub::EXTERNAL_REF_IGNORE, EPub::EXTERNAL_REF_ADD or EPub::EXTERNAL_REF_REMOVE_IMAGES? Default is EPub::EXTERNAL_REF_ADD. - * @param string $baseDir Default is "", meaning it is pointing to the document root. - * @param string $cssDir The of the CSS file's directory from the root of the archive. - * - * @return bool FALSE if unsuccessful (book is finalized or $externalReferences == EXTERNAL_REF_IGNORE). - */ - protected function processCSSExternalReferences(&$cssFile, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $cssDir = "") { - if ($this->isFinalized || $externalReferences === EPub::EXTERNAL_REF_IGNORE) { - return FALSE; - } - - $backPath = preg_replace('#[^/]+/#i', "../", $cssDir); - $imgs = null; - preg_match_all('#url\s*\([\'\"\s]*(.+?)[\'\"\s]*\)#im', $cssFile, $imgs, PREG_SET_ORDER); - - $itemCount = count($imgs); - 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); - } else { - $source = $img[1]; - - $pathData = pathinfo($source); - $internalSrc = $pathData['basename']; - $internalPath = ""; - $isSourceExternal = FALSE; - - if ($this->resolveImage($source, $internalPath, $internalSrc, $isSourceExternal, $baseDir, $cssDir, $backPath)) { - $cssFile = str_replace($img[0], "url('" . $backPath . $internalPath . "')", $cssFile); - } else if ($isSourceExternal) { - $cssFile = str_replace($img[0], "", $cssFile); // External image is missing - } // else do nothing, if the image is local, and missing, assume it's been generated. - } - } - return TRUE; - } - - /** - * Process style tags in a DOMDocument. Styles will be passed as CSS files and reinserted into the document. - * - * @param DOMDocument &$xmlDoc (referenced) - * @param int $externalReferences How to handle external references, EPub::EXTERNAL_REF_IGNORE, EPub::EXTERNAL_REF_ADD or EPub::EXTERNAL_REF_REMOVE_IMAGES? Default is EPub::EXTERNAL_REF_ADD. - * @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 FALSE if uncuccessful (book is finalized or $externalReferences == EXTERNAL_REF_IGNORE). - */ - protected function processChapterStyles(&$xmlDoc, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $htmlDir = "") { - 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++) { - $style = $styles->item($styleIdx); - - $styleData = preg_replace('#[/\*\s]*\<\!\[CDATA\[[\s\*/]*#im', "", $style->nodeValue); - $styleData = preg_replace('#[/\*\s]*\]\]\>[\s\*/]*#im', "", $styleData); - - $this->processCSSExternalReferences($styleData, $externalReferences, $baseDir, $htmlDir); - $style->nodeValue = "\n" . trim($styleData) . "\n"; - } - return TRUE; - } - - /** - * Process link tags in a DOMDocument. Linked files will be loaded into the archive, and the link src will be rewritten to point to that location. - * Link types text/css will be passed as CSS files. - * - * @param DOMDocument &$xmlDoc (referenced) - * @param int $externalReferences How to handle external references, EPub::EXTERNAL_REF_IGNORE, EPub::EXTERNAL_REF_ADD or EPub::EXTERNAL_REF_REMOVE_IMAGES? Default is EPub::EXTERNAL_REF_ADD. - * @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. - * @param string $backPath The path to get back to the root of the archive from $htmlDir. - * - * @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 = "") { - 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++) { - $link = $links->item($linkIdx); - $source = $link->attributes->getNamedItem("href")->nodeValue; - $sourceData = NULL; - - $pathData = pathinfo($source); - $internalSrc = $pathData['basename']; - - if (preg_match('#^(http|ftp)s?://#i', $source) == 1) { - $urlinfo = parse_url($source); - - if (strpos($urlinfo['path'], $baseDir."/") !== FALSE) { - $internalSrc = substr($urlinfo['path'], strpos($urlinfo['path'], $baseDir."/") + strlen($baseDir) + 1); - } - - @$sourceData = getFileContents($source); - } else if (strpos($source, "/") === 0) { - @$sourceData = file_get_contents($this->docRoot . $source); - } else { - @$sourceData = file_get_contents($this->docRoot . $baseDir . "/" . $source); - } - - if (!empty($sourceData)) { - if (!array_key_exists($internalSrc, $this->fileList)) { - $mime = $link->attributes->getNamedItem("type")->nodeValue; - 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); - $link->setAttribute("href", $backPath . $internalSrc); - } else { - $this->addFile($internalSrc, $internalSrc, $sourceData, $mime); - } - $this->fileList[$internalSrc] = $source; - } else { - $link->setAttribute("href", $backPath . $internalSrc); - } - } // else do nothing, if the link is local, and missing, assume it's been generated. - } - return TRUE; - } - - /** - * Process img tags in a DOMDocument. - * $externalReferences will determine what will happen to these images, and the img src will be rewritten accordingly. - * - * @param DOMDocument &$xmlDoc (referenced) - * @param int $externalReferences How to handle external references, EPub::EXTERNAL_REF_IGNORE, EPub::EXTERNAL_REF_ADD or EPub::EXTERNAL_REF_REMOVE_IMAGES? Default is EPub::EXTERNAL_REF_ADD. - * @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. - * @param string $backPath The path to get back to the root of the archive from $htmlDir. - * - * @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 = "") { - if ($this->isFinalized || $externalReferences === EPub::EXTERNAL_REF_IGNORE) { - return FALSE; - } - // process img tags. - $postProcDomElememts = array(); - $images = $xmlDoc->getElementsByTagName("img"); - $itemCount = $images->length; - - for ($idx = 0; $idx < $itemCount; $idx++) { - $img = $images->item($idx); - - if ($externalReferences === EPub::EXTERNAL_REF_REMOVE_IMAGES) { - $postProcDomElememts[] = $img; - } 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[] = array($img, $this->createDomFragment($xmlDoc, "[" . $alt . "]")); - } else { - $source = $img->attributes->getNamedItem("src")->nodeValue; - - $parsedSource = parse_url($source); - $internalSrc = $this->sanitizeFileName(urldecode(pathinfo($parsedSource['path'], PATHINFO_BASENAME))); - $internalPath = ""; - $isSourceExternal = FALSE; - - if ($this->resolveImage($source, $internalPath, $internalSrc, $isSourceExternal, $baseDir, $htmlDir, $backPath)) { - $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. - } - } - - foreach ($postProcDomElememts as $target) { - if (is_array($target)) { - $target[0]->parentNode->replaceChild($target[1], $target[0]); - } else { - $target->parentNode->removeChild($target); - } - } - return TRUE; - } - - /** - * Process source tags in a DOMDocument. - * $externalReferences will determine what will happen to these images, and the img src will be rewritten accordingly. - * - * @param DOMDocument &$xmlDoc (referenced) - * @param int $externalReferences How to handle external references, EPub::EXTERNAL_REF_IGNORE, EPub::EXTERNAL_REF_ADD or EPub::EXTERNAL_REF_REMOVE_IMAGES? Default is EPub::EXTERNAL_REF_ADD. - * @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. - * @param string $backPath The path to get back to the root of the archive from $htmlDir. - * - * @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 = "") { - if ($this->isFinalized || $externalReferences === EPub::EXTERNAL_REF_IGNORE) { - return FALSE; - } - - if ($this->bookVersion !== EPub::BOOK_VERSION_EPUB3) { - // ePub 2 does not support multimedia formats, and they must be removed. - $externalReferences = EPub::EXTERNAL_REF_REMOVE_IMAGES; - } - - $postProcDomElememts = array(); - $images = $xmlDoc->getElementsByTagName("source"); - $itemCount = $images->length; - for ($idx = 0; $idx < $itemCount; $idx++) { - $img = $images->item($idx); - if ($externalReferences === EPub::EXTERNAL_REF_REMOVE_IMAGES) { - $postProcDomElememts[] = $img; - } 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[] = array($img, $this->createDomFragment($xmlDoc, "[" . $alt . "]")); - } else { - $source = $img->attributes->getNamedItem("src")->nodeValue; - - $parsedSource = parse_url($source); - $internalSrc = $this->sanitizeFileName(urldecode(pathinfo($parsedSource['path'], PATHINFO_BASENAME))); - $internalPath = ""; - $isSourceExternal = FALSE; - - if ($this->resolveMedia($source, $internalPath, $internalSrc, $isSourceExternal, $baseDir, $htmlDir, $backPath)) { - $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. - } - } - } - - /** - * Resolve an image src and determine it's target location and add it to the book. - * - * @param string $source Image Source link. - * @param string &$internalPath (referenced) Return value, will be set to the target path and name in the book. - * @param string &$internalSrc (referenced) Return value, will be set to the target name in the book. - * @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. - * @param string $backPath The path to get back to the root of the archive from $htmlDir. - */ - protected function resolveImage($source, &$internalPath, &$internalSrc, &$isSourceExternal, $baseDir = "", $htmlDir = "", $backPath = "") { - if ($this->isFinalized) { - return FALSE; - } - $imageData = NULL; - - if (preg_match('#^(http|ftp)s?://#i', $source) == 1) { - $urlinfo = parse_url($source); - $urlPath = pathinfo($urlinfo['path']); - - if (strpos($urlinfo['path'], $baseDir."/") !== FALSE) { - $internalSrc = $this->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 = $this->getImage($source); - } else if (strpos($source, "/") === 0) { - $internalPath = pathinfo($source, PATHINFO_DIRNAME); - - $path = $source; - if (!file_exists($path)) { - $path = $this->docRoot . $path; - } - - $imageData = $this->getImage($path); - } else { - $internalPath = $htmlDir . "/" . preg_replace('#^[/\.]+#', '', pathinfo($source, PATHINFO_DIRNAME)); - - $path = $baseDir . "/" . $source; - if (!file_exists($path)) { - $path = $this->docRoot . $path; - } - - $imageData = $this->getImage($path); - } - if ($imageData !== FALSE) { - $iSrcInfo = pathinfo($internalSrc); - if (!empty($imageData['ext']) && $imageData['ext'] != $iSrcInfo['extension']) { - $internalSrc = $iSrcInfo['filename'] . "." . $imageData['ext']; - } - $internalPath = Zip::getRelativePath("images/" . $internalPath . "/" . $internalSrc); - if (!array_key_exists($internalPath, $this->fileList)) { - $this->addFile($internalPath, "i_" . $internalSrc, $imageData['image'], $imageData['mime']); - $this->fileList[$internalPath] = $source; - } - return TRUE; - } - return FALSE; - } - - /** - * Resolve a media src and determine it's target location and add it to the book. - * - * @param string $source Source link. - * @param string $internalPath (referenced) Return value, will be set to the target path and name in the book. - * @param string $internalSrc (referenced) Return value, will be set to the target name in the book. - * @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. - * @param string $backPath The path to get back to the root of the archive from $htmlDir. - */ - protected function resolveMedia($source, &$internalPath, &$internalSrc, &$isSourceExternal, $baseDir = "", $htmlDir = "", $backPath = "") { - if ($this->isFinalized) { - return FALSE; - } - $mediaPath = NULL; - $tmpFile; - - if (preg_match('#^(http|ftp)s?://#i', $source) == 1) { - $urlinfo = parse_url($source); - - if (strpos($urlinfo['path'], $baseDir."/") !== FALSE) { - $internalSrc = substr($urlinfo['path'], strpos($urlinfo['path'], $baseDir."/") + strlen($baseDir) + 1); - } - $internalPath = $urlinfo["scheme"] . "/" . $urlinfo["host"] . "/" . pathinfo($urlinfo["path"], PATHINFO_DIRNAME); - $isSourceExternal = TRUE; - $mediaPath = $this->getFileContents($source, true); - $tmpFile = $mediaPath; - } else if (strpos($source, "/") === 0) { - $internalPath = pathinfo($source, PATHINFO_DIRNAME); - - $mediaPath = $source; - if (!file_exists($mediaPath)) { - $mediaPath = $this->docRoot . $mediaPath; - } - } else { - $internalPath = $htmlDir . "/" . preg_replace('#^[/\.]+#', '', pathinfo($source, PATHINFO_DIRNAME)); - - $mediaPath = $baseDir . "/" . $source; - if (!file_exists($mediaPath)) { - $mediaPath = $this->docRoot . $mediaPath; - } - } - - if ($mediaPath !== FALSE) { - $mime = $this->getMime($source); - $internalPath = Zip::getRelativePath("media/" . $internalPath . "/" . $internalSrc); - - if (!array_key_exists($internalPath, $this->fileList) && - $this->addLargeFile($internalPath, "m_" . $internalSrc, $mediaPath, $mime)) { - $this->fileList[$internalPath] = $source; - } - if (isset($tmpFile)) { - unlink($tmpFile); - } - return TRUE; - } - return FALSE; - } - - /** - * Get Book Chapter count. - * - * @access public - * @return number of chapters - */ - function getChapterCount() { - return $this->chapterCount; - } - - /** - * Book title, mandatory. - * - * 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 - */ - function setTitle($title) { - if ($this->isFinalized) { - return FALSE; - } - $this->title = $title; - return TRUE; - } - - /** - * Get Book title. - * - * @access public - * @return $title - */ - function getTitle() { - return $this->title; - } - - /** - * Book language, mandatory - * - * Use the RFC3066 Language codes, such as "en", "da", "fr" etc. - * Defaults to "en". - * - * Used for the dc:language metadata parameter in the OPF file. - * - * @param string $language - * @access public - * @return bool $success - */ - function setLanguage($language) { - if ($this->isFinalized || mb_strlen($language) != 2) { - return FALSE; - } - $this->language = $language; - return TRUE; - } - - /** - * Get Book language. - * - * @access public - * @return $language - */ - function getLanguage() { - return $this->language; - } - - /** - * Unique book identifier, mandatory. - * Use the URI, or ISBN if available. - * - * An unambiguous reference to the resource within a given context. - * - * Recommended best practice is to identify the resource by means of a - * string conforming to a formal identification system. - * - * Used for the dc:identifier metadata parameter in the OPF file, as well - * as dtb:uid in the NCX file. - * - * Identifier type should only be: - * EPub::IDENTIFIER_URI - * EPub::IDENTIFIER_ISBN - * EPub::IDENTIFIER_UUID - * - * @param string $identifier - * @param string $identifierType - * @access public - * @return bool $success - */ - function setIdentifier($identifier, $identifierType) { - if ($this->isFinalized || ($identifierType !== EPub::IDENTIFIER_URI && $identifierType !== EPub::IDENTIFIER_ISBN && $identifierType !== EPub::IDENTIFIER_UUID)) { - return FALSE; - } - $this->identifier = $identifier; - $this->identifierType = $identifierType; - return TRUE; - } - - /** - * Get Book identifier. - * - * @access public - * @return $identifier - */ - function getIdentifier() { - return $this->identifier; - } - - /** - * Get Book identifierType. - * - * @access public - * @return $identifierType - */ - function getIdentifierType() { - return $this->identifierType; - } - - /** - * Book description, optional. - * - * An account of the resource. - * - * Description may include but is not limited to: an abstract, a table of - * contents, a graphical representation, or a free-text account of the - * resource. - * - * Used for the dc:source metadata parameter in the OPF file - * - * @param string $description - * @access public - * @return bool $success - */ - function setDescription($description) { - if ($this->isFinalized) { - return FALSE; - } - $this->description = $description; - return TRUE; - } - - /** - * Get Book description. - * - * @access public - * @return $description - */ - function getDescription() { - return $this->description; - } - - /** - * Book author or creator, optional. - * The $authorSortKey is basically how the name is to be sorted, usually - * it's "Lastname, First names" where the $author is the straight - * "Firstnames Lastname" - * - * An entity primarily responsible for making the resource. - * - * Examples of a Creator include a person, an organization, or a service. - * Typically, the name of a Creator should be used to indicate the entity. - * - * Used for the dc:creator metadata parameter in the OPF file and the - * 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 - */ - function setAuthor($author, $authorSortKey) { - if ($this->isFinalized) { - return FALSE; - } - $this->author = $author; - $this->authorSortKey = $authorSortKey; - return TRUE; - } - - /** - * Get Book author. - * - * @access public - * @return $author - */ - function getAuthor() { - return $this->author; - } - - /** - * Publisher Information, optional. - * - * An entity responsible for making the resource available. - * - * Examples of a Publisher include a person, an organization, or a service. - * Typically, the name of a Publisher should be used to indicate the entity. - * - * 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 - */ - function setPublisher($publisherName, $publisherURL) { - if ($this->isFinalized) { - return FALSE; - } - $this->publisherName = $publisherName; - $this->publisherURL = $publisherURL; - return TRUE; - } - - /** - * Get Book publisherName. - * - * @access public - * @return $publisherName - */ - function getPublisherName() { - return $this->publisherName; - } - - /** - * Get Book publisherURL. - * - * @access public - * @return $publisherURL - */ - function getPublisherURL() { - return $this->publisherURL; - } - - /** - * Release date, optional. If left blank, the time of the finalization will - * be used. - * - * A point or period of time associated with an event in the lifecycle of - * the resource. - * - * Date may be used to express temporal information at any level of - * granularity. Recommended best practice is to use an encoding scheme, - * such as the W3CDTF profile of ISO 8601 [W3CDTF]. - * - * Used for the dc:date metadata parameter in the OPF file - * - * @param long $timestamp - * @access public - * @return bool $success - */ - function setDate($timestamp) { - if ($this->isFinalized) { - return FALSE; - } - $this->date = $timestamp; - $this->opf->date = $timestamp; - return TRUE; - } - - /** - * Get Book date. - * - * @access public - * @return $date - */ - function getDate() { - return $this->date; - } - - /** - * Book (copy)rights, optional. - * - * Information about rights held in and over the resource. - * - * Typically, rights information includes a statement about various - * property rights associated with the resource, including intellectual - * property rights. - * - * Used for the dc:rights metadata parameter in the OPF file - * - * @param string $rightsText - * @access public - * @return bool $success - */ - function setRights($rightsText) { - if ($this->isFinalized) { - return FALSE; - } - $this->rights = $rightsText; - return TRUE; - } - - /** - * Get Book rights. - * - * @access public - * @return $rights - */ - function getRights() { - return $this->rights; - } - - /** - * Add book Subject. - * - * The topic of the resource. - * - * Typically, the subject will be represented using keywords, key phrases, - * or classification codes. Recommended best practice is to use a - * controlled vocabulary. To describe the spatial or temporal topic of the - * resource, use the Coverage element. - * - * @param string $subject - */ - function setSubject($subject) { - if ($this->isFinalized) { - return; - } - $this->opf->addDCMeta(DublinCore::SUBJECT, $this->decodeHtmlEntities($subject)); - } - - /** - * Book source URL, optional. - * - * A related resource from which the described resource is derived. - * - * The described resource may be derived from the related resource in whole - * or in part. Recommended best practice is to identify the related - * resource by means of a string conforming to a formal identification system. - * - * Used for the dc:source metadata parameter in the OPF file - * - * @param string $sourceURL - * @access public - * @return bool $success - */ - function setSourceURL($sourceURL) { - if ($this->isFinalized) { - return FALSE; - } - $this->sourceURL = $sourceURL; - return TRUE; - } - - /** - * Get Book sourceURL. - * - * @access public - * @return $sourceURL - */ - function getSourceURL() { - return $this->sourceURL; - } - - /** - * Coverage, optional. - * - * The spatial or temporal topic of the resource, the spatial applicability - * of the resource, or the jurisdiction under which the resource is relevant. - * - * Spatial topic and spatial applicability may be a named place or a location - * specified by its geographic coordinates. Temporal topic may be a named - * period, date, or date range. A jurisdiction may be a named administrative - * entity or a geographic place to which the resource applies. Recommended - * best practice is to use a controlled vocabulary such as the Thesaurus of - * Geographic Names [TGN]. Where appropriate, named places or time periods - * can be used in preference to numeric identifiers such as sets of - * coordinates or date ranges. - * - * Used for the dc:coverage metadata parameter in the OPF file - * - * Same as ->addDublinCoreMetadata(DublinCore::COVERAGE, $coverage); - * - * @param string $coverage - * @access public - * @return bool $success - */ - function setCoverage($coverage) { - if ($this->isFinalized) { - return FALSE; - } - $this->coverage = $coverage; - return TRUE; - } - - /** - * Get Book coverage. - * - * @access public - * @return $coverage - */ - function getCoverage() { - return $this->coverage; - } - - /** - * Set book Relation. - * - * A related resource. - * - * Recommended best practice is to identify the related resource by means - * of a string conforming to a formal identification system. - * - * @param string $relation - */ - function setRelation($relation) { - if ($this->isFinalized) { - return; - } - $this->relation = $relation; - } - - /** - * Get the book relation. - * - * @return string The relation. - */ - function getRelation() { - return $this->relation; - } - - /** - * Set book Generator. - * - * 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 - */ - function setGenerator($generator) { - if ($this->isFinalized) { - return; - } - $this->generator = $generator; - } - - /** - * Get the book relation. - * - * @return string The generator identity string. - */ - function getGenerator() { - return $this->generator; - } - - /** - * Set ePub date formate to the short yyyy-mm-dd form, for compliance with - * a bug in EpubCheck, prior to its version 1.1. - * - * The latest version of ePubCheck can be obtained here: - * http://code.google.com/p/epubcheck/ - * - * @access public - * @return bool $success - */ - function setShortDateFormat() { - if ($this->isFinalized) { - return FALSE; - } - $this->dateformat = $this->dateformatShort; - return TRUE; - } - - /** - * @Deprecated - */ - function setIgnoreEmptyBuffer($ignoreEmptyBuffer = TRUE) { - die ("Function was deprecated, functionality is no longer needed."); - } - - /** - * Set the references title for the ePub 3 landmarks section - * - * @param string $referencesTitle - * @param string $referencesId - * @param string $referencesClass - * @return bool - */ - function setReferencesTitle($referencesTitle = "Guide", $referencesId = "", $referencesClass = "references") { - 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"; - return TRUE; - } - - /** - * Set the references title for the ePub 3 landmarks section - * - * @param bool $referencesTitle - */ - function setisReferencesAddedToToc($isReferencesAddedToToc = TRUE) { - if ($this->isFinalized) { - return FALSE; - } - $this->isReferencesAddedToToc = $isReferencesAddedToToc === TRUE; - return TRUE; - } - - /** - * Get Book status. - * - * @access public - * @return bool - */ - function isFinalized() { - return $this->isFinalized; - } - - /** - * Build the Table of Contents. This is not strictly necessary, as most eReaders will build it from the navigation structure in the .ncx file. - * - * @param string $cssFileName Include a link to this css file in the TOC html. - * @param string $tocCSSClass The TOC is a
    , if you need special formatting, you can add a css class for that div. Default is "toc". - * @param string $title Title of the Table of contents. Default is "Table of Contents". Use this for ie. languages other than English. - * @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 teh default name of the TOC file. The default is "TOC.xhtml" - */ - function buildTOC($cssFileName = NULL, $tocCSSClass = "toc", $title = "Table of Contents", $addReferences = TRUE, $addToIndex = FALSE, $tocFileName = "TOC.xhtml") { - if ($this->isFinalized) { - return FALSE; - } - $this->buildTOC = TRUE; - $this->tocTitle = $title; - $this->tocFileName = $this->normalizeFileName($tocFileName); - if (!empty($cssFileName)) { - $this->tocCSSFileName = $this->normalizeFileName($cssFileName); - } - $this->tocCSSClass = $tocCSSClass; - $this->tocAddReferences = $addReferences; - - $this->opf->addItemRef("ref_" . Reference::TABLE_OF_CONTENTS, FALSE); - $this->opf->addReference(Reference::TABLE_OF_CONTENTS, $title, $this->tocFileName); - - if ($addToIndex) { - $navPoint = new NavPoint($this->decodeHtmlEntities($title), $this->tocFileName, "ref_" . Reference::TABLE_OF_CONTENTS); - $this->ncx->addNavPoint($navPoint); - } else { - $this->ncx->referencesList[Reference::TABLE_OF_CONTENTS] = $this->tocFileName; - $this->ncx->referencesName[Reference::TABLE_OF_CONTENTS] = $title; - } - } - - private function finalizeTOC() { - if (!$this->buildTOC) { - return FALSE; - } - - if (empty($this->tocTitle)) { - $this->tocTitle = "Table of Contents"; - } - - $tocData = "\n"; - - if ($this->isEPubVersion2()) { - $tocData .= "\n" - . "\n" - . "\n\n"; - } else { - $tocData .= "\n" - . "\n\n"; - } - - if (!empty($this->tocCssFileName)) { - $tocData .= "tocCssFileName . "\" />\n"; - } - - $tocData .= "" . $this->tocTitle . "\n" - . "\n" - . "\n" - . "

    " . $this->tocTitle . "

    \ntocCSSClass)) { - $tocData .= " class=\"" . $this->tocCSSClass . "\""; - } - $tocData .= ">\n"; - - while (list($item, $descriptive) = each($this->referencesOrder)) { - if ($item === "text") { - while (list($chapterName, $navPoint) = each($this->ncx->chapterList)) { - $fileName = $navPoint->getContentSrc(); - $level = $navPoint->getLevel() -2; - $tocData .= "\t

    " . str_repeat("      ", $level) . "sanitizeFileName($fileName) . "\">" . $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"; - } - } - } - $tocData .= "
    \n\n\n"; - - $this->addReferencePage($this->tocTitle, $this->tocFileName, $tocData, Reference::TABLE_OF_CONTENTS); - - } - - /** - * @return bool - */ - function isEPubVersion2() { - return $this->bookVersion === EPub::BOOK_VERSION_EPUB2; - } - - /** - * @param string $cssFileName - * @param string $title - * @return string - */ - function buildEPub3TOC($cssFileName = NULL, $title = "Table of Contents") { - $this->ncx->referencesOrder = $this->referencesOrder; - $this->ncx->setDocTitle($this->decodeHtmlEntities($this->title)); - return $this->ncx->finalizeEPub3($title, $cssFileName); - } - - /** - * @param string $fileName - * @param string $tocData - * @return bool - */ - function addEPub3TOC($fileName, $tocData) { - if ($this->isEPubVersion2() || $this->isFinalized || array_key_exists($fileName, $this->fileList)) { - return FALSE; - } - $fileName = Zip::getRelativePath($fileName); - $fileName = preg_replace('#^[/\.]+#i', "", $fileName); - - $this->zip->addFile($tocData, $this->bookRoot.$fileName); - - $this->fileList[$fileName] = $fileName; - $this->opf->addItem("toc", $fileName, "application/xhtml+xml", "nav"); - return TRUE; - } - - /** - * Check for mandatory parameters and finalize the e-book. - * Once finalized, the book is locked for further additions. - * - * @return bool $success - */ - function finalize() { - if ($this->isFinalized || $this->chapterCount == 0 || empty($this->title) || empty($this->language)) { - return FALSE; - } - - if (empty($this->identifier) || empty($this->identifierType)) { - $this->setIdentifier($this->createUUID(4), EPub::IDENTIFIER_UUID); - } - - if ($this->date == 0) { - $this->date = time(); - } - - if (empty($this->sourceURL)) { - $this->sourceURL = $this->getCurrentPageURL(); - } - - if (empty($this->publisherURL)) { - $this->sourceURL = $this->getCurrentServerURL(); - } - - // Generate OPF data: - $this->opf->setIdent("BookId"); - $this->opf->initialize($this->title, $this->language, $this->identifier, $this->identifierType); - - $DCdate = new DublinCore(DublinCore::DATE, gmdate($this->dateformat, $this->date)); - $DCdate->addOpfAttr("event", "publication"); - $this->opf->metadata->addDublinCore($DCdate); - - if (!empty($this->description)) { - $this->opf->addDCMeta(DublinCore::DESCRIPTION, $this->decodeHtmlEntities($this->description)); - } - - if (!empty($this->publisherName)) { - $this->opf->addDCMeta(DublinCore::PUBLISHER, $this->decodeHtmlEntities($this->publisherName)); - } - - if (!empty($this->publisherURL)) { - $this->opf->addDCMeta(DublinCore::RELATION, $this->decodeHtmlEntities($this->publisherURL)); - } - - if (!empty($this->author)) { - $author = $this->decodeHtmlEntities($this->author); - $this->opf->addCreator($author, $this->decodeHtmlEntities($this->authorSortKey), MarcCode::AUTHOR); - $this->ncx->setDocAuthor($author); - } - - if (!empty($this->rights)) { - $this->opf->addDCMeta(DublinCore::RIGHTS, $this->decodeHtmlEntities($this->rights)); - } - - if (!empty($this->coverage)) { - $this->opf->addDCMeta(DublinCore::COVERAGE, $this->decodeHtmlEntities($this->coverage)); - } - - if (!empty($this->sourceURL)) { - $this->opf->addDCMeta(DublinCore::SOURCE, $this->sourceURL); - } - - if (!empty($this->relation)) { - $this->opf->addDCMeta(DublinCore::RELATION, $this->decodeHtmlEntities($this->relation)); - } - - if ($this->isCoverImageSet) { - $this->opf->addMeta("cover", "coverImage"); - } - - if (!empty($this->generator)) { - $gen = $this->decodeHtmlEntities($this->generator); - $this->opf->addMeta("generator", $gen); - $this->ncx->addMetaEntry("dtb:generator", $gen); - } - - if ($this->EPubMark) { - $this->opf->addMeta("generator", "EPub (Version " . self::VERSION . ") by A. Grandt, http://www.phpclasses.org/package/6115"); - } - - reset($this->ncx->chapterList); - list($firstChapterName, $firstChapterNavPoint) = each($this->ncx->chapterList); - $firstChapterFileName = $firstChapterNavPoint->getContentSrc(); - $this->opf->addReference(Reference::TEXT, $this->decodeHtmlEntities($firstChapterName), $firstChapterFileName); - - $this->ncx->setUid($this->identifier); - - $this->ncx->setDocTitle($this->decodeHtmlEntities($this->title)); - - $this->ncx->referencesOrder = $this->referencesOrder; - if ($this->isReferencesAddedToToc) { - $this->ncx->finalizeReferences(); - } - - $this->finalizeTOC(); - - if (!$this->isEPubVersion2()) { - $this->addEPub3TOC("epub3toc.xhtml", $this->buildEPub3TOC()); - } - - $opfFinal = $this->fixEncoding($this->opf->finalize()); - $ncxFinal = $this->fixEncoding($this->ncx->finalize()); - - if (mb_detect_encoding($opfFinal, 'UTF-8', true) === "UTF-8") { - $this->zip->addFile($opfFinal, $this->bookRoot."book.opf"); - } else { - $this->zip->addFile(mb_convert_encoding($opfFinal, "UTF-8"), $this->bookRoot."book.opf"); - } - - if (mb_detect_encoding($ncxFinal, 'UTF-8', true) === "UTF-8") { - $this->zip->addFile($ncxFinal, $this->bookRoot."book.ncx"); - } else { - $this->zip->addFile(mb_convert_encoding($ncxFinal, "UTF-8"), $this->bookRoot."book.ncx"); - } - - $this->opf = NULL; - $this->ncx = NULL; - - $this->isFinalized = TRUE; - return TRUE; - } - - /** - * Ensure the encoded string is a valid UTF-8 string. - * - * Note, that a mb_detect_encoding on the returned string will still return ASCII if the entire string is comprized of characters in the 1-127 range. - * - * @link: http://snippetdb.com/php/convert-string-to-utf-8-for-mysql - * @param string $in_str - * @return string converted string. - */ - function fixEncoding($in_str) { - if (mb_detect_encoding($in_str) == "UTF-8" && mb_check_encoding($in_str,"UTF-8")) { - return $in_str; - } else { - return utf8_encode($in_str); - } - } - - /** - * Return the finalized book. - * - * @return string with the book in binary form. - */ - function getBook() { - if (!$this->isFinalized) { - $this->finalize(); - } - - return $this->zip->getZipData(); - } - - /** - * Remove disallowed characters from string to get a nearly safe filename - * - * @param string $fileName - * @return mixed|string - */ - function sanitizeFileName($fileName) { - $fileName1 = str_replace($this->forbiddenCharacters, '', $fileName); - $fileName2 = preg_replace('/[\s-]+/', '-', $fileName1); - return trim($fileName2, '.-_'); - - } - - /** - * Cleanup the filepath, and remove leading . and / characters. - * - * Sometimes, when a path is generated from multiple fragments, - * you can get something like "../data/html/../images/image.jpeg" - * ePub files don't work well with that, this will normalize that - * example path to "data/images/image.jpeg" - * - * @param string $fileName - * @return string normalized filename - */ - function normalizeFileName($fileName) { - return preg_replace('#^[/\.]+#i', "", Zip::getRelativePath($fileName)); - } - - /** - * 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 The sent file name if successfull, FALSE if it failed. - */ - function saveBook($fileName, $baseDir = '.') { - - // Make fileName safe - $fileName = $this->sanitizeFileName($fileName); - - // Finalize book, if it's not done already - if (!$this->isFinalized) { - $this->finalize(); - } - - if (stripos(strrev($fileName), "bupe.") !== 0) { - $fileName .= ".epub"; - } - - // Try to open file access - $fh = fopen($baseDir.'/'.$fileName, "w"); - - if ($fh) { - fputs($fh, $this->getBook()); - fclose($fh); - - // if file is written return TRUE - return $fileName; - } - - // return FALSE by default - return FALSE; - } - - /** - * Return the finalized book size. - * - * @return string - */ - function getBookSize() { - if (!$this->isFinalized) { - $this->finalize(); - } - - return $this->zip->getArchiveSize(); - } - - /** - * Send the book as a zip download - * - * Sending will fail if the output buffer is in use. You can override this limit by - * calling setIgnoreEmptyBuffer(TRUE), though the function will still fail if that - * buffer is not empty. - * - * @param string $fileName The name of the book without the .epub at the end. - * @return The sent file name if successfull, FALSE if it failed. - */ - function sendBook($fileName) { - if (!$this->isFinalized) { - $this->finalize(); - } - - if (stripos(strrev($fileName), "bupe.") !== 0) { - $fileName .= ".epub"; - } - - if (TRUE === $this->zip->sendZip($fileName, "application/epub+zip")) { - return $fileName; - } - return FALSE; - } - - /** - * Generates an UUID. - * - * Default version (4) will generate a random UUID, version 3 will URL based UUID. - * - * Added for convinience - * - * @param int $bookVersion UUID version to retrieve, See lib.uuid.manual.html for details. - * @param string $url - * @return string The formatted uuid - */ - function createUUID($bookVersion = 4, $url = NULL) { - include_once("lib.uuid.php"); - return UUID::mint($bookVersion, $url, UUID::nsURL); - } - - /** - * Get the url of the current page. - * Example use: Default Source URL - * - * $return string Page URL. - */ - function getCurrentPageURL() { - $pageURL = $this->getCurrentServerURL() . filter_input(INPUT_SERVER, "REQUEST_URI"); - return $pageURL; - } - - /** - * Get the url of the server. - * Example use: Default Publisher URL - * - * $return string Server URL. - */ - function getCurrentServerURL() { - $serverURL = 'http'; - $https = filter_input(INPUT_SERVER, "HTTPS"); - $port = filter_input(INPUT_SERVER, "SERVER_PORT"); - - if ($https === "on") { - $serverURL .= "s"; - } - $serverURL .= "://" . filter_input(INPUT_SERVER, "SERVER_NAME"); - if ($port != "80") { - $serverURL .= ":" . $port; - } - return $serverURL . '/'; - } - - /** - * Try to determine the mimetype of the file path. - * - * @param string $source Path - * @return string mimetype, or FALSE. - */ - function getMime($source) { - return $this->mimetypes[pathinfo($source, PATHINFO_EXTENSION)]; - } - - /** - * Get an image from a file or url, return it resized if the image exceeds the $maxImageWidth or $maxImageHeight directives. - * - * The return value is an array. - * ['width'] is the width of the image. - * ['height'] is the height of the image. - * ['mime'] is the mime type of the image. Resized images are always in jpeg format. - * ['image'] is the image data. - * ['ext'] is the extension of the image file. - * - * @param string $source path or url to file. - * $return array - */ - function getImage($source) { - $width = -1; - $height = -1; - $mime = "application/octet-stream"; - $type = FALSE; - $ext = ""; - - - $image = $this->getFileContents($source); - - if ($image !== FALSE && strlen($image) > 0) { - $imageFile = imagecreatefromstring($image); - if ($imageFile !== false) { - $width = ImageSX($imageFile); - $height = ImageSY($imageFile); - } - if ($this->isExifInstalled) { - @$type = exif_imagetype($source); - $mime = image_type_to_mime_type($type); - } - if ($mime === "application/octet-stream") { - $mime = $this->image_file_type_from_binary($image); - } - if ($mime === "application/octet-stream") { - $mime = $this->getMimeTypeFromUrl($source); - } - } else { - return FALSE; - } - - if ($width <= 0 || $height <= 0) { - return FALSE; - } - - $ratio = 1; - - if ($this->isGdInstalled) { - if ($width > $this->maxImageWidth) { - $ratio = $this->maxImageWidth/$width; - } - if ($height*$ratio > $this->maxImageHeight) { - $ratio = $this->maxImageHeight/$height; - } - - if ($ratio < 1 || empty($mime) || ($this->isGifImagesEnabled !== FALSE && $mime == "image/gif")) { - $image_o = imagecreatefromstring($image); - $image_p = imagecreatetruecolor($width*$ratio, $height*$ratio); - - if ($mime == "image/png") { - imagealphablending($image_p, false); - imagesavealpha($image_p, true); - imagealphablending($image_o, true); - - imagecopyresampled($image_p, $image_o, 0, 0, 0, 0, ($width*$ratio), ($height*$ratio), $width, $height); - ob_start(); - imagepng($image_p, NULL, 9); - $image = ob_get_contents(); - ob_end_clean(); - - $ext = "png"; - } else { - imagecopyresampled($image_p, $image_o, 0, 0, 0, 0, ($width*$ratio), ($height*$ratio), $width, $height); - ob_start(); - imagejpeg($image_p, NULL, 80); - $image = ob_get_contents(); - ob_end_clean(); - - $mime = "image/jpeg"; - $ext = "jpg"; - } - imagedestroy($image_o); - imagedestroy($image_p); - } - } - - if ($ext === "") { - static $mimeToExt = array ( - 'image/jpeg' => 'jpg', - 'image/gif' => 'gif', - 'image/png' => 'png' - ); - - if (isset($mimeToExt[$mime])) { - $ext = $mimeToExt[$mime]; - } - } - - $rv = array(); - $rv['width'] = $width*$ratio; - $rv['height'] = $height*$ratio; - $rv['mime'] = $mime; - $rv['image'] = $image; - $rv['ext'] = $ext; - - return $rv; - } - - /** - * Get file contents, using curl if available, else file_get_contents - * - * @param string $source - * @return bool - */ - function getFileContents($source, $toTempFile = FALSE) { - $isExternal = preg_match('#^(http|ftp)s?://#i', $source) == 1; - - if ($isExternal && $this->isCurlInstalled) { - $ch = curl_init(); - $outFile = NULL; - $fp = NULL; - $res = FALSE; - $info = array('http_code' => 500); - - curl_setopt($ch, CURLOPT_HEADER, 0); - curl_setopt($ch, CURLOPT_URL, str_replace(" ","%20",$source)); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_BUFFERSIZE, 4096); - - if ($toTempFile) { - $outFile = tempnam(sys_get_temp_dir(), "EPub_v" . EPub::VERSION . "_"); - $fp = fopen($outFile, "w+b"); - curl_setopt($ch, CURLOPT_FILE, $fp); - - $res = curl_exec($ch); - $info = curl_getinfo($ch); - - curl_close($ch); - fclose($fp); - } else { - $res = curl_exec($ch); - $info = curl_getinfo($ch); - - curl_close($ch); - } - - if ($info['http_code'] == 200 && $res != false) { - if ($toTempFile) { - return $outFile; - } - return $res; - } - return FALSE; - } - - if ($this->isFileGetContentsInstalled && (!$isExternal || $this->isFileGetContentsExtInstalled)) { - @$data = file_get_contents($source); - return $data; - } - return FALSE; - } - - /** - * get mime type from image data - * - * By fireweasel found on http://stackoverflow.com/questions/2207095/get-image-mimetype-from-resource-in-php-gd - * @staticvar array $type - * @param object $binary - * @return string - */ - function image_file_type_from_binary($binary) { - $hits = 0; - if (!preg_match( - '/\A(?:(\xff\xd8\xff)|(GIF8[79]a)|(\x89PNG\x0d\x0a)|(BM)|(\x49\x49(?:\x2a\x00|\x00\x4a))|(FORM.{4}ILBM))/', - $binary, $hits)) { - return 'application/octet-stream'; - } - static $type = array ( - 1 => 'image/jpeg', - 2 => 'image/gif', - 3 => 'image/png', - 4 => 'image/x-windows-bmp', - 5 => 'image/tiff', - 6 => 'image/x-ilbm', - ); - return $type[count($hits) - 1]; - } - - /** - * @param string $source URL Source - * @return string MimeType - */ - function getMimeTypeFromUrl($source) { - $ext = FALSE; - - $srev = strrev($source); - $pos = strpos($srev, "?"); - if ($pos !== FALSE) { - $srev = substr($srev, $pos+1); - } - - $pos = strpos($srev, "."); - if ($pos !== FALSE) { - $ext = strtolower(strrev(substr($srev, 0, $pos))); - } - - if ($ext !== FALSE) { - return $this->getMimeTypeFromExtension($ext); - } - return "application/octet-stream"; - } - - /** - * @param string $ext Extension - * @return string MimeType - */ - function getMimeTypeFromExtension($ext) { - switch ($ext) { - case "jpg": - case "jpe": - case "jpeg": - return 'image/jpeg'; - case "gif": - return 'image/gif'; - case "png": - return 'image/png'; - case "bmp": - return 'image/x-windows-bmp'; - case "tif": - case "tiff": - case "cpt": - return 'image/tiff'; - case "lbm": - case "ilbm": - return 'image/x-ilbm'; - default: - return "application/octet-stream"; - } - } - - /** - * Encode html code to use html entities, safeguarding it from potential character encoding peoblems - * This function is a bit different from the vanilla htmlentities function in that it does not encode html tags. - * - * The regexp is taken from the PHP Manual discussion, it was written by user "busbyjon". - * http://www.php.net/manual/en/function.htmlentities.php#90111 - * - * @param string $string string to encode. - */ - public function encodeHtml($string) { - $string = strtr($string, $this->html_encoding_characters); - - //return preg_replace("/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,5};)/", "&\\1", $string); - //return preg_replace("/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,5};)/", "&", $string); - return $string; - } - - /** - * Helper function to create a DOM fragment with given markup. - * - * @author Adam Schmalhofer - * - * @param DOMDocument $dom - * @param string $markup - * @return DOMNode fragment in a node. - */ - protected function createDomFragment($dom, $markup) { - $node = $dom->createDocumentFragment(); - $node->appendXML($markup); - return $node; - } - - /** - * Retrieve an array of file names currently added to the book. - * $key is the filename used in the book - * $value is the original filename, will be the same as $key for most entries - * - * @return array file list - */ - function getFileList() { - return $this->fileList; - } - - /** - * @deprecated Use Zip::getRelativePath($relPath) instead. - */ - function relPath($relPath) { - die ("Function was deprecated, use Zip::getRelativePath(\$relPath); instead"); - } - - /** - * Set default chapter target size. - * Default is 250000 bytes, and minimum is 10240 bytes. - * - * @param int $size segment size in bytes - * @return void - */ - function setSplitSize($size) { - $this->splitDefaultSize = (int)$size; - if ($size < 10240) { - $this->splitDefaultSize = 10240; // Making the file smaller than 10k is not a good idea. - } - } - - /** - * Get the chapter target size. - * - * @return $size - */ - function getSplitSize() { - return $this->splitDefaultSize; - } - - /** - * Remove all non essential html tags and entities. - * - * @global type $htmlEntities - * @param string $string - * @return string with the stripped entities. - */ - function decodeHtmlEntities($string) { - global $htmlEntities; - - $string = preg_replace('~\s*\s*~i', "\n", $string); - $string = preg_replace('~\s*\s*~i', "\n\n", $string); - $string = preg_replace('~<[^>]*>~', '', $string); - - $string = strtr($string, $htmlEntities); - - $string = str_replace('&', '&', $string); - $string = str_replace('&amp;', '&', $string); - $string = preg_replace('~&(#x*[a-fA-F0-9]+;)~', '&\1', $string); - $string = str_replace('<', '<', $string); - $string = str_replace('>', '>', $string); - - return $string; - } - - /** - * Simply remove all HTML tags, brute force and no finesse. - * - * @param string $string html - * @return string - */ - function html2text($string) { - return preg_replace('~<[^>]*>~', '', $string); - } - - /** - * @return string - */ - function getLog() { - return $this->log->getLog(); - } -} diff --git a/inc/3rdparty/libraries/PHPePub/EPubChapterSplitter.php b/inc/3rdparty/libraries/PHPePub/EPubChapterSplitter.php deleted file mode 100644 index 1d44f238..00000000 --- a/inc/3rdparty/libraries/PHPePub/EPubChapterSplitter.php +++ /dev/null @@ -1,201 +0,0 @@ - - * @copyright 2009-2014 A. Grandt - * @license GNU LGPL 2.1 - * @link http://www.phpclasses.org/package/6115 - * @link https://github.com/Grandt/PHPePub - * @version 3.20 - */ -class EPubChapterSplitter { - const VERSION = 3.20; - - private $splitDefaultSize = 250000; - private $bookVersion = EPub::BOOK_VERSION_EPUB2; - - /** - * - * Enter description here ... - * - * @param unknown_type $ident - */ - function setVersion($bookVersion) { - $this->bookVersion = is_string($bookVersion) ? trim($bookVersion) : EPub::BOOK_VERSION_EPUB2; - } - - /** - * Set default chapter target size. - * Default is 250000 bytes, and minimum is 10240 bytes. - * - * @param $size segment size in bytes - * @return void - */ - function setSplitSize($size) { - $this->splitDefaultSize = (int)$size; - if ($size < 10240) { - $this->splitDefaultSize = 10240; // Making the file smaller than 10k is not a good idea. - } - } - - /** - * Get the chapter target size. - * - * @return $size - */ - function getSplitSize() { - return $this->splitDefaultSize; - } - - /** - * Split $chapter into multiple parts. - * - * The search string can either be a regular string or a PHP PECL Regular Expression pattern as defined here: http://www.php.net/manual/en/pcre.pattern.php - * If the search string is a regular string, the matching will be for lines in the HTML starting with the string given - * - * @param String $chapter XHTML file - * @param Bool $splitOnSearchString Split on chapter boundaries, Splitting on search strings disables the split size check. - * @param String $searchString Chapter string to search for can be fixed text, or a regular expression pattern. - * - * @return array with 1 or more parts - */ - function splitChapter($chapter, $splitOnSearchString = false, $searchString = '/^Chapter\\ /i') { - $chapterData = array(); - $isSearchRegexp = $splitOnSearchString && (preg_match('#^(\D|\S|\W).+\1[imsxeADSUXJu]*$#m', $searchString) == 1); - if ($splitOnSearchString && !$isSearchRegexp) { - $searchString = '#^<.+?>' . preg_quote($searchString, '#') . "#"; - } - - if (!$splitOnSearchString && strlen($chapter) <= $this->splitDefaultSize) { - return array($chapter); - } - - $xmlDoc = new DOMDocument(); - @$xmlDoc->loadHTML($chapter); - - $head = $xmlDoc->getElementsByTagName("head"); - $body = $xmlDoc->getElementsByTagName("body"); - - $htmlPos = stripos($chapter, "", $htmlPos); - $newXML = substr($chapter, 0, $htmlEndPos+1) . "\n"; - if (strpos(trim($newXML), "\n" . $newXML; - } - $headerLength = strlen($newXML); - - $files = array(); - $chapterNames = array(); - $domDepth = 0; - $domPath = array(); - $domClonedPath = array(); - - $curFile = $xmlDoc->createDocumentFragment(); - $files[] = $curFile; - $curParent = $curFile; - $curSize = 0; - - $bodyLen = strlen($xmlDoc->saveXML($body->item(0))); - $headLen = strlen($xmlDoc->saveXML($head->item(0))) + $headerLength; - - $partSize = $this->splitDefaultSize - $headLen; - - if ($bodyLen > $partSize) { - $parts = ceil($bodyLen / $partSize); - $partSize = ($bodyLen / $parts) - $headLen; - } - - $node = $body->item(0)->firstChild; - - do { - $nodeData = $xmlDoc->saveXML($node); - $nodeLen = strlen($nodeData); - - if ($nodeLen > $partSize && $node->hasChildNodes()) { - $domPath[] = $node; - $domClonedPath[] = $node->cloneNode(false); - $domDepth++; - - $node = $node->firstChild; - } - - $node2 = $node->nextSibling; - - if ($node != null && $node->nodeName != "#text") { - $doSplit = false; - if ($splitOnSearchString) { - $doSplit = preg_match($searchString, $nodeData) == 1; - if ($doSplit) { - $chapterNames[] = trim($nodeData); - } - } - - if ($curSize > 0 && ($doSplit || (!$splitOnSearchString && $curSize + $nodeLen > $partSize))) { - $curFile = $xmlDoc->createDocumentFragment(); - $files[] = $curFile; - $curParent = $curFile; - if ($domDepth > 0) { - reset($domPath); - reset($domClonedPath); - $oneDomClonedPath = each($domClonedPath); - while ($oneDomClonedPath) { - list($k, $v) = $oneDomClonedPath; - $newParent = $v->cloneNode(false); - $curParent->appendChild($newParent); - $curParent = $newParent; - $oneDomClonedPath = each($domClonedPath); - } - } - $curSize = strlen($xmlDoc->saveXML($curFile)); - } - $curParent->appendChild($node->cloneNode(true)); - $curSize += $nodeLen; - } - - $node = $node2; - while ($node == null && $domDepth > 0) { - $domDepth--; - $node = end($domPath)->nextSibling; - array_pop($domPath); - array_pop($domClonedPath); - $curParent = $curParent->parentNode; - } - } while ($node != null); - - $curFile = null; - $curSize = 0; - - $xml = new DOMDocument('1.0', $xmlDoc->xmlEncoding); - $xml->lookupPrefix("http://www.w3.org/1999/xhtml"); - $xml->preserveWhiteSpace = false; - $xml->formatOutput = true; - - for ($idx = 0; $idx < count($files); $idx++) { - $xml2Doc = new DOMDocument('1.0', $xmlDoc->xmlEncoding); - $xml2Doc->lookupPrefix("http://www.w3.org/1999/xhtml"); - $xml2Doc->loadXML($newXML); - $html = $xml2Doc->getElementsByTagName("html")->item(0); - $html->appendChild($xml2Doc->importNode($head->item(0), true)); - $body = $xml2Doc->createElement("body"); - $html->appendChild($body); - $body->appendChild($xml2Doc->importNode($files[$idx], true)); - - // force pretty printing and correct formatting, should not be needed, but it is. - $xml->loadXML($xml2Doc->saveXML()); - - $doc = $xml->saveXML(); - - if ($this->bookVersion === EPub::BOOK_VERSION_EPUB3) { - $doc = preg_replace('#^\s*\s*#im', '', $doc); - } - - $chapterData[$splitOnSearchString ? $chapterNames[$idx] : $idx] = $doc; - } - - return $chapterData; - } -} -?> diff --git a/inc/3rdparty/libraries/PHPePub/Logger.php b/inc/3rdparty/libraries/PHPePub/Logger.php deleted file mode 100644 index 314019cb..00000000 --- a/inc/3rdparty/libraries/PHPePub/Logger.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright 2012-2013 A. Grandt - * @license GNU LGPL, Attribution required for commercial implementations, requested for everything else. - * @version 1.00 - */ -class Logger { - const VERSION = 1.00; - - private $log = ""; - private $tStart; - private $tLast; - private $name = NULL; - private $isLogging = FALSE; - private $isDebugging = FALSE; - - /** - * Class constructor. - * - * @return void - */ - function __construct($name = NULL, $isLogging = FALSE) { - if ($name === NULL) { - $this->name = ""; - } else { - $this->name = $name . " : "; - } - $this->isLogging = $isLogging; - $this->start(); - } - - /** - * Class destructor - * - * @return void - * @TODO make sure elements in the destructor match the current class elements - */ - function __destruct() { - unset($this->log); - } - - function start() { - /* Prepare Logging. Just in case it's used. later */ - if ($this->isLogging) { - $this->tStart = gettimeofday(); - $this->tLast = $this->tStart; - $this->log = "

    Log: " . $this->name . "

    \n
    Started: " . gmdate("D, d M Y H:i:s T", $this->tStart['sec']) . "\n Δ Start ;  Δ Last  ;";
    -			$this->logLine("Start");
    -		}
    -    }
    -
    -    function dumpInstalledModules() {
    -        if ($this->isLogging) {
    -            $isCurlInstalled = extension_loaded('curl') && function_exists('curl_version');
    -            $isGdInstalled = extension_loaded('gd') && function_exists('gd_info');
    -            $isExifInstalled = extension_loaded('exif') && function_exists('exif_imagetype');
    -            $isFileGetContentsInstalled = function_exists('file_get_contents');
    -            $isFileGetContentsExtInstalled = $isFileGetContentsInstalled && ini_get('allow_url_fopen');
    -
    -            $this->logLine("isCurlInstalled...............: " . ($isCurlInstalled ? "Yes" : "No"));
    -            $this->logLine("isGdInstalled.................: " . ($isGdInstalled ? "Yes" : "No"));
    -            $this->logLine("isExifInstalled...............: " . ($isExifInstalled ? "Yes" : "No"));
    -            $this->logLine("isFileGetContentsInstalled....: " . ($isFileGetContentsInstalled ? "Yes" : "No"));
    -            $this->logLine("isFileGetContentsExtInstalled.: " . ($isFileGetContentsExtInstalled ? "Yes" : "No"));
    -        }
    -    }
    -
    -    function logLine($line) {
    -        if ($this->isLogging) {
    -            $tTemp = gettimeofday();
    -            $tS = $this->tStart['sec'] + (((int)($this->tStart['usec']/100))/10000);
    -            $tL = $this->tLast['sec'] + (((int)($this->tLast['usec']/100))/10000);
    -            $tT = $tTemp['sec'] + (((int)($tTemp['usec']/100))/10000);
    -
    -			$logline = sprintf("\n+%08.04f; +%08.04f; ", ($tT-$tS), ($tT-$tL)) . $this->name . $line;
    -            $this->log .= $logline;
    -            $this->tLast = $tTemp;
    -
    -		    if ($this->isDebugging) {
    -				echo "
    " . $logline . "\n
    \n"; - } - } - } - - function getLog() { - return $this->log; - } -} -?> \ No newline at end of file diff --git a/inc/3rdparty/libraries/PHPePub/Zip.php b/inc/3rdparty/libraries/PHPePub/Zip.php deleted file mode 100644 index 01e03566..00000000 --- a/inc/3rdparty/libraries/PHPePub/Zip.php +++ /dev/null @@ -1,818 +0,0 @@ - - * @copyright 2009-2014 A. Grandt - * @license GNU LGPL 2.1 - * @link http://www.phpclasses.org/package/6110 - * @link https://github.com/Grandt/PHPZip - * @version 1.60 - */ -class Zip { - const VERSION = 1.60; - - const ZIP_LOCAL_FILE_HEADER = "\x50\x4b\x03\x04"; // Local file header signature - const ZIP_CENTRAL_FILE_HEADER = "\x50\x4b\x01\x02"; // Central file header signature - const ZIP_END_OF_CENTRAL_DIRECTORY = "\x50\x4b\x05\x06\x00\x00\x00\x00"; //end of Central directory record - - const EXT_FILE_ATTR_DIR = 010173200020; // Permission 755 drwxr-xr-x = (((S_IFDIR | 0755) << 16) | S_DOS_D); - const EXT_FILE_ATTR_FILE = 020151000040; // Permission 644 -rw-r--r-- = (((S_IFREG | 0644) << 16) | S_DOS_A); - - const ATTR_VERSION_TO_EXTRACT = "\x14\x00"; // Version needed to extract - const ATTR_MADE_BY_VERSION = "\x1E\x03"; // Made By Version - - // Unix file types - const S_IFIFO = 0010000; // named pipe (fifo) - const S_IFCHR = 0020000; // character special - const S_IFDIR = 0040000; // directory - const S_IFBLK = 0060000; // block special - const S_IFREG = 0100000; // regular - const S_IFLNK = 0120000; // symbolic link - const S_IFSOCK = 0140000; // socket - - // setuid/setgid/sticky bits, the same as for chmod: - - const S_ISUID = 0004000; // set user id on execution - const S_ISGID = 0002000; // set group id on execution - const S_ISTXT = 0001000; // sticky bit - - // And of course, the other 12 bits are for the permissions, the same as for chmod: - // When addding these up, you can also just write the permissions as a simgle octal number - // ie. 0755. The leading 0 specifies octal notation. - const S_IRWXU = 0000700; // RWX mask for owner - const S_IRUSR = 0000400; // R for owner - const S_IWUSR = 0000200; // W for owner - const S_IXUSR = 0000100; // X for owner - const S_IRWXG = 0000070; // RWX mask for group - const S_IRGRP = 0000040; // R for group - const S_IWGRP = 0000020; // W for group - const S_IXGRP = 0000010; // X for group - const S_IRWXO = 0000007; // RWX mask for other - const S_IROTH = 0000004; // R for other - const S_IWOTH = 0000002; // W for other - const S_IXOTH = 0000001; // X for other - const S_ISVTX = 0001000; // save swapped text even after use - - // Filetype, sticky and permissions are added up, and shifted 16 bits left BEFORE adding the DOS flags. - - // DOS file type flags, we really only use the S_DOS_D flag. - - const S_DOS_A = 0000040; // DOS flag for Archive - const S_DOS_D = 0000020; // DOS flag for Directory - const S_DOS_V = 0000010; // DOS flag for Volume - const S_DOS_S = 0000004; // DOS flag for System - const S_DOS_H = 0000002; // DOS flag for Hidden - const S_DOS_R = 0000001; // DOS flag for Read Only - - private $zipMemoryThreshold = 1048576; // Autocreate tempfile if the zip data exceeds 1048576 bytes (1 MB) - - private $zipData = NULL; - private $zipFile = NULL; - private $zipComment = NULL; - private $cdRec = array(); // central directory - private $offset = 0; - private $isFinalized = FALSE; - private $addExtraField = TRUE; - - private $streamChunkSize = 65536; - private $streamFilePath = NULL; - private $streamTimestamp = NULL; - private $streamFileComment = NULL; - private $streamFile = NULL; - private $streamData = NULL; - private $streamFileLength = 0; - private $streamExtFileAttr = null; - - /** - * Constructor. - * - * @param boolean $useZipFile Write temp zip data to tempFile? Default FALSE - */ - function __construct($useZipFile = FALSE) { - if ($useZipFile) { - $this->zipFile = tmpfile(); - } else { - $this->zipData = ""; - } - } - - function __destruct() { - if (is_resource($this->zipFile)) { - fclose($this->zipFile); - } - $this->zipData = NULL; - } - - /** - * Extra fields on the Zip directory records are Unix time codes needed for compatibility on the default Mac zip archive tool. - * These are enabled as default, as they do no harm elsewhere and only add 26 bytes per file added. - * - * @param bool $setExtraField TRUE (default) will enable adding of extra fields, anything else will disable it. - */ - function setExtraField($setExtraField = TRUE) { - $this->addExtraField = ($setExtraField === TRUE); - } - - /** - * Set Zip archive comment. - * - * @param string $newComment New comment. NULL to clear. - * @return bool $success - */ - public function setComment($newComment = NULL) { - if ($this->isFinalized) { - return FALSE; - } - $this->zipComment = $newComment; - - return TRUE; - } - - /** - * Set zip file to write zip data to. - * This will cause all present and future data written to this class to be written to this file. - * This can be used at any time, even after the Zip Archive have been finalized. Any previous file will be closed. - * Warning: If the given file already exists, it will be overwritten. - * - * @param string $fileName - * @return bool $success - */ - public function setZipFile($fileName) { - if (is_file($fileName)) { - unlink($fileName); - } - $fd=fopen($fileName, "x+b"); - if (is_resource($this->zipFile)) { - rewind($this->zipFile); - while (!feof($this->zipFile)) { - fwrite($fd, fread($this->zipFile, $this->streamChunkSize)); - } - - fclose($this->zipFile); - } else { - fwrite($fd, $this->zipData); - $this->zipData = NULL; - } - $this->zipFile = $fd; - - return TRUE; - } - - /** - * Add an empty directory entry to the zip archive. - * Basically this is only used if an empty directory is added. - * - * @param string $directoryPath Directory Path and name to be added to the archive. - * @param int $timestamp (Optional) Timestamp for the added directory, if omitted or set to 0, the current time will be used. - * @param string $fileComment (Optional) Comment to be added to the archive for this directory. To use fileComment, timestamp must be given. - * @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this. - * @return bool $success - */ - public function addDirectory($directoryPath, $timestamp = 0, $fileComment = NULL, $extFileAttr = self::EXT_FILE_ATTR_DIR) { - if ($this->isFinalized) { - return FALSE; - } - $directoryPath = str_replace("\\", "/", $directoryPath); - $directoryPath = rtrim($directoryPath, "/"); - - if (strlen($directoryPath) > 0) { - $this->buildZipEntry($directoryPath.'/', $fileComment, "\x00\x00", "\x00\x00", $timestamp, "\x00\x00\x00\x00", 0, 0, $extFileAttr); - return TRUE; - } - return FALSE; - } - - /** - * Add a file to the archive at the specified location and file name. - * - * @param string $data File data. - * @param string $filePath Filepath and name to be used in the archive. - * @param int $timestamp (Optional) Timestamp for the added file, if omitted or set to 0, the current time will be used. - * @param string $fileComment (Optional) Comment to be added to the archive for this file. To use fileComment, timestamp must be given. - * @param bool $compress (Optional) Compress file, if set to FALSE the file will only be stored. Default TRUE. - * @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this. - * @return bool $success - */ - public function addFile($data, $filePath, $timestamp = 0, $fileComment = NULL, $compress = TRUE, $extFileAttr = self::EXT_FILE_ATTR_FILE) { - if ($this->isFinalized) { - return FALSE; - } - - if (is_resource($data) && get_resource_type($data) == "stream") { - $this->addLargeFile($data, $filePath, $timestamp, $fileComment, $extFileAttr); - return FALSE; - } - - $gzData = ""; - $gzType = "\x08\x00"; // Compression type 8 = deflate - $gpFlags = "\x00\x00"; // General Purpose bit flags for compression type 8 it is: 0=Normal, 1=Maximum, 2=Fast, 3=super fast compression. - $dataLength = strlen($data); - $fileCRC32 = pack("V", crc32($data)); - - if ($compress) { - $gzTmp = gzcompress($data); - $gzData = substr(substr($gzTmp, 0, strlen($gzTmp) - 4), 2); // gzcompress adds a 2 byte header and 4 byte CRC we can't use. - // The 2 byte header does contain useful data, though in this case the 2 parameters we'd be interrested in will always be 8 for compression type, and 2 for General purpose flag. - $gzLength = strlen($gzData); - } else { - $gzLength = $dataLength; - } - - if ($gzLength >= $dataLength) { - $gzLength = $dataLength; - $gzData = $data; - $gzType = "\x00\x00"; // Compression type 0 = stored - $gpFlags = "\x00\x00"; // Compression type 0 = stored - } - - if (!is_resource($this->zipFile) && ($this->offset + $gzLength) > $this->zipMemoryThreshold) { - $this->zipflush(); - } - - $this->buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, $extFileAttr); - - $this->zipwrite($gzData); - - return TRUE; - } - - /** - * Add the content to a directory. - * - * @author Adam Schmalhofer - * @author A. Grandt - * - * @param string $realPath Path on the file system. - * @param string $zipPath Filepath and name to be used in the archive. - * @param bool $recursive Add content recursively, default is TRUE. - * @param bool $followSymlinks Follow and add symbolic links, if they are accessible, default is TRUE. - * @param array &$addedFiles Reference to the added files, this is used to prevent duplicates, efault is an empty array. - * If you start the function by parsing an array, the array will be populated with the realPath - * and zipPath kay/value pairs added to the archive by the function. - * @param bool $overrideFilePermissions Force the use of the file/dir permissions set in the $extDirAttr - * and $extFileAttr parameters. - * @param int $extDirAttr Permissions for directories. - * @param int $extFileAttr Permissions for files. - */ - public function addDirectoryContent($realPath, $zipPath, $recursive = TRUE, $followSymlinks = TRUE, &$addedFiles = array(), - $overrideFilePermissions = FALSE, $extDirAttr = self::EXT_FILE_ATTR_DIR, $extFileAttr = self::EXT_FILE_ATTR_FILE) { - if (file_exists($realPath) && !isset($addedFiles[realpath($realPath)])) { - if (is_dir($realPath)) { - if ($overrideFilePermissions) { - $this->addDirectory($zipPath, 0, null, $extDirAttr); - } else { - $this->addDirectory($zipPath, 0, null, self::getFileExtAttr($realPath)); - } - } - - $addedFiles[realpath($realPath)] = $zipPath; - - $iter = new DirectoryIterator($realPath); - foreach ($iter as $file) { - if ($file->isDot()) { - continue; - } - $newRealPath = $file->getPathname(); - $newZipPath = self::pathJoin($zipPath, $file->getFilename()); - - if (file_exists($newRealPath) && ($followSymlinks === TRUE || !is_link($newRealPath))) { - if ($file->isFile()) { - $addedFiles[realpath($newRealPath)] = $newZipPath; - if ($overrideFilePermissions) { - $this->addLargeFile($newRealPath, $newZipPath, 0, null, $extFileAttr); - } else { - $this->addLargeFile($newRealPath, $newZipPath, 0, null, self::getFileExtAttr($newRealPath)); - } - } else if ($recursive === TRUE) { - $this->addDirectoryContent($newRealPath, $newZipPath, $recursive, $followSymlinks, $addedFiles, $overrideFilePermissions, $extDirAttr, $extFileAttr); - } else { - if ($overrideFilePermissions) { - $this->addDirectory($zipPath, 0, null, $extDirAttr); - } else { - $this->addDirectory($zipPath, 0, null, self::getFileExtAttr($newRealPath)); - } - } - } - } - } - } - - /** - * Add a file to the archive at the specified location and file name. - * - * @param string $dataFile File name/path. - * @param string $filePath Filepath and name to be used in the archive. - * @param int $timestamp (Optional) Timestamp for the added file, if omitted or set to 0, the current time will be used. - * @param string $fileComment (Optional) Comment to be added to the archive for this file. To use fileComment, timestamp must be given. - * @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this. - * @return bool $success - */ - public function addLargeFile($dataFile, $filePath, $timestamp = 0, $fileComment = NULL, $extFileAttr = self::EXT_FILE_ATTR_FILE) { - if ($this->isFinalized) { - return FALSE; - } - - if (is_string($dataFile) && is_file($dataFile)) { - $this->processFile($dataFile, $filePath, $timestamp, $fileComment, $extFileAttr); - } else if (is_resource($dataFile) && get_resource_type($dataFile) == "stream") { - $fh = $dataFile; - $this->openStream($filePath, $timestamp, $fileComment, $extFileAttr); - - while (!feof($fh)) { - $this->addStreamData(fread($fh, $this->streamChunkSize)); - } - $this->closeStream($this->addExtraField); - } - return TRUE; - } - - /** - * Create a stream to be used for large entries. - * - * @param string $filePath Filepath and name to be used in the archive. - * @param int $timestamp (Optional) Timestamp for the added file, if omitted or set to 0, the current time will be used. - * @param string $fileComment (Optional) Comment to be added to the archive for this file. To use fileComment, timestamp must be given. - * @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this. - * @return bool $success - */ - public function openStream($filePath, $timestamp = 0, $fileComment = null, $extFileAttr = self::EXT_FILE_ATTR_FILE) { - if (!function_exists('sys_get_temp_dir')) { - die ("ERROR: Zip " . self::VERSION . " requires PHP version 5.2.1 or above if large files are used."); - } - - if ($this->isFinalized) { - return FALSE; - } - - $this->zipflush(); - - if (strlen($this->streamFilePath) > 0) { - $this->closeStream(); - } - - $this->streamFile = tempnam(sys_get_temp_dir(), 'Zip'); - $this->streamData = fopen($this->streamFile, "wb"); - $this->streamFilePath = $filePath; - $this->streamTimestamp = $timestamp; - $this->streamFileComment = $fileComment; - $this->streamFileLength = 0; - $this->streamExtFileAttr = $extFileAttr; - - return TRUE; - } - - /** - * Add data to the open stream. - * - * @param string $data - * @return mixed length in bytes added or FALSE if the archive is finalized or there are no open stream. - */ - public function addStreamData($data) { - if ($this->isFinalized || strlen($this->streamFilePath) == 0) { - return FALSE; - } - - $length = fwrite($this->streamData, $data, strlen($data)); - if ($length != strlen($data)) { - die ("

    Length mismatch

    \n"); - } - $this->streamFileLength += $length; - - return $length; - } - - /** - * Close the current stream. - * - * @return bool $success - */ - public function closeStream() { - if ($this->isFinalized || strlen($this->streamFilePath) == 0) { - return FALSE; - } - - fflush($this->streamData); - fclose($this->streamData); - - $this->processFile($this->streamFile, $this->streamFilePath, $this->streamTimestamp, $this->streamFileComment, $this->streamExtFileAttr); - - $this->streamData = null; - $this->streamFilePath = null; - $this->streamTimestamp = null; - $this->streamFileComment = null; - $this->streamFileLength = 0; - $this->streamExtFileAttr = null; - - // Windows is a little slow at times, so a millisecond later, we can unlink this. - unlink($this->streamFile); - - $this->streamFile = null; - - return TRUE; - } - - private function processFile($dataFile, $filePath, $timestamp = 0, $fileComment = null, $extFileAttr = self::EXT_FILE_ATTR_FILE) { - if ($this->isFinalized) { - return FALSE; - } - - $tempzip = tempnam(sys_get_temp_dir(), 'ZipStream'); - - $zip = new ZipArchive; - if ($zip->open($tempzip) === TRUE) { - $zip->addFile($dataFile, 'file'); - $zip->close(); - } - - $file_handle = fopen($tempzip, "rb"); - $stats = fstat($file_handle); - $eof = $stats['size']-72; - - fseek($file_handle, 6); - - $gpFlags = fread($file_handle, 2); - $gzType = fread($file_handle, 2); - fread($file_handle, 4); - $fileCRC32 = fread($file_handle, 4); - $v = unpack("Vval", fread($file_handle, 4)); - $gzLength = $v['val']; - $v = unpack("Vval", fread($file_handle, 4)); - $dataLength = $v['val']; - - $this->buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, $extFileAttr); - - fseek($file_handle, 34); - $pos = 34; - - while (!feof($file_handle) && $pos < $eof) { - $datalen = $this->streamChunkSize; - if ($pos + $this->streamChunkSize > $eof) { - $datalen = $eof-$pos; - } - $data = fread($file_handle, $datalen); - $pos += $datalen; - - $this->zipwrite($data); - } - - fclose($file_handle); - - unlink($tempzip); - } - - /** - * Close the archive. - * A closed archive can no longer have new files added to it. - * - * @return bool $success - */ - public function finalize() { - if (!$this->isFinalized) { - if (strlen($this->streamFilePath) > 0) { - $this->closeStream(); - } - $cd = implode("", $this->cdRec); - - $cdRecSize = pack("v", sizeof($this->cdRec)); - $cdRec = $cd . self::ZIP_END_OF_CENTRAL_DIRECTORY - . $cdRecSize . $cdRecSize - . pack("VV", strlen($cd), $this->offset); - if (!empty($this->zipComment)) { - $cdRec .= pack("v", strlen($this->zipComment)) . $this->zipComment; - } else { - $cdRec .= "\x00\x00"; - } - - $this->zipwrite($cdRec); - - $this->isFinalized = TRUE; - $this->cdRec = NULL; - - return TRUE; - } - return FALSE; - } - - /** - * Get the handle ressource for the archive zip file. - * If the zip haven't been finalized yet, this will cause it to become finalized - * - * @return zip file handle - */ - public function getZipFile() { - if (!$this->isFinalized) { - $this->finalize(); - } - - $this->zipflush(); - - rewind($this->zipFile); - - return $this->zipFile; - } - - /** - * Get the zip file contents - * If the zip haven't been finalized yet, this will cause it to become finalized - * - * @return zip data - */ - public function getZipData() { - if (!$this->isFinalized) { - $this->finalize(); - } - if (!is_resource($this->zipFile)) { - return $this->zipData; - } else { - rewind($this->zipFile); - $filestat = fstat($this->zipFile); - return fread($this->zipFile, $filestat['size']); - } - } - - /** - * Send the archive as a zip download - * - * @param String $fileName The name of the Zip archive, in ISO-8859-1 (or ASCII) encoding, ie. "archive.zip". Optional, defaults to NULL, which means that no ISO-8859-1 encoded file name will be specified. - * @param String $contentType Content mime type. Optional, defaults to "application/zip". - * @param String $utf8FileName The name of the Zip archive, in UTF-8 encoding. Optional, defaults to NULL, which means that no UTF-8 encoded file name will be specified. - * @param bool $inline Use Content-Disposition with "inline" instead of "attached". Optional, defaults to FALSE. - * @return bool $success - */ - function sendZip($fileName = null, $contentType = "application/zip", $utf8FileName = null, $inline = false) { - if (!$this->isFinalized) { - $this->finalize(); - } - - $headerFile = null; - $headerLine = null; - if (!headers_sent($headerFile, $headerLine) or die("

    Error: Unable to send file $fileName. HTML Headers have already been sent from $headerFile in line $headerLine

    ")) { - if ((ob_get_contents() === FALSE || ob_get_contents() == '') or die("\n

    Error: Unable to send file $fileName. Output buffer contains the following text (typically warnings or errors):
    " . htmlentities(ob_get_contents()) . "

    ")) { - if (ini_get('zlib.output_compression')) { - ini_set('zlib.output_compression', 'Off'); - } - - header("Pragma: public"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s T")); - header("Expires: 0"); - header("Accept-Ranges: bytes"); - header("Connection: close"); - header("Content-Type: " . $contentType); - $cd = "Content-Disposition: "; - if ($inline) { - $cd .= "inline"; - } else{ - $cd .= "attached"; - } - if ($fileName) { - $cd .= '; filename="' . $fileName . '"'; - } - if ($utf8FileName) { - $cd .= "; filename*=UTF-8''" . rawurlencode($utf8FileName); - } - header($cd); - header("Content-Length: ". $this->getArchiveSize()); - - if (!is_resource($this->zipFile)) { - echo $this->zipData; - } else { - rewind($this->zipFile); - - while (!feof($this->zipFile)) { - echo fread($this->zipFile, $this->streamChunkSize); - } - } - } - return TRUE; - } - return FALSE; - } - - /** - * Return the current size of the archive - * - * @return $size Size of the archive - */ - public function getArchiveSize() { - if (!is_resource($this->zipFile)) { - return strlen($this->zipData); - } - $filestat = fstat($this->zipFile); - - return $filestat['size']; - } - - /** - * Calculate the 2 byte dostime used in the zip entries. - * - * @param int $timestamp - * @return 2-byte encoded DOS Date - */ - private function getDosTime($timestamp = 0) { - $timestamp = (int)$timestamp; - $oldTZ = @date_default_timezone_get(); - date_default_timezone_set('UTC'); - $date = ($timestamp == 0 ? getdate() : getdate($timestamp)); - date_default_timezone_set($oldTZ); - if ($date["year"] >= 1980) { - return pack("V", (($date["mday"] + ($date["mon"] << 5) + (($date["year"]-1980) << 9)) << 16) | - (($date["seconds"] >> 1) + ($date["minutes"] << 5) + ($date["hours"] << 11))); - } - return "\x00\x00\x00\x00"; - } - - /** - * Build the Zip file structures - * - * @param string $filePath - * @param string $fileComment - * @param string $gpFlags - * @param string $gzType - * @param int $timestamp - * @param string $fileCRC32 - * @param int $gzLength - * @param int $dataLength - * @param int $extFileAttr Use self::EXT_FILE_ATTR_FILE for files, self::EXT_FILE_ATTR_DIR for Directories. - */ - private function buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, $extFileAttr) { - $filePath = str_replace("\\", "/", $filePath); - $fileCommentLength = (empty($fileComment) ? 0 : strlen($fileComment)); - $timestamp = (int)$timestamp; - $timestamp = ($timestamp == 0 ? time() : $timestamp); - - $dosTime = $this->getDosTime($timestamp); - $tsPack = pack("V", $timestamp); - - $ux = "\x75\x78\x0B\x00\x01\x04\xE8\x03\x00\x00\x04\x00\x00\x00\x00"; - - if (!isset($gpFlags) || strlen($gpFlags) != 2) { - $gpFlags = "\x00\x00"; - } - - $isFileUTF8 = mb_check_encoding($filePath, "UTF-8") && !mb_check_encoding($filePath, "ASCII"); - $isCommentUTF8 = !empty($fileComment) && mb_check_encoding($fileComment, "UTF-8") && !mb_check_encoding($fileComment, "ASCII"); - if ($isFileUTF8 || $isCommentUTF8) { - $flag = 0; - $gpFlagsV = unpack("vflags", $gpFlags); - if (isset($gpFlagsV['flags'])) { - $flag = $gpFlagsV['flags']; - } - $gpFlags = pack("v", $flag | (1 << 11)); - } - - $header = $gpFlags . $gzType . $dosTime. $fileCRC32 - . pack("VVv", $gzLength, $dataLength, strlen($filePath)); // File name length - - $zipEntry = self::ZIP_LOCAL_FILE_HEADER; - $zipEntry .= self::ATTR_VERSION_TO_EXTRACT; - $zipEntry .= $header; - $zipEntry .= pack("v", ($this->addExtraField ? 28 : 0)); // Extra field length - $zipEntry .= $filePath; // FileName - // Extra fields - if ($this->addExtraField) { - $zipEntry .= "\x55\x54\x09\x00\x03" . $tsPack . $tsPack . $ux; - } - $this->zipwrite($zipEntry); - - $cdEntry = self::ZIP_CENTRAL_FILE_HEADER; - $cdEntry .= self::ATTR_MADE_BY_VERSION; - $cdEntry .= ($dataLength === 0 ? "\x0A\x00" : self::ATTR_VERSION_TO_EXTRACT); - $cdEntry .= $header; - $cdEntry .= pack("v", ($this->addExtraField ? 24 : 0)); // Extra field length - $cdEntry .= pack("v", $fileCommentLength); // File comment length - $cdEntry .= "\x00\x00"; // Disk number start - $cdEntry .= "\x00\x00"; // internal file attributes - $cdEntry .= pack("V", $extFileAttr); // External file attributes - $cdEntry .= pack("V", $this->offset); // Relative offset of local header - $cdEntry .= $filePath; // FileName - // Extra fields - if ($this->addExtraField) { - $cdEntry .= "\x55\x54\x05\x00\x03" . $tsPack . $ux; - } - if (!empty($fileComment)) { - $cdEntry .= $fileComment; // Comment - } - - $this->cdRec[] = $cdEntry; - $this->offset += strlen($zipEntry) + $gzLength; - } - - private function zipwrite($data) { - if (!is_resource($this->zipFile)) { - $this->zipData .= $data; - } else { - fwrite($this->zipFile, $data); - fflush($this->zipFile); - } - } - - private function zipflush() { - if (!is_resource($this->zipFile)) { - $this->zipFile = tmpfile(); - fwrite($this->zipFile, $this->zipData); - $this->zipData = NULL; - } - } - - /** - * Join $file to $dir path, and clean up any excess slashes. - * - * @param string $dir - * @param string $file - */ - public static function pathJoin($dir, $file) { - if (empty($dir) || empty($file)) { - return self::getRelativePath($dir . $file); - } - return self::getRelativePath($dir . '/' . $file); - } - - /** - * Clean up a path, removing any unnecessary elements such as /./, // or redundant ../ segments. - * If the path starts with a "/", it is deemed an absolute path and any /../ in the beginning is stripped off. - * The returned path will not end in a "/". - * - * Sometimes, when a path is generated from multiple fragments, - * you can get something like "../data/html/../images/image.jpeg" - * This will normalize that example path to "../data/images/image.jpeg" - * - * @param string $path The path to clean up - * @return string the clean path - */ - public static function getRelativePath($path) { - $path = preg_replace("#/+\.?/+#", "/", str_replace("\\", "/", $path)); - $dirs = explode("/", rtrim(preg_replace('#^(?:\./)+#', '', $path), '/')); - - $offset = 0; - $sub = 0; - $subOffset = 0; - $root = ""; - - if (empty($dirs[0])) { - $root = "/"; - $dirs = array_splice($dirs, 1); - } else if (preg_match("#[A-Za-z]:#", $dirs[0])) { - $root = strtoupper($dirs[0]) . "/"; - $dirs = array_splice($dirs, 1); - } - - $newDirs = array(); - foreach ($dirs as $dir) { - if ($dir !== "..") { - $subOffset--; - $newDirs[++$offset] = $dir; - } else { - $subOffset++; - if (--$offset < 0) { - $offset = 0; - if ($subOffset > $sub) { - $sub++; - } - } - } - } - - if (empty($root)) { - $root = str_repeat("../", $sub); - } - return $root . implode("/", array_slice($newDirs, 0, $offset)); - } - - /** - * Create the file permissions for a file or directory, for use in the extFileAttr parameters. - * - * @param int $owner Unix permisions for owner (octal from 00 to 07) - * @param int $group Unix permisions for group (octal from 00 to 07) - * @param int $other Unix permisions for others (octal from 00 to 07) - * @param bool $isFile - * @return EXTRERNAL_REF field. - */ - public static function generateExtAttr($owner = 07, $group = 05, $other = 05, $isFile = true) { - $fp = $isFile ? self::S_IFREG : self::S_IFDIR; - $fp |= (($owner & 07) << 6) | (($group & 07) << 3) | ($other & 07); - - return ($fp << 16) | ($isFile ? self::S_DOS_A : self::S_DOS_D); - } - - /** - * Get the file permissions for a file or directory, for use in the extFileAttr parameters. - * - * @param string $filename - * @return external ref field, or FALSE if the file is not found. - */ - public static function getFileExtAttr($filename) { - if (file_exists($filename)) { - $fp = fileperms($filename) << 16; - return $fp | (is_dir($filename) ? self::S_DOS_D : self::S_DOS_A); - } - return FALSE; - } -} -?> diff --git a/inc/3rdparty/libraries/PHPePub/lib.uuid.LICENCE.txt b/inc/3rdparty/libraries/PHPePub/lib.uuid.LICENCE.txt deleted file mode 100644 index 9424a83e..00000000 --- a/inc/3rdparty/libraries/PHPePub/lib.uuid.LICENCE.txt +++ /dev/null @@ -1,31 +0,0 @@ - DrUUID RFC4122 library for PHP5 - by J. King (http://jkingweb.ca/) - Licensed under MIT license - - See http://jkingweb.ca/code/php/lib.uuid/ - for documentation - - Last revised 2010-02-15 - -Copyright (c) 2009 J. King - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/inc/3rdparty/libraries/PHPePub/lib.uuid.php b/inc/3rdparty/libraries/PHPePub/lib.uuid.php deleted file mode 100644 index c6a8de52..00000000 --- a/inc/3rdparty/libraries/PHPePub/lib.uuid.php +++ /dev/null @@ -1,314 +0,0 @@ -string; - } - - public function __get($var) { - switch($var) { - case "bytes": - return $this->bytes; - case "hex": - return bin2hex($this->bytes); - case "string": - return $this->__toString(); - case "urn": - return "urn:uuid:".$this->__toString(); - case "version": - return ord($this->bytes[6]) >> 4; - case "variant": - $byte = ord($this->bytes[8]); - if ($byte >= self::varRes) { - return 3; - } - if ($byte >= self::varMS) { - return 2; - } - if ($byte >= self::varRFC) { - return 1; - } - return 0; - case "node": - if (ord($this->bytes[6])>>4==1) { - return bin2hex(substr($this->bytes,10)); - } else { - return NULL; - } - case "time": - if (ord($this->bytes[6])>>4==1) { - // Restore contiguous big-endian byte order - $time = bin2hex($this->bytes[6].$this->bytes[7].$this->bytes[4].$this->bytes[5].$this->bytes[0].$this->bytes[1].$this->bytes[2].$this->bytes[3]); - // Clear version flag - $time[0] = "0"; - // Do some reverse arithmetic to get a Unix timestamp - $time = (hexdec($time) - self::interval) / 10000000; - return $time; - } else { - return NULL; - } - default: - return NULL; - } - } - - protected function __construct($uuid) { - if (strlen($uuid) != 16) { - throw new UUIDException("Input must be a 128-bit integer."); - } - $this->bytes = $uuid; - // Optimize the most common use - $this->string = - bin2hex(substr($uuid,0,4))."-". - bin2hex(substr($uuid,4,2))."-". - bin2hex(substr($uuid,6,2))."-". - bin2hex(substr($uuid,8,2))."-". - bin2hex(substr($uuid,10,6)); - } - - protected static function mintTime($node = NULL) { - /* Generates a Version 1 UUID. - These are derived from the time at which they were generated. */ - // Get time since Gregorian calendar reform in 100ns intervals - // This is exceedingly difficult because of PHP's (and pack()'s) - // integer size limits. - // Note that this will never be more accurate than to the microsecond. - $time = microtime(1) * 10000000 + self::interval; - // Convert to a string representation - $time = sprintf("%F", $time); - preg_match("/^\d+/", $time, $time); //strip decimal point - // And now to a 64-bit binary representation - $time = base_convert($time[0], 10, 16); - $time = pack("H*", str_pad($time, 16, "0", STR_PAD_LEFT)); - // Reorder bytes to their proper locations in the UUID - $uuid = $time[4].$time[5].$time[6].$time[7].$time[2].$time[3].$time[0].$time[1]; - // Generate a random clock sequence - $uuid .= self::randomBytes(2); - // set variant - $uuid[8] = chr(ord($uuid[8]) & self::clearVar | self::varRFC); - // set version - $uuid[6] = chr(ord($uuid[6]) & self::clearVer | self::version1); - // Set the final 'node' parameter, a MAC address - if ($node) { - $node = self::makeBin($node, 6); - } - if (!$node) { - // If no node was provided or if the node was invalid, - // generate a random MAC address and set the multicast bit - $node = self::randomBytes(6); - $node[0] = pack("C", ord($node[0]) | 1); - } - $uuid .= $node; - return $uuid; - } - - protected static function mintRand() { - /* Generate a Version 4 UUID. - These are derived soly from random numbers. */ - // generate random fields - $uuid = self::randomBytes(16); - // set variant - $uuid[8] = chr(ord($uuid[8]) & self::clearVar | self::varRFC); - // set version - $uuid[6] = chr(ord($uuid[6]) & self::clearVer | self::version4); - return $uuid; - } - - protected static function mintName($ver, $node, $ns) { - /* Generates a Version 3 or Version 5 UUID. - These are derived from a hash of a name and its namespace, in binary form. */ - if (!$node) { - throw new UUIDException("A name-string is required for Version 3 or 5 UUIDs."); - } - // if the namespace UUID isn't binary, make it so - $ns = self::makeBin($ns, 16); - if (!$ns) { - throw new UUIDException("A binary namespace is required for Version 3 or 5 UUIDs."); - } - $uuid = null; - $version = self::version3; - switch($ver) { - case self::MD5: - $version = self::version3; - $uuid = md5($ns.$node,1); - break; - case self::SHA1: - $version = self::version5; - $uuid = substr(sha1($ns.$node,1),0, 16); - break; - } - // set variant - $uuid[8] = chr(ord($uuid[8]) & self::clearVar | self::varRFC); - // set version - $uuid[6] = chr(ord($uuid[6]) & self::clearVer | $version); - return ($uuid); - } - - protected static function makeBin($str, $len) { - /* Insure that an input string is either binary or hexadecimal. - Returns binary representation, or false on failure. */ - if ($str instanceof self) { - return $str->bytes; - } - if (strlen($str)==$len) { - return $str; - } else { - $str = preg_replace("/^urn:uuid:/is", "", $str); // strip URN scheme and namespace - } - $str = preg_replace("/[^a-f0-9]/is", "", $str); // strip non-hex characters - if (strlen($str) != ($len * 2)) { - return FALSE; - } else { - return pack("H*", $str); - } - } - - public static function initRandom() { - /* Look for a system-provided source of randomness, which is usually crytographically secure. - /dev/urandom is tried first simply out of bias for Linux systems. */ - if (is_readable('/dev/urandom')) { - self::$randomSource = fopen('/dev/urandom', 'rb'); - self::$randomFunc = 'randomFRead'; - } - else if (class_exists('COM', 0)) { - try { - self::$randomSource = new COM('CAPICOM.Utilities.1'); // See http://msdn.microsoft.com/en-us/library/aa388182(VS.85).aspx - self::$randomFunc = 'randomCOM'; - } - catch(Exception $e) { - } - } - return self::$randomFunc; - } - - public static function randomBytes($bytes) { - return call_user_func(array('self', self::$randomFunc), $bytes); - } - - protected static function randomTwister($bytes) { - /* Get the specified number of random bytes, using mt_rand(). - Randomness is returned as a string of bytes. */ - $rand = ""; - for ($a = 0; $a < $bytes; $a++) { - $rand .= chr(mt_rand(0, 255)); - } - return $rand; - } - - protected static function randomFRead($bytes) { - /* Get the specified number of random bytes using a file handle - previously opened with UUID::initRandom(). - Randomness is returned as a string of bytes. */ - return fread(self::$randomSource, $bytes); - } - - protected static function randomCOM($bytes) { - /* Get the specified number of random bytes using Windows' - randomness source via a COM object previously created by UUID::initRandom(). - Randomness is returned as a string of bytes. */ - return base64_decode(self::$randomSource->GetRandom($bytes,0)); // straight binary mysteriously doesn't work, hence the base64 - } -} - -class UUIDException extends Exception { -} -- cgit v1.2.3