PluginProbe
Extendify / 3.1.4
Extendify v3.1.4
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / app / Shared / Services / Import / ImageUploader.php

ImageUploader.php in Extendify 3.1.4, at app/Shared/Services/Import/ImageUploader.php

242 lines 7.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Image uploader class
5 */
6
7 namespace Extendify\Shared\Services\Import;
8
9 defined('ABSPATH') || die('No direct access.');
10
11 /**
12 * This class responsible for uploading the image.
13 */
14
15 class ImageUploader
16 {
17 /**
18 * The mime types we support !!
19 *
20 * @var string[]
21 */
22 protected $mimes = [
23 'image/gif' => '.gif',
24 'image/jpeg' => '.jpg',
25 'image/png' => '.png',
26 'image/x-png' => '.png',
27 'image/jp2' => '.jp2',
28 'image/jpx' => '.jp2',
29 'image/webp' => '.wbmp',
30 'image/avif' => '.avif',
31 ];
32
33 /**
34 * The images domains we use
35 *
36 * @var string[] the domain names.
37 */
38 public static $imagesDomains = [
39 'unsplash.com',
40 'extendify.com',
41 ];
42
43 /**
44 * Upload the image and return the attachment information
45 * If the attachment is already there, then return the
46 * attachment information only.
47 *
48 * @param string $image the image url to upload.
49 * @param string|null $author the WordPress post author.
50 * @return array|\WP_Error
51 */
52 public function uploadImage($image, $author = null) // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
53 {
54 require_once ABSPATH . 'wp-admin/includes/image.php';
55
56 $image = preg_replace('/(\?.*?)\?/', '$1&', $image);
57 $image = str_replace('%2C', ',', $image);
58 // If the attachment has been already uploaded, just return it.
59 $attachment = $this->getAttachmentIfExists($image);
60
61 if ($attachment instanceof \WP_Post) {
62 return [
63 'attachment_id' => $attachment->ID,
64 'url' => $attachment->guid,
65 ];
66 }
67
68 $imageHeadersInformation = wp_remote_retrieve_headers(wp_safe_remote_head($image));
69
70 if (!empty($imageHeadersInformation)) {
71 $headers = $imageHeadersInformation->getAll();
72 $fileMimeType = $headers['content-type'];
73 } else {
74 $fileMimeType = wp_get_image_mime($image);
75 }
76
77 if (!array_key_exists($fileMimeType, $this->mimes)) {
78 return new \WP_Error(2002, 'File type is not allowed.');
79 }
80
81 if (!preg_match('(' . implode('|', array_map('preg_quote', self::$imagesDomains)) . ')i', $image)) {
82 $imageUrl = esc_url_raw($image);
83 } else {
84 $parsedUrl = wp_parse_url($image);
85 parse_str($parsedUrl['query'], $params);
86
87 if (!isset($params['w'])) {
88 $params['w'] = 1280;
89 }
90
91 if (isset($params['orientation'])) {
92 if ($params['orientation'] === 'portrait') {
93 $params['h'] = 1440;
94 unset($params['w']);
95 } elseif (in_array($params['orientation'], ['landscape', 'square'], true) && isset($params['w'])) {
96 $params['w'] = 1440;
97 }
98
99 unset($params['orientation']);
100 }
101
102 $params['auto'] = 'auto,compress';
103 $params['q'] = 70;
104
105 $imageUrl = $parsedUrl['scheme'] . '://'
106 . $parsedUrl['host']
107 . $parsedUrl['path']
108 . '?'
109 . http_build_query($params);
110 }//end if
111
112 $imageSha = sha1($image);
113 $upload = $this->handleImageUpload($imageUrl, $imageSha, $fileMimeType);
114 if (is_wp_error($upload)) {
115 return $upload;
116 }
117
118 $attachmentId = $this->createAttachment($upload, $image, $author);
119 if (is_wp_error($attachmentId)) {
120 return $attachmentId;
121 }
122
123 $upload['attachment_id'] = $attachmentId;
124 return $upload;
125 }
126
127 /**
128 * Handle the image upload process.
129 *
130 * @param string $imageUrl The image URL.
131 * @param string $imageSha The image SHA.
132 * @param string $fileMimeType The file mime type.
133 * @return array|\WP_Error
134 */
135 protected function handleImageUpload($imageUrl, $imageSha, $fileMimeType)
136 {
137 $upload = $this->upload($imageUrl, $imageSha, $fileMimeType);
138
139 if ($upload['error']) {
140 return new \WP_Error(2003, $upload['error']);
141 }
142
143 if (!wp_getimagesize($upload['file'])) {
144 // phpcs:ignore WordPress.PHP.NoSilencedErrors, Generic.PHP.NoSilencedErrors.Discouraged
145 @unlink($upload['file']);
146 $imageUrl = str_replace('avif', 'jpg', $imageUrl);
147 $upload = $this->upload($imageUrl, $imageSha, 'image/jpeg');
148 }
149
150 // phpcs:ignore WordPress.PHP.NoSilencedErrors, Generic.PHP.NoSilencedErrors.Discouraged
151 if (!@filesize($upload['file']) || !wp_getimagesize($upload['file'])) {
152 // phpcs:ignore WordPress.PHP.NoSilencedErrors, Generic.PHP.NoSilencedErrors.Discouraged
153 @unlink($upload['file']);
154 return new \WP_Error(2001, 'File is not a valid image.');
155 }
156
157 return $upload;
158 }
159
160 /**
161 * Create the attachment in WordPress.
162 *
163 * @param array $upload The upload information.
164 * @param string $image The original image URL.
165 * @param string|null $author The post author.
166 * @return int|\WP_Error
167 */
168 protected function createAttachment($upload, $image, $author)
169 {
170 $attachment = [
171 'guid' => $upload['url'],
172 'post_mime_type' => $upload['type'],
173 'post_title' => sha1($image),
174 'post_content' => '',
175 'post_status' => 'inherit',
176 'post_author' => $author,
177 ];
178
179 $attachmentId = wp_insert_attachment($attachment, $upload['file']);
180
181 if (is_wp_error($attachmentId) || !$attachmentId) {
182 return new \WP_Error(2004, 'There was an error while adding the attachment record in the database.');
183 }
184
185 $metadata = wp_generate_attachment_metadata($attachmentId, $upload['file']);
186 if (!empty($metadata)) {
187 wp_update_attachment_metadata($attachmentId, $metadata);
188 }
189
190 update_post_meta($attachmentId, '_extendify_source_url', $image);
191
192 return $attachmentId;
193 }
194
195 /**
196 * Upload the image and return the uploaded file information.
197 *
198 * @param string $imageUrl The image url to upload.
199 * @param string $imageSha The image sha.
200 * @param string $fileMimeType The file mime type.
201 * @return array {
202 * Information about the newly-uploaded file.
203 *
204 * @type string $file Filename of the newly-uploaded file.
205 * @type string $url URL of the uploaded file.
206 * @type string $type File type.
207 * @type string|false $error Error message, if there has been an error.
208 * }
209 */
210 protected function upload($imageUrl, $imageSha, $fileMimeType)
211 {
212 $response = wp_remote_get($imageUrl);
213 $body = trim(wp_remote_retrieve_body($response));
214 return wp_upload_bits($imageSha . $this->mimes[$fileMimeType], null, $body);
215 }
216
217 /**
218 * Check if the image has been already uploaded or not, if yes
219 * then return the attachment information.
220 *
221 * @param string $image the image url we need to check for.
222 * @return array|\WP_Post|null
223 */
224 protected function getAttachmentIfExists($image)
225 {
226 $postId = attachment_url_to_postid($image);
227 if ($postId) {
228 return get_post($postId);
229 }
230
231 $attachment = get_posts([
232 'post_type' => 'attachment',
233 'numberposts' => 1,
234 's' => sha1($image),
235 'post_status' => 'inherit',
236 'post_mime_type' => implode(',', array_keys($this->mimes)),
237 ]);
238
239 return $attachment ? $attachment[0] : [];
240 }
241 }
242