Atomic_Wind_Meta_Handler.php
3 months ago
Beaver_Data_Fix.php
5 years ago
Beaver_ParserXML.php
5 years ago
Elementor_Meta_Handler.php
3 months ago
WP_Import.php
3 months ago
WXR_Parser.php
5 years ago
WXR_Parser_SimpleXML.php
4 years ago
WXR_Parser_XML.php
5 years ago
WXR_Parser_XML.php
240 lines
| 1 | <?php |
| 2 | |
| 3 | namespace TIOB\Importers\WP; |
| 4 | |
| 5 | /** |
| 6 | * WXR Parser that makes use of the XML Parser PHP extension. |
| 7 | */ |
| 8 | class WXR_Parser_XML { |
| 9 | /** |
| 10 | * XML Tags. |
| 11 | * |
| 12 | * @var array |
| 13 | */ |
| 14 | public $wp_tags = array( |
| 15 | 'wp:post_id', |
| 16 | 'wp:post_date', |
| 17 | 'wp:post_date_gmt', |
| 18 | 'wp:comment_status', |
| 19 | 'wp:ping_status', |
| 20 | 'wp:attachment_url', |
| 21 | 'wp:status', |
| 22 | 'wp:post_name', |
| 23 | 'wp:post_parent', |
| 24 | 'wp:menu_order', |
| 25 | 'wp:post_type', |
| 26 | 'wp:post_password', |
| 27 | 'wp:is_sticky', |
| 28 | 'wp:term_id', |
| 29 | 'wp:category_nicename', |
| 30 | 'wp:category_parent', |
| 31 | 'wp:cat_name', |
| 32 | 'wp:category_description', |
| 33 | 'wp:tag_slug', |
| 34 | 'wp:tag_name', |
| 35 | 'wp:tag_description', |
| 36 | 'wp:term_taxonomy', |
| 37 | 'wp:term_parent', |
| 38 | 'wp:term_name', |
| 39 | 'wp:term_description', |
| 40 | 'wp:author_id', |
| 41 | 'wp:author_login', |
| 42 | 'wp:author_email', |
| 43 | 'wp:author_display_name', |
| 44 | 'wp:author_first_name', |
| 45 | 'wp:author_last_name', |
| 46 | ); |
| 47 | public $wp_sub_tags = array( |
| 48 | 'wp:comment_id', |
| 49 | 'wp:comment_author', |
| 50 | 'wp:comment_author_email', |
| 51 | 'wp:comment_author_url', |
| 52 | 'wp:comment_author_IP', |
| 53 | 'wp:comment_date', |
| 54 | 'wp:comment_date_gmt', |
| 55 | 'wp:comment_content', |
| 56 | 'wp:comment_approved', |
| 57 | 'wp:comment_type', |
| 58 | 'wp:comment_parent', |
| 59 | 'wp:comment_user_id', |
| 60 | ); |
| 61 | |
| 62 | /** |
| 63 | * Parse the XML |
| 64 | * |
| 65 | * @param $file |
| 66 | * |
| 67 | * @return array|WP_Error |
| 68 | */ |
| 69 | public function parse( $file ) { |
| 70 | global $wp_filesystem; |
| 71 | WP_Filesystem(); |
| 72 | $this->wxr_version = $this->in_post = $this->cdata = $this->data = $this->sub_data = $this->in_tag = $this->in_sub_tag = false; |
| 73 | $this->authors = $this->posts = $this->term = $this->category = $this->tag = array(); |
| 74 | $xml = xml_parser_create( 'UTF-8' ); |
| 75 | xml_parser_set_option( $xml, XML_OPTION_SKIP_WHITE, 1 ); |
| 76 | xml_parser_set_option( $xml, XML_OPTION_CASE_FOLDING, 0 ); |
| 77 | xml_set_object( $xml, $this ); |
| 78 | xml_set_character_data_handler( $xml, 'cdata' ); |
| 79 | xml_set_element_handler( $xml, 'tag_open', 'tag_close' ); |
| 80 | if ( ! xml_parse( $xml, $wp_filesystem->get_contents( $file ), true ) ) { |
| 81 | $current_line = xml_get_current_line_number( $xml ); |
| 82 | $current_column = xml_get_current_column_number( $xml ); |
| 83 | $error_code = xml_get_error_code( $xml ); |
| 84 | $error_string = xml_error_string( $error_code ); |
| 85 | |
| 86 | return new WP_Error( |
| 87 | 'XML_parse_error', |
| 88 | 'There was an error when reading this WXR file', |
| 89 | array( |
| 90 | $current_line, |
| 91 | $current_column, |
| 92 | $error_string, |
| 93 | ) |
| 94 | ); |
| 95 | } |
| 96 | xml_parser_free( $xml ); |
| 97 | if ( ! preg_match( '/^\d+\.\d+$/', $this->wxr_version ) ) { |
| 98 | return new WP_Error( 'WXR_parse_error', 'This does not appear to be a WXR file, missing/invalid WXR version number' ); |
| 99 | } |
| 100 | |
| 101 | return array( |
| 102 | 'authors' => $this->authors, |
| 103 | 'posts' => $this->posts, |
| 104 | 'categories' => $this->category, |
| 105 | 'tags' => $this->tag, |
| 106 | 'terms' => $this->term, |
| 107 | 'base_url' => $this->base_url, |
| 108 | 'base_blog_url' => $this->base_blog_url, |
| 109 | 'version' => $this->wxr_version, |
| 110 | ); |
| 111 | } |
| 112 | |
| 113 | public function tag_open( $parse, $tag, $attr ) { |
| 114 | if ( in_array( $tag, $this->wp_tags ) ) { |
| 115 | $this->in_tag = substr( $tag, 3 ); |
| 116 | |
| 117 | return; |
| 118 | } |
| 119 | if ( in_array( $tag, $this->wp_sub_tags ) ) { |
| 120 | $this->in_sub_tag = substr( $tag, 3 ); |
| 121 | |
| 122 | return; |
| 123 | } |
| 124 | switch ( $tag ) { |
| 125 | case 'category': |
| 126 | if ( isset( $attr['domain'], $attr['nicename'] ) ) { |
| 127 | $this->sub_data['domain'] = $attr['domain']; |
| 128 | $this->sub_data['slug'] = $attr['nicename']; |
| 129 | } |
| 130 | break; |
| 131 | case 'item': |
| 132 | $this->in_post = true; |
| 133 | break; |
| 134 | case 'title': |
| 135 | if ( $this->in_post ) { |
| 136 | $this->in_tag = 'post_title'; |
| 137 | } |
| 138 | break; |
| 139 | case 'guid': |
| 140 | $this->in_tag = 'guid'; |
| 141 | break; |
| 142 | case 'dc:creator': |
| 143 | $this->in_tag = 'post_author'; |
| 144 | break; |
| 145 | case 'content:encoded': |
| 146 | $this->in_tag = 'post_content'; |
| 147 | break; |
| 148 | case 'excerpt:encoded': |
| 149 | $this->in_tag = 'post_excerpt'; |
| 150 | break; |
| 151 | case 'wp:term_slug': |
| 152 | $this->in_tag = 'slug'; |
| 153 | break; |
| 154 | case 'wp:meta_key': |
| 155 | $this->in_sub_tag = 'key'; |
| 156 | break; |
| 157 | case 'wp:meta_value': |
| 158 | $this->in_sub_tag = 'value'; |
| 159 | break; |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | public function cdata( $parser, $cdata ) { |
| 164 | if ( ! trim( $cdata ) ) { |
| 165 | return; |
| 166 | } |
| 167 | if ( false !== $this->in_tag || false !== $this->in_sub_tag ) { |
| 168 | $this->cdata .= $cdata; |
| 169 | } else { |
| 170 | $this->cdata .= trim( $cdata ); |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | public function tag_close( $parser, $tag ) { |
| 175 | switch ( $tag ) { |
| 176 | case 'wp:comment': |
| 177 | unset( $this->sub_data['key'], $this->sub_data['value'] ); // remove meta sub_data |
| 178 | if ( ! empty( $this->sub_data ) ) { |
| 179 | $this->data['comments'][] = $this->sub_data; |
| 180 | } |
| 181 | $this->sub_data = false; |
| 182 | break; |
| 183 | case 'wp:commentmeta': |
| 184 | $this->sub_data['commentmeta'][] = array( |
| 185 | 'key' => $this->sub_data['key'], |
| 186 | 'value' => $this->sub_data['value'], |
| 187 | ); |
| 188 | break; |
| 189 | case 'category': |
| 190 | if ( ! empty( $this->sub_data ) ) { |
| 191 | $this->sub_data['name'] = $this->cdata; |
| 192 | $this->data['terms'][] = $this->sub_data; |
| 193 | } |
| 194 | $this->sub_data = false; |
| 195 | break; |
| 196 | case 'wp:postmeta': |
| 197 | if ( ! empty( $this->sub_data ) ) { |
| 198 | $this->data['postmeta'][] = $this->sub_data; |
| 199 | } |
| 200 | $this->sub_data = false; |
| 201 | break; |
| 202 | case 'item': |
| 203 | $this->posts[] = $this->data; |
| 204 | $this->data = false; |
| 205 | break; |
| 206 | case 'wp:category': |
| 207 | case 'wp:tag': |
| 208 | case 'wp:term': |
| 209 | $n = substr( $tag, 3 ); |
| 210 | array_push( $this->$n, $this->data ); |
| 211 | $this->data = false; |
| 212 | break; |
| 213 | case 'wp:author': |
| 214 | if ( ! empty( $this->data['author_login'] ) ) { |
| 215 | $this->authors[ $this->data['author_login'] ] = $this->data; |
| 216 | } |
| 217 | $this->data = false; |
| 218 | break; |
| 219 | case 'wp:base_site_url': |
| 220 | $this->base_url = $this->cdata; |
| 221 | break; |
| 222 | case 'wp:base_blog_url': |
| 223 | $this->base_blog_url = $this->cdata; |
| 224 | break; |
| 225 | case 'wp:wxr_version': |
| 226 | $this->wxr_version = $this->cdata; |
| 227 | break; |
| 228 | default: |
| 229 | if ( $this->in_sub_tag ) { |
| 230 | $this->sub_data[ $this->in_sub_tag ] = ! empty( $this->cdata ) ? $this->cdata : ''; |
| 231 | $this->in_sub_tag = false; |
| 232 | } elseif ( $this->in_tag ) { |
| 233 | $this->data[ $this->in_tag ] = ! empty( $this->cdata ) ? $this->cdata : ''; |
| 234 | $this->in_tag = false; |
| 235 | } |
| 236 | } |
| 237 | $this->cdata = false; |
| 238 | } |
| 239 | } |
| 240 |