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
WP_Import.php
991 lines
| 1 | <?php |
| 2 | /** |
| 3 | * WordPress WXR Importer. |
| 4 | */ |
| 5 | |
| 6 | namespace TIOB\Importers\WP; |
| 7 | |
| 8 | use TIOB\Importers\Cleanup\Active_State; |
| 9 | use TIOB\Importers\Helpers\Helper; |
| 10 | use TIOB\Importers\Helpers\Slug_Mapping; |
| 11 | use TIOB\Logger; |
| 12 | use WP_Error; |
| 13 | use WP_Importer; |
| 14 | |
| 15 | /** |
| 16 | * WordPress Importer class for managing the import process of a WXR file |
| 17 | * |
| 18 | * @package templates-patterns-collection |
| 19 | */ |
| 20 | class WP_Import extends WP_Importer { |
| 21 | use Helper; |
| 22 | /** |
| 23 | * @var Logger |
| 24 | */ |
| 25 | private $logger; |
| 26 | |
| 27 | public $max_wxr_version = 1.2; // max. supported WXR version |
| 28 | public $id; // WXR attachment ID |
| 29 | // information to import from WXR file |
| 30 | public $version; |
| 31 | public $posts = array(); |
| 32 | public $terms = array(); |
| 33 | public $categories = array(); |
| 34 | public $tags = array(); |
| 35 | public $base_url = ''; |
| 36 | public $base_blog_url = ''; |
| 37 | // mappings from old information to new |
| 38 | public $processed_posts = array(); |
| 39 | public $processed_terms = array(); |
| 40 | public $post_orphans = array(); |
| 41 | public $processed_menu_items = array(); |
| 42 | public $menu_item_orphans = array(); |
| 43 | public $missing_menu_items = array(); |
| 44 | public $fetch_attachments = true; |
| 45 | public $url_remap = array(); |
| 46 | public $featured_images = array(); |
| 47 | public $page_builder = null; |
| 48 | |
| 49 | /** |
| 50 | * WP_Import constructor. |
| 51 | * |
| 52 | * @param string $page_builder the page builder used. |
| 53 | */ |
| 54 | public function __construct( $page_builder = '' ) { |
| 55 | $this->page_builder = $page_builder; |
| 56 | require_once ABSPATH . 'wp-admin/includes/import.php'; |
| 57 | require_once ABSPATH . 'wp-admin/includes/post.php'; |
| 58 | require_once ABSPATH . 'wp-admin/includes/taxonomy.php'; |
| 59 | } |
| 60 | |
| 61 | |
| 62 | /** |
| 63 | * The main controller for the actual import stage. |
| 64 | * |
| 65 | * @param string $file Path to the WXR file for importing |
| 66 | */ |
| 67 | function import( $file ) { |
| 68 | $this->set_logger(); |
| 69 | add_filter( 'import_post_meta_key', array( $this, 'is_valid_meta_key' ) ); |
| 70 | add_filter( 'http_request_timeout', array( &$this, 'bump_request_timeout' ) ); |
| 71 | $this->import_start( $file ); |
| 72 | wp_suspend_cache_invalidation( true ); |
| 73 | $this->process_categories(); |
| 74 | $this->process_tags(); |
| 75 | $this->process_terms(); |
| 76 | add_filter( 'upload_mimes', array( $this, 'enable_svg_import' ) ); |
| 77 | $this->process_posts(); |
| 78 | remove_filter( 'upload_mimes', array( $this, 'enable_svg_import' ) ); |
| 79 | wp_suspend_cache_invalidation( false ); |
| 80 | // update incorrect/missing information in the DB |
| 81 | $this->backfill_parents(); |
| 82 | $this->backfill_attachment_urls(); |
| 83 | $this->remap_featured_images(); |
| 84 | $this->import_end(); |
| 85 | } |
| 86 | |
| 87 | /** |
| 88 | * Filter the allowed mime types and add SVG support. |
| 89 | * |
| 90 | * @param array $mimes List of allowed mime types. |
| 91 | * |
| 92 | * @return array |
| 93 | */ |
| 94 | public function enable_svg_import( $mimes ) { |
| 95 | $mimes['svg'] = 'image/svg+xml'; |
| 96 | return $mimes; |
| 97 | } |
| 98 | |
| 99 | /** |
| 100 | * Logger initialized. |
| 101 | */ |
| 102 | private function set_logger() { |
| 103 | $this->logger = Logger::get_instance(); |
| 104 | } |
| 105 | |
| 106 | /** |
| 107 | * Parses the WXR file and prepares us for the task of processing parsed data |
| 108 | * |
| 109 | * @param string $file Path to the WXR file for importing |
| 110 | */ |
| 111 | private function import_start( $file ) { |
| 112 | $this->logger->log( 'Import started.', 'success' ); |
| 113 | if ( ! is_file( $file ) ) { |
| 114 | $this->logger->log( 'No file to import.' ); |
| 115 | die(); |
| 116 | } |
| 117 | $import_data = $this->parse( $file ); |
| 118 | if ( is_wp_error( $import_data ) ) { |
| 119 | $this->logger->log( 'Error parsing WXR file.' ); |
| 120 | die(); |
| 121 | } |
| 122 | $this->version = $import_data['version']; |
| 123 | $this->posts = $import_data['posts']; |
| 124 | $this->terms = $import_data['terms']; |
| 125 | $this->categories = $import_data['categories']; |
| 126 | $this->tags = $import_data['tags']; |
| 127 | $this->base_url = esc_url( $import_data['base_url'] ); |
| 128 | $this->base_blog_url = esc_url( $import_data['base_blog_url'] ); |
| 129 | Slug_Mapping::register_source_url( $this->base_url ); |
| 130 | Slug_Mapping::register_source_url( $this->base_blog_url ); |
| 131 | wp_defer_term_counting( true ); |
| 132 | wp_defer_comment_counting( true ); |
| 133 | do_action( 'import_start' ); |
| 134 | } |
| 135 | |
| 136 | /** |
| 137 | * Performs post-import cleanup of files and the cache |
| 138 | */ |
| 139 | private function import_end() { |
| 140 | $this->logger->log( "Cleaning up import with id {$this->id}...", 'progress' ); |
| 141 | wp_import_cleanup( $this->id ); |
| 142 | $this->logger->log( 'Done cleanup. Flushing cache...', 'progress' ); |
| 143 | wp_cache_flush(); |
| 144 | $this->logger->log( 'Flushed cache. Removing temporary data..', 'progress' ); |
| 145 | foreach ( get_taxonomies() as $tax ) { |
| 146 | delete_option( "{$tax}_children" ); |
| 147 | _get_term_hierarchy( $tax ); |
| 148 | } |
| 149 | wp_defer_term_counting( false ); |
| 150 | wp_defer_comment_counting( false ); |
| 151 | $this->logger->log( 'Done importing', 'success' ); |
| 152 | do_action( 'import_end' ); |
| 153 | } |
| 154 | |
| 155 | /** |
| 156 | * Create new categories based on import information |
| 157 | * |
| 158 | * Doesn't create a new category if its slug already exists |
| 159 | */ |
| 160 | private function process_categories() { |
| 161 | $this->logger->log( 'Processing categories...', 'progress' ); |
| 162 | $this->categories = apply_filters( 'wp_import_categories', $this->categories ); |
| 163 | if ( empty( $this->categories ) ) { |
| 164 | $this->logger->log( 'No categories to process.', 'warning' ); |
| 165 | |
| 166 | return; |
| 167 | } |
| 168 | foreach ( $this->categories as $cat ) { |
| 169 | // if the category already exists leave it alone |
| 170 | $term_id = term_exists( $cat['category_nicename'], 'category' ); |
| 171 | if ( $term_id ) { |
| 172 | if ( is_array( $term_id ) ) { |
| 173 | $term_id = $term_id['term_id']; |
| 174 | } |
| 175 | if ( isset( $cat['term_id'] ) ) { |
| 176 | $this->processed_terms[ intval( $cat['term_id'] ) ] = (int) $term_id; |
| 177 | } |
| 178 | continue; |
| 179 | } |
| 180 | $category_parent = empty( $cat['category_parent'] ) ? 0 : category_exists( $cat['category_parent'] ); |
| 181 | $category_description = isset( $cat['category_description'] ) ? $cat['category_description'] : ''; |
| 182 | $catarr = array( |
| 183 | 'category_nicename' => $cat['category_nicename'], |
| 184 | 'category_parent' => $category_parent, |
| 185 | 'cat_name' => $cat['cat_name'], |
| 186 | 'category_description' => $category_description, |
| 187 | ); |
| 188 | $catarr = wp_slash( $catarr ); |
| 189 | $id = wp_insert_category( $catarr ); |
| 190 | if ( ! is_wp_error( $id ) ) { |
| 191 | if ( isset( $cat['term_id'] ) ) { |
| 192 | do_action( 'themeisle_cl_add_item_to_property_state', Active_State::CATEGORY_NSP, $id ); |
| 193 | $this->processed_terms[ intval( $cat['term_id'] ) ] = $id; |
| 194 | } |
| 195 | } else { |
| 196 | $this->logger->log( $id->get_error_message() ); |
| 197 | continue; |
| 198 | } |
| 199 | $this->process_termmeta( $cat, $id ); |
| 200 | } |
| 201 | unset( $this->categories ); |
| 202 | $this->logger->log( 'Processed categories.', 'success' ); |
| 203 | } |
| 204 | |
| 205 | /** |
| 206 | * Create new post tags based on import information |
| 207 | * |
| 208 | * Doesn't create a tag if its slug already exists |
| 209 | */ |
| 210 | private function process_tags() { |
| 211 | $this->logger->log( 'Processing tags...', 'progress' ); |
| 212 | $this->tags = apply_filters( 'wp_import_tags', $this->tags ); |
| 213 | if ( empty( $this->tags ) ) { |
| 214 | $this->logger->log( 'No tags to process.', 'success' ); |
| 215 | |
| 216 | return; |
| 217 | } |
| 218 | foreach ( $this->tags as $tag ) { |
| 219 | // if the tag already exists leave it alone |
| 220 | $term_id = term_exists( $tag['tag_slug'], 'post_tag' ); |
| 221 | if ( $term_id ) { |
| 222 | if ( is_array( $term_id ) ) { |
| 223 | $term_id = $term_id['term_id']; |
| 224 | } |
| 225 | if ( isset( $tag['term_id'] ) ) { |
| 226 | $this->processed_terms[ intval( $tag['term_id'] ) ] = (int) $term_id; |
| 227 | } |
| 228 | continue; |
| 229 | } |
| 230 | $tag = wp_slash( $tag ); |
| 231 | $tag_desc = isset( $tag['tag_description'] ) ? $tag['tag_description'] : ''; |
| 232 | $tagarr = array( |
| 233 | 'slug' => $tag['tag_slug'], |
| 234 | 'description' => $tag_desc, |
| 235 | ); |
| 236 | $id = wp_insert_term( $tag['tag_name'], 'post_tag', $tagarr ); |
| 237 | if ( ! is_wp_error( $id ) ) { |
| 238 | if ( isset( $tag['term_id'] ) ) { |
| 239 | do_action( 'themeisle_cl_add_item_to_property_state', Active_State::TAGS_NSP, $id['term_id'] ); |
| 240 | $this->processed_terms[ intval( $tag['term_id'] ) ] = $id['term_id']; |
| 241 | } |
| 242 | } else { |
| 243 | $this->logger->log( "Failed to import post tag {$tag['tag_name']}" ); |
| 244 | $this->logger->log( $id->get_error_message() ); |
| 245 | continue; |
| 246 | } |
| 247 | $this->process_termmeta( $tag, $id['term_id'] ); |
| 248 | } |
| 249 | $this->logger->log( 'Processed tags.', 'success' ); |
| 250 | unset( $this->tags ); |
| 251 | } |
| 252 | |
| 253 | /** |
| 254 | * Create new terms based on import information |
| 255 | * |
| 256 | * Doesn't create a term its slug already exists |
| 257 | */ |
| 258 | private function process_terms() { |
| 259 | $this->logger->log( 'Processing terms...', 'progress' ); |
| 260 | $this->terms = apply_filters( 'wp_import_terms', $this->terms ); |
| 261 | if ( empty( $this->terms ) ) { |
| 262 | $this->logger->log( 'No terms to process.', 'success' ); |
| 263 | |
| 264 | return; |
| 265 | } |
| 266 | foreach ( $this->terms as $term ) { |
| 267 | // if the term already exists in the correct taxonomy leave it alone |
| 268 | $term_id = term_exists( $term['slug'], $term['term_taxonomy'] ); |
| 269 | if ( $term_id ) { |
| 270 | if ( is_array( $term_id ) ) { |
| 271 | $term_id = $term_id['term_id']; |
| 272 | } |
| 273 | if ( isset( $term['term_id'] ) ) { |
| 274 | $this->processed_terms[ intval( $term['term_id'] ) ] = (int) $term_id; |
| 275 | } |
| 276 | continue; |
| 277 | } |
| 278 | if ( empty( $term['term_parent'] ) ) { |
| 279 | $parent = 0; |
| 280 | } else { |
| 281 | $parent = term_exists( $term['term_parent'], $term['term_taxonomy'] ); |
| 282 | if ( is_array( $parent ) ) { |
| 283 | $parent = $parent['term_id']; |
| 284 | } |
| 285 | } |
| 286 | $term = wp_slash( $term ); |
| 287 | $description = isset( $term['term_description'] ) ? $term['term_description'] : ''; |
| 288 | $termarr = array( |
| 289 | 'slug' => $term['slug'], |
| 290 | 'description' => $description, |
| 291 | 'parent' => intval( $parent ), |
| 292 | ); |
| 293 | $id = wp_insert_term( $term['term_name'], $term['term_taxonomy'], $termarr ); |
| 294 | if ( ! is_wp_error( $id ) ) { |
| 295 | if ( isset( $term['term_id'] ) ) { |
| 296 | do_action( |
| 297 | 'themeisle_cl_add_item_to_property_state', |
| 298 | Active_State::TERMS_NSP, |
| 299 | array( |
| 300 | 'id' => $id['term_id'], |
| 301 | 'taxonomy' => $term['term_taxonomy'], |
| 302 | ) |
| 303 | ); |
| 304 | $this->processed_terms[ intval( $term['term_id'] ) ] = $id['term_id']; |
| 305 | } |
| 306 | } else { |
| 307 | $this->logger->log( "Failed to import {$term['term_taxonomy']} {$term['term_name']}", 'warning' ); |
| 308 | $this->logger->log( $id->get_error_message() ); |
| 309 | continue; |
| 310 | } |
| 311 | $this->process_termmeta( $term, $id['term_id'] ); |
| 312 | } |
| 313 | |
| 314 | unset( $this->terms ); |
| 315 | $this->logger->log( 'Processed terms.', 'success' ); |
| 316 | } |
| 317 | |
| 318 | /** |
| 319 | * Add metadata to imported term. |
| 320 | * |
| 321 | * @since 0.6.2 |
| 322 | * |
| 323 | * @param array $term Term data from WXR import. |
| 324 | * @param int $term_id ID of the newly created term. |
| 325 | */ |
| 326 | private function process_termmeta( $term, $term_id ) { |
| 327 | if ( ! isset( $term['termmeta'] ) ) { |
| 328 | $term['termmeta'] = array(); |
| 329 | } |
| 330 | /** |
| 331 | * Filters the metadata attached to an imported term. |
| 332 | * |
| 333 | * @since 0.6.2 |
| 334 | * |
| 335 | * @param array $termmeta Array of term meta. |
| 336 | * @param int $term_id ID of the newly created term. |
| 337 | * @param array $term Term data from the WXR import. |
| 338 | */ |
| 339 | $term['termmeta'] = apply_filters( 'wp_import_term_meta', $term['termmeta'], $term_id, $term ); |
| 340 | if ( empty( $term['termmeta'] ) ) { |
| 341 | return; |
| 342 | } |
| 343 | foreach ( $term['termmeta'] as $meta ) { |
| 344 | /** |
| 345 | * Filters the meta key for an imported piece of term meta. |
| 346 | * |
| 347 | * @since 0.6.2 |
| 348 | * |
| 349 | * @param string $meta_key Meta key. |
| 350 | * @param int $term_id ID of the newly created term. |
| 351 | * @param array $term Term data from the WXR import. |
| 352 | */ |
| 353 | $key = apply_filters( 'import_term_meta_key', $meta['key'], $term_id, $term ); |
| 354 | if ( ! $key ) { |
| 355 | continue; |
| 356 | } |
| 357 | // Export gets meta straight from the DB so could have a serialized string |
| 358 | $value = maybe_unserialize( $meta['value'] ); |
| 359 | add_term_meta( $term_id, $key, $value ); |
| 360 | /** |
| 361 | * Fires after term meta is imported. |
| 362 | * |
| 363 | * @since 0.6.2 |
| 364 | * |
| 365 | * @param int $term_id ID of the newly created term. |
| 366 | * @param string $key Meta key. |
| 367 | * @param mixed $value Meta value. |
| 368 | */ |
| 369 | do_action( 'import_term_meta', $term_id, $key, $value ); |
| 370 | } |
| 371 | } |
| 372 | |
| 373 | /** |
| 374 | * Check whether the post type is a Pods plugin post type. |
| 375 | * |
| 376 | * @param string $post_type The post type. |
| 377 | * |
| 378 | * @return bool |
| 379 | */ |
| 380 | private function is_post_type_of_pods_plugin( $post_type ) { |
| 381 | if ( ! ( function_exists( 'pods_api' ) && class_exists( 'Pod', true ) ) ) { |
| 382 | return false; |
| 383 | } |
| 384 | $api = pods_api(); |
| 385 | $pods_post_types = $api->load_pods( |
| 386 | array( |
| 387 | 'type' => 'post_type', |
| 388 | 'refresh' => true, |
| 389 | ) |
| 390 | ); |
| 391 | foreach ( $pods_post_types as $pod_post_type ) { |
| 392 | if ( $pod_post_type['name'] === $post_type ) { |
| 393 | return true; |
| 394 | } |
| 395 | } |
| 396 | return false; |
| 397 | } |
| 398 | |
| 399 | /** |
| 400 | * Create new posts based on import information |
| 401 | * |
| 402 | * Posts marked as having a parent which doesn't exist will become top level items. |
| 403 | * Doesn't create a new post if: the post type doesn't exist, the given post ID |
| 404 | * is already noted as imported or a post with the same title and date already exists. |
| 405 | * Note that new/updated terms, comments and meta are imported for the last of the above. |
| 406 | */ |
| 407 | private function process_posts() { |
| 408 | $this->logger->log( 'Processing posts...', 'progress' ); |
| 409 | $this->posts = apply_filters( 'wp_import_posts', $this->posts ); |
| 410 | foreach ( $this->posts as $post ) { |
| 411 | $post = apply_filters( 'wp_import_post_data_raw', $post ); |
| 412 | if ( ! post_type_exists( $post['post_type'] ) ) { |
| 413 | if ( ! $this->is_post_type_of_pods_plugin( $post['post_type'] ) ) { |
| 414 | $this->logger->log( "Failed to import {$post['post_title']}. Invalid post type {$post['post_type']}" ); |
| 415 | do_action( 'wp_import_post_exists', $post ); |
| 416 | continue; |
| 417 | } |
| 418 | } |
| 419 | if ( isset( $this->processed_posts[ $post['post_id'] ] ) && ! empty( $post['post_id'] ) ) { |
| 420 | continue; |
| 421 | } |
| 422 | if ( $post['status'] == 'auto-draft' ) { |
| 423 | continue; |
| 424 | } |
| 425 | if ( 'nav_menu_item' == $post['post_type'] ) { |
| 426 | $this->process_menu_item( $post ); |
| 427 | continue; |
| 428 | } |
| 429 | $post_type_object = get_post_type_object( $post['post_type'] ); |
| 430 | $post_exists = post_exists( $post['post_title'], '', $post['post_date'] ); |
| 431 | /** |
| 432 | * Filter ID of the existing post corresponding to post currently importing. |
| 433 | * |
| 434 | * Return 0 to force the post to be imported. Filter the ID to be something else |
| 435 | * to override which existing post is mapped to the imported post. |
| 436 | * |
| 437 | * @see post_exists() |
| 438 | * @since 0.6.2 |
| 439 | * |
| 440 | * @param int $post_exists Post ID, or 0 if post did not exist. |
| 441 | * @param array $post The post array to be inserted. |
| 442 | */ |
| 443 | $post_exists = apply_filters( 'wp_import_existing_post', $post_exists, $post ); |
| 444 | if ( $post_exists && get_post_type( $post_exists ) == $post['post_type'] ) { |
| 445 | $this->logger->log( $post_type_object->labels->singular_name . ' ' . esc_html( $post['post_title'] ) . ' already exists.', 'success' ); |
| 446 | $comment_post_id = $post_id = $post_exists; |
| 447 | $this->processed_posts[ intval( $post['post_id'] ) ] = intval( $post_exists ); |
| 448 | } else { |
| 449 | $post_parent = (int) $post['post_parent']; |
| 450 | if ( $post_parent ) { |
| 451 | // if we already know the parent, map it to the new local ID |
| 452 | if ( isset( $this->processed_posts[ $post_parent ] ) ) { |
| 453 | $post_parent = $this->processed_posts[ $post_parent ]; |
| 454 | // otherwise record the parent for later |
| 455 | } else { |
| 456 | $this->post_orphans[ intval( $post['post_id'] ) ] = $post_parent; |
| 457 | $post_parent = 0; |
| 458 | } |
| 459 | } |
| 460 | $author = (int) get_current_user_id(); |
| 461 | $postdata = array( |
| 462 | 'import_id' => $post['post_id'], |
| 463 | 'post_author' => $author, |
| 464 | 'post_date' => $post['post_date'], |
| 465 | 'post_date_gmt' => $post['post_date_gmt'], |
| 466 | 'post_content' => $post['post_content'], |
| 467 | 'post_excerpt' => $post['post_excerpt'], |
| 468 | 'post_title' => $post['post_title'], |
| 469 | 'post_status' => $post['status'], |
| 470 | 'post_name' => $post['post_name'], |
| 471 | 'comment_status' => $post['comment_status'], |
| 472 | 'ping_status' => $post['ping_status'], |
| 473 | 'guid' => $post['guid'], |
| 474 | 'post_parent' => $post_parent, |
| 475 | 'menu_order' => $post['menu_order'], |
| 476 | 'post_type' => $post['post_type'], |
| 477 | 'post_password' => $post['post_password'], |
| 478 | ); |
| 479 | $original_post_id = $post['post_id']; |
| 480 | $postdata = apply_filters( 'wp_import_post_data_processed', $postdata, $post ); |
| 481 | $postdata = wp_slash( $postdata ); |
| 482 | if ( 'attachment' == $postdata['post_type'] ) { |
| 483 | $remote_url = ! empty( $post['attachment_url'] ) ? $post['attachment_url'] : $post['guid']; |
| 484 | // try to use _wp_attached file for upload folder placement to ensure the same location as the export site |
| 485 | // e.g. location is 2003/05/image.jpg but the attachment post_date is 2010/09, see media_handle_upload() |
| 486 | $postdata['upload_date'] = $post['post_date']; |
| 487 | if ( isset( $post['postmeta'] ) ) { |
| 488 | foreach ( $post['postmeta'] as $meta ) { |
| 489 | if ( $meta['key'] == '_wp_attached_file' ) { |
| 490 | if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta['value'], $matches ) ) { |
| 491 | $postdata['upload_date'] = $matches[0]; |
| 492 | } |
| 493 | break; |
| 494 | } |
| 495 | } |
| 496 | } |
| 497 | $comment_post_id = $post_id = $this->process_attachment( $postdata, $remote_url ); |
| 498 | do_action( 'themeisle_cl_add_item_to_property_state', Active_State::ATTACHMENT_NSP, $post_id ); |
| 499 | } else { |
| 500 | $this->logger->log( "Inserting {$postdata['post_type']}: {$postdata['post_title']}.", 'progress' ); |
| 501 | $postdata['post_content'] = apply_filters( 'tpc_post_content_processed_terms', $postdata['post_content'], $this->processed_terms ); |
| 502 | $postdata['post_content'] = apply_filters( 'tpc_post_content_before_insert', $postdata['post_content'], $this->base_blog_url ); |
| 503 | $comment_post_id = $post_id = wp_insert_post( $postdata, true ); |
| 504 | $this->logger->log( "Done inserting {$postdata['post_type']}: {$postdata['post_title']}.", 'success' ); |
| 505 | do_action( 'wp_import_insert_post', $post_id, $original_post_id, $postdata, $post ); |
| 506 | do_action( 'themeisle_cl_add_item_to_property_state', Active_State::POSTS_NSP, $post_id ); |
| 507 | } |
| 508 | if ( is_wp_error( $post_id ) ) { |
| 509 | $this->logger->log( "Failed to import {$post_type_object->labels->singular_name} {$post['post_title']}. \n {$post_id->get_error_message()}" ); |
| 510 | continue; |
| 511 | } |
| 512 | if ( $post['is_sticky'] == 1 ) { |
| 513 | stick_post( $post_id ); |
| 514 | } |
| 515 | } |
| 516 | // map pre-import ID to local ID |
| 517 | $this->processed_posts[ intval( $post['post_id'] ) ] = (int) $post_id; |
| 518 | if ( ! isset( $post['terms'] ) ) { |
| 519 | $post['terms'] = array(); |
| 520 | } |
| 521 | $post['terms'] = apply_filters( 'wp_import_post_terms', $post['terms'], $post_id, $post ); |
| 522 | // add categories, tags and other terms |
| 523 | if ( ! empty( $post['terms'] ) ) { |
| 524 | $terms_to_set = array(); |
| 525 | foreach ( $post['terms'] as $term ) { |
| 526 | // back compat with WXR 1.0 map 'tag' to 'post_tag' |
| 527 | $taxonomy = ( 'tag' == $term['domain'] ) ? 'post_tag' : $term['domain']; |
| 528 | $term_exists = term_exists( $term['slug'], $taxonomy ); |
| 529 | $term_id = is_array( $term_exists ) ? $term_exists['term_id'] : $term_exists; |
| 530 | if ( ! $term_id ) { |
| 531 | $t = wp_insert_term( $term['name'], $taxonomy, array( 'slug' => $term['slug'] ) ); |
| 532 | if ( ! is_wp_error( $t ) ) { |
| 533 | $term_id = $t['term_id']; |
| 534 | do_action( 'wp_import_insert_term', $t, $term, $post_id, $post ); |
| 535 | } else { |
| 536 | $this->logger->log( "Failed to import {$taxonomy} {$term['name']}", 'success' ); |
| 537 | $this->logger->log( $t->get_error_message() ); |
| 538 | do_action( 'wp_import_insert_term_failed', $t, $term, $post_id, $post ); |
| 539 | continue; |
| 540 | } |
| 541 | } |
| 542 | $terms_to_set[ $taxonomy ][] = intval( $term_id ); |
| 543 | } |
| 544 | foreach ( $terms_to_set as $tax => $ids ) { |
| 545 | $tt_ids = wp_set_post_terms( $post_id, $ids, $tax ); |
| 546 | do_action( 'wp_import_set_post_terms', $tt_ids, $ids, $tax, $post_id, $post ); |
| 547 | } |
| 548 | unset( $post['terms'], $terms_to_set ); |
| 549 | } |
| 550 | if ( ! isset( $post['comments'] ) ) { |
| 551 | $post['comments'] = array(); |
| 552 | } |
| 553 | $post['comments'] = apply_filters( 'wp_import_post_comments', $post['comments'], $post_id, $post ); |
| 554 | if ( ! empty( $post['comments'] ) ) { |
| 555 | foreach ( $post['comments'] as $comment ) { |
| 556 | $comment['comment_post_ID'] = $post_id; |
| 557 | $comment['comment_meta'] = array_combine( array_column( $comment['commentmeta'], 'key' ), array_column( $comment['commentmeta'], 'value' ) ); |
| 558 | unset( $comment['commentmeta'] ); |
| 559 | $comment_id = wp_insert_comment( $comment ); |
| 560 | if ( $comment_id === false ) { |
| 561 | $this->logger->log( "Could not import comment for {$post_id}." ); |
| 562 | continue; |
| 563 | } |
| 564 | do_action( 'themeisle_cl_add_item_to_property_state', Active_State::COMMENTS_NSP, $comment_id ); |
| 565 | } |
| 566 | } |
| 567 | |
| 568 | if ( ! isset( $post['postmeta'] ) ) { |
| 569 | $post['postmeta'] = array(); |
| 570 | } |
| 571 | $post['postmeta'] = apply_filters( 'wp_import_post_meta', $post['postmeta'], $post_id, $post ); |
| 572 | // add/update post meta |
| 573 | if ( ! empty( $post['postmeta'] ) ) { |
| 574 | foreach ( $post['postmeta'] as $meta ) { |
| 575 | $key = apply_filters( 'import_post_meta_key', $meta['key'], $post_id, $post ); |
| 576 | $value = false; |
| 577 | if ( '_edit_last' == $key ) { |
| 578 | $key = false; |
| 579 | } |
| 580 | if ( $key ) { |
| 581 | // export gets meta straight from the DB so could have a serialized string |
| 582 | if ( ! $value ) { |
| 583 | $value = maybe_unserialize( $meta['value'] ); |
| 584 | } |
| 585 | if ( $key === '_elementor_data' ) { |
| 586 | $this->logger->log( 'Filtering elementor meta...', 'progress' ); |
| 587 | $meta_handler = new Elementor_Meta_Handler( $value, $this->base_blog_url ); |
| 588 | $meta_handler->filter_meta(); |
| 589 | $this->logger->log( 'Filtered elementor meta.', 'success' ); |
| 590 | } else { |
| 591 | $value = Slug_Mapping::rewrite_value( $value ); |
| 592 | } |
| 593 | if ( $key === '_atomic_wind_css' ) { |
| 594 | $meta_handler = new Atomic_Wind_Meta_Handler( $value ); |
| 595 | $meta_handler->filter_meta(); |
| 596 | } |
| 597 | if ( in_array( |
| 598 | $key, |
| 599 | array( |
| 600 | 'tve_custom_css', |
| 601 | 'tve_content_before_more', |
| 602 | 'tve_updated_post', |
| 603 | ) |
| 604 | ) ) { |
| 605 | $value = $this->replace_image_urls( $value ); |
| 606 | } |
| 607 | update_post_meta( $post_id, $key, $value ); |
| 608 | do_action( 'import_post_meta', $post_id, $key, $value ); |
| 609 | // if the post has a featured image, take note of this in case of remap |
| 610 | if ( '_thumbnail_id' == $key ) { |
| 611 | $this->featured_images[ $post_id ] = (int) $value; |
| 612 | } |
| 613 | } |
| 614 | } |
| 615 | } |
| 616 | } |
| 617 | unset( $this->posts ); |
| 618 | $this->logger->log( 'Processed posts.', 'success' ); |
| 619 | } |
| 620 | |
| 621 | /** |
| 622 | * Attempt to create a new menu item from import data |
| 623 | * |
| 624 | * Fails for draft, orphaned menu items and those without an associated nav_menu |
| 625 | * or an invalid nav_menu term. If the post type or term object which the menu item |
| 626 | * represents doesn't exist then the menu item will not be imported (waits until the |
| 627 | * end of the import to retry again before discarding). |
| 628 | * |
| 629 | * @param array $item Menu item details from WXR file |
| 630 | */ |
| 631 | private function process_menu_item( $item ) { |
| 632 | $this->logger->log( "Processing single menu item '{$item['post_title']}'...", 'progress' ); |
| 633 | // skip draft, orphaned menu items |
| 634 | if ( 'draft' == $item['status'] ) { |
| 635 | return; |
| 636 | } |
| 637 | $menu_slug = false; |
| 638 | if ( isset( $item['terms'] ) ) { |
| 639 | // loop through terms, assume first nav_menu term is correct menu |
| 640 | foreach ( $item['terms'] as $term ) { |
| 641 | if ( 'nav_menu' == $term['domain'] ) { |
| 642 | $menu_slug = $term['slug']; |
| 643 | break; |
| 644 | } |
| 645 | } |
| 646 | } |
| 647 | // no nav_menu term associated with this menu item |
| 648 | if ( ! $menu_slug ) { |
| 649 | $this->logger->log( 'Menu item skipped. Missing slug.', 'error' ); |
| 650 | |
| 651 | return; |
| 652 | } |
| 653 | $menu_id = term_exists( $menu_slug, 'nav_menu' ); |
| 654 | if ( ! $menu_id ) { |
| 655 | $this->logger->log( "Menu item invalid slug: {$menu_slug}", 'success' ); |
| 656 | |
| 657 | return; |
| 658 | } else { |
| 659 | $menu_id = is_array( $menu_id ) ? $menu_id['term_id'] : $menu_id; |
| 660 | } |
| 661 | $nv_mm_options = ''; |
| 662 | foreach ( $item['postmeta'] as $meta ) { |
| 663 | ${$meta['key']} = $meta['value']; |
| 664 | } |
| 665 | if ( 'taxonomy' == $_menu_item_type && isset( $this->processed_terms[ intval( $_menu_item_object_id ) ] ) ) { |
| 666 | $_menu_item_object_id = $this->processed_terms[ intval( $_menu_item_object_id ) ]; |
| 667 | } elseif ( 'post_type' == $_menu_item_type && isset( $this->processed_posts[ intval( $_menu_item_object_id ) ] ) ) { |
| 668 | $_menu_item_object_id = $this->processed_posts[ intval( $_menu_item_object_id ) ]; |
| 669 | } elseif ( 'custom' != $_menu_item_type ) { |
| 670 | // associated object is missing or not imported yet, we'll retry later |
| 671 | $this->missing_menu_items[] = $item; |
| 672 | |
| 673 | return; |
| 674 | } |
| 675 | if ( isset( $this->processed_menu_items[ intval( $_menu_item_menu_item_parent ) ] ) ) { |
| 676 | $_menu_item_menu_item_parent = $this->processed_menu_items[ intval( $_menu_item_menu_item_parent ) ]; |
| 677 | } elseif ( $_menu_item_menu_item_parent ) { |
| 678 | $this->menu_item_orphans[ intval( $item['post_id'] ) ] = (int) $_menu_item_menu_item_parent; |
| 679 | $_menu_item_menu_item_parent = 0; |
| 680 | } |
| 681 | // wp_update_nav_menu_item expects CSS classes as a space separated string |
| 682 | $_menu_item_classes = maybe_unserialize( $_menu_item_classes ); |
| 683 | if ( is_array( $_menu_item_classes ) ) { |
| 684 | $_menu_item_classes = implode( ' ', $_menu_item_classes ); |
| 685 | } |
| 686 | $args = array( |
| 687 | 'menu-item-object-id' => $_menu_item_object_id, |
| 688 | 'menu-item-object' => $_menu_item_object, |
| 689 | 'menu-item-parent-id' => $_menu_item_menu_item_parent, |
| 690 | 'menu-item-position' => intval( $item['menu_order'] ), |
| 691 | 'menu-item-type' => $_menu_item_type, |
| 692 | 'menu-item-title' => $item['post_title'], |
| 693 | 'menu-item-url' => $_menu_item_url, |
| 694 | 'menu-item-description' => $item['post_content'], |
| 695 | 'menu-item-attr-title' => $item['post_excerpt'], |
| 696 | 'menu-item-target' => $_menu_item_target, |
| 697 | 'menu-item-classes' => $_menu_item_classes, |
| 698 | 'menu-item-xfn' => $_menu_item_xfn, |
| 699 | 'menu-item-status' => $item['status'], |
| 700 | ); |
| 701 | $args = apply_filters( 'wp_import_nav_menu_item_args', $args, $this->base_blog_url ); |
| 702 | $existing = wp_get_nav_menu_items( $menu_id ); |
| 703 | foreach ( $existing as $existing_item ) { |
| 704 | if ( $args['menu-item-url'] === $existing_item->url && trim( $args['menu-item-title'] ) === $existing_item->title ) { |
| 705 | $this->logger->log( 'Menu item already exists.', 'success' ); |
| 706 | |
| 707 | return; |
| 708 | } |
| 709 | } |
| 710 | |
| 711 | $id = wp_update_nav_menu_item( $menu_id, 0, $args ); |
| 712 | if ( $id && ! is_wp_error( $id ) ) { |
| 713 | if ( ! empty( $nv_mm_options ) ) { |
| 714 | update_post_meta( $id, 'nv_mm_options', $nv_mm_options ); |
| 715 | } |
| 716 | $this->processed_menu_items[ intval( $item['post_id'] ) ] = (int) $id; |
| 717 | } |
| 718 | $this->logger->log( 'Processed single menu item.', 'success' ); |
| 719 | } |
| 720 | |
| 721 | /** |
| 722 | * If fetching attachments is enabled then attempt to create a new attachment |
| 723 | * |
| 724 | * @param array $post Attachment post details from WXR |
| 725 | * @param string $url URL to fetch attachment from |
| 726 | * |
| 727 | * @return int|WP_Error Post ID on success, WP_Error otherwise |
| 728 | */ |
| 729 | private function process_attachment( $post, $url ) { |
| 730 | $this->logger->log( "Processing attachment: {$url}...", 'progress' ); |
| 731 | if ( ! $this->fetch_attachments ) { |
| 732 | $this->logger->log( 'Fetching attachments is not enabled', 'error' ); |
| 733 | } |
| 734 | // if the URL is absolute, but does not contain address, then upload it assuming base_site_url |
| 735 | if ( preg_match( '|^/[\w\W]+$|', $url ) ) { |
| 736 | $url = rtrim( $this->base_url, '/' ) . $url; |
| 737 | } |
| 738 | $upload = $this->fetch_remote_file( $url, $post ); |
| 739 | if ( is_wp_error( $upload ) ) { |
| 740 | $this->logger->log( $upload ); |
| 741 | |
| 742 | return $upload; |
| 743 | } |
| 744 | $info = wp_check_filetype( $upload['file'] ); |
| 745 | if ( $info ) { |
| 746 | $post['post_mime_type'] = $info['type']; |
| 747 | } else { |
| 748 | $error = new WP_Error( 'attachment_processing_error', 'Invalid file type' ); |
| 749 | $this->logger->log( $error->get_error_message() ); |
| 750 | |
| 751 | return $error; |
| 752 | } |
| 753 | $post['guid'] = $upload['url']; |
| 754 | // as per wp-admin/includes/upload.php |
| 755 | $this->logger->log( 'Inserting attachment...', 'progress' ); |
| 756 | $post_id = wp_insert_attachment( $post, $upload['file'] ); |
| 757 | $this->logger->log( 'Attachment inserted', 'success' ); |
| 758 | wp_update_attachment_metadata( $post_id, wp_generate_attachment_metadata( $post_id, $upload['file'] ) ); |
| 759 | // remap resized image URLs, works by stripping the extension and remapping the URL stub. |
| 760 | if ( preg_match( '!^image/!', $info['type'] ) ) { |
| 761 | $parts = pathinfo( $url ); |
| 762 | $name = basename( $parts['basename'], ".{$parts['extension']}" ); // PATHINFO_FILENAME in PHP 5.2 |
| 763 | $parts_new = pathinfo( $upload['url'] ); |
| 764 | $name_new = basename( $parts_new['basename'], ".{$parts_new['extension']}" ); |
| 765 | $this->url_remap[ $parts['dirname'] . '/' . $name ] = $parts_new['dirname'] . '/' . $name_new; |
| 766 | } |
| 767 | $this->logger->log( 'Processed attachment.', 'success' ); |
| 768 | |
| 769 | return $post_id; |
| 770 | } |
| 771 | |
| 772 | /** |
| 773 | * Attempt to download a remote file attachment |
| 774 | * |
| 775 | * @param string $url URL of item to fetch |
| 776 | * @param array $post Attachment details |
| 777 | * |
| 778 | * @return array|WP_Error Local file location details on success, WP_Error otherwise |
| 779 | */ |
| 780 | private function fetch_remote_file( $url, $post ) { |
| 781 | $this->logger->log( "Fetching attachment from url: {$url}...", 'progress' ); |
| 782 | // extract the file name and extension from the url |
| 783 | $file_name = basename( $url ); |
| 784 | // get placeholder file in the upload dir with a unique, sanitized filename |
| 785 | $upload = wp_upload_bits( $file_name, 0, '', $post['upload_date'] ); |
| 786 | if ( $upload['error'] ) { |
| 787 | return new WP_Error( 'upload_dir_error', $upload['error'] ); |
| 788 | } |
| 789 | // fetch the remote url and write it to the placeholder file |
| 790 | $remote_response = wp_safe_remote_get( |
| 791 | $url, |
| 792 | array( |
| 793 | 'timeout' => 300, |
| 794 | 'stream' => true, |
| 795 | 'filename' => $upload['file'], |
| 796 | ) |
| 797 | ); |
| 798 | $headers = wp_remote_retrieve_headers( $remote_response ); |
| 799 | // request failed |
| 800 | if ( ! $headers ) { |
| 801 | @unlink( $upload['file'] ); |
| 802 | $error = new WP_Error( 'import_file_error', 'Remote server did not respond' ); |
| 803 | $this->logger->log( $error->get_error_message() ); |
| 804 | |
| 805 | return $error; |
| 806 | } |
| 807 | $remote_response_code = wp_remote_retrieve_response_code( $remote_response ); |
| 808 | // make sure the fetch was successful |
| 809 | if ( $remote_response_code != '200' ) { |
| 810 | @unlink( $upload['file'] ); |
| 811 | $error = new WP_Error( 'import_file_error', sprintf( 'Remote server returned error response %1$d %2$s', esc_html( $remote_response_code ), get_status_header_desc( $remote_response_code ) ) ); |
| 812 | $this->logger->log( $error->get_error_message() ); |
| 813 | |
| 814 | return $error; |
| 815 | } |
| 816 | $filesize = filesize( $upload['file'] ); |
| 817 | if ( isset( $headers['content-length'] ) && $filesize != $headers['content-length'] ) { |
| 818 | @unlink( $upload['file'] ); |
| 819 | $error = new WP_Error( 'import_file_error', 'Remote file is incorrect size' ); |
| 820 | $this->logger->log( $error->get_error_message() ); |
| 821 | |
| 822 | return $error; |
| 823 | } |
| 824 | if ( 0 == $filesize ) { |
| 825 | @unlink( $upload['file'] ); |
| 826 | $error = new WP_Error( 'import_file_error', 'Zero size file downloaded' ); |
| 827 | $this->logger->log( $error->get_error_message() ); |
| 828 | |
| 829 | return $error; |
| 830 | } |
| 831 | $max_size = (int) $this->max_attachment_size(); |
| 832 | if ( ! empty( $max_size ) && $filesize > $max_size ) { |
| 833 | @unlink( $upload['file'] ); |
| 834 | $error = new WP_Error( 'import_file_error', sprintf( 'Remote file is too large, limit is %s', size_format( $max_size ) ) ); |
| 835 | $this->logger->log( $error->get_error_message() ); |
| 836 | |
| 837 | return $error; |
| 838 | } |
| 839 | // keep track of the old and new urls so we can substitute them later |
| 840 | $this->url_remap[ $url ] = $upload['url']; |
| 841 | $this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed? |
| 842 | // keep track of the destination if the remote url is redirected somewhere else |
| 843 | if ( isset( $headers['x-final-location'] ) && $headers['x-final-location'] != $url ) { |
| 844 | $this->url_remap[ $headers['x-final-location'] ] = $upload['url']; |
| 845 | } |
| 846 | |
| 847 | $this->logger->log( 'Fetched remote attachment.', 'success' ); |
| 848 | |
| 849 | return $upload; |
| 850 | } |
| 851 | |
| 852 | /** |
| 853 | * Attempt to associate posts and menu items with previously missing parents |
| 854 | * |
| 855 | * An imported post's parent may not have been imported when it was first created |
| 856 | * so try again. Similarly for child menu items and menu items which were missing |
| 857 | * the object (e.g. post) they represent in the menu |
| 858 | */ |
| 859 | function backfill_parents() { |
| 860 | global $wpdb; |
| 861 | // find parents for post orphans |
| 862 | foreach ( $this->post_orphans as $child_id => $parent_id ) { |
| 863 | $local_child_id = $local_parent_id = false; |
| 864 | if ( isset( $this->processed_posts[ $child_id ] ) ) { |
| 865 | $local_child_id = $this->processed_posts[ $child_id ]; |
| 866 | } |
| 867 | if ( isset( $this->processed_posts[ $parent_id ] ) ) { |
| 868 | $local_parent_id = $this->processed_posts[ $parent_id ]; |
| 869 | } |
| 870 | if ( $local_child_id && $local_parent_id ) { |
| 871 | $wpdb->update( $wpdb->posts, array( 'post_parent' => $local_parent_id ), array( 'ID' => $local_child_id ), '%d', '%d' ); |
| 872 | clean_post_cache( $local_child_id ); |
| 873 | } |
| 874 | } |
| 875 | // all other posts/terms are imported, retry menu items with missing associated object |
| 876 | $missing_menu_items = $this->missing_menu_items; |
| 877 | foreach ( $missing_menu_items as $item ) { |
| 878 | $this->process_menu_item( $item ); |
| 879 | } |
| 880 | // find parents for menu item orphans |
| 881 | foreach ( $this->menu_item_orphans as $child_id => $parent_id ) { |
| 882 | $local_child_id = $local_parent_id = 0; |
| 883 | if ( isset( $this->processed_menu_items[ $child_id ] ) ) { |
| 884 | $local_child_id = $this->processed_menu_items[ $child_id ]; |
| 885 | } |
| 886 | if ( isset( $this->processed_menu_items[ $parent_id ] ) ) { |
| 887 | $local_parent_id = $this->processed_menu_items[ $parent_id ]; |
| 888 | } |
| 889 | if ( $local_child_id && $local_parent_id ) { |
| 890 | update_post_meta( $local_child_id, '_menu_item_menu_item_parent', (int) $local_parent_id ); |
| 891 | } |
| 892 | } |
| 893 | } |
| 894 | |
| 895 | /** |
| 896 | * Use stored mapping information to update old attachment URLs |
| 897 | */ |
| 898 | function backfill_attachment_urls() { |
| 899 | global $wpdb; |
| 900 | // make sure we do the longest urls first, in case one is a substring of another |
| 901 | uksort( $this->url_remap, array( &$this, 'cmpr_strlen' ) ); |
| 902 | foreach ( $this->url_remap as $from_url => $to_url ) { |
| 903 | // remap urls in post_content |
| 904 | $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)", $from_url, $to_url ) ); |
| 905 | // remap enclosure urls |
| 906 | $result = $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = REPLACE(meta_value, %s, %s) WHERE meta_key='enclosure'", $from_url, $to_url ) ); |
| 907 | } |
| 908 | } |
| 909 | |
| 910 | /** |
| 911 | * Update _thumbnail_id meta to new, imported attachment IDs |
| 912 | */ |
| 913 | function remap_featured_images() { |
| 914 | // cycle through posts that have a featured image |
| 915 | foreach ( $this->featured_images as $post_id => $value ) { |
| 916 | if ( isset( $this->processed_posts[ $value ] ) ) { |
| 917 | $new_id = $this->processed_posts[ $value ]; |
| 918 | // only update if there's a difference |
| 919 | if ( $new_id != $value ) { |
| 920 | update_post_meta( $post_id, '_thumbnail_id', $new_id ); |
| 921 | } |
| 922 | } |
| 923 | } |
| 924 | } |
| 925 | |
| 926 | /** |
| 927 | * Parse a WXR file |
| 928 | * |
| 929 | * @param string $file Path to WXR file for parsing |
| 930 | * |
| 931 | * @return array Information gathered from the WXR file |
| 932 | */ |
| 933 | private function parse( $file ) { |
| 934 | $this->logger->log( 'Parsing XML file.', 'success' ); |
| 935 | $parser = new WXR_Parser( $this->page_builder ); |
| 936 | |
| 937 | return $parser->parse( $file ); |
| 938 | } |
| 939 | |
| 940 | /** |
| 941 | * Decide if the given meta key maps to information we will want to import |
| 942 | * |
| 943 | * @param string $key The meta key to check |
| 944 | * |
| 945 | * @return string|bool The key if we do want to import, false if not |
| 946 | */ |
| 947 | public function is_valid_meta_key( $key ) { |
| 948 | // skip attachment metadata since we'll regenerate it from scratch |
| 949 | // skip _edit_lock as not relevant for import |
| 950 | if ( in_array( $key, array( '_wp_attached_file', '_wp_attachment_metadata', '_edit_lock' ) ) ) { |
| 951 | return false; |
| 952 | } |
| 953 | |
| 954 | return $key; |
| 955 | } |
| 956 | |
| 957 | /** |
| 958 | * Decide whether or not the importer should attempt to download attachment files. |
| 959 | * Default is true, can be filtered via import_allow_fetch_attachments. The choice |
| 960 | * made at the import options screen must also be true, false here hides that checkbox. |
| 961 | * |
| 962 | * @return bool True if downloading attachments is allowed |
| 963 | */ |
| 964 | function allow_fetch_attachments() { |
| 965 | return apply_filters( 'import_allow_fetch_attachments', true ); |
| 966 | } |
| 967 | |
| 968 | /** |
| 969 | * Decide what the maximum file size for downloaded attachments is. |
| 970 | * Default is 0 (unlimited), can be filtered via import_attachment_size_limit |
| 971 | * |
| 972 | * @return int Maximum attachment file size to import |
| 973 | */ |
| 974 | private function max_attachment_size() { |
| 975 | return apply_filters( 'import_attachment_size_limit', 0 ); |
| 976 | } |
| 977 | |
| 978 | /** |
| 979 | * Added to http_request_timeout filter to force timeout at 60 seconds during import |
| 980 | * @return int 60 |
| 981 | */ |
| 982 | public function bump_request_timeout( $val ) { |
| 983 | return 60; |
| 984 | } |
| 985 | |
| 986 | // return the difference in length between two strings |
| 987 | public function cmpr_strlen( $a, $b ) { |
| 988 | return strlen( $b ) - strlen( $a ); |
| 989 | } |
| 990 | } |
| 991 |