PluginProbe ʕ •ᴥ•ʔ
Kirki – Freeform Page Builder, Website Builder & Customizer / 6.2.3
Kirki – Freeform Page Builder, Website Builder & Customizer v6.2.3
6.2.3 6.2.2 6.2.1 6.2.0 6.1.1 6.1.0 6.0.14 6.0.13 6.0.12 6.0.11 6.0.10 6.0.9 6.0.8 6.0.7 6.0.6 6.0.5 6.0.4 6.0.3 6.0.2 6.0.1 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 4.0.19 4.0.20 4.0.21 4.0.22 4.0.23 4.0.24 4.1 4.2.0 5.0.0 5.1.0 5.1.1 5.2.0 5.2.1 5.2.2 5.2.3 6.0.0 trunk 3.0.40 3.0.41 3.0.42 3.0.43 3.0.44 3.0.45 3.1.0 3.1.1 3.1.2
kirki / includes / ExportImport / TemplateImport.php
kirki / includes / ExportImport Last commit date
TemplateExport.php 4 weeks ago TemplateImport.php 5 days ago
TemplateImport.php
1545 lines
1 <?php
2 /**
3 * FormValidator class
4 *
5 * This class is responsible for validating form data
6 *
7 * @package kirki
8 */
9
10 namespace Kirki\ExportImport;
11
12 use Kirki\Ajax\Media;
13 use Kirki\Ajax\UserData;
14 use Kirki\API\ContentManager\ContentManagerHelper;
15 use Kirki\HelperFunctions;
16
17 if ( ! defined( 'ABSPATH' ) ) {
18 exit; // Exit if accessed directly.
19 }
20
21 // TODO: need to check lottie element
22
23 class TemplateImport {
24
25 private $zip_file_path = null;
26 private $batch_id = null;
27 private $staging = false;
28 private $prefix = null;
29 private $variable_id_tracker = array(); // this value is need to change the variable for every page or symbol
30 private $post_id_tracker = array();
31 private $delete_zip_after_import = true;
32 private $kirki_data_link_tracker = array();
33 private $kirki_cm_ref_field_post_tracker = array();
34
35
36 private $asset_upload_tracker = array(); // [ 'old_attachment_id':{'new_attachment_id': , 'url': 'new_url', old_url:'old_url'}]
37 // private $new_asset_urls = [];
38 private $asset_upload_batch_size = 5;
39 private $content_manager_batch_size = 300; // Batch size for content manager
40
41 public function __construct() {
42
43 }
44
45 private function count( $array ) {
46 if ( isset( $array ) && is_array( $array ) ) {
47 return count( $array );
48 }
49 return 0;
50 }
51
52 public function import( $zip_file_path, $delete_zip_after_import = true, $selectedMode = 'default' ) {
53 $this->delete_zip_after_import = $delete_zip_after_import;
54
55 $temp_folder_path = HelperFunctions::get_temp_folder_path();
56 HelperFunctions::delete_directory( $temp_folder_path );
57 $this->save_environment_data( false );
58
59 if ( HelperFunctions::is_remote_url( $zip_file_path ) ) {
60 $file_name_new = uniqid( '', true ) . '.zip'; // 'random.ext'
61 $zip_file_path = HelperFunctions::download_zip_from_remote( $zip_file_path, $file_name_new );
62 if ( $zip_file_path ) {
63 $this->zip_file_path = $zip_file_path;
64 } else {
65 wp_send_json_error( 'Failed to download zip file' );
66 }
67 } else {
68 $this->zip_file_path = $zip_file_path;
69 }
70
71 $zip = new \ZipArchive();
72 $res = $zip->open( $this->zip_file_path );
73
74 if ( $res === true ) {
75
76 $filtered_zip_path = HelperFunctions::filterZipFile( $zip, $this->zip_file_path );
77 if ( ! $filtered_zip_path ) {
78 return false;
79 }
80 $zip->close();
81
82 // Reopen the filtered ZIP file for extraction
83 $res = $zip->open( $filtered_zip_path );
84 if ( $res === true ) {
85 $temp_folder_path = HelperFunctions::get_temp_folder_path();
86
87 $zip->extractTo( $temp_folder_path );
88 $zip->close();
89
90 if ( $this->delete_zip_after_import ) {
91 wp_delete_file( $this->zip_file_path );
92 }
93
94 $json_data = array();
95
96 // site-settings.json
97 $site_settings_file = $temp_folder_path . '/site-settings.json';
98 $site_settings_json = file_get_contents( $site_settings_file );
99 $site_settings_data = json_decode( $site_settings_json, true );
100
101 $json_data['exportId'] = $site_settings_data['exportId'];
102 $json_data['variable_prefix'] = $site_settings_data['variable_prefix'];
103 $json_data['batch_id'] = $site_settings_data['batch_id'];
104 $json_data['staging'] = isset( $site_settings_data['staging'] ) ? $site_settings_data['staging'] : false;
105 $json_data['siteInfo'] = $site_settings_data['siteInfo'];
106 $json_data['prefix'] = isset( $site_settings_data['prefix'] ) ? $site_settings_data['prefix'] : '';
107
108 // assets.json
109 $assets_file = $temp_folder_path . '/assets.json';
110 if ( file_exists( $assets_file ) ) {
111 $assets_json = file_get_contents( $assets_file );
112 $assets_data = json_decode( $assets_json, true );
113 $json_data['assetUrls'] = isset( $assets_data['assetUrls'] ) ? $assets_data['assetUrls'] : array();
114 } else {
115 $json_data['assetUrls'] = array();
116 }
117
118 // pages.json
119 $pages_file = $temp_folder_path . '/pages.json';
120 $pages_json = file_get_contents( $pages_file );
121 $pages_data = json_decode( $pages_json, true );
122
123 $json_data['pages'] = $pages_data['pages'];
124 $json_data['templates'] = $pages_data['templates'];
125 $json_data['utility_pages'] = $pages_data['utility_pages'];
126
127 // popups.json
128 $popups_file = $temp_folder_path . '/popups.json';
129 $popups_json = file_get_contents( $popups_file );
130 $popups_data = json_decode( $popups_json, true );
131 $json_data['popups'] = $popups_data['popups'];
132
133 // content-manager.json
134 $content_manager_file = $temp_folder_path . '/content-manager.json';
135 $content_manager_json = file_get_contents( $content_manager_file );
136 $content_manager_data = json_decode( $content_manager_json, true );
137 $json_data['contentManager'] = $content_manager_data['contentManager'];
138
139 // content-manager-ref-fields.json
140 $content_manager_ref_fields_file = $temp_folder_path . '/content-manager-ref-fields.json';
141 $content_manager_ref_fields_json = file_get_contents( $content_manager_ref_fields_file );
142 $content_manager_ref_fields_data = json_decode( $content_manager_ref_fields_json, true );
143 $json_data['contentManagerRefFields'] = $content_manager_ref_fields_data['contentManagerRefFields'];
144
145 // symbols.json
146 $symbols_file = $temp_folder_path . '/symbols.json';
147 $symbols_json = file_get_contents( $symbols_file );
148 $symbols_data = json_decode( $symbols_json, true );
149 $json_data['symbols'] = $symbols_data['symbols'];
150
151 // styles.json
152 $styles_file = $temp_folder_path . '/styles.json';
153 $styles_json = file_get_contents( $styles_file );
154 $styles_data = json_decode( $styles_json, true );
155 $json_data['viewPorts'] = $styles_data['viewPorts'];
156 $json_data['customFonts'] = $styles_data['customFonts'];
157 $json_data['globalStyleBlocks'] = $styles_data['globalStyleBlocks'];
158 $json_data['variables'] = $styles_data['variables'];
159 $json_data['variables']['defaultMode'] = $selectedMode;
160
161 if ( empty( $json_data ) || ! isset( $json_data['pages'], $json_data['assetUrls'], $json_data['variables'], $json_data['customFonts'], $json_data['viewPorts'], $json_data['contentManager'], $json_data['templates'] ) ) {
162 wp_send_json_error( 'Failed to import template, Upload Kirki Exported Zip file' );
163 }
164
165 $environment = array(
166 'temp_folder_path' => $temp_folder_path,
167 'json_data' => $json_data,
168 'variable_id_tracker' => $this->variable_id_tracker,
169 'post_id_tracker' => $this->post_id_tracker,
170 'asset_upload_tracker' => $this->asset_upload_tracker,
171 'kirki_data_link_tracker' => $this->kirki_data_link_tracker,
172 'kirki_cm_ref_field_post_tracker' => $this->kirki_cm_ref_field_post_tracker,
173 );
174
175 $template_info = array(
176 'symbols' => $this->count( $json_data['symbols'] ),
177 'popups' => $this->count( $json_data['popups'] ),
178 'pages' => $this->count( $json_data['pages'] ),
179 'templates' => $this->count( $json_data['templates'] ),
180 'utilityPages' => $this->count( $json_data['utility_pages'] ),
181 'variables' => $this->count( $json_data['variables']['data'] ),
182 'images' => $this->count( $json_data['assetUrls'] ),
183 'fonts' => $this->count( $json_data['customFonts'] ),
184 'contentManager' => $this->count( $json_data['contentManager'] ),
185 'contentManagerRefFields' => $this->count( $json_data['contentManagerRefFields'] ),
186 'overwrite_pages' => array_map( fn( $page) => $page['post_title'], $json_data['pages'] ),
187 'contentManager_list' => array_map( fn( $item) => $item['post_title'] . ' (' . count( $item['children'] ) . ')', $json_data['contentManager'] ),
188 );
189
190 $environment['queue'] = array();
191
192 if ( $template_info['images'] > 0 ) {
193 $environment['queue'][] = 'assetUrls';
194 }
195 if ( $template_info['variables'] > 0 ) {
196 $environment['queue'][] = 'variables';
197 }
198 $environment['queue'][] = 'viewPorts_customFonts_globalStyleBlocks';
199 if ( $template_info['contentManager'] > 0 ) {
200 $environment['queue'][] = 'contentManager';
201 }
202
203 if ( $template_info['contentManagerRefFields'] > 0 ) {
204 $environment['queue'][] = 'contentManagerRefFields';
205 }
206
207 if ( $template_info['symbols'] > 0 ) {
208 $environment['queue'][] = 'symbols';
209 }
210 if ( $template_info['popups'] > 0 ) {
211 $environment['queue'][] = 'popups';
212 }
213 if ( $template_info['pages'] > 0 ) {
214 $environment['queue'][] = 'pages';
215 }
216 if ( $template_info['templates'] > 0 ) {
217 $environment['queue'][] = 'templates';
218 }
219 if ( $template_info['utilityPages'] > 0 ) {
220 $environment['queue'][] = 'utility_pages';
221 }
222 $environment['queue'][] = 'siteInfo';
223
224 $batch_id = $json_data['batch_id'];
225 $args = array(
226 'post_type' => array( 'page','kirki_template','kirki_utility' ),
227 'post_status' => array( 'draft', 'publish', 'future' ),
228 'meta_key' => 'kirki_imported_batch_id',
229 'meta_value' => $batch_id,
230 'posts_per_page' => -1, // Fetch all matching posts
231 );
232
233 $posts = get_posts( $args );
234
235 $response = array(
236 'status' => true,
237 'queue' => $environment['queue'],
238 'template_info' => $template_info,
239 );
240
241 if ( ! empty( $posts ) ) {
242 $response['is_template_exits'] = true;
243 $environment['is_template_exits'] = true;
244 }
245
246 $this->save_environment_data( $environment );
247
248 // Cleanup temporary filtered ZIP
249 wp_delete_file( $filtered_zip_path );
250
251 return $response;
252 }
253 }
254 return false;
255 }
256
257 public function check_existing_template_data( $data ) {
258 $all_pages = array_merge( $data['pages'], $data['templates'], $data['utility_pages'] );
259
260 // Initialize arrays for existing items
261 $existing_pages = array();
262 $existing_templates = array();
263 $existing_utility_pages = array();
264
265 // Fetch all pages, templates, and utility pages from the database
266 $total_pages = get_posts(
267 array(
268 'post_type' => array( 'page','kirki_template','kirki_utility' ),
269 'posts_per_page' => -1,
270 'fields' => 'ids', // Fetch only IDs for performance
271 )
272 );
273
274 // Create a lookup array with post_name
275 $existing_pages_data = array();
276 foreach ( $total_pages as $id ) {
277 $post_name = get_post_field( 'post_name', $id );
278 $post_title = get_post_field( 'post_title', $id );
279 $post_type = get_post_field( 'post_type', $id );
280
281 $existing_pages_data[ $post_name ] = array(
282 'post_title' => $post_title,
283 'post_type' => $post_type,
284 );
285 }
286
287 // Check for existing pages, templates, and utility pages
288 foreach ( $all_pages as $page ) {
289 $post_name = $page['post_name'];
290
291 if ( isset( $existing_pages_data[ $post_name ] ) ) {
292 $post_title = $existing_pages_data[ $post_name ]['post_title'];
293 $post_type = $existing_pages_data[ $post_name ]['post_type'];
294
295 $matched_data = array(
296 'post_title' => $post_title,
297 'post_name' => $post_name,
298 );
299
300 if ( $post_type === 'page' ) {
301 $existing_pages[] = $matched_data;
302 } elseif ( $post_type ==='kirki_template' ) {
303 $existing_templates[] = $matched_data;
304 } elseif ( $post_type ==='kirki_utility' ) {
305 $existing_utility_pages[] = $matched_data;
306 }
307 }
308 }
309
310 // Return categorized existing data with post_title and post_name
311 $result = array_merge( $existing_pages, $existing_templates, $existing_utility_pages );
312 wp_send_json(
313 array(
314 'success' => true,
315 'data' => $result,
316 )
317 );
318 }
319
320 private function save_environment_data( $environment ) {
321 if ( ! empty( $environment ) && $environment !== false ) {
322 $all_kirki_pages = $environment['json_data']['pages'];
323 $all_templates_pages = $environment['json_data']['templates'];
324 $all_utility_pages = $environment['json_data']['utility_pages'];
325
326 // remove all pages, templates, and utility pages from the environment data
327 unset( $environment['json_data']['pages'] );
328 unset( $environment['json_data']['templates'] );
329 unset( $environment['json_data']['utility_pages'] );
330
331 HelperFunctions::update_global_data_using_key( 'kirki_project_import', $environment );
332
333 HelperFunctions::update_global_data_using_key( 'kirki_project_import_pages', $all_kirki_pages );
334 HelperFunctions::update_global_data_using_key( 'kirki_project_import_templates', $all_templates_pages );
335 HelperFunctions::update_global_data_using_key( 'kirki_project_import_utility', $all_utility_pages );
336 } else {
337 HelperFunctions::update_global_data_using_key( 'kirki_project_import', false );
338 HelperFunctions::update_global_data_using_key( 'kirki_project_import_pages', false );
339 HelperFunctions::update_global_data_using_key( 'kirki_project_import_templates', false );
340 HelperFunctions::update_global_data_using_key( 'kirki_project_import_utility', false );
341 }
342 }
343
344 private function get_environment_data() {
345 $environment = HelperFunctions::get_global_data_using_key( 'kirki_project_import' );
346 $all_kirki_pages = HelperFunctions::get_global_data_using_key( 'kirki_project_import_pages' );
347 $all_templates_pages = HelperFunctions::get_global_data_using_key( 'kirki_project_import_templates' );
348 $all_utility_pages = HelperFunctions::get_global_data_using_key( 'kirki_project_import_utility' );
349
350 if ( ! empty( $environment ) && $environment !== false ) {
351 $environment['json_data']['pages'] = $all_kirki_pages;
352 $environment['json_data']['templates'] = $all_templates_pages;
353 $environment['json_data']['utility_pages'] = $all_utility_pages;
354 }
355
356 return $environment;
357 }
358
359
360 public function process() {
361 $environment = $this->get_environment_data();
362 if ( ! $environment ) {
363 return array(
364 'status' => false,
365 'message' => 'Nothing found to import',
366 );
367 }
368 $queue = $environment['queue'];
369 $temp_folder_path = $environment['temp_folder_path'];
370 $is_template_exits = isset( $environment['is_template_exits'] ) ? $environment['is_template_exits'] : false;
371 $json_data = $environment['json_data'];
372 $this->batch_id = $json_data['batch_id'];
373 $this->staging = $json_data['staging'];
374 $this->prefix = isset( $json_data['prefix'] ) ? $json_data['prefix'] : '';
375
376 if ( $is_template_exits ) {
377 // delete all posts
378 $args = array(
379 'post_type' => array( 'page','kirki_template','kirki_utility','kirki_cm','kirki_symbol' ),
380 'post_status' => array( 'draft', 'publish', 'future' ),
381 'meta_key' => 'kirki_imported_batch_id',
382 'meta_value' => $this->batch_id,
383 'posts_per_page' => -1, // Fetch all matching posts
384 );
385
386 $posts = get_posts( $args );
387
388 if ( ! empty( $posts ) ) {
389 foreach ( $posts as $post ) {
390 wp_delete_post( $post->ID, true );
391 }
392 }
393
394 // delete all other variables, content manager, etc.
395 $args = array(
396 'post_type' => 'any',
397 'meta_key' => 'kirki_imported_batch_id',
398 'post_status' => array( 'draft', 'publish', 'future' ),
399 'meta_value' => $this->batch_id,
400 'posts_per_page' => -1, // Fetch all matching posts
401 );
402
403 $posts = get_posts( $args );
404
405 // delete all other
406 if ( ! empty( $posts ) ) {
407 foreach ( $posts as $post ) {
408 wp_delete_post( $post->ID, true );
409 }
410 }
411
412 // delete all attachment
413 $args = array(
414 'post_type' => array( 'attachment' ),
415 'post_status' => array( 'inherit', 'publish' ),
416 'meta_key' => 'kirki_imported_batch_id',
417 'meta_value' => $this->batch_id,
418 'posts_per_page' => -1, // Fetch all matching posts
419 );
420
421 $posts = get_posts( $args );
422 if ( ! empty( $posts ) ) {
423 foreach ( $posts as $post ) {
424 wp_delete_post( $post->ID, true );
425 }
426 }
427
428 $environment['is_template_exits'] = false;
429 // save updated environment metadata
430 $this->save_environment_data( $environment );
431 }
432
433 if ( count( $queue ) > 0 ) {
434 $this->variable_id_tracker = $environment['variable_id_tracker'];
435 $this->post_id_tracker = $environment['post_id_tracker'];
436 $this->asset_upload_tracker = $environment['asset_upload_tracker'];
437 $this->kirki_data_link_tracker = $environment['kirki_data_link_tracker'];
438 $this->kirki_cm_ref_field_post_tracker = $environment['kirki_cm_ref_field_post_tracker'];
439
440 $current_task = array_shift( $queue );
441
442 switch ( $current_task ) {
443 case 'assetUrls':{
444 $this_batch_assets = array();
445 $left_assets = array();
446 $count = 0;
447 if ( count( $json_data['assetUrls'] ) > $this->asset_upload_batch_size ) {
448 foreach ( $json_data['assetUrls'] as $key => $a ) {
449 if ( $count < $this->asset_upload_batch_size ) {
450 $this_batch_assets[ $key ] = $a;
451 } else {
452 $left_assets[ $key ] = $a;
453 }
454 $count++;
455 }
456
457 array_unshift( $queue, $current_task );
458 } else {
459 $this_batch_assets = $json_data['assetUrls'];
460 }
461 $this->import_assets( $this_batch_assets );
462 $json_data['assetUrls'] = $left_assets;
463 break;
464 }
465 // viewPorts
466 case 'viewPorts_customFonts_globalStyleBlocks':{
467 $this->import_view_ports( $json_data['viewPorts'] );
468 $this->import_custom_fonts( $json_data['customFonts'] );
469 $this->import_global_style_blocks( $json_data['globalStyleBlocks'] );
470 break;
471 }
472
473 case 'variables': {
474 $this->import_variables( $json_data['variables'], $json_data['variable_prefix'], $json_data['variables']['defaultMode'] );
475 break;
476 }
477
478 case 'contentManager':{
479 $this_batch_content = array();
480 $left_content = array();
481 $count = 0;
482
483 if ( count( $json_data['contentManager'] ) > $this->content_manager_batch_size ) {
484 foreach ( $json_data['contentManager'] as $key => $c ) {
485 if ( $count < $this->content_manager_batch_size ) {
486 $this_batch_content[] = $c;
487 } else {
488 $left_content[] = $c;
489 }
490 $count++;
491 }
492 array_unshift( $queue, $current_task );
493 } else {
494 $this_batch_content = $json_data['contentManager'];
495 }
496
497 $this->import_content_manager( $this_batch_content );
498 $json_data['contentManager'] = $left_content;
499 break;
500 }
501
502 case 'contentManagerRefFields': {
503 $this_batch_content = array();
504 $left_content = array();
505 $count = 0;
506
507 if ( count( $json_data['contentManagerRefFields'] ) > $this->content_manager_batch_size ) {
508 foreach ( $json_data['contentManagerRefFields'] as $key => $c ) {
509 if ( $count < $this->content_manager_batch_size ) {
510 $this_batch_content[] = $c;
511 } else {
512 $left_content[] = $c;
513 }
514 $count++;
515 }
516 array_unshift( $queue, $current_task );
517 } else {
518 $this_batch_content = $json_data['contentManagerRefFields'];
519 }
520
521 $this->import_content_manager_ref_fields( $this_batch_content );
522 $json_data['contentManagerRefFields'] = $left_content;
523 break;
524 }
525
526 case 'symbols': {
527 $this->import_pages( $json_data['symbols'] );
528 break;
529 }
530 case 'popups':{
531 $this->import_pages( $json_data['popups'] );
532 break;
533 }
534 case 'pages':{
535 $this->import_pages( $json_data['pages'] );
536 break;
537 }
538 // templates
539 case 'templates':{
540 $this->import_pages( $json_data['templates'] );
541 break;
542 }
543 case 'utility_pages':{
544 $this->import_pages( $json_data['utility_pages'] );
545 break;
546 }
547 // siteInfo
548 case 'siteInfo':{
549 $this->import_site_info( $json_data['siteInfo'] );
550 $this->import_extra_info();
551 break;
552 }
553 default:
554 // code...
555 break;
556 }
557
558 $environment['queue'] = $queue;
559 $environment['json_data'] = $json_data;
560 $environment['variable_id_tracker'] = $this->variable_id_tracker;
561 $environment['post_id_tracker'] = $this->post_id_tracker;
562 $environment['asset_upload_tracker'] = $this->asset_upload_tracker;
563 $environment['kirki_data_link_tracker'] = $this->kirki_data_link_tracker;
564 $environment['kirki_cm_ref_field_post_tracker'] = $this->kirki_cm_ref_field_post_tracker;
565 $this->save_environment_data( $environment );
566 return array(
567 'status' => 'importing',
568 'queue' => $queue,
569 'done' => $current_task,
570 );
571 } else {
572 HelperFunctions::delete_directory( $temp_folder_path );
573 flush_rewrite_rules( true );
574 $this->save_environment_data( false );
575 return array(
576 'status' => 'done',
577 'queue' => $queue,
578 );
579 }
580 }
581
582 private function import_site_info( $new_site_info ) {
583 if ( ! empty( $new_site_info['page_on_front'] ) && isset( $this->post_id_tracker[ $new_site_info['page_on_front'] ] ) ) {
584 update_option( 'page_on_front', $this->post_id_tracker[ $new_site_info['page_on_front'] ] );
585 }
586 if ( ! empty( $new_site_info['show_on_front'] ) ) {
587 update_option( 'show_on_front', $new_site_info['show_on_front'] );
588 }
589 }
590
591 private function import_extra_info() {
592 foreach ( $this->kirki_data_link_tracker as $post_id => $block_ids ) {
593 $post = get_post( $post_id );
594 $kirki_data = get_post_meta( $post_id, 'kirki', true );
595 if ( is_serialized( $kirki_data ) ) {
596 $kirki_data = maybe_unserialize( $kirki_data );
597 }
598 foreach ( $block_ids as $key => $block_id_or_array ) {
599 // if $block_id_or_array is array then it is a symbol
600 if ( is_array( $block_id_or_array ) ) {
601 $b_id = $block_id_or_array['id'];
602 $ele_id = $block_id_or_array['ele_id'];
603 $type = $block_id_or_array['type'];
604 if ( $type === 'symbol' ) {
605 if ( isset( $kirki_data['data'][ $b_id ]['properties']['symbolElProps'][ $ele_id ]['type'], $kirki_data['data'][ $b_id ]['properties']['symbolElProps'][ $ele_id ]['attributes']['href'] ) ) {
606 $old_href = $kirki_data['data'][ $b_id ]['properties']['symbolElProps'][ $ele_id ]['attributes']['href'];
607 if ( isset( $this->post_id_tracker[ $old_href ] ) ) {
608 $kirki_data['data'][ $b_id ]['properties']['symbolElProps'][ $ele_id ]['attributes']['href'] = $this->post_id_tracker[ $old_href ];
609 }
610 }
611 }
612 } else {
613 if ( $post->post_type === 'kirki_symbol' ) {
614 if ( isset( $kirki_data['data'][ $block_id_or_array ]['properties']['attributes']['href'] ) ) {
615 $old_href = $kirki_data['data'][ $block_id_or_array ]['properties']['attributes']['href'];
616 if ( isset( $this->post_id_tracker[ $old_href ] ) ) {
617 $kirki_data['data'][ $block_id_or_array ]['properties']['attributes']['href'] = $this->post_id_tracker[ $old_href ];
618 }
619 }
620 } elseif ( $post->post_type === 'kirki_popup' ) {
621 if ( isset( $kirki_data[ $block_id_or_array ]['properties']['attributes']['href'] ) ) {
622 $old_href = $kirki_data[ $block_id_or_array ]['properties']['attributes']['href'];
623 if ( isset( $this->post_id_tracker[ $old_href ] ) ) {
624 $kirki_data[ $block_id_or_array ]['properties']['attributes']['href'] = $this->post_id_tracker[ $old_href ];
625 }
626 }
627 } else {
628 if ( isset( $kirki_data['blocks'][ $block_id_or_array ]['properties']['attributes']['href'] ) ) {
629 $old_href = $kirki_data['blocks'][ $block_id_or_array ]['properties']['attributes']['href'];
630 if ( isset( $this->post_id_tracker[ $old_href ] ) ) {
631 $kirki_data['blocks'][ $block_id_or_array ]['properties']['attributes']['href'] = $this->post_id_tracker[ $old_href ];
632 }
633 }
634 }
635 }
636 }
637 update_post_meta( $post_id, 'kirki', $kirki_data );
638 }
639
640 // now loop through the kirki_cm_ref_field_post_tracker and update the post_id and ref_post_id
641 foreach ( $this->kirki_cm_ref_field_post_tracker as $post_id_key => $tracker_post_id ) {
642 $new_post_id = $tracker_post_id;
643 // Now update the post id and ref post id in the meta table
644 $kirki_cm_fields = get_post_meta( $new_post_id, KIRKI_CONTENT_MANAGER_PREFIX . '_fields', true );
645
646 if ( is_serialized( $kirki_cm_fields ) ) {
647 $kirki_cm_fields = maybe_unserialize( $kirki_cm_fields );
648 }
649
650 foreach ( $kirki_cm_fields as $field_key => $field ) {
651 if ( isset( $field['ref_collection'] ) && ! empty( $field['ref_collection'] ) ) {
652 $new_ref_post_id = $this->post_id_tracker[ $field['ref_collection'] ];
653
654 if ( $new_post_id && $new_ref_post_id ) {
655 // update the post id and ref post id
656 $kirki_cm_fields[ $field_key ]['ref_collection'] = $new_ref_post_id;
657 }
658 }
659 }
660
661 // update the post meta
662 update_post_meta( $new_post_id, KIRKI_CONTENT_MANAGER_PREFIX . '_fields', $kirki_cm_fields );
663 }
664 }
665
666 private function import_view_ports( $new_view_ports ) {
667 $control = HelperFunctions::get_global_data_using_key( KIRKI_USER_CONTROLLER_META_KEY );
668 if ( ! $control ) {
669 $control = array();
670 }
671
672 if ( ! isset( $new_view_ports['list'] ) ) {
673 $new_view_ports['list'] = array();
674 }
675 if ( ! isset( $control['viewport'], $control['viewport']['list'] ) ) {
676 $control['viewport'] = $new_view_ports;
677 } else {
678 $control['viewport']['list'] = (object) array_merge( (array) $control['viewport']['list'], (array) $new_view_ports['list'] );
679 }
680 HelperFunctions::update_global_data_using_key( KIRKI_USER_CONTROLLER_META_KEY, $control );
681 return true;
682 }
683
684 private function import_custom_fonts( $new_fonts ) {
685 $custom_fonts = HelperFunctions::get_global_data_using_key( KIRKI_USER_CUSTOM_FONTS_META_KEY );
686 if ( ! $custom_fonts ) {
687 $custom_fonts = array();
688 }
689 $custom_fonts = array_merge( (array) $custom_fonts, (array) $new_fonts );
690
691 HelperFunctions::update_global_data_using_key( KIRKI_USER_CUSTOM_FONTS_META_KEY, $custom_fonts );
692 return true;
693 }
694 private function import_global_style_blocks( $new_blocks ) {
695 if(!$new_blocks){
696 return true;
697 }
698 $new_styles = $this->add_prefix_to_style_blocks( $new_blocks );
699 $global_styles = HelperFunctions::get_global_data_using_key( KIRKI_GLOBAL_STYLE_BLOCK_META_KEY );
700 if ( ! $global_styles ) {
701 $global_styles = array();
702 }
703 $global_styles = array_merge( (array) $global_styles, (array) $new_styles );
704 HelperFunctions::save_global_style_blocks( $global_styles );
705 return true;
706 }
707
708 private function add_prefix_to_style_block_class_names( $name ) {
709 if ( is_array( $name ) ) {
710 foreach ( $name as $key => $c ) {
711 $name[ $key ] = in_array( $c, KIRKI_PRESERVED_CLASS_LIST ) ? $c : $this->add_prefix( $c );
712 }
713 } else {
714 $name = in_array( $name, KIRKI_PRESERVED_CLASS_LIST ) ? $name : $this->add_prefix( $name );
715 }
716 return $name;
717 }
718
719 private function add_prefix_to_style_blocks( $style_blocks ) {
720 $new_styles = array();
721 foreach ( $style_blocks as $key => $block ) {
722 $obj = $block;
723 $obj['id'] = $this->add_prefix( $obj['id'] );
724 $obj['name'] = $this->add_prefix_to_style_block_class_names( $obj['name'] );
725 if ( isset( $obj['isDefault'] ) ) {
726 // remove isDefault from object
727 if ( $obj['isDefault'] === true ) {
728 $obj['isGlobal'] = true;
729 }
730 unset( $obj['isDefault'] );
731 }
732 $new_styles[ $this->add_prefix( $key ) ] = $obj;
733 }
734
735 // STRING RELATED TASK START HERE
736 $style_string = json_encode( $new_styles );
737 $style_string = $this->update_variable_data_from_css_string( $style_string );
738 $style_string = $this->update_assets_url_from_css_string( $style_string );
739
740 $new_styles = json_decode( $style_string, true );
741 // STRING RELATED TASK END HERE
742 return $new_styles;
743 }
744
745 private function update_assets_url_from_css_string( $string ) {
746 return $string; // TODO: need to change assets url
747 $string = stripslashes( $string );
748
749 foreach ( $this->asset_upload_tracker as $key => $asset ) {
750 // Define the pattern to match 'http://jshossen.com'
751 $pattern = '/' . preg_quote( $asset['old_url'], '/' ) . '/';
752 // Define the replacement URL
753 $replacement = $asset['url'];
754 // Replace the old URL with the new one
755 $string = preg_replace( $pattern, $replacement, $string );
756 }
757
758 return $string;
759 }
760
761 private function update_variable_data_from_css_string( $string ) {
762 foreach ( $this->variable_id_tracker as $old => $new ) {
763 $pattern = '/var\(--' . preg_quote( $old, '/' ) . '\)/';
764 $replacement = "var(--$new)";
765 $string = preg_replace( $pattern, $replacement, $string );
766 }
767 return $string;
768 }
769
770 private function filter_variables_by_prefix( array $data, string $prefix ): array {
771 $filtered_data = array_map(
772 function ( array $group ) use ( $prefix ) {
773 if ( ! isset( $group['variables'] ) || ! is_array( $group['variables'] ) ) {
774 $group['variables'] = array();
775 }
776
777 $group['variables'] = array_values(
778 array_filter(
779 $group['variables'],
780 function ( $variable ) use ( $prefix ) {
781 return isset( $variable['id'] ) && strpos( $variable['id'], $prefix ) !== 0;
782 }
783 )
784 );
785
786 return $group;
787 },
788 $data
789 );
790
791 // Remove groups that have no variables left
792 return array_values(
793 array_filter(
794 $filtered_data,
795 function ( $group ) {
796 return ! empty( $group['variables'] );
797 }
798 )
799 );
800 }
801
802 private function import_variables( $new_variables, $variable_prefix, $mode = 'default' ) {
803 $variables = UserData::get_kirki_variable_data();
804 $filter_variable = array();
805
806 if ( isset( $variables['data'] ) && ! empty( $variables['data'] ) ) {
807 $filter_variable = $this->filter_variables_by_prefix( $variables['data'], $this->batch_id );
808 }
809
810 // Normalize new variables if they are in old structure (groups lack 'key')
811 $is_old_structure = ! empty( $new_variables['data'] ) && ! isset( $new_variables['data'][0]['key'] );
812 if ( $is_old_structure ) {
813 $new_variables = UserData::normalize_variable_data( $new_variables );
814 }
815
816 $new_data = $new_variables['data'];
817
818 // Apply prefix + var reference rewrites to all variables in all groups
819 foreach ( $new_data as &$group ) {
820 if ( empty( $group['variables'] ) ) {
821 continue;
822 }
823
824 foreach ( $group['variables'] as &$v ) {
825 $new_id = $this->add_prefix( $v['id'] );
826 $this->variable_id_tracker[ $v['id'] ] = $new_id;
827 $v['id'] = $new_id;
828 $mode_value = isset( $v['value'][ $mode ] ) ? $v['value'][ $mode ] : $v['value']['default'];
829
830 if ( isset( $v['value'][ $mode ] ) && is_string( $v['value'][ $mode ] ) && preg_match( '/var\(--([a-zA-Z0-9\-]+)\)/', $v['value'][ $mode ], $matches ) ) {
831 $id = $matches[1];
832 $new_variable_name = $this->add_prefix( $id );
833 $mode_value = 'var(--' . $new_variable_name . ')';
834 } elseif ( isset( $v['value']['default'] ) && is_string( $v['value']['default'] ) && preg_match( '/var\(--([a-zA-Z0-9\-]+)\)/', $v['value']['default'], $matches ) ) {
835 $id = $matches[1];
836 $new_variable_name = $this->add_prefix( $id );
837 $mode_value = 'var(--' . $new_variable_name . ')';
838 }
839
840 $v['value'] = array( 'default' => $mode_value );
841 }
842 unset( $v );
843 }
844 unset( $group );
845
846 // Merge by group key so same-type groups are combined
847 $merged = array();
848 foreach ( array_merge( (array) $filter_variable, (array) $new_data ) as $group ) {
849 $group_key = isset( $group['key'] ) ? $group['key'] : '';
850 if ( ! isset( $merged[ $group_key ] ) ) {
851 $merged[ $group_key ] = $group;
852 continue;
853 }
854
855 // Deduplicate variables by ID
856 $existing_ids = array();
857 foreach ( $merged[ $group_key ]['variables'] as $var ) {
858 $existing_ids[ $var['id'] ] = true;
859 }
860 foreach ( $group['variables'] as $var ) {
861 if ( ! isset( $existing_ids[ $var['id'] ] ) ) {
862 $merged[ $group_key ]['variables'][] = $var;
863 }
864 }
865 }
866
867 $variables['data'] = array_values( $merged );
868 $saved_data = HelperFunctions::get_global_data_using_key( KIRKI_USER_SAVED_DATA_META_KEY );
869 if ( ! is_array( $saved_data ) ) {
870 $saved_data = array();
871 }
872 // sort variable data
873 $variables = UserData::sort_variable_data( $variables );
874 $saved_data['variableData'] = $variables;
875
876 HelperFunctions::update_global_data_using_key( KIRKI_USER_SAVED_DATA_META_KEY, $saved_data );
877 return true;
878 }
879
880 private function import_content_manager( $content_manager_posts ) {
881 foreach ( $content_manager_posts as $key => $parent_post ) {
882 $this->insert_single_post( $parent_post );
883 }
884 }
885
886 private function import_content_manager_ref_fields( $content_manager_ref_fields ) {
887
888 $updated_ref_fields = array();
889 foreach ( $content_manager_ref_fields as $key => $field ) {
890 // Check field -> post_id, field_meta_key, ref_post_id match with $this->post_id_tracker[field -> post_id] field. If match then update the $new_post['ID'] with the new post id
891 $post_id = $field['post_id'];
892 $field_meta_key = $field['field_meta_key'];
893 $ref_post_id = $field['ref_post_id'];
894
895 if ( isset( $this->post_id_tracker[ $post_id ] ) ) {
896 $new_post_id = $this->post_id_tracker[ $post_id ];
897 $field['post_id'] = $new_post_id;
898 }
899
900 if ( isset( $this->post_id_tracker[ $ref_post_id ] ) ) {
901 $new_ref_post_id = $this->post_id_tracker[ $ref_post_id ];
902 $field['ref_post_id'] = $new_ref_post_id;
903 }
904
905 // Check if the field_meta_key is in the $this->post_id_tracker array. If match then update the $new_post['ID'] with the new post id
906 // Get post ID from the field_meta_key like "kirki_cm_field_123_abc" => 123
907 $parent_post_id = '';
908 $parent_post_id_matches = array();
909 if ( preg_match( '/kirki_cm_field_(\d+)_/', $field_meta_key, $parent_post_id_matches ) ) {
910 $parent_post_id = $parent_post_id_matches[1];
911 }
912
913 // get the field id from the field_meta_key like "kirki_cm_field_123_abc" => abc
914 $field_id = '';
915 $field_id_matches = array();
916 if ( preg_match( '/kirki_cm_field_(\d+)_([a-zA-Z0-9]+)/', $field_meta_key, $field_id_matches ) ) {
917 $field_id = $field_id_matches[2];
918 }
919
920 // check if the parent_post_id is in the $this->post_id_tracker array. If match then update the $new_post['ID'] with the new post id
921 if ( ! empty( $parent_post_id ) && isset( $this->post_id_tracker[ $parent_post_id ] ) ) {
922 $new_parent_post_id = $this->post_id_tracker[ $parent_post_id ];
923
924 $field['field_meta_key'] = KIRKI_CONTENT_MANAGER_PREFIX . '_field_' . $new_parent_post_id . '_' . $field_id;
925 }
926
927 // Add the updated field to the array
928 $updated_ref_fields[] = $field;
929 }
930
931 // Now insert the updated ref fields to the database table name wp_kirki_cm_reference
932 global $wpdb;
933 foreach ( $updated_ref_fields as $key => $field ) {
934 $wpdb->insert(
935 $wpdb->prefix . 'kirki_cm_reference',
936 array(
937 'post_id' => $field['post_id'],
938 'field_meta_key' => $field['field_meta_key'],
939 'ref_post_id' => $field['ref_post_id'],
940 ),
941 array( '%d', '%s', '%d' )
942 );
943 }
944 }
945
946 private function import_pages( $old_pages ) {
947 foreach ( $old_pages as $key => $old_page ) {
948 $flag = apply_filters( 'kirki_import_should_create_page', true, $old_page );
949 if ( $flag === false ) {
950 continue;
951 }
952 $new_page_id = $this->insert_single_post( $old_page );
953
954 if ( ! is_wp_error( $new_page_id ) ) {
955 do_action( 'kirki_import_page_created', $new_page_id, $old_page );
956 }
957 }
958 }
959
960 private function add_post_all_meta( $post ) {
961 $meta = $post['meta'];
962 $post_id = $post['ID'];
963
964 foreach ( $meta as $key => $value ) {
965 $v = $value[0];
966 $updated_key_value = $this->handle_kirki_related_meta( $key, $v, $post );
967 update_post_meta( $post_id, $updated_key_value[0], $updated_key_value[1] );
968 }
969 }
970
971
972 private function update_element_properties_symbol_id( $data, $post_id ) {
973 foreach ( $data as $key => $block ) {
974 if ( isset( $block['properties'], $block['properties']['symbolId'] ) ) {
975 $block['properties']['symbolId'] = $post_id; // Update symbolId with post_id
976 $data[ $key ] = $block;
977 break;
978 }
979 }
980 return $data;
981 }
982
983 private function handle_kirki_related_meta( $key, $v, $post ) {
984 // '_wp_page_template', 'kirki_used_style_block_ids', 'kirki', 'kirki_global_style_block_random', 'kirki_used_style_block_ids_random', 'kirki_page_seo_settings', 'kirki_variable_mode', 'kirki_template_conditions','kirki_cm_fields', 'kirki_cm_basic_fields'
985 $post_type = $post['post_type'];
986 $post_parent = $post['post_parent'];
987 $post_id = $post['ID'];
988
989 if ( is_serialized( $v ) ) {
990 $v = maybe_unserialize( $v );
991 }
992 switch ( $key ) {
993 case 'kirki':
994 if ( $post_type === 'kirki_symbol' ) {
995 $v['data'] = $this->add_prefix_to_kirki_blocks( $v['data'], $post_id );
996 $v['data'] = $this->update_element_properties_symbol_id( $v['data'], $post_id );
997 $v['styleBlocks'] = $this->add_prefix_to_style_blocks( $v['styleBlocks'] );
998 $v['conditions'] = isset( $v['conditions'] ) ? $this->check_kirki_conditions( $v['conditions'] ) : array();
999 } elseif ( $post_type === 'kirki_popup' ) {
1000 $v = $this->add_prefix_to_kirki_blocks( $v, $post_id );
1001 foreach ( $v as $key2 => $v2 ) {
1002 if ( $v2['name'] === 'popup' && isset( $v2['properties'], $v2['properties']['popup'], $v2['properties']['popup'], $v2['properties']['popup']['visibilityConditions'] ) ) {
1003 $v2['properties']['popup']['visibilityConditions'] = $this->check_kirki_conditions( $v2['properties']['popup']['visibilityConditions'] );
1004 }
1005 $v[ $key2 ] = $v2;
1006 }
1007 } else {
1008 // template, pages
1009 $v['blocks'] = $this->add_prefix_to_kirki_blocks( $v['blocks'], $post_id );
1010 }
1011 return array( $key, $v );
1012 case '_wp_page_template':
1013 return array( $key, HelperFunctions::get_kirki_full_canvas_template_path() );
1014
1015 case 'kirki_variable_mode':
1016 return array( $key, '' );// TODO: need to get template mode or selected mode by user
1017 return array( $key, $this->add_prefix( $v ) );
1018
1019 case 'kirki_page_seo_settings':
1020 // TODO: need to update seo settings for kirki_template
1021 return array( $key, $v );
1022
1023 case 'kirki_used_style_block_ids':
1024 foreach ( $v as $key2 => $value ) {
1025 $v[ $key2 ] = $this->add_prefix( $value );
1026 }
1027 return array( $key, $v );
1028
1029 case 'kirki_used_style_block_ids_random':
1030 foreach ( $v as $key2 => $value ) {
1031 $v[ $key2 ] = $this->add_prefix( $value );
1032 }
1033 return array( $key, $v );
1034
1035 case 'kirki_global_style_block_random':
1036 $updated_blocks = $this->add_prefix_to_style_blocks( $v );
1037 return array( $key, $updated_blocks );
1038
1039 case 'kirki_template_conditions':
1040 $v = $this->check_kirki_conditions( $v );
1041 return array( $key, $v );
1042
1043 case 'kirki_cm_fields':
1044 // check if the parent $v array field has any field['ref_collection'] if yes then add the post to the $this->kirki_cm_ref_field_post_tracker array
1045 if ( is_array( $v ) ) {
1046 foreach ( $v as $field_key => $field ) {
1047 if ( isset( $field['ref_collection'] ) && ! empty( $field['ref_collection'] ) ) {
1048 $this->kirki_cm_ref_field_post_tracker[] = $post_id;
1049 break;
1050 }
1051 }
1052 }
1053
1054 // TODO: need to update cm fields default assets data
1055 return array( $key, $v );
1056
1057 case 'kirki_cm_basic_fields':
1058 return array( $key, $v );
1059
1060 default: {
1061 if ( str_contains( $key, 'kirki_cm_field_' ) ) {
1062 // thats means this is content manager item field post_meta key
1063 // Use preg_replace to replace the first instance of the numbers after 'kirki_cm_field_' with $post_parent
1064 $key = preg_replace( '/(kirki_cm_field_)\d+/', '${1}' . $post_parent, $key );
1065
1066 // get parent post fields
1067 $parent_post_fields = get_post_meta( $post_parent, 'kirki_cm_fields', true );
1068
1069 // get current field id
1070 $field_id = '';
1071 $field_id_matches = array();
1072 if ( preg_match( '/kirki_cm_field_(\d+)_([a-zA-Z0-9]+)/', $key, $field_id_matches ) ) {
1073 $field_id = $field_id_matches[2];
1074 }
1075
1076 if ( is_serialized( $parent_post_fields ) ) {
1077 $parent_post_fields = maybe_unserialize( $parent_post_fields );
1078 }
1079
1080 $field_type = $this->get_parent_post_field_type( $parent_post_fields, $field_id );
1081
1082 if ( isset( $field_type ) && $field_type === 'gallery' ) {
1083 foreach ( $v as $key2 => $value ) {
1084 $v[ $key2 ] = $this->format_uploaded_asset( $value );
1085 }
1086 } elseif ( is_array( $v ) ) {
1087 $v = $this->format_uploaded_asset( $v );
1088 }
1089 }
1090
1091 return array( $key, $v );
1092 }
1093 }
1094 }
1095
1096 private function format_uploaded_asset( $value ) {
1097 if ( isset( $value['id'], $value['url'], $value['file_extension'] ) ) {
1098 $attachment_id = $this->asset_upload_tracker[ $value['id'] ]['attachment_id'] ?? null;
1099
1100 if ( $attachment_id ) {
1101 $attachment_post = get_post( $attachment_id );
1102 if ( $attachment_post ) {
1103 $m = new Media();
1104 return $m->format_media_data( $attachment_post );
1105 }
1106 }
1107 }
1108
1109 // return original if no change
1110 return $value;
1111 }
1112
1113 private function get_parent_post_field_type( $parent_post_fields, $field_id ) {
1114 foreach ( $parent_post_fields as $key => $field ) {
1115 if ( isset( $field['id'] ) && $field['id'] === $field_id ) {
1116 return $field['type'];
1117 }
1118 }
1119 return '';
1120 }
1121
1122 private function check_kirki_conditions( $conditions ) {
1123 foreach ( $conditions as $key => $condition ) {
1124 if ( isset( $condition['category'] ) && str_contains( $condition['category'], 'kirki_cm_' ) ) {
1125 $post_parent = str_replace( 'kirki_cm_', '', $condition['category'] );
1126 if ( isset( $this->post_id_tracker[ $post_parent ] ) ) {
1127 $post_parent = $this->post_id_tracker[ $post_parent ];
1128 }
1129 $condition['category'] = ContentManagerHelper::get_child_post_post_type_value( $post_parent );
1130 if ( isset( $condition['apply'], $condition['apply']['to'] ) ) {
1131 $condition['apply']['to'] = $this->post_id_tracker[ $condition['apply']['to'] ];
1132 }
1133 } elseif ( isset( $condition['post_type'] ) && str_contains( $condition['post_type'], 'kirki_cm_' ) ) {
1134 $post_parent = str_replace( 'kirki_cm_', '', $condition['post_type'] );
1135 if ( isset( $this->post_id_tracker[ $post_parent ] ) ) {
1136 $post_parent = $this->post_id_tracker[ $post_parent ];
1137 $condition['post_type'] = ContentManagerHelper::get_child_post_post_type_value( $post_parent );
1138 }
1139 }
1140 $conditions[ $key ] = $condition;
1141 }
1142 return $conditions;
1143 }
1144
1145 private function add_prefix_to_kirki_blocks( $blocks, $post_id ) {
1146 $new_data = array();
1147 foreach ( $blocks as $key => $block ) {
1148 $obj = $block;
1149 if ( isset( $obj['styleIds'] ) && count( $obj['styleIds'] ) > 0 ) {
1150 foreach ( $obj['styleIds'] as $key2 => $style_id ) {
1151 $obj['styleIds'][ $key2 ] = $this->add_prefix( $style_id );
1152 }
1153 }
1154 if ( isset( $obj['properties'], $obj['properties']['textStyleId'] ) ) {
1155 $obj['properties']['textStyleId'] = $this->add_prefix( $obj['properties']['textStyleId'] );
1156 }
1157 // update assets url for kirki block
1158 $obj = $this->update_asset_url_for_kirki_block( $obj );
1159
1160 // update symbol id for kirki block
1161 $obj = $this->update_symbol_id_for_kirki_block( $obj );
1162
1163 // update interaction data for kirki block
1164 $obj = $this->update_interaction_data_for_kirki_block( $obj );
1165
1166 // update collection post type for kirki content manager
1167 $obj = $this->update_collection_settings_for_kirki_block( $obj );
1168 // update link dynamic url. like post id
1169 $obj = $this->update_link_wp_post_id_for_kirki_block( $obj, $post_id );
1170
1171 // TODO: need to update collection element filter data for cm (may be not need to do anything.)
1172
1173 $new_data[ $key ] = $obj;
1174 }
1175 return $new_data;
1176 }
1177
1178 private function insert_single_post( $new_post ) {
1179 $new_post_id = wp_insert_post(
1180 array(
1181 'post_title' => $new_post['post_title'],
1182 'post_content' => $new_post['post_content'],
1183 'post_status' => $this->staging ? 'draft' : $new_post['post_status'],
1184 'post_name' => $new_post['post_name'],
1185 'post_parent' => $new_post['post_parent'],
1186 'menu_order' => $new_post['menu_order'],
1187 'post_type' => $new_post['post_type'],
1188 )
1189 );
1190
1191 // assign meta tag
1192 if ( $new_post_id ) {
1193 update_post_meta( $new_post_id, 'kirki_imported_batch_id', $this->batch_id );
1194 $this->post_id_tracker[ $new_post['ID'] ] = $new_post_id;
1195 $new_post['ID'] = $new_post_id;
1196 $this->add_post_all_meta( $new_post );
1197
1198 if ( isset( $new_post['children'] ) && count( $new_post['children'] ) > 0 ) {
1199 foreach ( $new_post['children'] as $key => $child ) {
1200 $child['post_parent'] = $new_post_id;
1201 if ( str_contains( $child['post_type'], 'kirki_cm_' ) ) {
1202 $child['post_type'] = ContentManagerHelper::get_child_post_post_type_value( $new_post_id );
1203 }
1204 $this->insert_single_post( $child );
1205 }
1206 }
1207 }
1208
1209 return $new_post_id;
1210 }
1211
1212 private function import_assets( $asset_urls ) {
1213
1214 foreach ( $asset_urls as $key => $asset_item ) {
1215 $attachment_id = $asset_item['attachment_id'];
1216
1217 if ( empty( $this->asset_upload_tracker[ $attachment_id ]['url'] ) ) {
1218 // new asset
1219 $new_asset = $this->upload_file( $asset_item );
1220
1221 if ( $new_asset ) {
1222 $this->asset_upload_tracker[ $attachment_id ]['attachment_id'] = $new_asset['attachment_id'];
1223 $this->asset_upload_tracker[ $attachment_id ]['url'] = $new_asset['url'];
1224 $this->asset_upload_tracker[ $attachment_id ]['old_url'] = $asset_item['url'];
1225 }
1226 }
1227 }
1228 }
1229
1230 private function upload_file( $asset_item ) {
1231 $temp_folder_path = HelperFunctions::get_temp_folder_path();
1232 $asset_name = basename( $asset_item['url'] );
1233 $source_file_path = $temp_folder_path . '/assets/' . $asset_name;
1234
1235 if ( file_exists( $source_file_path ) ) {
1236 $file_name = basename( $source_file_path );
1237
1238 // Upload the file
1239 $file_array = array(
1240 'name' => $file_name,
1241 'tmp_name' => $source_file_path,
1242 );
1243
1244 $_FILES['file'] = $file_array;
1245
1246 $attachment_id = media_handle_upload(
1247 'file',
1248 0,
1249 array(),
1250 array(
1251 'test_form' => false,
1252 'action' => 'upload-attachment',
1253 )
1254 );
1255
1256 // Check if the upload was successful
1257 if ( ! is_wp_error( $attachment_id ) ) {
1258 $post = get_post( $attachment_id );
1259 update_post_meta( $post->ID, 'kirki_imported_batch_id', $this->batch_id );
1260 $new_asset = array(
1261 'url' => $post->guid,
1262 'attachment_id' => $attachment_id,
1263 );
1264
1265 return $new_asset;
1266 }
1267 }
1268
1269 return null;
1270 }
1271
1272 private function update_symbol_id_for_kirki_block( $block ) {
1273 if ( $block['name'] === 'symbol' ) {
1274 $block['properties']['symbolId'] = $this->post_id_tracker[ $block['properties']['symbolId'] ];
1275 }
1276 return $block;
1277 }
1278
1279 private function update_collection_settings_for_kirki_block( $block ) {
1280 if(!$block) return $block;
1281
1282 $dynamic_content_key = 'dynamicContent';
1283 if($block['name'] === 'slider'){
1284 $dynamic_content_key = 'dynamicSliderContent';
1285 }
1286
1287 if ( ! isset( $block['properties'], $block['properties'][$dynamic_content_key] ) ) {
1288 return $block;
1289 }
1290
1291 $dc = $block['properties'][$dynamic_content_key];
1292
1293 if ( $block['name'] === 'collection' || $block['name'] === 'slider' ) {
1294 if ( isset( $dc['collectionType'], $dc['type'] ) && $dc['collectionType'] === 'posts' && str_contains( $dc['type'], 'kirki_cm_' ) ) {
1295 $post_parent = str_replace( 'kirki_cm_', '', $dc['type'] );
1296
1297 if ( isset( $this->post_id_tracker[ $post_parent ] ) ) {
1298 $dc['type'] = ContentManagerHelper::get_child_post_post_type_value( $this->post_id_tracker[ $post_parent ] );
1299 }
1300
1301 if ( isset( $dc['filters'] ) ) {
1302 foreach ( $dc['filters'] as $filter_key => $filter ) {
1303 if ( empty( $filter['items'] ) ) {
1304 continue;
1305 }
1306 foreach ( $filter['items'] as $item_key => $item ) {
1307 if ( isset( $this->post_id_tracker[ $item['value'] ] ) ) {
1308 $dc['filters'][ $filter_key ]['items'][ $item_key ]['value'] = $this->post_id_tracker[ $item['value'] ];
1309 }
1310 }
1311 }
1312 }
1313
1314 $block['properties'][$dynamic_content_key] = $dc;
1315 } elseif ( isset( $dc['collectionType'], $dc['type'] ) && $dc['collectionType'] === KIRKI_CONTENT_MANAGER_PREFIX . '_multi_reference' ) {
1316 $post_parent = isset( $dc['cm_ref_collection_id'] ) ? $dc['cm_ref_collection_id'] : '';
1317 if ( isset( $this->post_id_tracker[ $post_parent ] ) ) {
1318 $dc['cm_ref_collection_id'] = $this->post_id_tracker[ $post_parent ];
1319 }
1320 $block['properties'][$dynamic_content_key] = $dc;
1321 }
1322 } elseif ( isset( $dc['type'] ) && $dc['type'] === 'reference' ) {
1323 $post_parent = isset( $dc['cm_post_id'] ) ? $dc['cm_post_id'] : '';
1324
1325 if ( isset( $this->post_id_tracker[ $post_parent ] ) ) {
1326 $dc['cm_post_id'] = $this->post_id_tracker[ $post_parent ];
1327 }
1328
1329 $block['properties'][$dynamic_content_key] = $dc;
1330 }
1331
1332 return $block;
1333 }
1334
1335 private function update_link_wp_post_id_for_kirki_block( $block, $post_id ) {
1336 if ( isset( $block['properties'], $block['properties']['type'], $block['properties']['attributes'], $block['properties']['attributes']['href'] ) ) {
1337 $href = $block['properties']['attributes']['href'];
1338 if ( is_numeric( $href ) && intval( $href ) == $href ) {
1339 if ( isset( $this->post_id_tracker[ $href ] ) ) {
1340 $block['properties']['attributes']['href'] = $this->post_id_tracker[ $href ];
1341 } else {
1342 if ( isset( $this->kirki_data_link_tracker[ $post_id ] ) ) { // Fix: Use $this->kirki_data_link_tracker instead
1343 $this->kirki_data_link_tracker[ $post_id ][] = $block['id'];
1344 } else {
1345 $this->kirki_data_link_tracker[ $post_id ] = array( $block['id'] );
1346 }
1347 }
1348 }
1349
1350 if ( isset( $block['properties'], $block['properties']['attributes'], $block['properties']['attributes']['popup'] ) ) {
1351 $popup = $block['properties']['attributes']['popup'];
1352 if ( isset( $popup ) && is_numeric( $popup ) && intval( $popup ) == $popup ) {
1353 if ( isset( $this->post_id_tracker[ $popup ] ) ) {
1354 $block['properties']['attributes']['popup'] = $this->post_id_tracker[ $popup ];
1355 } else {
1356 if ( isset( $this->kirki_data_link_tracker[ $post_id ] ) ) {
1357 $this->kirki_data_link_tracker[ $post_id ][] = $block['id'];
1358 } else {
1359 $this->kirki_data_link_tracker[ $post_id ] = array( $block['id'] );
1360 }
1361 }
1362 }
1363 }
1364 }
1365
1366 // for symbol link
1367 if ( $block['name'] === 'symbol' ) {
1368 if ( isset( $block['properties']['symbolElProps'] ) ) {
1369 foreach ( $block['properties']['symbolElProps'] as $ele_id => $v ) {
1370 if ( isset( $block['properties']['symbolElProps'][ $ele_id ]['type'], $block['properties']['symbolElProps'][ $ele_id ]['attributes'], $block['properties']['symbolElProps'][ $ele_id ]['attributes']['href'] ) ) {
1371 $href = $block['properties']['symbolElProps'][ $ele_id ]['attributes']['href'];
1372 if ( is_numeric( $href ) && intval( $href ) == $href ) {
1373 if ( isset( $this->post_id_tracker[ $href ] ) ) {
1374 $block['properties']['symbolElProps'][ $ele_id ]['attributes']['href'] = $this->post_id_tracker[ $href ];
1375 } else {
1376 if ( isset( $this->kirki_data_link_tracker[ $post_id ] ) ) {
1377 $this->kirki_data_link_tracker[ $post_id ][] = array(
1378 'id' => $block['id'],
1379 'ele_id' => $ele_id,
1380 'type' => 'symbol',
1381 );
1382 } else {
1383 $this->kirki_data_link_tracker[ $post_id ] = array(
1384 array(
1385 'id' => $block['id'],
1386 'ele_id' => $ele_id,
1387 'type' => 'symbol',
1388 ),
1389 );
1390 }
1391 }
1392 }
1393 }
1394 }
1395 }
1396 }
1397
1398 return $block;
1399 }
1400
1401 private function update_interaction_data_for_kirki_block( $block ) {
1402 if ( isset( $block['properties']['interactions'] ) ) {
1403 $block['properties']['interactions']['deviceAndClassList'] = isset( $block['properties']['interactions']['deviceAndClassList'] ) ? $this->update_interaction_device_and_class_list( $block['properties']['interactions']['deviceAndClassList'] ) : null;
1404
1405 $element_as_trigger = $block['properties']['interactions']['elementAsTrigger'];
1406 foreach ( $element_as_trigger as $key => $trigger ) {
1407
1408 foreach ( $trigger as $key2 => $single_trigger ) {
1409
1410 foreach ( $single_trigger as $key3 => $custom_or_preset ) {
1411
1412 if ( isset( $custom_or_preset['deviceAndClassList'] ) ) {
1413 $custom_or_preset['deviceAndClassList'] = $this->update_interaction_device_and_class_list( $custom_or_preset['deviceAndClassList'] );
1414 }
1415 foreach ( $custom_or_preset['data'] as $ele_id => $single_res ) {
1416 $obj = $single_res;
1417 if ( str_contains( $ele_id, '____info' ) ) {
1418 if ( isset( $obj['applyToClass'], $obj['styleBlockId'] ) && $obj['applyToClass'] ) {
1419 $obj['styleBlockId'] = $this->add_prefix( $obj['styleBlockId'] );
1420 }
1421 }
1422 foreach ( $obj as $ani_key => $animation ) {
1423 if ( isset( $animation['property'] ) && $animation['property'] === 'class-change' ) {
1424 if ( isset( $animation['end'], $animation['end']['className'], $animation['end']['className']['id'] ) ) {
1425 $obj[ $ani_key ]['end']['className']['id'] = $this->add_prefix( $animation['end']['className']['id'] );
1426 }
1427 }
1428
1429 if ( isset( $animation['property'] ) && ( $animation['property'] === 'background-color' || $animation['property'] === 'color' || $animation['property'] === 'border-color' ) ) {
1430 if ( isset( $animation['start'], $animation['start']['value'] ) ) {
1431 if ( str_contains( $animation['start']['value'], 'var(--' ) ) {
1432 // Use regex to extract the value inside var(--...)
1433 preg_match( '/var\(--(.*?)\)/', $animation['start']['value'], $matches );
1434 $animation['start']['value'] = 'var(--' . $this->variable_id_tracker[ $matches[1] ] . ')';
1435 }
1436 }
1437
1438 if ( isset( $animation['end'], $animation['end']['value'] ) ) {
1439 if ( str_contains( $animation['end']['value'], 'var(--' ) ) {
1440 // Use regex to extract the value inside var(--...)
1441 preg_match( '/var\(--(.*?)\)/', $animation['end']['value'], $matches );
1442 $animation['end']['value'] = 'var(--' . $this->variable_id_tracker[ $matches[1] ] . ')';
1443 }
1444 }
1445 }
1446 $obj[ $ani_key ] = $animation;
1447 }
1448
1449 $custom_or_preset['data'][ $ele_id ] = $obj;
1450 }
1451
1452 $single_trigger[ $key3 ] = $custom_or_preset;
1453 }
1454 $trigger[ $key2 ] = $single_trigger;
1455 }
1456
1457 $element_as_trigger[ $key ] = $trigger;
1458 }
1459 $block['properties']['interactions']['elementAsTrigger'] = $element_as_trigger;
1460 }
1461 return $block;
1462 }
1463
1464 private function update_interaction_device_and_class_list( $device_and_class_list ) {
1465 if ( $device_and_class_list && $device_and_class_list['applyToClass'] && ! empty( $device_and_class_list['styleBlockId'] ) ) {
1466 $device_and_class_list['styleBlockId'] = $this->add_prefix( $device_and_class_list['styleBlockId'] );
1467 $new_class_list = $this->add_prefix_to_style_block_class_names( $device_and_class_list['classList'] );
1468 $device_and_class_list['classList'] = $new_class_list;
1469 }
1470
1471 return $device_and_class_list;
1472 }
1473
1474 private function update_asset_url_for_kirki_block( $block ) {
1475 // image
1476 if ( $block['name'] === 'image' && isset( $block['properties']['wp_attachment_id'] ) ) {
1477 $block_attachment_id = $block['properties']['wp_attachment_id'];
1478
1479 if ( isset( $this->asset_upload_tracker[ $block_attachment_id ] ) ) {
1480 $block['properties']['wp_attachment_id'] = $this->asset_upload_tracker[ $block_attachment_id ]['attachment_id'];
1481 $block['properties']['attributes']['src'] = $this->asset_upload_tracker[ $block_attachment_id ]['url'];
1482 };
1483 } elseif ( $block['name'] === 'video' ) {
1484 foreach ( $this->asset_upload_tracker as $key => $asset_item ) {
1485 if ( $block['properties']['attributes']['src'] === $asset_item['old_url'] ) {
1486 $block['properties']['attributes']['src'] = $asset_item['url'];
1487 $block['properties']['wp_attachment_id'] = $asset_item['attachment_id'];
1488 }
1489
1490 if ( $block['properties']['thumbnail']['url'] === $asset_item['old_url'] ) {
1491 $block['properties']['thumbnail']['url'] = $asset_item['url'];
1492 $block['properties']['thumbnail']['wp_attachment_id'] = $asset_item['attachment_id'];
1493 }
1494 }
1495 } elseif ( $block['name'] === 'lottie' ) {
1496
1497 foreach ( $this->asset_upload_tracker as $key => $asset_item ) {
1498 if ( $block['properties']['lottie']['src'] === $asset_item['old_url'] ) {
1499 $block['properties']['lottie']['src'] = $asset_item['url'];
1500 $block['properties']['wp_attachment_id'] = $asset_item['attachment_id'];
1501 }
1502 }
1503 } elseif ( $block['name'] === 'lightbox' ) {
1504 foreach ( $this->asset_upload_tracker as $key => $asset_item ) {
1505 if ( $block['properties']['lightbox']['thumbnail']['src'] === $asset_item['old_url'] ) {
1506 $block['properties']['lightbox']['thumbnail']['src'] = $asset_item['url'];
1507 $block['properties']['wp_attachment_id'] = $asset_item['attachment_id'];
1508 }
1509 }
1510
1511 if ( ! empty( $block['properties']['lightbox']['media'] ) ) {
1512 $media = $block['properties']['lightbox']['media'];
1513
1514 foreach ( $media as $key => $media_item ) {
1515 if ( ! empty( $media_item['id'] ) && isset( $this->asset_upload_tracker[ $media_item['id'] ] ) ) {
1516 $media[ $key ]['id'] = $this->asset_upload_tracker[ $media_item['id'] ]['attachment_id'];
1517 $media[ $key ]['sources']['original'] = $this->asset_upload_tracker[ $media_item['id'] ]['url'];
1518 }
1519 }
1520 $block['properties']['lightbox']['media'] = $media;
1521 }
1522 }
1523
1524 return $block;
1525 }
1526
1527 private function add_prefix( $string ) {
1528 $prefix = $this->prefix ? $this->prefix . '_' : '';
1529
1530 // If there's no prefix set, return the original string
1531 if ( ! $prefix ) {
1532 return $string;
1533 }
1534
1535 // Check if the string already has the correct prefix
1536 if ( strpos( $string, $prefix ) === 0 ) {
1537 return $string; // Return unchanged
1538 }
1539
1540 // If no prefix exists, simply prepend the new prefix
1541 return $prefix . $string;
1542 }
1543
1544 }
1545