diff --git a/composer.json b/composer.json
index d350f1d1e..7f0a75ea6 100644
--- a/composer.json
+++ b/composer.json
@@ -34,6 +34,10 @@
{
"type": "vcs",
"url": "https://github.com/wallabag/pagination"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/wallabag/PHPePub"
}
],
"require": {
@@ -43,10 +47,11 @@
"fabpot/goutte": "2.0.*@dev",
"ezyang/htmlpurifier": "dev-master",
"mgargano/simplehtmldom": "dev-master",
+ "robmorgan/phinx": "*",
"wallabag/PHP-Flash-Messages": "dev-master",
"wallabag/kriss_php5": "dev-master",
"wallabag/pagination": "dev-master",
- "robmorgan/phinx": "*"
+ "wallabag/PHPePub": "dev-master"
},
"require-dev": {
"phpunit/phpunit": "~3.7"
diff --git a/composer.lock b/composer.lock
index 64f86e3de..b1a864b96 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "256d4b68ab2de1b3aa0dea820f3acdb0",
+ "hash": "376dd2761a2a44043b834a7cb5897e37",
"packages": [
{
"name": "ezyang/htmlpurifier",
@@ -1595,6 +1595,50 @@
"description": "The Twig Gettext Extractor is Poedit friendly tool which extracts translations from twig templates.",
"time": "2013-02-14 16:41:48"
},
+ {
+ "name": "wallabag/PHPePub",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/wallabag/PHPePub.git",
+ "reference": "7c78733d33344308520758d7f3f7bc2cc51b3512"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/wallabag/PHPePub/zipball/7c78733d33344308520758d7f3f7bc2cc51b3512",
+ "reference": "7c78733d33344308520758d7f3f7bc2cc51b3512",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "EPub.php",
+ "EPub.HtmlEntities.php",
+ "EPub.NCX.php",
+ "EPub.OPF.php",
+ "EPubChapterSplitter.php",
+ "lib.uuid.php",
+ "Logger.php",
+ "Zip.php"
+ ]
+ },
+ "authors": [
+ {
+ "name": "Nicolas Lœuillet",
+ "email": "nicolas@loeuillet.org",
+ "homepage": "http://www.cdetc.fr"
+ }
+ ],
+ "description": "PHP Classes for dynamically generating EPub files.",
+ "homepage": "https://github.com/wallabag/PHPePub",
+ "support": {
+ "source": "https://github.com/wallabag/PHPePub/tree/master"
+ },
+ "time": "2015-01-19 11:44:19"
+ },
{
"name": "wallabag/kriss_php5",
"version": "dev-master",
@@ -2092,7 +2136,8 @@
"mgargano/simplehtmldom": 20,
"wallabag/php-flash-messages": 20,
"wallabag/kriss_php5": 20,
- "wallabag/pagination": 20
+ "wallabag/pagination": 20,
+ "wallabag/phpepub": 20
},
"prefer-stable": false,
"prefer-lowest": false,
diff --git a/inc/3rdparty/libraries/PHPePub/EPub.HtmlEntities.php b/inc/3rdparty/libraries/PHPePub/EPub.HtmlEntities.php
deleted file mode 100644
index 376b61336..000000000
--- 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 e5da05cdb..000000000
--- 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 .= "
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.
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\t<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 " . str_repeat(" ", $level) . "sanitizeFileName($fileName) . "\">" . $chapterName . "
\n"; - } - } else if ($this->tocAddReferences === TRUE) { - if (array_key_exists($item, $this->ncx->referencesList)) { - $tocData .= "\t\n"; - } else if ($item === "toc") { - $tocData .= "\t\n"; - } else if ($item === "cover" && $this->isCoverImageSet) { - $tocData .= "\t\n"; - } - } - } - $tocData .= "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 01e035662..000000000 --- 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("\nError: Unable to send file $fileName. Output buffer contains the following text (typically warnings or errors):
")) { - 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 9424a83e7..000000000 --- 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 c6a8de523..000000000 --- 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 { -} diff --git a/inc/poche/global.inc.php b/inc/poche/global.inc.php index c17d54e63..308a416f1 100755 --- a/inc/poche/global.inc.php +++ b/inc/poche/global.inc.php @@ -25,22 +25,13 @@ require_once INCLUDES . '/poche/WallabagEBooks.class.php'; require_once INCLUDES . '/poche/Poche.class.php'; require_once INCLUDES . '/poche/Database.class.php'; -require_once INCLUDES . '/3rdparty/paginator.php'; +require_once INCLUDES . '/poche/FlattrItem.class.php'; require_once INCLUDES . '/3rdparty/libraries/feedwriter/FeedItem.php'; require_once INCLUDES . '/3rdparty/libraries/feedwriter/FeedWriter.php'; -require_once INCLUDES . '/poche/FlattrItem.class.php'; - -# epub library -require_once INCLUDES . '/3rdparty/libraries/PHPePub/Logger.php'; -require_once INCLUDES . '/3rdparty/libraries/PHPePub/EPub.php'; -require_once INCLUDES . '/3rdparty/libraries/PHPePub/EPubChapterSplitter.php'; - # mobi library require_once INCLUDES . '/3rdparty/libraries/MOBIClass/MOBI.php'; - # pdf library -#require_once INCLUDES . '/3rdparty/libraries/mpdf/mpdf.php'; require_once INCLUDES . '/3rdparty/libraries/tcpdf/tcpdf.php'; # system configuration; database credentials et caetera
" . htmlentities(ob_get_contents()) . "