Skip to content

Commit 0805cf3

Browse files
committed
Added more traits and tests
1 parent 7556394 commit 0805cf3

File tree

6 files changed

+215
-8
lines changed

6 files changed

+215
-8
lines changed

src/Metadata.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ class Metadata
1414
use Traits\InteractsWithAuthors;
1515
use Traits\InteractsWithPublisher;
1616
use Traits\InteractsWithLanguage;
17+
use Traits\InteractsWithSubject;
18+
use Traits\InteractsWithIdentifier;
1719

1820
private readonly SimpleXMLElement $opfXml;
1921
private string $dcNamespace;

src/Traits/InteractsWithDate.php

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,38 @@
44

55
namespace PhpEpub\Traits;
66

7-
use DateTime;
8-
97
trait InteractsWithDate
108
{
119
/**
1210
* Gets the date of the EPUB.
1311
*/
14-
public function getDate(): ?DateTime
12+
public function getDate(): string
1513
{
16-
if (! isset($this->opfXml->metadata->date)) {
17-
return null;
14+
$this->opfXml->registerXPathNamespace('dc', $this->dcNamespace);
15+
16+
$dateNode = $this->opfXml->xpath('//dc:date');
17+
18+
if ($dateNode === false || $dateNode === null || $dateNode === []) {
19+
return '';
1820
}
1921

20-
return new DateTime((string) $this->opfXml->metadata->date);
22+
return (string) $dateNode[0];
2123
}
2224

2325
/**
2426
* Sets the date of the EPUB.
2527
*/
26-
public function setDate(DateTime $date): void
28+
public function setDate(string $date): void
2729
{
28-
$this->opfXml->metadata->date = $date->format('Y-m-d');
30+
$this->opfXml->registerXPathNamespace('dc', $this->dcNamespace);
31+
32+
$dateNode = $this->opfXml->xpath('//dc:date');
33+
34+
if ($dateNode !== false && $dateNode !== null && $dateNode !== [] && isset($dateNode[0])) {
35+
// @phpstan-ignore-next-line
36+
$dateNode[0][0] = $date;
37+
} else {
38+
$this->opfXml->metadata->addChild('date', $date, $this->dcNamespace);
39+
}
2940
}
3041
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpEpub\Traits;
6+
7+
trait InteractsWithIdentifier
8+
{
9+
/**
10+
* Gets the authors of the EPUB.
11+
*
12+
* @return array<int, string>
13+
*/
14+
public function getIdentifiers(): array
15+
{
16+
$this->opfXml->registerXPathNamespace('dc', $this->dcNamespace);
17+
18+
$identifierNodes = $this->opfXml->xpath('//dc:identifier');
19+
20+
$identifiers = [];
21+
22+
if ($identifierNodes === false || $identifierNodes === null || $identifierNodes === []) {
23+
return $identifiers;
24+
}
25+
26+
foreach ($identifierNodes as $identifierNode) {
27+
$identifiers[] = (string) $identifierNode;
28+
}
29+
return $identifiers;
30+
}
31+
32+
/**
33+
* Sets the identifiers of the EPUB.
34+
*
35+
* @param array<int, string> $identifiers
36+
*/
37+
public function setIdentifiers(array $identifiers): void
38+
{
39+
$this->opfXml->registerXPathNamespace('dc', $this->dcNamespace);
40+
41+
$identifierNodes = $this->opfXml->xpath('//dc:identifier');
42+
43+
if ($identifierNodes !== false && $identifierNodes !== null && $identifierNodes !== []) {
44+
foreach ($identifierNodes as $key => $identifierNode) {
45+
unset($identifierNodes[$key][0]);
46+
}
47+
}
48+
49+
foreach ($identifiers as $identifier) {
50+
$this->opfXml->metadata->addChild('identifier', $identifier, $this->dcNamespace);
51+
}
52+
}
53+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpEpub\Traits;
6+
7+
trait InteractsWithSubject
8+
{
9+
/**
10+
* Gets the subject of the EPUB.
11+
*/
12+
public function getSubject(): string
13+
{
14+
$this->opfXml->registerXPathNamespace('dc', $this->dcNamespace);
15+
16+
$subjectNode = $this->opfXml->xpath('//dc:subject');
17+
18+
if ($subjectNode === false || $subjectNode === null || $subjectNode === []) {
19+
return '';
20+
}
21+
22+
return (string) $subjectNode[0];
23+
}
24+
25+
/**
26+
* Sets the subject of the EPUB.
27+
*/
28+
public function setSubject(string $subject): void
29+
{
30+
$this->opfXml->registerXPathNamespace('dc', $this->dcNamespace);
31+
32+
$subjectNode = $this->opfXml->xpath('//dc:subject');
33+
34+
if ($subjectNode !== false && $subjectNode !== null && $subjectNode !== [] && isset($subjectNode[0])) {
35+
// @phpstan-ignore-next-line
36+
$subjectNode[0][0] = $subject;
37+
} else {
38+
$this->opfXml->metadata->addChild('subject', $subject, $this->dcNamespace);
39+
}
40+
}
41+
}

tests/EpubFileTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ public function testLoadEpub(string $epubPath, bool $shouldLoad, array $expected
8585
$this->assertSame($expectedMetadata['description'], $metadata->getDescription());
8686
$this->assertSame($expectedMetadata['publisher'], $metadata->getPublisher());
8787
$this->assertSame($expectedMetadata['language'], $metadata->getLanguage());
88+
$this->assertSame($expectedMetadata['subject'], $metadata->getSubject());
89+
$this->assertSame($expectedMetadata['date'], $metadata->getDate());
90+
$this->assertSame($expectedMetadata['identifiers'], $metadata->getIdentifiers());
8891
}
8992
}
9093

@@ -114,6 +117,12 @@ public static function epubFileProvider(): Iterator
114117
'description' => 'These tests include starting the reading system and opening the titles, navigating the content, searching, and using bookmarks and notes.',
115118
'publisher' => '',
116119
'language' => 'en',
120+
'subject' => 'basic-functionality',
121+
'date' => '',
122+
'identifiers' => [
123+
'com.github.epub-testsuite.epub30-test-0301-2.0.0',
124+
'9781003410126'
125+
],
117126
]];
118127
yield [__DIR__ . DIRECTORY_SEPARATOR . 'fixtures' . DIRECTORY_SEPARATOR . 'valid_1.epub', true, [
119128
'title' => 'Anonim',
@@ -123,6 +132,11 @@ public static function epubFileProvider(): Iterator
123132
'description' => '',
124133
'publisher' => '',
125134
'language' => 'ro',
135+
'subject' => '',
136+
'date' => '2015-08-24',
137+
'identifiers' => [
138+
'AWP-DF47F263-F894-490D-9E8A-2492EC571534'
139+
],
126140
]];
127141
yield [__DIR__ . DIRECTORY_SEPARATOR . 'fixtures' . DIRECTORY_SEPARATOR . 'valid_2.epub', true, [
128142
'title' => 'Brave New World',
@@ -132,6 +146,11 @@ public static function epubFileProvider(): Iterator
132146
'description' => '',
133147
'publisher' => 'epubBooks Classics',
134148
'language' => 'en',
149+
'subject' => 'Science Fiction',
150+
'date' => '2014-12-29',
151+
'identifiers' => [
152+
'_simple_book'
153+
],
135154
]];
136155
yield [__DIR__ . DIRECTORY_SEPARATOR . 'fixtures' . DIRECTORY_SEPARATOR . 'valid_3.epub', true, [
137156
'title' => 'King of the Range',
@@ -141,6 +160,11 @@ public static function epubFileProvider(): Iterator
141160
'description' => '',
142161
'publisher' => 'Distributed Proofreaders Canada',
143162
'language' => 'en',
163+
'subject' => 'fiction',
164+
'date' => '1974-01-14T13:30:00+00:00',
165+
'identifiers' => [
166+
'0fe42443-c7d5-4615-a5b2-cc8b07de619c'
167+
],
144168
]];
145169
yield [__DIR__ . DIRECTORY_SEPARATOR . 'fixtures' . DIRECTORY_SEPARATOR . 'valid_4.epub', true, [
146170
'title' => 'EPUB 3.0 Specification',
@@ -150,6 +174,11 @@ public static function epubFileProvider(): Iterator
150174
'description' => '',
151175
'publisher' => '',
152176
'language' => 'en',
177+
'subject' => '',
178+
'date' => '',
179+
'identifiers' => [
180+
'code.google.com.epub-samples.epub30-spec'
181+
],
153182
]];
154183
yield [__DIR__ . DIRECTORY_SEPARATOR . 'fixtures' . DIRECTORY_SEPARATOR . 'valid_5.epub', true, [
155184
'title' => 'Children\'s Literature',
@@ -160,6 +189,11 @@ public static function epubFileProvider(): Iterator
160189
'description' => '',
161190
'publisher' => '',
162191
'language' => 'en',
192+
'subject' => 'Children -- Books and reading',
193+
'date' => '2008-05-20',
194+
'identifiers' => [
195+
'http://www.gutenberg.org/ebooks/25545'
196+
],
163197
]];
164198
yield [__DIR__ . DIRECTORY_SEPARATOR . 'fixtures' . DIRECTORY_SEPARATOR . 'valid_6.epub', true, [
165199
'title' => '500 Rätsel und Rätselscherze für jung und alt / Ein Bringmichraus für Schul und Haus',
@@ -169,20 +203,35 @@ public static function epubFileProvider(): Iterator
169203
'description' => '',
170204
'publisher' => '',
171205
'language' => 'de',
206+
'subject' => 'Puzzles',
207+
'date' => '2010-02-15',
208+
'identifiers' => [
209+
'http://www.gutenberg.org/31281'
210+
],
172211
]];
173212
yield [__DIR__ . DIRECTORY_SEPARATOR . 'fixtures' . DIRECTORY_SEPARATOR . 'invalid.epub', false, [
174213
'title' => '',
175214
'authors' => [],
176215
'description' => '',
177216
'publisher' => '',
178217
'language' => '',
218+
'subject' => '',
219+
'date' => '',
220+
'identifiers' => [
221+
''
222+
],
179223
]];
180224
yield [__DIR__ . DIRECTORY_SEPARATOR . 'fixtures' . DIRECTORY_SEPARATOR . 'nonexistent.epub', false, [
181225
'title' => '',
182226
'authors' => [],
183227
'description' => '',
184228
'publisher' => '',
185229
'language' => '',
230+
'subject' => '',
231+
'date' => '',
232+
'identifiers' => [
233+
''
234+
],
186235
]];
187236
}
188237

tests/MetadataTest.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,23 @@ public function testSetTitle(): void
5151
$this->assertSame('New Title', $updatedMetadata->getTitle());
5252
}
5353

54+
public function testGetDate(): void
55+
{
56+
$metadata = new Metadata($this->tempOpfFilePath);
57+
$date = $metadata->getDate();
58+
$this->assertSame('', $date);
59+
}
60+
61+
public function testSetDate(): void
62+
{
63+
$metadata = new Metadata($this->tempOpfFilePath);
64+
$metadata->setDate('2022-01-01');
65+
$metadata->save($this->tempOpfFilePath);
66+
67+
$updatedMetadata = new Metadata($this->tempOpfFilePath);
68+
$this->assertSame('2022-01-01', $updatedMetadata->getDate());
69+
}
70+
5471
public function testGetAuthors(): void
5572
{
5673
$metadata = new Metadata($this->tempOpfFilePath);
@@ -119,6 +136,40 @@ public function testSetDescription(): void
119136
$this->assertSame('new description', $updatedMetadata->getDescription());
120137
}
121138

139+
public function testGetSubject(): void
140+
{
141+
$metadata = new Metadata($this->tempOpfFilePath);
142+
$subject = $metadata->getSubject();
143+
$this->assertSame('basic-functionality', $subject);
144+
}
145+
146+
public function testSetSubject(): void
147+
{
148+
$metadata = new Metadata($this->tempOpfFilePath);
149+
$metadata->setSubject('new subject');
150+
$metadata->save($this->tempOpfFilePath);
151+
152+
$updatedMetadata = new Metadata($this->tempOpfFilePath);
153+
$this->assertSame('new subject', $updatedMetadata->getSubject());
154+
}
155+
156+
public function testGetIdentifier(): void
157+
{
158+
$metadata = new Metadata($this->tempOpfFilePath);
159+
$identifiers = $metadata->getIdentifiers();
160+
$this->assertSame(['com.github.epub-testsuite.epub30-test-0301-2.0.0', '9781003410126'], $identifiers);
161+
}
162+
163+
public function testSetIdentifier(): void
164+
{
165+
$metadata = new Metadata($this->tempOpfFilePath);
166+
$metadata->setIdentifiers(['new identifier']);
167+
$metadata->save($this->tempOpfFilePath);
168+
169+
$updatedMetadata = new Metadata($this->tempOpfFilePath);
170+
$this->assertSame(['new identifier'], $updatedMetadata->getIdentifiers());
171+
}
172+
122173
public function testLoadInvalidOpfThrowsException(): void
123174
{
124175
$this->expectException(Exception::class);

0 commit comments

Comments
 (0)