PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.4.0
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.4.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 3.1.10 All 111 releases
templately / includes / Core / Importer / Runners / Attachments.php

Attachments.php in Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! 3.4.0, at includes/Core/Importer/Runners/Attachments.php

330 lines 9.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Templately\Core\Importer\Runners;
4
5 use Templately\Core\Importer\WPImport;
6
7 class Attachments extends WPContent {
8
9 private $data = [];
10
11 public function __construct($request_params) {
12 parent::__construct($request_params);
13 $this->attachments_init();
14 }
15
16 public function get_name(): string {
17 return 'attachments';
18 }
19
20 public function get_label(): string {
21 return __('Attachments', 'templately');
22 }
23
24 public function should_log(): bool {
25 return true;
26 }
27
28 public function get_action(): string {
29 return 'updateLog';
30 }
31
32 public function log_message(): string {
33 if ($this->total > 0) {
34 return __('Importing Attachments: (' . $this->get_processed() . '/' . $this->total . ')', 'templately');
35 }
36 return __('Importing Attachment.', 'templately');
37 }
38
39 public function should_run($data, $imported_data = []): bool {
40 return !empty($this->manifest['has_attachments']);
41 }
42
43 public function import($data, $imported_data): array {
44 $path = $this->dir_path;
45 $taxonomies = [];
46 $terms = [];
47 $results = [];
48 $this->data = $data;
49
50 $this->clear_old_el_cache();
51
52 $this->import_actions();
53
54 $import = $this->_import_type_data('attachments', $path, $imported_data, $taxonomies, $terms);
55 $results['attachments'] = $import['summary']['posts'];
56 $results['attachments_errors'] = $import['errors'];
57
58 $this->import_actions(true);
59
60 return $results;
61 }
62
63 /**
64 * Clear old elementor cache
65 * so that our second image hash for original_attachment_url don't
66 * pick up attachment from previous import
67 */
68 public function clear_old_el_cache() {
69 global $wpdb;
70
71 $has_processed = $this->get_progress(false, 'attachments-cleared-old-el-cache', false);
72 if($has_processed){
73 return;
74 }
75
76 // Step 1: Retrieve all meta values where the meta_key is '_templately_image_hash_meta_id'
77 $meta_ids = $wpdb->get_col(
78 $wpdb->prepare(
79 "SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_key = %s",
80 '_templately_image_hash_meta_id'
81 )
82 );
83
84 // Step 2: Delete the corresponding meta entries using the retrieved meta_ids
85 if (!empty($meta_ids)) {
86 $placeholders = implode(',', array_fill(0, count($meta_ids), '%d'));
87 $wpdb->query(
88 $wpdb->prepare(
89 "DELETE FROM {$wpdb->postmeta} WHERE meta_id IN ($placeholders)",
90 ...$meta_ids
91 )
92 );
93
94 if (defined('TEMPLATELY_DEBUG_LOG') && TEMPLATELY_DEBUG_LOG) {
95 error_log('Deleted _elementor_source_image_hash entries with meta_ids: ' . implode(', ', $meta_ids));
96 }
97 }
98
99 // Step 3: Delete all '_templately_image_hash_meta_id' entries
100 $wpdb->delete(
101 $wpdb->postmeta,
102 array('meta_key' => '_templately_image_hash_meta_id'),
103 array('%s')
104 );
105
106 // Check for errors
107 if (defined('TEMPLATELY_DEBUG_LOG') && TEMPLATELY_DEBUG_LOG) {
108 if($wpdb->last_error){
109 error_log('MySQL Error during image hash cleanup: ' . $wpdb->last_error);
110 }
111 }
112 }
113
114 protected function import_actions($remove = false) {
115 parent::import_actions($remove);
116
117 if ($remove) {
118 remove_filter('templately_import_copy_attachment', [$this, 'copy_attachment_file'], 10);
119 remove_filter('wp_import_post_data_raw', [$this, 'ai_image_replacement_url'], 10);
120 remove_filter('wp_import_post_meta', [$this, 'ai_image_replacement_metadata'], 10);
121 } else {
122 add_filter('templately_import_copy_attachment', [$this, 'copy_attachment_file'], 10, 4);
123 add_filter('wp_import_post_data_raw', [$this, 'ai_image_replacement_url'], 10, 2);
124 add_filter('wp_import_post_meta', [$this, 'ai_image_replacement_metadata'], 10, 3);
125 }
126 }
127
128 public function copy_attachment_file($return, $att_id, $dest_file, $upload_dir) {
129 // @todo check mapping url to new id
130
131 if (!empty($att_id)) {
132 // skip ai image replacement from local file
133 if ($this->is_ai_image($att_id)) {
134 return $return;
135 }
136
137 $file_name = basename($dest_file);
138 $path = $this->dir_path . 'attachments' . DIRECTORY_SEPARATOR;
139 $wp_filetype = wp_check_filetype($file_name);
140 $ext = $wp_filetype['ext'];
141
142 $source_path = "{$path}{$att_id}.{$ext}";
143
144 if (!file_exists($source_path)) {
145 return $return;
146 }
147
148 $move_new_file = copy($source_path, $dest_file);
149
150 if (!$move_new_file) {
151 return $return;
152 }
153
154 $wp_filetype = wp_check_filetype_and_ext($source_path, $file_name);
155
156 // Set correct file permissions.
157 $stat = stat(dirname($dest_file));
158 $perms = $stat['mode'] & 0000666;
159 chmod($dest_file, $perms);
160
161 return [
162 'file' => $dest_file,
163 'url' => $upload_dir['url'] . "/$file_name",
164 'type' => $wp_filetype['type'],
165 'error' => false,
166 ];
167 }
168
169
170 return $return;
171 }
172
173 public function is_ai_image($post_id) {
174 if (!empty($post_id) && !empty($this->data["image_mappings"][$post_id])) {
175 return true;
176 }
177 return false;
178 }
179
180 /**
181 * @param $post
182 * @param WPImport $wp_importer
183 * @return array
184 */
185 public function ai_image_replacement_url($post, $wp_importer) {
186 $post_id = $post['post_id'] ?? null;
187 if ($this->is_ai_image($post_id) && !empty($post['post_type']) && $post['post_type'] === 'attachment') {
188 $image_data = $this->data["image_mappings"][$post_id];
189
190 if (!empty($image_data["newData"]["original"])) {
191 $source = $image_data["source"];
192 if($source === 'upload'){
193 $new_id = $image_data["newData"]["id"];
194 $original_url = $image_data["originalUrl"];
195 $new_url = $image_data["newUrl"];
196
197 $wp_importer->update_post_meta( $new_id );
198
199 // Map pre-import ID to local ID.
200 $wp_importer->processed_posts[ (int) $post_id ] = (int) $new_id;
201
202 $wp_importer->set_url_map($original_url, $new_url);
203 $wp_importer->set_url_map($original_url, $new_url, true);
204
205 return $new_id;
206 }
207 else if($source ==='stock' && $image_data['newData']['provider'] == 'pexels'){
208 $post['original_attachment_url'] = $post['attachment_url'];
209 $post['guid'] = $image_data["newData"]["original"];
210 $post['attachment_url'] = $image_data["newData"]["original"];
211 }
212 else if($source === 'ai'){
213 // @todo: coming soon
214 }
215 }
216 }
217 return $post;
218 }
219
220 public function ai_image_replacement_metadata($postmeta, $post_id, $post) {
221
222 if ($this->is_ai_image($post_id)) {
223 $image_data = $this->data["image_mappings"][$post_id]["newData"] ?? [];
224 // alt. provider, photographer
225 if (!empty($image_data["alt"])) {
226 $postmeta[] = [
227 'key' => '_wp_attachment_image_alt',
228 'value' => $image_data["alt"],
229 ];
230 }
231 if (!empty($image_data["provider"])) {
232 $postmeta[] = [
233 'key' => '_templately_ai_image_provider',
234 'value' => $image_data["provider"],
235 ];
236 }
237 if (!empty($image_data["photographer"])) {
238 $postmeta[] = [
239 'key' => '_templately_ai_image_photographer',
240 'value' => $image_data["photographer"],
241 ];
242 }
243 }
244
245 return $postmeta;
246 }
247
248 public function get_processed() {
249 $processed = $this->processed ?? [];
250 $succeed = $processed['succeed'] ?? [];
251 $failed = $processed['failed'] ?? [];
252
253 return count($succeed) + count($failed);
254 }
255
256 public function post_log($post, $result) {
257 if (isset($post['post_type'])) {
258 if ($post['post_type'] !== 'attachment') {
259 return;
260 }
261
262 // need to assign to processed so log_message() can use get_processed() to calculate progress
263 // also bellow code used it to calculate progress
264 $this->processed = $result;
265
266 $type = $post['post_type'];
267 $title = $post['post_title'];
268 }
269
270 if (empty($type) || empty($title)) {
271 return;
272 }
273
274 $progress = $this->total > 0 ? ceil((100 * ($this->get_processed())) / $this->total) : 100;
275
276 $this->log($progress);
277 }
278
279 public function attachments_init() {
280 add_filter('pre_http_request', [$this, 'pre_http_request'], 10, 3);
281 add_filter('http_response', [$this, 'http_response'], 10, 3);
282 // attachment insert hooks
283 add_filter('wp_insert_attachment_data', [$this, 'before_insert_attachment'], 10, 2);
284 add_action('add_attachment', [$this, 'after_insert_attachment'], 10, 1);
285 add_filter('wp_update_attachment_metadata', [$this, 'wp_update_attachment_metadata'], 99999, 2);
286 }
287
288 public function pre_http_request($preempt, $parsed_args, $url) {
289 // error_log(print_r([$preempt, $parsed_args, $url], true));
290
291 $this->sse_log('attachments', 'Before downloading attachment: ' . $url, 1, 'eventLog');
292
293 return $preempt;
294 }
295
296 public function http_response($response, $parsed_args, $url) {
297 // error_log(print_r([$response, $parsed_args, $url], true));
298 $this->sse_log('attachments', 'After downloading attachment: ' . $url, 1, 'eventLog');
299 return $response;
300 }
301
302 /**
303 * Log before inserting attachment.
304 */
305 public function before_insert_attachment($data, $postarr) {
306 $this->sse_log('attachments', 'Before inserting attachment: ' . ($data['post_title'] ?? ''), 1, 'eventLog');
307 return $data;
308 }
309
310 /**
311 * Log after attachment is inserted.
312 */
313 public function after_insert_attachment($post_ID) {
314 $post = get_post($post_ID);
315 $this->sse_log('attachments', 'After inserting attachment: ' . ($post->post_title ?? ''), 1, 'eventLog');
316 }
317
318 public function wp_update_attachment_metadata($metadata, $attachment_id) {
319 $this->sse_log('attachments', 'Updated attachment metadata: ' . $attachment_id, 1, 'eventLog');
320 // $this->sse_message([
321 // "action" => "eventLog",
322 // "type" => "attachments",
323 // "progress" => 1,
324 // "message" => "Updated attachment metadata => " . $attachment_id,
325 // "backtrace" => debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 30),
326 // ]);
327 return $metadata;
328 }
329 }
330