PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.1-beta.2
Jetpack – WP Security, Backup, Speed, & Growth v16.1-beta.2
16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / vendor / wp-php-toolkit / data-liberation / EntityReader / class-epubentityreader.php
jetpack / vendor / wp-php-toolkit / data-liberation / EntityReader Last commit date
class-blockswithmetadataentityreader.php 6 days ago class-databasecontententityreader.php 6 days ago class-databaserowsentityreader.php 6 days ago class-entityreaderiterator.php 6 days ago class-epubentityreader.php 6 days ago class-filesystementityreader.php 6 days ago class-htmlentityreader.php 6 days ago class-wxrentityreader.php 6 days ago interface-entity-reader.php 6 days ago
class-epubentityreader.php
197 lines
1 <?php
2
3 namespace WordPress\DataLiberation\EntityReader;
4
5 use WordPress\DataLiberation\DataFormatConsumer\BlocksWithMetadata;
6 use WordPress\DataLiberation\DataFormatConsumer\MarkupProcessorConsumer;
7 use WordPress\Filesystem\Filesystem;
8 use WordPress\XML\XMLProcessor;
9
10 use function WordPress\Filesystem\wp_join_unix_paths;
11
12 /**
13 * EPub specification: https://www.w3.org/AudioVideo/ebook/
14 *
15 * An EPUB Publication is transported as a single file (a "portable document") that contains:
16 * * a Package Document (OPF file) which specifies all the Publication's constituent content documents and their required resources, defines a reading order and associates Publication-level metadata and navigation information.
17 * * A metadata element including and/or referencing metadata applicable to the entire Publication and particular resources within it.
18 * * A manifest element: identifies (via IRI) and describes (via MIME media type) the set of resources that constitute the EPUB Publication.
19 * * A spine element : defines the default reading order of the Publication. (An ordered list of Publication Resources (EPUB Content Documents).
20 * * A Bindings element defines a set of custom handlers for media types not supported by EPUB3. If the Reading System cannot support the specific media type, it could use scripting fallback if supported.
21 * * all Content Documents
22 * * all other required resources for processing the Publication.
23 *
24 * The OCF Container is packaged into a physical single ZIP file containing:
25 * * Mime Type file: application/epub+zip.
26 * * META-INF folder (container file which points to the location of the .opf file), signatures, encryption, rights, are xml files
27 * * OEBPS folder stores the book content .(opf, ncx, html, svg, png, css, etc. files)
28 */
29 class EPubEntityReader implements EntityReader {
30
31 protected $zip;
32 protected $finished = false;
33 protected $current_post_id;
34 protected $remaining_html_files;
35 protected $current_html_reader;
36 protected $manifest;
37 protected $manifest_path;
38
39 public function __construct( Filesystem $zip, $first_post_id = 1 ) {
40 $this->zip = $zip;
41 $this->current_post_id = $first_post_id;
42 }
43
44 public function next_entity() {
45 if ( $this->finished ) {
46 return false;
47 }
48
49 if ( null === $this->remaining_html_files ) {
50 if ( false === $this->parse_manifest() ) {
51 _doing_it_wrong( __METHOD__, 'The EPUB file did not contain a manifest.', '1.0.0' );
52 $this->finished = true;
53
54 return false;
55 }
56
57 $this->remaining_html_files = array();
58 foreach ( $this->manifest['items'] as $item ) {
59 if ( 'application/xhtml+xml' !== $item['media-type'] ) {
60 continue;
61 }
62 if ( 'nav' === ( $item['properties'] ?? '' ) ) {
63 continue;
64 }
65 $this->remaining_html_files[] = wp_join_unix_paths(
66 dirname( $this->manifest_path ),
67 $item['href']
68 );
69 }
70 }
71
72 while ( true ) {
73 if ( null !== $this->current_html_reader ) {
74 if (
75 ! $this->current_html_reader->is_finished() &&
76 $this->current_html_reader->next_entity()
77 ) {
78 return true;
79 }
80 }
81
82 if ( 0 === count( $this->remaining_html_files ) ) {
83 $this->finished = true;
84
85 return false;
86 }
87
88 $html_file = array_shift( $this->remaining_html_files );
89 $html = $this->zip->get_contents( $html_file );
90 $converter = new MarkupProcessorConsumer(
91 XMLProcessor::create_from_string( $html )
92 );
93 $blocks_with_meta = $converter->consume();
94 $meta = $blocks_with_meta->get_all_metadata();
95 if ( ! array_key_exists( 'post_name', $meta ) ) {
96 $meta['post_name'] = array(
97 basename( $html_file, '.xhtml' ),
98 );
99 }
100 if ( ! array_key_exists( 'post_title', $meta ) ) {
101 $meta['post_title'] = array(
102 basename( $html_file, '.xhtml' ),
103 );
104 }
105 $meta['post_type'] = array( 'page' );
106 $meta['post_status'] = array( 'publish' );
107 $meta['link'] = array( 'file://' . $html_file );
108 $blocks_with_meta = new BlocksWithMetadata(
109 $blocks_with_meta->get_block_markup(),
110 $meta
111 );
112 $this->current_html_reader = new HTMLEntityReader(
113 $blocks_with_meta,
114 $this->current_post_id
115 );
116 ++$this->current_post_id;
117 }
118
119 return false;
120 }
121
122 /**
123 * An absolute path to the manifest file. Starting with slash.
124 */
125 public function get_manifest_path() {
126 if ( null === $this->manifest_path ) {
127 $this->parse_manifest();
128 }
129
130 return $this->manifest_path;
131 }
132
133 private function parse_manifest() {
134 if ( null !== $this->manifest ) {
135 return true;
136 }
137
138 $xml = XMLProcessor::create_from_string(
139 $this->zip->get_contents( 'META-INF/container.xml' )
140 );
141
142 if ( false === $xml->next_tag( array( 'urn:oasis:names:tc:opendocument:xmlns:container', 'rootfile' ) ) ) {
143 return false;
144 }
145
146 $full_path = $xml->get_attribute( '', 'full-path' );
147 if ( ! $full_path ) {
148 return false;
149 }
150
151 $this->manifest_path = '/' . ltrim( $full_path, '/' );
152 $manifest = $this->zip->get_contents( $this->manifest_path );
153 if ( ! $manifest ) {
154 return false;
155 }
156 $xml = XMLProcessor::create_from_string(
157 $manifest
158 );
159
160 $parsed = array(
161 'metadata' => array(),
162 'items' => array(),
163 );
164 while ( $xml->next_tag() ) {
165 $parsed_entry = array();
166 $keys = $xml->get_attribute_names_with_prefix( '', '' );
167 foreach ( $keys as list($ns, $key) ) {
168 $parsed_entry[ $key ] = $xml->get_attribute( $ns, $key );
169 }
170 if ( $xml->matches_breadcrumbs( array( 'package', 'metadata', '*' ) ) ) {
171 $parsed['metadata'][] = array(
172 'tag' => $xml->get_tag_local_name(),
173 'attributes' => $parsed_entry,
174 );
175 } elseif ( $xml->matches_breadcrumbs( array( 'package', 'manifest', 'item' ) ) ) {
176 $parsed_entry['type'] = 'item';
177 $parsed['items'][] = $parsed_entry;
178 }
179 }
180 $this->manifest = $parsed;
181
182 return true;
183 }
184
185 public function get_entity() {
186 return $this->current_html_reader->get_entity();
187 }
188
189 public function is_finished(): bool {
190 return $this->finished;
191 }
192
193 public function get_reentrancy_cursor() {
194 return '';
195 }
196 }
197