← All changes
|
includes/import/image-parsers/abstract-image-parser.php
+132
-0
2.7.4
→
2.14.0
View file →
| @@ -1,0 +1,132 @@ | ||
| 1 | +<?php | |
| 2 | + | |
| 3 | +namespace ABlocks\import\ImageParsers; | |
| 4 | + | |
| 5 | +use ABlocks\import\ImageParsers\ablocks\ImageParser; | |
| 6 | +use DOMDocument; | |
| 7 | +use WP_Error; | |
| 8 | + | |
| 9 | +abstract class AbstractImageParser { | |
| 10 | + | |
| 11 | + protected array $block; | |
| 12 | + | |
| 13 | + public function __construct( array $block ) { | |
| 14 | + $this->block = $block; | |
| 15 | + } | |
| 16 | + | |
| 17 | + abstract protected function parse(); | |
| 18 | + | |
| 19 | + public function do_parse(): array { | |
| 20 | + $this->parse(); | |
| 21 | + return $this->block; | |
| 22 | + } | |
| 23 | + | |
| 24 | + /** | |
| 25 | + * Function handles downloading a remote file and inserting it | |
| 26 | + * into the WP Media Library. | |
| 27 | + * | |
| 28 | + * @param string $url HTTP URL address of a remote file. | |
| 29 | + * | |
| 30 | + * @return int|WP_Error The ID of the attachment or a WP_Error on failure | |
| 31 | + * @see https://developer.wordpress.org/reference/functions/media_handle_sideload/ | |
| 32 | + */ | |
| 33 | + protected function upload_file( string $url ) { | |
| 34 | + // URL Validation. | |
| 35 | + if ( ! wp_http_validate_url( $url ) ) { | |
| 36 | + return new WP_Error( 'invalid_url', 'File URL is invalid', array( 'status' => 400 ) ); | |
| 37 | + } | |
| 38 | + | |
| 39 | + $previous_uploaded = $this->previous_uploaded_file( $url ); | |
| 40 | + if ( $previous_uploaded ) { | |
| 41 | + return $previous_uploaded; | |
| 42 | + } | |
| 43 | + | |
| 44 | + // Gives us access to the download_url() and media_handle_sideload() functions. | |
| 45 | + if ( ! function_exists( 'download_url' ) || ! function_exists( 'media_handle_sideload' ) ) { | |
| 46 | + require_once ABSPATH . 'wp-admin/includes/image.php'; | |
| 47 | + require_once ABSPATH . 'wp-admin/includes/file.php'; | |
| 48 | + require_once ABSPATH . 'wp-admin/includes/media.php'; | |
| 49 | + } | |
| 50 | + | |
| 51 | + // Download file to temp dir. | |
| 52 | + $temp_file = download_url( $url ); | |
| 53 | + | |
| 54 | + // if the file was not able to be downloaded. | |
| 55 | + if ( is_wp_error( $temp_file ) ) { | |
| 56 | + return $temp_file; | |
| 57 | + } | |
| 58 | + | |
| 59 | + // An array similar to that of a PHP `$_FILES` POST array | |
| 60 | + $file_url_path = wp_parse_url( $url, PHP_URL_PATH ); | |
| 61 | + $file_info = wp_check_filetype( $file_url_path ); | |
| 62 | + $file = array( | |
| 63 | + 'tmp_name' => $temp_file, | |
| 64 | + 'type' => $file_info['type'], | |
| 65 | + 'name' => basename( $file_url_path ), | |
| 66 | + 'size' => filesize( $temp_file ), | |
| 67 | + ); | |
| 68 | + | |
| 69 | + // Move the temporary file into the upload directory. | |
| 70 | + $attachment_id = media_handle_sideload( $file ); | |
| 71 | + update_post_meta( $attachment_id, '_ablocks_demo_ref', $url ); | |
| 72 | + | |
| 73 | + // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.unlink_unlink | |
| 74 | + @unlink( $temp_file ); | |
| 75 | + | |
| 76 | + return $attachment_id; | |
| 77 | + } | |
| 78 | + | |
| 79 | + protected function previous_uploaded_file( string $url ) { | |
| 80 | + $attachment = get_posts( [ | |
| 81 | + 'post_type' => 'attachment', | |
| 82 | + 'meta_key' => '_ablocks_demo_ref', | |
| 83 | + 'meta_value' => $url, | |
| 84 | + 'posts_per_page' => 1, | |
| 85 | + ] ); | |
| 86 | + | |
| 87 | + if ( ! empty( $attachment ) ) { | |
| 88 | + return $attachment[0]->ID; | |
| 89 | + } | |
| 90 | + | |
| 91 | + return false; | |
| 92 | + } | |
| 93 | + | |
| 94 | + protected function check_external_url( string $url ): bool { | |
| 95 | + $link_url = wp_parse_url( $url ); | |
| 96 | + $home_url = wp_parse_url( home_url() ); | |
| 97 | + | |
| 98 | + return ( ! empty( $link_url['host'] ) && ( $link_url['host'] !== $home_url['host'] ) ); | |
| 99 | + } | |
| 100 | + | |
| 101 | + /** | |
| 102 | + * Parse single <img/> element from DOM. | |
| 103 | + * | |
| 104 | + * @param DOMDocument $dom DOM. | |
| 105 | + * @param int $index Index number. | |
| 106 | + * | |
| 107 | + * @return array|false | |
| 108 | + */ | |
| 109 | + protected function parse_img_tag( DOMDocument $dom, int $index ) { | |
| 110 | + $imgHtml = $dom->getElementsByTagName( 'img' )->item( $index ); | |
| 111 | + | |
| 112 | + if ( ! $imgHtml ) { | |
| 113 | + return false; | |
| 114 | + } | |
| 115 | + | |
| 116 | + $imgSRC = $imgHtml->attributes->getNamedItem( 'src' ); | |
| 117 | + // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- Calling a property from native class `DOMDocument`. | |
| 118 | + $imgURL = $imgSRC->nodeValue; | |
| 119 | + if ( ! $this->check_external_url( $imgURL ) ) { | |
| 120 | + return false; | |
| 121 | + } | |
| 122 | + | |
| 123 | + $attachment_id = $this->upload_file( $imgURL ); | |
| 124 | + if ( is_wp_error( $attachment_id ) ) { | |
| 125 | + return false; | |
| 126 | + } | |
| 127 | + | |
| 128 | + $attachment_url = wp_get_attachment_url( $attachment_id ); | |
| 129 | + | |
| 130 | + return array( $attachment_id, $attachment_url, $imgURL ); | |
| 131 | + } | |
| 132 | +} | |