PluginProbe ʕ •ᴥ•ʔ
Kirki – Freeform Page Builder, Website Builder & Customizer / trunk
Kirki – Freeform Page Builder, Website Builder & Customizer vtrunk
6.2.5 6.2.4 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 1 month ago TemplateImport.php 1 week ago
TemplateImport.php
1580 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 } else if ( isset( $v['value'][ $mode ] ) ) {
839 // check all the nested nested object and replace the variable name
840 if ( is_array( $v['value'][ $mode ] ) ) {
841 $mode_value = $this->replace_variables_in_nested_array( $v['value'][ $mode ] );
842 }
843 }
844
845 $v['value'] = array( 'default' => $mode_value );
846 }
847 unset( $v );
848 }
849 unset( $group );
850
851 // Merge by group key so same-type groups are combined
852 $merged = array();
853 foreach ( array_merge( (array) $filter_variable, (array) $new_data ) as $group ) {
854 $group_key = isset( $group['key'] ) ? $group['key'] : '';
855 if ( ! isset( $merged[ $group_key ] ) ) {
856 $merged[ $group_key ] = $group;
857 continue;
858 }
859
860 // Deduplicate variables by ID
861 $existing_ids = array();
862 foreach ( $merged[ $group_key ]['variables'] as $var ) {
863 $existing_ids[ $var['id'] ] = true;
864 }
865 foreach ( $group['variables'] as $var ) {
866 if ( ! isset( $existing_ids[ $var['id'] ] ) ) {
867 $merged[ $group_key ]['variables'][] = $var;
868 }
869 }
870 }
871
872 $variables['data'] = array_values( $merged );
873 $saved_data = HelperFunctions::get_global_data_using_key( KIRKI_USER_SAVED_DATA_META_KEY );
874 if ( ! is_array( $saved_data ) ) {
875 $saved_data = array();
876 }
877 // sort variable data
878 $variables = UserData::sort_variable_data( $variables );
879 $saved_data['variableData'] = $variables;
880
881 HelperFunctions::update_global_data_using_key( KIRKI_USER_SAVED_DATA_META_KEY, $saved_data );
882 return true;
883 }
884
885
886 /**
887 * Recursively replace variable references in nested arrays
888 *
889 * @param mixed $data The data to process (array, string, or other)
890 * @return mixed The processed data with replaced variable names
891 */
892 private function replace_variables_in_nested_array( $data ) {
893 if ( is_string( $data ) ) {
894 // Check if the string contains a variable reference like var(--variable-name)
895 if ( preg_match( '/var\(--([a-zA-Z0-9\-]+)\)/', $data, $matches ) ) {
896 $id = $matches[1];
897 $new_variable_name = $this->add_prefix( $id );
898 return 'var(--' . $new_variable_name . ')';
899 }
900 return $data;
901 }
902
903 if ( is_array( $data ) ) {
904 // Recursively process each element in the array
905 foreach ( $data as $key => $value ) {
906 $data[ $key ] = $this->replace_variables_in_nested_array( $value );
907 }
908 return $data;
909 }
910
911 // Return unchanged for other types (int, bool, null, etc.)
912 return $data;
913 }
914
915 private function import_content_manager( $content_manager_posts ) {
916 foreach ( $content_manager_posts as $key => $parent_post ) {
917 $this->insert_single_post( $parent_post );
918 }
919 }
920
921 private function import_content_manager_ref_fields( $content_manager_ref_fields ) {
922
923 $updated_ref_fields = array();
924 foreach ( $content_manager_ref_fields as $key => $field ) {
925 // 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
926 $post_id = $field['post_id'];
927 $field_meta_key = $field['field_meta_key'];
928 $ref_post_id = $field['ref_post_id'];
929
930 if ( isset( $this->post_id_tracker[ $post_id ] ) ) {
931 $new_post_id = $this->post_id_tracker[ $post_id ];
932 $field['post_id'] = $new_post_id;
933 }
934
935 if ( isset( $this->post_id_tracker[ $ref_post_id ] ) ) {
936 $new_ref_post_id = $this->post_id_tracker[ $ref_post_id ];
937 $field['ref_post_id'] = $new_ref_post_id;
938 }
939
940 // 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
941 // Get post ID from the field_meta_key like "kirki_cm_field_123_abc" => 123
942 $parent_post_id = '';
943 $parent_post_id_matches = array();
944 if ( preg_match( '/kirki_cm_field_(\d+)_/', $field_meta_key, $parent_post_id_matches ) ) {
945 $parent_post_id = $parent_post_id_matches[1];
946 }
947
948 // get the field id from the field_meta_key like "kirki_cm_field_123_abc" => abc
949 $field_id = '';
950 $field_id_matches = array();
951 if ( preg_match( '/kirki_cm_field_(\d+)_([a-zA-Z0-9]+)/', $field_meta_key, $field_id_matches ) ) {
952 $field_id = $field_id_matches[2];
953 }
954
955 // 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
956 if ( ! empty( $parent_post_id ) && isset( $this->post_id_tracker[ $parent_post_id ] ) ) {
957 $new_parent_post_id = $this->post_id_tracker[ $parent_post_id ];
958
959 $field['field_meta_key'] = KIRKI_CONTENT_MANAGER_PREFIX . '_field_' . $new_parent_post_id . '_' . $field_id;
960 }
961
962 // Add the updated field to the array
963 $updated_ref_fields[] = $field;
964 }
965
966 // Now insert the updated ref fields to the database table name wp_kirki_cm_reference
967 global $wpdb;
968 foreach ( $updated_ref_fields as $key => $field ) {
969 $wpdb->insert(
970 $wpdb->prefix . 'kirki_cm_reference',
971 array(
972 'post_id' => $field['post_id'],
973 'field_meta_key' => $field['field_meta_key'],
974 'ref_post_id' => $field['ref_post_id'],
975 ),
976 array( '%d', '%s', '%d' )
977 );
978 }
979 }
980
981 private function import_pages( $old_pages ) {
982 foreach ( $old_pages as $key => $old_page ) {
983 $flag = apply_filters( 'kirki_import_should_create_page', true, $old_page );
984 if ( $flag === false ) {
985 continue;
986 }
987 $new_page_id = $this->insert_single_post( $old_page );
988
989 if ( ! is_wp_error( $new_page_id ) ) {
990 do_action( 'kirki_import_page_created', $new_page_id, $old_page );
991 }
992 }
993 }
994
995 private function add_post_all_meta( $post ) {
996 $meta = $post['meta'];
997 $post_id = $post['ID'];
998
999 foreach ( $meta as $key => $value ) {
1000 $v = $value[0];
1001 $updated_key_value = $this->handle_kirki_related_meta( $key, $v, $post );
1002 update_post_meta( $post_id, $updated_key_value[0], $updated_key_value[1] );
1003 }
1004 }
1005
1006
1007 private function update_element_properties_symbol_id( $data, $post_id ) {
1008 foreach ( $data as $key => $block ) {
1009 if ( isset( $block['properties'], $block['properties']['symbolId'] ) ) {
1010 $block['properties']['symbolId'] = $post_id; // Update symbolId with post_id
1011 $data[ $key ] = $block;
1012 break;
1013 }
1014 }
1015 return $data;
1016 }
1017
1018 private function handle_kirki_related_meta( $key, $v, $post ) {
1019 // '_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'
1020 $post_type = $post['post_type'];
1021 $post_parent = $post['post_parent'];
1022 $post_id = $post['ID'];
1023
1024 if ( is_serialized( $v ) ) {
1025 $v = maybe_unserialize( $v );
1026 }
1027 switch ( $key ) {
1028 case 'kirki':
1029 if ( $post_type === 'kirki_symbol' ) {
1030 $v['data'] = $this->add_prefix_to_kirki_blocks( $v['data'], $post_id );
1031 $v['data'] = $this->update_element_properties_symbol_id( $v['data'], $post_id );
1032 $v['styleBlocks'] = $this->add_prefix_to_style_blocks( $v['styleBlocks'] );
1033 $v['conditions'] = isset( $v['conditions'] ) ? $this->check_kirki_conditions( $v['conditions'] ) : array();
1034 } elseif ( $post_type === 'kirki_popup' ) {
1035 $v = $this->add_prefix_to_kirki_blocks( $v, $post_id );
1036 foreach ( $v as $key2 => $v2 ) {
1037 if ( $v2['name'] === 'popup' && isset( $v2['properties'], $v2['properties']['popup'], $v2['properties']['popup'], $v2['properties']['popup']['visibilityConditions'] ) ) {
1038 $v2['properties']['popup']['visibilityConditions'] = $this->check_kirki_conditions( $v2['properties']['popup']['visibilityConditions'] );
1039 }
1040 $v[ $key2 ] = $v2;
1041 }
1042 } else {
1043 // template, pages
1044 $v['blocks'] = $this->add_prefix_to_kirki_blocks( $v['blocks'], $post_id );
1045 }
1046 return array( $key, $v );
1047 case '_wp_page_template':
1048 return array( $key, HelperFunctions::get_kirki_full_canvas_template_path() );
1049
1050 case 'kirki_variable_mode':
1051 return array( $key, '' );// TODO: need to get template mode or selected mode by user
1052 return array( $key, $this->add_prefix( $v ) );
1053
1054 case 'kirki_page_seo_settings':
1055 // TODO: need to update seo settings for kirki_template
1056 return array( $key, $v );
1057
1058 case 'kirki_used_style_block_ids':
1059 foreach ( $v as $key2 => $value ) {
1060 $v[ $key2 ] = $this->add_prefix( $value );
1061 }
1062 return array( $key, $v );
1063
1064 case 'kirki_used_style_block_ids_random':
1065 foreach ( $v as $key2 => $value ) {
1066 $v[ $key2 ] = $this->add_prefix( $value );
1067 }
1068 return array( $key, $v );
1069
1070 case 'kirki_global_style_block_random':
1071 $updated_blocks = $this->add_prefix_to_style_blocks( $v );
1072 return array( $key, $updated_blocks );
1073
1074 case 'kirki_template_conditions':
1075 $v = $this->check_kirki_conditions( $v );
1076 return array( $key, $v );
1077
1078 case 'kirki_cm_fields':
1079 // 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
1080 if ( is_array( $v ) ) {
1081 foreach ( $v as $field_key => $field ) {
1082 if ( isset( $field['ref_collection'] ) && ! empty( $field['ref_collection'] ) ) {
1083 $this->kirki_cm_ref_field_post_tracker[] = $post_id;
1084 break;
1085 }
1086 }
1087 }
1088
1089 // TODO: need to update cm fields default assets data
1090 return array( $key, $v );
1091
1092 case 'kirki_cm_basic_fields':
1093 return array( $key, $v );
1094
1095 default: {
1096 if ( str_contains( $key, 'kirki_cm_field_' ) ) {
1097 // thats means this is content manager item field post_meta key
1098 // Use preg_replace to replace the first instance of the numbers after 'kirki_cm_field_' with $post_parent
1099 $key = preg_replace( '/(kirki_cm_field_)\d+/', '${1}' . $post_parent, $key );
1100
1101 // get parent post fields
1102 $parent_post_fields = get_post_meta( $post_parent, 'kirki_cm_fields', true );
1103
1104 // get current field id
1105 $field_id = '';
1106 $field_id_matches = array();
1107 if ( preg_match( '/kirki_cm_field_(\d+)_([a-zA-Z0-9]+)/', $key, $field_id_matches ) ) {
1108 $field_id = $field_id_matches[2];
1109 }
1110
1111 if ( is_serialized( $parent_post_fields ) ) {
1112 $parent_post_fields = maybe_unserialize( $parent_post_fields );
1113 }
1114
1115 $field_type = $this->get_parent_post_field_type( $parent_post_fields, $field_id );
1116
1117 if ( isset( $field_type ) && $field_type === 'gallery' ) {
1118 foreach ( $v as $key2 => $value ) {
1119 $v[ $key2 ] = $this->format_uploaded_asset( $value );
1120 }
1121 } elseif ( is_array( $v ) ) {
1122 $v = $this->format_uploaded_asset( $v );
1123 }
1124 }
1125
1126 return array( $key, $v );
1127 }
1128 }
1129 }
1130
1131 private function format_uploaded_asset( $value ) {
1132 if ( isset( $value['id'], $value['url'], $value['file_extension'] ) ) {
1133 $attachment_id = $this->asset_upload_tracker[ $value['id'] ]['attachment_id'] ?? null;
1134
1135 if ( $attachment_id ) {
1136 $attachment_post = get_post( $attachment_id );
1137 if ( $attachment_post ) {
1138 $m = new Media();
1139 return $m->format_media_data( $attachment_post );
1140 }
1141 }
1142 }
1143
1144 // return original if no change
1145 return $value;
1146 }
1147
1148 private function get_parent_post_field_type( $parent_post_fields, $field_id ) {
1149 foreach ( $parent_post_fields as $key => $field ) {
1150 if ( isset( $field['id'] ) && $field['id'] === $field_id ) {
1151 return $field['type'];
1152 }
1153 }
1154 return '';
1155 }
1156
1157 private function check_kirki_conditions( $conditions ) {
1158 foreach ( $conditions as $key => $condition ) {
1159 if ( isset( $condition['category'] ) && str_contains( $condition['category'], 'kirki_cm_' ) ) {
1160 $post_parent = str_replace( 'kirki_cm_', '', $condition['category'] );
1161 if ( isset( $this->post_id_tracker[ $post_parent ] ) ) {
1162 $post_parent = $this->post_id_tracker[ $post_parent ];
1163 }
1164 $condition['category'] = ContentManagerHelper::get_child_post_post_type_value( $post_parent );
1165 if ( isset( $condition['apply'], $condition['apply']['to'] ) ) {
1166 $condition['apply']['to'] = $this->post_id_tracker[ $condition['apply']['to'] ];
1167 }
1168 } elseif ( isset( $condition['post_type'] ) && str_contains( $condition['post_type'], 'kirki_cm_' ) ) {
1169 $post_parent = str_replace( 'kirki_cm_', '', $condition['post_type'] );
1170 if ( isset( $this->post_id_tracker[ $post_parent ] ) ) {
1171 $post_parent = $this->post_id_tracker[ $post_parent ];
1172 $condition['post_type'] = ContentManagerHelper::get_child_post_post_type_value( $post_parent );
1173 }
1174 }
1175 $conditions[ $key ] = $condition;
1176 }
1177 return $conditions;
1178 }
1179
1180 private function add_prefix_to_kirki_blocks( $blocks, $post_id ) {
1181 $new_data = array();
1182 foreach ( $blocks as $key => $block ) {
1183 $obj = $block;
1184 if ( isset( $obj['styleIds'] ) && count( $obj['styleIds'] ) > 0 ) {
1185 foreach ( $obj['styleIds'] as $key2 => $style_id ) {
1186 $obj['styleIds'][ $key2 ] = $this->add_prefix( $style_id );
1187 }
1188 }
1189 if ( isset( $obj['properties'], $obj['properties']['textStyleId'] ) ) {
1190 $obj['properties']['textStyleId'] = $this->add_prefix( $obj['properties']['textStyleId'] );
1191 }
1192 // update assets url for kirki block
1193 $obj = $this->update_asset_url_for_kirki_block( $obj );
1194
1195 // update symbol id for kirki block
1196 $obj = $this->update_symbol_id_for_kirki_block( $obj );
1197
1198 // update interaction data for kirki block
1199 $obj = $this->update_interaction_data_for_kirki_block( $obj );
1200
1201 // update collection post type for kirki content manager
1202 $obj = $this->update_collection_settings_for_kirki_block( $obj );
1203 // update link dynamic url. like post id
1204 $obj = $this->update_link_wp_post_id_for_kirki_block( $obj, $post_id );
1205
1206 // TODO: need to update collection element filter data for cm (may be not need to do anything.)
1207
1208 $new_data[ $key ] = $obj;
1209 }
1210 return $new_data;
1211 }
1212
1213 private function insert_single_post( $new_post ) {
1214 $new_post_id = wp_insert_post(
1215 array(
1216 'post_title' => $new_post['post_title'],
1217 'post_content' => $new_post['post_content'],
1218 'post_status' => $this->staging ? 'draft' : $new_post['post_status'],
1219 'post_name' => $new_post['post_name'],
1220 'post_parent' => $new_post['post_parent'],
1221 'menu_order' => $new_post['menu_order'],
1222 'post_type' => $new_post['post_type'],
1223 )
1224 );
1225
1226 // assign meta tag
1227 if ( $new_post_id ) {
1228 update_post_meta( $new_post_id, 'kirki_imported_batch_id', $this->batch_id );
1229 $this->post_id_tracker[ $new_post['ID'] ] = $new_post_id;
1230 $new_post['ID'] = $new_post_id;
1231 $this->add_post_all_meta( $new_post );
1232
1233 if ( isset( $new_post['children'] ) && count( $new_post['children'] ) > 0 ) {
1234 foreach ( $new_post['children'] as $key => $child ) {
1235 $child['post_parent'] = $new_post_id;
1236 if ( str_contains( $child['post_type'], 'kirki_cm_' ) ) {
1237 $child['post_type'] = ContentManagerHelper::get_child_post_post_type_value( $new_post_id );
1238 }
1239 $this->insert_single_post( $child );
1240 }
1241 }
1242 }
1243
1244 return $new_post_id;
1245 }
1246
1247 private function import_assets( $asset_urls ) {
1248
1249 foreach ( $asset_urls as $key => $asset_item ) {
1250 $attachment_id = $asset_item['attachment_id'];
1251
1252 if ( empty( $this->asset_upload_tracker[ $attachment_id ]['url'] ) ) {
1253 // new asset
1254 $new_asset = $this->upload_file( $asset_item );
1255
1256 if ( $new_asset ) {
1257 $this->asset_upload_tracker[ $attachment_id ]['attachment_id'] = $new_asset['attachment_id'];
1258 $this->asset_upload_tracker[ $attachment_id ]['url'] = $new_asset['url'];
1259 $this->asset_upload_tracker[ $attachment_id ]['old_url'] = $asset_item['url'];
1260 }
1261 }
1262 }
1263 }
1264
1265 private function upload_file( $asset_item ) {
1266 $temp_folder_path = HelperFunctions::get_temp_folder_path();
1267 $asset_name = basename( $asset_item['url'] );
1268 $source_file_path = $temp_folder_path . '/assets/' . $asset_name;
1269
1270 if ( file_exists( $source_file_path ) ) {
1271 $file_name = basename( $source_file_path );
1272
1273 // Upload the file
1274 $file_array = array(
1275 'name' => $file_name,
1276 'tmp_name' => $source_file_path,
1277 );
1278
1279 $_FILES['file'] = $file_array;
1280
1281 $attachment_id = media_handle_upload(
1282 'file',
1283 0,
1284 array(),
1285 array(
1286 'test_form' => false,
1287 'action' => 'upload-attachment',
1288 )
1289 );
1290
1291 // Check if the upload was successful
1292 if ( ! is_wp_error( $attachment_id ) ) {
1293 $post = get_post( $attachment_id );
1294 update_post_meta( $post->ID, 'kirki_imported_batch_id', $this->batch_id );
1295 $new_asset = array(
1296 'url' => $post->guid,
1297 'attachment_id' => $attachment_id,
1298 );
1299
1300 return $new_asset;
1301 }
1302 }
1303
1304 return null;
1305 }
1306
1307 private function update_symbol_id_for_kirki_block( $block ) {
1308 if ( $block['name'] === 'symbol' ) {
1309 $block['properties']['symbolId'] = $this->post_id_tracker[ $block['properties']['symbolId'] ];
1310 }
1311 return $block;
1312 }
1313
1314 private function update_collection_settings_for_kirki_block( $block ) {
1315 if(!$block) return $block;
1316
1317 $dynamic_content_key = 'dynamicContent';
1318 if($block['name'] === 'slider'){
1319 $dynamic_content_key = 'dynamicSliderContent';
1320 }
1321
1322 if ( ! isset( $block['properties'], $block['properties'][$dynamic_content_key] ) ) {
1323 return $block;
1324 }
1325
1326 $dc = $block['properties'][$dynamic_content_key];
1327
1328 if ( $block['name'] === 'collection' || $block['name'] === 'slider' ) {
1329 if ( isset( $dc['collectionType'], $dc['type'] ) && $dc['collectionType'] === 'posts' && str_contains( $dc['type'], 'kirki_cm_' ) ) {
1330 $post_parent = str_replace( 'kirki_cm_', '', $dc['type'] );
1331
1332 if ( isset( $this->post_id_tracker[ $post_parent ] ) ) {
1333 $dc['type'] = ContentManagerHelper::get_child_post_post_type_value( $this->post_id_tracker[ $post_parent ] );
1334 }
1335
1336 if ( isset( $dc['filters'] ) ) {
1337 foreach ( $dc['filters'] as $filter_key => $filter ) {
1338 if ( empty( $filter['items'] ) ) {
1339 continue;
1340 }
1341 foreach ( $filter['items'] as $item_key => $item ) {
1342 if ( isset( $this->post_id_tracker[ $item['value'] ] ) ) {
1343 $dc['filters'][ $filter_key ]['items'][ $item_key ]['value'] = $this->post_id_tracker[ $item['value'] ];
1344 }
1345 }
1346 }
1347 }
1348
1349 $block['properties'][$dynamic_content_key] = $dc;
1350 } elseif ( isset( $dc['collectionType'], $dc['type'] ) && $dc['collectionType'] === KIRKI_CONTENT_MANAGER_PREFIX . '_multi_reference' ) {
1351 $post_parent = isset( $dc['cm_ref_collection_id'] ) ? $dc['cm_ref_collection_id'] : '';
1352 if ( isset( $this->post_id_tracker[ $post_parent ] ) ) {
1353 $dc['cm_ref_collection_id'] = $this->post_id_tracker[ $post_parent ];
1354 }
1355 $block['properties'][$dynamic_content_key] = $dc;
1356 }
1357 } elseif ( isset( $dc['type'] ) && $dc['type'] === 'reference' ) {
1358 $post_parent = isset( $dc['cm_post_id'] ) ? $dc['cm_post_id'] : '';
1359
1360 if ( isset( $this->post_id_tracker[ $post_parent ] ) ) {
1361 $dc['cm_post_id'] = $this->post_id_tracker[ $post_parent ];
1362 }
1363
1364 $block['properties'][$dynamic_content_key] = $dc;
1365 }
1366
1367 return $block;
1368 }
1369
1370 private function update_link_wp_post_id_for_kirki_block( $block, $post_id ) {
1371 if ( isset( $block['properties'], $block['properties']['type'], $block['properties']['attributes'], $block['properties']['attributes']['href'] ) ) {
1372 $href = $block['properties']['attributes']['href'];
1373 if ( is_numeric( $href ) && intval( $href ) == $href ) {
1374 if ( isset( $this->post_id_tracker[ $href ] ) ) {
1375 $block['properties']['attributes']['href'] = $this->post_id_tracker[ $href ];
1376 } else {
1377 if ( isset( $this->kirki_data_link_tracker[ $post_id ] ) ) { // Fix: Use $this->kirki_data_link_tracker instead
1378 $this->kirki_data_link_tracker[ $post_id ][] = $block['id'];
1379 } else {
1380 $this->kirki_data_link_tracker[ $post_id ] = array( $block['id'] );
1381 }
1382 }
1383 }
1384
1385 if ( isset( $block['properties'], $block['properties']['attributes'], $block['properties']['attributes']['popup'] ) ) {
1386 $popup = $block['properties']['attributes']['popup'];
1387 if ( isset( $popup ) && is_numeric( $popup ) && intval( $popup ) == $popup ) {
1388 if ( isset( $this->post_id_tracker[ $popup ] ) ) {
1389 $block['properties']['attributes']['popup'] = $this->post_id_tracker[ $popup ];
1390 } else {
1391 if ( isset( $this->kirki_data_link_tracker[ $post_id ] ) ) {
1392 $this->kirki_data_link_tracker[ $post_id ][] = $block['id'];
1393 } else {
1394 $this->kirki_data_link_tracker[ $post_id ] = array( $block['id'] );
1395 }
1396 }
1397 }
1398 }
1399 }
1400
1401 // for symbol link
1402 if ( $block['name'] === 'symbol' ) {
1403 if ( isset( $block['properties']['symbolElProps'] ) ) {
1404 foreach ( $block['properties']['symbolElProps'] as $ele_id => $v ) {
1405 if ( isset( $block['properties']['symbolElProps'][ $ele_id ]['type'], $block['properties']['symbolElProps'][ $ele_id ]['attributes'], $block['properties']['symbolElProps'][ $ele_id ]['attributes']['href'] ) ) {
1406 $href = $block['properties']['symbolElProps'][ $ele_id ]['attributes']['href'];
1407 if ( is_numeric( $href ) && intval( $href ) == $href ) {
1408 if ( isset( $this->post_id_tracker[ $href ] ) ) {
1409 $block['properties']['symbolElProps'][ $ele_id ]['attributes']['href'] = $this->post_id_tracker[ $href ];
1410 } else {
1411 if ( isset( $this->kirki_data_link_tracker[ $post_id ] ) ) {
1412 $this->kirki_data_link_tracker[ $post_id ][] = array(
1413 'id' => $block['id'],
1414 'ele_id' => $ele_id,
1415 'type' => 'symbol',
1416 );
1417 } else {
1418 $this->kirki_data_link_tracker[ $post_id ] = array(
1419 array(
1420 'id' => $block['id'],
1421 'ele_id' => $ele_id,
1422 'type' => 'symbol',
1423 ),
1424 );
1425 }
1426 }
1427 }
1428 }
1429 }
1430 }
1431 }
1432
1433 return $block;
1434 }
1435
1436 private function update_interaction_data_for_kirki_block( $block ) {
1437 if ( isset( $block['properties']['interactions'] ) ) {
1438 $block['properties']['interactions']['deviceAndClassList'] = isset( $block['properties']['interactions']['deviceAndClassList'] ) ? $this->update_interaction_device_and_class_list( $block['properties']['interactions']['deviceAndClassList'] ) : null;
1439
1440 $element_as_trigger = $block['properties']['interactions']['elementAsTrigger'];
1441 foreach ( $element_as_trigger as $key => $trigger ) {
1442
1443 foreach ( $trigger as $key2 => $single_trigger ) {
1444
1445 foreach ( $single_trigger as $key3 => $custom_or_preset ) {
1446
1447 if ( isset( $custom_or_preset['deviceAndClassList'] ) ) {
1448 $custom_or_preset['deviceAndClassList'] = $this->update_interaction_device_and_class_list( $custom_or_preset['deviceAndClassList'] );
1449 }
1450 foreach ( $custom_or_preset['data'] as $ele_id => $single_res ) {
1451 $obj = $single_res;
1452 if ( str_contains( $ele_id, '____info' ) ) {
1453 if ( isset( $obj['applyToClass'], $obj['styleBlockId'] ) && $obj['applyToClass'] ) {
1454 $obj['styleBlockId'] = $this->add_prefix( $obj['styleBlockId'] );
1455 }
1456 }
1457 foreach ( $obj as $ani_key => $animation ) {
1458 if ( isset( $animation['property'] ) && $animation['property'] === 'class-change' ) {
1459 if ( isset( $animation['end'], $animation['end']['className'], $animation['end']['className']['id'] ) ) {
1460 $obj[ $ani_key ]['end']['className']['id'] = $this->add_prefix( $animation['end']['className']['id'] );
1461 }
1462 }
1463
1464 if ( isset( $animation['property'] ) && ( $animation['property'] === 'background-color' || $animation['property'] === 'color' || $animation['property'] === 'border-color' ) ) {
1465 if ( isset( $animation['start'], $animation['start']['value'] ) ) {
1466 if ( str_contains( $animation['start']['value'], 'var(--' ) ) {
1467 // Use regex to extract the value inside var(--...)
1468 preg_match( '/var\(--(.*?)\)/', $animation['start']['value'], $matches );
1469 $animation['start']['value'] = 'var(--' . $this->variable_id_tracker[ $matches[1] ] . ')';
1470 }
1471 }
1472
1473 if ( isset( $animation['end'], $animation['end']['value'] ) ) {
1474 if ( str_contains( $animation['end']['value'], 'var(--' ) ) {
1475 // Use regex to extract the value inside var(--...)
1476 preg_match( '/var\(--(.*?)\)/', $animation['end']['value'], $matches );
1477 $animation['end']['value'] = 'var(--' . $this->variable_id_tracker[ $matches[1] ] . ')';
1478 }
1479 }
1480 }
1481 $obj[ $ani_key ] = $animation;
1482 }
1483
1484 $custom_or_preset['data'][ $ele_id ] = $obj;
1485 }
1486
1487 $single_trigger[ $key3 ] = $custom_or_preset;
1488 }
1489 $trigger[ $key2 ] = $single_trigger;
1490 }
1491
1492 $element_as_trigger[ $key ] = $trigger;
1493 }
1494 $block['properties']['interactions']['elementAsTrigger'] = $element_as_trigger;
1495 }
1496 return $block;
1497 }
1498
1499 private function update_interaction_device_and_class_list( $device_and_class_list ) {
1500 if ( $device_and_class_list && $device_and_class_list['applyToClass'] && ! empty( $device_and_class_list['styleBlockId'] ) ) {
1501 $device_and_class_list['styleBlockId'] = $this->add_prefix( $device_and_class_list['styleBlockId'] );
1502 $new_class_list = $this->add_prefix_to_style_block_class_names( $device_and_class_list['classList'] );
1503 $device_and_class_list['classList'] = $new_class_list;
1504 }
1505
1506 return $device_and_class_list;
1507 }
1508
1509 private function update_asset_url_for_kirki_block( $block ) {
1510 // image
1511 if ( $block['name'] === 'image' && isset( $block['properties']['wp_attachment_id'] ) ) {
1512 $block_attachment_id = $block['properties']['wp_attachment_id'];
1513
1514 if ( isset( $this->asset_upload_tracker[ $block_attachment_id ] ) ) {
1515 $block['properties']['wp_attachment_id'] = $this->asset_upload_tracker[ $block_attachment_id ]['attachment_id'];
1516 $block['properties']['attributes']['src'] = $this->asset_upload_tracker[ $block_attachment_id ]['url'];
1517 };
1518 } elseif ( $block['name'] === 'video' ) {
1519 foreach ( $this->asset_upload_tracker as $key => $asset_item ) {
1520 if ( $block['properties']['attributes']['src'] === $asset_item['old_url'] ) {
1521 $block['properties']['attributes']['src'] = $asset_item['url'];
1522 $block['properties']['wp_attachment_id'] = $asset_item['attachment_id'];
1523 }
1524
1525 if ( $block['properties']['thumbnail']['url'] === $asset_item['old_url'] ) {
1526 $block['properties']['thumbnail']['url'] = $asset_item['url'];
1527 $block['properties']['thumbnail']['wp_attachment_id'] = $asset_item['attachment_id'];
1528 }
1529 }
1530 } elseif ( $block['name'] === 'lottie' ) {
1531
1532 foreach ( $this->asset_upload_tracker as $key => $asset_item ) {
1533 if ( $block['properties']['lottie']['src'] === $asset_item['old_url'] ) {
1534 $block['properties']['lottie']['src'] = $asset_item['url'];
1535 $block['properties']['wp_attachment_id'] = $asset_item['attachment_id'];
1536 }
1537 }
1538 } elseif ( $block['name'] === 'lightbox' ) {
1539 foreach ( $this->asset_upload_tracker as $key => $asset_item ) {
1540 if ( $block['properties']['lightbox']['thumbnail']['src'] === $asset_item['old_url'] ) {
1541 $block['properties']['lightbox']['thumbnail']['src'] = $asset_item['url'];
1542 $block['properties']['wp_attachment_id'] = $asset_item['attachment_id'];
1543 }
1544 }
1545
1546 if ( ! empty( $block['properties']['lightbox']['media'] ) ) {
1547 $media = $block['properties']['lightbox']['media'];
1548
1549 foreach ( $media as $key => $media_item ) {
1550 if ( ! empty( $media_item['id'] ) && isset( $this->asset_upload_tracker[ $media_item['id'] ] ) ) {
1551 $media[ $key ]['id'] = $this->asset_upload_tracker[ $media_item['id'] ]['attachment_id'];
1552 $media[ $key ]['sources']['original'] = $this->asset_upload_tracker[ $media_item['id'] ]['url'];
1553 }
1554 }
1555 $block['properties']['lightbox']['media'] = $media;
1556 }
1557 }
1558
1559 return $block;
1560 }
1561
1562 private function add_prefix( $string ) {
1563 $prefix = $this->prefix ? $this->prefix . '_' : '';
1564
1565 // If there's no prefix set, return the original string
1566 if ( ! $prefix ) {
1567 return $string;
1568 }
1569
1570 // Check if the string already has the correct prefix
1571 if ( strpos( $string, $prefix ) === 0 ) {
1572 return $string; // Return unchanged
1573 }
1574
1575 // If no prefix exists, simply prepend the new prefix
1576 return $prefix . $string;
1577 }
1578
1579 }
1580