Skip to content

Commit dce2d08

Browse files
committed
Initial commit
0 parents  commit dce2d08

File tree

10 files changed

+247
-0
lines changed

10 files changed

+247
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
tests/
2+
vendor/
3+
.php-cs-fixer.cache
4+
.php-cs-fixer.php

.php-cs-fixer.dist.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
$finder = PhpCsFixer\Finder::create()
4+
->in([
5+
__DIR__ . '/src',
6+
__DIR__ . '/tests'
7+
]);
8+
9+
$config = new PhpCsFixer\Config();
10+
return $config->setRules([
11+
'@Symfony' => true,
12+
'concat_space' => [
13+
'spacing' => 'one'
14+
],
15+
'multiline_whitespace_before_semicolons' => [
16+
'strategy' => 'no_multi_line'
17+
]
18+
])->setFinder($finder);

composer.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "espresso-tutorials/epub-to-html-converter",
3+
"type": "library",
4+
"license": "ISC",
5+
"autoload": {
6+
"psr-4": {
7+
"EspressoTutorials\\Epub\\": "src/"
8+
}
9+
},
10+
"authors": [
11+
{
12+
"name": "Jonas Regner",
13+
"email": "[email protected]"
14+
}
15+
],
16+
"require": {
17+
"ext-zip": "*",
18+
"ext-simplexml": "*"
19+
}
20+
}

src/Container.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace EspressoTutorials\Epub;
4+
5+
use EspressoTutorials\Epub\Elements\RootFile;
6+
7+
class Container
8+
{
9+
protected ?RootFile $rootFile = null;
10+
11+
public function __construct(
12+
protected SimpleXMLElement $element,
13+
) {
14+
}
15+
16+
public function rootFile(): RootFile
17+
{
18+
if ($this->rootFile) {
19+
return $this->rootFile;
20+
}
21+
22+
return $this->rootFile = new RootFile(
23+
(string) $this->element->rootfiles->rootfile->attributes()['full-path']
24+
);
25+
}
26+
}

src/Content.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace EspressoTutorials\Epub;
4+
5+
use EspressoTutorials\Epub\Elements\Item;
6+
use EspressoTutorials\Epub\Elements\ItemRef;
7+
8+
class Content
9+
{
10+
protected array $manifest = [];
11+
12+
protected array $spine = [];
13+
14+
public function __construct(
15+
protected SimpleXMLElement $element
16+
) {
17+
}
18+
19+
public function manifest(): array
20+
{
21+
if ($this->manifest) {
22+
return $this->manifest;
23+
}
24+
25+
foreach ($this->element->manifest->item as $node) {
26+
$this->manifest[] = new Item(
27+
(string) $node->attributes()['id'],
28+
(string) $node->attributes()['href'],
29+
(string) $node->attributes()['media-type'],
30+
);
31+
}
32+
33+
return $this->manifest;
34+
}
35+
36+
public function spine(): array
37+
{
38+
if ($this->spine) {
39+
return $this->spine;
40+
}
41+
42+
foreach ($this->element->spine->itemref as $node) {
43+
$this->spine[] = new ItemRef(
44+
(string) $node->attributes()['idref'],
45+
);
46+
}
47+
48+
return $this->spine;
49+
}
50+
}

src/Elements/Item.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace EspressoTutorials\Epub\Elements;
4+
5+
class Item
6+
{
7+
public function __construct(
8+
protected string $id,
9+
protected string $path,
10+
protected string $mimetype
11+
) {
12+
}
13+
14+
public function id(): string
15+
{
16+
return $this->id;
17+
}
18+
19+
public function path(): string
20+
{
21+
return $this->path;
22+
}
23+
24+
public function mimeType(): string
25+
{
26+
return $this->mimetype;
27+
}
28+
}

src/Elements/ItemRef.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace EspressoTutorials\Epub\Elements;
4+
5+
class ItemRef
6+
{
7+
public function __construct(
8+
protected string $idRef,
9+
) {
10+
}
11+
12+
public function idRef(): string
13+
{
14+
return $this->idRef;
15+
}
16+
}

src/Elements/RootFile.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace EspressoTutorials\Epub\Elements;
4+
5+
class RootFile
6+
{
7+
public function __construct(
8+
protected string $path
9+
) {
10+
}
11+
12+
public function path(): string
13+
{
14+
return $this->path;
15+
}
16+
}

src/Epub.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
namespace EspressoTutorials\Epub;
4+
5+
class Epub
6+
{
7+
protected \ZipArchive $archive;
8+
9+
protected ?Container $container = null;
10+
11+
protected ?Content $content = null;
12+
13+
protected string $extractionPath;
14+
15+
public function __construct(
16+
protected string $path
17+
) {
18+
}
19+
20+
public function container(): Container
21+
{
22+
if ($this->container) {
23+
return $this->container;
24+
}
25+
26+
return $this->container = new Container(
27+
SimpleXMLElement::fromPath($this->extractionPath . '/META-INF/container.xml')
28+
);
29+
}
30+
31+
public function content(): Content
32+
{
33+
if ($this->content) {
34+
return $this->content;
35+
}
36+
37+
return $this->content = new Content(
38+
SimpleXMLElement::fromPath($this->extractionPath . '/' . $this->container()->rootFile()->path())
39+
);
40+
}
41+
42+
public function extractTo(string $path): bool
43+
{
44+
$this->archive = new \ZipArchive();
45+
46+
if (!$this->archive->open($this->path)) {
47+
return false;
48+
}
49+
50+
if (!$this->archive->extractTo($path)) {
51+
return false;
52+
}
53+
54+
$this->extractionPath = $path;
55+
56+
return true;
57+
}
58+
}

src/SimpleXMLElement.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace EspressoTutorials\Epub;
4+
5+
class SimpleXMLElement extends \SimpleXMLElement
6+
{
7+
public static function fromPath(string $path): self
8+
{
9+
return new self(file_get_contents($path));
10+
}
11+
}

0 commit comments

Comments
 (0)