PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.8.0
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.8.0
3.8.0 3.7.5 3.7.4 3.7.3 3.7.2 1-final 3.7.1 3.7.0 3.6.8 3.6.7 3.6.6 3.6.5 3.6.4 3.6.3 3.6.2 3.6.1 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 All 112 releases
templately / modules / full-site-import / Parsers / WXR_Parser_XML.php

WXR_Parser_XML.php in Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! 3.8.0, at modules/full-site-import/Parsers/WXR_Parser_XML.php

370 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Templately\Modules\FullSiteImport\Parsers;
3
4 use Elementor\Utils;
5 use WP_Error;
6
7 if ( ! defined( 'ABSPATH' ) ) {
8 exit; // Exit if accessed directly.
9 }
10
11 /**
12 * WordPress extended RSS file parser implementations,
13 * Originally made by WordPress part of WordPress/Importer.
14 * https://plugins.trac.wordpress.org/browser/wordpress-importer/trunk/parsers/class-wxr-parser-xml.php
15 *
16 * What was done (by Elementor):
17 * Reformat of the code.
18 * Added PHPDOC.
19 * Changed text domain.
20 * Added clear() method.
21 * Added undeclared class properties.
22 * Changed methods visibility.
23 */
24
25 /**
26 * WXR Parser that makes use of the XML Parser PHP extension.
27 */
28 class WXR_Parser_XML {
29 private static $wp_tags = [
30 'wp:post_id',
31 'wp:post_date',
32 'wp:post_date_gmt',
33 'wp:comment_status',
34 'wp:ping_status',
35 'wp:attachment_url',
36 'wp:attachment_type',
37 'wp:status',
38 'wp:post_name',
39 'wp:post_parent',
40 'wp:menu_order',
41 'wp:post_type',
42 'wp:post_password',
43 'wp:is_sticky',
44 'wp:term_id',
45 'wp:category_nicename',
46 'wp:category_parent',
47 'wp:cat_name',
48 'wp:category_description',
49 'wp:tag_slug',
50 'wp:tag_name',
51 'wp:tag_description',
52 'wp:term_taxonomy',
53 'wp:term_parent',
54 'wp:term_name',
55 'wp:term_description',
56 'wp:author_id',
57 'wp:author_login',
58 'wp:author_email',
59 'wp:author_display_name',
60 'wp:author_first_name',
61 'wp:author_last_name',
62 ];
63
64 private static $wp_sub_tags = [
65 'wp:comment_id',
66 'wp:comment_author',
67 'wp:comment_author_email',
68 'wp:comment_author_url',
69 'wp:comment_author_IP',
70 'wp:comment_date',
71 'wp:comment_date_gmt',
72 'wp:comment_content',
73 'wp:comment_approved',
74 'wp:comment_type',
75 'wp:comment_parent',
76 'wp:comment_user_id',
77 ];
78
79 /**
80 * @var string
81 */
82 private $wxr_version;
83
84 /**
85 * @var string
86 */
87 private $cdata;
88
89 /**
90 * @var array
91 */
92 private $data;
93
94 /**
95 * @var array
96 */
97 private $sub_data;
98
99 /**
100 * @var boolean
101 */
102 private $in_post;
103
104 /**
105 * @var boolean
106 */
107 private $in_tag;
108
109 /**
110 * @var boolean
111 */
112 private $in_sub_tag;
113
114 /**
115 * @var array
116 */
117 private $authors;
118
119 /**
120 * @var array
121 */
122 private $posts;
123
124 /**
125 * @var array
126 */
127 private $term;
128
129 /**
130 * @var array
131 */
132 private $category;
133
134 /**
135 * @var array
136 */
137 private $tag;
138
139 /**
140 * @var string
141 */
142 private $base_url;
143
144 /**
145 * @var string
146 */
147 private $base_blog_url;
148
149 /**
150 * @param string $file
151 *
152 * @return array|WP_Error
153 */
154 public function parse( $file ) {
155 $this->clear();
156
157 $xml = xml_parser_create( 'UTF-8' );
158 xml_parser_set_option( $xml, XML_OPTION_SKIP_WHITE, 1 );
159 xml_parser_set_option( $xml, XML_OPTION_CASE_FOLDING, 0 );
160 xml_set_object( $xml, $this );
161
162 xml_set_character_data_handler( $xml, function ( $parser, $cdata ) {
163 $this->cdata( $cdata );
164 } );
165
166 $tag_open_callback = function ( $parse, $tag, $attr ) {
167 $this->tag_open( $tag, $attr );
168 };
169
170 $tag_close_callback = function ( $parser, $tag ) {
171 $this->tag_close( $tag );
172 };
173
174 xml_set_element_handler( $xml, $tag_open_callback, $tag_close_callback );
175
176 if ( ! xml_parse( $xml, Utils::file_get_contents( $file ), true ) ) {
177 $current_line = xml_get_current_line_number( $xml );
178 $current_column = xml_get_current_column_number( $xml );
179 $error_code = xml_get_error_code( $xml );
180 $error_string = xml_error_string( $error_code );
181
182 return new WP_Error( 'XML_parse_error', 'There was an error when reading this WXR file', [
183 $current_line,
184 $current_column,
185 $error_string,
186 ] );
187 }
188 xml_parser_free( $xml );
189
190 if ( ! preg_match( '/^\d+\.\d+$/', $this->wxr_version ) ) {
191 return new WP_Error( 'WXR_parse_error', esc_html__( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'elementor' ) );
192 }
193
194 return array(
195 'authors' => $this->authors,
196 'posts' => $this->posts,
197 'categories' => $this->category,
198 'tags' => $this->tag,
199 'terms' => $this->term,
200 'base_url' => $this->base_url,
201 'base_blog_url' => $this->base_blog_url,
202 'version' => $this->wxr_version,
203 );
204 }
205
206 private function tag_open( $tag, $attr ) {
207 if ( in_array( $tag, self::$wp_tags ) ) {
208 $this->in_tag = substr( $tag, 3 );
209
210 return;
211 }
212
213 if ( in_array( $tag, self::$wp_sub_tags ) ) {
214 $this->in_sub_tag = substr( $tag, 3 );
215
216 return;
217 }
218
219 switch ( $tag ) {
220 case 'category':
221 if ( isset( $attr['domain'], $attr['nicename'] ) ) {
222 $this->sub_data['domain'] = $attr['domain'];
223 $this->sub_data['slug'] = $attr['nicename'];
224 }
225 break;
226 case 'item':
227 $this->in_post = true;
228 // No break !!!.
229 case 'title':
230 if ( $this->in_post ) {
231 $this->in_tag = 'post_title';
232 }
233 break;
234 case 'guid':
235 $this->in_tag = 'guid';
236 break;
237 case 'dc:creator':
238 $this->in_tag = 'post_author';
239 break;
240 case 'content:encoded':
241 $this->in_tag = 'post_content';
242 break;
243 case 'excerpt:encoded':
244 $this->in_tag = 'post_excerpt';
245 break;
246
247 case 'wp:term_slug':
248 $this->in_tag = 'slug';
249 break;
250 case 'wp:meta_key':
251 $this->in_sub_tag = 'key';
252 break;
253 case 'wp:meta_value':
254 $this->in_sub_tag = 'value';
255 break;
256 }
257 }
258
259 private function cdata( $cdata ) {
260 if ( ! trim( $cdata ) ) {
261 return;
262 }
263
264 if ( false !== $this->in_tag || false !== $this->in_sub_tag ) {
265 $this->cdata .= $cdata;
266 } else {
267 $this->cdata .= trim( $cdata );
268 }
269 }
270
271 private function tag_close( $tag ) {
272 switch ( $tag ) {
273 case 'wp:comment':
274 unset( $this->sub_data['key'], $this->sub_data['value'] ); // Remove meta sub_data.
275 if ( ! empty( $this->sub_data ) ) {
276 $this->data['comments'][] = $this->sub_data;
277 }
278 $this->sub_data = [];
279 break;
280 case 'wp:commentmeta':
281 $this->sub_data['commentmeta'][] = [
282 'key' => $this->sub_data['key'],
283 'value' => $this->sub_data['value'],
284 ];
285 break;
286 case 'category':
287 if ( ! empty( $this->sub_data ) ) {
288 $this->sub_data['name'] = $this->cdata;
289 $this->data['terms'][] = $this->sub_data;
290 }
291 $this->sub_data = [];
292 break;
293 case 'wp:postmeta':
294 if ( ! empty( $this->sub_data ) ) {
295 $this->data['postmeta'][] = $this->sub_data;
296 }
297 $this->sub_data = [];
298 break;
299 case 'item':
300 // Ensure attachment_type field is set, default to null if not present
301 if ( ! isset( $this->data['attachment_type'] ) ) {
302 $this->data['attachment_type'] = null;
303 }
304 $this->posts[] = $this->data;
305 $this->data = [];
306 break;
307 case 'wp:category':
308 case 'wp:tag':
309 case 'wp:term':
310 $n = substr( $tag, 3 );
311 array_push( $this->$n, $this->data );
312 $this->data = [];
313 break;
314 case 'wp:termmeta':
315 if ( ! empty( $this->sub_data ) ) {
316 $this->data['termmeta'][] = $this->sub_data;
317 }
318 $this->sub_data = [];
319 break;
320 case 'wp:author':
321 if ( ! empty( $this->data['author_login'] ) ) {
322 $this->authors[ $this->data['author_login'] ] = $this->data;
323 }
324 $this->data = [];
325 break;
326 case 'wp:base_site_url':
327 $this->base_url = $this->cdata;
328 if ( ! isset( $this->base_blog_url ) ) {
329 $this->base_blog_url = $this->cdata;
330 }
331 break;
332 case 'wp:base_blog_url':
333 $this->base_blog_url = $this->cdata;
334 break;
335 case 'wp:wxr_version':
336 $this->wxr_version = $this->cdata;
337 break;
338
339 default:
340 if ( $this->in_sub_tag ) {
341 $this->sub_data[ $this->in_sub_tag ] = $this->cdata;
342 $this->in_sub_tag = false;
343 } else if ( $this->in_tag ) {
344 $this->data[ $this->in_tag ] = $this->cdata;
345 $this->in_tag = false;
346 }
347 }
348
349 $this->cdata = '';
350 }
351
352 private function clear() {
353 $this->wxr_version = '';
354
355 $this->cdata = '';
356 $this->data = [];
357 $this->sub_data = [];
358
359 $this->in_post = false;
360 $this->in_tag = false;
361 $this->in_sub_tag = false;
362
363 $this->authors = [];
364 $this->posts = [];
365 $this->term = [];
366 $this->category = [];
367 $this->tag = [];
368 }
369 }
370