You are here

epub.module in Epub 8

Same filename and directory in other branches
  1. 6 epub.module
  2. 7 epub.module

File

epub.module
View source
<?php

use Drupal\file\Entity\File;

/**
 * Implements hook_theme().
 */
function epub_theme() {
  return array(
    'epub_formatter_cover' => array(
      'variables' => array(
        'file' => NULL,
        'image' => 'https://upload.wikimedia.org/wikipedia/en/1/14/EPUB_logo.svg',
        'width' => NULL,
      ),
      'file' => 'epub.field.inc',
    ),
    'epub_formatter_default' => array(
      'variables' => array(
        'file' => NULL,
        'width' => NULL,
        'height' => NULL,
      ),
      'file' => 'epub.field.inc',
    ),
    'epub_formatter_toc' => array(
      'variables' => array(
        'file' => NULL,
        'toc' => NULL,
      ),
      'file' => 'epub.field.inc',
    ),
    'epub_formatter_js' => array(
      'variables' => array(
        'file' => NULL,
        'reader' => NULL,
        'unzipped' => TRUE,
        'width' => NULL,
        'height' => NULL,
      ),
      'file' => 'epub.field.inc',
    ),
    'epub_formatter_reader' => array(
      'variables' => array(
        'file' => NULL,
      ),
      'file' => 'epub.field.inc',
    ),
  );
}

/**
 * Implements hook_entity_delete().
 */
function epub_entity_delete(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity
    ->getEntityTypeId() == 'file') {
    $destination = 'public://epub_content/' . $entity
      ->id();
    file_unmanaged_delete_recursive($destination);
  }
}

/**
 * Implements hook_file_update().
 */
function epub_file_update(File $file) {
  $destination = 'public://epub_content/' . $file
    ->id();
  $tmp = explode('.', $file
    ->getFilename());
  $file_extension = end($tmp);
  switch ($file_extension) {
    case 'epub':
      file_prepare_directory($destination, FILE_CREATE_DIRECTORY);
      return epub_unzip(drupal_realpath($file
        ->getFileUri()), $destination);
    case 'ibooks':
      file_prepare_directory($destination, FILE_CREATE_DIRECTORY);
      return epub_unzip(drupal_realpath($file
        ->getFileUri()), $destination);
  }
}

///'application/epub+zip' is in /core/lib/Drupal/Core/File/MimeType/ExtensionMimeTypeGuesser.php
function epub_reset_mimetype($file) {
  $tmp = explode('.', $file
    ->getFilename());
  $file_extension = end($tmp);
  switch ($file_extension) {
    case 'ibooks':
      $file
        ->setMimeType('application/x-ibooks+zip');
      return $file
        ->save();
  }
  return FALSE;
}
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 = \Drupal::service('file.mime_type.guesser')
            ->guess($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 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')[0];
    return $dir . '/' . (string) $rootfile[0];
  }
  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_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_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_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;
}