View source
<?php
module_load_include('inc', 'epub', '/includes/epub.field');
function epub_file_mimetype_mapping_alter(&$mapping) {
$new_mappings['epub'] = 'application/epub+zip';
$new_mappings['ibooks'] = 'application/x-ibooks+zip';
foreach ($new_mappings as $extension => $mime_type) {
if (!in_array($mime_type, $mapping['mimetypes'])) {
$mapping['mimetypes'][] = $mime_type;
}
$index = array_search($mime_type, $mapping['mimetypes']);
$mapping['extensions'][$extension] = $index;
}
}
function epub_reset_mimetype($file) {
$tmp = explode('.', $file->filename);
$file_extension = end($tmp);
switch ($file_extension) {
case 'epub':
$file->mimetype = 'application/epub+zip';
return file_save($file);
case 'ibooks':
$file->mimetype = 'application/x-ibooks+zip';
return file_save($file);
}
return FALSE;
}
function epub_ctools_plugin_api($owner, $api) {
if ($owner == 'file_entity' && $api == 'file_type') {
return array(
'version' => 1,
);
}
}
function epub_file_default_types() {
return array(
'ebook' => (object) array(
'api_version' => 1,
'type' => 'ebook',
'label' => t('eBook'),
'description' => t("An <em>eBook</em> is a book-length publication in digital form."),
'mimetypes' => array(
'application/epub+zip',
'application/x-ibooks+zip',
),
),
);
}
function epub_block_info($op = 'list', $delta = 0, $edit = array()) {
$blocks['epub'] = array(
'info' => t('EPUB TOC'),
'visibility' => BLOCK_VISIBILITY_LISTED,
'pages' => 'file/*',
);
return $blocks;
}
function epub_block_view($delta = '') {
$block = array();
switch ($delta) {
case 'epub':
if (arg(0) == 'file' && ($file = file_load(arg(1)))) {
if ($file->filemime == 'application/epub+zip') {
$path = file_create_url('public://epub_content/' . $file->fid);
$file_url = file_create_url($file->uri);
$block['subject'] = t('Contents');
$block['content'] = epub_get_toc('public://epub_content/' . $file->fid, 'epub');
}
}
}
return $block;
}
function epub_theme() {
$path = drupal_get_path('module', 'epub') . '/theme';
$theme = array(
'epub_formatter_cover' => array(
'variables' => array(
'file' => NULL,
'width' => NULL,
),
'file' => 'includes/epub.field.inc',
),
'epub_formatter_default' => array(
'variables' => array(
'file' => NULL,
'width' => NULL,
'height' => NULL,
),
'file' => 'includes/epub.field.inc',
),
'epub_formatter_toc' => array(
'variables' => array(
'file' => NULL,
),
'file' => 'includes/epub.field.inc',
),
'epub_formatter_epubjs' => array(
'variables' => array(
'file' => NULL,
'unzipped' => TRUE,
'width' => NULL,
'height' => NULL,
),
'file' => 'includes/epub.field.inc',
),
'epub_formatter_epubjs_reader' => array(
'variables' => array(
'file' => NULL,
'unzipped' => TRUE,
),
'file' => 'includes/epub.field.inc',
),
'epub_js_reader' => array(
'template' => 'epub-js-reader',
'variables' => array(
'file' => NULL,
),
'path' => $path,
),
);
return $theme;
}
function epub_file_update($file) {
$destination = 'public://epub_content/' . $file->fid;
$tmp = explode('.', $file->filename);
$file_extension = end($tmp);
switch ($file_extension) {
case 'epub':
file_prepare_directory($destination, FILE_CREATE_DIRECTORY);
return epub_unzip(drupal_realpath($file->uri), $destination);
case 'ibooks':
file_prepare_directory($destination, FILE_CREATE_DIRECTORY);
return epub_unzip(drupal_realpath($file->uri), $destination);
}
}
function epub_file_delete($file) {
$destination = 'public://epub_content/' . $file->fid;
return file_unmanaged_delete_recursive($destination);
}
function epub_unzip($filepath, $destination) {
$destination .= '/';
$extracted = array();
if ($z = zip_open($filepath)) {
while ($entry = zip_read($z)) {
if (zip_entry_open($z, $entry, 'r') && ($zip_entry_filesize = zip_entry_filesize($entry))) {
$entry_name = zip_entry_name($entry);
$data = zip_entry_read($entry, $zip_entry_filesize);
$filepath = $destination . $entry_name;
$parent_dir = dirname($filepath);
if (!file_exists($parent_dir)) {
file_prepare_directory($parent_dir, FILE_CREATE_DIRECTORY);
}
if ($filepath = file_unmanaged_save_data($data, $filepath, FILE_EXISTS_REPLACE)) {
$file = new StdClass();
$file->filename = $entry_name;
$file->filemime = file_get_mimetype($filepath);
$file->filesize = filesize($filepath);
$extracted[] = $file;
}
zip_entry_close($entry);
}
}
zip_close($z);
}
return $extracted;
}
function epub_get_item($dir, $id) {
$file = epub_get_opf($dir);
if ($file) {
$opfXML = simplexml_load_file($file);
$opfXML
->registerXPathNamespace('opf', 'http://www.idpf.org/2007/opf');
$element = $opfXML
->xpath('//opf:item[@id="' . $id . '"]');
if (empty($element)) {
return FALSE;
}
else {
$attributes = $element[0]
->attributes();
$href = (string) $attributes['href'];
$filename = pathinfo($href);
$scan = file_scan_directory($dir, '/.*' . $filename['basename'] . '$/');
return file_create_url(array_shift($scan)->uri);
}
}
else {
return FALSE;
}
}
function epub_get_opf($dir) {
if (file_exists($dir . '/META-INF/container.xml')) {
$ocfXML = simplexml_load_file($dir . '/META-INF/container.xml');
$ocfXML
->registerXPathNamespace('ocf', 'urn:oasis:names:tc:opendocument:xmlns:container');
$rootfile = $ocfXML
->xpath('//ocf:rootfile/@full-path');
if ($rootfile) {
return $dir . '/' . (string) $rootfile[0];
}
}
return false;
}
function epub_get_ncx($dir) {
$file = epub_get_opf($dir);
if ($file == FALSE) {
return false;
}
$opfXML = simplexml_load_file($file);
$opfXML
->registerXPathNamespace('opf', 'http://www.idpf.org/2007/opf');
$ncx = $opfXML
->xpath('//opf:item[@media-type="application/x-dtbncx+xml"]');
if ($ncx) {
$attributes = $ncx[0]
->attributes();
return dirname($file) . '/' . (string) $attributes['href'];
}
else {
return FALSE;
}
}
function epub_get_nav($dir) {
$file = epub_get_opf($dir);
if ($file == FALSE) {
return false;
}
$opfXML = simplexml_load_file($file);
$opfXML
->registerXPathNamespace('opf', 'http://www.idpf.org/2007/opf');
$nav = $opfXML
->xpath('//opf:item[@properties="nav"]');
if ($nav) {
$attributes = $nav[0]
->attributes();
return dirname($file) . '/' . (string) $attributes['href'];
}
else {
return FALSE;
}
}
function epub_get_toc($dir, $target = FALSE) {
$file = epub_get_nav($dir);
if ($file) {
$tocXML = simplexml_load_file($file);
$tocXML
->registerXPathNamespace('xhtml', 'http://www.w3.org/1999/xhtml');
$tocXML
->registerXPathNamespace('epub', 'http://www.idpf.org/2007/ops');
foreach ($tocXML
->xpath('//xhtml:a[@href]') as $item) {
$item[0]
->attributes()->href = rawurldecode(file_create_url(dirname($file) . '/' . $item[0]
->attributes()->href));
if ($target) {
$item[0]
->addAttribute('target', $target);
}
}
$toc = $tocXML
->xpath('//*[@epub:type="toc"]');
if ($toc) {
return $toc[0]
->asXML();
}
}
$file = epub_get_ncx($dir);
if ($file) {
$tocXML = simplexml_load_file(epub_get_ncx($dir));
$tocXML = simplexml_load_file($file);
$tocXML
->registerXPathNamespace('ncx', 'http://www.daisy.org/z3986/2005/ncx/');
foreach ($tocXML
->xpath('//@src') as $item) {
$item[0] = rawurldecode(file_create_url(dirname($file) . '/' . $item[0]));
}
$toc = $tocXML
->xpath('//ncx:navMap');
if ($toc) {
$output = new SimpleXMLElement('<nav type="toc"><h2>Contents</h2></nav>');
$html = epub_ncx_item($toc[0], $target);
return $html;
}
}
return FALSE;
}
function epub_ncx_item($navmap, $target = FALSE) {
$html = '<ol>';
foreach ($navmap as $item) {
if ($item
->attributes()->id) {
$html .= '<li><a href="' . $item->content
->attributes()->src . '"';
if ($target) {
$html .= ' target="' . $target . '" ';
}
$html .= '>' . $item->navLabel->text . '</a>';
if ($item->navPoint) {
$subitems = epub_ncx_item($item->navPoint, $target);
$html .= $subitems;
}
$html .= '</li>';
}
}
$html .= '</ol>';
return $html;
}
function epub_preprocess_html(&$variables) {
if (arg(0) == 'file' && is_numeric(arg(1)) && arg(2) == '') {
if ($file = file_load(arg(1))) {
if (file_entity_access('view', $file) && $file->filemime == 'application/epub+zip') {
$parameters = drupal_get_query_parameters();
if (isset($parameters['fullscreen'])) {
$variables['theme_hook_suggestions'][] = 'epub_js_reader';
$variables['file'] = $file;
$variables['unzipped'] = TRUE;
}
}
}
}
}