PluginProbe
Themify Builder / trunk
Themify Builder vtrunk
7.8.1 7.8.0 7.7.9 7.7.8 7.7.7 7.7.6 7.7.5 7.7.4 7.7.3 7.7.2 trunk 7.6.0 7.6.1 7.6.2 7.6.3 7.6.4 7.6.5 7.6.6 7.6.7 7.6.8 7.6.9 7.7.0 7.7.1
themify-builder / themify / themify-import-functions.php

themify-import-functions.php in Themify Builder trunk, at themify/themify-import-functions.php

1,185 lines 54.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * importing/erasing contents of the theme
5 *
6 * @package Themify
7 */
8 defined('ABSPATH') || exit;
9
10 class Themify_Import_Helper {
11
12 const DEMO_KEY = 'tf_demo';
13
14 public static function init() {
15 add_action('wp_ajax_themify_import_terms', array(__CLASS__, 'import_ajax_terms'));
16 add_action('wp_ajax_themify_import_posts', array(__CLASS__, 'import_ajax_posts'));
17 add_action('wp_ajax_themify_import_theme_data', array(__CLASS__, 'import_ajax_theme_data'));
18 add_action('wp_ajax_themify_upload_image', array(__CLASS__, 'import_ajax_image'));
19 add_action('wp_ajax_themify_import_gallery', array(__CLASS__, 'import_ajax_post_gallery'));
20 add_action('wp_ajax_themify_erase_content', array(__CLASS__, 'erase_demo'));
21 }
22
23 public static function import_ajax_posts() {
24 check_ajax_referer('tf_nonce', 'nonce');
25 if (current_user_can('import')) {
26 if (isset($_POST['data'])) {
27 $posts = stripslashes_deep($_POST['data']);
28 } elseif (isset($_FILES['data'])) {
29 $posts = file_get_contents($_FILES['data']['tmp_name']);
30 }
31 if (!empty($posts)) {
32 self::set_time_limit();
33 self::raise_memory_limit();
34 $posts = json_decode($posts, true);
35 $skinId = !empty($_POST['id']) ? $_POST['id'] : 'default';
36 $ids = array();
37 foreach ($posts as $post) {
38 $id = self::import_post($post, $skinId);
39 if (is_numeric($id) && $post['post_type'] !== 'tbp_template') {
40 self::set_import_id($post['ID'], $id, 'post', $skinId);
41 }
42 $ids[$post['ID']] = $id;
43 }
44 if (!empty($ids)) {
45 wp_send_json_success($ids);
46 }
47 }
48 }
49 wp_send_json_error();
50 }
51
52 public static function import_ajax_terms() {
53 check_ajax_referer('tf_nonce', 'nonce');
54 if (current_user_can('import')) {
55 if (isset($_POST['data'])) {
56 $terms = stripslashes_deep($_POST['data']);
57 } elseif (isset($_FILES['data'])) {
58 $terms = file_get_contents($_FILES['data']['tmp_name']);
59 }
60 if (!empty($terms)) {
61 self::set_time_limit();
62 self::raise_memory_limit();
63 $terms = json_decode($terms, true);
64 $skinId = !empty($_POST['id']) ? $_POST['id'] : 'default';
65 $ids = array();
66 foreach ($terms as $term) {
67 $id = self::import_term($term);
68 if (is_numeric($id)) {
69 self::set_import_id($term['term_id'], $id, 'taxonomy', $skinId);
70 }
71 $ids[$term['term_id']] = $id;
72 }
73 if (!empty($ids)) {
74 wp_send_json_success($ids);
75 }
76 }
77 }
78 wp_send_json_error();
79 }
80
81 public static function import_ajax_theme_data() {
82 check_ajax_referer('tf_nonce', 'nonce');
83 if (current_user_can('manage_options')) {
84 if (isset($_POST['data'])) {
85 $settings = stripslashes_deep($_POST['data']);
86 } elseif (isset($_FILES['data'])) {
87 $settings = file_get_contents($_FILES['data']['tmp_name']);
88 }
89 if (!empty($settings)) {
90 self::set_time_limit();
91 self::raise_memory_limit();
92 $settings = json_decode($settings, true);
93 $skinId = !empty($_POST['id']) ? $_POST['id'] : 'default';
94 $id = self::import_settings($settings, $skinId);
95 if ($id !== false) {
96 wp_send_json_success($id);
97 }
98 }
99 }
100 wp_send_json_error();
101 }
102
103 public static function import_ajax_image() {
104 if (!empty($_POST['postData']) && current_user_can('import')) {
105 check_ajax_referer('tf_nonce', 'nonce');
106 $postData = json_decode(stripslashes_deep($_POST['postData']), true);
107 $response = array();
108 if (!empty($postData)) {
109 self::set_time_limit();
110 self::raise_memory_limit('image');
111 $skinId = !empty($_POST['save_id']) ? $_POST['save_id'] : '';
112 $webp = empty($_POST['stop_webp']) ? true : false;
113 foreach ($postData as $key => $arrPost) {
114 if (!empty($arrPost['thumb'])) {
115 $blob = !empty($_FILES[$key]) && $_FILES[$key] != '1' ? $_FILES[$key] : null;
116 $res = self::import_media($arrPost, $blob, $webp);
117 if ($skinId !== '' && is_array($res) && isset($res['id'])) {
118 self::set_import_id(null, $res['id'], 'attachment', $skinId);
119 }
120 $response[$arrPost['thumb']] = $res;
121 }
122 }
123 }
124
125
126 wp_send_json_success($response);
127 }
128 wp_send_json_error();
129 }
130
131 public static function import_ajax_post_gallery() {
132 check_ajax_referer('tf_nonce', 'nonce');
133 if (current_user_can('import')) {
134 if (isset($_POST['data'])) {
135 $data = stripslashes_deep($_POST['data']);
136 } elseif (isset($_FILES['data'])) {
137 $data = file_get_contents($_FILES['data']['tmp_name']);
138 }
139 if (!empty($data)) {
140 $data = json_decode($data, true);
141 if (!empty($data)) {
142 self::set_time_limit();
143 self::raise_memory_limit();
144 foreach ($data as $post_id => $gallery) {
145 self::import_post_gallery($post_id, $gallery);
146 }
147 wp_send_json_success();
148 }
149 }
150 }
151 wp_send_json_error();
152 }
153
154 protected static function set_time_limit(int $limit = 0) {
155 ignore_user_abort(true);
156 if (function_exists('set_time_limit') && false === strpos(ini_get('disable_functions'), 'set_time_limit') && !ini_get('safe_mode')) { // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.safe_modeDeprecatedRemoved
157 @set_time_limit($limit); // @codingStandardsIgnoreLine
158 }
159 }
160
161 protected static function raise_memory_limit(string $context = 'admin',string $size = '512MB') {
162 if (!defined('WP_MAX_MEMORY_LIMIT')) {
163 define('WP_MAX_MEMORY_LIMIT', $size);
164 }
165 return wp_raise_memory_limit($context);
166 }
167
168 public static function import_product_attribute($name, $slug) {
169 if (function_exists('wc_create_attribute') && !empty($name) && !empty($slug) && current_user_can('import')) {
170 wc_create_attribute(array(
171 'name' => $name,
172 'slug' => $slug,
173 ));
174 $slug = wc_attribute_taxonomy_name($slug);
175 register_taxonomy($slug, array('product'), array(
176 'labels' => array(
177 'name' => sprintf(_x('Product %s', 'Product Attribute', 'woocommerce'), $name),
178 'singular_name' => $name,
179 )
180 ));
181 }
182 }
183
184 protected static function get_term_id_by_slug($slug, $tax, $importId = 0) {
185 $term = get_term_by('slug', $slug, $tax);
186 if ($importId > 0 && (!$term || is_wp_error($term))) {
187 $term = get_term((int) $importId, $tax);
188 }
189 if (!empty($term) && !is_wp_error($term) && $term->taxonomy === $tax) {
190 return (int) $term->term_id;
191 }
192 return false;
193 }
194
195 /**
196 * Removes all content marked as demo
197 *
198 * @return void
199 */
200 public static function erase_demo() {
201 check_ajax_referer('tf_nonce', 'nonce');
202 if (!current_user_can('delete_pages')) {
203 wp_send_json_error(__('You are not allowed to delete pages on this site', 'themify'));
204 }
205 if (isset($_POST['data'])) {
206 $data = json_decode(stripslashes_deep($_POST['data']), true);
207 } elseif (isset($_FILES['data'])) {
208 $data = file_get_contents($_FILES['data']['tmp_name']);
209 } else {
210 $data = array();
211 }
212 self::set_time_limit();
213 self::raise_memory_limit();
214 $keepModified = !empty($data['keep_modify']) && $data['keep_modify'] !== '0';
215 $isWc = themify_is_woocommerce_active();
216 $wc_pages = array();
217 if ($isWc === true) {
218 foreach (array('myaccount', 'shop', 'cart', 'checkout', 'view_order', 'terms') as $wc_page) {
219 $page_id = wc_get_page_id($wc_page);
220 if ($page_id > 0) {
221 $wc_pages[$page_id] = $wc_page;
222 }
223 }
224 }
225 $terms = get_terms([
226 'number' => 0,
227 'meta_key' => '_' . static::DEMO_KEY,
228 'meta_value' => 1,
229 'no_found_rows' => true,
230 ]
231 );
232 if (!empty($terms)) {
233 foreach ($terms as $term) {
234 wp_delete_term($term->term_id, $term->taxonomy);
235 }
236 }
237
238 $posts = get_posts([
239 'post_type' => get_post_types(),
240 'post_status' => 'any',
241 'meta_key' => '_' . static::DEMO_KEY,
242 'meta_value' => 1,
243 'no_found_rows' => true,
244 'posts_per_page' => -1,
245 ]);
246 foreach ($posts as $post) {
247 $delete = $keepModified === true ? !(strtotime($post->post_modified) > strtotime($post->post_date)) : true;
248 if ($delete === true) {
249 if ($post->post_type === 'attachment') {
250 self::erase_image($post, $keepModified);
251 } elseif ($isWc === true && $post->post_type === 'product') {
252 self::erase_product($post->ID, $keepModified);
253 } else {
254 wp_delete_post($post->ID, true);
255 if (isset($wc_pages[$post->ID])) {
256 delete_option('woocommerce_' . $post->post_name . '_page_id');
257 }
258 }
259 }
260 }
261 $items = Themify_Storage::get(static::DEMO_KEY);
262 $isBreak = false;
263 if (!empty($items)) {
264 $items = json_decode($items, true);
265 $memory = (int) (wp_convert_hr_to_bytes(WP_MEMORY_LIMIT) * MB_IN_BYTES);
266 $limit = $memory > 128 ? 100 : ($memory < 64 ? 60 : 80);
267 $count = 0;
268 foreach ($items as $skin => $el) {
269 if (!empty($el['taxonomy'])) {
270 foreach ($el['taxonomy'] as $oldId => $newId) {
271 $term = get_term($newId);
272 $delete = true;
273 if (!empty($term) && !is_wp_error($term)) {
274 $success = current_user_can('delete_term', $newId) ? wp_delete_term($newId, $term->taxonomy) : false;
275 if ($success === true) {
276 ++$count;
277 } elseif ($success === false) {
278 $delete = false;
279 } elseif (is_wp_error($success) && $success === 0) {
280 unset($items[$skin]['taxonomy'][$oldId]);
281 }
282 }
283 if ($delete === true) {
284 unset($items[$skin]['taxonomy'][$oldId]);
285 if ($count >= $limit) {
286 $isBreak = true;
287 break;
288 }
289 }
290 }
291 }
292 if (!empty($el['post']) && $count < $limit) {
293 foreach ($el['post'] as $oldId => $newId) {
294 $post = get_post($newId);
295 $delete = true;
296 if (!empty($post)) {
297 $delete = $keepModified === true ? !(strtotime($post->post_modified) > strtotime($post->post_date)) : true;
298 if ($delete === true) {
299 $post_type = $post->post_type;
300 if (($post_type !== 'page' && current_user_can('delete_post', $newId)) || ($post_type === 'page' && current_user_can('delete_page', $newId))) {
301 if ($post_type === 'attachment') {
302 $el['attachment'][] = $newId;
303 } else {
304 if ($isWc === true && $post_type === 'product') {
305 $deletedItems = self::erase_product($post->ID, $keepModified);
306 $delete = false;
307 foreach ($deletedItems['posts'] as $product_id => $is_deleted) {
308 if ($is_deleted === true) {
309 ++$count;
310 $product_id = (int) $product_id;
311 unset($items[$skin]['post'][$product_id]);
312 }
313 }
314 if (!empty($deletedItems['attachment'])) {
315 foreach ($deletedItems['attachment'] as $image_id => $is_deleted) {
316 if ($is_deleted === true) {
317 ++$count;
318 if (isset($items[$skin]['attachment'])) {
319 $image_id = (int) $image_id;
320 unset($items[$skin]['attachment'][$image_id], $el['attachment'][$image_id]);
321 }
322 }
323 }
324 }
325 } else {
326 $success = wp_delete_post($post->ID, true);
327 $delete = !empty($success);
328 if ($delete === true) {
329 ++$count;
330 }
331 }
332 }
333 } else {
334 $delete = false;
335 }
336 }
337 }
338 if ($delete === true) {
339 unset($items[$skin]['post'][$oldId]);
340 if (!empty($post) && isset($wc_pages[$post->ID])) {
341 delete_option('woocommerce_' . str_replace('-', '', $post->post_name) . '_page_id');
342 }
343 }
344 if ($count >= $limit) {
345 $isBreak = true;
346 break;
347 }
348 }
349 }
350 if (!empty($el['attachment']) && $count < $limit) {
351 foreach ($el['attachment'] as $oldId => $newId) {
352 $post = get_post($newId);
353 $delete = true;
354 if (!empty($post) && $post->post_type === 'attachment') {
355 $delete = $keepModified === true ? !(strtotime($post->post_modified) > strtotime($post->post_date)) : true;
356 if ($delete === true) {
357 $delete = current_user_can('delete_post', $newId) ? self::erase_image($post, $keepModified) : false;
358 if ($delete === true) {
359 ++$count;
360 }
361 }
362 }
363 if ($delete === true) {
364 unset($items[$skin]['attachment'][$oldId]);
365 if ($count >= $limit) {
366 $isBreak = true;
367 break;
368 }
369 }
370 }
371 }
372
373 if (empty($items[$skin]['taxonomy'])) {
374 unset($items[$skin]['taxonomy']);
375 }
376 if (empty($items[$skin]['post'])) {
377 unset($items[$skin]['post']);
378 }
379 if (empty($items[$skin]['attachment'])) {
380 unset($items[$skin]['attachment']);
381 }
382 if (empty($items[$skin])) {
383 unset($items[$skin]);
384 }
385 if ($isBreak === true) {
386 break;
387 }
388 }
389 if (!empty($items)) {
390 Themify_Storage::set(static::DEMO_KEY, $items);
391 } else {
392 Themify_Storage::delete(static::DEMO_KEY);
393 }
394 }
395 if ($isBreak === true) {
396 $response = 'repeat';
397 } else {
398 $response = self::has_demo_content() ? 'hasdemo' : 0;
399 }
400 wp_send_json_success($response);
401 }
402
403 public static function erase_product($id, $keepModified = false) {
404 $product = themify_is_woocommerce_active() ? wc_get_product($id) : null;
405 $res = array('posts' => array());
406 if (!empty($product)) {
407 $isVariable = $product->is_type('variable');
408 $isGroup = $product->is_type('grouped');
409 if ($isVariable || $isGroup) {
410 foreach ($product->get_children() as $child_id) {
411 $child = wc_get_product($child_id);
412 $delete = true;
413 if (!empty($child)) {
414 if ($isVariable) {
415 $delete = $child->delete(true);
416 } else {
417 $child->set_parent_id(0);
418 $delete = $child->save();
419 $delete = $delete > 0 ? true : false;
420 }
421 }
422 $res['posts'][$child_id] = $delete;
423 }
424 }
425 $image_galleries_id = $product->get_gallery_image_ids();
426
427 if (!empty($image_galleries_id)) {
428 $res['attachment'] = array();
429 foreach ($image_galleries_id as $image_id) {
430 $post = get_post($image_id);
431 $delete = true;
432 if (!empty($post) && $post->post_type === 'attachment') {
433 $delete = $keepModified === true ? !(strtotime($post->post_modified) > strtotime($post->post_date)) : true;
434 if ($delete === true) {
435 $delete = self::erase_image($image_id, $keepModified);
436 }
437 }
438 $res['attachment'][$image_id] = $delete;
439 }
440 }
441 $res['posts'][$id] = $product->delete(true);
442 // Delete parent product transients.
443 if ($parent_id = wp_get_post_parent_id($id)) {
444 wc_delete_product_transients($parent_id);
445 }
446 } else {
447 $res['posts'][$id] = wp_delete_post($id, true);
448 }
449 return $res;
450 }
451
452 public static function erase_image($post, $force = false) {
453 $post = get_post($post);
454 if (!empty($post) && $post->post_type === 'attachment') {
455 $delete = $force === true || $post->post_parent === 0 || get_post_status($post->post_parent) === false;
456 if ($delete === true) {
457 if ($force === true) {
458 global $wpdb;
459 $file_name = wp_basename(wp_get_attachment_url($post->ID));
460 $path = pathinfo($file_name);
461 $file_name = esc_sql($path['basename']);
462 $size_name = esc_sql($path['filename']) . '-';
463 $sql = "'%$file_name%' OR '%$size_name%'";
464 unset($path, $file_name, $size_name);
465 $exist = $wpdb->query("SELECT 1 FROM $wpdb->postmeta WHERE `meta_value` LIKE $sql LIMIT 1");
466 if (!empty($exist)) {
467 return false;
468 }
469 $exist = $wpdb->query("SELECT 1 FROM $wpdb->posts WHERE `post_content` LIKE $sql LIMIT 1");
470 if (!empty($exist)) {
471 return false;
472 }
473 $exist = $wpdb->query("SELECT 1 FROM $wpdb->termmeta WHERE `meta_value` LIKE $sql LIMIT 1");
474 if (!empty($exist)) {
475 return false;
476 }
477 }
478 return wp_delete_attachment($post->ID, true);
479 }
480 }
481 return true;
482 }
483
484 /**
485 * Returns true only if there are any demo contents installed on this site
486 *
487 * @return bool
488 */
489 public static function has_demo_content() {
490 $content = Themify_Storage::get(static::DEMO_KEY);
491 if (!empty($content)) {
492 return true;
493 }
494 $terms = get_terms([
495 'number' => 1,
496 'meta_key' => '_' . static::DEMO_KEY,
497 'meta_value' => 1,
498 'no_found_rows' => true,]
499 );
500 if (!empty($terms)) {
501 return true;
502 }
503
504 $posts = get_posts([
505 'post_type' => get_post_types(),
506 'post_status' => 'any',
507 'meta_key' => '_' . static::DEMO_KEY,
508 'meta_value' => 1,
509 'no_found_rows' => true,
510 'posts_per_page' => 1,
511 ]);
512 if (!empty($posts)) {
513 return true;
514 }
515 return false;
516 }
517
518 protected static function set_import_id($oldId, $newId, $type, $skinId = 'default') {
519 $newId = (int) $newId;
520 if ($newId > 0) {
521 $items = Themify_Storage::get(static::DEMO_KEY);
522 $items = empty($items) ? array() : json_decode($items, true);
523 if (empty($items[$skinId])) {
524 $items[$skinId] = array();
525 }
526 if (empty($items[$skinId][$type])) {
527 $items[$skinId][$type] = array();
528 }
529 if (!$oldId) {
530 $items[$skinId][$type][] = $newId;
531 } else {
532 $items[$skinId][$type][$oldId] = $newId;
533 }
534 return Themify_Storage::set(static::DEMO_KEY, $items);
535 }
536 return false;
537 }
538
539 protected static function get_import_id($old_id, $skinId = 'default', $import_type = null) {
540 global $wpdb;
541 $type = 'post';
542 $key = 'post_id';
543 $table = $wpdb->postmeta;
544 if ($import_type === 'taxonomy') {
545 $type = 'taxonomy';
546 $key = 'term_id';
547 $table = $wpdb->termmeta;
548 }
549 $items = Themify_Storage::get(static::DEMO_KEY);
550 $items = empty($items) ? array() : json_decode($items, true);
551 if (isset($items[$skinId])) {
552 $items = $items[$skinId];
553 }
554 if (!empty($items) && !empty($items[$type][$old_id])) {
555 return $items[$type][$old_id];
556 }
557
558 //backward
559 $result = $wpdb->get_row($wpdb->prepare(
560 "SELECT {$key} FROM {$table} WHERE meta_key = '_" . static::DEMO_KEY . "_id' AND meta_value = %d LIMIT 1",
561 $old_id
562 ), ARRAY_A);
563
564 if (isset($result[$key])) {
565 if (self::set_import_id($old_id, $result[$key], $type, $skinId)) {
566 if ($type === 'taxonomy') {
567 delete_term_meta($result[$key], '_' . static::DEMO_KEY . '_id');
568 } else {
569 delete_post_meta($result[$key], '_' . static::DEMO_KEY . '_id');
570 }
571 }
572 return $result[$key];
573 }
574
575 return false;
576 }
577
578 public static function import_term(array $term, $skinId = 'default', $update = false) {
579 if (!empty($term)) {
580 if (taxonomy_exists($term['taxonomy'])) {
581 if ($term['taxonomy'] === 'nav_menu') {
582 return self::import_menu($term, $update);
583 }
584 $term_id = term_exists($term['slug'], $term['taxonomy']);
585 if (empty($term['parent']) || empty($term['parent_slug'])) {
586 $parent = 0;
587 } else {
588 $parentTerm = self::get_term_id_by_slug($term['parent_slug'], $term['taxonomy'], self::get_import_id($term['parent'], $skinId, 'taxonomy'));
589 $parent = $parentTerm !== false ? $parentTerm : 0;
590 unset($parentTerm);
591 }
592 if (empty($term_id)) {
593
594 $term_id = wp_insert_term($term['name'], $term['taxonomy'], array(
595 'parent' => $parent,
596 'slug' => $term['slug'],
597 'description' => isset($term['description']) ? $term['description'] : ''
598 ));
599 } elseif ($update === true) {
600 $term_id = wp_update_term($term_id, $term['taxonomy'], array(
601 'name' => $term['name'],
602 'slug' => $term['slug'],
603 'parent' => $parent,
604 'description' => isset($term['description']) ? $term['description'] : ''
605 ));
606 }
607 if ($term_id && !is_wp_error($term_id)) {
608 if (is_array($term_id)) {
609 $term_id = $term_id['term_id'];
610 }
611 return self::get_import_id($term_id, $skinId, 'taxonomy') ? true : (int) $term_id;
612 } else {
613 return false;
614 }
615 } else {
616 return array('msg' => sprintf(__("Taxonomy %s dosen't exist", 'themify'), $term['taxonomy']), 'skip' => $term['taxonomy']);
617 }
618 }
619 return false;
620 }
621
622 public static function import_post(array $post, $skinId = 'default', $update = false) {
623 if (!empty($post)) {
624
625 if (post_type_exists($post['post_type'])) {
626 $post['post_author'] = get_current_user_id();
627 $post['post_status'] = 'publish';
628 if (!isset($post['post_parent'])) {
629 $post['post_parent'] = 0;
630 }
631 if (!isset($post['menu_order'])) {
632 $post['menu_order'] = 0;
633 }
634 if (!isset($post['post_content'])) {
635 $post['post_content'] = '';
636 }
637 if (!isset($post['post_excerpt'])) {
638 $post['post_excerpt'] = '';
639 }
640 if (isset($post['post_date'])) {
641 $post['post_modified'] = $post['post_date'];
642 }
643 if ($post['post_type'] === 'nav_menu_item') {
644 return self::import_menu_item($post, $skinId, $update);
645 }
646 $old_id = $post['ID'];
647 $isWcPage = false;
648 unset($post['ID']);
649 /* Menu items don't have reliable post_title, skip the post_exists check */
650 /* With tbp_template, different Themes can have duplicate templates so skip post_exists */
651 if ($post['post_type'] !== 'tbp_template') {
652 $isWcPage = !empty($post['is_wc_page']) && themify_is_woocommerce_active();
653 $post_id = isset($post['post_date'], $post['post_title']) ? post_exists($post['post_title'], '', $post['post_date'], $post['post_type']) : 0;
654 if ($isWcPage === true && !$post_id && isset($post['post_name'])) {
655 $post_id = wc_get_page_id(str_replace('-', '', $post['post_name'])); //wc doesn't check if a post exist
656 }
657 if (!$post_id) {
658 $post_id = self::get_import_id($old_id, $skinId);
659 }
660 if (!$post_id || $post_id <= 0 || get_post_type($post_id) !== $post['post_type']) {
661 $post_id = 0;
662 }
663 if ($post_id > 0) {
664 if ($update === true) {
665 $post['ID'] = $post_id;
666 } else {
667 return $post_id;
668 }
669 }
670
671 if ($post['post_parent'] > 0) {
672 $parent_id = self::get_import_id($post['post_parent'], $skinId);
673 $post['post_parent'] = empty( $parent_id ) ? 0 : $parent_id;
674 }
675
676 /**
677 * for hierarchical taxonomies, IDs must be used so wp_set_post_terms can function properly
678 * convert term slugs to IDs for hierarchical taxonomies
679 */
680 if (!empty($post['tax_input'])) {
681 foreach ($post['tax_input'] as $tax => $terms) {
682 if (!taxonomy_exists($tax)) {
683 unset($post['tax_input'][$tax]);
684 } elseif (is_taxonomy_hierarchical($tax)) {
685 $post['tax_input'][$tax] = array();
686 $terms = explode(', ', $terms);
687 foreach ($terms as $t) {
688 $tid = self::get_term_id_by_slug($t, $tax);
689 if ($tid !== false) {
690 $post['tax_input'][$tax][] = $tid;
691 }
692 }
693 if (empty($post['tax_input'][$tax])) {
694 unset($post['tax_input'][$tax]);
695 }
696 }
697 }
698 }
699 }
700 $builderKey = ThemifyBuilder_Data_Manager::META_KEY;
701 if (!empty($post['meta_input'][$builderKey])) {
702 $builder = $post['meta_input'][$builderKey];
703 }
704 $isHome = !empty($post['is_home']);
705 $productGallery = !empty($post['_product_image_gallery']) ? $post['_product_image_gallery'] : null;
706 unset($post['meta_input'][$builderKey], $post['is_home'], $post['is_wc_page'], $post['_product_image_gallery']);
707 $post_id = wp_insert_post($post, true);
708
709 if (!$post_id || is_wp_error($post_id)) {
710 return false;
711 }
712 $post_id = (int) $post_id;
713 if (!empty($builder)) {
714 $res = ThemifyBuilder_Data_Manager::update_builder_meta($post_id, $builder, false);
715 if (!empty($res['mid'])) {
716 Themify_Global_Styles::save_used_global_styles($res['builder_data'], $post_id);
717 }
718 unset($builder, $res);
719 }
720 if (isset($post['post_date'])) {
721 global $wpdb;
722 $wpdb->update($wpdb->posts, array('post_modified' => $post['post_date'], 'post_modified_gmt' => get_gmt_from_date($post['post_date'])), array('id' => $post_id));
723 }
724 // Home page
725 if ($isHome === true) {
726 update_option('show_on_front', 'page');
727 update_option('page_on_front', $post_id);
728 }
729 if ($isWcPage === true) {
730 $post_name = str_replace('-', '', $post['post_name']);
731 $wc_page = wc_get_page_id($post_name);
732 if ($wc_page <= 0 || get_post_type($wc_page) !== $post['post_type']) {
733 update_option('woocommerce_' . $post_name . '_page_id', $post_id, true);
734 }
735 }
736 if ($productGallery !== null) {
737 self::import_post_gallery($post_id, $productGallery);
738 }
739 return $post_id;
740 } else {
741 return array('msg' => sprintf(__("Post Type %s dosen't exist", 'themify'), $post['post_type']), 'skip' => $post['post_type']);
742 }
743 }
744 }
745
746 public static function import_menu_item(array $post, $skinId = 'default', $update = false) {
747 if ($post['post_type'] === 'nav_menu_item' && isset($post['tax_input']['nav_menu'])) {
748 $oldId = (!empty($post['post_title']) && !empty($post['post_date'])) ? post_exists($post['post_title'], '', $post['post_date'], $post['post_type']) : false;
749 if (!$oldId) {
750 $oldId = self::get_import_id($post['ID'], $skinId);
751 }
752 if (!$oldId || get_post_type($oldId) !== $post['post_type']) {
753 $oldId = 0;
754 } elseif ($update === false) {
755 return true;
756 }
757 $m = wp_get_nav_menu_object($post['tax_input']['nav_menu']);
758 if (empty($m) || is_wp_error($m)) {
759 return array('msg' => sprintf(__("Menu %s dosen't exist", 'themify'), $post['tax_input']['nav_menu']));
760 }
761 $menuId = $m->term_id;
762 if (empty($post['meta_input']) || empty($post['meta_input']['_menu_item_type']) || empty($post['meta_input']['_menu_item_object'])) {
763 return false;
764 }
765 $meta = $post['meta_input'];
766 $menuType = $meta['_menu_item_type'];
767 $args = array(
768 'menu-item-title' => isset($post['post_title']) ? $post['post_title'] : '',
769 'menu-item-position' => isset($post['menu_order']) ? $post['menu_order'] : 0,
770 'menu-item-classes' => isset($meta['_menu_item_classes']) ? (is_array($meta['_menu_item_classes']) ? implode(' ', $meta['_menu_item_classes']) : $meta['_menu_item_classes']) : '',
771 'menu-item-xfn' => isset($meta['_menu_item_xfn']) ? (is_array($meta['_menu_item_xfn']) ? implode(' ', $meta['_menu_item_xfn']) : $meta['_menu_item_xfn']) : '',
772 'menu-item-type' => $menuType,
773 'menu-item-object' => $meta['_menu_item_object'],
774 'menu-item-target' => isset($meta['_menu_item_target']) ? $meta['_menu_item_target'] : '',
775 'menu-item-description' => isset($post['post_content']) ? $post['post_content'] : '',
776 'menu-item-post-date' => isset($post['post_date']) ? $post['post_date'] : '',
777 'menu-item-post-date-gmt' => isset($post['post_date_gmt']) ? $post['post_date_gmt'] : '',
778 'menu-item-status' => isset($post['post_status']) ? $post['post_status'] : 'publish',
779 'menu-item-object-id' => 0
780 );
781 unset($m);
782 if ($args['menu-item-post-date-gmt'] === '') {
783 $args['menu-item-post-date-gmt'] = $args['menu-item-post-date'];
784 }
785 if ($menuType !== 'custom') {
786 $objectType = $meta['_menu_item_object'];
787 if (($menuType === 'post_type_archive' || $menuType === 'post_type') && !post_type_exists($objectType)) {
788 return array('msg' => sprintf(__("Post Type %s dosen't exist", 'themify'), $objectType));
789 } elseif ($menuType === 'taxonomy' && !taxonomy_exists($objectType)) {
790 return array('msg' => sprintf(__("Taxonomy %s dosen't exist", 'themify'), $objectType));
791 }
792 if ($menuType !== 'post_type_archive') {
793 $menu_item_id = $meta['_menu_item_object_id'];
794 $newId = null;
795 if (!is_numeric($menu_item_id) && function_exists('wc_get_page_id')) {
796 $newId = wc_get_page_id($menu_item_id); //wc doesn't check if a post exist
797 if ($newId <= 0 || get_post_type($newId) !== $objectType) {
798 $newId = null;
799 }
800 } else {
801 if (is_numeric($menu_item_id)) {
802 $menu_item_id = (int) $menu_item_id;
803 $newId = self::get_import_id($menu_item_id, $skinId, $menuType);
804 }
805 if ($menuType === 'post_type') {
806 if (isset($meta['slug']) && (!$newId || get_post_type($newId) !== $objectType)) {
807 $newId = null;
808 if ($objectType === 'page') {
809 $newId = get_page_by_path($meta['slug']);
810 } else {
811 $tmp = array(
812 'name' => $meta['slug'],
813 'post_type' => $objectType,
814 'post_status' => 'any',
815 'no_found_rows' => true,
816 'posts_per_page' => 1
817 );
818 $newId = get_posts($tmp);
819 if (!empty($newId)) {
820 $newId = $newId[0];
821 }
822 unset($tmp);
823 }
824 }
825 $newId = !empty($newId) ? (is_numeric($newId) ? $newId : $newId->ID) : null;
826 } elseif ($menuType === 'taxonomy' && isset($meta['slug']) && (!$newId || !term_exists($newId, $objectType))) {
827 $newId = self::get_term_id_by_slug($meta['slug'], $objectType, $newId);
828 }
829 }
830 if (empty($newId)) {
831 return false;
832 }
833 $args['menu-item-object-id'] = $newId;
834 }
835 } else {
836 $args['menu-item-url'] = isset($meta['_menu_item_url']) ? $meta['_menu_item_url'] : '';
837 }
838 $parent = isset($meta['_menu_item_menu_item_parent']) ? (int) $meta['_menu_item_menu_item_parent'] : 0;
839 if ($parent > 0) {
840 $parent = self::get_import_id($parent, $skinId);
841 if (!$parent || get_post_type($parent) !== $post['post_type']) {
842 $parent = 0;
843 }
844 }
845 unset($post);
846 $args['menu-item-parent-id'] = $parent;
847 $post_id = wp_update_nav_menu_item($menuId, $oldId, $args);
848 if (!$post_id || is_wp_error($post_id)) {
849 return false;
850 }
851 unset($args,
852 $parent,
853 $meta['slug'],
854 $meta['is_home'],
855 $meta['_menu_item_object'],
856 $meta['_menu_item_object_id'],
857 $meta['_menu_item_url'],
858 $meta['_menu_item_menu_item_parent'],
859 $meta['_menu_item_xfn'],
860 $meta['_menu_item_classes'],
861 $meta['_menu_item_target'],
862 $meta['_menu_item_type']);
863 if (!empty($meta)) {
864 foreach ($meta as $k => $v) {
865 if ($v !== '' && $v !== null) {
866 update_post_meta($post_id, $k, sanitize_key($v));
867 }
868 }
869 }
870 return $post_id;
871 }
872 return false;
873 }
874
875 public static function import_menu(array $menu, $update = false) {
876 $m = wp_get_nav_menu_object($menu['slug']);
877 if (empty($m) || is_wp_error($m)) {
878 $m = wp_get_nav_menu_object(sanitize_title($menu['name']));
879 }
880 $m = empty($m) || is_wp_error($m) ? 0 : $m->term_id;
881 if ($m === 0 || $update === true) {
882 $m = wp_update_nav_menu_object($m, array(
883 'menu-name' => $menu['name'],
884 'parent' => isset($menu['parent']) ? $menu['parent'] : 0,
885 'description' => isset($menu['description']) ? $menu['description'] : ''
886 ));
887 }
888 return $m && !is_wp_error($m) ? $m : false;
889 }
890
891 public static function import_settings(array $settings, $skinId = 'default', $update = false) {
892 if (!empty($settings)) {
893 if (!empty($settings['theme_mods'])) {
894 $theme = get_option('stylesheet');
895 update_option('theme_mods_' . $theme, $settings['theme_mods']);
896 unset($theme);
897 }
898 if (!empty($settings['menu'])) {
899 foreach ($settings['menu'] as $menu) {
900 $m = self::import_menu($menu, $update);
901 if ($m !== false) {
902 self::set_import_id($menu['term_id'], $m, 'taxonomy', $skinId);
903 }
904 }
905 }
906 if (!empty($settings['menu_locations'])) {
907 $locations = $settings['menu_locations'];
908 $themeLocations = get_theme_mod('nav_menu_locations');
909 if(empty($themeLocations)){
910 $themeLocations=[];
911 }
912 foreach ($locations as $location => $menu) {
913 $m = self::import_menu($menu, $update);
914 if ($m !== false) {
915 $themeLocations[$location] = $m;
916 self::set_import_id($menu['term_id'], $m, 'taxonomy', $skinId);
917 }
918 }
919 set_theme_mod('nav_menu_locations', $themeLocations);
920 unset($themeLocations, $locations);
921 }
922 if (!empty($settings['product_filter']) && method_exists('WPF', 'get_instance') && method_exists('WPF_Options', 'get_option')) {
923 $instance = WPF::get_instance();
924 if (method_exists($instance, 'get_plugin_name') && method_exists($instance, 'get_version')) {
925 $instance = WPF_Options::get_option($instance->get_plugin_name(), $instance->get_version());
926 if (method_exists($instance, 'get') && method_exists($instance, 'set')) {
927 $instance->set(array_merge($settings['product_filter'], $instance->get()));
928 }
929 }
930 }
931 if (!empty($settings['product_attribute'])) {
932 foreach ($settings['product_attribute'] as $slug => $label) {
933 self::import_product_attribute($label, $slug);
934 }
935 }
936 if (!empty($settings['homepage'])) {
937 $homepage = get_page_by_path($settings['homepage']);
938 if (!empty($homepage) && !is_wp_error($homepage)) {
939 update_option('show_on_front', 'page');
940 update_option('page_on_front', $homepage->ID);
941 }
942 unset($homepage);
943 }
944 if (!empty($settings['widgets'])) {
945 $importWidgets = $settings['widgets'];
946 $sidebars_widgets = array();
947 $index = 1001;
948 foreach ($importWidgets as $wid => $widgets) {
949 $sidebars_widgets[$wid] = array();
950 foreach ($widgets as $widget) {
951 if (is_array($widget['options']) && isset($widget['options']['nav_menu'])) {
952 $menuId = self::get_term_id_by_slug($widget['options']['nav_menu'], 'nav_menu');
953 if ($menuId !== false) {
954 $widget['options']['nav_menu'] = $menuId;
955 } else {
956 continue;
957 }
958 }
959 ++$index;
960 $id = 'widget_' . $widget['id'];
961 $themeWidget = get_option($id);
962 if (empty($themeWidget)) {
963 $themeWidget = array();
964 }
965 $themeWidget[$index] = $widget['options'];
966 update_option($id, $themeWidget);
967 $sidebars_widgets[$wid][] = $widget['id'] . '-' . $index;
968 }
969 }
970 update_option('sidebars_widgets', $sidebars_widgets);
971 unset($sidebars_widgets, $importWidgets);
972 }
973 if (!empty($settings['themify_settings'])) {
974 $skinSettings = array_merge(themify_get_data(), $settings['themify_settings']);
975 themify_set_data($skinSettings);
976 }
977 if (!empty($settings['style_variables']) && is_array($settings['style_variables']) && class_exists('TF_SV_Framework', false)) {
978 TF_SV_Framework::import_missing_vars($settings['style_variables']);
979 }
980 return true;
981 }
982 return false;
983 }
984
985 public static function import_post_gallery($post_id, $gallery) {
986 if (!empty($gallery)) {
987 if (is_array($gallery)) {
988 $gallery = implode(',', $gallery);
989 }
990 return update_post_meta($post_id, '_product_image_gallery', $gallery);
991 }
992 return false;
993 }
994
995 public static function compare_files($f1, $f2, $size = 4096) {
996 $fh1 = fopen($f1, 'rb');
997 $fh2 = fopen($f2, 'rb');
998 if ($fh1 !== false && $fh2 !== false) {
999 try {
1000 while (!feof($fh1) && !feof($fh2)) {
1001 yield fread($fh1, $size) => fread($fh2, $size);
1002 }
1003 } finally {
1004 fclose($fh1);
1005 fclose($fh2);
1006 }
1007 } else {
1008 yield false;
1009 }
1010 }
1011
1012 public static function import_media(array $post, $blob = null, $generate = true) {
1013 if (!empty($post['thumb'])) {
1014 if (!current_user_can('upload_files')) {
1015 $error = __('You aren`t allowed to upload file', 'themify');
1016 } else {
1017 global $wpdb;
1018 $error = '';
1019 $thumb = sanitize_text_field($post['thumb']);
1020 $file_name = sanitize_file_name(wp_basename($thumb));
1021 $type = wp_check_filetype( $file_name )['type'];
1022 $sql = sprintf('`post_name` IN("%1$s","%1$s-1","%1$s-2","%1$s-3")',sanitize_title(pathinfo($file_name,PATHINFO_FILENAME)));
1023 $query = $wpdb->get_row("SELECT ID,post_mime_type FROM {$wpdb->prefix}posts WHERE `post_type`='attachment' AND {$sql} AND `post_mime_type`='{$type}' LIMIT 1");
1024
1025 $isImage = 0 === strpos( $type, 'image/' );
1026 $isVideo=$isImage===false && 0 === strpos( $type, 'video/' );
1027 $attach_id = !empty($query) ? $query->ID : null;
1028 if ($attach_id !== null) {
1029 $duplicate = $isImage===true?wp_get_original_image_path($attach_id):get_attached_file( $attach_id );
1030 if(!$duplicate && $isImage===true){
1031 $duplicate=get_attached_file( $attach_id );
1032 }
1033 if ($duplicate && is_file($duplicate)) {
1034 $size = (int) filesize($duplicate);
1035 $mimeType = $query->post_mime_type;
1036 }
1037 }
1038 unset($query, $sql,$type);
1039 require_once ABSPATH . 'wp-admin/includes/image.php';
1040 require_once ABSPATH . 'wp-admin/includes/file.php';
1041 require_once ABSPATH . 'wp-admin/includes/media.php';
1042 if (!empty($blob)) {
1043 if ($blob['error'] > 0) {
1044 $error = __('Uploading error', 'themify');
1045 } else {
1046 $file = array(
1047 'type' => $blob['type'],
1048 'tmp_name' => $blob['tmp_name'],
1049 'error' => 0,
1050 'size' => $blob['size']
1051 );
1052 }
1053 } else {
1054 $tmp = download_url($thumb.'?polish=0');
1055 if (is_wp_error($tmp)) {
1056 $error = $tmp->get_error_message();
1057 } else {
1058 $file = array(
1059 'size' => filesize($tmp),
1060 'error' => 0,
1061 'tmp_name' => $tmp
1062 );
1063 }
1064 }
1065 if ($error === '') {
1066 $checked = wp_check_filetype_and_ext($file['tmp_name'], $file_name);
1067 if (!empty($checked['type'])) {
1068 $file['name'] = !empty($checked['proper_filename']) ? $checked['proper_filename'] : $file_name;
1069 $isFileExist = isset($size) && $mimeType === $checked['type'] && abs($size - (int)$file['size']) < 15;
1070 if ($isFileExist === true) {
1071 $mbSize = (float) $size / MB_IN_BYTES;
1072 if ($mbSize < 4) {//is below 4mb
1073 $isFileExist = sha1_file($duplicate) === sha1_file($file['tmp_name']);
1074 } else {
1075 $chunkSize = 4096;
1076 $maxCheck = 4 * MB_IN_BYTES; //check only the first 4mb
1077 $i = (int) $maxCheck / $chunkSize;
1078 $arr = self::compare_files($duplicate, $file['tmp_name'], $chunkSize);
1079 foreach ($arr as $k => $v) {
1080 if ($k === false || $v === false || $v !== $k) {
1081 $isFileExist = false;
1082 break;
1083 }
1084 if ($i <= 0) {
1085 break;
1086 }
1087 --$i;
1088 }
1089 unset($maxCheck, $chunkSize, $i,$arr);
1090 }
1091 unset($duplicate, $mbSize);
1092 }
1093 unset($checked);
1094
1095 $post_id = !empty($post['post_id']) ? (int) $post['post_id'] : 0;
1096 $term_id = (!$post_id && !empty($post['term_id'])) ? (int) $post['term_id'] : 0;
1097 if ($isFileExist === false) {
1098 $check = function_exists('check_upload_size') ? check_upload_size($file) : array('error' => 0);
1099 if ($check['error'] === 0) {
1100 $attach_id = media_handle_sideload($file, $post_id);
1101 if (!$attach_id) {
1102 $error = __('Uploading Error', 'themify');
1103 } elseif (is_wp_error($attach_id)) {
1104 $error = $attach_id->get_error_messages();
1105 }
1106 } else {
1107 $error = $check['error'];
1108 }
1109 unset($check);
1110 }
1111 } else {
1112 $error = __('Invalid file type', 'themify');
1113 }
1114 }
1115 if (isset($file)) {
1116 if (is_file($file['tmp_name'])) {
1117 unlink($file['tmp_name']);
1118 }
1119 unset($file, $thumb,$tmp);
1120 }
1121 if ($error === '' && !empty($attach_id)) {
1122 $attach_id=(int)$attach_id;
1123 if($isImage===true){
1124 if ($post_id > 0) {
1125 set_post_thumbnail($post_id, $attach_id);
1126 } elseif ($term_id > 0) {
1127 update_term_meta($term_id, 'thumbnail_id', $attach_id);
1128 }
1129 unset($post_id, $term_id);
1130 $imageMeta = wp_get_attachment_metadata($attach_id);
1131 if ( empty($imageMeta['file'])) {
1132 $data = wp_get_attachment_image_src($attach_id, 'full');
1133 $src = $data[0];
1134 $w = $h = '';
1135 if (empty($data[1])) {
1136 $size = themify_get_image_size($src);
1137 if ($size !== false) {
1138 $w = $size['w'];
1139 $h = $size['h'];
1140 }
1141 } else {
1142 $w = $data[1];
1143 $h = $data[2];
1144 }
1145 $imageSizes['_orig_'] = array('file' => $src, $w, 'height' => $h);
1146 unset($data);
1147 } else {
1148 $imageSizes = !empty($imageMeta['sizes']) ? $imageMeta['sizes'] : array();
1149 $imageSizes['_orig_'] = array('file' => basename($imageMeta['file']), 'width' => $imageMeta['width'], 'height' => $imageMeta['height']);
1150 $folder = '/' . dirname($imageMeta['file']) . '/';
1151 $baseUrl = themify_upload_dir('baseurl') . $folder;
1152 unset($imageMeta);
1153 if ($generate === true) {
1154 foreach ($imageSizes as $v) {
1155 themify_get_image_size($baseUrl . $v['file']);
1156 themify_create_webp($baseUrl . $v['file']);
1157 }
1158 }
1159 $src = $baseUrl . $imageSizes['_orig_']['file'];
1160 }
1161 $img = '<img src="' . $src . '" class="wp-image-' . $attach_id . '"';
1162 if (!empty($imageSizes['_orig_']['width'])) {
1163 $img .= ' width="' . $imageSizes['_orig_']['width'] . '" height="' . $imageSizes['_orig_']['height'] . '"';
1164 }
1165 $img .= '>';
1166 unset($imageSizes);
1167 $img = function_exists('wp_filter_content_tags') ? wp_filter_content_tags($img) : wp_make_content_images_responsive($img);
1168 }else{
1169 $img='';
1170 $src=wp_get_attachment_url($attach_id);
1171 if($isVideo===true){
1172 themify_get_video_size($src);
1173 }
1174 }
1175 return array('html' => $img, 'id' => $attach_id, 'src' => $src);
1176 }
1177 }
1178 return $error;
1179 }
1180 }
1181 }
1182
1183 if (themify_is_ajax()) {
1184 Themify_Import_Helper::init();
1185 }